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

Problem with mesh DFU

Hi,

I already asked a similar question 6 month ago (ticket) but we never got a solution to this.

Now, after 15 month of development, our mesh-applications are almost finished and we really need DFU.

To be able to upload code, I open a private ticket here.

Our mesh-client is now running on Mesh SDK 3.1.0 and SDK 15.2. This client is supposed to get DFU-updates via UART0.

Our script for programming the client:

@echo off
for /f "tokens=1,2 delims==" %%a in (version.ini) do (
	if %%a==client_version set client_version=%%b
)
echo __________Connectivity Client Version: %client_version%__________
@echo:
echo __________Device page erstellen____________________
cd pc-nrfutil-mesh_dfu
cd dfu
REM bootloader_config_default.json erstellen (bestehende Version der Firmware)
set /a "prior_version=%client_version%-1"
 (
   echo {
   echo     "bootloader_config": {
   echo        "bootloader_id": 1,
   echo        "bootloader_version": 1,
   echo        "company_id": 89,
   echo        "application_id": 1,
   echo        "application_version": %prior_version%
   echo    }
   echo }
 ) > bootloader_config_default.json
python device_page_generator.py -d nrf52840_xxAA -sd "s140_6.0.0" -o ../client.hex
cd ..
@echo:
echo __________Programmieren____________________________
nrfjprog --recover -f NRF52
REM use --verify to verify programming with --program
nrfjprog --eraseall
nrfjprog --program ../../Mesh_SDK/bin/softdevice/s140_nrf52_6.0.0_softdevice.hex --chiperase --verify
nrfjprog --program bootloader/mesh_bootloader_serial_gccarmemb_nrf52840_xxAA.hex --verify
nrfjprog --program ../../Source/connectivity_client/build/connectivity_client_Release/connectivity_client.hex --verify
nrfjprog --program client.hex --verify
nrfjprog --memrd 0x10001014
nrfjprog --readcode my_flash_dump.txt
nrfjprog --reset
@echo:
cd ..

pause

Our script for updating the client: 

@echo off
for /f "tokens=1,2 delims==" %%a in (version.ini) do (
if %%a==client_version set client_version=%%b
if %%a==Comport set Comport=%%b
)
@echo off
echo __________Connectivity Client Version: %client_version%__________

cd pc-nrfutil-mesh_dfu
@echo:
echo __________DFU file erstellen_______________________
nrfutil dfu genpkg --application ..\..\Source\connectivity_client\build\connectivity_client_release\connectivity_client.hex --company-id 0x00000059 --application-id 1 --application-version %client_version% --sd-req 0x00A9 --mesh client.zip
@echo:
echo __________DFU Update an COM%Comport%_______________________
nrfutil --verbose dfu serial -pkg client.zip -p COM%Comport% -b 115200 -i 300 -fc --mesh
@echo:
cd ..
pause

The output when updating:

__________DFU Update an COM6_______________________
Upgrading target on COM6 with DFU package C:\Users\se\Desktop\Oblamatik\Connectivityair_15.2_3.10\DFU\pc-nrfutil-mesh_dfu\client.zip. Flow control is enabled.
Flushing com-port...
Opened com-port
Starting DFU upgrade of type 4, SoftDevice size: 0, bootloader size: 0, application size: 122220
Sending DFU start packet, afterwards we wait for the flash on target to be initialized before continuing.
PC -> target: 0502aabbccdd
target -> PC: 0582aabbccdd
Got echo response
Sending DFU init packet
PC -> target: 1378fdff040f65c3e7d559000000010002000000
target -> PC: 16a6045900000001000200000059000000010001000000
target -> PC: 03847800
PC -> target: 1378fdff040f65c3e7d559000000010002000000
target -> PC: 03847800
PC -> target: 1478fcff000065c3e7d5ffffffff5b77000000000c
target -> PC: 0da2010459000000010002000000
target -> PC: 03847800
Sending firmware file
  [------------------------------------]    1%  00:11:52PC -> target: 1978fcff010065c3e7d500f0032059620200896202008b620200
