[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] __checksum
From: |
Blake Leverett |
Subject: |
Re: [avr-gcc-list] __checksum |
Date: |
Thu, 29 May 2008 11:25:01 -0600 |
User-agent: |
KMail/1.9.9 |
On Thursday 29 May 2008, trile58 wrote:
> I have been successfully porting the old code from IAR to AVR GCC except
> for the followings:
>
> extern flash unsigned short __checksum;
> CRC_SUM = 0; /* Clear CRC-Check of Program Memory (Flash)
> */
> /* Checksum of Program memory (IAR-Example) */
> CRC_SUM = slow_crc16(CRC_SUM,(unsigned char flash *)0,(unsigned
> long)&__checksum);
> CRC_SUM = slow_crc16(CRC_SUM,(unsigned char flash
> *)&zero,sizeof(zero)); /* call with two 0 bytes for the correct calculation
> of crc */
>
> I had flash changed to PROGMEM as instructed in the porting document.
> However, I got an error "undefined reference to __checksum" . From Porting
> from IAR to AVR GCC document, it does not list __checksum is one of the
> thing need to be ported. I wonder how this __checksum gets created and
> where it is located. Please advice.
>
> Thanks
It looks like the problem is the "flash" keyword. Avr-gcc handles flash
differently from IAR - so more is needed than just a keyword change. The
__checksum name is just a variable name, so I think that the flash keyword is
where the compiler is losing track.
Be sure you are including <avr/pgmspace.h>, and you may want to place the
PROGMEM keyword later in the line:
extern unsigned short PROGMEM __checksum;
One disturbing thing is that __checksum is declared but not assigned any
value. This may be causing gcc to not compile the line correctly and silently
drop the __checksum keyword. Maybe you could find out where __checksum is
really declared, and make sure that __checksum is declared properly with
PROGMEM, and that it is set in that declaration to a real value.
I am not sure that you need the PROGMEM keyword in the extern declaration
above, though I don't think it hurts.
Also, in the slow_crc16() function, make sure that you call pgm_read_byte() or
pgm_read_word() as necessary. You cannot simply say
uint16_t a = __checksum;
you have to use
uint16_t a = pgm_read_word(&__checksum);
Or something like that.
Blake