[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] Embedding CRC into hex file
From: |
Bob Paddock |
Subject: |
Re: [avr-gcc-list] Embedding CRC into hex file |
Date: |
Tue, 27 Mar 2007 13:10:39 -0400 |
User-agent: |
Opera Mail/9.10 (Win32) |
On Tue, 27 Mar 2007 11:22:13 -0400, larry barello <address@hidden>
wrote:
Does anyone have the AVR equivalent routine for one of the CRC16
generated with "srecord" they would share?
I would like to modify my boot loader to
check the application code before running so corrupted downloads don't
wedge
my application.
Here is the automagical stuff I have in my Makefile and main.c.
If the CRC is bad you get nothing but a blinking red LED;
assuming things are not so bad that the LED won't blink...
Most of this is bits accumulated from the avr lists here
over the years:
Snippets from my Makefile:
# Set to one to use CRC Flash testing of memory contents. If CRC
# fails the Red LED will blink each 1/4 second, the unit will do
# nothing else. Set to zero to disable the CRC check.
USE_CRC_FLASH_CHECK=1
ifeq ($(USE_CRC_FLASH_CHECK),1)
CFLAGS += -DUSE_CRC_FLASH_CHECK=1
else
CFLAGS += -DUSE_CRC_FLASH_CHECK=0
endif
# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
ifeq ($(USE_CRC_FLASH_CHECK),1)
mv $@ $(TARGET).org.hex
srec_cat $(TARGET).org.hex -Intel -Little_Endian_CRC16 -max
$(TARGET).org.hex -Intel -Cyclic_Redundancy_Check_16_XMODEM -Fill 0xFF
-OVER $(TARGET).org.hex -Intel -Output $(TARGET).hex -Intel
endif
...
In main.c:
#if( USE_CRC_FLASH_CHECK > 0 )
uint16_t __data_load_end[1]; /* Defined by the linker script. Set to
address of last byte of .text+.data section */
#include <util/crc16.h>
static __inline__ uint16_t crc_flash_check_has_error( void );
static __inline__ uint16_t crc_flash_check_has_error( void )
{
uint8_t byte_u8;
uint16_t crc_u16, i;
uint16_t flash_end_u16 = (uint16_t) &(__data_load_end[0]);
for( crc_u16 = i = 0; i < flash_end_u16; i++)
{
byte_u8 = pgm_read_byte( i );
crc_u16 = _crc_xmodem_update( crc_u16, byte_u8 );
}
if( pgm_read_word( flash_end_u16 ) != crc_u16 )
{
return( 1 ); /* Bad CRC */
}
else
{
return( 0 ); /* Good CRC */
}
}
#endif
MAIN_TYPE main( void )
{
#if( USE_CRC_FLASH_CHECK > 0 )
if( crc_flash_check_has_error() )
{/* Hardware should still be setup from bootloader when we get here: */
LED_GREEN_DEASSERT();
for(;;)/*ever*/
{
delay_50MS();
delay_50MS();
delay_50MS();
delay_50MS();
delay_50MS();
LED_RED_TOGGLE();
}
}
#endif
...
}
On my far to long ToDo list is to get a proper CCITT-CRC16 into
srec_cat so that you can get the 0xF0B8 magic number test to work.
The XMODEM version used here can miss leading zeros.