PC -> target: 1978fcff010065c3e7d500f0032059620200896202008b620200
target -> PC: 03847887
target -> PC: 03840082
PC -> target: 1978fcff010065c3e7d500f0032059620200896202008b620200
PC -> target: 1978fcff010065c3e7d500f0032059620200896202008b620200
PC -> target: 1978fcff010065c3e7d500f0032059620200896202008b620200


Failed to upgrade target. Error is: Device returned status code ERROR_INVALID_DATA (135) on a DFU data packet.

and sometimes it outputs:

 Starting DFU upgrade of type 4, SoftDevice size: 0, bootloader size: 0, application size: 122220
Sending DFU start packet, afterwards we wait for the flash on target to be initialized before continuing.
PC -> target: 0502aabbccdd
target -> PC: 0582aabbccdd
Got echo response
Sending DFU init packet
PC -> target: 1378fdff040fed78a76359000000010002000000
target -> PC: 16a6045900000001000200000059000000010001000000
target -> PC: 03847800
PC -> target: 1378fdff040fed78a76359000000010002000000
target -> PC: 03847800
PC -> target: 1478fcff0000ed78a763ffffffff5b77000000000c
PC -> target: 1478fcff0000ed78a763ffffffff5b77000000000c
PC -> target: 1478fcff0000ed78a763ffffffff5b77000000000c
PC -> target: 1478fcff0000ed78a763ffffffff5b77000000000c
PC -> target: 1478fcff0000ed78a763ffffffff5b77000000000c


Failed to upgrade target. Error is: Crashed on start packet

RTT outputs the following during the DFU-update:

 0> <t:    1523878>, nrf_mesh_dfu.c,  390, 	New firmware!
 0> <t:    1523881>, mesh.c,  744, DFU update application 
 0> <t:    1523883>, mesh.c,  778, DFU me 
 0> <t:    1523885>, nrf_mesh_dfu.c,  528, 	RADIO TX! SLOT 0, count 255, interval: periodic, handle: FFFD
 0> <t:    1523889>, nrf_mesh_dfu.c,  534, Killing a TX slot prematurely (repeats done: 5).
 0> <t:    1523893>, nrf_mesh_dfu.c,  561, 	SERIAL TX!
 0> <t:    1590164>, nrf_mesh_dfu.c,  528, 	RADIO TX! SLOT 0, count 255, interval: periodic, handle: FFFD
 0> <t:    1590168>, nrf_mesh_dfu.c,  534, Killing a TX slot prematurely (repeats done: 0).
 0> <t:    1590172>, nrf_mesh_dfu.c,  561, 	SERIAL TX!
 0> <t:    1656741>, nrf_mesh_dfu.c,  430, 	DFU start
 0> <t:    1656743>, mesh.c,  792, DFU start 
 0> <t:    1656746>, nrf_mesh_dfu.c,  528, 	RADIO TX! SLOT 1, count 6, interval: exponential, handle: FFFC
 0> <t:    1739614>, nrf_mesh_dfu.c,  329, Erase complete (0x44000)
 0> <t:    1739617>, nrf_mesh_dfu.c,  333, Flash idle.

I already tried making changes like described here, but this didn't help.

What could be the problem here?

Best regards

Gerry

