我正在使用 IAR 工具集,设备是 MKE02Z64。我有几个常量值想放在闪存中(如果可能的话)以释放 RAM,但我找不到用 IAR 工具实现的方法。
最初,我使用的只是一个相当标准的:const uint16_t foobar;
这样一来,foobar 仍然处于数据内存中。我接下来试了试(根据我在网上找到的资料):const volatile uint16_t foobar @"FLASH";
这没有产生任何错误或警告,但 foobar 仍在数据内存中,而不是代码内存中。
能做到吗?
谢谢!
Great explanation of how `const` works when stored in flash memory, especially for embedded systems where every byte matters. It’s interesting how efficient memory placement can tighten performance without changing logic. I recently explored similar structured info on Cass County Justice while researching data storage and organization best practices. Posts like this are helpful for bridging theory with real-world application.
很好地解释了 “const” 在闪存中存储时的工作原理,特别是对于每个字节都很重要的嵌入式系统。有趣的是,在不改变逻辑的情况下,高效的内存布局可以提高性能。最近,我在研究数据存储和组织的最佳实践时,在卡斯县司法局 探索了类似的结构化信息。这样的帖子有助于将理论与实际应用相结合。
看来 Mark Butcher 是对的--我查看了链接器的输出,实际上,const 存在闪存中。让我感到不解的是,生成的映射文件显示 const 为"Data" ,而不是"Code" ,我以为它说的是内存部分,而不是实际的数据类型。
感谢您的回复!
嗨,戴夫、
请查看以下示例,了解如何将 Const 置于 IAR IDE 软件的 Flash 地址。
在 *.icf 文件中定义一个 [.我的参数] 部分的起始地址,并将该部分置于 ROM 内存中:
定义符号 __region_FlexNVM_start__ = 0x10000000;
置于 mem:__region_FlexNVM_start__ { 只读部分 .myparameter};
在代码文件 (*.c) 中,将数据放入该部分:
const char parameter1[16] @".myparameter"= {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};
IAR 在专用地址中放置变量的另一种方法:
#pragma location=0x3000
const int test1 = 1;
const int test2 @ 0x3004 = 2;
然后,我在地图文件中找到了以下结果:
test1 0x00003000 0x4 数据 GB hello_world.o[1]
test2 0x00003004 0x4 数据 GB hello_world.o[1]
如果我使用以下代码
#pragma location=0x3000
const int test1 = 1;
const int test2 = 2;
然后只把 test1 变量放在 0x3000,把 test2 放在另一个地方,映射结果如下:
test1 0x00003000 0x4 数据 GB hello_world.o[1]
test2 0x000016ec 0x4 数据 GB hello_world.o[1]
将变量放入专用地址的另一种方法:
在 .icf文件定义的内存区域,如
定义符号 __ICFEDIT_region_ROM_DATA_start__ = 0x0003F800;
定义符号 __ICFEDIT_region_ROM_DATA_end__ = 0x0003FFFF;
定义区域 ROM_DATA_region = mem:[从 __ICFEDIT_region_ROM_DATA_start__ to __ICFEDIT_region_ROM_DATA_end__];
置于 ROM_region { 只读,代码块重定位};
在 C 代码中,例如
#define NVM_DATA _Pragma("location=\"NVM_DATA\"" )
NVM_DATA 常量 int test1 = 1;
NVM_DATA const int test2 = 2;
_Pragma("location=\"NVM_DATA\"" ) 与 #pragma location="NVM_DATA 相同。"
希望能有所帮助。
祝您愉快,
、
马辉
-----------------------------------------------------------------------------------------------------------------------
注:如果本帖回答了您的问题,请点击正确答案按钮。Thank you!
-----------------------------------------------------------------------------------------------------------------------
你好,戴夫
@"FLASH" 仅用于 volatile 常量。
IAR(默认)行为是将常量(全局和静态)放入 Flash,尽管严格来说,const 关键字意味着该变量具有只读属性,而不是它位于特定的内存区域中(尽管嵌入式系统通常会像这样工作是有感知)。
例如
static const unsigned char usb_language_string[] = {4, DESCRIPTOR_TYPE_STRING, LITTLE_SHORT_WORD_BYTES(UNICODE_LANGUAGE_INDEX)};
静态常量 unsigned char manufacturer_str[] = {10, DESCRIPTOR_TYPE_STRING, 'M',0, 'a',0, 'n',0, 'u',0};
static 常量 unsigned char product_str[] = {16, DESCRIPTOR_TYPE_STRING, 'M',0, 'y',0, ' ',0, 'P',0, 'r',0, 'o',0, 'd',0};
静态常量 unsigned char serial_number_str[] = {10, DESCRIPTOR_TYPE_STRING, '0',0, '0',0, '0',0, '1',0};
static const unsigned char config_str[] = {10, DESCRIPTOR_TYPE_STRING, 'C',0, 'o',0, 'n',0, 'f',0};
static 常量 unsigned char interface_str[] = {8, DESCRIPTOR_TYPE_STRING, 'I',0, 'n',0, 't',0};
静态常量无符号 char *ucStringTable[] = {usb_language_strring, manufacturer_str, product_str, serial_number_str, config_str, interface_str};
地图显示
usb_language_string 0x00003d24
manufacturer_str 0x00003d28
product_str 0x00003d34
serial_number_str 0x00003d44
config_str 0x00003d50
interface_str 0x00003d5c
ucStringTable 0x1ffff11c
请注意,除了最后一个阵列外,其他阵列都放入了闪存。我无法解释为什么规则会有一些例外,而你的特殊情况可能就是这样的例外,不管是出于什么原因。
也许最好直接联系 IAR,因为我也找不到控制最后几个剩余异常的方法。幸运的是,就我所见,它只影响到极少数这类东西。
此致
Mark
Kinetis:µTasker Kinetis 支持
KE:支持 µTasker FRDM-KE02Z/支持 µTasker FRDM-KE02Z40M/支持 µTasker FRDM-KE06Z
欲获得完整的"开箱即用" Kinetis 体验并加快产品上市时间