|
@@ -3,6 +3,9 @@
|
|
#include "systick.h"
|
|
#include "systick.h"
|
|
#include "w25q32.h"
|
|
#include "w25q32.h"
|
|
#include "main.h"
|
|
#include "main.h"
|
|
|
|
+#include "ec800m.h"
|
|
|
|
+#include <stdio.h>
|
|
|
|
+#include "string.h"
|
|
|
|
|
|
#define APPBLOCKNB 2 //下载的程序位于block的第3块中
|
|
#define APPBLOCKNB 2 //下载的程序位于block的第3块中
|
|
#define OTA_EVENT_BLOCKNB 1 //OTA事件完成标志存储的位置位于第2块中
|
|
#define OTA_EVENT_BLOCKNB 1 //OTA事件完成标志存储的位置位于第2块中
|
|
@@ -13,9 +16,123 @@
|
|
#define EOT 0x04 // 结束标志
|
|
#define EOT 0x04 // 结束标志
|
|
int8_t xmodem(uint16_t timeout);
|
|
int8_t xmodem(uint16_t timeout);
|
|
OTA_T ota_data;
|
|
OTA_T ota_data;
|
|
-uint8_t w25q32_data[256]; //存放w25q32数据
|
|
|
|
-
|
|
|
|
uint16_t Xmodem_CRC16(uint8_t *data, uint16_t datalen);
|
|
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()
|
|
* 函数名:uint8_t check_ota_event()
|
|
* 输入参数:无
|
|
* 输入参数:无
|
|
@@ -29,14 +146,16 @@ int8_t check_ota_event()
|
|
// 当标志位为1时证明ota事件产生,将进入ota升级路线
|
|
// 当标志位为1时证明ota事件产生,将进入ota升级路线
|
|
if (ota_data.ota_flag == 1)
|
|
if (ota_data.ota_flag == 1)
|
|
{
|
|
{
|
|
- W25Q32_Erase64K(APPBLOCKNB); //程序文件在第三block以后
|
|
|
|
- int8_t recvSta = xmodem(1000);
|
|
|
|
|
|
+ // W25Q32_Erase64K(APPBLOCKNB); //程序文件在第三block以后
|
|
|
|
+ // EC800MSendCmd(DEL_otaDATA_FILE, strlen(DEL_otaDATA_FILE)); //清空OTA数据文件
|
|
|
|
+ int8_t recvSta = xmodem(1000); //在1000秒内解决OTA更新
|
|
if (recvSta == 0)
|
|
if (recvSta == 0)
|
|
{
|
|
{
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
- else
|
|
|
|
|
|
+ else
|
|
{
|
|
{
|
|
|
|
+ // read_ota_DATA(ota_message.XmodemByte);
|
|
NVIC_SystemReset();
|
|
NVIC_SystemReset();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -44,6 +163,44 @@ int8_t check_ota_event()
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * @brief 专门用来解析往文件里写数据的响应数据
|
|
|
|
+ *
|
|
|
|
+ * @param timeout 超时时间(ms)
|
|
|
|
+ * @return uint8_t 实际写入字节数
|
|
|
|
+ */
|
|
|
|
+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)
|
|
int8_t xmodem(uint16_t timeout)
|
|
{
|
|
{
|
|
int startTime = gettick();
|
|
int startTime = gettick();
|
|
@@ -54,10 +211,19 @@ int8_t xmodem(uint16_t timeout)
|
|
while(1)
|
|
while(1)
|
|
{
|
|
{
|
|
task_fwdgt_reload(); //喂狗
|
|
task_fwdgt_reload(); //喂狗
|
|
- if(gettick()-startTime>timeout*1000)return 0;
|
|
|
|
- usart_data_transmit(COM_232, 'C');
|
|
|
|
|
|
+ if(gettick()-startTime>timeout*1000)return 0; //如果一直得不到上位机的xmode数据相应,超时则跳出本函数
|
|
|
|
+ usart_data_transmit(COM_232, 'C'); //向上位机发送'C',表明请求xmodem数据
|
|
delay_1ms(1000);
|
|
delay_1ms(1000);
|
|
- if(ota_data.done==1)break;
|
|
|
|
|
|
+ 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)
|
|
while (gettick() - startTime < timeout * 1000)
|
|
@@ -65,23 +231,44 @@ int8_t xmodem(uint16_t timeout)
|
|
if (ota_data.done == 1)
|
|
if (ota_data.done == 1)
|
|
{
|
|
{
|
|
task_fwdgt_reload(); //喂狗
|
|
task_fwdgt_reload(); //喂狗
|
|
- if (ota_data.data[0] == SOH && ota_data.data_cnt == 133)
|
|
|
|
|
|
+ if (ota_data.data[0] == SOH && ota_data.data_cnt == 133) //如果xmodem数据包是满的128个字节
|
|
{
|
|
{
|
|
- uint16_t XCRC = Xmodem_CRC16(ota_data.data + 3, 128);
|
|
|
|
|
|
+ uint16_t XCRC = Xmodem_CRC16(ota_data.data + 3, 128);
|
|
if (XCRC == ota_data.data[131] * 256 + ota_data.data[132]) // 经过校验的数据一致时将进行数据处理
|
|
if (XCRC == ota_data.data[131] * 256 + ota_data.data[132]) // 经过校验的数据一致时将进行数据处理
|
|
{
|
|
{
|
|
- data_flag.xmodemNB++;
|
|
|
|
- //因为W25Q32只支持按页写入数据、所以将128字节数据找了一个暂存空间,两次应答才进行一次数据写入,最后在结束语句判断是否为奇数在进行
|
|
|
|
- //数据尾部的处理
|
|
|
|
- if(ota_data.data[1]%2==0)
|
|
|
|
|
|
+ data_flag.xmodemNB++; //xmodem数据包计数
|
|
|
|
+ // W25Q32_PageWrite(w25q32_data,APPBLOCKNB*256+(data_flag.xmodemNB-1)/2);
|
|
|
|
+ uint8_t sed_flg = 0;
|
|
|
|
+ while(sed_flg < 2)
|
|
{
|
|
{
|
|
- memcpy(w25q32_data+128,ota_data.data + 3,128);
|
|
|
|
- W25Q32_PageWrite(w25q32_data,APPBLOCKNB*256+(data_flag.xmodemNB-1)/2);
|
|
|
|
- memset(w25q32_data,0,256);
|
|
|
|
|
|
+ EC800MSendCmd(WRITE_otaDATA_FILE,strlen(WRITE_otaDATA_FILE));
|
|
|
|
+ if(WaitResponse("CONNECT", 2000) == 0)
|
|
|
|
+ {
|
|
|
|
+ sed_flg++;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ sed_flg = 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- else
|
|
|
|
|
|
+ while(sed_flg < 2)
|
|
{
|
|
{
|
|
- memcpy(w25q32_data,ota_data.data + 3,128);
|
|
|
|
|
|
+ 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;
|
|
ota_data.data_cnt = 0;
|
|
@@ -101,22 +288,100 @@ int8_t xmodem(uint16_t timeout)
|
|
//进入结束的包处理
|
|
//进入结束的包处理
|
|
else if (ota_data.data[0] == EOT && ota_data.data_cnt == 1)
|
|
else if (ota_data.data[0] == EOT && ota_data.data_cnt == 1)
|
|
{
|
|
{
|
|
- if(data_flag.xmodemNB%2!=0) //将可能为奇数的数据写入进去
|
|
|
|
|
|
+ // 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)
|
|
{
|
|
{
|
|
- W25Q32_PageWrite(w25q32_data,APPBLOCKNB*256+(data_flag.xmodemNB-1)/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);
|
|
usart_data_transmit(COM_232, ACK);
|
|
//完成xmodem协议的交互将完成的标志存储到内存中
|
|
//完成xmodem协议的交互将完成的标志存储到内存中
|
|
- OTA_MESSAGE ota_message;
|
|
|
|
ota_message.Completion_flag=1U;
|
|
ota_message.Completion_flag=1U;
|
|
ota_message.XmodemByte=data_flag.xmodemNB*128;//后续补齐的0x1A还需要进一步考虑
|
|
ota_message.XmodemByte=data_flag.xmodemNB*128;//后续补齐的0x1A还需要进一步考虑
|
|
|
|
|
|
- W25Q32_Erase64K(OTA_EVENT_BLOCKNB);//擦除原先的数据
|
|
|
|
- W25Q32_PageWrite((uint8_t *)&ota_message,OTA_EVENT_BLOCKNB*256);
|
|
|
|
-
|
|
|
|
|
|
+ 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);
|
|
delay_1ms(50);
|
|
// 写入事件完成标志后重启设备,其他状态页无需回滚,写入完成会执行重启指令
|
|
// 写入事件完成标志后重启设备,其他状态页无需回滚,写入完成会执行重启指令
|
|
return 1;
|
|
return 1;
|