Parents
  • Hi Gerry, 

    Your client.zip worked fine for me here. 


    I haven't tested to flash your client.hex file but only use our SDK's dfu example to do a DFU. (I'm not sure if you use the same UART pins in your client.hex,) 

    Could you try testing using our DFU example ? I attached our main.c file with the fixplease replace with the original main.c and send us the RTT log file after you test. The .hex of the DFU application is also attached. 

    dfu_nrf52840_xxAA_s140_6.1.0.hex

    /* Copyright (c) 2010 - 2018, Nordic Semiconductor ASA
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     * list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    #include <boards.h>
    #include "nrf_mesh_events.h"
    #include "log.h"
    #include "nrf_mesh_dfu.h"
    #include "mesh_app_utils.h"
    #include "mesh_stack.h"
    #include "ble_softdevice_support.h"
    #include "mesh_provisionee.h"
    #include "nrf_mesh_config_examples.h"
    #include "simple_hal.h"
    #include "app_timer.h"
    #include "example_common.h"
    #include "mesh_app_utils.h"
    #include "nrf_mesh_configure.h"
    
    #ifndef NRF_MESH_SERIAL_ENABLE
    #define NRF_MESH_SERIAL_ENABLE 1
    #endif
    
    #if NRF_MESH_SERIAL_ENABLE
    #include "nrf_mesh_serial.h"
    #endif
    
    #if defined(NRF51) && defined(NRF_MESH_STACK_DEPTH)
    #include "stack_depth.h"
    #endif
    
    
    #define STATIC_AUTH_DATA {0x6E, 0x6F, 0x72, 0x64, 0x69, 0x63, 0x5F, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x5F, 0x31}
    
    #if defined(NRF51)
        #define FLASH_PAGE_SIZE                 ( 0x400)
        #define FLASH_PAGE_MASK             (0xFFFFFC00)
    #elif defined(NRF52_SERIES)
        #define FLASH_PAGE_SIZE                 (0x1000)
        #define FLASH_PAGE_MASK             (0xFFFFF000)
    #endif
    
    #if defined(_lint)
        const volatile uint32_t * rom_base   = NULL;
        const volatile uint32_t * rom_length = NULL;
        uint32_t rom_end;
        uint32_t bank_addr;
    #elif defined ( __CC_ARM )
        extern uint32_t Image$$ER_IROM1$$Base;
        extern uint32_t Image$$ER_IROM1$$Length;
        const volatile uint32_t * rom_base   = &Image$$ER_IROM1$$Base;
        const volatile uint32_t * rom_length = &Image$$ER_IROM1$$Length;
        uint32_t rom_end;
        uint32_t bank_addr;
    #elif defined   ( __GNUC__ )
        extern uint32_t _start;
        extern uint32_t __exidx_end;
        const volatile uint32_t rom_base   = (uint32_t) &_start;
        const volatile uint32_t rom_end    = (uint32_t) &__exidx_end;
        uint32_t rom_length;
        uint32_t bank_addr;
    #endif
    
    static nrf_mesh_evt_handler_t m_evt_handler;
    static bool m_device_provisioned;
    
    
    static bool fw_updated_event_is_for_me(const nrf_mesh_evt_dfu_t * p_evt)
    {
        switch (p_evt->fw_outdated.transfer.dfu_type)
        {
            case NRF_MESH_DFU_TYPE_APPLICATION:
                return (p_evt->fw_outdated.current.application.app_id == p_evt->fw_outdated.transfer.id.application.app_id &&
                        p_evt->fw_outdated.current.application.company_id == p_evt->fw_outdated.transfer.id.application.company_id &&
                        p_evt->fw_outdated.current.application.app_version < p_evt->fw_outdated.transfer.id.application.app_version);
    
            case NRF_MESH_DFU_TYPE_BOOTLOADER:
                return (p_evt->fw_outdated.current.bootloader.bl_id == p_evt->fw_outdated.transfer.id.bootloader.bl_id &&
                        p_evt->fw_outdated.current.bootloader.bl_version < p_evt->fw_outdated.transfer.id.bootloader.bl_version);
    
            case NRF_MESH_DFU_TYPE_SOFTDEVICE:
                return false;
    
            default:
                return false;
        }
    }
    static uint32_t * optimal_bank_address(void)
    {
        /* The incoming transfer has to fit on both sides of the bank address: First it needs to fit
         * above the bank address when we receive it, then it needs to fit below the bank address when
         * we install it. We want to put the bank address in the middle of the available application
         * code area, to maximize the potential transfer size we can accept. */
        const uint32_t * p_start;
        uint32_t dummy;
        ERROR_CHECK(mesh_stack_persistence_flash_usage(&p_start, &dummy));
    
        uint32_t middle_of_app_area = (CODE_START + (intptr_t) p_start) / 2;
    
        /* The bank can't start in the middle of the application code, and should be page aligned: */
        return (uint32_t *) ALIGN_VAL(MAX(middle_of_app_area, CODE_END), PAGE_SIZE);
    }
    
    static void mesh_evt_handler(const nrf_mesh_evt_t* p_evt)
    {
        switch (p_evt->type)
        {
            case NRF_MESH_EVT_DFU_FIRMWARE_OUTDATED:
            case NRF_MESH_EVT_DFU_FIRMWARE_OUTDATED_NO_AUTH:
                if (fw_updated_event_is_for_me(&p_evt->params.dfu))
                {
                    __LOG(LOG_SRC_APP, LOG_LEVEL_DBG2, "bank_addr   %X\n", optimal_bank_address());
                    ERROR_CHECK(nrf_mesh_dfu_request(p_evt->params.dfu.fw_outdated.transfer.dfu_type,
                                                     &p_evt->params.dfu.fw_outdated.transfer.id,
                                                   optimal_bank_address()));
                                                  //   (uint32_t*) bank_addr));
                    hal_led_mask_set(LEDS_MASK, false); /* Turn off all LEDs */
                }
                else
                {
                    ERROR_CHECK(nrf_mesh_dfu_relay(p_evt->params.dfu.fw_outdated.transfer.dfu_type,
                                                   &p_evt->params.dfu.fw_outdated.transfer.id));
                }
                break;
    
            case NRF_MESH_EVT_DFU_START:
                hal_led_mask_set(BSP_LED_0_MASK | BSP_LED_2_MASK, true);
                break;
    
            case NRF_MESH_EVT_DFU_END:
                hal_led_mask_set(LEDS_MASK, false); /* Turn off all LEDs */
                hal_led_mask_set(BSP_LED_0_MASK | BSP_LED_1_MASK, true); /* Yellow */
                break;
    
            case NRF_MESH_EVT_DFU_BANK_AVAILABLE:
                hal_led_mask_set(LEDS_MASK, false); /* Turn off all LEDs */
                ERROR_CHECK(nrf_mesh_dfu_bank_flash(p_evt->params.dfu.bank.transfer.dfu_type));
                break;
    
            default:
                break;
    
        }
    }
    
    static void node_reset(void)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- Node reset  -----\n");
        hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_RESET);
        /* This function may return if there are ongoing flash operations. */
        mesh_stack_device_reset();
    }
    
    static void config_server_evt_cb(const config_server_evt_t * p_evt)
    {
        if (p_evt->type == CONFIG_SERVER_EVT_NODE_RESET)
        {
            node_reset();
        }
    }
    
    static void mesh_init(void)
    {
        mesh_stack_init_params_t init_params =
        {
            .core.irq_priority       = NRF_MESH_IRQ_PRIORITY_LOWEST,
            .core.lfclksrc           = DEV_BOARD_LF_CLK_CFG,
            .models.config_server_cb = config_server_evt_cb
        };
        ERROR_CHECK(mesh_stack_init(&init_params, &m_device_provisioned));
    
    #if NRF_MESH_SERIAL_ENABLE
        ERROR_CHECK(nrf_mesh_serial_init(NULL));
    #endif
    
        m_evt_handler.evt_cb = mesh_evt_handler;
        nrf_mesh_evt_handler_add(&m_evt_handler);
    }
    
    static void initialize(void)
    {
    #if defined(NRF51) && defined(NRF_MESH_STACK_DEPTH)
        stack_depth_paint_stack();
    #endif
    
        ERROR_CHECK(app_timer_init());
        hal_leds_init();
    
        __LOG_INIT(LOG_MSK_DEFAULT | LOG_SRC_DFU | LOG_SRC_APP | LOG_SRC_SERIAL, LOG_LEVEL_DBG2, log_callback_rtt);
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- Bluetooth Mesh DFU Example -----\n");
    
    #if defined ( __CC_ARM )
        rom_end    = (uint32_t) rom_base + (uint32_t) rom_length;
    #elif defined   ( __GNUC__ )
        rom_length = (uint32_t) rom_end - rom_base;
    #endif
        /* Take the next available page address */
        bank_addr  = (uint32_t) (rom_end & FLASH_PAGE_MASK) + FLASH_PAGE_SIZE;
        __LOG(LOG_SRC_APP, LOG_LEVEL_DBG2, "rom_base   %X\n", rom_base);
        __LOG(LOG_SRC_APP, LOG_LEVEL_DBG2, "rom_end    %X\n", rom_end);
        __LOG(LOG_SRC_APP, LOG_LEVEL_DBG2, "rom_length %X\n", rom_length);
    
        __LOG(LOG_SRC_APP, LOG_LEVEL_DBG2, "bank_addr   %X\n", bank_addr);
    
        ble_stack_init();
    
        mesh_init();
        __LOG(LOG_SRC_APP, LOG_LEVEL_DBG2, "optimal bank addr   %X\n", optimal_bank_address());
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Initialization complete!\n");
    }
    
    static void start(void)
    {
        if (!m_device_provisioned)
        {
            static const uint8_t static_auth_data[NRF_MESH_KEY_SIZE] = STATIC_AUTH_DATA;
            mesh_provisionee_start_params_t prov_start_params =
            {
                .p_static_data = static_auth_data,
                .prov_complete_cb = NULL,
                .prov_device_identification_start_cb = NULL,
                .prov_device_identification_stop_cb = NULL,
                .prov_abort_cb = NULL,
                .p_device_uri = EX_URI_DFU
            };
            ERROR_CHECK(mesh_provisionee_prov_start(&prov_start_params));
        }
    
    #if NRF_MESH_SERIAL_ENABLE
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Enabling serial interface...\n");
        ERROR_CHECK(nrf_mesh_serial_enable());
    #endif
    
        mesh_app_uuid_print(nrf_mesh_configure_device_uuid_get());
    
        ERROR_CHECK(mesh_stack_start());
    
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "DFU example started!\n");
    }
    
    int main(void)
    {
        initialize();
        start();
    
        for (;;)
        {
            (void)sd_app_evt_wait();
        }
    }
    

