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

Using the SD API directly - is it straightforward, or too much hassle?

I am experienced with ARM Cortex-M devices, but new to Nordic. I am using C++, and have a publisher-subcriber event driven framework of my own in place already. My own software timers are integrated with this (driven by SysTick or RTCx or whatever). My question relates to how best to integrate all this with the NRF52 SDK. I've just started working through some of the BLE examples. I'm slightly hampered by also being new to BLE...

There seems to be a huge layer of abstraction between the application and the actual SoftDevice API. I try to never use macros which generate lines of code, and the SDK appears to be riddled with them. Is it *practical* to just use the SD API directly, and where might I find examples of this? I can see the documentation online for the SD API, including a lot of useful-looking sequence charts, but no PDF. In principle, it looks like a relatively small number of API calls to set up my advertising, services and whatnot, implementing an ISR to receive events, and then pressing go. I'll need to make sure my application's vector table is at the right location, and to give the SoftDevice enough RAM, but that's about it. Is that a fair assessment?   

For context, I found it *much* simpler and cleaner to configure and operate the hardware peripherals directly through registers. I dispensed with the HAL and drivers entirely (except for the convenient definitions of bitmasks and so on). And my driver classes are integrated with my application framework...

Thanks.


Al

Parents
  • Fellow traveler. Please have a look here:

    https://github.com/natersoz/nrf

    I have coded the peripherals side of the equation using the SD with limited SDK dependencies. This code is on master, is working and has issues written against it.

    I am currently working on the central side of the implementation.

    After that: The security manager (there is no bonding nor security handshakes being executed).

    Under docs/nordic/NORDIC.md you might find some other interesting information.

    This is a hobby project for me and it gets attention during winter weekends.  :)

Reply
  • Fellow traveler. Please have a look here:

    https://github.com/natersoz/nrf

    I have coded the peripherals side of the equation using the SD with limited SDK dependencies. This code is on master, is working and has issues written against it.

    I am currently working on the central side of the implementation.

    After that: The security manager (there is no bonding nor security handshakes being executed).

    Under docs/nordic/NORDIC.md you might find some other interesting information.

    This is a hobby project for me and it gets attention during winter weekends.  :)

Children
  • I am currently trying to modify my project to include the FreeRTOS example. I am using CMake, and have all the same include paths and files as in the example Makefile. I'm pretty sure I have all the same compiler options and am using an identical linker script. The example dies when it "calls" NRF_LOG_DEFAULT_BACKENDS_INIT() - more macro magic. Why? Because it appears the linker has not included the data for UARTE0 in .bss, so the peripheral m_cb[] control block thingy is uninitiliased. I found that this peripheral was not enabled in the 12,000 line configuration file. I enabled it, which should cause it to be initialised, but it is still broken.

    I've taken a pretty deep dive into the code for the SDK now, and I think I can honestly say it is hands down the worst SDK I have ever tried to use in more than 30 years of software development. The whole point of the SoftDevice seems to be a clean separation between the stack and the application. That's a really attractive, open, non-intrusive model which would allow me to implement my application however I like, and to call the appropriate API methods in the right places, and to handle events via an ISR.

    I expected the SDK to be similar: maybe a bunch a higher level convenience functions and libraries which wrap up the low level details of calling API functions. A sane implementation would allow me to painlessly integrate, for example, a peer manager without affecting any other aspect my application. It seems instead to be a closed all-or-nothing deal which forces a horrible implementation of the observer pattern on me, and forces me to use some of the horrible peripheral drivers (used within the SDK). It appears that the only way to make progress is to take an example and modify it. And I have my doubts about that.

    In my view, this SDK is a very severe impediment to progress with a really, *really* nice chip with a really, *really* nice implementation of the BLE stack, and Nordic simply should discard this entire pile of garbage and start over.


    Al

  • I understand. Which is why I've chosen to remove myself from working with the SDK as much as possible. The softdevice, however, IMO is well written. I am mystified as to how Nordic can do such a good job at provisioning the softdevice and fail so hard with this SDK.

    I'll keep my rants to a minimum in order to not displease the Nordic gods. They have lightning I am told. And vikings.

    They also have #define MACRO_HELL()

    To your specific missing linkage: UARTE0

    Nordic has done something rather nasty here: It is not sufficient to include a module in the compile and link phase of your project. You have to also satisfy their #define module nonsense.

    You have probably already looked into the source nrfx_arte.c ? 

    #if NRFX_CHECK(NRFX_UARTE_ENABLED)
    
    #if !(NRFX_CHECK(NRFX_UARTE0_ENABLED) || NRFX_CHECK(NRFX_UARTE1_ENABLED))
    #error "No enabled UARTE instances. Check <nrfx_config.h>."
    #endif

    If NRFX_UARTE_ENABLED (and a few others!) are not defined then the uarte_control_block instance is not instantiated.

    In Nordic' defense, when it comes to peripherals, there will have to be some macro hell in play.

    They have shared UART/SPI master/slave/I2C devices which all have to share the IRQ vector and handlers.

    Having looked at this, and the compromises required to deal with shared peripherals, some type of macro is required. Minimizing and isolating their dependencies did not seem important to whoever is leading the direction for Nordic's SDK. In fact, with SDK 15 compared to 14 it seems to have gotten worse  :(

  • I did see NRFX_UARTE0_ENABLED in the config.h, but this did not fix the problem. I think I stumbled over some problem in the linker script which means that __bss_start__ is not correctly initialised. Lightning could hardly be worse than this endless yak shaving. :)

    I agree that it is hard to understand how the people who created the SD also created this SDK. I have rarely been so infuriated and so depressed by a body of code.

Related