|
@@ -35,24 +35,59 @@
|
35
|
35
|
*/
|
36
|
36
|
#define FLASH_OFFSET (PICO_FLASH_BANK_STORAGE_OFFSET - FLASH_SECTOR_SIZE)
|
37
|
37
|
|
38
|
|
-// TODO add checksum
|
|
38
|
+struct mem_contents {
|
|
39
|
+ uint8_t version;
|
|
40
|
+ uint32_t checksum;
|
39
|
41
|
|
40
|
|
-static struct mem_data data_ram = MEM_DATA_INIT;
|
|
42
|
+ struct mem_data data;
|
|
43
|
+} __attribute__((packed));
|
|
44
|
+
|
|
45
|
+#define MEM_CONTENTS_INIT { \
|
|
46
|
+ .version = MEM_VERSION, \
|
|
47
|
+ .checksum = 0, \
|
|
48
|
+ .data = MEM_DATA_INIT, \
|
|
49
|
+}
|
|
50
|
+
|
|
51
|
+static struct mem_contents data_ram = MEM_CONTENTS_INIT;
|
41
|
52
|
static const uint8_t *data_flash = (const uint8_t *)(XIP_BASE + FLASH_OFFSET);
|
42
|
53
|
|
43
|
|
-static_assert(sizeof(struct mem_data) < FLASH_SECTOR_SIZE,
|
|
54
|
+static_assert(sizeof(struct mem_contents) < FLASH_SECTOR_SIZE,
|
44
|
55
|
"Config needs to fit inside a flash sector");
|
45
|
56
|
|
|
57
|
+static uint32_t calc_checksum(const struct mem_contents *data) {
|
|
58
|
+ uint32_t c = 0x4223DEAD;
|
|
59
|
+ const uint8_t *d = (const uint8_t *)data;
|
|
60
|
+
|
|
61
|
+ const size_t offset_checksum = offsetof(struct mem_contents, checksum);
|
|
62
|
+ const size_t size_checksum = sizeof(data->checksum);
|
|
63
|
+
|
|
64
|
+ for (size_t i = 0; i < sizeof(struct mem_contents); i++) {
|
|
65
|
+ if ((i >= offset_checksum) && (i < (offset_checksum + size_checksum))) {
|
|
66
|
+ continue;
|
|
67
|
+ }
|
|
68
|
+
|
|
69
|
+ c ^= d[i];
|
|
70
|
+ }
|
|
71
|
+
|
|
72
|
+ return c;
|
|
73
|
+}
|
|
74
|
+
|
46
|
75
|
void mem_init(void) {
|
47
|
76
|
if (!flash_safe_execute_core_init()) {
|
48
|
77
|
debug("error calling flash_safe_execute_core_init");
|
49
|
78
|
}
|
50
|
79
|
|
51
|
|
- const struct mem_data *flash_ptr = (const struct mem_data *)data_flash;
|
|
80
|
+ const struct mem_contents *flash_ptr = (const struct mem_contents *)data_flash;
|
52
|
81
|
|
53
|
82
|
if (flash_ptr->version == MEM_VERSION) {
|
54
|
83
|
debug("found matching config (0x%02X)", flash_ptr->version);
|
55
|
|
- data_ram = *flash_ptr;
|
|
84
|
+
|
|
85
|
+ uint32_t checksum = calc_checksum(flash_ptr);
|
|
86
|
+ if (checksum != flash_ptr->checksum) {
|
|
87
|
+ debug("invalid checksum (0x%08lX != 0x%08lX)", flash_ptr->checksum, checksum);
|
|
88
|
+ } else {
|
|
89
|
+ data_ram = *flash_ptr;
|
|
90
|
+ }
|
56
|
91
|
} else {
|
57
|
92
|
debug("invalid config (0x%02X != 0x%02X)", flash_ptr->version, MEM_VERSION);
|
58
|
93
|
}
|
|
@@ -66,11 +101,14 @@ static void mem_write_flash(void *param) {
|
66
|
101
|
}
|
67
|
102
|
|
68
|
103
|
void mem_write(void) {
|
69
|
|
- if (memcmp(&data_ram, data_flash, sizeof(struct mem_data)) == 0) {
|
|
104
|
+ if (memcmp(&data_ram, data_flash, sizeof(struct mem_contents)) == 0) {
|
70
|
105
|
debug("no change, skip write");
|
71
|
106
|
return;
|
72
|
107
|
}
|
73
|
108
|
|
|
109
|
+ data_ram.checksum = calc_checksum(&data_ram);
|
|
110
|
+
|
|
111
|
+ debug("writing new data");
|
74
|
112
|
int r = flash_safe_execute(mem_write_flash, &data_ram, FLASH_LOCK_TIMEOUT_MS);
|
75
|
113
|
if (r != PICO_OK) {
|
76
|
114
|
debug("error calling mem_write_flash: %d", r);
|
|
@@ -78,5 +116,5 @@ void mem_write(void) {
|
78
|
116
|
}
|
79
|
117
|
|
80
|
118
|
struct mem_data *mem_data(void) {
|
81
|
|
- return &data_ram;
|
|
119
|
+ return &data_ram.data;
|
82
|
120
|
}
|