Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to update Firmware using MCUBoot on STM32G0 series #42453

Closed
PxGreen101 opened this issue Feb 3, 2022 · 8 comments
Closed

Unable to update Firmware using MCUBoot on STM32G0 series #42453

PxGreen101 opened this issue Feb 3, 2022 · 8 comments
Assignees
Labels
bug The issue is a bug, or the PR is fixing a bug platform: STM32 ST Micro STM32 priority: low Low impact/importance bug

Comments

@PxGreen101
Copy link

PxGreen101 commented Feb 3, 2022

Describe the bug
Firmware will not update on STM32G0 series hardware using MCUBoot and Zephyr using mcumgr

Zephyr version 2.6
Nucleo board : nucleo_g0b1re

Steps to reproduce the behavior:

  1. Edit the nucleo_g0b1re.dts file to setup the correct partitions for flash0

&flash0 {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;

	boot_partition: partition@0 {
		label = "mcuboot";
		reg = <0x00000000 0x00010000>;
		read-only;
	};
	slot0_partition: partition@10000 {
		label = "image-0";
		reg = <0x00010000 0x00032000>;
	};
	slot1_partition: partition@42000 {
		label = "image-1";
		reg = <0x00042000 0x00032000>;
	};
	scratch_partition: partition@74000 {
		label = "image-scratch";
		reg = <0x00074000 0x00004000>;
	};
	storage_partition: partition@78000 {
		label = "storage";
		reg = <0x00078000 0x00008000>;
	};
};

};

  1. Build the MCUBoot project: west build -b nucleo_g0b1re -p. Apart from the configuration options already presented in prj.conf add the following.
    CONFIG_BOOT_VALIDATE_SLOT0=n

CONFIG_MCUBOOT_SERIAL=y
CONFIG_BOOT_SERIAL_UART=y
CONFIG_UART_CONSOLE=n

CONFIG_BOOT_SERIAL_DETECT_PORT="GPIOC"
CONFIG_BOOT_SERIAL_DETECT_PIN=13
CONFIG_BOOT_SERIAL_DETECT_PIN_VAL=0
CONFIG_BOOT_MAX_IMG_SECTORS=256
CONFIG_MULTITHREADING=y

  1. Build the blinky project using west build -b nucleo_g0b1re zephyr/samples/basic/blinky -p. Also add the following to the prj.conf file

CONFIG_BOOTLOADER_MCUBOOT=y
CONFIG_MCUMGR=y
CONFIG_MCUMGR_CMD_OS_MGMT=y
CONFIG_MCUMGR_CMD_IMG_MGMT=y

Also inside main.c for the blinky project, we add the following header files
#include "os_mgmt/os_mgmt.h"
#include "img_mgmt/img_mgmt.h"

Inside main.c add the following
#ifdef CONFIG_MCUMGR_CMD_OS_MGMT
os_mgmt_register_group();
#endif
#ifdef CONFIG_MCUMGR_CMD_IMG_MGMT
img_mgmt_register_group();
#endif

  1. Using imgtool to sign the zephyr.hex application file which was copied to the imgtool folder
    ./imgtool.py sign --key ../root-rsa-2048.pem --header-size 0x200 --align 8 --version 1.0 --slot-size 0x32000 zephyr.hex zephyrv1out.hex

  2. The Nucleo board has already been updated to function as a J-Link using the instructions here: https://www.segger.com/products/debug-probes/j-link/models/other-j-links/st-link-on-board/

  3. Using Segger J-Flash Lite program the bootloader file first zephyr.hex followed by the zephyrv1out.hex file

