在 MDK (Keil MDK) 中,__no_init 关键字用于声明不需要初始化的变量。这通常用于保留特定内存区域的内容,例如在复位后保留某些变量的值。 要自动分配变量地址,你可以使用链接器脚本(Scatter File)来定义内存区域,不用手动指定地址。:
1. 创建或修改链接器脚本: 在你的项目中创建一个 .sct 文件(如果还没有的话)。例如,exit.sct。
2.在链接器脚本中定义内存区域:
LR_IROM1 0x08000000 0x00080000 { ; load region size_region ER_IROM1 0x08000000 0x00080000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x20000000 UNINIT 0x00000100 { ;no init section *(NoInit) } RW_IRAM2 0x20000100 0x0000FFF0 { ;all other rw data .ANY(+RW +ZI) } }
3.修改变量声明: 将 __no_init 变量放在一个特定的段中:
使用 Arm Compiler 5 时,请将 zero_init 属性添加到变量中,以防止优化。这会将变量保留为不会初始化的 ZI 数据。
使用 Arm 编译器 6 时,将部分名称“NoInit”重命名为“.bss”。NoInit“的这会在 ZI 节中创建变量,从而阻止初始化。
// Arm Compiler 5 unsigned long NI_longVar __attribute__( ( section( "NoInit"),zero_init) ) ; // Arm Compiler 6 unsigned long NI_longVar __attribute__( ( section( ".bss.NoInit")) ) ; //also modify one line of the scatterfile from: // *(NoInit) //to: // *(.bss.NoInit) 也可以使用我如下这种定义,方便快捷 #define __no_init __attribute__( ( section( "NoInit"),zero_init) ) __no_init uint8_t g_noInitTest ;
4.在 MDK 项目设置中:
转到 “Project” -> “Options for Target” -> “Linker” 标签
在 “Scatter File” 字段中,选择你创建的 .sct 文件
这样,链接器会自动将 g_isSoftRst 变量放置在 NO_INIT 区域,而不需要手动指定地址。
注意:确保 NO_INIT 区域的大小足够容纳所有 __no_init 变量。你可以根据需要调整其大小和起始地址。 通过这种方法,你可以让链接器自动管理内存分配,同时仍然保持 __no_init 变量的特性。这样做更灵活,也更容易维护,因为你不需要手动跟踪和分配地址。
参考资料:
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
评论(0)