Skip to content

Commit 503b008

Browse files
committed
New feature: allow swapping from external memory (e.g. SPI flash)
1 parent 07db864 commit 503b008

11 files changed

Lines changed: 466 additions & 149 deletions

File tree

Makefile

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,17 @@ ifeq ($(FASTMATH),1)
6969
CFLAGS+=-DUSE_FAST_MATH
7070
endif
7171

72-
ifeq ($(EXT_FLASH),1)
73-
CFLAGS+=-DEXT_FLASH -DPART_UPDATE_EXT
74-
endif
75-
7672
CFLAGS+=-mthumb -Wall -Wextra -Wno-main -Wstack-usage=1024 -ffreestanding -Wno-unused \
7773
-Ilib/bootutil/include -Iinclude/ -Ilib/wolfssl -nostartfiles \
7874
-DWOLFSSL_USER_SETTINGS \
7975
-mthumb -mlittle-endian -mthumb-interwork \
8076
-DPLATFORM_$(TARGET)
8177

78+
ifeq ($(EXT_FLASH),1)
79+
CFLAGS+=-DEXT_FLASH=1 -DPART_UPDATE_EXT=1 -DPART_SWAP_EXT=1
80+
endif
81+
82+
8283
ifeq ($(SIGN),ED25519)
8384
OBJS+= ./lib/wolfssl/wolfcrypt/src/sha512.o \
8485
./lib/wolfssl/wolfcrypt/src/ed25519.o \
@@ -131,7 +132,7 @@ wolfboot-align.bin: wolfboot.elf
131132
$(SIZE) wolfboot.elf
132133

133134
test-app/image.bin:
134-
make -C test-app TARGET=$(TARGET)
135+
make -C test-app TARGET=$(TARGET) EXT_FLASH=$(EXT_FLASH)
135136

136137
tools/ed25519/ed25519_sign:
137138
make -C tools/ed25519
@@ -165,7 +166,7 @@ src/ecc256_pub_key.c: ecc256.der
165166
keys: $(PRIVATE_KEY)
166167

167168
clean:
168-
rm -f *.bin *.elf $(OBJS) wolfboot.map *.bin *.hex
169+
rm -f *.bin *.elf $(OBJS) wolfboot.map *.bin *.hex hal/*.o
169170
make -C test-app clean
170171

171172
distclean: clean

hal/stm32f4.c

Lines changed: 85 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,17 +112,18 @@
112112
#define FLASH_SECTOR_5 0x0020000
113113
#define FLASH_SECTOR_6 0x0040000
114114
#define FLASH_SECTOR_7 0x0060000
115-
#define FLASH_TOP 0x007FFFF
115+
#define FLASH_TOP 0x0080000
116116

117-
const uint32_t flash_sector[8] = {
117+
const uint32_t flash_sector[9] = {
118118
FLASH_SECTOR_0,
119119
FLASH_SECTOR_1,
120120
FLASH_SECTOR_2,
121121
FLASH_SECTOR_3,
122122
FLASH_SECTOR_4,
123123
FLASH_SECTOR_5,
124124
FLASH_SECTOR_6,
125-
FLASH_SECTOR_7
125+
FLASH_SECTOR_7,
126+
FLASH_TOP
126127
};
127128

128129
static void flash_set_waitstates(int waitstates)
@@ -194,17 +195,20 @@ void hal_flash_lock(void)
194195
int hal_flash_erase(uint32_t address, int len)
195196
{
196197
int start = -1, end = -1;
197-
uint32_t end_address = address + len;
198+
uint32_t end_address;
198199
int i;
200+
if (len == 0)
201+
return -1;
202+
end_address = address + len - 1;
199203

200204
if (address < flash_sector[0] || end_address > FLASH_TOP)
201205
return -1;
202-
for (i = 0; i < 7; i++)
206+
for (i = 0; i < 8; i++)
203207
{
204208
if ((address >= flash_sector[i]) && (address < flash_sector[i + 1])) {
205209
start = i;
206210
}
207-
if ((end_address >= flash_sector[i]) && (address < flash_sector[i + 1])) {
211+
if ((end_address >= flash_sector[i]) && (end_address < flash_sector[i + 1])) {
208212
end = i;
209213
}
210214
if (start > 0 && end > 0)
@@ -325,3 +329,78 @@ void hal_prepare_boot(void)
325329
clock_pll_off();
326330
}
327331

332+
333+
#ifdef EXT_FLASH
334+
#define SIM_ADDRESS (0x40000)
335+
336+
int ext_flash_read(uint32_t address, uint8_t *data, int len)
337+
{
338+
int i;
339+
uint32_t val;
340+
address += SIM_ADDRESS;
341+
for (i = 0; i < len; i++)
342+
data[i] = *((uint8_t *)(address + i));
343+
return len;
344+
}
345+
346+
int ext_flash_write(uint32_t address, const uint8_t *data, int len)
347+
{
348+
int i;
349+
uint32_t val;
350+
address += SIM_ADDRESS;
351+
flash_wait_complete();
352+
clear_errors();
353+
/* Set 8-bit write */
354+
FLASH_CR &= (~(0x03 << 8));
355+
for (i = 0; i < len; i++) {
356+
FLASH_CR |= FLASH_CR_PG;
357+
*((uint8_t *)(address + i)) = data[i];
358+
flash_wait_complete();
359+
FLASH_CR &= ~FLASH_CR_PG;
360+
}
361+
return 0;
362+
}
363+
364+
void ext_flash_unlock(void)
365+
{
366+
FLASH_CR |= FLASH_CR_LOCK;
367+
FLASH_KEYR = FLASH_KEY1;
368+
FLASH_KEYR = FLASH_KEY2;
369+
}
370+
371+
void ext_flash_lock(void)
372+
{
373+
FLASH_CR |= FLASH_CR_LOCK;
374+
}
375+
376+
377+
int ext_flash_erase(uint32_t address, int len)
378+
{
379+
int start = -1, end = -1;
380+
uint32_t end_address;
381+
int i;
382+
address += SIM_ADDRESS;
383+
end_address = address + len - 1;
384+
385+
if (address < flash_sector[0] || end_address > FLASH_TOP)
386+
return -1;
387+
for (i = 0; i < 8; i++)
388+
{
389+
if ((address >= flash_sector[i]) && (address < flash_sector[i + 1])) {
390+
start = i;
391+
}
392+
if ((end_address >= flash_sector[i]) && (end_address < flash_sector[i + 1])) {
393+
end = i;
394+
}
395+
if (start > 0 && end > 0)
396+
break;
397+
}
398+
if (start < 0 || end < 0)
399+
return -1;
400+
for (i = start; i <= end; i++)
401+
flash_erase_sector(i);
402+
return 0;
403+
}
404+
405+
406+
#endif

