Topic: NVM_FLASH_WRITEONCE doesn't seem to work

Hi,
I'm implementing wolfboot on an STM32F1xx chip and I need to have NVM_FLASH_WRITEONCE set on. I've arranged the partitions as follows:
WOLFBOOT_PARTITION_BOOT_ADDRESS = 0x8003800
WOLFBOOT_PARTITION_UPDATE_ADDRESS = 0x8011800
WOLFBOOT_PARTITION_SIZE = 0xE000 (=56k)
FLASH_PAGE_SIZE = 0x400 (=1k)
WOLFBOOT_SECTOR_SIZE = 0x400 (=1k)

I've written the appropriate HAL functions for write and erase, etc.

The problem I'm having is that when I call wolfBoot_success(), it does not set the sector flags at the end of the boot partition as expected.

I can step it through and see it call wolfBoot_set_partition_state() in libwolfboot.c, then call set_partition_magic(). This works and I can see the flash is now programmed with "BOOT" at address 0x80117FC to 0x80117FF (ie. the end of the boot partition, as expected).

Then "state = get_partition_state(part);" is called, which erases the page that it just programmed. If I step through get_partition_state() I can see it ultimately calls nvm_select_fresh_sector() and it's in here that it erases the same flash page that it just programmed.

In nvm_select_fresh_sector(), this code:

    /* Erase the non-selected partition */
    addr_align = (uint32_t)(base - ((!sel) * WOLFBOOT_SECTOR_SIZE))
        & (~(NVM_CACHE_SIZE - 1));
    if (*((uint32_t*)(addr_align + WOLFBOOT_SECTOR_SIZE - sizeof(uint32_t)))
            != FLASH_WORD_ERASED) {
        hal_flash_erase(addr_align, WOLFBOOT_SECTOR_SIZE);
    }

Seems to want to erase the wrong page:
If "sel == 0", then:
addr_align = 0x8011800 - (1 * 0x400) = 0x8011400. So this will erase 0x8011400 to 0x80117FF.
If "sel == 1", then:
addr_align = 0x8011800 - (0 * 0x400) = 0x8011800. So this will erase 0x8011800 to 0x8011BFF.
This is outside the boot partition (ie. it's the start of 'update' partition).


How is this supposed to work? Have I got some configuration wrong somewhere?


Thanks,
Gareth.

Share

Re: NVM_FLASH_WRITEONCE doesn't seem to work

Hello Gareth,

We have recently modified the NVM_FLASH_WRITEONCE code to add redundancy in the last two sectors of each partition, to mitigate the risk of corrupted/incomplete update flags for MCUs requiring this option.
This was introduced in https://github.com/wolfSSL/wolfBoot/pull/276

The problem you are reporting seems indeed a bug introduced in the above PR. The non-selected block address should be rather

(uint32_t)(base - ((1 + (!sel)) * WOLFBOOT_SECTOR_SIZE)) & (~(NVM_CACHE_SIZE - 1); 

>

I have submitted a fix here:
https://github.com/wolfSSL/wolfBoot/pull/287 and I'm planning to integrate more tests to avoid such errors in the future.

Please let me know if this fixes the issue for you.

Thanks,

--
Daniele, wolfSSL

Share

Re: NVM_FLASH_WRITEONCE doesn't seem to work

Hi Daniele,

That change does now seem to work, from the quick test I've done.


Thank you,

Gareth.

Share

Re: NVM_FLASH_WRITEONCE doesn't seem to work

Hi Gareth,

Glad to hear this. We have merged the PR. Thanks again for reporting this issue. I'm now adding more unit tests to intercept similar failures.

Best Regards,

--
Daniele

Share