Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

An easy to use open source C++ nRF5 SDK based on SoftDevice

Hi everyone,

Not very sure this is the right place to share this, if not, moderator please help me to move it to where it should be.

I just want to share with you a development tool I've created, it's wriiten in C++ for nRF5 chips, I just published it in Github and made it open source with MIT license. Here is the link: https://github.com/jj8431/cpp_nRF5_BLE_SDK

It's still in very basic form and can only support BLE peripherals at the moment, and only nRF52832 is used for the examples because it's the only chip I have at hand, but it should be very easy to be adapted to other chips.

I feel the development became very clear and easy using the C++ class hierarchy, and the code can be reduced to as many as a few hundreds lines for the entire SDK and application.

Here are some highlights of this tool:

  • Pure C++

  • Light Weight. The whole SDK for BLE peripheral devices consists of only 8 .cpp files.

  • Fully functional. Includes all the functions a typical BLE device will need including bonding, ready for commercial use.

  • High efficiency. Code size is only 4.2k for the Blood Pressure example in Release mode (excluding SoftDevice itself).

  • Easy to use. Creating BLE device applications in days, not weeks

  • Providing 3 download-and-run example projects with 0 or minimum hardware dependency.

I made it open source hoping it will be useful for someone, and also hope some of you can contribute your talent to make it better.

And the last thing, if you like it or want to encourage me to keep improving it, don't forget to give a star on Github.

Cheers

  • Hi Jian

    It is fine to share projects like these in a public ticket Slight smile

    Personally I would love for our own API's to be C++ based, as it makes it possible to create very intuitive and flexible API's compared to what you can do in C. 

    Arduino is a good example of this, with a strong focus on user friendly API's and a minimal amount of 'boiler plate' code. 

    I haven't looked through all your code, but I will provide some feedback based on what I did have time to look through:

    1) If you ever plan to add support for more recent devices from us, such as the nRF5340 or any future products, then you would need to change over to the new software architecture based around the nRF Connect SDK. Unfortunately in this ecosystem there is no SoftDevice anymore, rather there is a SoftDevice controller combined with an open source Bluetooth host, and the API is different. 

    2) Why do all the examples need to have the nRF folder, where various startup and header files are duplicated for each example?

    It makes sense to have project specific linker files, since you often need to change linker settings from project to project, but things like peripheral header files, startup files etc should be shared between all the projects in my opinion. 

    3) I find the mix of C style variable/function/method names and C++ style ones a bit messy, like this line:

    AdvDevice.Adv.packet_add_flags(&AdvDevice.Adv.MainPkt);

    For a more consistent interface it is better to ensure that all application facing code follows a more typically C++ naming convention, and hide all the C API's in the underlying libraries. 

    In order to achieve this you would need to wrap all the SoftDevice calls obviously, since they follow C style 'snake case'.  

    4) Having to implement the SWI2_EGU2 directly in main.c seems a bit against the ease of use argument. I think it would be better to allow the application to register a callback function, and hide the specifics of pulling events and forwarding them to the application in a separate file. 

    And if you want to forego C style callbacks for a more object oriented approach you could also set up a system where classes can subscribe to SoftDevice events, allowing for example a Bluetooth service class to automatically process updates to its own attributes. This would obviously require a bit more work to implement, including some kind of static class that can manage all the other classes that have subscribed to various events, and an interface definition for classes that want to subscribe to events.  

    5) Saying the code is ready for commercial use is a bold claim. How much testing have you done to verify this? 
    It does help that what you have made is a relatively lean wrapper of the SoftDevice, in that sense there is not a lot of extra functionality to test. 
    An important thing to note for anyone using a third party software framework like this is that Nordic cannot support this code directly, and to a large extent the support falls on the author of the code if there are any issues during development or production. 

    Hopefully that wasn't all too negative. Like I said I like the idea of a more object oriented approach to Bluetooth development, but it is important not to underestimate the effort of making your own SDK Slight smile

    Best regards
    Torbjørn

  • Hi Torbjørn,

    Thanks a lot for the reply. Your opinion and suggestions are precious and important for me, I'm not very experienced in creating tools for use by others, so I appreciate any suggestions, especially those point out issues.

    It's sorry to see that Nordic will no longer develop SoftDevice, I just hope the existing SoftDevice versions and chips will not become obsolete too soon. I also hope me or someone else will have a chance to adopt this project to the new Nordic environment.

    For other points you mentioned:

    2), The nRF folder is created by Segger Embedded Studio every time you create a new nRF project by default, so I think it's better to leave it in the project other than make it part of the tool.

    3), yeah I agree, the naming looks messy, I always found the naming became messy when I used multiple components in a project, such as FreeRTOS and a HAL library, each one will have its own naming convention and I can't avoid to put them together then the names become inconsistent. I'll add a naming convention part in the README to see if that can help.

    4), I'm an engineer coming from 8-bit controllers, so register manipulations and interrupts seem more convenient and straight forward to me. But you could be right it might be a better idea to wrap and hide these operations to make it a tool for those who doesn't want to know the low level details. For all the others reading this: I'm wondering how many of you are like me that like to do coding in the 'register' way?

    5), I'll remove the 'ready for commercial' statement.

    Again, thank you very much for the comments.

    Jian

  • Hi Jian

    jj8431 said:
    It's sorry to see that Nordic will no longer develop SoftDevice, I just hope the existing SoftDevice versions and chips will not become obsolete too soon. I also hope me or someone else will have a chance to adopt this project to the new Nordic environment.

    In general we don't obsolete chips as long as people are still ordering them in somewhat meaningful quantities, and we are not forced to by external factors (such as the fabrication partner seising production). The nRF52 series is made on a 55nm node that should be available for a long time. 

    At some point in the future you will not be allowed to qualify new Bluetooth products based on the current SoftDevices, because the Bluetooth SIG will deprecate older Bluetooth versions, but this should be many years of for the latest SoftDevice versions. 

    jj8431 said:
    2), The nRF folder is created by Segger Embedded Studio every time you create a new nRF project by default, so I think it's better to leave it in the project other than make it part of the tool.

    That is interesing. If you look at the examples we provide in the nRF5 SDK they don't contain this folder. The only Segger specific files are the project file (.emProject), the session file (.emSession) and the flash_placement.xml file. 

    jj8431 said:
    4), I'm an engineer coming from 8-bit controllers, so register manipulations and interrupts seem more convenient and straight forward to me. But you could be right it might be a better idea to wrap and hide these operations to make it a tool for those who doesn't want to know the low level details.

    It's about consistency. There is nothing wrong with working either low level or high level. High level allows you to do more with less code, while low level gives you more fine control (and also more room to make mistakes....). 

    The problem is when you mix low level and high level code in the same interface.  

    Most software frameworks these days follow something similar to the OSI model, where you have multiple layers of code, some of which are very close to the hardware, and other that are further removed from the hardware. The application will normally only be given access to the upper most layer in the stack, and will not be given direct register access to the underlying hardware. 

    Others in the community can chime in if they like, but if you want to make an interface that is easy and quick to use, and doesn't require a deep understanding of the Nordic hardware, then that usually necessitates a high level approach. 

    Best regards
    Torbjørn

Related