【问题标题】:How to specify the memory location (fast/slow) of functions/vars in C99?如何在 C99 中指定函数/变量的内存位置(快/慢)?
【发布时间】:2015-09-24 18:24:58
【问题描述】:

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

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

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

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

所以我正在寻找一种更通用的解决方案来对我的函数/变量进行分类,以存储在慢速或快速内存段中。这是一个例子:

___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,因为以下划线开头的名称被C 语言保留。
  • 一般来说,你无法避免定义这样的宏,因为 C 标准既没有提供将变量标记为某个段中的方法,也没有完全是一个“段”。
  • @FUZxxl 你说的__ 错位的名字是由 C 语言保留的。 ____ 是怎么回事?我正在寻找一个在我的代码或 C 库中都找不到的前缀。
  • 这取决于编译器,对于一个全面的答案来说太宽泛了。
  • @nowox:请自己做一些研究。已经有足够的关于保留的前缀和后缀的信息。从标准开始。请注意,___(三个下划线)确实以两个下划线开头,所以......好吧,我将把它作为一个小作业。

标签: c memory c99


【解决方案1】:

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

可能最可移植的方法是将您的函数分离到单独的源文件中,这些源文件是“快”或“慢”(甚至更细粒度,每个文件放置一个函数组),然后拥有链接器描述符文件处理将段粘贴到您想要的位置。这样可以将所有非标准内容从源文件中排除,并将其放在一个位置。

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

【讨论】:

  • 通常情况下,您会使用带有预定义段名称的预制链接描述文件来实现慢速和快速内存。在这些情况下,最好手动指定段名称,而不是摆弄你不应该接触的链接器脚本。
  • 除了您的预制链接器脚本几乎肯定不会匹配供应商 ABC 选择的部分名称。如果您正在进行嵌入式工作,您(或您组织中的某个人)正在处理链接器描述符文件。
  • 是的,但是在几个宏中更改部分名称比使用不同的链接器脚本编译不同的源代码形式要容易得多(但这会起作用)。
  • 您无需对代码执行任何操作,只需将其拆分为可以直接放入链接器描述符文件中的段的文件。在链接器描述符中指定文件就像在正确的位置添加mycode_fast.o(.text) 一样简单。作为嵌入式世界中图书馆的消费者,我希望我的供应商不要做出强迫我使用他们的方法的假设(这可能与其他方法冲突)。
【解决方案2】:

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

#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
...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    • 2018-11-28
    • 2013-12-20
    • 2020-11-08
    • 2011-07-06
    相关资源
    最近更新 更多