Reply
  • Hi Gerry, 

    Your client.zip worked fine for me here. 


    I haven't tested to flash your client.hex file but only use our SDK's dfu example to do a DFU. (I'm not sure if you use the same UART pins in your client.hex,) 

    Could you try testing using our DFU example ? I attached our main.c file with the fixplease replace with the original main.c and send us the RTT log file after you test. The .hex of the DFU application is also attached. 

    dfu_nrf52840_xxAA_s140_6.1.0.hex

    /* Copyright (c) 2010 - 2018, Nordic Semiconductor ASA
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     * list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    #include <boards.h>
    #include "nrf_mesh_events.h"
    #include "log.h"
    #include "nrf_mesh_dfu.h"
    #include "mesh_app_utils.h"
    #include "mesh_stack.h"
    #include "ble_softdevice_support.h"
    #include "mesh_provisionee.h"
    #include "nrf_mesh_config_examples.h"
    #include "simple_hal.h"
    #include "app_timer.h"
    #include "example_common.h"
    #include "mesh_app_utils.h"
    #include "nrf_mesh_configure.h"
    
    #ifndef NRF_MESH_SERIAL_ENABLE
    #define NRF_MESH_SERIAL_ENABLE 1
    #endif
    
    #if NRF_MESH_SERIAL_ENABLE
    #include "nrf_mesh_serial.h"
    #endif
    
    #if defined(NRF51) && defined(NRF_MESH_STACK_DEPTH)
    #include "stack_depth.h"
    #endif
    
    
    #define STATIC_AUTH_DATA {0x6E, 0x6F, 0x72, 0x64, 0x69, 0x63, 0x5F, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x5F, 0x31}
    
    #if defined(NRF51)
        #define FLASH_PAGE_SIZE                 ( 0x400)
        #define FLASH_PAGE_MASK             (0xFFFFFC00)
    #elif defined(NRF52_SERIES)
        #define FLASH_PAGE_SIZE                 (0x1000)
        #define FLASH_PAGE_MASK             (0xFFFFF000)
    #endif
    
    #if defined(_lint)
        const volatile uint32_t * rom_base   = NULL;
        const volatile uint32_t * rom_length = NULL;
        uint32_t rom_end;
        uint32_t bank_addr;
    #elif defined ( __CC_ARM )
        extern uint32_t Image$$ER_IROM1$$Base;
        extern uint32_t Image$$ER_IROM1$$Length;
        const volatile uint32_t * rom_base   = &Image$$ER_IROM1$$Base;
        const volatile uint32_t * rom_length = &Image$$ER_IROM1$$Length;
        uint32_t rom_end;
        uint32_t bank_addr;
    #elif defined   ( __GNUC__ )
        extern uint32_t _start;
        extern uint32_t __exidx_end;
        const volatile uint32_t rom_base   = (uint32_t) &_start;
        const volatile uint32_t rom_end    = (uint32_t) &__exidx_end;
        uint32_t rom_length;
        uint32_t bank_addr;
    #endif
    
    static nrf_mesh_evt_handler_t m_evt_handler;
    static bool m_device_provisioned;
    
    
    static bool fw_updated_event_is_for_me(const nrf_mesh_evt_dfu_t * p_evt)
    {
        switch (p_evt->fw_outdated.transfer.dfu_type)
        {
            case NRF_MESH_DFU_TYPE_APPLICATION:
                return (p_evt->fw_outdated.current.application.app_id == p_evt->fw_outdated.transfer.id.application.app_id &&
                        p_evt->fw_outdated.current.application.company_id == p_evt->fw_outdated.transfer.id.application.company_id &&
                        p_evt->fw_outdated.current.application.app_version < p_evt->fw_outdated.transfer.id.application.app_version);
    
            case NRF_MESH_DFU_TYPE_BOOTLOADER:
                return (p_evt->fw_outdated.current.bootloader.bl_id == p_evt->fw_outdated.transfer.id.bootloader.bl_id &&
                        p_evt->fw_outdated.current.bootloader.bl_version < p_evt->fw_outdated.transfer.id.bootloader.bl_version);
    
            case NRF_MESH_DFU_TYPE_SOFTDEVICE:
                return false;
    
            default:
                return false;
        }
    }
    static uint32_t * optimal_bank_address(void)
    {
        /* The incoming transfer has to fit on both sides of the bank address: First it needs to fit
         * above the bank address when we receive it, then it needs to fit below the bank address when
         * we install it. We want to put the bank address in the middle of the available application
         * code area, to maximize the potential transfer size we can accept. */
        const uint32_t * p_start;
        uint32_t dummy;
        ERROR_CHECK(mesh_stack_persistence_flash_usage(&p_start, &dummy));
    
        uint32_t middle_of_app_area = (CODE_START + (intptr_t) p_start) / 2;
    
        /* The bank can't start in the middle of the application code, and should be page aligned: */
        return (uint32_t *) ALIGN_VAL(MAX(middle_of_app_area, CODE_END), PAGE_SIZE);
    }
    
    static void mesh_evt_handler(const nrf_mesh_evt_t* p_evt)
    {
        switch (p_evt->type)
        {
            case NRF_MESH_EVT_DFU_FIRMWARE_OUTDATED:
            case NRF_MESH_EVT_DFU_FIRMWARE_OUTDATED_NO_AUTH:
                if (fw_updated_event_is_for_me(&p_evt->params.dfu))
                {
                    __LOG(LOG_SRC_APP, LOG_LEVEL_DBG2, "bank_addr   %X\n", optimal_bank_address());
                    ERROR_CHECK(nrf_mesh_dfu_request(p_evt->params.dfu.fw_outdated.transfer.dfu_type,
                                                     &p_evt->params.dfu.fw_outdated.transfer.id,
                                                   optimal_bank_address()));
                                                  //   (uint32_t*) bank_addr));
                    hal_led_mask_set(LEDS_MASK, false); /* Turn off all LEDs */
                }
                else
                {
                    ERROR_CHECK(nrf_mesh_dfu_relay(p_evt->params.dfu.fw_outdated.transfer.dfu_type,
                                                   &p_evt->params.dfu.fw_outdated.transfer.id));
                }
                break;
    
            case NRF_MESH_EVT_DFU_START:
                hal_led_mask_set(BSP_LED_0_MASK | BSP_LED_2_MASK, true);
                break;
    
            case NRF_MESH_EVT_DFU_END:
                hal_led_mask_set(LEDS_MASK, false); /* Turn off all LEDs */
                hal_led_mask_set(BSP_LED_0_MASK | BSP_LED_1_MASK, true); /* Yellow */
                break;
    
            case NRF_MESH_EVT_DFU_BANK_AVAILABLE:
                hal_led_mask_set(LEDS_MASK, false); /* Turn off all LEDs */
                ERROR_CHECK(nrf_mesh_dfu_bank_flash(p_evt->params.dfu.bank.transfer.dfu_type));
                break;
    
            default:
                break;
    
        }
    }
    
    static void node_reset(void)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- Node reset  -----\n");
        hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_RESET);
        /* This function may return if there are ongoing flash operations. */
        mesh_stack_device_reset();
    }
    
    static void config_server_evt_cb(const config_server_evt_t * p_evt)
    {
        if (p_evt->type == CONFIG_SERVER_EVT_NODE_RESET)
        {
            node_reset();
        }
    }
    
    static void mesh_init(void)
    {
        mesh_stack_init_params_t init_params =
        {
            .core.irq_priority       = NRF_MESH_IRQ_PRIORITY_LOWEST,
            .core.lfclksrc           = DEV_BOARD_LF_CLK_CFG,
            .models.config_server_cb = config_server_evt_cb
        };
        ERROR_CHECK(mesh_stack_init(&init_params, &m_device_provisioned));
    
    #if NRF_MESH_SERIAL_ENABLE
        ERROR_CHECK(nrf_mesh_serial_init(NULL));
    #endif
    
        m_evt_handler.evt_cb = mesh_evt_handler;
        nrf_mesh_evt_handler_add(&m_evt_handler);
    }
    
    static void initialize(void)
    {
    #if defined(NRF51) && defined(NRF_MESH_STACK_DEPTH)
        stack_depth_paint_stack();
    #endif
    
        ERROR_CHECK(app_timer_init());
        hal_leds_init();
    
        __LOG_INIT(LOG_MSK_DEFAULT | LOG_SRC_DFU | LOG_SRC_APP | LOG_SRC_SERIAL, LOG_LEVEL_DBG2, log_callback_rtt);
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- Bluetooth Mesh DFU Example -----\n");
    
    #if defined ( __CC_ARM )
        rom_end    = (uint32_t) rom_base + (uint32_t) rom_length;
    #elif defined   ( __GNUC__ )
        rom_length = (uint32_t) rom_end - rom_base;
    #endif
        /* Take the next available page address */
        bank_addr  = (uint32_t) (rom_end & FLASH_PAGE_MASK) + FLASH_PAGE_SIZE;
        __LOG(LOG_SRC_APP, LOG_LEVEL_DBG2, "rom_base   %X\n", rom_base);
        __LOG(LOG_SRC_APP, LOG_LEVEL_DBG2, "rom_end    %X\n", rom_end);
        __LOG(LOG_SRC_APP, LOG_LEVEL_DBG2, "rom_length %X\n", rom_length);
    
        __LOG(LOG_SRC_APP, LOG_LEVEL_DBG2, "bank_addr   %X\n", bank_addr);
    
        ble_stack_init();
    
        mesh_init();
        __LOG(LOG_SRC_APP, LOG_LEVEL_DBG2, "optimal bank addr   %X\n", optimal_bank_address());
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Initialization complete!\n");
    }
    
    static void start(void)
    {
        if (!m_device_provisioned)
        {
            static const uint8_t static_auth_data[NRF_MESH_KEY_SIZE] = STATIC_AUTH_DATA;
            mesh_provisionee_start_params_t prov_start_params =
            {
                .p_static_data = static_auth_data,
                .prov_complete_cb = NULL,
                .prov_device_identification_start_cb = NULL,
                .prov_device_identification_stop_cb = NULL,
                .prov_abort_cb = NULL,
                .p_device_uri = EX_URI_DFU
            };
            ERROR_CHECK(mesh_provisionee_prov_start(&prov_start_params));
        }
    
    #if NRF_MESH_SERIAL_ENABLE
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Enabling serial interface...\n");
        ERROR_CHECK(nrf_mesh_serial_enable());
    #endif
    
        mesh_app_uuid_print(nrf_mesh_configure_device_uuid_get());
    
        ERROR_CHECK(mesh_stack_start());
    
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "DFU example started!\n");
    }
    
    int main(void)
    {
        initialize();
        start();
    
        for (;;)
        {
            (void)sd_app_evt_wait();
        }
    }
    

Children
No Data
Related