diff --git a/bootloader.c b/bootloader.c index b34d264..fa5662a 100644 --- a/bootloader.c +++ b/bootloader.c @@ -31,6 +31,8 @@ char* argvs[3][10]; cmd_t cmd; +uint32_t* size_store = (uint32_t*) 0x3400; +crc_t* crc_store = (crc_t*) 0x3000; uint32_t offset, total_size, offset_pointer; @@ -43,43 +45,82 @@ crc_t crc_prog, crc_data; char buff[256]; +int is_code_valid(){ + crc_t expected_crc = *crc_store; + size_t application_size = *size_store; + crc_t real_crc = crc_init(); + real_crc = crc_update(real_crc, (void*)APP_OFFSET, application_size); + real_crc = crc_finalize(real_crc); + error_code is_error = uart_commands_check(real_crc, expected_crc); + if(is_error == ok){ + return 1; + } + else return 0; +} + +void write_app_info(crc_t* checksum, size_t* size){ + iap_prepare_sectors(&status, addr_to_sector(0x3000), addr_to_sector(0x3fff)); + if(status != ok){ + uart_send_err(); + } + iap_erase_sectors(&status, addr_to_sector(0x3000), addr_to_sector(0x3fff)); + if(status != ok){ + uart_send_err(); + } + iap_prepare_sectors(&status, addr_to_sector(0x3000), addr_to_sector(0x3fff)); + if(status != ok){ + uart_send_err(); + } + iap_copy_to_flash(&status, (long unsigned int *)crc_store, (long unsigned int*)checksum, 0x0400); + iap_copy_to_flash(&status, (long unsigned int *)size_store, (long unsigned int*)size, 0x0400); +} + int main(void) { - cmd.argv = argvs; + cmd.argv = (char**)argvs; + //verify b is pressed + //checksum is correct ( + //bootloader_init(); uart_init(115200); - while(1){ - uart_receive_command(buff); - uart_parse_command(buff, &cmd); - if (strncmp("GETID", cmd.argv[0], 5)==0){ - uart_commands_getid(&status); + if(is_code_valid()){ + SCB->VTOR = APP_OFFSET; + __asm("ldr r0,=0x4000"); + __asm("ldr sp,[r0]"); + __asm("ldr pc,[r0,#4]"); + }else{ + while(1){ + uart_receive_command(buff); + uart_parse_command(buff, &cmd); + if (strncmp("GETID", cmd.argv[0], 5)==0){ + uart_commands_getid(&status); - }else if(strncmp("GETSE", cmd.argv[0], 5)==0){ - uart_commands_getserial(&status); + }else if(strncmp("GETSE", cmd.argv[0], 5)==0){ + uart_commands_getserial(&status); - }else if(strncmp("PROG", cmd.argv[0], 4)==0){ - crc_prog = uart_string_to_int(cmd.argv[3]); - total_size = uart_string_to_int(cmd.argv[2]); - offset = uart_string_to_int(cmd.argv[1]); - SCB->VTOR = offset; - crc_data = uart_commands_prog(&status, total_size); - offset_pointer = offset; + }else if(strncmp("PROG", cmd.argv[0], 4)==0){ + crc_prog = uart_string_to_int(cmd.argv[3]); + total_size = uart_string_to_int(cmd.argv[2]); + offset = uart_string_to_int(cmd.argv[1]); + write_app_info(&crc_prog, (unsigned int *)&total_size); + crc_data = uart_commands_prog(&status, total_size); + offset_pointer = offset; - }else if(strcmp("DATA", cmd.argv[0])==0){ - int size = uart_string_to_int(cmd.argv[1]); - crc_t local_checksum = uart_string_to_int(cmd.argv[2]); - uart_commands_data(&status, size, &crc_data, local_checksum, offset_pointer); - //uart_commands_data(&status, size, &crc_data, crc_data, offset_pointer); - if(status == 0) offset_pointer += size; + }else if(strcmp("DATA", cmd.argv[0])==0){ + int size = uart_string_to_int(cmd.argv[1]); + crc_t local_checksum = uart_string_to_int(cmd.argv[2]); + uart_commands_data(&status, size, &crc_data, local_checksum, offset_pointer); + if(status == 0) offset_pointer += size; + + }else if(strncmp("CHECK", cmd.argv[0], 5)==0){ + error_code is_error = uart_commands_check(crc_prog, crc_data); + if(is_error == ok){ + uart_send_ok(); + }else{ + uart_send_err(); + } - }else if(strncmp("CHECK", cmd.argv[0], 5)==0){ - error_code is_error = uart_commands_check(crc_prog, crc_data); - if(is_error == ok){ - uart_send_ok(); - }else{ - uart_send_err(); } - } - } + } while(1); return 0 ; } diff --git a/iap.c b/iap.c index 1bcf45c..714fde9 100644 --- a/iap.c +++ b/iap.c @@ -14,11 +14,39 @@ #include "iap.h" -uint32_t command[5]; -uint32_t output[5]; +unsigned int command[5]; +unsigned int output[5]; IAP iap_entry =(IAP) IAP_LOCATION; - +int addr_to_sector(int addr){ + int tmp = addr & 0xfffff; + tmp = tmp >> 12; + if(tmp <= 15) return tmp; + else{ + if(tmp >= 0x10 && tmp <=0x17) + return 16; + else if(tmp >= 0x18 && tmp <= 0x1f) + return 17; + else if(tmp >= 0x20 && tmp <= 0x27) + return 18; + else if(tmp >= 0x28 && tmp <= 0x2f) + return 19; + else if(tmp >= 0x30 && tmp <= 0x37) + return 20; + else if(tmp >= 0x38 && tmp <= 0x3f) + return 21; + else if(tmp >= 0x40 && tmp <= 0x47) + return 22; + else if(tmp >= 0x48 && tmp <= 0x4f) + return 23; + else if(tmp >= 0x50 && tmp <= 0x57) return 24; + else if(tmp >= 0x58 && tmp <= 0x3f) return 25; + else if(tmp >= 0x60 && tmp <= 0x67) return 26; + else if(tmp >= 0x68 && tmp <= 0x6f) return 27; + else if(tmp >= 0x70 && tmp <= 0x77) return 28; + else if(tmp >= 0x78 && tmp <= 0x7f) return 29; + } +} void iap_entry_wrapped(void){ __disable_irq(); @@ -66,10 +94,8 @@ uint32_t iap_read_part_id(error_code* status){ } } -void iap_copy_to_flash(error_code* status, int dst_flash, uint32_t* src_ram, int num_bytes){ - //iap_prepare_sectors(status, dst_flash, dst_flash+num_bytes); - //iap_erase_sectors(status, dst_flash, dst_flash+num_bytes); - iap_prepare_sectors(status, dst_flash, dst_flash+num_bytes); +void iap_copy_to_flash(error_code* status, long unsigned int * dst_flash, long unsigned int* src_ram, int num_bytes){ + iap_prepare_sectors(status, addr_to_sector(dst_flash), addr_to_sector(dst_flash+num_bytes)); command[0] = 51; command[1] = dst_flash; command[2] = src_ram; @@ -94,7 +120,7 @@ void iap_read_serial(error_code* status, uint32_t* res){ res[2] = output[3]; res[3] = output[4]; }else{ - *status = -1; + *status = output[0]; } } diff --git a/iap.h b/iap.h index 0441660..5a584c7 100644 --- a/iap.h +++ b/iap.h @@ -26,14 +26,18 @@ typedef enum _error_code { typedef void (*IAP)(unsigned int[], unsigned int[]); - +/*This command must be executed before executing "Copy RAM to Flash" or +"Erase Sector(s)" command. Successful execution of the "Copy RAM to Flash" or +"Erase Sector(s)" command causes relevant sectors to be protected again. To +prepare a single sector use the same "Start" and "End" sector numbers.*/ void iap_prepare_sectors(error_code* status, int start, int end); void iap_erase_sectors(error_code* status, int start, int end); -void iap_copy_to_flash(error_code* status, int dst_flash, uint32_t* src_ram, int num_bytes); +void iap_copy_to_flash(error_code* status, long unsigned int * dst_flash, long unsigned int* src_ram, int num_bytes); uint32_t iap_read_part_id(error_code* status); void iap_read_serial(error_code* status, uint32_t* res); +int addr_to_sector(int addr); diff --git a/uart_commands.c b/uart_commands.c index 2b87628..7144c1d 100644 --- a/uart_commands.c +++ b/uart_commands.c @@ -103,47 +103,19 @@ void digit_to_str(char* str, uint32_t number, int base){ str[tmp_counter] = '\0'; }*/ -int addr_to_sector(int addr){ - int tmp = addr & 0xfffff; - tmp = tmp >> 12; - if(tmp <= 15) return tmp; - else{ - if(tmp >= 0x10 && tmp <=0x17) - return 16; - else if(tmp >= 0x18 && tmp <= 0x1f) - return 17; - else if(tmp >= 0x20 && tmp <= 0x27) - return 18; - else if(tmp >= 0x28 && tmp <= 0x2f) - return 19; - else if(tmp >= 0x30 && tmp <= 0x37) - return 20; - else if(tmp >= 0x38 && tmp <= 0x3f) - return 21; - else if(tmp >= 0x40 && tmp <= 0x47) - return 22; - else if(tmp >= 0x48 && tmp <= 0x4f) - return 23; - else if(tmp >= 0x50 && tmp <= 0x57) return 24; - else if(tmp >= 0x58 && tmp <= 0x3f) return 25; - else if(tmp >= 0x60 && tmp <= 0x67) return 26; - else if(tmp >= 0x68 && tmp <= 0x6f) return 27; - else if(tmp >= 0x70 && tmp <= 0x77) return 28; - else if(tmp >= 0x78 && tmp <= 0x7f) return 29; - } -} void uart_commands_getid(error_code* status){ - char hex[15] = "0x26113f37\r\n"; - //char hex[15]; + //char hex[15] = "0x26113f37\r\n"; + char hex[15]; uint32_t res = iap_read_part_id(status); - //digit_to_str(hex+1, res, 16); + digit_to_str(hex+2, res, 16); hex[0]='0'; hex[1]='x'; //sprintf(hex, "0x%x\r\n", res); if(*status == 0){ uart_send_ok(); uart_send(hex, strlen(hex)); + uart_send("\r\n", 2); } } @@ -166,11 +138,10 @@ void uart_commands_getserial(error_code* status){ } crc_t uart_commands_prog(error_code* status, int size){ - //iap_prepare_sectors(status, APP_OFFSET, APP_OFFSET+size/4095+5); + char digit; int start = addr_to_sector(APP_OFFSET); int end = addr_to_sector(APP_OFFSET+size); iap_prepare_sectors(status, addr_to_sector(APP_OFFSET), addr_to_sector(APP_OFFSET+size)); - char digit; if(*status != ok){ uart_send_err(); itoa(*status, &digit, 10); @@ -201,8 +172,6 @@ error_code uart_commands_data(error_code* status, int size, crc_t* checksum_glob int offset_counter = offset; if(checksum_loc == checksum_tmp){ int tmp = size; - //iap_prepare_sectors(status, APP_OFFSET, APP_OFFSET+size/4095+1); - //iap_erase_sectors(status, APP_OFFSET, APP_OFFSET+size/4095+1); iap_prepare_sectors(status, addr_to_sector(offset), addr_to_sector(offset+size)+1); *checksum_global = crc_update(*checksum_global, data, size); //verify if size == 4095 if smaller diff --git a/uart_commands.h b/uart_commands.h index 0175b48..3df8f1a 100644 --- a/uart_commands.h +++ b/uart_commands.h @@ -35,7 +35,6 @@ void uart_send_ok(); void uart_send_err(); -int addr_to_sector(int addr); void digit_to_str(char* str, uint32_t number, int base);