Hi everyone,
I'm working on the nrf52832 using the SDK 15.2.0 with freertos and the application I am developing requires to save data on the flash while the BLE stack is running. I am working on the dwm1001-dev board from Decawave which also embeds a JLinkOB for SWD debugging.
Here is my issue: While the BLE stack is enabled, I call nrf_fstorage_erase on a flash page I have defined. This function succeeds and the RTOS is still scheduling the tasks properly but after few ms, supposely when the erase event is triggered, the CPU hardfaults. The PC is at 0x245aa (unaligned) which is an address in the soft device SW. But it gets fun when we know that the CPU doesn't hardfault and works properly when the JLink is enabled (using gdb or rtt logs).
Here are additionnal infos:
- The nrf_fstorage_init is called with the sd api before the BLE stack is initialized but the erase is done after
- I am using s132_nrf52_6.1.0_softdevice
- This issue happens even when the system works while the application isn't doing much and no ISR are triggered at same time
- I build my code with GCC 5.4.1 and using my own ld script (see below, note that CONFIG isn't the flash page concerned by the erase). I feel like the bug comes from the code alignment in the flash memory. I've opened a gdb debug session to print m_sys_obs (the SOC observer) and nrf_fstorage_sys_evt_handler (the event handler) defined in nrf_fstorage_sd.c and I got this:
- p nrf_fstorage_sys_evt_handler: 0x3551c
- p m_sys_obs.handler : 0x3551d
What could I do wrong ?
Cordially,
Gabriel
Ld script:
/* Linker script to configure memory regions. */ SEARCH_DIR(.) GROUP(-lgcc -lc -lnosys) MEMORY { FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0x76000 - 0x26000 CONFIG (rw) : ORIGIN = 0x7D000, LENGTH = 0x1000 RAM (rwx) : ORIGIN = 0x200039A0, LENGTH = 0xC660 uicr_bootloader_start_address (r) : ORIGIN = 0x10001014, LENGTH = 0x4 } SECTIONS { .uicr_bootloader_start_address : { PROVIDE(__start_uicr_bootloader_start_address = .); KEEP(*(SORT(.uicr_bootloader_start_address*))) PROVIDE(__stop_uicr_bootloader_start_address = .); } > uicr_bootloader_start_address } SECTIONS { . = ALIGN(4); .mem_section_dummy_ram : { } .cli_sorted_cmd_ptrs : { PROVIDE(__start_cli_sorted_cmd_ptrs = .); KEEP(*(.cli_sorted_cmd_ptrs)) PROVIDE(__stop_cli_sorted_cmd_ptrs = .); } > RAM .fs_data : { PROVIDE(__start_fs_data = .); KEEP(*(.fs_data)) PROVIDE(__stop_fs_data = .); } > RAM .log_dynamic_data : { PROVIDE(__start_log_dynamic_data = .); KEEP(*(SORT(.log_dynamic_data*))) PROVIDE(__stop_log_dynamic_data = .); } > RAM .log_filter_data : { PROVIDE(__start_log_filter_data = .); KEEP(*(SORT(.log_filter_data*))) PROVIDE(__stop_log_filter_data = .); } > RAM } INSERT AFTER .data; SECTIONS { .mem_section_dummy_rom : { } .sdh_soc_observers : { PROVIDE(__start_sdh_soc_observers = .); KEEP(*(SORT(.sdh_soc_observers*))) PROVIDE(__stop_sdh_soc_observers = .); } > FLASH .sdh_ble_observers : { PROVIDE(__start_sdh_ble_observers = .); KEEP(*(SORT(.sdh_ble_observers*))) PROVIDE(__stop_sdh_ble_observers = .); } > FLASH .sdh_stack_observers : { PROVIDE(__start_sdh_stack_observers = .); KEEP(*(SORT(.sdh_stack_observers*))) PROVIDE(__stop_sdh_stack_observers = .); } > FLASH .sdh_req_observers : { PROVIDE(__start_sdh_req_observers = .); KEEP(*(SORT(.sdh_req_observers*))) PROVIDE(__stop_sdh_req_observers = .); } > FLASH .sdh_state_observers : { PROVIDE(__start_sdh_state_observers = .); KEEP(*(SORT(.sdh_state_observers*))) PROVIDE(__stop_sdh_state_observers = .); } > FLASH .nrf_queue : { PROVIDE(__start_nrf_queue = .); KEEP(*(.nrf_queue)) PROVIDE(__stop_nrf_queue = .); } > FLASH .nrf_balloc : { PROVIDE(__start_nrf_balloc = .); KEEP(*(.nrf_balloc)) PROVIDE(__stop_nrf_balloc = .); } > FLASH .cli_command : { PROVIDE(__start_cli_command = .); KEEP(*(.cli_command)) PROVIDE(__stop_cli_command = .); } > FLASH .crypto_data : { PROVIDE(__start_crypto_data = .); KEEP(*(SORT(.crypto_data*))) PROVIDE(__stop_crypto_data = .); } > FLASH .pwr_mgmt_data : { PROVIDE(__start_pwr_mgmt_data = .); KEEP(*(SORT(.pwr_mgmt_data*))) PROVIDE(__stop_pwr_mgmt_data = .); } > FLASH .log_const_data : { PROVIDE(__start_log_const_data = .); KEEP(*(SORT(.log_const_data*))) PROVIDE(__stop_log_const_data = .); } > FLASH .log_backends : { PROVIDE(__start_log_backends = .); KEEP(*(SORT(.log_backends*))) PROVIDE(__stop_log_backends = .); } > FLASH } INSERT AFTER .text SECTIONS { . = ALIGN(4); .device_config(NOLOAD) : { PROVIDE(__start_config = .); KEEP(*(SORT(.device_config*))) PROVIDE(__stop_config = .); } > CONFIG } INCLUDE "nrf_common.ld"