Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Initialize and use multiple BLE services

I am trying to initialize the BLE NUS UART service and the BLE LBS service so both can be used at the same time in a single nRF52 application. I can initialize a single service without any problems. But if I call the init function for the second service the application hardfaults. Is it possible to initialize two services to run simultaneously? Please advise how I might accomplish this. 

I am using nRF52 SDK version 14.2 combined with the Mesh SDK version 1.0.1 on an nRF52 development kit. I used the ble_peripheral NUS UART example as the basis. Then I added the LBS service source file to that project and added the lbs init function to the services_init function in the NUS example.

  • Hi,

    Both the LBS and the NUS service use so called Vendor Specific UUIDs (128-bits). When you configure the Softdevice at startup you need to tell it how many of these VS UUIDs you plan to use (so that it can allocated enough memory for them). Here is a very similar case with a solution: https://devzone.nordicsemi.com/f/nordic-q-a/30790/sd_ble_uuid_vs_add-error-code-4/121851#121851

    If you have simply forgotten to allocate enough RAM for your UUIDs your could shouldn't hard fault though. So can you please confirm that your code actually hard faults, and not just asserts on an error? If it hard faults have you tried debugging and figured out what line of code is at fault?

  • I assumed hard fault was occurring because I receive a message on the log that says "HARDFAULT...". This comes form the file nrf_mesh_sdk.c function HardFault_Handler. I am using the combined SDKs so maybe the performance is slightly different than when using a single SDK. But once I change the NRF_SDH_BLE_VS_UUID_COUNT to 2 the hard fault no longer occurred.

    I changed NRF_SDH_BLE_VS_UUID_COUNT to 2. In changed the RAM start and size to the suggested values that appear in the logger.

    <warning> nrf_sdh_ble: RAM starts at 0x20002780, can be adjusted to 0x20002770.
    <warning> nrf_sdh_ble: RAM size can be adjusted to 0xD890.

    I also tried simply increasing the RAM size from 0xD890 to 0xFFFF and increasing the flash size from 0x5d000 to 0x5f000.

    However now when I call ble_advertising_init I get a return value of NRF_ERROR_DATA_SIZE. Any idea what is happening? I am not sure what else to change.

    I am using the following for the advertising UUID array which is passed into ble_advertising_init  using the ble_advertising_init_t structure.

    static ble_uuid_t m_adv_uuids[] =  
    {
        {BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE},
        {LBS_UUID_SERVICE, BLE_UUID_TYPE_VENDOR_BEGIN}
    };

  • Hi,

    That is very strange. Can't blame you for assuming it is a hard fault then. It could be a bug in the code though, that calls the hardfault_handler instead of app_error_handler. If it had called the latter you would have seen some error codes as well. I'll try to investigate it. 

    For your next question: It looks like you are trying to fit two VS UUIDs in one advertising packet. Each one is 16 bytes long, a total of 32 bytes. Unfortunately, according to the BLE specification you are only allowed to put 31 bytes in the packet. Please see this thread: https://devzone.nordicsemi.com/f/nordic-q-a/7066/setting-tx_power_level. What you can do is to put one UUID in the advertising packet, and the other one in the scan response packet. 

  • Thanks Martin. The size issue makes sense. But I am curious, do devices usually only offer one VS service? Is that a restriction that is inherently created by the BLE specification making the advertising packet 31 bytes? What does a device normally do if it needs to offer two VS services? Is there a standard way of offering two VS services in Bluetooth?

  • You can have as many VS UUIDs as you want, you just can't advertise them all. It might not be relevant in your case, but remember that each and every byte you transmit will drain your battery. So it makes sense to keep the advertising packets as short as possible. Instead of advertising entire VS UUIDs you can also look into using the manufacturer specific data field in your packets. If your central device needs to know all the features your peripheral provides then maybe you can put some indicators in there instead. 


    PS: The thing about the 31 byte limit is only partially true. BLE 5.0 introduced new advertising features that allow you to advertise streams of data: Bluetooth 5 Advertising Extensions. However, we do not support these features in our Softdevices yet. 

Related