avr-gcc-list
[Top][All Lists]
Advanced

[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.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]