image

  1. Confirm that the bootloader loads the application

  2. We will now try to update the firmware using mcumgr

  3. Make 1 code change in the application file created in step 3 so we have a different file to load using mcumgr. I added a new printf. Build the application again using west build -b nucleo_g0b1re zephyr/samples/basic/blinky -p.

  4. Using imgtool sign the new file. Since mcumgr uses the .bin file use the Zephyr.bin file in this step
    ./imgtool.py sign --key ../root-rsa-2048.pem --header-size 0x200 --align 8 --version 1.3 --slot-size 0x32000 zephyr.bin zephyrv1out.bin

  5. Run the mcumgr image list command and confirm we can communicate
    mcumgr --conntype serial --connstring "com5,baud=115200" image list
    Images:
    image=0 slot=0
    version: 1.0.0
    bootable: true
    flags: active confirmed
    hash: 76d2531b7c5bf02296fc8eda63d6a391b798d31d1b918395e1398dee52f4eec3
    Split status: N/A (0)

  6. Update the firmware using image upload
    mcumgr --conntype serial --connstring "com5,baud=115200" image upload -e zephyrv1out.bin
    40.25 KiB / 40.25 KiB [==============================================================================================================================================================================================] 100.00% 607 B/s 1m7s
    Done

  7. Run image list command

mcumgr --conntype serial --connstring "com5,baud=115200" image list
Images:
image=0 slot=0
version: 1.0.0
bootable: true
flags: active confirmed
hash: 76d2531b7c5bf02296fc8eda63d6a391b798d31d1b918395e1398dee52f4eec3
image=0 slot=1
version: 1.3.0
bootable: true
flags:
hash: e3004cdad5c63fa1de3f2c3b93fd4440b84f1ca53702ce631bf7352a2bcead7b
Split status: N/A (0)

  1. Confirm the image
    mcumgr --conntype serial --connstring "com5,baud=115200" image confirm e3004cdad5c63fa1de3f2c3b93fd4440b84f1ca53702ce631bf7352a2bcead7b
    Images:
    image=0 slot=0
    version: 1.0.0
    bootable: true
    flags: active confirmed
    hash: 76d2531b7c5bf02296fc8eda63d6a391b798d31d1b918395e1398dee52f4eec3
    image=0 slot=1
    version: 1.3.0
    bootable: true
    flags: pending permanent
    hash: e3004cdad5c63fa1de3f2c3b93fd4440b84f1ca53702ce631bf7352a2bcead7b
    Split status: N/A (0)

  2. Issue a reset
    mcumgr --conntype serial --connstring "com5,baud=115200" reset

Expected behavior
Firmware should be updated and image in slot 1 should run

Impact
Showstopper
After the reboot the image is still showing as pending even after confirming and never actually runs.
mcumgr --conntype serial --connstring "com5,baud=115200" image list
Images:
image=0 slot=0
version: 1.0.0
bootable: true
flags: active confirmed
hash: 76d2531b7c5bf02296fc8eda63d6a391b798d31d1b918395e1398dee52f4eec3
image=0 slot=1
version: 1.3.0
bootable: true
flags: pending permanent
hash: e3004cdad5c63fa1de3f2c3b93fd4440b84f1ca53702ce631bf7352a2bcead7b
Split status: N/A (0)

There were actually hard faults previously taking place when jumping back into the bootloader but after observing this issue regarding stm32g0 dual bank,
cfac53b#diff-a2d5fca25c404eac402acbfb96ca6316e697094af4b25f25e457991a6f044764

the flash_stm32g0x.c was replaced with this new version. Also the flash_stm32_write_range function was modified as this would also cause a hard fault. This is the new function
int flash_stm32_write_range(const struct device *dev, unsigned int offset,
const void *data, unsigned int len)

{
int i, rc = 0;
uint64_t ddata;
for (i = 0; i < len; i += 8, offset += 8) {
memcpy(&ddata, (uint8_t*)data + i, sizeof(uint64_t));
rc = write_dword(dev, offset, ddata);
if (rc < 0) {
return rc;
}
}
return rc;
}

With these changes I am able to use mcumgr and can confirm after the reboot that the second image does not run. The image passes all the MCUBoot required validation including the header. I have confirmed this by using the Ozone Debugger. However it does not actually run the new program.

