Skip to content

Commit

Permalink
Improve network core firmware update.
Browse files Browse the repository at this point in the history
  • Loading branch information
dgarske committed Sep 27, 2024
1 parent 5be7646 commit fb39621
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 100 deletions.
2 changes: 1 addition & 1 deletion config/examples/nrf5340_net.config
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ RAM_CODE?=1

DUALBANK_SWAP?=0
FLAGS_HOME=0
DISABLE_BACKUP=0
DISABLE_BACKUP=1
EXT_FLASH?=0
SPI_FLASH?=0
QSPI_FLASH?=0
Expand Down
203 changes: 122 additions & 81 deletions hal/nrf5340.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,17 @@ static int test_flash(void);
#define PART_NET_ADDR 0x100000UL
#endif

/* Shared Memory between network and application cores */
/* SHM: Shared Memory between network and application cores */
/* first 64KB (0x10000) is used by wolfBoot and limited in nrf5340.ld */
#ifndef SHARED_MEM_ADDR
#define SHARED_MEM_ADDR (0x20000000UL + (64 * 1024))
#define SHARED_MEM_SIZE (256 * 1024) /* enable access to full 256KB for entire network update image */
#endif
/* Shared memory states */
/* Shared memory states (mask, easier to check) */
#define SHARED_STATUS_UNKNOWN 0
#define SHARED_STATUS_READY 1
#define SHARED_STATUS_UPDATE_START 2
#define SHARED_STATUS_UPDATE_DONE 3
#define SHARED_STATUS_DO_BOOT 4
#define SHARED_STATUS_UPDATE_DONE 4
#define SHARED_STATUS_DO_BOOT 8

#define SHAREM_MEM_MAGIC 0x5753484D /* WSHM */

Expand All @@ -78,11 +77,12 @@ typedef struct {
ShmInfo_t app; /* application core write location */

/* application places firmware here */
uint8_t data[0];
uint8_t data[FLASH_SIZE_NET];
} SharedMem_t;
static SharedMem_t* shm = (SharedMem_t*)SHARED_MEM_ADDR;


/* UART */
#ifdef DEBUG_UART
#ifndef UART_SEL
#define UART_SEL 0 /* select UART 0 or 1 */
Expand Down Expand Up @@ -280,24 +280,77 @@ void hal_net_core(int hold) /* 1=hold, 0=release */
}
#endif

static uint8_t* get_image_hdr(struct wolfBoot_image* img)
{
#ifdef EXT_FLASH
return img->hdr_cache;
#else
return img->hdr;
#endif
}
static uint16_t get_image_partition_id(struct wolfBoot_image* img)
{
return wolfBoot_get_blob_type(get_image_hdr(img)) & HDR_IMG_TYPE_PART_MASK;
}

