中科蓝讯 data 区溢出的解决方法示例

    哈喽,大家好。

    本文基于中科蓝讯 AB5301A 中 data 区溢出 3316 字节的情况,介绍解决溢出的一般解决方法和注意事项。 建议先看博文《中科蓝讯 ram.ld 文件浅析》。

溢出的原因,输出区 .bss 的所有输入段大于输出区 .bss 链接到的 data 区就会发生溢出,如下图所示:

   

    一、SECTIONS 命令内的区不是按地址大小自上而下链接,而是按先后链接的,后面的区若有与前面的区同名的段,将不再链接,此点可以作为解决 data 区溢出的一种方法

    1、首先在 MEMORY 命令中把 data 区的大小改大到编译不会再提示溢出,此处由 25k 改为 29k(data 区溢出 3316 字节,大小在 3k 到 4k 之间,因此增加 4k。 注意,最后需要改回 25k):
    
    

    2、查看 map.txt 文件中,输出节 .bss 的内存分配情况:
    

    段 .dac_obuf (这个段在 ram.ld 文件的 SECTIONS 命令中的输出区 .bss中可找到)的大小为 0x1600,即为 5632 字节,大于溢出的 3316 字节,那么将该段移到前面的其他区先链接,输出节 .bss 就不会再为该段开辟空间,溢出问题就可以得到解决;

    3、查看 map.txt 文件中 SECTIONS 命令中哪个区仍有大于或等于段 .dac_obuf 的空间:
    

    如上图,通过 __comm_end 在 map.txt 文件中可直接定位 comm 区链接后的最终地址为 0x2694c; comm 区最大地址为 0x20000 + 34k = 0x28800; comm 区剩余空间 = 0x28800 – 0x2694c = 0x1EB4 = 7680 字节,大于段 .dac_obuf 的空间; 因此可以把输出区 .bss 的段 .dac_obuf 放到 comm区,其操作方法和链接结果如下图所示,
    
    
    
    

    查看 map.txt 链接文件,可见输出区 .bss 中的段 .dac_obuf 没有再开辟空间,当然最好要把输出区 .bss 中的段 .dac_obuf 注释掉; 注意,最后 data 区的大小要改回 25k。

 

    二、此方法和方法一类似,实际是将溢出区的某个或某些目标文件的段(这个或这些输入节要大于或等于溢出的字节大小)链接到 SECTIONS 命令中溢出区前面的区

    1、和法一中的步骤 1 相同;

    2、查看 map.txt 文件中,输出区 .bss 的内存分配情况,查看哪些目标文件的段可以链接到 SECTIONS 命令中溢出区前面的区:
    

    目标文件 ext_plc.o 的段 .bss.plc_data、目标文件 btstack_memory.o 的段 .bss(注意,有 .bss 段的目标文件有多个,此处只是把目标文件 btstack_memory.o 的段 .bss 做移动)、目标文件btstack_memory.o 的段 .bss.bb.conn 总大小 = 0x828 + 0x19c + 0x40c = 0xDD0 = 3536 字节,大于 3316(0xcf4)字节;

    3、由法一的步骤 3 已知 comm 区剩余 7680 字节,那么可以将步骤2中描述的三个段放到 comm 区,并把 data 区的大小改回 25k:
    

    举例说明一下圈中的语句意义与输出区 .comm 语句意义的差异。

    *(.data*) 指将所有目标文件的段 .data 输入到输出区 .comm,“>”使输出区 .comm 链接到内存区 .comm,括号里的 * 号指段 .data 还可以其后延展名字生成小段,这些小段占用的内存都是包含在段 .data 里的。

    *btstack_memory.o(.bss.bb.conn) 指将目标文件 btstack_memory.o 的段 .bss.bb.conn 输入到输出区 .comm; 这里相当于指定了某个目标文件。 所以也可以如下改:


    

    *btstack_memory.o(.bss*) 指将目标文件 btstack_memory.o 段 .bss 包含的所有小段输入到输出区 .comm。 可查看链接结果来验证。

   

    4、链接结果:
    

    输出区 .comm 多了步骤 2 中描述的三个段;
    

    前面描述的三个段成功放到 SECTIONS 命令中的前面的区,则在 map.txt 文件中可见输出区 .bss 中的地址 0x14068 变成了目标文件 btstack_tws.o 的段 .bss 的起始地址;

    5、编译结果:

   

 

    三、区复用解决 data 区溢出

    若某个区代码在同一个程序周期内不会与自添加的目标文件代码在同一时序同时运行,则可以把溢出代码的目标文件的段复用到其他区; 本示例以复用到 cram 区做示例;

    1、放大 data 区,查看 map.txt 文件可见:
    

    目标文件 tmf882x_example_simple.o 的 .bss 段大小为 0x28e0 = 10464 字节,大于溢出的 3316 字节,又小于 cram 的 18k = 18432 字节,因此可以复用到 cram;

    2、复用的输出区 .cram_bss 要放在输出区 .bss 前 :

    .cram_bss 输出区的名字是任意起的。

 

    四、关闭用不到的功能,减小 data 区内容

    如不需用到 TWS 功能,可把宏 BT_TWS_EN 关掉,可省一些 data 区空间,当然 TWS 功能关闭,TWS 功能占用其它区的空间也会被释放。 此方法释放的空间较小。

 

    五、注意事项

    1、data 区的代码或数据可放 comm 区,但 comm 区的代码不能轻易放到 data 区,因为 comm 区的代码对实时性要求较高。 comm 区和 bcomm 区性质一样,comm 区溢出的内容可以放到 bcomm 区,反之同理。

    2、复用 RAM 来解决溢出问题,务必确认在同一个程序周期内,复用的代码在同一时序不会同时进行。

    本文的介绍就到这里,希望对大家有所帮助。 如有错误欢迎大家批评指正。 如果大家还有什么其他的问题或者功能想要询问,亦可以在评论区中提出,可以共同探讨,一起进步。

 

参考文档:

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

链接:中科蓝讯蓝牙:RAM使用,ram.ld文件和map.txt文件的查看_ld文件怎么看_nunu1010的博客-CSDN博客

2、中科蓝讯蓝皮书《芯片框架简述》

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论