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

Notification Enabled by event or poll

Should we keep track of this by monitoring the write events or poll the gatts value via the softdevice?

It looks like it's faster (+shorter = less consumption) to monitor the event, as to poll the value seems like a lot of code overhead, which I would then have to execute for every request to the state.

At the same time I wonder why the SoftDevice is not already providing boolean "properties" for this stuff, and is keeping track of it behind the scenes.

All of this brings me back to another ongoing question on my mind... Why are you not using c++ which would really make it a lot easier to organise and reuse the code and hereby keep the overall size and execution cycles shorter?

The only reason I can think of is to make sure that every code path is as "lightweight" as possible with simple C99 procedural code - which is probably true for most simple uses. However, when you add more complexity (and I think the SD is knocking on the door, if it's not already entered the room :-) , it's not a lightweight scenario anymore, and you'll start to copy the samme patterns all over the place and loosing the advanced data+code management OOP gives you.

Well, since I've not coded at this level for many years I might have overlooked the obvious reasons for keeping it in straight C99 only :-)

  • To know when the CCCD is written, you have to monitor the write event, and compare the handle to the CCCD handle of the characteristic you're interested in. However, unless you want to start anything exactly when the CCCD is written, you can also just try to send a notification and look at the return code. If you get NRF_ERROR_INVALID_STATE back, this means that the CCCD is not currently enabled.

    As for why the softdevice doesn't expose a C++ API, I don't really have an explanation as such. However, there isn't any problems with using the softdevice from a C++ based application, and I know several customers who have been doing this. Using C or C++ in an embedded application seems to me to be mostly a matter of personal preference, but when exposing a C compatible API, this choice is entirely left to the application developer.

  • Thanks. I did originally check the NRF_ERROR_INVALID_STATE, but figured that I could probably save some power by not read out data through SPI, preparing it, put it into a buffer and then try to send it - if nobody was actually asking for it :-)

    So I've implemented the event handler, as this also induces less overhead than querying the structure for every packet I send.

    If it doesn't really matter which flavour it comes in, I'll vote for a future C++ version. I believe that most of your customers will favour this over time as well, as C++ is not as imparative as C (meaning that you can define and see more of the trees in the forest). I've already started to convert some of the C files, and the number of lines are shrinking considerably, and the code becomes more natural to read, understand and work with. Of course you will need to adapt to C++ and OOP principles if you are not already familiar with it, but it will pay off in the long run.

  • With C++ it is much more difficult (for mere mortals like myself) to understand the memory layout of "classes" and "objects" etc. This is important for embedded programming, so I prefer to use C as it is easier for me to have reasonably accurate expectations of what the compiler will produce.

  • Ahh yes I see that this could become an issue, espcially when you are working with limited resources.

    But honestly, I wouldn't mind not to have to think about it. In many ways I'd also say that you could probably save memory with C++ by simply working smarter - or at least save CPU cycles. Plain procedural C code often has a slight overhead in memory housekeeping, and might therefore be less efficent by moving blocks around more frequently.

    But I 'd guess that objects would be similar to structs in their memory behaviour. Most of the API code is carrying structs around from function to function - this is what C++ does behind the scenes with the object instance. When you declare/construct a class it will either live on the stack or in the free (global) memory area, (unless you allocate it dynamically via the heap). So I think it would be comparable to using structs. There are also some memory aspects when working with virtual methods and so on, but these might actually benefit your overall design from beein less clumsy and memory hungry in that you need less blocks of memory to do the same.

Related