4506|1

2144

帖子

3

TA的资源

五彩晶圆(中级)

楼主
 

helper2416_内存分配实现_有分析 [复制链接]

好了,昨天我们的RTOS已经跑起来了,相关的DRAM划分也说的比较清楚了,这里我主要实现内存分配,使用自带的微型库。
相关细节,主要参考ARM官方的doc,方法如下
1)进入如下地址
http://infocenter.arm.com/help/index.jsp

2)搜索关键字即可,如
__user_initial_stackheap
__initial_sp
__heap_base
__heap_limit



好了,这里需要指定堆栈,有两种方法

1)通过汇编代码
新建一个heap.S文件,内容如下
  1. ;-------------------------------------------------------------------------------
  2. ; 堆栈
  3. ;-------------------------------------------------------------------------------
  4.         AREA          |.text|, CODE, READONLY
  5.        
  6.        
  7.     EXPORT __initial_sp
  8. __initial_sp EQU 0x30800000                ;STACK栈顶

  9.     EXPORT __heap_base
  10. __heap_base EQU  0x30200000                ;HEAP起始地址

  11.     EXPORT __heap_limit
  12. __heap_limit EQU 0x30600000               ;HEAP结束地址


  13.         END
  14.        
  15. ;-------------------------------------------------------------------------------
  16. ; 文件结束
  17. ;-------------------------------------------------------------------------------
复制代码
主要依据如下,可参考中文资料在ARM的文档中,右边目录可以找到位于:
ARM 软件开发工具--->RealView Development Suite---->Version 4.0 中文用户手册




2)通过分散加载描述文件
  1. LR_ROM1 0x30800000 0x2800000          {                    ; load region size_region
  2.         RW_ROM1 0x30800000 0x2800000 {                  ; load address = execution address
  3.                 *.o (RESET, +First)
  4.                 .ANY (+RO +RW)
  5.         }
  6.         RW_RAM1 0x33000000 0x1000000 {  
  7.                 .ANY(+ZI)
  8.         }
  9.        
  10.         ARM_LIB_HEAP  0x30200000 EMPTY  0x00400000 {
  11.                
  12.         }
  13.     ARM_LIB_STACK 0x30800000 EMPTY -0x00200000 {
  14.                
  15.         }
  16. }
复制代码
主要依据,如下





----------------------------------------------------------------------------------------------------------------------------------------

重要提示,请看官方doc复制的原文
从 RVCT v2.x 及更低版本移植到 RVCT v4.0
在 RVCT 2.x 及更低版本中,__user_initial_stackheap() 的缺省实现使用符号 Image$$ZI$$Limit 的值。 如果链接器使用分散加载描述文件(使用 --scatter 命令行选项指定),则不会定义该符号;因此,如果使用的是分散加载描述文件,则必须重新实现__user_initial_stackheap(),否则,链接步骤将会失败。
另外,您也可以使用 __user_setup_stackheap()(而不是 __user_initial_stackheap())来升级源代码。

从 RVCT v3 移植到 RVCT v4.0
在 RVCT v3.x 和更高版本中,库包含更多的 __user_initial_stackheap() 实现,并且可通过分散加载描述文件中提供的信息自动选择正确的实现。 这意味着,如果使用的是分散加载文件,则不需要重新实现该函数。 有关详细信息,请参阅使用分散加载描述文件




----------------------------------------------------------------------------------------------------------------------------------------


因为我在参考ARM文档之前,在网上看了一些前人的总结,基本上都要说需要自行实现__user_setup_stackheap(),其实这里我们可以看出来高版本的已经不需要了,很智能啊。在这以前我一直在用IAR,现在我算是知道使用ARM的工具可以获取到更多原滋原味的支持文档,对开发尤其是裸机开发帮助很大。

我的测试程序如下:
  1.        
  2. /**
  3. * @brief  malloc_test
  4. * @note   内存分配测试
  5. * @param  none
  6. * @retval none
  7. */
  8. void malloc_test(void)
  9. {
  10.         int *ptr1;
  11.         int *ptr2;
  12.         int *ptr3;
  13.         int *ptr4;
  14.         OS_ALLOC_SR();
  15.        
  16.     ptr1 = (int *)malloc(sizeof(int) * 10);  
  17.     if (ptr1) {
  18.                 OS_ENTER_CRITICAL();
  19.         DEBUG1("Prt1 alloc at address: %x", (unsigned int)ptr1);  
  20.                 OS_EXIT_CRITICAL();
  21.         } else {
  22.         DEBUG0("No enough memory!");  
  23.         }
  24.     free(ptr1);
  25.         DEBUG0("Ptr1 free!");  
  26.        
  27.         ptr2 = (int *)malloc(sizeof(int) * 20);  
  28.     if (ptr2) {
  29.                 OS_ENTER_CRITICAL();
  30.         DEBUG1("Prt2 alloc at address: %x", (unsigned int)ptr2);  
  31.                 OS_EXIT_CRITICAL();
  32.         } else {
  33.         DEBUG0("No enough memory!");  
  34.         }
  35.     free(ptr2);
  36.         DEBUG0("Ptr2 free!");  

  37.        
  38.         ptr3 = (int *)malloc(sizeof(int) * 10);  
  39.     if (ptr3) {
  40.                 OS_ENTER_CRITICAL();
  41.         DEBUG1("Prt3 alloc at address: %x", (unsigned int)ptr3);  
  42.                 OS_EXIT_CRITICAL();
  43.         } else {
  44.         DEBUG0("No enough memory!");  
  45.         }
  46.        
  47.        
  48.         ptr4 = (int *)malloc(sizeof(int) * 20);  
  49.     if (ptr4) {
  50.                 OS_ENTER_CRITICAL();
  51.         DEBUG1("Ptr4 alloc at address: %x", (unsigned int)ptr4);  
  52.                 OS_EXIT_CRITICAL();
  53.         } else {
  54.         DEBUG0("No enough memory!");  
  55.         }
  56.         free(ptr3);
  57.     free(ptr4);
  58.         DEBUG0("Ptr3 free!");
  59.         DEBUG0("Ptr4 free!");  

  60. }
复制代码
这里有一点疑问,还没解决,就是那个长的printf需要在临界区,不然会abort异常。我尝试使用短的,没有问题,为了调试,这里加上临界区保护,感觉是模式设置有问题,有可能是MMU那块,不一定。printf我使用微型库自带的或者我自己的开源的都是一样,跑一下就直接异常了。

我的调试结果,可以看出地址是我们指定Heap的0x030200000,两种方式都可以。

这篇帖子主要用于告诉大家如何使用MDK开发工具,想了解细节的东西,直接去看ARM的文档,一定能找到你的答案。
有问题希望大家一起讨论。


点赞 关注(2)
个人签名电工

回复
举报

2144

帖子

3

TA的资源

五彩晶圆(中级)

沙发
 
大家有问题可以跟帖交流,裸机开发必备的帮助文档
 
个人签名电工
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表