I have also tried adding the following MCUBoot configuration options 1 at a time
CONFIG_BOOT_UPGRADE_ONLY=y

CONFIG_BOOT_SWAP_USING_MOVE=y

CONFIG_BOOT_DIRECT_XIP=y

Even with CONFIG_BOOT_DIRECT_XIP the application in slot1 does not run which it should as no copying takes place.

Memory start of image in slot 0

image

Memory start of image in slot 1

image

Environment (please complete the following information):

  • OS: Linux (Ubuntu 20.04)
  • Toolchain - Zephyr version 2.6
  1. Does anyone see any issues with the imgtool commands that are run? Am I generating the .bin file that is to be uploaded using mcumgr correctly?
  2. Are my configuration options correct for both the application and the bootloader?
  3. Will upgrading to Zephyr 3.0 solve this issue as there seem to be other updates to support the stm32g0 dual bank?
@PxGreen101 PxGreen101 added the bug The issue is a bug, or the PR is fixing a bug label Feb 3, 2022
@erwango erwango added the platform: STM32 ST Micro STM32 label Feb 3, 2022
@erwango erwango added the priority: low Low impact/importance bug label Feb 3, 2022
@PxGreen101
Copy link
Author

By the way I did the exact same steps and targeted the Nucleo STM32F429ZI board instead. Same MCUboot bootloader, same application, same configuration options, same commands when building and signing with imgtool. Everything works correctly with the Nucleo STM32F429ZI. There must be some issue to target the Nucleo STM32G0B1RE.

@PxGreen101
Copy link
Author

This sounds very similar to #37389. Can someone confirm this works with Zephyr version 3.0 ?

@ycsin
Copy link
Member

ycsin commented Feb 9, 2022

I can confirm it works on 2.7.0 RC3, can't verify on 3.0 yet as I have some issues with that branch

@de-nordic
Copy link
Collaborator

The application you have uploaded, have it been built for the slot you are uploading it to?

@PxGreen101
Copy link
Author

The application you have uploaded, have it been built for the slot you are uploading it to?

Yes - that is correct.

@PxGreen101
Copy link
Author

PxGreen101 commented Feb 25, 2022

For anyone interested I have confirmed this does not work with Zephyr 2.7.1 as it does not have the changes to support the STM32G0 dual bank. I had to use the backport branch revision: backport-37480-to-v2.7-branch then everything worked fine.

image

@PxGreen101
Copy link
Author

PxGreen101 commented Feb 25, 2022

One more comment is that if we are trying to do serial recover i.e in the prj.conf

CONFIG_MCUBOOT_SERIAL=y
CONFIG_BOOT_SERIAL_UART=y
CONFIG_UART_CONSOLE=n

one must replace the int flash_stm32_write_range(const struct device *dev, unsigned int offset, const void *data, unsigned int len) function with the one I have described above. If we do not do this if you try to use mcumgr to boot an application (if one does not exist) this will hard fault. With this change you can successfully do a serial recovery if the board only has a bootloader file on it

@ycsin
Copy link
Member

ycsin commented Feb 26, 2022

I can confirm it works on 2.7.0 RC3, can't verify on 3.0 yet as I have some issues with that branch

Sorry about my previous comment, the driver support for g0 is merged after the 2.7 LTS, it works in my 2.7.0 RC3 because I manually merged it into my local branch. Once #42655 is merged when it will work on the 2.7 LTS.

one must replace the int flash_stm32_write_range(const struct device *dev, unsigned int offset, const void *data, unsigned int len) function with the one I have described above. If we do not do this if you try to use mcumgr to boot an application (if one does not exist) this will hard fault. With this change you can successfully do a serial recovery if the board only has a bootloader file on it

Not really sure what you meant, maybe you can raise a new issue & propose a PR to fix if there's any bug?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug The issue is a bug, or the PR is fixing a bug platform: STM32 ST Micro STM32 priority: low Low impact/importance bug
Projects
None yet
Development

No branches or pull requests

5 participants