include/hal.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,21 @@
33

44

55
#include <inttypes.h>
6+
#include "target.h"
67
void hal_init(void);
78
int hal_flash_write(uint32_t address, const uint8_t *data, int len);
89
int hal_flash_erase(uint32_t address, int len);
910
void hal_flash_unlock(void);
1011
void hal_flash_lock(void);
1112
void hal_prepare_boot(void);
13+
14+
#ifdef EXT_FLASH
15+
/* external flash interface */
16+
int ext_flash_write(uint32_t address, const uint8_t *data, int len);
17+
int ext_flash_read(uint32_t address, uint8_t *data, int len);
18+
int ext_flash_erase(uint32_t address, int len);
19+
void ext_flash_lock(void);
20+
void ext_flash_unlock(void);
21+
#endif
1222

1323
#endif /* H_HAL_FLASH_ */

include/image.h

Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <stdint.h>
44
#include <target.h>
55
#include <wolfboot/wolfboot.h>
6+
#include "image.h"
67

78

89
#define SECT_FLAG_NEW 0x0F
@@ -11,32 +12,6 @@
1112
#define SECT_FLAG_UPDATED 0x00
1213

1314

14-
#ifdef EXT_FLASH
15-
# ifndef PART_UPDATE_DRIVER
16-
# define PART_UPDATE_DRIVER (&internal_flash_driver)
17-
# endif
18-
# define flash_lock(x) (x->flash_driver.lock())
19-
# define flash_unlock(x) (x->flash_driver.unlock())
20-
# define flash_erase(x, addr, len) (x->flash_driver.erase(addr, len)
21-
# define flash_write(x, addr, data, len) (x->flash_driver.write(addr, data, len)
22-
# define flash_read(x, addr, data, len) (x->flash_driver.read(addr, data, len)
23-
#else
24-
# define flash_lock(x) hal_flash_lock()
25-
# define flash_unlock(x) hal_flash_unlock()
26-
# define flash_erase(x, addr, len) (x->flash_driver.erase(addr, len)
27-
# define flash_write(x, addr, data, len) (x->flash_driver.write(addr, data, len)
28-
# define flash_read(x, addr, data, len) (memcpy(data, addr, len) - data + len)
29-
#endif
30-
31-
struct wolfBoot_flash_driver {
32-
int (*write)(uint32_t address, const uint8_t *data, int len);
33-
int (*read)(uint32_t address, uint8_t *data, int len);
34-
int (*erase)(uint32_t address, int len);
35-
void (*lock)(void);
36-
void (*unlock)(void);
37-
};
38-
39-
extern const struct wolfBoot_flash_driver internal_flash_driver;
4015

