STM32的RAM的绝对地址定位,以及初始化不为0

MDK帮助文档里面写的还是比较清楚:


__attribute__((at(address))) variable attribute

__attribute__((at(address))) variable attribute

This variable attribute enables you to specify the absolute address of a variable.

The variable is placed in its own section, and the section containing the variable is given an appropriate type by the compiler:

  • Read-only variables are placed in a section of type RO.

  • Initialized read-write variables are placed in a section of type RW.

    Variables explicitly initialized to zero are placed in:

    • A section of type ZI in RVCT 4.0 and later.

    • A section of type RW (not ZI) in RVCT 3.1 and earlier. Such variables are not candidates for the ZI-to-RW optimization of the compiler.

  • Uninitialized variables are placed in a section of type ZI.

Show/hideSyntax

__attribute__((at(address)))

where:

address

is the desired address of the variable.

Show/hideRestrictions

The linker is not always able to place sections produced by the at variable attribute.

The compiler faults use of the at attribute when it is used on declarations with incomplete types.

Show/hideErrors

The linker gives an error message if it is not possible to place a section at a specified address.

Show/hideExamples

const int x1 __attribute__((at(0x10000))) = 10; /* RO */
int x2 __attribute__((at(0x12000))) = 10; /* RW */
int x3 __attribute__((at(0x14000))) = 0; /* RVCT 3.1 and earlier: RW.
                                          * RVCT 4.0 and later: ZI. */
int x4 __attribute__((at(0x16000))); /* ZI */


=====================================================================

关于RAM初始化不为0

Noinit selects areas that should be excluded from zero initialization。

NoInitSpecifies areas that should be excluded from zero initialization.

NOINIT

Indicates that the data section is uninitialized, or initialized to zero. It contains only space reservation directives SPACE or DCB, DCD, DCDU, DCQ, DCQU, DCW, or DCWU with initialized values of zero. You can decide at link time whether an area is uninitialized or zero initialized.


=====================================

NOINIT的资料网上非常少。看样子大家用的不多啊。

MDK的target界面有个选项NOINIT ,看样子只能靠这个设置了。还是比较靠谱。

### STM32 RAM初始化问题及解决方案 在嵌入式开发中,STM32微控制器的RAM通常会在系统启动时被自动清零。然而,在某些特殊应用场景下,可能希望保留RAM中的数据而不对其进行初始化。以下是关于如何解决STM32 RAM初始化问题的具体分析和方案。 #### 1. 默认行为解析 在基于GNU工具链(如GCC)构建的项目中,默认情况下,链接脚本会将`.bss`段的内容设置为全零。这是因为标准C库的行为是在程序启动阶段对全局变量和静态变量所在的`.bss`段进行清零操作[^3]。如果需要跳过这一默认行为,则可以通过修改链接脚本来实现自定义配置。 #### 2. 修改链接脚本以禁用BSS区清零 为了防止RAM区域内的数据被清除,可以在链接器命令文件(通常是`.ld`文件)中加入特殊的处理逻辑: - **创建新的内存分区** 定义一个新的内存区域用于放置不需要初始化的数据,并指定该区域不会参与常规的初始化流程。例如: ```plaintext MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K SRAM_NOINIT (rw) : ORIGIN = 0x20000000, LENGTH = 64K /* 假设SRAM大小 */ } ``` - **分配特定段至新内存区域** 使用`NOLOAD`属性来告诉链接器忽略对此部分内存的加载动作: ```plaintext .noinit : { *(.noinit) } > SRAM_NOINIT ``` 此处定义了一个名为`.noinit`的新段,任何标记为此段的对象都不会经历初始值填充的过程。 #### 3. C源码层面的操作 当开发者希望通过编程手段控制哪些数据应保持其原始状态而非被重置成零时,可利用编译器扩展功能完成此目标。具体做法如下所示: - 对于那些期望维持原有数值不变的变量,需显式标注它们所属的位置。比如采用`__attribute__((section(".noinit")))`语法将其关联到之前设定好的`.noinit`节里去。 ```c int persistent_data __attribute__((section(".noinit"))); // 不会被初始化 ``` - 如果存在多个这样的持久化变量或者数组结构体实例的话,则建议集中管理起来形成统一命名空间以便后续维护更加方便简洁明了一些列操作之后再继续往下看其他相关内容吧 #### 4. 测试验证效果 最后一步非常重要——即确认上述改动确实达到了预期目的。这可通过打印调试信息观察实际运行状况;也可以借助仿真环境下的断点技术逐条检查各关键位置的状态变化趋势从而得出最终结论。 ```c #include <stdio.h> int main() { static int test_var __attribute__((section(".noinit"))); printf("Value of non-initialized variable: %d\n", test_var); while(1); } ``` 以上代码片段展示了如何检测一个未经初始化的静态整型数值得当前取值范围是否符合设计初衷的要求。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值