From: Joseph Coffland Date: Sun, 9 Jul 2017 00:45:48 +0000 (-0700) Subject: Added checksumming to bootloader X-Git-Url: https://git.buildbotics.com/?a=commitdiff_plain;h=3aecc4aba4df314e84174b929837e8a57823c839;p=bbctrl-firmware Added checksumming to bootloader --- diff --git a/avr/src/boot/boot.c b/avr/src/boot/boot.c index 885ef74..a0ac310 100644 --- a/avr/src/boot/boot.c +++ b/avr/src/boot/boot.c @@ -258,17 +258,15 @@ int main() { break; } - case CMD_CHIP_ERASE: - // Erase the application section + case CMD_FLASH_ERASE: SP_EraseApplicationSection(); - - // Wait for completion nvm_wait(); + send_char(REPLY_ACK); + break; - // Erase EEPROM + case CMD_EEPROM_ERASE: NVM.CMD = NVM_CMD_ERASE_EEPROM_gc; nvm_exec(); - send_char(REPLY_ACK); break; @@ -371,7 +369,7 @@ int main() { case CMD_VERSION: send_char('0'); - send_char('1'); + send_char('2'); break; case CMD_READ_SIGNATURE: @@ -380,6 +378,48 @@ int main() { send_char(SIGNATURE_0); break; + case CMD_READ_CHECKSUM: + // Setup + nvm_wait(); + + // Reset CRC + CRC_CTRL |= CRC_RESET_RESET1_gc; + CRC.CHECKSUM0 = CRC.CHECKSUM1 = CRC.CHECKSUM2 = CRC.CHECKSUM3 = 0xff; + + // 32-bit mode, flash source + CRC_CTRL = CRC_CRC32_bm | CRC_SOURCE_FLASH_gc; + + // Start address + NVM.ADDR0 = (uint8_t)(APP_SECTION_START >> 0); + NVM.ADDR1 = (uint8_t)(APP_SECTION_START >> 8); + NVM.ADDR2 = 0; + + // End address + NVM.DATA0 = (uint8_t)(APP_SECTION_END >> 0); + NVM.DATA1 = (uint8_t)(APP_SECTION_END >> 8); + NVM.DATA2 = (uint8_t)(APP_SECTION_END >> 16); + + NVM.CMD = NVM_CMD_FLASH_RANGE_CRC_gc; + CCP = CCP_IOREG_gc; + NVM.CTRLA = NVM_CMDEX_bm; + + // Compute + nvm_wait(); + while (CRC.STATUS & CRC_BUSY_bm) continue; + + // Send 32-bit checksum + send_char(CRC.CHECKSUM3); + send_char(CRC.CHECKSUM2); + send_char(CRC.CHECKSUM1); + send_char(CRC.CHECKSUM0); + break; + + case CMD_FLASH_LENGTH: + send_char((uint8_t)(APP_SECTION_SIZE >> 16)); + send_char((uint8_t)(APP_SECTION_SIZE >> 8)); + send_char((uint8_t)(APP_SECTION_SIZE >> 0)); + break; + case CMD_BLOCK_CRC: send_char(block_crc >> 8); send_char((uint8_t)block_crc); diff --git a/avr/src/boot/boot.h b/avr/src/boot/boot.h index b966c1d..2af4be1 100644 --- a/avr/src/boot/boot.h +++ b/avr/src/boot/boot.h @@ -53,13 +53,16 @@ enum { CMD_VERSION = 'V', CMD_HW_VERSION = 'v', // Unsupported extension CMD_READ_SIGNATURE = 's', + CMD_READ_CHECKSUM = 'X', + CMD_FLASH_LENGTH = 'n', // Addressing CMD_SET_ADDRESS = 'A', CMD_SET_EXT_ADDRESS = 'H', // Erase - CMD_CHIP_ERASE = 'e', + CMD_FLASH_ERASE = 'e', + CMD_EEPROM_ERASE = '_', // Block Access CMD_BLOCK_LOAD = 'B', diff --git a/scripts/avr109-flash.py b/scripts/avr109-flash.py index 87b919d..111d812 100755 --- a/scripts/avr109-flash.py +++ b/scripts/avr109-flash.py @@ -25,6 +25,17 @@ def crc16(data): return crc +def avr_crc32(data, length): + mem = [0xff] * length + + for addr, chunk in data: + for x in chunk: + mem[addr] = x + addr += 1 + + return binascii.crc32(bytes(mem)) + + def read_intel_hex(f): base = 0 pos = 0 @@ -82,7 +93,7 @@ def recv_int(size): # Read firmware hex file -data = read_intel_hex(open(sys.argv[1], 'r')) +data = list(read_intel_hex(open(sys.argv[1], 'r'))) # Open serial port sp = serial.Serial(dev, baud, timeout = 10) @@ -105,12 +116,39 @@ send('S') if boot_id != recv(len(boot_id)): raise Exception('Failed to communicate with bootloader') +# Get version +send('V') +major = int(recv(1)) +minor = int(recv(1)) +print('Bootloader version: %d.%d' % (major, minor)) + +# If bootloader is new enough compare checksums +if 0 < major or 1 < minor: + # Get flash length + send('n') + flash_len = recv_int(3) + + # Get current flash CRC + send('X') + new_crc = avr_crc32(data, flash_len) + old_crc = recv_int(4) + if old_crc == new_crc: + print('Flash already up to date') + sys.exit(0) + + print('CRC: old=0x%08x new=0x%08x' % (old_crc, new_crc)) + + # Erase + send('e') + if recv(1) != '\r': raise Exception('Flash erase failed') + # Get page size send('b') if recv(1) != 'Y': raise Exception('Cannot get page size') page_size = recv_int(2) print('Page size:', page_size) + # Program print('Programming', end = '') count = 0