C语言 无法使用IAR ARM编译器将函数表强制到特定地址

1u4esq0p  于 2023-08-03  发布在  其他
关注(0)|答案(3)|浏览(191)

我有一个函数表类型定义如下

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 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放置在请求的地址。有人能告诉我我做错了什么吗?我甚至不能让部分显示在Map文件中。我能找到的唯一例子是.intvec部分,但向量表是在汇编文件中定义的。我想把我的启动表放在C文件中。

h7appiyu

h7appiyu1#

未使用的符号由连接符排除。
尝试显式地告诉链接器保留该节。添加一行,如:

keep { section boottable };

字符集

ukdjmx9f

ukdjmx9f2#

@user694733是正确的。因为我并没有用

BootFunctionTable_t bootFunctions

字符集
而是链接器遗漏的硬编码地址。我把密码改成了

BootFunctionTable_t * bootf;
bootf = &bootFunctions;


这也解决了问题

nr9pn0ug

nr9pn0ug3#

我不得不说,我不能让'保持'链接器指令为我工作。我发现的是IAR note 51348 https://www.iar.com/support/tech-notes/linker/the-linker-removing-functions-and-variables-or-external-not-found/,它建议使用__root来强制链接器保留内容,这对我很有效。

相关问题