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.

Parents
  • 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.

Reply
  • 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.

Children
Related