C99中如何指定functions/vars的内存位置(fast/slow)?

How to specify the memory location (fast/slow) of functions/vars in C99?

在许多嵌入式架构中,可以 运行 将代码或数据存储到内部 RAM(快速访问)或外部 SDRAM(慢速访问)中。

在像 SHARC 处理器这样的架构上,可以定义函数链接到的内存区域。

segment("seg_ext_dm32") void foo( void ); // External memory 32-bit location

不幸的是,说明符 segment("seg_ext_dm32") 并不是真正的 ANSI,我不能在我的通用库中省略它,因为它可以在不同的体系结构(例如 x86)上进行单元测试。

所以我正在寻找一种更通用的解决方案来将我的 functions/variables 分类为存储在慢速或快速内存段中。这是一个例子:

___slow void fft_configure( int parameter );
___fast void fft_tick();

最常用的方法是什么?

当然,一种简单的方法是将通用头文件添加到我的特定编译器中,以定义 __slow 或 __fast 的内容:

在我的主文件中:

#ifndef __slow
   #define __slow /* nothing */
#endif
#ifndef __fast
   #define __fast /* nothing */
#endif

在我的编译器中:

cc -D__slow=segment("seg_ext_dm32") -D__fast=segment("seg_dm32")

但我认为这不是最佳解决方案。

有很多方法可以给这只猫剥皮,有些方法比其他方法更便携。

可能最便携的方法是将您的函数隔离到单独的源文件中,这些文件是 'fast' 或 'slow'(或者通过为每个文件放置一个函数组来实现更精细的粒度),并且然后让链接器描述符文件处理将段粘贴到您想要的位置。这会将所有非标准内容排除在源文件之外并将其放在一个位置。

链接器描述符文件必须由使用该库的人管理,但无论如何他们都必须这样做才能将任何段正确定位到 'fast' 和 'slow' 内存。使用这种方法,他们只需在他们在正确位置定义的加载段中指定正确的 .o 文件,而不是依赖编译器发出您选择的包罗万象的名称。

这就是我所做的。 我创建了一个可以根据编译器更改的属性。 对于我的嵌入式应用程序,我使用以下

#ifdef IS_EMBEDDED
  #define FAST_DATA  __attribute__ ((section ("fast_data")))
#else
  #define FAST_DATA /* DO NOTHING */
#endif

然后当我创建需要在快速数据部分内的全局数据时,我按如下方式应用部分位置。

char fastStack[1024*5] FAST_DATA;

终于在我的链接描述文件中了。

MEMORY
{
   fastMemory : ORIGIN = 0x00000050, LENGTH = 0x0000ffff
   DDR3 : ORIGIN = 0x60000000, LENGTH = 0x8000000
   FLASH : ORIGIN = 0xC0000000, LENGTH = 0x02000000
}

...

.fast_data : {
    __fast_data_start = .;
    . = ALIGN(8);
    *(fast_data)
    . = ALIGN(8);   
    __fast_data_end = .;
} > fastMemory
...