rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
backup_ram.cpp
Go to the documentation of this file.
1/**
2 * @file backup_ram.cpp
3 * @brief NVRAM emulation using Internal Flash (flash_int driver)
4 *
5 * @date May 22, 2020
6 */
7
8#include "pch.h"
9#include "backup_ram.h"
10#include "flash_int.h"
11
12#define BACKUP_NOT_INITIALIZED 0xFFFF
13#define BACKUP_SAVED 0x5555
14#define BACKUP_PENDING 0x0000
15
16// we store the flash state at 0 index + all backup variables
17static volatile uint32_t backupRam[(int)LAST_BACKUP_RAM_ENUM + 1];
18static bool wasLoaded = false;
19// these offsets are indices in the 'BACKUP_FLASH_ADDR' (32-bit array)
20static const int backupStateOffset = 0, backupDataOffset = 1;
21const size_t backupSize = ((int)LAST_BACKUP_RAM_ENUM + 1) * sizeof(uint32_t);
22
23static void backupInit() {
24 static_assert(backupSize <= BACKUP_FLASH_SIZE, "Backup flash overflow");
25 static_assert(BACKUP_FLASH_ADDR != (flashaddr_t)nullptr, "Backup address undefined");
26
27 // first, load the whole buffer into the memory
28 intFlashRead((flashaddr_t)BACKUP_FLASH_ADDR, (char *)backupRam, backupSize);
29 // check if we have a reliable properly saved data
30 if (backupRam[backupStateOffset] != BACKUP_SAVED) {
31 // zero is the default value
32 memset((void *)backupRam, 0, backupSize);
33 }
34
35 // we cannot trust the saved data anymore, until it's saved in backupRamFlush()
36 // so we mark is as 'pending'
37 backupRam[backupStateOffset] = BACKUP_PENDING;
38 intFlashWrite((flashaddr_t)BACKUP_FLASH_ADDR + backupStateOffset, (char *)backupRam, sizeof(backupRam[backupStateOffset]));
39
40 wasLoaded = true;
41}
42
44 // this is executed only once during the firmware init
45 if (!wasLoaded) {
46 backupInit();
47 }
48
49 return backupRam[(int)idx + backupDataOffset];
50}
51
52void backupRamSave(backup_ram_e idx, uint32_t value) {
53 // this is executed only once during the firmware init
54 if (!wasLoaded) {
55 backupInit();
56 }
57
58 backupRam[(int)idx + backupDataOffset] = value;
59}
60
61void backupRamFlush(void) {
62
63 // todo: implement an incremental "append-to-the-end" algorithm to minimize sector erasings?
64
65 // Enter the critical zone
66 syssts_t sts = chSysGetStatusAndLockX();
67
68 // rewrite the whole sector
69 intFlashErase((flashaddr_t)BACKUP_FLASH_ADDR, BACKUP_FLASH_SIZE);
70 // mark the data as valid & saved
71 backupRam[(int)backupStateOffset] = BACKUP_SAVED;
72 // save the data to the flash
73 intFlashWrite((flashaddr_t)BACKUP_FLASH_ADDR, (char *)backupRam, backupSize);
74
75 // Leaving the critical zone
76 chSysRestoreStatusX(sts);
77
78 // there should not be any backup-RAM activity after this call
79 // but if there is, at least try to reinitialize...
80 wasLoaded = false;
81}
82
83//// TODO: implement me!
84//BackupSramData* getBackupSram() {
85// return nullptr;
86//}
Non-volatile backup-RAM registers support.
backup_ram_e
Definition backup_ram.h:14
static const int backupStateOffset
uint32_t backupRamLoad(backup_ram_e idx)
const size_t backupSize
void backupRamSave(backup_ram_e idx, uint32_t value)
void backupRamFlush(void)
static volatile uint32_t backupRam[(int) LAST_BACKUP_RAM_ENUM+1]
static const int backupDataOffset
static void backupInit()
static bool wasLoaded
int intFlashErase(flashaddr_t address, size_t size)
Erase the sectors containing the span of size bytes starting at address.
uintptr_t flashaddr_t
Address in the flash memory.
Definition flash_int.h:86
int intFlashWrite(flashaddr_t address, const char *buffer, size_t size)
Copy data from a buffer to the flash memory.
int intFlashRead(flashaddr_t source, char *destination, size_t size)
Copy data from the flash memory to a destination.