Open umair-uas opened 9 months ago
Right, these commands are not implemented. We don't need them at the moment, I think because of the "CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y" setting. But feel free to submit a PR, and I'll integrated it, should be easy.
So how do you use the uploaded image in slot 1 then ? I do have CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y in my prj.conf but still when I upload it goes to slot 1,I have no idea how it will be used after the reset .
It is a bit tricky. We use mcuboot to update the image. So we figured that we don't need the usual swap process, because we can always update it again from mcuboot, if something went wrong. And with the setting "CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y", slot 1 is actually slot 0, see flash_map_extended.c:
#if defined(CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD)
int flash_area_id_from_direct_image(int image_id)
{
switch (image_id) {
case 0:
case 1:
return FIXED_PARTITION_ID(slot0_partition);
...
And we also have our custom sign script:
python3 `west topdir`/bootloader/mcuboot/scripts/imgtool.py sign --confirm --header-size 0x400 --align 32 --version 0.0.0+0 --slot-size 0xe0000 build/zephyr/zephyr.bin firmware-image-slot1.bin
This creates a pre-confirmed image. And the flash partition table is defined like this:
flash0: flash@8000000 {
compatible = "st,stm32-nv-flash", "soc-nv-flash";
write-block-size = < 0x20 >;
erase-block-size = < 0x20000 >;
max-erase-time = < 0xfa0 >;
reg = < 0x8000000 0x200000 >;
partitions {
compatible = "fixed-partitions";
#address-cells = < 0x1 >;
#size-cells = < 0x1 >;
boot_partition: partition@0 {
reg = < 0x0 0x20000 >;
read-only;
};
slot0_partition: partition@20000 {
reg = < 0x20000 0xe0000 >;
label = "image-0";
};
storage_partition: partition@100000 {
reg = < 0x100000 0x120000 >;
};
slot1_partition: partition@120000 {
reg = < 0x120000 0xe0000 >;
label = "image-1";
};
};
};
We have also a slot 2, to update an external flash with application data:
mt25ql512: qspi-nor-flash@0 {
compatible = "st,stm32-qspi-nor";
reg = < 0x0 >;
qspi-max-frequency = < 0x7ed6b40 >;
spi-bus-width = < 0x4 >;
size = < 0x20000000 >;
partitions {
compatible = "fixed-partitions";
#address-cells = < 0x1 >;
#size-cells = < 0x1 >;
slot2_partition: partition@0 {
reg = < 0x0 0x4000000 >;
label = "image-2";
};
};
};
All this allows us to directly update slot 1 (which is in fact slot 0, as shown above, which is the slot used to boot the image for the first core), and also slot 2 for the external flash. I reserved slot 1 for later, if we want someday update it from the application instead of mcuboot, with the usual swap on reboot process, or if we want to use the second core of the STM32, which is currently disabled.
It is a bit tricky. We use mcuboot to update the image. So we figured that we don't need the usual swap process, because we can always update it again from mcuboot, if something went wrong. And with the setting "CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y", slot 1 is actually slot 0, see flash_map_extended.c:
#if defined(CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD) int flash_area_id_from_direct_image(int image_id) { switch (image_id) { case 0: case 1: return FIXED_PARTITION_ID(slot0_partition); ...
And we also have our custom sign script:
python3 `west topdir`/bootloader/mcuboot/scripts/imgtool.py sign --confirm --header-size 0x400 --align 32 --version 0.0.0+0 --slot-size 0xe0000 build/zephyr/zephyr.bin firmware-image-slot1.bin
This creates a pre-confirmed image. And the flash partition table is defined like this:
flash0: flash@8000000 { compatible = "st,stm32-nv-flash", "soc-nv-flash"; write-block-size = < 0x20 >; erase-block-size = < 0x20000 >; max-erase-time = < 0xfa0 >; reg = < 0x8000000 0x200000 >; partitions { compatible = "fixed-partitions"; #address-cells = < 0x1 >; #size-cells = < 0x1 >; boot_partition: partition@0 { reg = < 0x0 0x20000 >; read-only; }; slot0_partition: partition@20000 { reg = < 0x20000 0xe0000 >; label = "image-0"; }; storage_partition: partition@100000 { reg = < 0x100000 0x120000 >; }; slot1_partition: partition@120000 { reg = < 0x120000 0xe0000 >; label = "image-1"; }; }; };
We have also a slot 2, to update an external flash with application data:
mt25ql512: qspi-nor-flash@0 { compatible = "st,stm32-qspi-nor"; reg = < 0x0 >; qspi-max-frequency = < 0x7ed6b40 >; spi-bus-width = < 0x4 >; size = < 0x20000000 >; partitions { compatible = "fixed-partitions"; #address-cells = < 0x1 >; #size-cells = < 0x1 >; slot2_partition: partition@0 { reg = < 0x0 0x4000000 >; label = "image-2"; }; }; };
All this allows us to directly update slot 1 (which is in fact slot 0, as shown above, which is the slot used to boot the image for the first core), and also slot 2 for the external flash. I reserved slot 1 for later, if we want someday update it from the application instead of mcuboot, with the usual swap on reboot process, or if we want to use the second core of the STM32, which is currently disabled.
Thanks for the clarification. In our use case ,we have BLE Dongle , we use two virtual interfaces /dev/ttyACM0 and /dev/ttyACM1 on it. On one our application runs using HCI UART. On the second interface we upload the image with mcumgr.
mcumgr --conntype serial --connstring "/dev/ttyACM1,baud=115200,mtu=512" image list
Images:
image=0 slot=0
version: 2.2.3
bootable: true
flags: active confirmed
hash: ead226ff89d69a0a9f441c227cd91f70bedaf947042a2d3fd2a5a0963ce2df3f
image=0 slot=1
version: 2.2.1
bootable: true
flags:
hash: eeb089d0eee135e2663f8af9595b1456ee0bb4c8ee74bef8768f199c030aa06b
Split status: N/A (0)
❯ mcumgr --conntype serial --connstring "/dev/ttyACM1,baud=115200,mtu=512" image confirm ""
Images:
image=0 slot=0
version: 2.2.3
bootable: true
flags: active confirmed
hash: ead226ff89d69a0a9f441c227cd91f70bedaf947042a2d3fd2a5a0963ce2df3f
image=0 slot=1
version: 2.2.1
bootable: true
flags:
hash: eeb089d0eee135e2663f8af9595b1456ee0bb4c8ee74bef8768f199c030aa06b
Split status: N/A (0)
So when uploading the image , it goes here to slot=1, and then I have to do whole testing, confirming to make the image active in slot 0.
Ok, this sounds like what we do for another hardware, which we update OTA with Bluetooth while the application is running. We are using pre-confirmed images for this as well (see the custom Python sign step I wrote), which avoids the testing and confirming step on the device. Should be effectively the same as the "image confirm" step of the Go mcumgr program, if you don't need the confirm step done by the app on the device.
But could be that HCI UART is different. If you have a sample project of your configuration for the nRF5340-DK, then I can test it.
Ok, this sounds like what we do for another hardware, which we update OTA with Bluetooth while the application is running. We are using pre-confirmed images for this as well (see the custom Python sign step I wrote), which avoids the testing and confirming step on the device. Should be effectively the same as the "image confirm" step of the Go mcumgr program, if you don't need the confirm step done by the app on the device.
But could be that HCI UART is different. If you have a sample project of your configuration for the nRF5340-DK, then I can test it.
We use the sample project from Zephyr for HCI UART for nrf52840dongle, should work with nrf5340dk as well. [zephyr-sample-hci_uart](https://github.com/zephyrproject-rtos/zephyr/tree/main/samples/bluetooth/hci_uart)
Right, these commands are not implemented. We don't need them at the moment, I think because of the "CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y" setting. But feel free to submit a PR, and I'll integrated it, should be easy.
We use dual-bank updates over serial. A second serial port is offered for mcumgr, where we upload the image, mark it for testing, and also confirm it after running.
Unfortunately, we cannot use this tool because of the missing support for marking images for testing/confirmed. We will need to stick with the poor Go version.
This feature would be really nice if you can add it. If not, I can have a look when I get some time :)
The go mcumgr client has some commands for
image test
andimage confirm <hash>
to test and confirm the uploaded image, I don't seem to see how it is done using this client. I am able to upload the image and can also reset ,the functionality that was just added I think. But I am not able to switch to the newly uploaded image.Here is what I mean :
now when I upload the image
NOTE: (see I had to reduce the MTU to 256, default does not work I don't know why, any way that's another issue)
I can see it being uploaded correctly
Even after resetting the device it does not move it to slot 0 and nor can I test or confirm the image.