4116
struct wolfBoot_image {
4217
uint8_t *hdr;
@@ -47,7 +22,6 @@ struct wolfBoot_image {
4722
uint8_t *fw_base;
4823
uint32_t fw_size;
4924
uint8_t part;
50-
struct wolfBoot_flash_driver *flash_driver;
5125
};
5226

5327

@@ -59,4 +33,64 @@ int wolfBoot_set_sector_flag(uint8_t part, uint8_t sector, uint8_t newflag);
5933
int wolfBoot_get_partition_state(uint8_t part, uint8_t *st);
6034
int wolfBoot_get_sector_flag(uint8_t part, uint8_t sector, uint8_t *flag);
6135

36+
#ifdef EXT_FLASH
37+
# ifdef PART_UPDATE_EXT
38+
# define UPDATE_EXT 1
39+
# else
40+
# define UPDATE_EXT 0
41+
# endif
42+
# ifdef PART_SWAP_EXT
43+
# define SWAP_EXT 1
44+
# else
45+
# define SWAP_EXT 0
46+
# endif
47+
# define PART_IS_EXT(x) (((x)->part == PART_UPDATE)?UPDATE_EXT:(((x)->part == PART_SWAP)?SWAP_EXT:0))
48+
#include "hal.h"
49+
50+
static inline int wb_flash_erase(struct wolfBoot_image *img, uint32_t off, uint32_t size)
51+
{
52+
if (PART_IS_EXT(img))
53+
return ext_flash_erase((uint32_t)(img->hdr) + off, size);
54+
else
55+
return hal_flash_erase((uint32_t)(img->hdr) + off, size);
56+
}
57+
58+
static inline int wb_flash_write(struct wolfBoot_image *img, uint32_t off, const void *data, uint32_t size)
59+
{
60+
if (PART_IS_EXT(img))
61+
return ext_flash_write((uint32_t)(img->hdr) + off, data, size);
62+
else
63+
return hal_flash_write((uint32_t)(img->hdr) + off, data, size);
64+
}
65+
66+
static inline int wb_flash_write_verify_word(struct wolfBoot_image *img, uint32_t off, uint32_t word)
67+
{
68+
int ret;
69+
volatile uint32_t copy;
70+
if (PART_IS_EXT(img))
71+
{
72+
ext_flash_read((uint32_t)(img->hdr) + off, (void *)&copy, sizeof(uint32_t));
73+
while (copy != word) {
74+
ret = ext_flash_write((uint32_t)(img->hdr) + off, (void *)&word, sizeof(uint32_t));
75+
if (ret < 0)
76+
return ret;
77+
ext_flash_read((uint32_t)(img->hdr) + off, (void *)&copy, sizeof(uint32_t));
78+
}
79+
} else {
80+
volatile uint32_t *pcopy = (volatile uint32_t*)(img->hdr + off);
81+
while(*pcopy != word) {
82+
hal_flash_write((uint32_t)pcopy, (void *)&word, sizeof(uint32_t));
83+
}
84+
}
85+
return 0;
86+
}
87+
88+
89+
#else
90+
# define PART_IS_EXT(x) (0)
91+
# define wb_flash_erase(im, of, siz) hal_flash_erase(((uint32_t)(((im)->hdr)) + of), siz)
92+
# define wb_flash_write(im, of, dat, siz) hal_flash_write(((uint32_t)((im)->hdr)) + of, dat, siz)
93+
# define wb_flash_write_verify_word(im, of, x) do { hal_flash_write(((uint32_t)((im)->hdr)) + of, (void *)&x, sizeof(uint32_t)); } while (*(uint32_t *)(((im)->hdr) + of) != x)
94+
#endif /* EXT_FLASH */
95+
6296
#endif /* IMAGE_H */

include/target.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#define WOLFBOOT_PARTITION_SIZE 0x20000
1111

1212
#define WOLFBOOT_PARTITION_BOOT_ADDRESS 0x20000
13-
#define WOLFBOOT_PARTITION_UPDATE_ADDRESS 0x40000
14-
#define WOLFBOOT_PARTITION_SWAP_ADDRESS 0x60000
13+
#define WOLFBOOT_PARTITION_UPDATE_ADDRESS 0x0
14+
#define WOLFBOOT_PARTITION_SWAP_ADDRESS 0x20000
1515

1616
#endif

include/wolfboot/wolfboot.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,8 @@
2929
void wolfBoot_erase_partition(uint8_t part);
3030
void wolfBoot_update_trigger(void);
3131
void wolfBoot_success(void);
32+
uint32_t wolfBoot_get_image_version(uint8_t part);
33+
#define wolfBoot_current_firmware_version() wolfBoot_get_image_version(PART_BOOT)
34+
#define wolfBoot_update_firmware_version() wolfBoot_get_image_version(PART_UPDATE)
3235

3336
#endif /* IMAGE_H */

0 commit comments

Comments
 (0)