Absolute locations for CRC - my turn to be confused

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

I sure could use some help.  I am attempting to store a dword CRC at end of application memory memory for an xmega 128A3U part.  I have set up a .section in the memory linker settings and the hex file is properly

created, storing 0x55AA55AA (fake crc) at the proper location.  This has been verified.  The problem is I cannot seem to properly use the variable crcval.  The debugger shows that crcval contains the 0x55AA55AA crc but when I attempt to assign it to another 32bit variable, the data is corrupt.  The snippet below is what I was using to prove out what I am attempting to do.  I am obviously missing something basic.

Your help would be appreciated.

Thanks

Jim

 

 

/*
 * CRCtesting.c
 *
 * Created: 3/6/2017 2:25:47 PM
 */ 

#include <avr/io.h>
#include <avr/pgmspace.h>


//.thecrc=0xFFFE
uint32_t __attribute__ ((section(".thecrc")))  crcval  = 0x55AA55AA;
int main(void)
{

    volatile uint32_t crc;
    crc = crcval;

    while (1) 
    {
    }
}

 

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

I'm not that conversant in your toolchain, but don't you have to tell it that the source of the field in the assignment is in flash?  pgmreaddword or something like that?

 

My first guess was some kind of byte (GCC) vs. word (Atmel) flash addressing but it appears that might be OK.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Hi -

I thought the same - using pgm_read_dword(crcval) and did not get the 0x55AA55AA

 

I also tried:

const __flash uint32_t __attribute__ ((section(".thecrc")))  crcval  = 0x55AA55AA;

However, the linker appears to ignore the __attribute__ statement as the 0x55AA55AA was not stored at the word location 0x1FFFC;

Not sure what is going on.  Something simple, I'm sure.

 

 

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

rfdes wrote:
I thought the same - using pgm_read_dword(crcval) and did not get the 0x55AA55AA

 

Macro pgm_read_dword

#define pgm_read_dword(address_short) \
	pgm_read_dword_near(address_short) 

Read a double word from the program space with a 16-bit (near) address.

Note

The address is a byte address. The address is in the program space.

Do you get the same result with &crcval?

 

Isn't there a difference between const and PROGMEM?  (I guess I'd think you'd get a warning)

 

Isn't there a Tutorial forum article on using the pgm_ facilities?

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Mon. Mar 6, 2017 - 08:43 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

 

I've tried the following, each with the same results:

 

 

crc == 0xFFFFFFFF

 

 

/*
 * CRCtesting.c
 *
 * Created: 3/6/2017 2:25:47 PM
 */ 

#include <avr/io.h>
#include <avr/pgmspace.h>


//.thecrc=0xFFFE

volatile uint32_t __attribute__ ((section(".thecrc")))  crcval = 0x55AA55AA;

int main(void)
{

    volatile uint32_t crc;
    crc = pgm_read_dword(&crcval);
    crc = pgm_read_dword_near(&crcval);
    crc = pgm_read_dword_far(&crcval);    
    while (1) 
    {
        
    }
}

 

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

I'm surprised a GCC expert hasn't jumped in.

 

Excerpt from .map:

 

.thecrc         0x00802000        0x4 load address 0x0000023c
 .thecrc        0x00802000        0x4 main.o
                0x00802000                crcval

.bss            0x00802000        0x0
                [!provide]                PROVIDE (__bss_start, .)

 

Does that imply that crcval is in SRAM?  Dunno.  Don't you need a PROGMEM in there somewhere?

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

https://www.avrfreaks.net/forum/p...

https://www.avrfreaks.net/forum/d...

In the latter, Cliff sez PROGMEM not needed.  But looks like exactly your situation...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

rfdes wrote:
I have set up a .section in the memory linker settings and the hex file is properly created, storing 0x55AA55AA (fake crc) at the proper location. This has been verified.
rfdes wrote:
However, the linker appears to ignore the __attribute__ statement as the 0x55AA55AA was not stored at the word location 0x1FFFC; Not sure what is going on.
What is true now? Is it there or not?

rfdes wrote:
crc = pgm_read_dword_far(&crcval);
Pointers are only 16 bit wide, so you can't use the normal c notation to get an address beyond 0xffff.

Either use pgm_get_far_address(), or since you place it at a fixed address anyway use that directly.

Stefan Ernst

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

 

Still no luck -

 

I should have mentioned that I am using 4.9.2 of the compiler in case that may be an issue.

I tried creating a pointer to __flash and I still have not been able to read the data into a variable. 

Hopefully, Cliff will jump in and set me straight.

 

 

/*
 * CRCtesting.c
 *
 * Created: 3/6/2017 2:25:47 PM
 */

#include <avr/io.h>
#include <avr/pgmspace.h>

//.thecrc=0xFFFE   <<< word address in Linker Memory FLASH section

uint32_t __attribute__ ((section(".thecrc")))  crcval = 0x55AA55AA;

const __flash uint32_t * ptrcrc = (const __flash uint32_t *)0x1FFFC;  // I understand that this is to be a byte address

int main(void)
{

    volatile uint32_t crc;
    
    crc = pgm_read_dword(&crcval);    // crc does NOT contain correct value
    crc = *ptrcrc;                             // crc does NOT contain correct value

    while (1)
    {
        
    }
}

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

rfdes wrote:
crc = pgm_read_dword(&crcval);
You need to use the _far versions of the pgm_read_ functions. And again: &crcval will not work.

rfdes wrote:
const __flash uint32_t * ptrcrc = (const __flash uint32_t *)0x1FFFC;
Won't work. Again: size of pointers is only 16 bit.

Stefan Ernst

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

 

Thanks for the help -

 

Yes, the crc value has been placed at 0x1FFFC and I attempted to use my fixed address as below, but it does not work as I would expect:

 

uint32_t * ptrcrc = (uint32_t *)0x1FFFC;

 

 

 

#include <avr/io.h>
#include <avr/pgmspace.h>

//.thecrc=0xFFFE   <<< word address in Linker Memory FLASH section

uint32_t __attribute__ ((section(".thecrc")))  crcval = 0x55AA55AA;
uint32_t * ptrcrc = (uint32_t *)0x1FFFC;

 

int main(void)
{

volatile uint32_t crc;   
 

    crc = pgm_read_dword_far(&crcval);    
    crc = *ptrcrc;   // crc  != 0x55AA55AA

    while (1)
    {
        
    }
}

Last Edited: Mon. Mar 6, 2017 - 10:48 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

 

Thanks  @sternst

 

Ok - Your solution finally hit sank in.

 

By the way. When developing large programs that will be in excess of 64K in size, how does one ensure that his code will properly execute when exceeding the 64K limit?

Will the compiler likely catch these situations and alert the firmware engineer?

 

//.thecrc=0xFFFE   <<< word address in Linker Memory FLASH section

uint32_t __attribute__ ((section(".thecrc")))  crcval = 0x55AA55AA;

 

int main(void)
{

volatile uint32_t crc;   

    crc = pgm_read_dword_far(pgm_get_far_address(crcval));    //finally works!!

    while (1)
    {
        
    }
}