【中科蓝讯BT896X】app.lst、ram.ld、map.txt文件的分析和使用

【中科蓝讯BT896X】app.lst、ram.ld、map.txt文件的分析和使用

测试SDK版本:《SDK_BT896X_S12685_20240314》



前言

要熟悉蓝讯开发的app.lst、ram.ld、map.txt文件,建议先仔细研读下面几篇博客,可以对蓝讯开发有一个较为全面的认识:

  1. 中科蓝讯蓝牙: 芯片框架简述
  2. 中科蓝讯蓝牙: 公共区(com区)空间不够一般优化方法
  3. 中科蓝讯蓝牙:RAM使用,ram.ld文件和map.txt文件的查看

一、app.lst、ram.ld、map.txt文件介绍

1.1 app.lst文件

app.lst 文件是编译过程中的中间输出文件,通常由编译器生成,它包含了汇编级别的详细信息,如每行源代码对应的机器指令、地址、符号信息等。在RISC-V架构下,使用RV32-Toolchain编译应用程序时,如果启用了生成清单文件(listing file)的选项,就会产出app.lst这样的文件。

要创建并查看app.lst,你需要遵循以下步骤:

打开CodeBlock,并导入或创建一个新的项目。
将你的源代码文件(例如:app.c)添加到该项目中。
在项目设置中,确保编译器设置正确,并启用生成清单文件的选项。这可能位于“构建目标”> “全局选项”> “C/C++”类别下的相应配置。
编译你的项目。点击“构建”或“编译并运行”,CodeBlock将调用RV32-Toolchain进行编译。
如果编译成功,app.lst文件将在你的项目目录下生成,与你的.o对象文件和最终的.dcf文件在同一位置。

1.2 ram.ld文件

ram.ld 是一种链接脚本(Linker Script),用于在构建嵌入式系统时定义内存布局和映射。它通常由GNU ld或者类似的链接器使用,用来指导编译器如何将编译后的对象文件组织到最终的可执行文件中,特别是在资源有限的微控制器如ARM Cortex-M系列芯片上。

在中科蓝讯的设备中,ram.ld 可能定义了如下内容:

  • RAM 区域的开始地址和大小,比如 .data 和 .bss 段的位置。
  • FLASH 区域的开始地址和大小,用于存放程序代码和初始化数据。
  • 有可能还包括中断向量表(Vector Table)的位置。
  • 可能会指定某些段是否应该在加载时初始化或者是在运行时由硬件自动扩展。

以下是一个简化的ram.ld例子:

MEMORY {
    RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
    FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
}

SECTIONS {
    .vector_table :
        {
            *(.vectors)
        } >FLASH

    .text :
        {
            *(.text*)
            *(.rodata*)
        } >FLASH

    .data :
        {
            *(.data*)
        } AT>FLASH ALIGH_TO(4)
        {
            _sidata = LOADADDR(.data);
            *(.data*)
        } >RAM

    .bss :
        {
            _sbss = .;
            *(.bss*)
            _ebss = .;
        } >RAM
}

在这个例子中:

  • MEMORY 定义了两个内存区域,一个是RAM,另一个是FLASH。
  • SECTIONS 部分定义了各个段(如.text, .data, .bss)应该如何被放置在内存中。

ram.ld文件是用于定义RAM空间分配的规则,它指导链接器如何在内存中安排程序和数据。在530X标准SDK的例子中,MEMORY部分列出了所有可用的RAM区域。例如,这个特定的530X芯片有总共156.4KB的RAM,不包括内部的CACHE。

在ram.ld中,不同的RAM区域有不同的用途,比如:

  • comm和bcomm区是公共区,用于存放用户代码和数据,它们是上电时加载并且一直驻留在RAM中的。
  • stack区通常用于栈操作,长度为1K。
  • data段包含了初始化的数据。
  • heap段则用于动态内存分配(尽管蓝讯SDK可能不支持malloc/free)。
  • aram, bram, cram, dram, eram, 和 fram可能是不同类型的RAM复用方式。

优化公共区的方法包括检查512字节的对齐是否必要,查看map.txt文件找出占用空间的代码,以及尝试将部分代码移动到其他未充分利用的RAM区域。

1.3 map.txt文件

map.txt 文件是软件开发过程中的一种映射文件,它通常由编译器或链接器生成,详细列出了编译后的程序各个部分在内存中的分布情况。在中科蓝讯的蓝牙方案中,map.txt 文件对于分析和优化COM区的空间使用非常关键。你可以通过以下步骤使用和分析这个文件:

  1. 打开 map.txt 文件:使用文本编辑器打开此文件,它将列出程序的所有段(如.text, .data, .bss等)以及它们的地址和大小。
  2. 查找占用空间的函数或模块:在文件中搜索关键字,例如“com”,“public”,或者特定函数名,找出占用com区空间的部分。
  3. 分析内存分配:检查各个段的起始地址和长度,了解哪部分代码占据了最多的RAM空间。
  4. 识别可优化部分:确定哪些函数或模块不是必需的,或者可以通过优化减少其大小。
  5. 调整代码:根据分析结果,禁用不必要的宏定义,删除冗余代码,或者将某些部分移到其他区域(如BANK区),然后重新编译。
  6. 验证优化效果:重新生成 map.txt 文件,对比优化前后com区的占用变化。

二、通过 ram.ld 和 map.txt文件,查看代码在CPU Ram中的占用情况

