This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Mesh DFU dfu_cmd_handler_set always failing?

Hi @ll,

I'm still trying to get the Mesh DFU example up and running. I'm following the guide in the documentation. (Mesh Version 2.0.0: it's the same in 2.0.1 so don't worry about the version)

Setup: Everything flashed (Softdevice 6.0.0, Bootloader, DevicePage and DFU example application)

Once I try to send a dfu packet the device throws this error:
<t:     452185>, nrf_mesh_dfu.c,  901, ERROR: No CMD handler!

Looking at the code I found something that looks strange to me:
nrf_mesh_dfu.c in mesh/dfu/src

uint32_t nrf_mesh_dfu_init(void)
{
    uint32_t error_code;
#if !defined(HOST)
    error_code = dfu_cmd_handler_set(*((bl_if_cmd_handler_t*) (DEVICE_DATA_RAM_END_GET() - sizeof(bl_if_cmd_handler_t))));
    if (error_code != NRF_SUCCESS)
    {
        m_transfer_state.state = NRF_MESH_DFU_STATE_INITIALIZED;
        return NRF_ERROR_NOT_SUPPORTED;
    }

This part calls dfu_cmd_handler_set with an address that is in the range of RAM (for the nRF52 about 0x2000xxxx)

But the function it self does/checks this:
nrf_mesh_dfu.c in mesh/dfu/src

static uint32_t dfu_cmd_handler_set(bl_if_cmd_handler_t handler)
{
    if (handler == NULL)
    {
        return NRF_ERROR_NULL;
    }
    if (BOOTLOADERADDR() == 0xFFFFFFFF)
    {
        /* No bootloader present. */
        return NRF_ERROR_NOT_SUPPORTED;
    }
    if (((uint32_t) handler >= DEVICE_FLASH_END_GET()) ||
        ((uint32_t) handler < BOOTLOADERADDR()))
    {
        /* out of bounds. */
        return NRF_ERROR_INVALID_ADDR;
    }

So it compares the address it gets with a FLASH address? Speaking about address in the range of 0x00000000-0x00080000.

So this will always return NRF_ERROR_INVALID_ADDR in case there is a bootloader address in NRF_UICR->NRFFW[0]? Otherwise it will always return NRF_ERROR_INVALID_ADDR?

Maybe I got something wrong Confounded

Thank you in advance for your help Slight smile

Bye
Andrej

  • Hi Andrej, 

    Did you use SES to build the DFU project ? 

    If you did, could you try a quick patch to see if it fixes the issue for you? R&D told me about the bug that SES-built firmware will clear the RAM part of the bootloader and cause the CMD handler location to be NULL.

    In examples/dfu/flash_placement.xml, change line 32 from

      <MemorySegment name="RAM" start="$(RAM_PH_START)" size="$(RAM_PH_SIZE)">

    to

      <MemorySegment name="RAM" start="$(RAM_PH_START)" size="$(RAM_SIZE)">

     

    Please let me know if it fixes the issue. 

  • Hi Hung,

    this solution is working. Thanks for that.
    But I still have a massiv problem with the serial communication using SEGGER 6.16c on my linux machine. Disappointed

    It looks like this communication is only working by chance as it is almost always working on my windows machine.

    Is there a way to replace everything SEGGER<->UART related by external USB<->UART?

    Bye
    Andrej

  • Hi Andrej, 

    If you have your own UART port on your PC you don't have to use the SEGGER one. Just configure the firmware on the chip to use different UART pin and use those pins to connect to your USB-UART. 

    As far as I remember the communication were quite stable when we were at the training ?

     

  • Hi Hung,

    changing the pins for the bootloader will be hard without the source code. Disappointed

    The serial communication was not working all the time at the training. Once it worked we kept everything open and running. Once we disconnected something and tried to use it again we had the timeout issue again. Remember?

    Bye
    Andrej

  • I now bypassed the problem by now, just in case someone has the same problem on a Linux machine:

    https://cote.cc/blog/serialproxy-v014-can-use-com-ports-above-9
    Used SerProxy 0.1.4 on my Windows machine to forward the COM-Port to TCP/IP

    Connected on my Linux machine the TCP/IP to a virtual modem:
    sudo socat pty,link=/dev/vmodem0,raw tcp:x.x.x.x:xxxx

    Then used nrfutil for mesh with the virtual modem as serial interface.

    --> Working

    But this is just a workaround. Please solve this issue as I need two machines for this and it might not be that reliable.

    I hope this will help some people.

    Bye
    Andrej

    P.S.: If someone has the same problem it might be also possible to forward the USB device (DevKit) to a Windows VM that is then in a private network with the host. Not confirmed but should work. Using this method you would one have to use one physical machine. Could not test it due to license issues (no additional corporate Windows license)

Related