Merge pull request #617 from mattia-moffa/20251023-h5-update-fix

Fix STM32H5 update
pull/620/head
David Garske 2025-10-29 13:53:55 -07:00 committed by GitHub
commit b795cce0f7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 219 additions and 67 deletions

View File

@ -21,7 +21,7 @@ DUALBANK_SWAP?=1
WOLFBOOT_PARTITION_SIZE?=0xA0000
WOLFBOOT_SECTOR_SIZE?=0x2000
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08060000
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08160000
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x0C160000
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0xFFFFFFFF
FLAGS_HOME=0
DISABLE_BACKUP=0

View File

@ -21,7 +21,7 @@ DUALBANK_SWAP?=1
WOLFBOOT_PARTITION_SIZE?=0xA0000
WOLFBOOT_SECTOR_SIZE?=0x2000
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08060000
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08160000
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x0C160000
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0xFFFFFFFF
FLAGS_HOME=0
DISABLE_BACKUP=0

View File

@ -21,8 +21,8 @@ DUALBANK_SWAP?=0
WOLFBOOT_PARTITION_SIZE?=0xA0000
WOLFBOOT_SECTOR_SIZE?=0x2000
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08060000
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08100000
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x081A0000
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x0C100000
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x0C1A0000
FLAGS_HOME=0
DISABLE_BACKUP=0
WOLFCRYPT_TZ=1

View File

@ -66,3 +66,35 @@ the two images again.
For more information about the update process, see [Firmware Update](firmware_update.md)
For the image format, see [Firmware Image](firmware_image.md)
## NSC API
If you're running wolfBoot on an ARM TrustZone-enabled device (see for example
[STM32-TZ](STM32-TZ.md)) you may wish to run your application in non-secure
mode, while keeping the UPDATE and SWAP partitions in the secure domain. In
order to accomplish this, any operation by the application that requires access
to those partitions needs to be performed via wolfBoot code running in the
secure domain. For this purpose, wolfBoot provides Non-Secure Callable (NSC)
APIs that allow code running in the non-secure domain to call into the secure
domain managed by wolfBoot.
These APIs are listed below.
- `void wolfBoot_nsc_success(void)`: wrapper for `wolfBoot_success()`
- `void wolfBoot_nsc_update_trigger(void)`: wrapper for
`wolfBoot_update_trigger()`
- `uint32_t wolfBoot_nsc_get_image_version(uint8_t part)`: wrapper for
`wolfBoot_get_image_version()`
- `uint32_t wolfBoot_nsc_current_firmware_version(void)`: wrapper for
`wolfBoot_current_firmware_version()`
- `uint32_t wolfBoot_nsc_update_firmware_version(void)`: wrapper for
`wolfBoot_update_firmware_version()`
- `int wolfBoot_nsc_get_partition_state(uint8_t part, uint8_t *st)`: wrapper
for `wolfBoot_get_partition_state()`
- `int wolfBoot_nsc_erase_update(uint32_t address, uint32_t len)`: allows the
application to erase the update partition in secure mode. The `address`
parameter is an offset from the beginning of the partition.
- `int wolfBoot_nsc_write_update(uint32_t address, const uint8_t *buf, uint32_t
len)`: allows the application to write to the update partition in secure
mode. The `address` parameter is an offset from the beginning of the
partition.

View File

