123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422 |
- #include "otaEvent.h"
- #include "usart.h"
- #include "systick.h"
- #include "w25q32.h"
- #include "main.h"
- #include "ec800m.h"
- #include <stdio.h>
- #include "string.h"
- #define APPBLOCKNB 2 //下载的程序位于block的第3块中
- #define OTA_EVENT_BLOCKNB 1 //OTA事件完成标志存储的位置位于第2块中
- #define SOH 0x01 // XMOD协议帧头
- #define ACK 0X06 // 应答标志
- #define NAK 0x15 // 非应答标志
- #define EOT 0x04 // 结束标志
- int8_t xmodem(uint16_t timeout);
- OTA_T ota_data;
- uint16_t Xmodem_CRC16(uint8_t *data, uint16_t datalen);
- static OTA_MESSAGE ota_message;
- #if 0
- //测试用的
- int WaitForReadData(uint8_t* data,int timeout,int datalen)
- {
- uint32_t len = 0;
- bool timeoutFlag = false;
- if (timeout >= 0)
- {
- timeoutFlag = true;
- }
- while (1)
- {
- delay_1ms(50);
- if (UART0_RX_STAT > 0)
- {
- UART0_RX_STAT = 0;
- char *p = strstr((char *)&UART0_RX_BUF, "CONNECT ");
- if (p)
- {
- p += 8;
- sscanf(p, "%u\r", &len); // 读取长度
- if(len == datalen)
- {
- p = strchr(p, '\n') + 1; // 跳过换行
- memcpy(data,p,datalen);
- Clear_DMA_Buffer();
- return datalen;
- }
- else
- {
- Clear_DMA_Buffer();
- return len;
- }
- }
-
- }
- timeout -= 50;
- if (timeoutFlag == true && timeout <= 0)
- {
- Clear_DMA_Buffer();
- return -1;
- }
- }
- }
- static uint8_t app_programmer[1024];
- void read_ota_DATA(uint32_t app_byte)
- {
- /* 打开UFS:otaDATA.txt */
- EC800MSendCmd(CLOSE_otaDATA_FILE,strlen(CLOSE_otaDATA_FILE));
- WaitResponse("QFCLOSE",1000);
- EC800MSendCmd(OPEN_otaDATA_FILE,strlen(OPEN_otaDATA_FILE));
- if(WaitResponse("QFOPEN:", 2000) == 0)
- return;
- for(uint8_t i=0;i<app_byte/1024;i++) //一次读1KB
- {
- task_fwdgt_reload();
- memset(app_programmer,0,1024);
- // uint32_t addr=APP_PROGRAMMER_BLOCK*64*1024+i*1024; //其在w25q32中的地址
- // W25Q32_Read(app_programmer,addr,1024);
- while(1)
- {
- int x = 0;
- EC800MSendCmd(READ_otaDATA_FILE,strlen(READ_otaDATA_FILE));
- x = WaitForReadData(app_programmer,2000,1024);
- if((x != 1024) && (x != -1))
- {
- char* SEEK_otaDATA_FILE = "";
- sprintf(SEEK_otaDATA_FILE,"AT+QFSEEK=1,%d,2\r\n",x);
- EC800MSendCmd(SEEK_otaDATA_FILE,strlen(SEEK_otaDATA_FILE)); //出错的话文件指针向左偏移1024个字节
- }
- else if(x == 1024)
- {
- break;
- }
- }
- delay_1ms(50);
- }
- //将不满1024数据单独写入
- if(app_byte % 1024 != 0)
- {
- uint32_t startAddress=(app_byte/1024)*1024;
- memset(app_programmer,0,1024);
- // uint32_t addr=APP_PROGRAMMER_BLOCK*64*1024+(app_byte/1024)*1024; //其在w25q32中的地址
- // W25Q32_Read(app_programmer,addr,app_byte%1024);
- while(1)
- {
- int x = 0;
- EC800MSendCmd(READ_otaDATA_FILE,strlen(READ_otaDATA_FILE));
- x = WaitForReadData(app_programmer,2000,app_byte % 1024);
- if(x != (app_byte % 1024) && (x != -1))
- {
- char* SEEK_otaDATA_FILE = "";
- sprintf(SEEK_otaDATA_FILE,"AT+QFSEEK=1,%d,2\r\n",x);
- EC800MSendCmd(SEEK_otaDATA_FILE,strlen(SEEK_otaDATA_FILE)); //出错的话文件指针向左偏移读取字节数
- }
- else if(x == (app_byte % 1024))
- {
- break;
- }
- }
- delay_1ms(50);
- }
- // 关闭保存UFS文件
- while(1)
- {
- EC800MSendCmd(CLOSE_otaDATA_FILE,strlen(CLOSE_otaDATA_FILE));
- if(WaitResponse("OK", 2000) == 1)
- {
- break;
- }
- }
- }
- #endif
- /*
- * 函数名:uint8_t check_ota_event()
- * 输入参数:无
- * 输出参数:无
- * 返回值:无
- * 函数作用:判断ota事件是否产生是否要进入更新部分
- */
- int8_t check_ota_event()
- {
- //关闭看门狗
- // 当标志位为1时证明ota事件产生,将进入ota升级路线
- if (ota_data.ota_flag == 1)
- {
- // W25Q32_Erase64K(APPBLOCKNB); //程序文件在第三block以后
- // EC800MSendCmd(DEL_otaDATA_FILE, strlen(DEL_otaDATA_FILE)); //清空OTA数据文件
- int8_t recvSta = xmodem(1000); //在1000秒内解决OTA更新
- if (recvSta == 0)
- {
- return 0;
- }
- else
- {
- // read_ota_DATA(ota_message.XmodemByte);
- NVIC_SystemReset();
- }
- }
- else
- return 0;
- }
- uint8_t WaitResponse_value(int timeout)
- {
- bool timeoutFlag = false;
- if (timeout >= 0)
- {
- timeoutFlag = true;
- }
- while (1)
- {
- delay_1ms(50);
- if (UART0_RX_STAT > 0)
- {
- UART0_RX_STAT = 0;
- char *p = strstr((char *)&UART0_RX_BUF, ": ") + 2;
- if (p)
- {
- uint8_t ret = 0;
- ret = strtol(p, &p, 10);
- Clear_DMA_Buffer();
- return ret;
- }
- }
- timeout -= 50;
- if (timeoutFlag == true && timeout <= 0)
- {
- Clear_DMA_Buffer();
- return 0;
- }
- };
- }
- int8_t xmodem(uint16_t timeout)
- {
- int startTime = gettick();
- ota_data.done=0;
- OTA_flag data_flag;
- data_flag.flag=0;
- data_flag.xmodemNB=0;
- while(1)
- {
- task_fwdgt_reload(); //喂狗
- if(gettick()-startTime>timeout*1000)return 0; //如果一直得不到上位机的xmode数据相应,超时则跳出本函数
- usart_data_transmit(COM_232, 'C'); //向上位机发送'C',表明请求xmodem数据
- delay_1ms(1000);
- if(ota_data.done==1)
- {
- //打开otaData.txt文件
- EC800MSendCmd(CLOSE_otaDATA_FILE,strlen(CLOSE_otaDATA_FILE));
- WaitResponse("QFCLOSE",1000);
- EC800MSendCmd(OPEN_otaDATA_FILE,strlen(OPEN_otaDATA_FILE));
- if(WaitResponse("QFOPEN:", 2000) == 0)
- return 0;
- break; //如果上位机响应请求则跳出循环等待
- }
- }
- // 判断数据帧头是否符合标准
- while (gettick() - startTime < timeout * 1000)
- {
- if (ota_data.done == 1)
- {
- task_fwdgt_reload(); //喂狗
- if (ota_data.data[0] == SOH && ota_data.data_cnt == 133) //如果xmodem数据包是满的128个字节
- {
- uint16_t XCRC = Xmodem_CRC16(ota_data.data + 3, 128);
- if (XCRC == ota_data.data[131] * 256 + ota_data.data[132]) // 经过校验的数据一致时将进行数据处理
- {
- data_flag.xmodemNB++; //xmodem数据包计数
- // W25Q32_PageWrite(w25q32_data,APPBLOCKNB*256+(data_flag.xmodemNB-1)/2);
- uint8_t sed_flg = 0;
- while(sed_flg < 2)
- {
- EC800MSendCmd(WRITE_otaDATA_FILE,strlen(WRITE_otaDATA_FILE));
- if(WaitResponse("CONNECT", 2000) == 0)
- {
- sed_flg++;
- }
- else
- {
- sed_flg = 0;
- break;
- }
- }
- while(sed_flg < 2)
- {
- EC800MSendCmd(ota_data.data + 3,128);
- // EC800MSendCmd(TEST_DATA,128);
- int x = WaitResponse_value(2000);
- if(x != 128)
- {
- sed_flg++;
- char* QFSEEK_CMD;
- sprintf(QFSEEK_CMD,"AT+QFSEEK=1,%d,2\r\n",x);
- EC800MSendCmd(QFSEEK_CMD,strlen(QFSEEK_CMD)); //出错的话文件指针向左偏移x个字节
- }
- else
- {
- sed_flg = 0;
- break;
- }
- }
-
- ota_data.data_cnt = 0;
- memset(ota_data.data, 0, 133);
- ota_data.done = 0;
- usart_data_transmit(COM_232, ACK);
-
- }
- else
- {
- ota_data.data_cnt = 0;
- memset(ota_data.data, 0, 133);
- ota_data.done = 0;
- usart_data_transmit(COM_232, NAK);
- }
- }
- //进入结束的包处理
- else if (ota_data.data[0] == EOT && ota_data.data_cnt == 1)
- {
- // if(data_flag.xmodemNB%2!=0) //将可能为奇数的数据写入进去
- // {
- // W25Q32_PageWrite(w25q32_data,APPBLOCKNB*256+(data_flag.xmodemNB-1)/2);
- // }
- // 保存UFS文件
- uint8_t sed_flg = 0;
- while(sed_flg < 2)
- {
- EC800MSendCmd(CLOSE_otaDATA_FILE,strlen(CLOSE_otaDATA_FILE));
- if(WaitResponse("OK", 2000) == 0)
- {
- sed_flg++;
- }
- else
- {
- sed_flg = 0;
- break;
- }
- }
- usart_data_transmit(COM_232, ACK);
- //完成xmodem协议的交互将完成的标志存储到内存中
- ota_message.Completion_flag=1U;
- ota_message.XmodemByte=data_flag.xmodemNB*128;//后续补齐的0x1A还需要进一步考虑
- while(sed_flg < 2)
- {
- EC800MSendCmd(CLOSE_otaDATA_FILE,strlen(CLOSE_otaDATA_FILE));
- WaitResponse("QFCLOSE",1000);
- EC800MSendCmd(OPEN_otaMSG_FILE,strlen(OPEN_otaMSG_FILE));
- if(WaitResponse("QFOPEN:", 2000) == 0)
- {
- sed_flg++;
- }
- else
- {
- sed_flg = 0;
- break;
- }
- }
-
- while(sed_flg < 2)
- {
- EC800MSendCmd(WRITE_otaMSG_FILE,strlen(WRITE_otaMSG_FILE));
- if(WaitResponse("CONNECT", 2000) == 0)
- {
- sed_flg++;
- }
- else
- {
- sed_flg = 0;
- break;
- }
- }
- while(sed_flg < 2)
- {
- EC800MSendCmd((uint8_t *)&ota_message,sizeof(OTA_MESSAGE));
- // delay_1ms(3000);
- int x = WaitResponse_value(2000);
- if(x != sizeof(OTA_MESSAGE))
- {
- sed_flg++;
- char* QFSEEK_CMD;
- sprintf(QFSEEK_CMD,"AT+QFSEEK=1,%d,2",x);
- EC800MSendCmd(QFSEEK_CMD,strlen(QFSEEK_CMD)); //出错的话文件指针向左偏移x个字节
- }
- else
- {
- sed_flg = 0;
- break;
- }
- }
- while(sed_flg < 2)
- {
- EC800MSendCmd(CLOSE_otaMSG_FILE,strlen(CLOSE_otaMSG_FILE));
- if(WaitResponse("OK", 2000))
- {
- sed_flg++;
- }
- else
- {
- sed_flg = 0;
- break;
- }
- }
- // W25Q32_Erase64K(OTA_EVENT_BLOCKNB);//擦除原先的数据
- // W25Q32_PageWrite((uint8_t *)&ota_message,OTA_EVENT_BLOCKNB*256);
- ota_data.data_cnt = 0;
- memset(ota_data.data, 0, 133);
- ota_data.done = 0;
- delay_1ms(50);
- // 写入事件完成标志后重启设备,其他状态页无需回滚,写入完成会执行重启指令
- return 1;
- }
- else
- {
- ota_data.data_cnt = 0;
- memset(ota_data.data, 0, 133);
- ota_data.done = 0;
- usart_data_transmit(COM_232, NAK);
- }
- }
- delay_1ms(1);
- }
- return 0;
- }
- /*-------------------------------------------------*/
- /*函数名:Xmodem_CRC16校验 */
- /*参 数:data:数据指针 datalen:数据长度 */
- /*返回值:校验后的数据 */
- /*-------------------------------------------------*/
- uint16_t Xmodem_CRC16(uint8_t *data, uint16_t datalen)
- {
- uint8_t i; // 用于for循环
- uint16_t Crcinit = 0x0000; // Xmdoem CRC校验的初始值,必须是0x0000
- uint16_t Crcipoly = 0x1021; // Xmdoem CRC校验的多项式,必须是0x1021
- while (datalen--)
- { // 根据datalen大小,有多少字节循环多少次
- Crcinit = (*data << 8) ^ Crcinit; // 先将带校验的字节,挪到高8位
- for (i = 0; i < 8; i++)
- { // 每个字节8个二进制位,循环8次
- if (Crcinit & 0x8000) // 判断BIT15是1还是0,是1的话,进入if
- Crcinit = (Crcinit << 1) ^ Crcipoly; // 是1的话,先左移,再异或多项式
- else // 判断BIT15是1还是0,是0的话,进入else
- Crcinit = (Crcinit << 1); // 是0的话,只左移
- }
- data++; // 下移,计算一个字节数据
- }
- return Crcinit; // 返回校验后的数据
- }
|