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

Project file-system structure - best practice.

I have recently switched to using SEGGER embedded studio (SES) which seems to be advocated by Nordic.  I have arrived from Eclipse which though extremely flexible is complex in the extreme. So I greeted SES with joyful anticipation.  I should mention here that I dallied briefly with PlatformIO which doesn't seem well (at all) intergated with the nRF DK. 

Yearning for a clean IDE, I have persevered with SES, but I have become increasingly confused by the variety of (implied) ways to structure my new projects, and the various tools and veneers that seem to offer more options than clarity.  I'd really like to get some advice, or a pointer to a document describing the options best practices, and the rationale behind choices.  Too much to ask?

From my perspective there are several major challenges in deciding how to organize and manage a new SES project:. 

  1. Deciding where to place my project code base in relation to the SDK code base.  Because some of the SDK path names are very long, there can be obscure build issues.  It is advocated (somewhere) that the SDK should be placed close to the file-system root.  On the other hand my own development code might live in my "user" file hierarchy where source control systems can manage it, along with related. hardware designs, enclosure designs. 
  2. When a bit of code fails to compile because it references code from the SDK, it is often a challenge to figure out:
    1. where the relevant components reside for my particular configuration;
    2. what defined constants have to be set to cause it to be compiled.  GREP revealed that there are 33 SDK files that contain a unique definition of the form *_ENABLED.  e.g.  NRF_LOG_ENABLED.  That in itself is to be expected, but there is (AFAIK) no single place where the 297 "_ENABLED" definitions are defined.  
  3. Actually communicating what files I want included by SES seems to involve a hodge-podge of overlapping techniques.  To include ".c" or ".h" files from the SDK, I can:
    1. edit an sdk_config.h header file directly
    2. add preprocessor-includes into the project options form;
    3. copy files into my development directory.  The latter is clearly a pain if I take a new SDK release
  4. Setting defintions presents another smorgasbord of options:
    1. use the CMSIS wizard
    2. add pre-processor definitions in the option form
    3. create my own app.config.h

Those very useful example files generated by Nordic are of course embedded in the release, and observe a structure that allows them to be compiled by a number of different IDEs (Cheer)..  Creating an example using the SES "New" facility creates a completely different structure though, and seems to copy in a lot of files that some might argue are better left in the SDK release structure.  The program compiles and runs right away, but when you try to embellish it the puzzle begins.

Now I understand that I am viewing the results of several years of excellent code evolution at Nordic, and that this is unlikely to be harmonious with the excellent SES system.  So perhaps that's why I have found it so hard to find a "best practice" document/video that provides some reasoned guidance on project structure.  Of course there is no "best practice", and every developer will have their own predilectons, but for someone new to SES it is really hard to get a running start at SES.

  • Hi Michael

    1. It is indeed recommended to place the SDK folder close to the file-system root to avoid build issues due to the length of the paths. We also generally recommend to start out with one of our examples when beginning a project, as you usually will use the peripherals/services of at least one of the already existing examples, and then adding additional functionalities to that project. This will generally save you the time of setting up a project from scratch. 

    2. In existing projects, most of these defines are defined in the sdk_config.h file, which is why there are so many _ENABLED defines. I suggest you make one configuration file like this for your custom projects as well.

    3. When adding .h files to your SES project, we recommend adding user include directories in the preprocessor options of your project (see picture below). 

    4. For preprocessor definitions, this comes down to your personal preference. I for one, prefer using the preprocessor definitions from the options for setting definitions in my project, but this is entirely up to you.

    Best regards,

    Simon

  • Thanks Simon.

    I can see that my question/suggestion was not well-phrased.

    I was trying to clarify a process to share with some other developers. Imagine trying to coach/kick-start some reasonably experienced people who have used a different IDE, or micro-controller.  They understand what's needed in theory, but there are a lot of approaches - some of which are sub-optimal.  It seems to me that a very useful tutorial/video would explain how to make your "first-base" novel program, so that you can get down to writing actual code.  Let me have a naive attempt at explaining the steps.  I'm following what I think is Nordic's suggested acceptable practice.  Please try to actually do this and see how many tiny/puzzling/time-consuming gotchas you encounter?

    • Find an example program that most closely resembles the program you are intending to build.
      e.g. C:\nRF_SDK\nRF5_SDK_16.0.0_98a08e2\examples\ble_peripheral\ble_app_beacon
    • Copy the ble_app_beacon directory to your chosen development location. e.g. C:\Users\lamming\Documents\SES_Projects2\nRF_Projects\MyStuff
    • Open the appropriate EMPROJECT, e.g. ble_app_beacon_pca10056_s140

    Clearly it won't build for a bunch of reasons.  For example the import and source references in EMPROJECT are now relative to the wrong place.  

    So now the new user should open the Options dialog

    • Edit every relative reference to replace all those pesky "../../../../../.." with the correct path  (since this is tedious - copy all the references to a text editor and do a global replace, then paste them back?)
    • Perhaps even create a new symbol definition SDK_ROOT=C:\nRF_SDK\nRF5_SDK_16.0.0_98a08e2\ and replace the ""../../../../../.."  stuff with a symbol, to make the code marginally more relocatable.

    Now for example, add a line of code that uses some facility that requires a module-DEF that is not in the current sdk.config file. Hunt down the file, perhaps in a different application with the relevant DEFS in it.  Now there are multiple approaches.

    • Create a new app.config and figure out how to include it in a general way, and add the definitions required by the new module.

      or

    • Learn the format used by the CMSIS wizard
    • Figure out how/where to add a new section to sdk_config, so it all works correctly

    Obviously there's more trivial stuff...

    Please understand that I'm not trying to throw rocks.  I'm an ardent Nordic supporter and want to see more people adopting this platform.  I'm suggesting that a tutorial, or document of the form I describe could be very helpful.  If there is such a thing out there, I would be relieved, though appropriately embarrassed to be shown it.

  • Hi

    Generally, we don't suggest moving the project out of the SDK due to all the extra work it causes (like you're describing), but I see why one would want to have a project in "its own" folder, and see the use of a guide on how you would do this. I will forward your suggestion for this kind of a guide/blog post to be made, but I can't promise it will be made any time soon.

    What we do have, is the intro blog post to Segger Embedded Studios, which explains how to add user includes, preprocessor definitions, etc.

    You will have to decide whether it is worth moving projects out of the SDK or not. As far as I can see, the suggestions you have looks like a good place to start. We're glad to receive suggestions for new blog posts, tutorials, and constructive criticism like this. It helps us as a company to provide a better product, so don't feel bad for letting us know what we can do better.

    Best regards,

    Simon

  • Hi Simon,  Yes it is a bit of a challenge, but if you have a project that uses more than one manufacturers uC. Then it's a tug-of-way between who get's "embedded" in whom.  

    I've probably read the SEGGER document, but point me at it again please, in case I missed a trick.

    Thanks for your help. I hope I was able to "illuminate the opportunity" :-)

    I'll consider my suggestion "solved",  

    Takk
    Mik
Related