123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- #include "myBootloader.h"
- #include "flash.h"
- #include "stdio.h"
- #include "sys.h"
- #include "eventUnit.h"
- #include "myUart.h"
- #include "stm32f10x_it.h"
- #define POST_EVENT_TIMEOUT_QUIT_BOOTLOAD 7
- #define BOOT_TIMEOUT_10MS 300
- UPDATE_STATUS_te update_status = UPDATE_PRE;
- CMD_CTR_STEP cmd_ctr_flag=CMD_CTR_IDLE;
- CMD_DATA_STRUCT cmd_data_struct;
- CMD_DATA_STEP cmd_data_flag=CMD_DATA_IDLE;
- static uint8_t cmd_addr_cnt=0;
- static uint32_t cmd_data_cnt=0;
- static uint32_t timeOutCount=0;
- static uint32_t firm_len;
- static uint8_t spliteLen;
- const uint8_t ACK_OK[] = {0xCC, 0xDD};
- const uint8_t ACK_ERROR[] = {0xEE, 0xFF};
- const uint8_t IAP_START1[] = {0x5A, 0xA5};
- const uint8_t IAP_START2[] = {0x5A, 0x01};
- const uint8_t IAP_DATA_DONE[] = {0x5A, 0x02};
- static uint8_t setDataSrc=0;
- iapfun jump2app;
- extern void recoveryQuitBootloadEvent(void);
- // extern void clearQuitBootloadEvent(void);
- // extern void bootloadOverGotoApp(void);
- //跳转到应用程序段
- //appxaddr:用户代码起始地址.
- #if defined (__CC_ARM)
- #pragma O0 //IAP_Load_APP不进行优化
- #elif defined (__ICCARM__)
- #pragma optimize=s none
- #endif
- void myFlash_setBootloadFlag(void)
- {
- uint16_t flag = IAP_UPGRADE_FLAG;
- FLASH_Write(IAP_UPGRADE_FLAG_ADDR, (uint16_t *)flag, 2);
- }
- void myFlash_clearBootloadFlag(void)
- {
- uint16_t flag = 0;
- FLASH_Write(IAP_UPGRADE_FLAG_ADDR, (uint16_t *)flag, 2);
- }
- bool myFlash_checkFlag(void)
- {
- return ((*(vu32*)IAP_UPGRADE_FLAG_ADDR) == IAP_UPGRADE_FLAG ? true : false);
- }
- void IAP_Load_APP(uint32_t appxaddr)
- {
- if( ((*(vu32*)appxaddr)-0x20000000) < (SRAM_SIZE*1024) ) //检查栈顶地址是否合法.
- {
- jump2app=(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址)
- MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
- jump2app(); //跳转到APP.
- }
- }
- void bootDelay(uint32_t time_ms)
- {
- uint32_t i, j;
- i = time_ms;
- while (i --)
- {
- for ( j = 0; j < 20000; j++)
- {
- ;
- }
- }
- }
- void Back_Ok( )
- {
- bootDelay(10);
- myUart1_sendArray((uint8_t *)ACK_OK, 2);
- }
- void Back_Err( )
- {
- bootDelay(10);
- myUart1_sendArray((uint8_t *)ACK_ERROR, 2);
- cmd_data_flag=CMD_DATA_IDLE;
- cmd_ctr_flag=CMD_CTR_IDLE;
- update_status=UPDATE_PRE;
- cmd_addr_cnt=0;
- cmd_data_cnt=0;
- // TIME_IRA_CNT=0;
- // GetDaraFromUSART_Flag=0;
- // myPrintf2("Back_Err\r\n");
- }
- void Back_FirmErr( )
- {
- bootDelay(10);
- myUart1_sendArray((uint8_t *)ACK_ERROR, 2);
- cmd_data_flag=CMD_DATA_IDLE;
- cmd_addr_cnt=0;
- cmd_data_cnt=0;
- // myPrintf2("Back_FirmErr\r\n");
- }
- // #define myPrintf2(args...) //do{{printf("\r\ndecodeBootLoadData-\r\n");printf(args);}}while(0)
- uint8_t decodeBootLoadData(uint8_t *src, uint16_t len)
- {
- static uint8_t ret = CMD_PRO_IDLE;
- switch (update_status)
- {
- case UPDATE_PRE:
- {
- switch (cmd_ctr_flag)
- {
- case CMD_CTR_IDLE:
- {
- if (len == 2 && (memcmp(src, IAP_START1, 2) == 0))
- {
- //1、准备开始固件升级
- cmd_ctr_flag = CMD_CTR_INIT;
- // myPrintf2("begin bootload\r\n");
- Back_Ok();
- timeOutCount = BOOT_TIMEOUT_10MS;
- ret = CMD_PRO_START;
- }
- }break;
- case CMD_CTR_INIT:
- {
- if (len == 7 && (memcmp(src, IAP_START2, 2) == 0))
- {
- //2、开始固件升级
- cmd_ctr_flag = CMD_CTR_IDLE;
- update_status = UPDATE_ING;
- spliteLen = src[2];
- firm_len = (src[3]<<24)+(src[4]<<16)+(src[5]<<8)+src[6];
- Back_Ok();
- timeOutCount = BOOT_TIMEOUT_10MS;
- // myPrintf2("start bootload\r\n");
- ret = CMD_PRO_GET_INIT;
- }
- }break;
- default:
- break;
- }
- }break;
- case UPDATE_ING:
- {
- switch(cmd_data_flag)
- {
- case CMD_DATA_IDLE:
- {
- if(src[0]==0x31)
- {
- //3、接收IAP写入地址
- cmd_data_flag = CMD_DATA_ADDR;
- // myPrintf2("begin receive addr\r\n");
- Back_Ok();
- timeOutCount = BOOT_TIMEOUT_10MS;
- }
- if (len == 2 && (memcmp(src, IAP_DATA_DONE, 2) == 0))
- {
- break;
- }
- }
- case CMD_DATA_ADDR:
- {
- uint32_t addr;
- //4、成功接收IAP写入地址,准备接收固件数据
- memcpy(cmd_data_struct.cmd_addr, src+1, 4);
- cmd_data_flag = CMD_DATA_BUF;
- addr = (cmd_data_struct.cmd_addr[0]<<24)+(cmd_data_struct.cmd_addr[1]<<16)+(cmd_data_struct.cmd_addr[2]<<8)+cmd_data_struct.cmd_addr[3];
- len = len - 5;
- ret = CMD_PRO_GET_OFFSET_ADDR;
- }
- break;
- case CMD_DATA_BUF:
- {
- ret = CMD_PRO_RECV_ING;
- //5、接收固件数据,满2k字节写入一次IAP
- timeOutCount = BOOT_TIMEOUT_10MS;
- memcpy(cmd_data_struct.cmd_buf+cmd_data_cnt, src, len);
- cmd_data_cnt += len;
- if(cmd_data_cnt == 2048)
- {
- //6、满2k字节后先校验数据
- cmd_data_flag=CMD_DATA_CHACK;
- cmd_data_cnt=0;
- Back_Ok();
- }
- else
- {
- //接收固件数据包时必须整包接收
- //否则认为是错误包,
- if (len == spliteLen)
- {
- Back_Ok();
- }
- else
- {
- Back_FirmErr();
- }
- }
- }
- break;
- case CMD_DATA_CHACK:
- {
- uint8_t Val,checksum;
- u16 i;
- timeOutCount = BOOT_TIMEOUT_10MS;
- //7、检验数据
- checksum=0x31;
- for(i=0;i<4;i++)
- {
- checksum+=cmd_data_struct.cmd_addr[i];
- }
- for(i=0;i<2048;i++)
- {
- checksum+=cmd_data_struct.cmd_buf[i];
- }
- if(checksum==src[0])
- {
- //8、IAP写入固件
- uint32_t write_addr=0;
- write_addr = (cmd_data_struct.cmd_addr[0]<<24)+(cmd_data_struct.cmd_addr[1]<<16)+(cmd_data_struct.cmd_addr[2]<<8)+cmd_data_struct.cmd_addr[3];
- if((write_addr>=APP_START_ADDR)&&(write_addr<FLASH_BASE+1024*FLASH_SIZE))
- {
- ret = CMD_PRO_WRITE_2KBYTE;
- FLASH_Write_2KB(write_addr, cmd_data_struct.cmd_buf);
- cmd_data_flag = CMD_DATA_IDLE;
- cmd_data_cnt = 0;
- Back_Ok();
- myFlash_setBootloadFlag();
- }
- else
- {
- cmd_data_flag = CMD_DATA_IDLE;
- Back_FirmErr();
- }
- }
- else
- {
- cmd_data_flag = CMD_DATA_IDLE;
- cmd_data_cnt = 0;
- Back_FirmErr();
- ret = CMD_PRO_CRC_ERROR;
- }
-
- }break;
- default:
- break;
- }
- if (len == 2 && (memcmp(src, IAP_DATA_DONE, 2) == 0))
- {
- //9、固件接收完毕
- timeOutCount = 0;
- // cmd_ctr_flag = CMD_CTR_DONE;
- cmd_ctr_flag = CMD_CTR_IDLE;
- update_status = UPDATE_ING;
- Back_Ok();
- bootDelay(50);
- if(((*(vu32*)(APP_START_ADDR+4))&0xFF000000)==0x08000000) //判断是否为0x08XXXXXX.
- {
- ret = CMD_PRO_BOOT_DONE;
- myFlash_clearBootloadFlag();
- printf("goto app\r\n\r\n");
- bootDelay(50);
- RCC->APB1RSTR = 0xFFFFFFFF;
- RCC->APB2RSTR = 0xFFFFFFFF;
- RCC->APB1RSTR = 0x00000000;
- RCC->APB2RSTR = 0x00000000;
- IAP_Load_APP(APP_START_ADDR);//执行FLASH APP代码
- }
- else
- {
- ret = CMD_PRO_ADDR_ERROR;
- Back_Err();
- }
- }
- }break;
- case UPDATE_DONE:
- {
- }break;
- default:
- break;
- }
- return ret;
- }
- static irqCallback_ts myIrqCallback_tim1;
- /**
- * @brief tim1中断函数
- * 通过API@TIM1_callbackRegiste注册到@stm32f10x_it.c中的真正的中断函数
- *
- * @param status
- * @param param
- */
- static void tim1_callback(uint8_t status, uint32_t param) //TIM1中断
- {
- static uint8_t timeCnt_1ms = 0;
- if(timeCnt_1ms ++ == 50)
- {
- timeCnt_1ms = 0;
- if(timeOutCount)
- {
- timeOutCount --;
- if (timeOutCount == 0)
- {
- Back_Err();
- }
- }
- }
- }
- void bootloader_init(void)
- {
- myIrqCallback_tim1.thisCb = tim1_callback;
- TIM1_callbackRegiste(&myIrqCallback_tim1);
- }
|