Custom board DFU on USB port on VS Code

Hello,

i'm using VS Code + Nrf Connect SDK (SDK/Toolchain 2.3.0) to develop firmware for a custom board based on nrf5340. I'm trying to use the USB port of the board (connected to D+ and D- pins of the nrf5340 chip) for both debugging (serial console) and firmware upgrade (DFU). My dream-goal would be having the custom board to behave similarly to a nrf5340DK: i can connect it through USB, it pops up automatically on "Connected Devices" VS Code view and i can flash it pressing "Flash" on Action View. Generally, it would be enough to be able to program it using the USB with whatever software.

Until now, starting from this tutorial and consulting a lot of Kconfig reference and the Zephyr board porting guide i have been able to achieve the following results:

- Build (using VS Code) and flash (using SWD port) the hello world example specifically for my custom board (with custom_board.dts, custom_board_defconfig, etc.)

- Enable MCUBoot subsystem

- Build correctly using MCUMGR options (see prj.conf code below);

- Enable USB console (my "Helloworld" printk statements are printed on serial console through USB connection, tested using Putty software)

However, i'm still missing something to enable DFU. I know that i need to start from SMP_server_sample and configurate MCUMGR correctly, but i'm a bit confused on what is the working procedure.

Here below is my proj.conf

# --------------------------------------- MCUBOOT CONFIG SETTINGS --------------------------------------#

# Enable mcumgr.
CONFIG_MCUMGR=y

# Enable most core commands.
CONFIG_MCUMGR_CMD_IMG_MGMT=y
CONFIG_MCUMGR_CMD_OS_MGMT=y

# Ensure an MCUboot-compatible binary is generated.
CONFIG_BOOTLOADER_MCUBOOT=y

# Enable the serial mcumgr transport.
CONFIG_MCUMGR_SMP_UART=y

# --------------------------------------- RTT CONSOLE CONFIG SETTINGS --------------------------------------#
#Use this config as alternatives to USB console. USB needs "UART_CONSOLE" dependency, here disabled, so they cannot be used together

# Disable UART Console and enable the RTT console
#CONFIG_UART_CONSOLE=n
#CONFIG_RTT_CONSOLE=y
#CONFIG_USE_SEGGER_RTT=y

# Some command handlers require a large stack.
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096


# --------------------------------------- USB CONFIG SETTINGS --------------------------------------#

# Enable the USB stack
CONFIG_USB_DEVICE_STACK=y

# Enable the CDC_ACM service -> the connected device will emulate a modem or serial port
CONFIG_USB_CDC_ACM=y

# Configure name, Product Id and Vendor ID of the USB device
CONFIG_USB_DEVICE_PRODUCT="My Custom board"
CONFIG_USB_DEVICE_PID=0x0110
# CONFIG_USB_DEVICE_VID=0x2FE3   // Zephyr project Device ID - Only for development

# Inizialize USB automatically at boot time
CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y

# Enable console inputs and UART based drivers -> Logger and shell can be used on USB
CONFIG_UART_INTERRUPT_DRIVEN=y 

and here below i put the interested parts of my dts:

/ {
	model = "my_custom_board";
	compatible = "cnr-imm,my_custom_board";

	chosen {
		zephyr,sram = &sram0;
		zephyr,flash = &flash0;
		zephyr,code-partition = &slot0_partition;
		zephyr,console = &cdc_acm_uart0;
		zephyr,shell-uart = &uart0;
		zephyr,uart-mcumgr = &uart0;
				
		/* shared memory reserved for the inter-processor communication */
		zephyr,ipc_shm = &sram0_shared;
	};
};


	        

I'm missing something probably both in prj.conf (maybe CONFIG_UART_CONSOLE_MCUMGR?) and dts (maybe zephyr,uart-mcumgr = &uart0 is wrong?). Moreover, i'm missing something aboout procedure (is it possible to flash the custom board using VS Code?)

Thank you for any hint you can provide me

Frax

