Das ist nicht so kompliziert zu machen.
Grundsätzlich benötigen Sie eine konstante globale Variable, die in Flash platziert wird und die Position mithilfe eines Pragmas definiert.
In C ++ könnte der Header ungefähr so aussehen:
class FlashLookUpTable
{
public:
struct LookUpTable_t
{
uint32_t table[100];
};
public:
static LookUpTable_t const * GetLookUpTablePointer();
private:
static const uint32_t FLASH_PAGE_SIZE = 1024U; // or whatever the flash smallest deletable size is
// This variable contains the number of bytes needed to store the structure in complete flash pages
static const uint32_t ARRAY_SIZE = (sizeof(LookUpTable_t)/FLASH_PAGE_SIZE) + FLASH_PAGE_SIZE;
union FlashPageSizedStructure
{
LookUpTable_t t;
uint8_t flashpage[ARRAY_SIZE];
}
static const FlashPageSizedStructure tableInFlash;
};
Und so sieht die Implementierung aus:
// the exact pragma depends on the compiler used, this one works for IAR
// the location should be at the start of a page boundary, especially when using this union approach
#pragma location=0x800FC00U
const FlashLookUpTable::FlashPageSizedStructure FlashLookUpTable::tableInFlash =
{
// initialize values here
}
FlashLookUpTable::LookUpTable_t const * FlashLookUpTable::GetLookUpTablePointer(void) const
{
return &tableInFlash.t;
}
Um diese Seite in Flash zu schreiben, benötigen Sie einen Puffer (entweder im RAM oder in Flash) mit der gleichen Größe wie eine Flash-Seite, da Sie die Seite löschen müssen, bevor Sie sie erneut schreiben, sodass eine Änderung eines einzelnen Werts an Ort und Stelle erfolgt nicht möglich.
Je nachdem, wie genau Sie es verwenden, müssen Sie die Struktur möglicherweise als deklarieren volatile
. Dies geschieht insbesondere, wenn Sie direkt auf die Tabelle zugreifen (nicht mit einem Zeiger wie in diesem Fall).
Einige Compiler optimieren den Code so, dass sie die Konstante aus der Tabelle direkt in den Code übernehmen. Das Ergebnis ist, dass wenn Sie den Wert in Ihrer Tabelle ändern, der Wert im Code nicht berücksichtigt wird.
Der IAR-Compiler hatte einige Probleme (es ist in der aktuellen Version behoben) bei der Handhabung von a, static volatile const
also wechselte ich zur Verwendung eines Zeigers.
Wenn Sie die Werte ändern möchten, benötigen Sie eine Art Flash-Algorithmus.
Das Schreiben von Flash besteht immer aus:
- Seiteninhalt sichern
- Update mit geänderten Werten aktualisieren
- Seite löschen
- Seite schreiben
- Zur Sicherheit: Vergleichen Sie die geschriebene Seite mit dem Backup
Hinweis für Fortgeschrittene: In einigen Fällen können Sie ausnutzen, dass Sie Nullen an Positionen schreiben können, an denen sich eine Eins befand, sodass Sie 0x7F in 0x3F ändern können, aber nicht umgekehrt. In diesem Fall müssen Sie keine Seite löschen. Einige Controller unterstützen dies möglicherweise nicht.