在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条回答
ZQW发烧友
2019-07-16 04:38
这并不复杂,基本上你需要的是一个常量全局变量,它将放在flash中并使用pragma定义位置。
在C ++中,标题可能如下所示:
  1. class FlashLookUpTable
  2. {
  3.     public:
  4.     struct LookUpTable_t
  5.     {
  6.         uint32_t table[100];
  7.     };
  8.     public:
  9.     static LookUpTable_t const * GetLookUpTablePointer();
  10.     private:
  11.     static const uint32_t FLASH_PAGE_SIZE = 1024U; // or whatever the flash smallest deletable size is
  12.     // This variable contains the number of bytes needed to store the structure in complete flash pages
  13.     static const uint32_t ARRAY_SIZE = (sizeof(LookUpTable_t)/FLASH_PAGE_SIZE) + FLASH_PAGE_SIZE;
  14.     union FlashPageSizedStructure
  15.     {
  16.         LookUpTable_t t;
  17.         uint8_t flashpage[ARRAY_SIZE];
  18.     }
  19.     static const FlashPageSizedStructure tableInFlash;
  20. };
复制代码
这就是实现的样子:

  1. // the exact pragma depends on the compiler used, this one works for IAR
  2. // the location should be at the start of a page boundary, especially when using this union approach
  3. #pragma location=0x800FC00U
  4. const FlashLookUpTable::FlashPageSizedStructure FlashLookUpTable::tableInFlash =
  5. {
  6.     // initialize values here
  7. }
  8. FlashLookUpTable::LookUpTable_t const * FlashLookUpTable::GetLookUpTablePointer(void) const
  9. {
  10.     return &tableInFlash.t;
  11. }
复制代码
要在闪存中写入该页面,您需要一个具有相同大小的闪存页面的缓冲区(在RAM或闪存中),因为您必须在再次写入之前擦除页面,因此单个值的更改是不可能。
根据您使用它的准确程度,您可能需要将结构声明为volatile。特别是如果直接访问表(而不是像这种情况下的指针),就会发生这种情况。
有些编译器以这种方式优化代码,它们将常量从表中直接带入代码中。结果是,如果更改表中的值,则不会在代码中考虑该值。
IAR编译器遇到了一些麻烦(在当前版本中已修复)处理一个,static volatile const所以我切换到使用指针。

一周热门 更多>