#define IMAGE_IS_NET_CORE(img) ( \
(img->type & HDR_IMG_TYPE_PART_MASK) == PART_NET_ID && \
img->fw_size < FLASH_SIZE_NET)
static int hal_net_get_image(struct wolfBoot_image* img)
(get_image_partition_id(img) == PART_NET_ID) && \
(img->fw_size < (FLASH_SIZE_NET - IMAGE_HEADER_SIZE)))
static int hal_net_get_image(struct wolfBoot_image* img, ShmInfo_t* info)
{
int ret;
#ifdef TARGET_nrf5340_app
/* check the update partition for a network core update */
int ret = wolfBoot_open_image(img, PART_UPDATE);
if (ret == 0 && IMAGE_IS_NET_CORE(img)) {
return 0;
ret = wolfBoot_open_image(img, PART_UPDATE);
if (ret == 0 && !IMAGE_IS_NET_CORE(img)) {
ret = -1;
}
/* if external flash is enabled, try an alternate location */
#ifdef EXT_FLASH
ret = wolfBoot_open_image_external(img, PART_UPDATE, PART_NET_ADDR);
if (ret == 0 && IMAGE_IS_NET_CORE(img)) {
return 0;
#ifdef EXT_FLASH
if (ret != 0) {
ret = wolfBoot_open_image_external(img, PART_UPDATE,
(uint8_t*)PART_NET_ADDR);
if (ret == 0 && !IMAGE_IS_NET_CORE(img)) {
ret = -1;
}
}
#endif
return (ret != 0) ? ret : -1;
#endif
#else /* TARGET_nrf5340_net */
ret = wolfBoot_open_image(img, PART_BOOT);
#endif /* TARGET_nrf5340_* */
if (ret == 0) {
info->version = wolfBoot_get_blob_version(get_image_hdr(img));
info->size = img->fw_size;
wolfBoot_printf("Network Image: Ver 0x%x, Size %d\n",
info->version, info->size);
}
else {
info->version = 0; /* not known */
wolfBoot_printf("Network Image: Update not found\n");
}
return ret;
}

static void hal_shm_status_set(ShmInfo_t* info, uint32_t status)
{
info->magic = SHAREM_MEM_MAGIC;
info->status = status;
}

static int hal_shm_status_wait(ShmInfo_t* info, uint32_t status,
uint32_t timeout_us)
{
int ret = 0;
uint32_t timeout = timeout_us;
while ((info->magic != SHAREM_MEM_MAGIC || (info->status & status) == 0)
&& --timeout > 0) {
sleep_us(1);
};
if (timeout == 0) {
wolfBoot_printf("Timeout: status 0x%x\n", status);
ret = -1; /* timeout */
}
return ret;
}

static void hal_net_check_version(void)
Expand All @@ -308,65 +361,49 @@ static void hal_net_check_version(void)

#ifdef TARGET_nrf5340_app
/* check the network core version */
ret = hal_net_get_image(&img);
if (ret == 0) {
shm->app.version = img.fw_ver;
shm->app.size = img.fw_size;
wolfBoot_printf("Network: Ver 0x%x, Size %d\n",
shm->app.version, shm->app.size);
}
else {
wolfBoot_printf("Failed finding net core update on ext flash 0x%x\n",
PART_NET_ADDR);
}
shm->app.magic = SHAREM_MEM_MAGIC;
shm->app.status = SHARED_STATUS_READY;
hal_net_get_image(&img, &shm->app);
hal_shm_status_set(&shm->app, SHARED_STATUS_READY);

/* release network core - issue boot command */
hal_net_core(0);

/* wait for ready status from network core */
timeout = 1000000;
while (shm->net.magic != SHAREM_MEM_MAGIC &&
shm->net.status != SHARED_STATUS_READY &&
--timeout > 0) {
/* wait */
};
if (timeout == 0) {
wolfBoot_printf("Timeout: network core ready!\n");
}
ret = hal_shm_status_wait(&shm->net, SHARED_STATUS_READY, 1000000);

/* check if network core can continue booting or needs to wait for update */
if (shm->app.version == shm->net.version) {
shm->app.status = SHARED_STATUS_DO_BOOT;
}
#else /* net */
ret = wolfBoot_open_image(&img, PART_BOOT);
if (ret == 0) {
shm->net.version = img.fw_ver;
shm->net.size = img.fw_size;
wolfBoot_printf("Network: Ver 0x%x, Size %d\n",
shm->net.version, shm->net.size);
if (ret != 0 || shm->app.version <= shm->net.version) {
wolfBoot_printf("Network Core: Releasing for boot\n");
hal_shm_status_set(&shm->app, SHARED_STATUS_DO_BOOT);
}
else {
wolfBoot_printf("Error getting boot partition info\n");
wolfBoot_printf("Network Core: Holding for update\n");
}
shm->net.magic = SHAREM_MEM_MAGIC;
shm->net.status = SHARED_STATUS_READY;

wolfBoot_printf("Network version: 0x%x\n", shm->net.version);

/* wait for do_boot or update */
timeout = 1000000;
while (shm->app.magic == SHAREM_MEM_MAGIC &&
shm->app.status == SHARED_STATUS_READY &&
--timeout > 0) {
/* wait */
};
if (timeout == 0) {
wolfBoot_printf("Timeout: app core boot signal!\n");
#else /* TARGET_nrf5340_net */
hal_net_get_image(&img, &shm->net);
hal_shm_status_set(&shm->net, SHARED_STATUS_READY);

/* wait for do_boot or update from app core */
ret = hal_shm_status_wait(&shm->app,
(SHARED_STATUS_UPDATE_START | SHARED_STATUS_DO_BOOT), 1000000);
/* are we updating? */
if (ret == 0 && shm->app.status == SHARED_STATUS_UPDATE_START) {
wolfBoot_printf("Starting update: Ver %d->%d, Size %d->%d\n",
shm->net.version, shm->app.version, shm->net.size, shm->net.size);
/* Erase network core boot flash */
wb_flash_erase(&img, 0, WOLFBOOT_PARTITION_SIZE);
/* Write new firmware to internal flash */
wb_flash_write(&img, 0, shm->data, shm->app.size);

/* Reopen image and refresh information */
wolfBoot_open_image(&img, PART_BOOT);
wolfBoot_printf("Network version (after update): 0x%x\n",
shm->net.version);
hal_net_get_image(&img, &shm->net);
hal_shm_status_set(&shm->net, SHARED_STATUS_UPDATE_DONE);

/* continue booting */
}
#endif
#endif /* TARGET_nrf5340_* */
exit:
wolfBoot_printf("Status: App %d (ver %d), Net %d (ver %d)\n",
shm->app.status, shm->app.version, shm->net.status, shm->net.version);
Expand All @@ -380,28 +417,32 @@ void hal_net_check_update(void)
struct wolfBoot_image img;

/* handle update for network core */
ret = hal_net_get_image(&img);
if (ret == 0 && img.fw_ver > shm->net.version) {
ret = hal_net_get_image(&img, &shm->app);
if (ret == 0 && shm->app.version > shm->net.version) {
wolfBoot_printf("Found Network Core update: Ver %d->%d, Size %d->%d\n",
shm->net.version, shm->app.version, shm->net.size, shm->net.size);

/* validate the update is valid */
if (wolfBoot_verify_integrity(&img) == 0 &&
wolfBoot_verify_authenticity(&img) == 0)
{
/* relocate image to ram */
ret = spi_flash_read(PART_NET_ADDR, shm->data, img.fw_size);
uint32_t fw_size = IMAGE_HEADER_SIZE + img.fw_size;
wolfBoot_printf("Network image valid, loading into shared mem\n");
/* relocate image to shared ram */
#ifdef EXT_FLASH
ret = ext_flash_read(PART_NET_ADDR, shm->data, fw_size);
#else
memcpy(shm->data, img.hdr, fw_size);
#endif
if (ret >= 0) {
/* signal network core to do update */
shm->app.status = SHARED_STATUS_UPDATE_START;
hal_shm_status_set(&shm->app, SHARED_STATUS_UPDATE_START);

/* wait for update_done */
timeout = 1000000;
while (shm->net.magic == SHAREM_MEM_MAGIC &&
shm->net.status < SHARED_STATUS_UPDATE_DONE &&
--timeout > 0) {
sleep_us(1);
};
if (timeout == 0) {
wolfBoot_printf("Timeout: net core update done!\n");
}
ret = hal_shm_status_wait(&shm->net,
SHARED_STATUS_UPDATE_DONE, 1000000);
if (ret == 0)
wolfBoot_printf("Network core firmware update sent\n");
}
}
else {
Expand All @@ -410,7 +451,7 @@ void hal_net_check_update(void)
}
}
/* inform network core to boot */
shm->app.status = SHARED_STATUS_DO_BOOT;
hal_shm_status_set(&shm->app, SHARED_STATUS_DO_BOOT);
}
#endif

Expand Down
12 changes: 7 additions & 5 deletions include/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,13 @@ int wolfBot_get_dts_size(void *dts_addr);

struct wolfBoot_image {
uint8_t *hdr;
#ifdef EXT_FLASH
uint8_t *hdr_cache;
#endif
uint8_t *trailer;
uint8_t *sha_hash;
uint8_t *fw_base;
uint32_t fw_size;
uint32_t fw_ver;
uint32_t type;
uint32_t part;
uint32_t hdr_ok;
uint32_t canary_FEED4567;
Expand Down Expand Up @@ -512,12 +513,13 @@ static void __attribute__((noinline)) wolfBoot_image_confirm_signature_ok(

struct wolfBoot_image {
uint8_t *hdr;
#ifdef EXT_FLASH
uint8_t *hdr_cache;
#endif
uint8_t *trailer;
uint8_t *sha_hash;
uint8_t *fw_base;
uint32_t fw_size;
uint32_t fw_ver;
uint16_t type;
uint8_t part;
uint8_t hdr_ok : 1;
uint8_t signature_ok : 1;
Expand Down Expand Up @@ -567,7 +569,7 @@ static void wolfBoot_image_confirm_signature_ok(struct wolfBoot_image *img)
/* Defined in image.c */
int wolfBoot_open_image(struct wolfBoot_image *img, uint8_t part);
#ifdef EXT_FLASH
int wolfBoot_open_image_external(struct wolfBoot_image* img, uint8_t part, uint32_t addr);
int wolfBoot_open_image_external(struct wolfBoot_image* img, uint8_t part, uint8_t* addr);
#endif
int wolfBoot_open_image_address(struct wolfBoot_image* img, uint8_t* image);
int wolfBoot_verify_integrity(struct wolfBoot_image *img);
Expand Down
16 changes: 9 additions & 7 deletions src/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -881,12 +881,15 @@ int wolfBoot_open_image_address(struct wolfBoot_image *img, uint8_t *image)
#endif
img->hdr_ok = 1;
img->fw_base = img->hdr + IMAGE_HEADER_SIZE;
img->fw_ver = wolfBoot_get_blob_version(image);
img->type = wolfBoot_get_blob_type(image);
#ifdef EXT_FLASH
img->hdr_cache = image;
#endif

wolfBoot_printf("%s partition: %p (sz %d, ver 0x%x, type 0x%d)\n",
(img->part == PART_BOOT) ? "Boot" : "Update",
img->hdr, (unsigned int)img->fw_size, img->fw_ver, img->type);
img->hdr, (unsigned int)img->fw_size,
wolfBoot_get_blob_version(image),
wolfBoot_get_blob_type(image));

return 0;
}
Expand Down Expand Up @@ -992,16 +995,15 @@ int wolfBoot_open_image(struct wolfBoot_image *img, uint8_t part)

#ifdef EXT_FLASH
int wolfBoot_open_image_external(struct wolfBoot_image* img, uint8_t part,
uint32_t addr)
uint8_t* addr)
{
uint8_t *image;

uint8_t* image;
if (img == NULL)
return -1;

memset(img, 0, sizeof(struct wolfBoot_image));
img->part = part;
img->hdr = (void*)addr;
img->hdr = addr;
img->hdr_ok = 1;
hdr_cpy_done = 0; /* reset hdr "open" flag */
image = fetch_hdr_cpy(img);
Expand Down
Loading

0 comments on commit fb39621

Please sign in to comment.