Strange behaviour of incrementing variable in "noinit" section while desetting debugger

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
HuEl_264296
Level 5
Level 5
First like given 25 sign-ins First solution authored

I am trying to use a variable in the "noinit" memory section. I am testing it with some very simple code:

 

#include "project.h"
CY_NOINIT int myVar;

int main(void)
{
    CY_NOP;
    myVar++;
    for(;;) {}
}

 

 

I then try to use that code in the debugger. However, I see a very strange effect when I click the Reset button:

HuEl_264296_0-1658499496192.png

Note that I never click the Play button. I just click Reset again and again.

When I first start the debugger, I see this:

HuEl_264296_1-1658499594293.png

There's the code, and the CY_NOP is highlighted in yellow, meaning that line hasn't been executed yet.

Then I don't click Play.

But I just click Reset again, and this is what I see:

HuEl_264296_2-1658500747573.png

Look at that, myVar has increased in value by 4! Each time I click Reset, the value increases by 4. This is strange for two reasons:

  1.  No code should have been executed yet, as I haven't clicked Play.
  2. There's nowhere in the code that adds 4 to the variable.

What is going on here?

Here's some more evidence:

  • If I step through the code and execute the line myVar++; then I see the variable increase by 1.
  • If I change the type of myVar to char, it still increases by 4.

 

0 Likes
1 Solution
DennisS_46
Employee
Employee
100 sign-ins 50 likes received 50 solutions authored

The chip runs a lot of code in the boot process, this includes un-packing a bit-stream that defines the initial state of ALL of the registers and assigned memory locations (but not NOINIT section), exercising the Reset line and lots of other stuff. Who knows what memory locations can get over-written in the process? It's even messier in de-bug mode. What you are seeing is non un-expected behavior. If you need to save myvar so that it doesn't get randomly over-written at start, save it in Flash every time you use it so the next time you need it at start-up it will have your known value.
---- Dennis Seguine, PSoC Applications Engineer (with help from our software development team)

View solution in original post

0 Likes
4 Replies
HuEl_264296
Level 5
Level 5
First like given 25 sign-ins First solution authored

After some more investigation, it looks like the Reset command of the debugger actually causes the firmware to execute 4 times, each time for about 2.7ms, before eventually getting it to stop back at the beginning of the code:

I tested some new firmware:

#include "project.h"

CY_NOINIT int myVar;

int main(void)
{
    CY_NOP;
    myVar++;
    
    while(1)
    {
        LED_Write(1);
        CyDelayUs(3);
        LED_Write(0);
        CyDelayUs(3);
    }
        
    for(;;) {}
}

Then I used my logic analyser to observe the GPIO pin. Here we can see 4 groups of pulse trains:

HuEl_264296_0-1658503248602.png

Looking more closely, it looks like each one lasts for about 2.7ms.

HuEl_264296_2-1658503353720.png

Is this the expected behaviour of the debugger?

 

0 Likes

I can see it's actually pulsing the reset line:

HuEl_264296_3-1658503833139.png

Is it supposed to do that?

BTW, I'm using the MiniProg4.

 

0 Likes
DennisS_46
Employee
Employee
100 sign-ins 50 likes received 50 solutions authored

The chip runs a lot of code in the boot process, this includes un-packing a bit-stream that defines the initial state of ALL of the registers and assigned memory locations (but not NOINIT section), exercising the Reset line and lots of other stuff. Who knows what memory locations can get over-written in the process? It's even messier in de-bug mode. What you are seeing is non un-expected behavior. If you need to save myvar so that it doesn't get randomly over-written at start, save it in Flash every time you use it so the next time you need it at start-up it will have your known value.
---- Dennis Seguine, PSoC Applications Engineer (with help from our software development team)

0 Likes

Hi Dennis,

Thanks for your reply. Two things:

1a. Whatever else happens in the boot process, the NOINIT memory shouldn't be overwritten. That is after all the whole point of the NOINIT memory. If you're telling me that maybe the NOINIT memory gets overwritten, and maybe it doesn't, "who knows?", then essentially the NOINIT memory is 100% useless.

1b. I'm pretty sure it's not 100% useless as the Cypress library code actually uses it (e.g. in CyLib.c).

2. If you read my replies, you'll see that I worked out what was happening. When I click "Reset" in the debugger, it releases the reset line 4 times, each for about 2.5ms. This allows the first 2.5ms of code to execute before the chip is held in reset again.

This is very surprising behaviour. I would not expect any code at all to be executed when I click Reset in the debugger. I would expect that code would only be executed when I clicked Play.

In my test, I was incrementing a NOINIT variable near the beginning of my code, and so I was seeing it incremented 4 times each time I clicked "Reset".

Kind regards

Hugo

 

0 Likes