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

Variable Not Incrementing with nrf_delay_ms()

I have the follow code in my application for a PCA10028 program from the nRF51 Development Kit (S110 v9.0):

int main(void)
{
    int i = 0;
    while(true)
    {
        SEGGER_RTT_printf(0, "%d\n", i);
        i++;

        nrf_delay_ms(1000);
    }
}

Output:

0
0
0
0

I want the variable "i" to increment 1,2,3... but it looks like during the nrf_delay_ms() the device is resetting my variable to 0 every time.

Is there any way to have this variable persisted without the use of "pstorage.h"?

  • pstorage? You're way out the weeds thinking about that, this is simple C, i's a variable, it should just work, in fact that code does work when I test it, as you'd totally absolutely expect it to.

    What compiler are you using and are you in debug or release mode?

    The only thing I can think of here is that the nrf_delay function (in assembler) doesn't appear in every case to tell the compiler it's using r0, so it's quite possible that 'i' is in r0 and is getting clobbered. That would be somewhat odd however, especially in a debug version.

    You could take a look at the assembler and see what it's doing. This code should "just work". Try a few things like making i static and volatile, see if it changes things.

  • Definitely unexpected behaviour.

    Could the device be being reset for some reason? Try putting a SEGGER_RTT_printf() call before the while() loop that outputs something like main started.... Then see if this message occurs between each output of the 0 line.

    Or you could achieve something similar with a debugger break point.

  • @Tanner Nelson: I tried to reproduce but it worked normally. Here is my code (SDK 9.0 S110 v8.0): blinky - rtt.zip

  • Thank you for the help, it turns out the culprit was not nrf_delay_ms() as I thought.

    The full version of the code I was running included a call to advertising_start() in the while(true) loop.

    That advertising_start() function looked like this:

    /**@brief Function for starting advertising.
     */
    static void advertising_start(void)
    {
        uint32_t err_code;
    
        err_code = sd_ble_gap_adv_start(&m_adv_params);
        APP_ERROR_CHECK(err_code);
    
        err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
        APP_ERROR_CHECK(err_code);
    }
    

    Commenting out the first APP_ERROR_CHECK() call so that it looks like this

    /**@brief Function for starting advertising.
     */
    static void advertising_start(void)
    {
        uint32_t err_code;
    
        err_code = sd_ble_gap_adv_start(&m_adv_params);
        //APP_ERROR_CHECK(err_code);
    
        err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
        APP_ERROR_CHECK(err_code);
    }
    

    fixed the issue. Commenting out the other APP_ERROR_CHECK() (or any other line in this method, or line in the main() method) has no effect. The only line that affects my variables being reinitialized is that line I commented out.

    I have no idea why that would be happening, but my application works perfectly now since commenting that out.

    I have both the int i = 0; in the main function and an external bool m_flip = false; that were getting reset by that APP_ERROR_CHECK() call in advertising_start(). I would be very interested to know how that function is affecting the memory for those variables.

  • err_code = sd_ble_gap_adv_start(&m_adv_params);

    generates error and APP_ERROR_CHECK(err_code) resets CPU that's why it always sends only zero. Probably advertising_start() call is after the SEGGER_RTT_printf

Related