不能使用IAR ARM编译器强制function表到特定地址

我有一个像这样定义的函数表类型

typedef struct { uint16_t majorRevision; uint16_t minorRevision; uint8_t (*CommInit)(void *); uint8_t (*CommDeInit)(void); uint16_t (*Write)(uint8_t *, uint16_t); uint16_t (*Read)(uint8_t *, uint16_t); uint8_t (*Attached)(void); uint8_t (*ExitApp)(uint8_t); uint8_t (*Jump)(uint32_t address); uint16_t (*GetCRC)(uint8_t*, uint32_t); int (*Encrypt)(uint8_t *, uint32_t); int (*Decrypt)(uint8_t *, uint32_t); uint8_t (*Reset)(void); uint32_t (*GetTickCount)(void); void (*Sleep)(uint32_t); uint8_t (*ReadASCIIByte)(void); uint16_t (*ReadASCIIWord)(void); uint32_t (*ReadASCIIDWord)(void); void (*WriteASCIIByte)(uint8_t); void (*WriteASCIIWord)(uint16_t); void (*WriteASCIIDWord)(uint32_t); void (*PutChar)(uint8_t); uint8_t (*GetChar)(void); uint8_t (*WaitChar)(uint8_t *, uint32_t); uint8_t (*IsOpen)(void); } BootFunctionTable_t; 

然后我使用default_function_attribute pragma声明该类型的变量,以强制它到特定地址并用我的特定函数填充它。

 #pragma default_variable_attributes = @ "boottable" BootFunctionTable_t bootFunctions = { MAJOR_REVISION, MINOR_REVISION, BootSerialInit, /* Communication Init */ BootSerialDeInit, /* Communication Deinit */ BootSerialWrite, BootSerialRead, BootSerialAttached, BootExitToApp, BootJump, BootGetCRC, NULL, NULL, BootReset, BootGetTickCount, BootSleep, NULL, NULL, NULL, NULL, NULL, NULL, BootSerialPutChar, BootSerialGetChar, NULL }; #pragma default_variable_attributes = 

在main中我创建一个新指针并将其指向我试图强制该表的地址

 BootFunctionTable_t * bootf; bootf = (BootFunctionTable_t *)0x080000200; 

最后,我在链接器文件中创建了该部分

 /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x08000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x08000300; define symbol __ICFEDIT_region_ROM_end__ = 0x080FFFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF; define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000; define symbol __ICFEDIT_region_CCMRAM_end__ = 0x1000FFFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x400; define symbol __ICFEDIT_size_heap__ = 0x200; /**** End of ICF editor section. ###ICF###*/ define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define region CCMRAM_region = mem:[from __ICFEDIT_region_CCMRAM_start__ to __ICFEDIT_region_CCMRAM_end__]; define region BOOTTABLE_region = mem:[from 0x08000200 to 0x080002FF]; initialize by copy {section boottable}; place in BOOTTABLE_region { readonly section boottable}; define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; initialize by copy { readwrite }; do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; 

但是我不能将链接器放在请求的地址上的bootFunctions。 有人可以告诉我我做错了什么吗? 我甚至无法将该部分显示在地图文件中。 我能找到的唯一例子是.intvec部分,但是向量表是在汇编文件中定义的。 我想将我的boottable放在一个C文件中。

链接器排除未使用的符号。

尝试明确告诉链接器保留该部分。 添加如下行:

 keep { section boottable }; 

@ user694733是正确的。 因为我实际上并没有使用

 BootFunctionTable_t bootFunctions 

而是链接器将其留下的硬编码地址。 我将代码更改为

 BootFunctionTable_t * bootf; bootf = &bootFunctions; 

这也修复了它。