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

Compare sdk_config files

Hi!

What is the easiest way to compare two sdk_config files? Some tools, etc. Why do I need it:

  1. My idea is to use "$NRF_SDK/config/nrf52840/config/sdk_config.h" as base config and don't change it. All changed parameters ("diff") put into "app_config.h". Usually it's not a lot of changes compared to the base configuration, but if i need to see it in "modified" (compared to the base) sdk_config - it's very hard. Now I have projects with "modified" sdk_config files, I want to get "diff". 
  2. It would be useful for sdk examples to see "diff".

I hope my explanation is understandable. Thanks for answers and suggestions in advance.

  • Why it seems that using "$NRF_SDK/config/nrf52840/config/sdk_config.h" unchanged from the SDK and overriding with my own "app_config.h" can never work.

    This discussion is based on SDK 15.2 and using SES to develop for nrf52840 on both the DK and the dongle. Development environment on both Windows 10 and Linux.
    I developed my application using my own version of sdk_config.h edited from an existing one, adding chunks as needed from others until all the packages I needed behaved well. I do not consider this good practice despite all the Nordic provided examples doing exactly that.

    I relied on the following from the Nordic infocenter:

    Quote[
    Overriding the sdk_config.h configuration

    Each define in the sdk_config.h file is a conditional define that is added only if it has not been defined previously so it can be easily overriden.

    Configuration in sdk_config.h can be overriden in two ways:

        Adding a project flag/define.
        Adding the USE_APP_CONFIG flag to the project settings and creating an app_config.h file which is included at the top of the sdk_config.h file.
    ]

    Therefore I added the path $NRF_SDK/config/nrf52840/config/sdk_config.h at the top of the include search list, defined USE_APP_CONFIG and, sure enough, it accessed my app_config.h file. For the purpose of this explanation I will concentrate on the first problem that this generated. There may be others, but I cannot find an elegant way of avoiding this problem.

    Amongst others, I had the lines:
    #define NRFX_CLOCK_ENABLED 1
    #define NRFX_TIMER_ENABLED 1
    #define NRFX_TIMER1_ENABLED 1
    #define APP_PWM_ENABLED 1
     
    which had previously been at the top of my own version of sdk_config.h and worked.

    Attempting to compile my application, I had a compilation error:

    At the line "APP_PWM_INSTANCE(analogue_out,1); // Create the instance "analogue_out" using TIMER1."
    I got the error:
    error: 'NRFX_TIMER1_INST_IDX' undeclared here (not in a function);

    In the crumb-trail back to the problem was the area of Nordic code that creates the value NRFX_TIMER1_INST_IDX which is from nrfx_timer.h:

    enum {
    #if NRFX_CHECK(NRFX_TIMER0_ENABLED)
        NRFX_TIMER0_INST_IDX,
    #endif
    #if NRFX_CHECK(NRFX_TIMER1_ENABLED)
        NRFX_TIMER1_INST_IDX,
    #endif
    #if NRFX_CHECK(NRFX_TIMER2_ENABLED)
        NRFX_TIMER2_INST_IDX,
    #endif
    #if NRFX_CHECK(NRFX_TIMER3_ENABLED)
        NRFX_TIMER3_INST_IDX,
    #endif
    #if NRFX_CHECK(NRFX_TIMER4_ENABLED)
        NRFX_TIMER4_INST_IDX,
    #endif
        NRFX_TIMER_ENABLED_COUNT
    };

    This is an anonymous enum which generates an index for enabled timers. Essentially the code NRFX_CHECK(NRFX_TIMER1_ENABLED) turned out to be returning "false" and therefore failed to generate TIMER1 index. But just a minute, I had defined it right at the beginning of includes to be 1 - what gives???

    The culprit.

    It has to be said that it took me a few Sherlock Holmes moments to get to the bottom of this.

    In $NRF_SDK/config/nrf52840/config/sdk_config.h
    I found:
    #ifndef NRFX_TIMER1_ENABLED
    #define NRFX_TIMER1_ENABLED 0
    #endif

    but that is fine, since I had defined it already as 1 so the first line returned false - I checked - it did. There are no other references to
    NRFX_TIMER1_ENABLED in $NRF_SDK/config/nrf52840/config/sdk_config.h so the culprit for undefining or zeroing it is not there.

    But there is a culprit and they are the following lines in $NRF_SDK/config/nrf52840/config/sdk_config.h:

    // <e> TIMER_ENABLED - nrf_drv_timer - TIMER periperal driver - legacy layer
    //==========================================================
    #ifndef TIMER_ENABLED
    #define TIMER_ENABLED 0
    #endif
    and
    #ifndef TIMER1_ENABLED
    #define TIMER1_ENABLED 0
    #endif

    Now, I had not defined TIMER_ENABLED so the ifndef returned TRUE so TIMER_ENABLED and TIMER1_ENABLED were defined as zero.
    "So what?", I hear you ask, "0 means 'not enabled' so that is fine". Well it would be but for some code lurking elsewhere.
    Read now the file "apply_old_config.h" which arrives via nrfx_clock.h via nrfx.h via nrfx_glue.h

    That file contains the code:

    #if defined(TIMER_ENABLED)
    #undef NRFX_TIMER_ENABLED
    #define NRFX_TIMER_ENABLED  TIMER_ENABLED

    #if defined(TIMER0_ENABLED)
    #undef NRFX_TIMER0_ENABLED
    #define NRFX_TIMER0_ENABLED  TIMER0_ENABLED
    #endif
    #if defined(TIMER1_ENABLED)
    #undef NRFX_TIMER1_ENABLED
    #define NRFX_TIMER1_ENABLED  TIMER1_ENABLED
    #endif
    ...ETC.

    This file DOESN'T CARE what TIMER_ENABLED is set to, just that it has been defined. It then quite happily sets
    NRFX_TIMER1_ENABLED to TIMER1_ENABLED which, of course, $NRF_SDK/config/nrf52840/config/sdk_config.h set to zero - disabled!

    TA-DAH Dr Watson, all is revealed! We now know who is the guilty party for the murder of NRFX_TIMER1_ENABLED.

    If only $NRF_SDK/config/nrf52840/config/sdk_config.h had not fiddled with TIMER_ENABLED.
    Worse, there is nothing you can do in app_config because that it called before the evil deed is done by defining TIMER_ENABLED
    essentially we cannot AFAIK "undefine" it in advance. I did think about defining APPLY_OLD_CONFIG_H__ which would block
    "apply_old_config.h" from doing anything, but that file is a catch-all for lots of other stuff as well so I cannot predict the side
    effects.

    For the future - This was only the first of perhaps many problems that direct use of $NRF_SDK/config/nrf52840/config/sdk_config.h
    might cause so I conclude that it is just too dangerous to try to use it without modification OR changing the legacy code to
    correspond to the later protocol of the value of a definition determining the yes/no and not simply the act of defining.

    So I conclude that the entry in the documentation of Nordic Infocenter is essentially useless. Sure, pre-defining things might work, but using a standard sdk_config certainly doesn't. I have checked with SDK 16 : It has the same problem as far as I can tell.

    I hope that this explanation will help others in the future - it sure wasted a lot of my time.

  • Oh Ray you hit the nail on the head.

    In nrfx_glue.h this tiny line:

       #include <legacy/apply_old_config.h>

    is the source of all EVIL :}  and days of wasted time


    This is a very poorly explained legacy issue I think that Nordic should (must) obliterate.

    What is killing me is seeing that a fresh download of SDK16.0.0 applies this by default, and many (or possibly all) example projects are based on these legacy nrf_drv implementations.   But elsewhere, I see the nrfx_ are the preferred route, so why they have defaulted to legacy is unknown.

    Many others are getting tripped up by this issue ...

    https://devzone.nordicsemi.com/f/nordic-q-a/59960/how-to-use-the-nrf5_sdk/244087#244087

    https://devzone.nordicsemi.com/f/nordic-q-a/60536/do-we-need-to-define-nrfx_timer1_enabled-inorder-to-use-timer1/246209#246209


    We should start a Nordic bounty to remove all EVIL legacy stuff in SDK16 … I would throw in $100 … :}

    It is never explained properly anywhere, and the 16K line sdk_config.h is full of surprises like this.

  • Hi mtsunstrum, I had sort-of given up on anyone responding - Phew, I have a fellow coder who understands the issue. Unfortunately there is a BUT. The BUT is that I suspect any fix to this is likely to make some end-user legacy code fail to compile. If it uses the original nrf  stuff then anything that triggers nrfx code is likely to screw up the nrf stuff. I suspect that is why they tried to default back to the nrf code - albeit with the consequence that sdk_config cannot be used both by the legacy AND the nrfx stuff.

    I really don't have concrete evidence of this, not having tested it, but surely there must be a reason other than failure to separate legacy and new.

    In any case, thanks for the support, I wasted quite  a bit of time to decide it was a mess. Perhaps others will read and understand this, and thereby avoid wasting their time.

    My wish is that Nordic abandon the documentation encouraging the use of app_config.h until (and if) the problem with legacy code is resolved. I don't like the "copy and edit" model for sdk_config.h but at least it works and is simple.

  • I should have added: what did I do? I started with minimal sdk_config.h My code failed to compile. I looked at the first thing that was missing, searched all sdk_config until I found it, copied and pasted the entire chunk in which it appeared. Thereafer rinse and repeat until it compiles... A bit crude but it works ;-)

  • PPS, I failed to identify the other coders having problems. Well done. The advice needs to be "only put into your own version of sdk_config.h what you absolutely need for your application" the remainder is dangerous.

Related