Parents
  • Hi,

    The nRF5340 DK has an onboard debugger (on recent versions that is another nRF5340 with Segger firmware). For a custom board you will need that in order to be able to debug it. Without it the only thing you can get via USB is logging via CDC ACM, which I see you already got working.

    nRF Connect for VS Code only supports flashing via a debugger, it has no DFU support, so that needs to be handled separately (typically via mcumgr).

    To get DFU via USB working for development and also logging via DFU working I would consider using serial recovery with USB, so that the USB is used only for DFU in MCUboot and only for logging/console when the application is running. A colleague of mine have made some samples for serial recovery, including via USB here, which I suggest you refer to. 

  • Here i come again,

    it has been very hard to understand what i needed. There is a lot of confusing materials due to the fragmentation in nrf connect sdk and zephyr versions. There are tons of variations on the theme. In the end, i'm still stuck with my issue, but at least now i have an "improved knowledge" on the topic.

    Respect to the last time i created a "child_image" folder and a "mcuboot.conf" file with these settings:

    # Enable MCUboot Serial Recovery
    CONFIG_MCUBOOT_SERIAL=y
    CONFIG_UART_CONSOLE=n
    
    # Point Serial Recovery to CDC_ACM
    CONFIG_BOOT_SERIAL_CDC_ACM=y
    
    CONFIG_BOOT_SERIAL_UART=y
    
    # Enable wait for DFU functionality
    CONFIG_BOOT_SERIAL_WAIT_FOR_DFU=y
    CONFIG_BOOT_SERIAL_WAIT_FOR_DFU_TIMEOUT=5000

    After several attempts, i decided to NOT modify my "CMakeLists.txt" file but i verified that the "mcuboot.conf" file is used in my build log. I don't know if i need to add anything in this file, there is a lot of contradictory material here and there.

    By now, i'm able to compile my "Hello world" with MCUBOOT enabled and DFU Serial with wait timeout on CDC_ACM for nrf5340dk board but it doesn't build for my custom board. It could be something related to dts file, but i'm trying casually, and a focused hint would be more effective!

    EDIT: For some reason i'm not able to add my build log.

  • Hi,

    frax84 said:
    After several attempts, i decided to NOT modify my "CMakeLists.txt" file but i verified that the "mcuboot.conf" file is used in my build log. I don't know if i need to add anything in this file, there is a lot of contradictory material here and there.

    There are several way to achieve most things, so you do not necessarily need a specific configuration file, as long as you get the configurations you need in somehow (though some methods are cleaner than others, like trying to ensure that project specific changes are in your project files and not in the SDK in general, and that board specific settings are in your board file etc).

    frax84 said:
    By now, i'm able to compile my "Hello world" with MCUBOOT enabled and DFU Serial with wait timeout on CDC_ACM for nrf5340dk board but it doesn't build for my custom board. It could be something related to dts file, but i'm trying casually, and a focused hint would be more effective!

    In order to give specific feedback we need to know more about both your project and how things fail. Can you share your project files and board files and the full build log where it fails?

    frax84 said:
    EDIT: For some reason i'm not able to add my build log.

    Some file suffixes are not possible to upload here. Could you try zipping it (together wit the other files I requested)? Then drag-and drop into the editor window here on DevZone. Alternatively, you also share logs etc via Insert -> Code and copy-past the content there.

  • There are several way to achieve most things, so you do not necessarily need a specific configuration file, as long as you get the configurations you need in somehow (though some methods are cleaner than others, like trying to ensure that project specific changes are in your project files and not in the SDK in general, and that board specific settings are in your board file etc).

    I assume the approach i used (making a child_image folder with conf file inside) goes in the direction of being "cleaner", that is always a good practice. It's just troubling/confusing to have to collect/filter the right material from many sources, but that's how open source some times works! Smiley

    Some file suffixes are not possible to upload here. Could you try zipping it (together wit the other files I requested)? Then drag-and drop into the editor window here on DevZone. Alternatively, you also share logs etc via Insert -> Code and copy-past the content there.

    I tried the "insert->Code" route, but for some reason it sometimes fail (i press OK but nothing happens). It's really random. As you could see i use "insert->Code" very often. I'm attaching a zip file. You will find all the project files and settings (boards included). In the main directory you will find "build log.txt", where i copy-pasted the build log.

    6403.hello_world_test.zip

    Again, thank you for your support

    Frax

  • Hi Frax,

    Looking at the build log the error is this:

    C:\Users\Frax\ncs\v2.3.0\bootloader\mcuboot\boot\zephyr\main.c:443:1: error: static assertion failed: ""
      443 | BUILD_ASSERT(CONFIG_BOOT_SERIAL_DETECT_PIN != -1);
          | ^~~~~~~~~~~~

    which comes from this assert in main.c from MCUboot:

    /* The value of -1 is used by default. It must be properly specified for a board before used. */
    BUILD_ASSERT(CONFIG_BOOT_SERIAL_DETECT_PIN != -1);

    And this is not set via mcuboot-button0 in the device tree. See this post. You can serach for "mcuboot-button0" in the SDK to see how most boards include an alias for mcuboot-button0, and you need to do the same in yours devicetree.

  • Hi,

    actually i don't want to use an entrance pin because my board has not. I want to use only "serial wait for DFU" with a set timeout. Thanks to the feedback you gave me i have been able to find this source with the possible Kconfig settings i can use. Among these i found:

    menuconfig BOOT_SERIAL_ENTRANCE_GPIO
    	bool "GPIO"
    	default y
    	depends on GPIO
    	help
    	  Use a GPIO to enter serial recovery mode.

    Unfortunately, when i add 

    CONFIG_BOOT_SERIAL_ENTRANCE_GPIO=n

    to my mcuboot.conf file i get a build fail for "undefined symbol". I verified the KCONFIG dependencies in the source i linked above and it seems that everything should work.

    Maybe this depends on the fact that i'm using SDK 2.3.0? I tried to use SDK 2.4.2 and, after some corrections due to version changes (see below) i am able to build and flash (CONFIG_BOOT_SERIAL_ENTRANCE_GPIO=n doesn't throw an error now). Unfortunately, i'm not able to run mcumgr commands during the time after boot, but this could be related to my inexperience with mcumgr and/or some missing Kconfig dependency i need to add to run commands.Please note that, after a certain time (not exactly the timeout set) i'm able to read kprint on my Putty console.

    In any case if you confirm me that changing the sdk is the right route to go i would appreciate it.

    For the sake of community, this is my proj.conf now:

    # --------------------------------------- MCUBOOT CONFIG SETTINGS --------------------------------------#
    
    # Enable mcumgr.
    CONFIG_NET_BUF=y
    CONFIG_ZCBOR=y
    CONFIG_MCUMGR=y
    
    # Mcumgr settings
    
    #----- SDK 2.3.0 ------
    #CONFIG_MCUMGR_CMD_IMG_MGMT=y
    #CONFIG_MCUMGR_CMD_OS_MGMT=y
    
    #----- SDK 2.4.2 ------
    CONFIG_MCUMGR_GRP_OS=y
    CONFIG_MCUMGR_GRP_IMG=y
    CONFIG_FLASH=y                  #dependency for MCUMGR_GRP_IMG
    CONFIG_IMG_MANAGER=y            #dependency for MCUMGR_GRP_IMG
    CONFIG_STREAM_FLASH=y           #dependency for IMG_MANAGER
    CONFIG_MCUBOOT_IMG_MANAGER=y
    CONFIG_FLASH_MAP=y              #dependency for MCUBOOT_IMG_MANAGER
    
    # Ensure an MCUboot-compatible binary is generated.
    CONFIG_BOOTLOADER_MCUBOOT=y
    
    # Enable the serial mcumgr transport.
    
    #----- SDK 2.3.0 ------
    # CONFIG_MCUMGR_SMP_UART=y      #for SDK 2.3.0
    
    #----- SDK 2.4.2 ------
    CONFIG_MCUMGR_TRANSPORT_UART=y  #FOR sdk 2.4.2
    CONFIG_BASE64=y                 #dependency for MCUMGR_TRANSPORT_UART
    
    # --------------------------------------- RTT CONSOLE CONFIG SETTINGS --------------------------------------#
    #Use this config as alternatives to USB console. USB needs "UART_CONSOLE" dependency, here disabled, so they cannot be used together
    
    # Disable UART Console and enable the RTT console
    #CONFIG_UART_CONSOLE=n
    #CONFIG_RTT_CONSOLE=y
    #CONFIG_USE_SEGGER_RTT=y
    
    # Some command handlers require a large stack.
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
    
    
    # --------------------------------------- USB CONFIG SETTINGS --------------------------------------#
    
    # Enable the USB stack
    CONFIG_USB_DEVICE_STACK=y
    
    # Enable the CDC_ACM service -> the connected device will emulate a modem or serial port
    CONFIG_USB_CDC_ACM=y
    
    # Configure name, Product Id and Vendor ID of the USB device
    CONFIG_USB_DEVICE_PRODUCT="My custom board"
    CONFIG_USB_DEVICE_PID=0x0110
    # CONFIG_USB_DEVICE_VID=0x2FE3   // Zephyr project Device ID - Only for development
    
    # Inizialize USB automatically at boot time
    CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y
    
    # Enable console inputs and UART based drivers -> Logger and shell can be used on USB
    CONFIG_UART_INTERRUPT_DRIVEN=y 

    and this is my child_image/mcuboot.conf:

    CONFIG_CONSOLE=y
    CONFIG_USE_SEGGER_RTT=y
    CONFIG_RTT_CONSOLE=y
    
    # Enable MCUboot Serial Recovery
    CONFIG_MCUBOOT_SERIAL=y
    CONFIG_UART_CONSOLE=n
    
    # Point Serial Recovery to CDC_ACM
    CONFIG_BOOT_SERIAL_CDC_ACM=y
    
    CONFIG_BOOT_SERIAL_UART=y
    
    # Enable wait for DFU functionality
    CONFIG_BOOT_SERIAL_ENTRANCE_GPIO=n
    CONFIG_BOOT_SERIAL_WAIT_FOR_DFU=y
    CONFIG_BOOT_SERIAL_WAIT_FOR_DFU_TIMEOUT=5000

    Any comment/suggestion?

    Frax

    EDIT: Updated all the proper dependecies with SDK 2.4.2 in proj.conf and mcuboot.conf. Now the software compiles and throw just one warning:

    CMake Warning at C:/ncs/v2.4.2/zephyr/CMakeLists.txt:839 (message):
      No SOURCES given to Zephyr library: lib__libc__common

    In the end, i'm still not able to send mcumgr commands because of NMP timeout error

  • Hi,

    You are right that CONFIG_BOOT_SERIAL_ENTRANCE_GPIO did not exist in nRF Connect SDK 2.3.0. In earlier versions there was no option to disable it in serial recovery.

    Generally I would always recommend using the latest SDK release, so now I would suggest using 2.4.2 (2.5.0 is also expected to be released quite soon).

    The CMake error you are seeing will be fixed in 2.5, but you can also fix it yourself  by doing as shown in this PR.

    Regarding the NMP timeout I suspect an issue with your serial UART configuration for your custom board. Does it work if you build for the DK?

Reply
  • Hi,

    You are right that CONFIG_BOOT_SERIAL_ENTRANCE_GPIO did not exist in nRF Connect SDK 2.3.0. In earlier versions there was no option to disable it in serial recovery.

    Generally I would always recommend using the latest SDK release, so now I would suggest using 2.4.2 (2.5.0 is also expected to be released quite soon).

    The CMake error you are seeing will be fixed in 2.5, but you can also fix it yourself  by doing as shown in this PR.

    Regarding the NMP timeout I suspect an issue with your serial UART configuration for your custom board. Does it work if you build for the DK?

Children
  • Generally I would always recommend using the latest SDK release, so now I would suggest using 2.4.2 (2.5.0 is also expected to be released quite soon).

    You're right, but when i start to develop applications i usually prefer to keep the SDK fixed unless some bug/issue arises.

    The CMake error you are seeing will be fixed in 2.5, but you can also fix it yourself  by doing as shown in this PR.

    This fix actually solved not only the CMake error but even the mcumgr nxp timeout issue without changing anything else! Now everything works and i'm able to upload new firmware image through my usb cable.

    Thank you for your support. 

Related