中科蓝讯蓝牙:RAM使用,ram.ld文件和map.txt文件的查看


1.ram.ld文件和map.txt文件的作用:

ram.ld文件:是RAM或FLASH空间分配的规则,工具链中的链接器按ram.ld中的规则分配程序或ram占用的空间。 map.txt 文件: 最终链接的结果可以在map.txt中查看,程序或各种buf占用的ram,在map.txt中可以找到 (static 函数或变量除外)

注意: 1.目前蓝讯所有SDK均不支持malloc/free之类的RAM动态分配。RAM复用可以在ld文件中定义来实现。 2.基本上所有RAM均可以放程序(如comm或bcomm),也可以放数据(如a / b / c / d / e /fram ,stack ,data, heap)

2. ram.ld文件 MEMORY

下面可以来看看ram.ld文件中的内容(以530X标准SDK为例) 在MEMORY中,可以看到所有RAM的的大致分配。(内部程序CACHE和数据CACHE 没有列到这里)

从MEMORY中可以看到:530X所有的RAM一共有 34+8+1+25+12+16+24+18+12+2.5+4 = 156.4K (不包括cache,内部有几十K的cache,先不分析)

3.flash区

首先来看flash区:(函数地址从__base+512也就是从0x10000200开始) 如果函数定义时,未用AT指定的段名,均放到flash区。由于comm区有限,大部份代码均放到flash区。flash主要存放代码及常量及各种资源文件(如提示音,EQ参数)

为了方便评估每个模块用了多少代码空间,建议放在flash区中的代码均要用AT指定,放到text中的某个段(按模块划分,(.text*),这里的*表示任意字符),如:

关于flash区和com区的定义及使用,可以查看如下链接

下面描述各RAM的使用情况:

4. comm (34K) 公共区:

.comm (34K) 公共区:(0x20000 到 0x20000+34K),也就是【0x20000,0x28800】

上电后公共区代码会从flash加载进来,整个程序生命周期内,comm区的代码均驻留在ram中,主要存放中断及各种中断检测代码,或一些对运行时间要求比较高的代码(运行时省掉了从falsh加载代码的时间)。当然也可以存放数据。 在 SECTIONS中,可以看到如下的段均放到comm区内。

其中 如(.com_text*),后面的 * 表示 任意符号,如(.com_text.bsp.key) 也在(.com_text*)段内 放入comm区的函数,需要在函数前增加 "AT(comm区中的段名)", 如 AT(.com_text.bsp.key)

可以在map.txt文件中看到,bsp_key_process在comm区[0x20000,0x28800]之中

当然,数据区也可以放到RAM中,只需要在定义时AT到comm区中:

在map.txt文件中可以看到,test_u8和TestBuf均在[0x20000,0x28800]的公共区中

 5.bcomm区:

和comm区类似, bcomm这里指蓝牙专用的com区,也是上电时程序就加载进来,如果不用到蓝牙,可以随便使用该区域

6.stack区(长度为1K):

栈,主要用于函数调用时,保存调用者当前的运行环境,当被调函数执行完成后,从stack中恢复调用者函数的运行环境并继续执行下去。 这里的栈只有1K,所以要避免函数中定义大的局部buf,当局部buf接近或超过栈大小时,会引起栈爆掉,导致各种死机。

 7.data段:

存放全局变量或数组,如,定义一个,当没有对TestBuf指定段时,默认是放到data段中 [0x1C00,0x8000]

当data区的数据空间爆后,如果comm区还有空间,经常可以把data区的一些buf移到comm区中,见comm区章节存放变量及buf数组示例

8.heap 段

系统用到,这里暂时不做分析。

9.aram,bram,cram,dram,eram,fram。RAM复用方法

这些ram主要用于存放数据(当然也可以手动加载代码到这些ram中运行)。 具体这些ram的作用,可以在ld文件 中查看,也可以仿照ld文件中的做法,实现ram的复用。 如下面的dram, 这里就复用来做各中解码用到的buf, 由于同一时刻,不会同时做多种解码,所以这里可以复用 总结:同一时序不会同时用到的RAM,就可以拿来做复用

上面程序中的 .= 0x3000表示从__dram_vma到0x3000的偏移,当dram中段数据总量超过了0x3000,编译就会报错。 这种用法ld文件中很常见,如下面的*(.rec.sco)这段buf就限制在了

(__dram_vma)到 (__dram_vma+0x1400)这段地址内,如果*(.rec.sco)这段容量超过了0x1400,程序就会报错

通过这种对buf的限制,可以实现更多精细化的复用 当然,一个buf要定义到*(.rec.sco)中,只需要定义时增加AT命令即可,如: u8 test_buf[100] AT*(.rec.sco)

//————————————————————————-

bram: 蓝牙后台(蓝牙后台代码或数据会加载到此RAM中运行),当不做蓝牙后台时,可用于各种数据缓存如,复用于做karaok混响,变速不变调(stretch)数据区

//————————————————————————-

cram:复用有点多,这里暂列举几个: flac解码,upd或串口升级代码,fcc测试缓存,fota无线升级,wma解码,mp3压缩等

剩下的eram/fram可以查看ld文件 ,这里不再细述。

//————————————————————————-

在ram.ld文件中,还有大量如下使用

这种用法,是SDK内部加载代码用的,用于一些对时效性要求高的代码。 如这里在sbc解码或mp3解码时,可以把这些代码一次性加载到RAM中运行,在解码周期内,不会释放,解码模式完成后,才释放,相当于动态增加了com区,节约解码时间。

//————————————————————————-

这部份相当于是 comm和bcomm区在flash中的地址和实际ram中的地址,加载com区时会用到

实际在,在内部加载com区是memcpy直接把代码从flash中拷贝到ram中实现的 memcpy(&__comm_vma, &__comm_lma, (u32)&__comm_size); //Load COMM memcpy(&__bcomm_vma, &__bcomm_lma, (u32)&__bcomm_size); //Load BTCOMM

//————————————————————————-

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/290772.html

(0)
上一篇 2022年10月8日
下一篇 2022年10月8日

相关推荐

发表回复

登录后才能评论