MCUBoot: adding custom serial flash driver as secondary partition

We use spi flash with custom driver and goal is to set it to act as secondary partition for MCUBoot.

The question is how to adapt driver to be accepted by MCUBoot, maybe there is an example on how driver should look like?

As far as I understand Nordic supports mx25r64, what files have to be produced and where to place them to enable custom driver to be accepted by MCUBoot?

Parents
  • The nRF91 DK which contains an mx25r64, and it will use the spi nor driver to communicate with it:

    https://github.com/nrfconnect/sdk-zephyr/blob/v3.0.99-ncs1/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_common_0_14_0.dtsi#L66

    https://github.com/nrfconnect/sdk-zephyr/blob/v3.0.99-ncs1/drivers/flash/spi_nor.c#L10

    As you can see, the spi_nor.c is located inside zephyr/drivers/flashIf you do it this way, you will be able to write/read to the spi flash using the flash API.

    After adding your spi flash driver and adding your flash device to the device tree you can put the secondary partition in your external flash by doing the following:

    Best regards,

    Simon

  • Thank you for clarification, Simon.

    At the moment I am struggling with this error: "zephyr\include\generated\devicetree_unfixed.h:6002:34: error: 'DT_N_S_soc_S_spi_40023000_S_at25xe081_0_P_size' undeclared here (not in a function); did you mean 'DT_N_S_soc_S_spi_40023000_S_at25xe081_0_P_reg".

    I added this to my_board.dts file:

    And in my driver wrapper I added #define DT_DRV_COMPAT at25xe081. However it seems that size property is not found when I am doing: flash_size = DT_INST_PROP(0, size) / 8. What I am missing here?

  • mesh777 said:

    And placed it in the same folder of project files, where my_board.dts resides. But still get the same error.

    Also I tried to modify my_board.yaml and added include of the new file, but it did not change anything.

    Try placing it in the same folder as jedec,spi-nor.yaml, the folder zephyr/dts/bindings/mtd.

    This section may be useful to learn more about compatible/bindings: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/2.0.2/zephyr/build/dts/bindings.html 

    mesh777 said:
    At the end it is important that MCUBoot builds using the new driver and I am not sure where to place files in order to accomplish that. Can these files be part of project or I have to modify SDK folder (that we want to avoid if possible).

    I'm not sure how to add a dts bindings out of tree. However, adding it directly to Zephyr might not be a bad idea, then you could create a Pull Request at the end, making your driver a part of Zephyr upstream (and Nordic Zephyr downstream). If this is not preferable, let me know, and I can look into do this out-of-tree.

  • If this is not preferable, let me know, and I can look into do this out-of-tree.

    Many thanks for fast response.

    Yes, I think it would be better to have out-of-tree solution.

  • Try adding the binding to your board folder like it's done here (<board>/dts/bindings): https://github.com/nrfconnect/sdk-nrf/tree/v2.0.2/boards/arm/thingy91_nrf9160/dts/bindings.

    Regarding adding your driver out-of-tree, I'm not sure if it will work by simply following this approach: https://github.com/nrfconnect/sdk-zephyr/tree/v3.0.99-ncs1/samples/application_development/out_of_tree_driver, since your driver should not be used directly, but rather through the flash.h API. The other flash drivers are put in https://github.com/nrfconnect/sdk-zephyr/tree/v3.0.99-ncs1/drivers/flash.

    I'll ask internally tomorrow how to go about this.

    I realized that it might be possible that the spi_nor driver actually supports the at25xe081, I'll look into this as well.

  • Is it possible to run debugger in bootloader (using VS Code) ?

    I managed to build the project, however get the following error from the bootloader:

    And this is my pm_static.yml:

  • I just talked to a colleague familiar with this stuff, and asked if at25xe081 was supported by the spi_nor driver. He said as far as he knew, most of the NOR chips should be supported by the spi_nor driver, and most of the commands from the data sheets seems to be generic, so it should not be a problem as far as he knew.

    To get more details, and a more certain answer, try to ask the Zephyr experts on Zephyr Discord, if at25xe081 is supported by the spi_nor driver (Maybe add a link to the data sheet). If that is the case, you may save a lot of time.

    Best regards,

    Simon

Reply
  • I just talked to a colleague familiar with this stuff, and asked if at25xe081 was supported by the spi_nor driver. He said as far as he knew, most of the NOR chips should be supported by the spi_nor driver, and most of the commands from the data sheets seems to be generic, so it should not be a problem as far as he knew.

    To get more details, and a more certain answer, try to ask the Zephyr experts on Zephyr Discord, if at25xe081 is supported by the spi_nor driver (Maybe add a link to the data sheet). If that is the case, you may save a lot of time.

    Best regards,

    Simon

Children
  • Thank you for information, Simon.

    Maybe you can also provide a hint on how to debug the bootloader?

  • mesh777 said:
    Maybe you can also provide a hint on how to debug the bootloader?

    Ah, yes. Of course. If you debug through VS Code GDB it should be quite straightforward. See the following video: https://youtu.be/MGsZJpdLtco?list=PLx_tBuQ_KSqEt7NK-H7Lu78lT2OijwIMl&t=30 

    Then set a break point in <ncs location>/bootloader/mcuboot/boot/zephyr/main.c-->main() and you can start to debug.

    Let me know if you don't get it to work.

  • I use VS Code and GDB.

    Can you share working launch.json, as I am not able to manage to reach that breakpoint.

    EDIT: I enabled debugging by unchecking Debug Options in build configuration.

    Now I have problem with device_get_binding, it returns Null for my driver. Although MCUBoot uses the same dts file when building. What else could be possibly wrong?

  • mesh777 said:
    Now I have problem with device_get_binding, it returns Null for my driver. Although MCUBoot uses the same dts file when building. What else could be possibly wrong?

    There may be different reasons for the failure of device_get_binding(). I can see in the overlay you provider earlier that label="AT25XE081", so maybe you could start by putting a break point in mcuboot when device_get_binding() is called and check that it evaluates to device_get_binding("AT25XE081").

    Maybe also check the file build/mcuboot/zephyr/zephyr.dts (notice that this is a different path than build/zephyr/zephyr.dts), and check if you find the at25x node, and that it is enabled. If not, you probably need to enable it following the approaches explained in https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/nrf/ug_multi_image.html#image-specific-variables.

    If the init function of you driver fails (the function that is passed into DEVICE_DT_INST_DEFINE, like done here), the call to device_get_binding will also fail.

    In this reply I give some detailed explanations about why init function need to be successful for device_get_binding() to succeed, if you're interested. It may be a bit outdated due to an older NCS version.

    Best regards,

    Simon

  • I checked build/mcuboot/zephyr/zephyr.dts, at25x appears in spi2 node. Also device_get_binding is called with correct label.

    However init function is not called. In driver file the following macro is added at the end of file:

    DEVICE_DT_INST_DEFINE(0, &spi_flash_init, NULL,
             &spi_flash_data_0, &spi_flash_config_0,
             POST_KERNEL, 80,
             &spi_flash_api);
    And spi_flash_init is not called. What I am still missing?