You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

数组在内存中的存储位置咨询——基于Infineon Aurix与HighTec编译器

全局数组在Aurix单片机中的内存存储位置问题

我来帮你捋捋这个问题,你遇到的情况在嵌入式开发里挺常见的,尤其是Aurix这种内存架构比较复杂的单片机。首先先明确:全局数组和普通全局变量一样,都属于全局/静态存储类,理论上应该和你找到的全局变量a存在同一个内存区域(通常是RAM的.data段,因为你初始化了数组值),但你找不到它,大概率是这几个原因导致的:

1. 你读取的内存范围根本没包含数组的实际地址

Aurix的内存映射非常多,有PFlash、DFlash、多种RAM区域(比如PSPRAM、DSRAM、BSRAM等),不同的段(.data.bss.text)会被链接到不同的地址范围。你现在固定读取0xd0000000开始的4KB,但你的全局数组tab可能根本不在这个区间里。

排查方法:

用HighTec编译器自带的nm工具查看数组的实际地址:

nm your_program.elf | grep tab

这个命令会输出类似d0100000 D tab的结果,其中d0100000就是数组的起始地址。如果这个地址不在你读取的0xd0000000-0xd0000fff范围内,那自然找不到数组内容。

2. 编译器优化把数组“干掉”了

如果你的代码里完全没有使用过这个数组(只是声明了但没读/写任何元素),HighTec的优化选项(比如-O1及以上)会自动移除未使用的全局变量/数组,最终烧写到单片机里的程序根本没有这个数组的内容,内存里当然找不到。

解决方法:

  • 要么在代码里实际使用数组,比如加一行:
    volatile int temp = tab[2]; // 用volatile防止编译器优化掉这行代码
    
  • 要么给数组加编译器属性强制保留:
    int tab[5] __attribute__((used)) = {10,9,12,34,30};
    

3. 你找的字节序列不对(数据宽度和端序问题)

你用unsigned char逐个读取内存字节,但你的数组是int类型——在Aurix上int是32位(4字节),而且Aurix是小端模式存储。比如数组第一个元素10(十六进制0x0000000A),在内存里会按0xA → 0x00 → 0x00 → 0x00的顺序存储,第二个元素90x09 → 0x00 → 0x00 → 0x00,以此类推。

如果你只是在内存里找连续的10、9、12...单字节值,肯定找不到,因为它们被分散在每个4字节块的第一个位置,后面跟着三个0字节。

4. 内存访问权限限制

Aurix有严格的内存保护单元(MPU),如果你的代码运行的核没有权限访问数组所在的内存区域,读取到的可能是无效值或者0,看起来像是数组不存在。

排查方法:

查看编译器的链接脚本(.ld文件),确认.data段(初始化全局变量所在段)的地址范围,再对照Aurix手册里的内存保护配置,确保当前运行的核有权限读写该区域。


内容的提问来源于stack exchange,提问作者Rbn

火山引擎 最新活动