merging examples with DFU cause NRF_ERROR_NO_MEM

Windows 10, Segger Embedded Studio V5.60a

nRF52833-DK (also nRF52840-DK, along with custom boards for each for later purpose)

SDK 17.1.0 S140 

Hello, I'm trying to merge my project (NUS example, BAS, bonding, etc) with DFU bootloader OTA.

It's similar case with https://devzone.nordicsemi.com/f/nordic-q-a/48872/how-to-merge-one-application-with-dfu-feature

I did as instructed. It was built successfully but when executed, I get following errors:

<error> app: No bootloader was found
<error> app: ERROR 4 [NRF_ERROR_NO_MEM] at [my project address] files.c:1105
PC at: 0x000414C5
<error> app: End of error report

the error is pointing to following code:

err_code = ble_dfu_buttonless_async_svci_init();    //nrf_dfu_svci_vector_table_set(),   bootloader_addr != 0xFFFFFFFF problem
APP_ERROR_CHECK(err_code);//NRF_ERROR_NO_MEM

unlike the given link's, I don't get message related to how to reallocate RAM or ROM via debuggin message or Tera Term

my current allocation is as following:

FLASH_PH_START=0x0
FLASH_PH_SIZE=0x80000
RAM_PH_START=0x20000000
RAM_PH_SIZE=0x20000
FLASH_START=0x27000
FLASH_SIZE=0x59000
FCONFIG_START=0x10000
FCONFIG_SIZE=0x400
DEFAULT_CONFIG_START=0x10500
DEFAULT_CONFIG_SIZE=0x400
INIT_START=0x12000
RAM_START=0x20002be0
RAM_SIZE=0x1d420

macros:

c_preprocessor_definitions="APP_TIMER_V2;APP_TIMER_V2_RTC1_ENABLED;BL_SETTINGS_ACCESS_ONLY;BOARD_PCA10100;BLE_STACK_SUPPORT_REQD;CONFIG_GPIO_AS_PINRESET;FLOAT_ABI_HARD;INITIALIZE_USER_SECTIONS;NO_VTOR_CONFIG;NRF52833_XXAA;NRF_CRYPTO_MAX_INSTANCE_COUNT=1;NRF_SD_BLE_API_VERSION=7;S140;SOFTDEVICE_PRESENT;NRF_DFU_SVCI_ENABLED;NRF_DFU_TRANSPORT_BLE=1;"

What's causing NRF_ERROR_NO_MEM and how to resolve it? 

What is PC at number referring to? Nevermind, found out it was Program counter 

Do I need SW/config modification for custom board?

Thank you in advance

Parents
  • Thanks for the reply!

    You were right, it was due to lack of bootloader - I didn't program the bootloader. 

    So I did 'nrfutil setting' (is nrfutil setting ... same as programming bootloader?)

    nrfutil settings generate --family NRF52 --application "my_app.hex" --application-version 0 --bootloader-version 0 --bl-settings-version 2 bootloader_setting_user.hex

    I couldn't use 'mergehex', my cmd promt didn't recognize the command. (Python27)

    Instead, I used nRF Connect - Programmer v2.3.3.

    I added my bootloader_setting_user.hex + my_application.hex + softdevice_s140.hex(found on dfu example) and programmed over it.

    Sadly it didn't went well (Sometime same error from 'attach debugger', sometime no response, sometime hardfault error)

    About bootloader programming, am I heading the right direction?

    I'm on Windows 10 + Python27, how do I get mergehex to work?

    Is it alright to use Programmer instead of mergehex?

    BTW thanks for the 'Attach Debugger' tip, I was using Segger Studio.

    I also rely on 'Tera Term' to debug via serial.

    tutorial I was relying on: https://devzone.nordicsemi.com/guides/short-range-guides/b/software-development-kit/posts/getting-started-with-nordics-secure-dfu-bootloader

  • June20 said:
    tutorial I was relying on

    That is a good guide. I use to point at this one when someone have questions about DFU in the nRF5 SDK. 

    I suggest that you consider upgrading to python 3.8, as most of our tools use that. 

    You don't need to use mergehex, really. Do you have nrfjprog, and does that work? If so, you can just program all the components separately:

    nrfjprog --program bl.hex
    nrfjprog --program softdevice.hex
    nrfjprog --program app.hex
    nrfjprog --program bl_settings.hex
    nrfjprog --reset

    I am not sure how nRF Connect for Desktop handles several writes. The issue is that if the chip is flashed between the bootloader being flashed and the bl settings being flashed, then the bootloader will generate its own settings, and the bl_settings.hex will not be able to be programmed correctly. That is why I prefer to use nrfjprog.

    BR,
    Edvin

  • I haven't dig deep into the example, all I can tell is that peripheral will enter dfu-mode due to ble package from the central. I want my ble app to run until I decided to connect to dfu device (other case/explanation will be welcomed). How is bootloader_start() triggered?

    Edit: Sorry for adding reply here, I don't see reply button below for some reason.

Reply
  • I haven't dig deep into the example, all I can tell is that peripheral will enter dfu-mode due to ble package from the central. I want my ble app to run until I decided to connect to dfu device (other case/explanation will be welcomed). How is bootloader_start() triggered?

    Edit: Sorry for adding reply here, I don't see reply button below for some reason.

Children
  • I'll continue here, so it shows up approximately chronologically Slight smile If you lack a reply button, try reloading the page a couple of times.

    June20 said:
    I haven't dig deep into the example, all I can tell is that peripheral will enter dfu-mode due to ble package from the central. I want my ble app to run until I decided to connect to dfu device (other case/explanation will be welcomed). How is bootloader_start() triggered?

    I believe what you want to do is to add the buttonless service to your custom application. Strictly speaking, you don't need this service, but it will be recognized as a DFU target by nRF Connect for Mobile/Desktop if you include it. An alternative is to have a custom service/characteristic that enters DFU mode, like the dfu_buttonless_service does, and then connect to the dfu target (advertisements from the bootloader) after it resets.

    So let us assume you are using the DFU buttonless service for now. The workflow here is that you connect to the device (when the application with the buttonless service is running). Then, whenever you want to enter DFU mode, it will write to the buttonless service's characteristic, which will trigger it to reset into DFU mode. In order to reset into DFU mode, it needs to tell the bootloader when it wakes up to not start the application as normal, but to start advertising in DFU mode. 

    If you open the buttonless dfu example, you can see how this is done in ble_dfu_buttonless_bootloader_start_prepare() in ble_dfu_unbonded.c. in ble_dfu_buttonless_bootloader_start_finalize() (called from ble_dfu_buttonless_bootloader_start_prepare()), you can see that it writes to the GPREGRET register using sd_power_gpregret_set(). This will write to a register that the bootloader will check when it starts. If it has the value that is set here, it will enter DFU mode. This is the minimum that you must do from your application before resetting. 

    Does that answer the question that you had?

    Best regards,

    Edvin

Related