C定义变量,申请内存,初始化值位置,外部RAM和Flash的使用 总结

Part1: 初始化的变量

如下定义一个变量,定义时就初始化

int a = 0x5A;

 

在单片机内是如下操作的。

flash中没有 a, 只有 a 初始值 0x5A;

因 a 是初始化了的变量,所以变量 a 会被放在flahs的.data区域;

 

注意flash的.data区域和linker script定义的.data区域的联系及区别。

Linker script中可以将.data定义在RAM,也可以定义在flash,可以定义在任何memory区域;

但注意linker script中定义的.data是flash .data区域的映射。

扫描二维码关注公众号,回复: 4719580 查看本文章

比如,linker script通常将.data定义在RAM中,这样一上电,会将flash中的.data区域的内容,复制到RAM中。

之后,CPU要用到或操作.data中的内容时,就在RAM中操作,处理速度就会提升很高。

Linker script将.data定义在flash也是可以工作的,但CPU读写flash的速度比RAM要低很多,所以整体处理速度就会降低。

可以先简单如下理解:

如linker script将.data定义在RAM,通电时linker script定义的.data内数据和flash .data内的数据是一样的;

但一旦掉电,RAM内就没有数据了,flash内仍保持源数据;

再次上电时,linker继续将flash中的.data复制到RAM中。

在MCU硬件中是没有linker的,所以当一上电程序启动运行是没有实际的linker电路的,那怎么复制呢?

在程序编译过程中,是有linker的。编译过程中的分配就标记在程序中了,所以运行程序时,MCU就就知道哪些内容是要复制到RAM中去执行的。

 

flash的.data区域放的什么值呢,放的就是变量的初始值,如 a 的初始值 0x5A。

 

回过头来再看C语言程序中,申请内存其实就是定义一个变量(申请一段内存就定义一个数组)。

 

Part2: 以上心得由来

在使用SMIF XIP FRAM去完成GUI emWin显示的工程中。

将显示图片的数据通过 __attribute__ ((section(".xipbuf"))) 定义到XIP FRAM内。以为这样可以将大数据量的内容放到外部RAM,实现很多图片的显示。

但是硬件运行后,屏幕显示花屏。

分析历程:要显示的pattern数据如下

要注意,这个pattern数据是一个初始化了的数组 _acClock[],

当我如上将它定义到.pattern_clock section并在linker script中将它分配的XIP区域

这些操作其实只是在XIP区域申请了一段存储空间(目前使用的FRAM,所以也就相当于申请了一段内存),申请的存储空间大小就是定义该数组时初始化的值所占的大小。这点可以在编译后的.map文件中看到

重点来了,申请的内存大小没有问题,申请的内存也可以使用,但是申请的内存内是没有这些初始化值的!

这样定义和定义那个图片被注释掉那行定义的区别就在这里,这样定义后申请到的并且后面CPU会去调用的的这段内存内的数据,不是定义的初始化值,而是FRAM内这段区域的默认值(随机)。所以会显示花屏。

看被注释掉那行 static GUI_CONST_STORAGE unsigned char _acClock [] ,这行和前面的区别在于,这个定义不仅申请了一段存储区域,而且这段存储区域的值也要保存下来(即初始化值)。这些值保存在哪呢?保存在flash中。这就是MCU默认的定义初始化变量操作,详见Part1部分。

 

因为目前XIP区域硬件连接的是FRAM,所以它只能当RAM使用,这就是为什么跑emWin例程,申请的内存部分用这里没有问题的原因。看emWin需要的内存定义:

它只是要申请一段内存,这段内存供它后续操作使用,并不需要初始值。所以这部分定义到XIP后没有问题,可以正常使用,定义如下

Part 3: 现在的问题

把图片这些有初始化的大量数据,定义到外部flash中

 

 

 

猜你喜欢

转载自blog.csdn.net/phenixyf/article/details/84942510