【问题标题】:Memory placements of C-functionC 函数的内存布局
【发布时间】:2019-05-02 17:13:51
【问题描述】:

我想创建一个软件,稍后可以在我的微控制器上对某些功能(或块)进行编程,而无需再次重新刷新整个软件(闪存将由通信接口完成,例如 SPI)。新块都将具有相同的 API(例如,5 个字节作为参数,1 个字节返回)。

内存架构将如下图所示进行组织: memory architecture

总而言之,FBL 和 APPL 模块将在 MCU 上仅编程 1 次。在这个过程的后期,我希望有可能在创建的块中编程或更改一些功能(BLOCK 1,BLOCK 2 ...)

对于每个块,我都有:

  • 2 段 flash(一段用于 init 函数,一段用于“任务”函数)。
  • 我可以在其中放置静态变量的 1 个 RAM 部分。

目前,我的问题是我无法创建一个包含我函数的所有内容的单个内存块。例如,如果我想在我的新块中使用 math.h 中的函数,链接器会将 math.h 函数放置在我的 APPL 扇区中,而不是放在专门为此块分配的内存扇区中。但正如我所说,我的 APPL 扇区不应该改变,因为它只会被编程 1 次。所以我想知道如何写一些“独立”的块......

非常感谢!

【问题讨论】:

  • 这不是一个好主意。相反,您应该以某种标准格式(如 S-record 或 Intel hex)生成二进制文件,然后在进行程序更新时,运行差异工具并查看发生了什么变化。然后只编程那部分,而不是整个事情。不幸的是,现代程序闪存具有可笑的大擦除大小,因此无论如何它都不会有效。也许您可以考虑获得一个带有大型 eeprom/数据闪存的零件,它可以从那里执行代码。
  • 此功能的目的与任何闪存加载优化(时间或单元寿命)无关,而是与仅可更改功能而无需更新应用程序代码(用于验证目的)的软件架构有关)

标签: c memory architecture iar


【解决方案1】:

您必须确保至少调用一次您需要的标准库的所有函数,以便将其包含在您的二进制基本代码中。

对于您的“变量”代码,您必须在块的开头有一种跳转表。你的基本代码调用变量代码中的函数,跳转表跳转到实际的函数入口点(或者你可以有包装函数),例如:

char f1(int a, int b) { return _f1(a,b)}
char f2(int a, int b) { return _f2(a,b)}

char _f1(int a, int b) { return 0;} /* function not yet developed */
char _f2(int a, int b) { return 0;} /* function not yet developed */

并且在开发后的代码中:

char f1(int a, int b) { return _f1(a,b)}
char f2(int a, int b) { return _f2(a,b)}

char _f1(int a, int b) {
   /* lots of complex stuff */
   return result;
}
char _f2(int a, int b) {
   /* lots of complex stuff */
   return result;
}

这里,f1f2等函数都将位于变量代码的固定位置,因此可以从基础代码中调用。一旦代码块的最终版本被刷新,他们就会调用他们的最终版本。


注意:我不确定如何处理放置在基本代码区域中的标准库中的可变代码调用函数。变量块的链接器必须在变量代码中重复加载函数,或者必须知道它在基本代码区域中的绝对位置。您应该检查链接器/加载器文档。

【讨论】:

  • 感谢您的回答。如果 math.h 中的函数在代码中从未被调用过至少一次,就没有办法直接将它放在我的块中吗?我将查看链接器文档
猜你喜欢
  • 2016-09-11
  • 1970-01-01
  • 2012-07-09
  • 1970-01-01
  • 1970-01-01
  • 2014-03-07
  • 2010-12-10
  • 2022-01-24
  • 1970-01-01
相关资源
最近更新 更多