Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
2 years, 3 months ago.
How does MBED set aside RAM for the NORDIC softdevice?
Hi, I am trying to connect multiple Peripherals to one Central using the MBED BLE librarys. However, when i try to change the maximum allowed clients, my app wont run anymore (hangs in BLE::Instance();).
I have tried following in sdk_config.h:
NRF_SDH_BLE_PERIPHERAL_LINK_COUNT 1 ; NRF_SDH_BLE_CENTRAL_LINK_COUNT 3 ; NRF_SDH_BLE_TOTAL_LINK_COUNT 4 ; this and anything below works! NRF_SDH_BLE_PERIPHERAL_LINK_COUNT 1 ; NRF_SDH_BLE_CENTRAL_LINK_COUNT 4 ; NRF_SDH_BLE_TOTAL_LINK_COUNT 5 ; this and anything above does not work! NRF_SDH_BLE_PERIPHERAL_LINK_COUNT 1 ; NRF_SDH_BLE_CENTRAL_LINK_COUNT 1 ; NRF_SDH_BLE_TOTAL_LINK_COUNT 5 ; this does also not work!
I assume this has something to do with RAM reservation for the softdevice, because it needs a reserved area in RAM. I looked at the linker script (NRF52832.ld) and noticed following:
Linker script snippet
/* If app_start is 0, do not set aside space for the softdevice */ #if MBED_APP_START == 0 #define MBED_RAM_START 0x20000000 #define MBED_RAM_SIZE 0x10000 #else #define MBED_RAM_START 0x200031D0 #define MBED_RAM_SIZE 0xCE30 #endif
if I am correct, that means that if the softdevice is Enabled MBED sets aside a predefined amount of RAM, but that may not be enough. Debugging shows that sd_ble_enable(uint32_t * p_app_ram_base) sets 0x20007410 as app_ram_base. So one can see that the value in the linker script isnt even close to what is needed by the Softdevice. I tried changing the MBED_RAM_START address manually, but that leads to strange behaviour on my device, I think i am missing something.
So what am I missing here?
EDIT: I just experimented with the linker settings, and i got it to work! I put a breakpoint to nrf_sdh_ble_enable in nrf_sdh_ble.c and read the *p_app_ram_start, app_ram_start_link then I used the value of *p_app_ram_start as MBED_RAM_START and ram_end_address_get() - (*p_app_ram_start) as MBED_RAM_SIZE in the linker script. and voila it works! (although i had to perform a full clean for the changes to take effect)
then I checked if the values of *p_app_ram_start and app_ram_start_link would match now, but they dont. then I did some calculating and found out, that its not the MBED_RAM0 address thats important, but MBED_RAM1, so I have to subtract MBED_RAM0_SIZE from *p_app_ram_start and get the real intendet ram start address. again, I tried to verify it, and now the ram start address and the ram_start_link address differ by only 0x4. I guess thats because the ram start address is set to the next Memory page instead of the almost full one. anyways, I can accept wasting 4 bytes of memory and it now works! BUT i Highly suggest to change the linker script so that it calculates these values automatically, because its a real hassle to go through this. maybe I wrote this text a bit confusing, so if you have questions please ask, as i really would like to know if all of my assumptions were true.
thanks in advance, Jonas
this is a follow-up question regarding an issue discussed here: https://os.mbed.com/questions/83165/why-cant-i-connect-multiple-peripherals-/
2 years, 3 months ago.
It's really impressive on the analysis! The way you adjust the MBED_RAM_START and MBED_RAM_SIZE is correct, the value is decided through sd_ble_enable(), please refer to this documentation, targets\TARGET_NORDIC\TARGET_NRF5x\TARGET_SDK_14_2\TARGET_SOFTDEVICE_S140_FULL\doc\s140_nrf52840_5.0.0-2.alpha_migration-document.pdf, section "SoftDevice RAM usage"
The required memory is got from execution time, but the linker script is used in compilation time, so it's hard to change these values automatically. But we could try to show some notification when this error happens, so that everyone will know how to deal with it.
If you have any other idea please let me know!
- Desmond, team Mbed