在STM32上创建可编程查找表

2019-07-14 17:47发布

我想在STM32F103上定义一个不是常量的查找表,就是一个闪存页面在正常操作中显示,但每隔一段时间我希望能够擦除该表并将一个新表写入闪存页面。我知道如何使用HAL函数在我的程序中执行我需要的操作,但我需要在链接器文件中声明这个内存块并且我在查找示例时遇到了很多麻烦。CubeMX的默认mem.ld如下所示:

  1. <font size="4">MEMORY
  2. {
  3.   FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K
  4.   RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
  5. }</font>
复制代码
看起来我需要一个输出部分块之后,我提交一个关键字> FLASH但我不知道将是什么关键字或如何在代码中声明表以给它正确的地址。我已经看过模拟的EEPROM应用笔记,但对于内存来说,似乎需要额外的大量开销才能看到足够的擦除/写入周期来关注内存的生命周期。有人知道要怎么做吗?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
9条回答
储蓄叛逆
1楼-- · 2019-07-15 00:48
注意:链接不是C语言标准的一部分,因此每个编译器都以不同方式实现链接器文件。你使用的是GCC,因此我分享一些适用于它的代码。
  1. linker.ld:

  2. MEMORY
  3. {
  4. RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 8K
  5. FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 31K
  6. /*(1)*/ FIXED_DATA(rw)  : ORIGIN = 0x8007C00, LENGTH = 1K /* your LUT here*/
  7. }
  8. ............
  9. .FIXED_DATA (NOLOAD):/*(2)*/
  10.   {
  11.     *(STATIC_DATA);/*(3)*/
  12.   } >FIXED_DATA /*(4)*/
复制代码
(1)创建一个给定位置和大小的名为FIXED_DATA的区域。请注意,我的代码来自不同的设备。检查你的数据表确实看到块的大小(它们在设备内的大小可能不同!)。确保相应地减小FLASH的大小,否则你将收到有关它们不适合内存的错误。
(2)创建一个名为FIXED_DATA的部分。它实际上不必被称为FIXED_DATA,但它有助于跟踪。属性NOLOAD告诉链接器不填充区域(见下文)。
(3)将所有标记为STATIC DATA的变量放入该存储器部分
(4)将此部分中的所有内容放入我们上面创建的名为FIXED_DATA的区域
在C文件中,你只需要标记要放入该区域的变量。我建议将它们称为const,因为通常不想直接写入闪存。Volatile有助于编译器优化,假设const数据永远不会改变。
为什么要经历所有这些麻烦,而不是在其他答案中使用更简单的解决方案?因为它可以升级。如果将来要进行FW更新,你可能希望将存储的数据保留在内存中。链接器文件中的NOLOAD指令就是这样:链接器不会用0填充数据,因为如果你有一个全局变量通常会这样做。
joereil
2楼-- · 2019-07-15 05:39
在我看来,楼上是正确的方法,很好的答案
lingjianghui
3楼-- · 2019-07-15 09:10
非常感谢3楼,最近盯着一堆链接器文件的一个问题,应该有某种形式。= ALIGN(4); 声明STATIC_DATA属性后的语句,或者是数据类型隐含的语句。
储蓄叛逆
4楼-- · 2019-07-15 12:33
我认为你不能错误地对齐数据,最小的数据类型是8位,编译器将填充插入结构和位域以确保正确对齐。如果你确实需要对齐一些更大的大小(例如16个字节),我建议你也在链接器文件中进行。那么,当你向该部分添加新变量时可以保证对齐。
hisysteeoke
5楼-- · 2019-07-15 18:31
 精彩回答 2  元偷偷看……
杀狼000
6楼-- · 2019-07-15 21:25
是的,你的表有一个部分是最干净的。
但最简单的方法是按页面大小减少FLASH部分,然后:
int *table = (int *) (0x0800000 +0x20000 - PAGE_SIZE)

一周热门 更多>