@ -55,6 +55,12 @@ image header size must be supplied as an environment variable. For example:
IMAGE_HEADER_SIZE=1024 ./tools/keytools/sign --sha256 --ecc256 myapp.bin wolfboot_signing_private_key.der 1
```
### NSC API
wolfBoot provides a few Non-Secure Callable functions to allow a non-secure
application to perform certain operations that must be run from the secure
domain. For more information, see [API](API.md#nsc-api).
### Example using STM32L552
- Copy the example configuration for STM32-L5 with support for wolfCrypt in
@ -192,7 +198,7 @@ OPTION BYTES BANK: 2
Boot Configuration:
NSBOOTADD : 0x80400 (0x8040000)
NSBOOTADD : 0x80600 (0x8060000)
NSBOOT_LOCK : 0xC3 (The SWAP_BANK and NSBOOTADD can still be modified following their individual rules.)
SECBOOT_LOCK : 0xC3 (The BOOT_UBE, SWAP_BANK and SECBOOTADD can still be modified following their individual rules.)
SECBOOTADD : 0xC0000 (0xC000000)
@ -201,7 +207,7 @@ OPTION BYTES BANK: 3
Bank1 - Flash watermark area definition:
SECWM1_STRT : 0x0 (0x8000000)
SECWM1_END : 0x1F (0x803E000)
SECWM1_END : 0x2F (0x805e000)
Write sector group protection 1:
@ -211,7 +217,7 @@ OPTION BYTES BANK: 4
Bank2 - Flash watermark area definition:
SECWM2_STRT : 0x0 (0x08100000)
SECWM2_END : 0x1F (0x0813e000)
SECWM2_END : 0x7F (0x081fe0000)
Write sector group protection 2:
@ -251,7 +257,7 @@ OPTION BYTES BANK: 9
```
STM32_Programmer_CLI -c port=swd -d wolfboot.bin 0x0C000000
STM32_Programmer_CLI -c port=swd -d test-app/image_v1_signed.bin 0x08040000
STM32_Programmer_CLI -c port=swd -d test-app/image_v1_signed.bin 0x08060000
```
- After rebooting, the LED on the board should turn on sequentially:

View File

@ -175,10 +175,10 @@ The example configuration for this scenario is available in [/config/examples/st
- User Option Bytes requirement (with STM32CubeProgrammer tool - see below for instructions)
```
TZEN = 1 System with TrustZone-M enabled
DBANK = 1 Dual bank mode
SECWM1_PSTRT=0x0 SECWM1_PEND=0x7F All 128 pages of internal Flash Bank1 set as secure
SECWM2_PSTRT=0x1 SECWM2_PEND=0x0 No page of internal Flash Bank2 set as secure, hence Bank2 non-secure
TZEN = 1 System with TrustZone-M enabled
DBANK = 1 Dual bank mode
SECWM1_STRT=0x0 SECWM1_END=0x7F All 128 pages of internal Flash Bank1 set as secure
SECWM2_STRT=0x1 SECWM2_END=0x0 No page of internal Flash Bank2 set as secure, hence Bank2 non-secure
```
- NOTE: STM32CubeProgrammer V2.3.0 is required (v2.4.0 has a known bug for STM32L5)
@ -189,7 +189,7 @@ SECWM2_PSTRT=0x1 SECWM2_PEND=0x0 No page of internal Flash Bank2 set as secur
2. `make`
3. Prepare board with option bytes configuration reported above
- `STM32_Programmer_CLI -c port=swd mode=hotplug -ob TZEN=1 DBANK=1`
- `STM32_Programmer_CLI -c port=swd mode=hotplug -ob SECWM1_PSTRT=0x0 SECWM1_PEND=0x7F SECWM2_PSTRT=0x1 SECWM2_PEND=0x0`
- `STM32_Programmer_CLI -c port=swd mode=hotplug -ob SECWM1_STRT=0x0 SECWM1_END=0x7F SECWM2_STRT=0x1 SECWM2_END=0x0`
4. flash wolfBoot.bin to 0x0c00 0000
- `STM32_Programmer_CLI -c port=swd -d ./wolfboot.bin 0x0C000000`
5. flash .\test-app\image_v1_signed.bin to 0x0804 0000
@ -316,10 +316,10 @@ SRAM memories into two parts:
- User Option Bytes requirement (with STM32CubeProgrammer tool - see below for instructions)
```
TZEN = 1 System with TrustZone-M enabled
DBANK = 1 Dual bank mode
SECWM1_PSTRT=0x0 SECWM1_PEND=0x7F All 128 pages of internal Flash Bank1 set as secure
SECWM2_PSTRT=0x1 SECWM2_PEND=0x0 No page of internal Flash Bank2 set as secure, hence Bank2 non-secure
TZEN = 1 System with TrustZone-M enabled
DBANK = 1 Dual bank mode
SECWM1_STRT=0x0 SECWM1_END=0x7F All 128 pages of internal Flash Bank1 set as secure
SECWM2_STRT=0x1 SECWM2_END=0x0 No page of internal Flash Bank2 set as secure, hence Bank2 non-secure
```
- NOTE: STM32CubeProgrammer V2.8.0 or newer is required
@ -330,7 +330,7 @@ SECWM2_PSTRT=0x1 SECWM2_PEND=0x0 No page of internal Flash Bank2 set as secur
2. `make TZEN=1`
3. Prepare board with option bytes configuration reported above
- `STM32_Programmer_CLI -c port=swd mode=hotplug -ob TZEN=1 DBANK=1`
- `STM32_Programmer_CLI -c port=swd mode=hotplug -ob SECWM1_PSTRT=0x0 SECWM1_PEND=0x7F SECWM2_PSTRT=0x1 SECWM2_PEND=0x0`
- `STM32_Programmer_CLI -c port=swd mode=hotplug -ob SECWM1_STRT=0x0 SECWM1_END=0x7F SECWM2_STRT=0x1 SECWM2_END=0x0`
4. flash wolfBoot.bin to 0x0c000000
- `STM32_Programmer_CLI -c port=swd -d ./wolfboot.bin 0x0C000000`
5. flash .\test-app\image_v1_signed.bin to 0x08010000
@ -915,7 +915,7 @@ The example configuration for this scenario is available in [/config/examples/st
`STM32_Programmer_CLI -c port=swd -ob TZEN=0xB4`
- set the option bytes to enable flash secure protection of first 384KB and remainder as non-secure:
`STM32_Programmer_CLI -c port=swd -ob SECWM1_PSTRT=0x0 SECWM1_PEND=0x2F SECWM2_PSTRT=0x2F SECWM2_PEND=0x0`
`STM32_Programmer_CLI -c port=swd -ob SECWM1_STRT=0x0 SECWM1_END=0x2F SECWM2_STRT=0x0 SECWM2_END=0x7F`
- flash the wolfboot image to the secure partition:
`STM32_Programmer_CLI -c port=swd -d wolfboot.bin 0x0C000000`
@ -925,6 +925,19 @@ The example configuration for this scenario is available in [/config/examples/st
For a full list of all the option bytes tested with this configuration, refer to [STM32-TZ.md](/docs/STM32-TZ.md).
You can use the "update" command and XMODEM to send a newly signed update (see docs/flash-OTP.md) or use the steps below using the STM32_Programmer:
```sh
IMAGE_HEADER_SIZE=1024 tools/keytools/sign --ecc256 test-app/image.bin wolfboot_signing_private_key.der 2
echo -n "pBOOT" > trigger_magic.bin
./tools/bin-assemble/bin-assemble \
update.bin \
0x0 test-app/image_v2_signed.bin \
0x9FFFB trigger_magic.bin
STM32_Programmer_CLI -c port=swd -d update.bin 0x0C100000
```
### Scenario 2: TrustZone Enabled, wolfCrypt as secure engine for NS applications
This is similar to Scenario 1, but also includes wolfCrypt in secure mode, and
@ -975,7 +988,7 @@ To initiate an update, sign a new version of the app and upload the v3 to the up
on the second bank:
```sh
tools/keytools/sign --ecc256 test-app/image.bin wolfboot_signing_private_key.der 3
IMAGE_HEADER_SIZE=1024 tools/keytools/sign --ecc256 test-app/image.bin wolfboot_signing_private_key.der 3
STM32_Programmer_CLI -c port=swd -d test-app/image_v3_signed.bin 0x08160000
```

View File

@ -96,6 +96,7 @@ void hal_tz_claim_nonsecure_area(uint32_t address, int len)
uint32_t reg;
uint32_t end = address + len;
uint32_t start_address = address;
uint32_t start_page_n;
uint32_t bank = 0;
int pos;
@ -103,12 +104,13 @@ void hal_tz_claim_nonsecure_area(uint32_t address, int len)
return;
if (address < FLASH_BANK2_BASE) {
page_n = (address - ARCH_FLASH_OFFSET) / FLASH_PAGE_SIZE;
start_page_n = (address - ARCH_FLASH_OFFSET) / FLASH_PAGE_SIZE;
bank = 0;
} else {
page_n = (address - FLASH_BANK2_BASE) / FLASH_PAGE_SIZE;
start_page_n = (address - FLASH_BANK2_BASE) / FLASH_PAGE_SIZE;
bank = 1;
}
page_n = start_page_n;
#ifdef TARGET_stm32h5
/* Take into account current swap configuration */
if ((FLASH_OPTSR_CUR & FLASH_OPTSR_SWAP_BANK) >> 31)
@ -129,13 +131,14 @@ void hal_tz_claim_nonsecure_area(uint32_t address, int len)
page_n++;
}
address = start_address;
page_n = start_page_n;
while (address < end) {
/* Erase claimed non-secure page, in secure mode */
#ifndef TARGET_stm32h5
reg = FLASH_CR & (~((FLASH_CR_PNB_MASK << FLASH_CR_PNB_SHIFT) | FLASH_CR_PER | FLASH_CR_BKER | FLASH_CR_PG | FLASH_CR_MER1 | FLASH_CR_MER2));
FLASH_CR = reg | ((page_n << FLASH_CR_PNB_SHIFT) | FLASH_CR_PER);
#else
reg = FLASH_CR & (~((FLASH_CR_PNB_MASK << FLASH_CR_PNB_SHIFT) | FLASH_CR_SER | FLASH_CR_BER | FLASH_CR_PG | FLASH_CR_MER));
reg = FLASH_CR & (~((FLASH_CR_PNB_MASK << FLASH_CR_PNB_SHIFT) | FLASH_CR_SER | FLASH_CR_BER | FLASH_CR_PG | FLASH_CR_MER | FLASH_CR_BKSEL));
FLASH_CR = reg | ((page_n << FLASH_CR_PNB_SHIFT) | FLASH_CR_SER | (bank << 31));
#endif
@ -162,8 +165,11 @@ void hal_tz_release_nonsecure_area(void)
{
#ifndef DUALBANK_SWAP
int i;
for (i = 0; i < FLASH_SECBB_NREGS; i++)
/* Set all banks as non-secure */
for (i = 0; i < FLASH_SECBB_NREGS; i++) {
FLASH_SECBB1[i] = 0;
FLASH_SECBB2[i] = 0;
}
#else
uint32_t addr;
int bank_swp = 0;

View File

@ -32,15 +32,11 @@
#define PLL_SRC_HSE 1
#if TZ_SECURE()
/* This function assumes that the boot and the update
* partitions are at the same address in the two banks,
* regardless if DUALBANK_SWAP is active or not.
*/
static int is_flash_nonsecure(uint32_t address)
{
uint32_t in_bank_offset = (address & 0x000FFFFF);
if (in_bank_offset >= (WOLFBOOT_PARTITION_BOOT_ADDRESS - FLASHMEM_ADDRESS_SPACE)) {
if (address >= WOLFBOOT_PARTITION_BOOT_ADDRESS &&
address < WOLFBOOT_PARTITION_BOOT_ADDRESS +
WOLFBOOT_PARTITION_SIZE) {
return 1;
}
return 0;
@ -189,6 +185,7 @@ void RAMFUNCTION hal_flash_opt_lock(void)
int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
{
uint32_t start_address;
uint32_t end_address;
uint32_t p;
@ -199,24 +196,33 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
if (address < 0x08000000)
return -1;
end_address = address + len - 1;
for (p = address; p < end_address; p += FLASH_PAGE_SIZE) {
#if TZ_SECURE()
if (address & FLASH_SECURE_MMAP_BIT) {
/* Get address in non-secure address space */
start_address = address & ~FLASH_SECURE_MMAP_BIT;
}
else {
if (is_flash_nonsecure(address)) {
hal_tz_claim_nonsecure_area(address, len);
}
start_address = address;
}
#else
start_address = address;
#endif
end_address = start_address + len - 1;
for (p = start_address; p < end_address; p += FLASH_PAGE_SIZE) {
uint32_t reg;
uint32_t base;
uint32_t bnksel = 0;
base = FLASHMEM_ADDRESS_SPACE;
reg = FLASH_CR & (~((FLASH_CR_PNB_MASK << FLASH_CR_PNB_SHIFT) | FLASH_CR_BER));
if(p >= (FLASH_BANK2_BASE) && (p <= (FLASH_TOP) ))
reg = FLASH_CR & (~((FLASH_CR_PNB_MASK << FLASH_CR_PNB_SHIFT) | FLASH_CR_SER | FLASH_CR_BER | FLASH_CR_PG | FLASH_CR_MER | FLASH_CR_BKSEL));
if (p >= FLASH_BANK2_BASE && p <= FLASH_TOP)
{
base = FLASH_BANK2_BASE;
bnksel = 1;
}
#if TZ_SECURE()
/* When in secure mode, skip erasing non-secure pages: will be erased upon claim */
if (is_flash_nonsecure(address)) {
return 0;
}
#endif
/* Check for swapped banks to invert bnksel */
if ((FLASH_OPTSR_CUR & FLASH_OPTSR_SWAP_BANK) >> 31)
bnksel = !bnksel;
@ -224,10 +230,16 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
FLASH_CR = reg;
ISB();
FLASH_CR |= FLASH_CR_STRT;
hal_flash_wait_complete(0);
hal_flash_wait_complete(bnksel);
}
/* If the erase operation is completed, disable the associated bits */
FLASH_CR &= ~FLASH_CR_SER ;
#if TZ_SECURE()
if (!(address & FLASH_SECURE_MMAP_BIT) && is_flash_nonsecure(address)) {
hal_tz_release_nonsecure_area();
}
#endif
return 0;
}

View File

@ -49,6 +49,7 @@
#endif
#define FLASH_SECURE_MMAP_BASE (0x0C000000)
#define FLASH_SECURE_MMAP_BIT (0x04000000)
#define RCC_CR (*(volatile uint32_t *)(RCC_BASE + 0x00)) /* RM0481 - Table 108 */
#define RCC_CR_PLL3RDY (1 << 29) /* RM0481 - Table 108 */

View File

@ -420,7 +420,6 @@ int wolfBoot_erase_encrypt_key(void);
*/
/* Call wolfBoot_success from non-secure application */
__attribute__((cmse_nonsecure_entry))
void wolfBoot_nsc_success(void);
@ -428,6 +427,16 @@ void wolfBoot_nsc_success(void);
__attribute__((cmse_nonsecure_entry))
void wolfBoot_nsc_update_trigger(void);
/* Call wolfBoot_get_image_version from non-secure application */
__attribute__((cmse_nonsecure_entry))
uint32_t wolfBoot_nsc_get_image_version(uint8_t part);
#define wolfBoot_nsc_current_firmware_version() wolfBoot_nsc_get_image_version(PART_BOOT)
#define wolfBoot_nsc_update_firmware_version() wolfBoot_nsc_get_image_version(PART_UPDATE)
/* Call wolfBoot_get_partition_state from non-secure application */
__attribute__((cmse_nonsecure_entry))
int wolfBoot_nsc_get_partition_state(uint8_t part, uint8_t *st);
/* Erase one or more sectors in the update partition.
* - address: offset within the update partition ('0' corresponds to PARTITION_UPDATE_ADDRESS)
* - len: size, in bytes

View File

@ -2051,25 +2051,48 @@ void wolfBoot_nsc_update_trigger(void)
wolfBoot_update_trigger();
}
__attribute__((cmse_nonsecure_entry))
uint32_t wolfBoot_nsc_get_image_version(uint8_t part)
{
return wolfBoot_get_image_version(part);
}
__attribute__((cmse_nonsecure_entry))
int wolfBoot_nsc_get_partition_state(uint8_t part, uint8_t *st)
{
return wolfBoot_get_partition_state(part, st);
}
__attribute__((cmse_nonsecure_entry))
int wolfBoot_nsc_erase_update(uint32_t address, uint32_t len)
{
int ret;
if (address > WOLFBOOT_PARTITION_SIZE)
return -1;
if (address + len > WOLFBOOT_PARTITION_SIZE)
return -1;
return hal_flash_erase(address + WOLFBOOT_PARTITION_UPDATE_ADDRESS, len);
hal_flash_unlock();
ret = hal_flash_erase(address + WOLFBOOT_PARTITION_UPDATE_ADDRESS, len);
hal_flash_lock();
return ret;
}
__attribute__((cmse_nonsecure_entry))
int wolfBoot_nsc_write_update(uint32_t address, const uint8_t *buf, uint32_t len)
{
int ret;
if (address > WOLFBOOT_PARTITION_SIZE)
return -1;
if (address + len > WOLFBOOT_PARTITION_SIZE)
return -1;
return hal_flash_write(address + WOLFBOOT_PARTITION_UPDATE_ADDRESS, buf, len);
hal_flash_unlock();
ret = hal_flash_write(address + WOLFBOOT_PARTITION_UPDATE_ADDRESS, buf, len);
hal_flash_lock();
return ret;
}
#endif

View File

@ -267,21 +267,27 @@ static int cmd_update_xmodem(const char *args)
{
int ret = -1;
uint8_t xpkt[XMODEM_PACKET_SIZE];
uint32_t dst_flash = (uint32_t)WOLFBOOT_PARTITION_UPDATE_ADDRESS;
uint32_t dst_offset = 0;
uint8_t pkt_num = 0, pkt_num_expected=0xFF;
uint32_t pkt_size = XMODEM_PACKET_SIZE;
uint32_t t_size = 0;
uint32_t update_ver = 0;
uint32_t now = jiffies;
uint32_t i = 0;
uint8_t pkt_num_inv;
uint8_t crc, calc_crc;
int transfer_started = 0;
int eot_expected = 0;
printf("Erasing update partition...");
fflush(stdout);
#ifdef WOLFCRYPT_SECURE_MODE
wolfBoot_nsc_erase_update(dst_offset, WOLFBOOT_PARTITION_SIZE);
#else
hal_flash_unlock();
hal_flash_erase(dst_flash, WOLFBOOT_PARTITION_SIZE);
hal_flash_erase(WOLFBOOT_PARTITION_UPDATE_ADDRESS + dst_offset, WOLFBOOT_PARTITION_SIZE);
#endif
printf("Done.\r\n");
printf("Waiting for XMODEM transfer...\r\n");
@ -303,6 +309,8 @@ static int cmd_update_xmodem(const char *args)
}
} else {
now = jiffies;
if (i == 0 && xpkt[0] == XEOT)
break;
i += ret;
}
}
@ -313,6 +321,12 @@ static int cmd_update_xmodem(const char *args)
extra_led_on();
break;
}
else if (eot_expected) {
ret = 1;
uart_tx(XNAK);
break;
}
if (xpkt[0] != XSOH) {
continue;
}
@ -335,10 +349,13 @@ static int cmd_update_xmodem(const char *args)
crc = xpkt[XMODEM_PACKET_SIZE - 1];
calc_crc = crc8(xpkt, XMODEM_PACKET_SIZE - 1);
if (crc == calc_crc) {
uint32_t t_size;
/* CRC is valid */
memcpy(xpkt_payload, xpkt + 3, XMODEM_PAYLOAD_SIZE);
ret = hal_flash_write(dst_flash, xpkt_payload, XMODEM_PAYLOAD_SIZE);
#ifdef WOLFCRYPT_SECURE_MODE
ret = wolfBoot_nsc_write_update(dst_offset, xpkt_payload, XMODEM_PAYLOAD_SIZE);
#else
ret = hal_flash_write(WOLFBOOT_PARTITION_UPDATE_ADDRESS + dst_offset, xpkt_payload, XMODEM_PAYLOAD_SIZE);
#endif
if (ret != 0) {
xcancel();
printf("Error writing to flash\r\n");
@ -347,15 +364,16 @@ static int cmd_update_xmodem(const char *args)
uart_tx(XACK);
pkt_num++;
pkt_num_expected++;
dst_flash += XMODEM_PAYLOAD_SIZE;
t_size = *((uint32_t *)(WOLFBOOT_PARTITION_UPDATE_ADDRESS + 4));
t_size += IMAGE_HEADER_SIZE;
if ((uint32_t)dst_flash >= (WOLFBOOT_PARTITION_UPDATE_ADDRESS + t_size)) {
ret = 0;
extra_led_off();
break;
dst_offset += XMODEM_PAYLOAD_SIZE;
if (t_size == 0) {
/* At first packet, save expected partition size */
t_size = *(uint32_t *)(xpkt_payload + 4);
t_size += IMAGE_HEADER_SIZE;
}
uart_tx(XACK);
if (dst_offset >= t_size) {
eot_expected = 1;
}
/*uart_tx(XACK);*/
} else {
uart_tx(XNAK);
}
@ -367,17 +385,34 @@ static int cmd_update_xmodem(const char *args)
uart_tx('\r');
printf("End of transfer. ret: %d\r\n", ret);
update_ver = wolfBoot_update_firmware_version();
if (update_ver != 0) {
printf("New firmware version: 0x%lx\r\n", update_ver);
printf("Triggering update...\r\n");
wolfBoot_update_trigger();
printf("Update completed successfully.\r\n");
} else {
printf("No valid image in update partition\r\n");
if (ret != 0) {
printf("Transfer failed\r\n");
}
else {
printf("Transfer succeeded\r\n");
#ifdef WOLFCRYPT_SECURE_MODE
update_ver = wolfBoot_nsc_update_firmware_version();
#else
update_ver = wolfBoot_update_firmware_version();
#endif
if (update_ver != 0) {
printf("New firmware version: 0x%lx\r\n", update_ver);
printf("Triggering update...\r\n");
#ifdef WOLFCRYPT_SECURE_MODE
wolfBoot_nsc_update_trigger();
#else
wolfBoot_update_trigger();
#endif
printf("Update written successfully. Reboot to apply.\r\n");
} else {
printf("No valid image in update partition\r\n");
}
}
#ifndef WOLFCRYPT_SECURE_MODE
hal_flash_lock();
#endif
return ret;
}
@ -427,17 +462,25 @@ static int cmd_info(const char *args)
uint16_t hdrSz;
uint8_t boot_part_state = IMG_STATE_NEW, update_part_state = IMG_STATE_NEW;
#ifdef WOLFCRYPT_SECURE_MODE
cur_fw_version = wolfBoot_nsc_current_firmware_version();
update_fw_version = wolfBoot_nsc_update_firmware_version();
wolfBoot_nsc_get_partition_state(PART_BOOT, &boot_part_state);
wolfBoot_nsc_get_partition_state(PART_UPDATE, &update_part_state);
#else
cur_fw_version = wolfBoot_current_firmware_version();
update_fw_version = wolfBoot_update_firmware_version();
wolfBoot_get_partition_state(PART_BOOT, &boot_part_state);
wolfBoot_get_partition_state(PART_UPDATE, &update_part_state);
#endif
printf("\r\n");
printf("System information\r\n");
printf("====================================\r\n");
printf("Flash banks are %sswapped.\r\n", ((FLASH_OPTSR_CUR & (FLASH_OPTSR_SWAP_BANK)) == 0)?"not ":"");
printf("Firmware version : 0x%lx\r\n", wolfBoot_current_firmware_version());
printf("Firmware version : 0x%lx\r\n", cur_fw_version);
printf("Current firmware state: %s\r\n", part_state_name(boot_part_state));
if (update_fw_version != 0) {
if (update_part_state == IMG_STATE_UPDATING)
@ -482,7 +525,11 @@ static int cmd_info(const char *args)
static int cmd_success(const char *args)
{
#ifdef WOLFCRYPT_SECURE_MODE
wolfBoot_nsc_success();
#else
wolfBoot_success();
#endif
printf("update success confirmed.\r\n");
return 0;
}
@ -741,14 +788,17 @@ void main(void)
int ret;
uint32_t app_version;
/* Turn on boot LED */
boot_led_on();
/* Enable SysTick */
systick_enable();
#ifdef WOLFCRYPT_SECURE_MODE
app_version = wolfBoot_nsc_current_firmware_version();
#else
app_version = wolfBoot_current_firmware_version();
#endif
nvic_irq_setprio(NVIC_USART3_IRQN, 0);
nvic_irq_enable(NVIC_USART3_IRQN);