Debugging flash variables with CodeVisionAVR/Atmel Studio?

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all,

 

I am using CodeVisionAVR 3.34 and Atmel Studio 7.0.1931. I just noticed that I have difficulties debugging flash variables.

 

To illustrate this, I prepared a CodeVisionAVR application project for ATxmega128A1U: flashvars_xmega.zip

 

The project is simple: there is nothing in the main `while(1)`; then there is a (multidimensional) array of ints stored in flash:

 

// my_flash_array size: 3*4*5 = 60 (unsigned) int entries
flash unsigned int my_flash_array[3][4][5] =
{
  // I=0
  {
    {0b1111111111111111,0b1111111111111000,0b1111111111111111,0b1111111111111000,0b1111111111111111}, // 65535,65528,65535,65528,65535
    {0b1111111111111101,0b1111111111111010,0b1111111111111101,0b1111111111111010,0b1111111111111101}, // 65533,65530,65533,65530,65533
    {0b1111111111111110,0b1111111111111011,0b1111111111111110,0b1111111111111011,0b1111111111111110}, // 65534,65531,65534,65531,65534
    {0b1111111111111001,0b1111111111111010,0b1111111111111100,0b1111111111111010,0b1111111111111001}  // 65529,65530,65532,65530,65529
  },
...

... and there is a volatile global counter variable. Then there is a timer interrupt that hits each second, increases the global counter -> then indices for access are calculated from the global counter, so we "slide" along the values in the array in sequence; the corresponding value in the array is read into a variable, and then the three least significant bits of this variable is applied to PORTE pins 2, 3 and 4 (where I have LEDs, so I can see approx what is happening).

 

The code works fine, in the sense that the LEDs change according to the bit patterns in the `my_flash_array` as expected.

 

However, when I export this project for Atmel Studio, and try to debug by inserting a breakpoint in the timer interrupt, and doing a "Watch" on the `my_flash_array` variable, this is what I get:

 

flashvars_xmega_AtmelStudio.png

 

That is, I get the values of `my_flash_array` to be mostly zeroes - which they are not, as I can confirm that via the LED patterns. Also, if I type`my_flash_array` in the Address field of the "Memory 4" window, then I get taken to Address: "0x000000,data" (the default is otherwise "0x000000,prog"), and the memory shown there seems to correspond to what is shown for `my_flash_array`in the "Watch 1" windows (but clearly, not to what is actually in `my_flash_array` in flash memory).

 

Is it possible to somehow set up CodeVisionAVR, or Atmel Studio, so I get the actual (flash) values of `my_flash_array` shown in the "Watch 1" window?

 

Attachment(s): 

Last Edited: Fri. Jun 14, 2019 - 02:06 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you look in the type column in the watch, what is the type that CodeVision is saying that these variables are (first guess is that they are not tagged with flash in the debug info, so we're actually reading address 0x0000 in ram, not in flash...)

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


I wanted to see how AS7 handled the same thing from avr-gcc so I tried:

 

Good news is that it knows the symbol is "prog" so presumably it would try to deference it in the right memory space. Bad news is that it seems to have lost the fact that it's a pointer to 2D uint32_t :-(

 

It may just be easiest to step to the actual LPM and see what gets loaded !

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As you can see, the debug info seems to have lost the type info, calling it a void. You should be able to watch it by doing a (uint32_t**) or (uint32[][]) cast in front of it... Hopefully the cast won't cast away the storage specifier... If it does then there's a expression format to force evaluation from flash...

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

Last Edited: Fri. Jun 14, 2019 - 03:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you omit the flash modifier the multi-dimensional array is in SRAM.   The debugger can Watch it just fine.

And you can inspect individual elements.

 

Why would you want to "debug" a const multi-dimensional array is in Flash ?

Incidentally,  it is stored at 0x1FC (byte address)

 

I suspect that GCC would have a similar issue.   i.e.  a multi-dimension array in Flash.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Ok, so I was curious to see how Imagecraft handled this:

 

Looks like it works as expected.  Thanks guys for the interesting discussion.

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
stack gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks all, for the responses!

 

meolsen wrote:

If you look in the type column in the watch, what is the type that CodeVision is saying that these variables are (first guess is that they are not tagged with flash in the debug info, so we're actually reading address 0x0000 in ram, not in flash...)

 

Just took a screenshot of that - I guess the type is `unsigned int{data}`:

 

flashvars_xmega_vartype.png

 

Now, I vaguely remember, you could add a comma to a watch expression in Atmel Studio 7, and then append some "specifiers", I guess (though I cannot remember where I saw this first)

 

Interestingly, if I append `,flash` to `my_flash_array` in the watch window, then I get something else:

 

flashvars_xmega_vartype_flash.png

 

Now, the datatype seems to be `unsigned int{prog}`; and indeed, `my_flash_array[0]` is not 0 anymore, but instead it is 37900 - which indeed does correspond to the first two bytes in prog APP_SECTION, 0c 94, because 0x940c = 37900; however, it still does not correspond to the expected flash value of `my_flash_array[0]`, which should be 65535 (0xff 0xff).

 

meolsen wrote:

... then there's a expression format to force evaluation from flash...

 

It would be great to know: what is the expression format to force evaluation from flash?

 

In any case, the above quite inspired me to try the following in Watch: `(unsigned int[][][])my_flash_array,flash` - and now I get this:

 

flashvars_xmega_vartype_flash_cast.png

 

Well, finally I got the `my_flash_array[0][0][0]` value to be shown as 65535, as expected - but:

 

  • This value is indicated to be at address 0x940c,prog - I have tried to align that address in "Memory 4" window; and while the first two bytes are indeed 0xff 0xff, also the second pair is 0xff 0xff, while as per the spec of `my_flash_array`, I'd expect 65528 = 0xfff8, or 0xf8 0xff instead
  • The `(unsigned int[][][])my_flash_array,flash` specification only prints the first element - but I'd like the entire array to be shown (as when I just used `my_flash_array` in watch); is there a syntax I can use for that?

 

 

david.prentice wrote:

Incidentally,  it is stored at 0x1FC (byte address)

 

Fantastic! Could you please tell me how did you figure this out? I was trying very hard to look for this address in the Atmel Studio GUI, and I couldn't find it anywhere!

 

Anyways, here's a screenshot:

 

flashvars_xmega_vartype_flash_1FC.png

 

It's clear now, from the "Memory 4" window, that we're looking at the right spot, as the first few bytes are 0xff 0xff 0xf8 0xff, as expected... However:

 

  • What would be the right syntax for the watch expression, so I could observe 0x01FC as a [3][4][5] array? I've tried `(unsigned int[][][])0x0001FC,flash` above, but it too just shows me the first element...
  • Is there a watch expression, so that I could enter `my_flash_array` and have it resolve to 0x01FC automatically - instead of having to look up the address 0x01FC manually, and having to use the address verbatim?

 

david.prentice wrote:

If you omit the flash modifier the multi-dimensional array is in SRAM.   The debugger can Watch it just fine.

And you can inspect individual elements.

 

Why would you want to "debug" a const multi-dimensional array is in Flash ?

 

Well, the project in OP is just a stand-in for another project I'm working on. There, the multidimensional array has to be stored in flash, because it otherwise is too big and doesn't fit in RAM.

 

When I worked on that project a couple of months ago, I could just read any element of the flash array in a RAM variable, for instance `unsigned int my_val = my_flash_array[x][y][z];`, and then it is used in some calculations, and the result of those is printed on LCD - a couple of months ago there was no problem with this whatsoever.

 

In the meantime, other people also worked on the project and made some changes (while I was doing something else), and now I'm back again at it. Now when I try the same, the result printed on the LCD is the same regardless of which element of the multidimensional array is read - and the value printed is, as if any element of the multidimensional array is zero!?

 

As I found this rather confusing, I thought it is time to take a trip to the debugger, just to confirm that variables are being read right - and I was quite surprised to see the debugger reporting `my_flash_array` as being full of zeroes, instead of the values that are explicitly specified in code.

 

So I thought, I better try to ask and find out what is going on, otherwise poking around in the debugger won't help me much in troubleshooting ...

 

Last Edited: Mon. Jun 17, 2019 - 08:55 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


sdbbs wrote:
however, it still does not correspond to the expected flash value of `my_flash_array[0]`,
That's because it "thinks" that my_flash_array is at address 0x0000

 

 

which it clearly cannot be.

sdbbs wrote:
and made some changes (while I was doing something else)
Do you not have a revision control system? Surely you can either "git blame" to see who changed which lines or you can just look at "git log" and see what changes were pushed.

 

There is little doubt that the array access works. If you just do int "dummy = my_array[1][2][3];" then break and inspect dummy surely it must confirm that the element [1][2][3] is loaded so if the LCD display is wrong it's going to be dome later processing of the data that is messed up (or perhaps the thing that determined [1][2][3] in the first place?). So you may be focussing all your energy in the wrong place. I'm pretty sure Codevision will LPM when you ask it to !

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


sdbbs wrote:
however, it still does not correspond to the expected flash value of `my_flash_array[0]`,
That's because it "thinks" that my_flash_array is at address 0x0000

 

 

which it clearly cannot be.

sdbbs wrote:
and made some changes (while I was doing something else)
Do you not have a revision control system? Surely you can either "git blame" to see who changed which lines or you can just look at "git log" and see what changes were pushed.

 

There is little doubt that the array access works. If you just do int "dummy = my_array[1][2][3];" then break and inspect dummy surely it must confirm that the element [1][2][3] is loaded so if the LCD display is wrong it's going to be dome later processing of the data that is messed up (or perhaps the thing that determined [1][2][3] in the first place?). So you may be focussing all your energy in the wrong place. I'm pretty sure Codevision will LPM when you ask it to !