下面,我们通过一个实例进行分析:
请添加图片描述
例如我们灯效代码段命名为 lamp_rgb,下一步,在LD文件中,将lamp_rgb段添加到ram的一段空间内:请添加图片描述
可以看到,我将lamp_rgb段放到了 Ram的comm1段,让灯效上电时加载后,一直驻留在RAM中。
然后我们在LD文件中搜索 comm1这个ram的公共段,查看这个comm1的空间分配情况:请添加图片描述
从上图我们可以看出,comm1段在RAM中的起始地址为 0x24000,占用大小为32kByte(16进制:0x8000),所以,可用范围:0x24000~0x2c000
在清楚上面的信息后,我们就可以通过map文件查看代码在RAM中的使用情况了
如下图,我们先在map文件中搜索comm1,找到comm1段,再找到comm1段下的lamp_rgb段,当然,你也可以直接搜索lamp_rgb段:请添加图片描述
请添加图片描述
以 .lamp_rgb.eff段为例:
可以看到,目前 .lamp_rgb.eff段占用RAM大小为0x2194字节(8K+Byte)

三、通过 分析 map.txt文件,节省用户代码对RAM空间的消耗

有了前几个小节对RAM空间分布的认识,我们试着优化下代码,看能不能省点RAM空间出来:
在这里插入图片描述
如上图,左边是.lamp_rgb.eff段占用RAM大小为0x2194字节的代码,在这个灯效模式中,所有用到的变量都是单独初始化,我们直接改用memset函数一次性初始化,然后再编译看看map文件有什么不同:请添加图片描述
从上面对比数据可知,优化后的代码.lamp_rgb.eff段占用0x2178字节,较原来省了0x16字节的空间。

四、分析 map.txt文件中的字节对齐

例如前面lamp_rgb段末尾出现的 0x000000000002be00 . = ALIGN (0x200)

在计算机编程和链接器脚本中,0x000000000002be00 是一个内存地址,而 . = ALIGN (0x200) 是用于对齐内存位置的指令。这里是对这段语句的一个解释:

  • 0x000000000002be00: 这是一个十六进制数,表示当前的数据或代码将被放置在内存中的这个位置开始。
  • . = ALIGN (0x200): 这条指令意味着当前的段(通常是数据段或者代码段)将会被调整到下一个 0x200(即 512 字节)的边界。这意味着如果当前地址不是 512 字节的倍数,它会被增加到最近的512字节倍数的位置。这样做通常是为了优化处理器的性能,因为某些处理器在访问对齐的内存时效率更高。

因此,如果当前的地址 0x000000000002be00 不是 512 字节的倍数,那么. = ALIGN (0x200) 将会把地址向后调整到下一个 512 字节的边界。

请添加图片描述

五、RAM空间溢出分析

如下图,是编译时RAM爆空间后的错误信息提示:
请添加图片描述
可以看到,提示说.comm1段溢出了512字节,让我们来看看map文件的描述:
请添加图片描述
可以看到,.comm1段的大小已经到0x2c200 byte了,结合前面内容得知,comm1段最大0x2c000字节,现在超了0x200字节,刚好是512字节。
解决办法如下:
1、结合用户代码段(例如lamp_rgb段)的占用大小,看看有无其它RAM段可以放得下的,放到其它空间足够的段。
2、优化代码,将没用到的变量、函数等删除或注释,换更省RAM空间的写法。

六、代码优化 省RAM空间

请添加图片描述
未完待续~~

七、通过app.lst文件查看程序运行流程

芯片启动流程:
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

### 中科蓝讯智能手表芯片方案 #### 芯片选型 中科蓝讯提供了多款适用于智能手表的芯片型号,其中最新的选型表《中科蓝讯芯片选型表2023》涵盖了多种高性能芯片,例如 AB212B、AB135C AB2016A 等[^1]。这些芯片不仅具备低功耗特性,还能够满足智能手表对于性能功能的需求。 #### 主流方案介绍 基于中科蓝讯 BT8958B2 的 Smart Watch 方案被广泛应用于智能手表领域。此方案支持多项核心功能,包括但不限于心率检测、计步统计、抬腕唤醒等健康监测功能;同时还支持表盘自定义切换、消息提醒推送、蓝牙通话以及本地音乐播放等功能[^2]。这使得搭载该芯片的手表能够在日常生活中为用户提供全方位的服务体验。 #### 应用场景扩展 除了基础的功能外,在智能家居设备方面,通过集成中科蓝讯蓝牙模块,还可以实现与家庭其他智能终端之间的联动操作,比如控制灯光亮度调节或者开关状态调整等等[^3]。这种跨平台互联互通的能力进一步增强了产品的实用价值。 #### 开发资料准备 为了更好地理解应用上述提到的各种特性优势,在实际开发过程中还需要深入学习一些关键技术文档。其中包括 `app.lst` 文件用于描述应用程序结构布局;`ram.ld` 则是用来配置内存分配情况;而 `map.txt` 提供了详细的链接映射信息以便于调试优化程序性能等问题[^4]。 ```python # 示例代码片段展示如何初始化一个简单的BLE服务 (假设使用Python模拟环境) import bluetooth def initialize_ble_service(): server_sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM ) port = 1 server_sock.bind(("",port)) server_sock.listen(1) initialize_ble_service() print("Waiting for connection on RFCOMM channel %d" % port) ``` 以上就是关于中科蓝讯智能手表相关的信息概览及其背后所依托的技术支撑体系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值