#define MAIN_PROGRAM_START_ADDRESS 0x08010000 #define MAIN_PROGRAM_END_ADDRESS 0x08080000
static const uint8_t AES_FW_KEY[] = {0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF}; static const uint8_t AES_IV[] = {0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA};
#define FW_START 5 #define FW_READ 1000 #define FW_WRITE 2000 #define FW_FINISH 10000 #define FW_ERROR 100000
uint32_t t; /* */ uint32_t fw_step; /* */ uint32_t fw_buf[512]; /* */ uint32_t aes_buf[512]; /* */ /* Flash-*/ uint32_t idx; /* */ char tbuf[64]; /* sprintf */ FATFS FS; /* fatFS - */ FIL F; /* fatFS - */ case FW_READ: /* */ { if(f_mount(&FS, "" , 0) == FR_OK) /* SD-*/ { /* , . */ if(f_open(&F, "FIRMWARE.BIN", FA_READ | FA_OPEN_EXISTING) == FR_OK) { f_lseek(&F, 0); /* */ CRC_ResetDR(); /* CRC */ lcd_putstr(" ", 1, 0); /* */ /* */ idx = MAIN_PROGRAM_START_ADDRESS; fw_step = FW_READ + 10; /* */ } else {fw_step = FW_FINISH;} /* - */ } else {fw_step = FW_FINISH;} /* SD- - */ break; }
case FW_READ + 10: /* */ { /* , */ sprintf(tbuf, ": %d", idx - MAIN_PROGRAM_START_ADDRESS); lcd_putstr(tbuf, 2, 1); if (idx > MAIN_PROGRAM_END_ADDRESS) /* */ { f_read(&F, &t, sizeof(t), &idx); /* 4 */ /* 4 CRC */ CRC_CalcCRC(t); if(CRC_GetCRC() == 0) /* 0, */ { /* */ idx = MAIN_PROGRAM_START_ADDRESS; f_lseek(&F, 0); /* */ fw_step = FW_READ + 20; /* */ break; } else { lcd_putstr(" ", 3, 2); /* */ fw_step = FW_ERROR; /* */ break; } } f_read(&F, &fw_buf, sizeof(fw_buf), &t); /* 2 */ if(t != sizeof(fw_buf)) /* */ { lcd_putstr(" ", 3, 2); fw_step = FW_ERROR; /* */ break; } /* */ AES_CBC_decrypt_buffer((uint8_t*)&aes_buf, (uint8_t *)&fw_buf, sizeof(fw_buf), AES_FW_KEY, AES_IV); for(t=0;t<NELEMS(aes_buf);t++) /* CRC */ { CRC_CalcCRC(aes_buf[t]); /* 4 */ } idx+=sizeof(fw_buf); /* 2 */ break; }
case FW_READ + 20: // Flash Firmware { /* , */ sprintf(tbuf, ": %d", idx - MAIN_PROGRAM_START_ADDRESS); lcd_putstr(tbuf, 4, 2); if (idx > MAIN_PROGRAM_END_ADDRESS) /* */ { lcd_putstr("", 7, 3); /* */ f_unlink("FIRMWARE.BIN"); /* SD- */ fw_step = FW_FINISH; /* */ break; } f_read(&F, &fw_buf, sizeof(fw_buf), &t); /* 2 */ if(t != sizeof(fw_buf)) /* */ { lcd_putstr(" ", 3, 3); /* */ fw_step = FW_ERROR; /* */ break; } /* */ AES_CBC_decrypt_buffer((uint8_t*)&aes_buf, (uint8_t *)&fw_buf, sizeof(fw_buf), AES_FW_KEY, AES_IV); FLASH_Unlock(); /* FLash- */ FLASH_ErasePage(idx); /* */ for(t=0;t<sizeof(aes_buf);t+=4) /* 4 */ { FLASH_ProgramWord(idx+t, aes_buf[t/4]); } FLASH_Lock(); /* */ idx+=sizeof(fw_buf); /* */ break; }
case FW_ERROR: { /* - */ break; } case FW_FINISH: { ExecMainFW(); /* */ /* */ break; }
void ExecMainFW() { /* */ /* , */ /* +4 , */ uint32_t jumpAddress = *(__IO uint32_t*) (MAIN_PROGRAM_START_ADDRESS + 4); pFunction Jump_To_Application = (pFunction) jumpAddress; /* APB1 */ RCC->APB1RSTR = 0xFFFFFFFF; RCC->APB1RSTR = 0x0; /* APB2 */ RCC->APB2RSTR = 0xFFFFFFFF; RCC->APB2RSTR = 0x0; RCC->APB1ENR = 0x0; /* APB1 */ RCC->APB2ENR = 0x0; /* APB2 */ RCC->AHBENR = 0x0; /* AHB */ /* , HSI*/ RCC_DeInit(); /* */ __disable_irq(); /* */ NVIC_SetVectorTable(NVIC_VectTab_FLASH, MAIN_PROGRAM_START_ADDRESS); /* */ __set_MSP(*(__IO uint32_t*) MAIN_PROGRAM_START_ADDRESS); /* */ Jump_To_Application(); }
__disable_irq(); NVIC_SetVectorTable(NVIC_VectTab_FLASH, MAIN_PROGRAM_START_ADDRESS); __enable_irq();
case FW_WRITE: { if(f_mount(&FS, "" , 0) == FR_OK) /* SD-*/ { /* */ if(f_open(&F, "FIRMWARE.BIN", FA_WRITE | FA_CREATE_ALWAYS) == FR_OK) { CRC_ResetDR(); /* CRC */ /* */ idx = MAIN_PROGRAM_START_ADDRESS; fw_step = FW_WRITE + 10; /* */ } else {fw_step = FW_ERROR;} /* */ } else {fw_step = FW_ERROR;} /* */ break; } case FW_WRITE + 10: { if (idx > MAIN_PROGRAM_END_ADDRESS) /* */ { t = CRC_GetCRC(); f_write(&F, &t, sizeof(t), &idx); /* */ f_close(&F); /* , */ fw_step = FW_FINISH; /* */ } /* 2 Flash- */ memcpy(&fw_buf, (uint32_t *)idx, sizeof(fw_buf)); for(t=0;t<NELEMS(fw_buf);t++) /* CRC */ { CRC_CalcCRC(fw_buf[t]); } /* */ AES_CBC_encrypt_buffer((uint8_t*)&aes_buf, (uint8_t *)&fw_buf, sizeof(fw_buf), AES_FW_KEY, AES_IV); /* */ f_write(&F, &aes_buf, sizeof(aes_buf), &t); idx+=sizeof(fw_buf); /* */ break; }
Source: https://habr.com/ru/post/432966/
All Articles