258 lines
7.8 KiB
C
258 lines
7.8 KiB
C
#include "main.h"
|
||
|
||
IAP_Stuct IAPStuct;
|
||
|
||
//[INFO] 串口2本次接收229字节报文数据(*4G模组*):
|
||
//[INFO]
|
||
//+MSUB: "/iot/data/down/a284c67982b089f9",175 byte,{"id":"1471561db17870ef","header":"iot.ota.upgrade.post","body":{"crc16":"1f8c","ver":1,"url":"http://iot.futureny.cn/ota/pull/f46bf3544fe6ca73.bin","md5":"f46bf3544fe6ca73"}}
|
||
|
||
//[INFO] 收到OTA升级指令
|
||
//[INFO] 版本号后的数据为:1,"url":"http://iot.futureny.cn/ota/pull/f46bf3544fe6ca73.bin","md5":"f46bf3544fe6ca73"}}
|
||
|
||
//[INFO] 新的版本号是1
|
||
//[INFO] id后的数据为:1471561db17870ef","header":"iot.ota.upgrade.post","body":{"crc16":"1f8c","ver":1,"url":"http://iot.futureny.cn/ota/pull/f46bf3544fe6ca73.bin","md5":"f46bf3544fe6ca73"}}
|
||
|
||
//[INFO] ErrFlag= 0
|
||
|
||
//[INFO] 更新代码测试
|
||
|
||
|
||
|
||
|
||
|
||
uint8_t checkId(uint8_t *data){
|
||
uint8_t i;
|
||
char *TempPointer; // 临时指针
|
||
uint8_t ErrFlag = 0;
|
||
uint16_t Version = 0;
|
||
uint8_t Err = 0;
|
||
uint8_t verRepeti = 0;
|
||
|
||
TempPointer = strstr((char *)data, "\"ver\":");
|
||
TempPointer += 6;
|
||
log_info("版本号后的数据为:%s", TempPointer);
|
||
i = 0;
|
||
while ((TempPointer[i] >= '0') && (TempPointer[i] <= '9')){
|
||
Version = (Version * 10) + (TempPointer[i] - '0');
|
||
i++;
|
||
}
|
||
if (TempPointer[i] != ','){
|
||
log_info("版本号解析错误");
|
||
Err = 1;
|
||
}
|
||
if (Version == MqttInfoStr.iapVer){
|
||
log_info("版本号重复");
|
||
Err = 1;
|
||
verRepeti = 1;
|
||
}else{ // 无误则存储版本号
|
||
MqttInfoStr.iapVer = Version;
|
||
log_info("新的版本号是%d", MqttInfoStr.iapVer);
|
||
eepromWriteData(0, &MqttInfoStr, MQTT_STRUCT_LEN);//将变化的数据写入eeprom
|
||
}
|
||
TempPointer = strstr((char *)data, "\"id\":\"");
|
||
TempPointer += 6; // 找到id的第一个位置
|
||
log_info("id后的数据为:%s", TempPointer);
|
||
if(verRepeti == 1){
|
||
log_info("****ERR 版本号重复,发送成功指令 ERR****");
|
||
CAT1_printf("AT+MPUB=\"/iot/data/up/%s\",0,0,\"{\\22header\\22:\\22iot.ota.progress.post\\22,\\22body\\22:{\\22id\\22:\\22%.16s\\22,\\22progress\\22:10}}\"\r\n",MqttInfoStr.ClientID,TempPointer);
|
||
return Err; // 版本号重复或降级退出程序
|
||
}
|
||
for(i = 0; i < 16; i++){
|
||
if (((TempPointer[i] >= '0') && (TempPointer[i] <= '9')) || ((TempPointer[i] >= 'a') && (TempPointer[i] <= 'z'))){ // 检查是否是字符
|
||
if (MqttInfoStr.iapid[i] == TempPointer[i]){
|
||
ErrFlag++;
|
||
}
|
||
}
|
||
else{ // 不是字符,直接退出
|
||
ErrFlag = 16;
|
||
log_info("id[%d]不是字符,id=%d", i, TempPointer[i]);
|
||
break;
|
||
}
|
||
}
|
||
if (ErrFlag >= 16){ // 如果所有字都相同,直接退出,认为重复发送了升级数据
|
||
Err = 1;
|
||
}
|
||
ErrFlag = 0;
|
||
if (Err == 0){ // 无误,准备存储id
|
||
for (i = 0; i < 16; i++){ // 存储id值
|
||
MqttInfoStr.iapid[i] = TempPointer[i];
|
||
eepromWriteData(0, &MqttInfoStr, MQTT_STRUCT_LEN);//将变化的数据写入eeprom
|
||
}
|
||
}
|
||
return Err;
|
||
}
|
||
|
||
|
||
#if 0
|
||
void otaUpData(void){
|
||
uint8_t i;
|
||
char NetMessage[512]; // 定义网络数据
|
||
if (GetUpgradePara() == 1)
|
||
{
|
||
i = 0;
|
||
while ((Connce2TCP()) && (i < 200))
|
||
{
|
||
i++;
|
||
}
|
||
if (i < 200)
|
||
{
|
||
if (GetUpgradeFile() == 0)
|
||
{
|
||
Ping_flag = 0; // 要清除Ping_flag标志
|
||
Connect_flag = 0;
|
||
ConnectPack_flag = 0;
|
||
SubcribePack_flag = 0;
|
||
printf("代码升级失败 准备重连\r\n");
|
||
|
||
memset(NetMessage, 0, 512 * sizeof(char)); // 清零消息
|
||
sprintf(NetMessage, "AT+MSUB=\"/iot/data/up/%s\",0,0,0,\"{\\\"header\\\":\\\"iot.ota.result.post\\\",\\\"body\\\":{\\\"id\\\":\\\"%.16s\\\",\\\"success\\\":false}}\"\r\n", DEVICEID, IapFlashStuct.iapid); // 构建回复数据
|
||
TxDataBuf_Deal((u8 *)NetMessage, (strlen(NetMessage))); // 添加数据,发布给服务器
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("连接TCP 81端口超时,程序更新失败,准备等待看门狗复位\r\n");
|
||
for (; i > 0; i--)
|
||
{
|
||
printf("%d", i);
|
||
delay_ms(1000);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Ping_flag = 0; // 要清除Ping_flag标志
|
||
Connect_flag = 0;
|
||
ConnectPack_flag = 0;
|
||
SubcribePack_flag = 0;
|
||
printf("解析指令失败(可能不是Bin文件) 准备重连\r\n");
|
||
memset(NetMessage, 0, 512 * sizeof(char)); // 清零消息
|
||
|
||
sprintf(NetMessage, "AT+MSUB=\"/iot/data/up/%s\",0,0,0,\"{\\\"header\\\":\\\"iot.ota.result.post\\\",\\\"body\\\":{\\\"id\\\":\\\"%.16s\\\",\\\"success\\\":false}}\"\r\n", DEVICEID, IapFlashStuct.iapid); // 构建回复数据
|
||
TxDataBuf_Deal((u8 *)NetMessage, (strlen(NetMessage))); // 添加数据,发布给服务器
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//获取升级文件
|
||
u8 GetUpgradeFile()
|
||
{
|
||
char TempStr[80];
|
||
uint8_t count = 0;
|
||
u16 i=0;
|
||
u8 UpdataOkFlag = 0;
|
||
|
||
log_info("准备获取更新数据\r\n"); //串口提示数据
|
||
while((count<30)&&(UpdataOkFlag == 0))
|
||
{
|
||
count ++;
|
||
IapStuct.GetBinFlag = 1;//获取Bin文件标志位置1,提示串口接收中断放大其接收数组
|
||
IOT_RxCounter = 0;
|
||
|
||
sprintf(TempStr,"GET /ota/pull/%.20s HTTP/1.1\r\nHost: %s:81\r\n\r\n",IapStuct.iapUrl,ServerIP);
|
||
IOT_printf("%s",TempStr);
|
||
|
||
|
||
|
||
printf("发送的网络指令是:%s\r\n",TempStr);
|
||
if(!WaitDownLoad(90000000))
|
||
{
|
||
IapStuct.bit2K_Pointer = 2048 - DMA_GetCurrDataCounter(DMA1_Channel6);
|
||
if(IapStuct.bit2K_Pointer != 0)
|
||
{
|
||
Crc = GetCRC(BIN_RX_BUF[IapStuct.bit2K_Select],IapStuct.bit2K_Pointer,Crc);//校验最后一部分CRC
|
||
|
||
for(i=0;i<IapStuct.bit2K_Pointer;i++)
|
||
{
|
||
printf("%.2X ",BIN_RX_BUF[IapStuct.bit2K_Select][i]);
|
||
}
|
||
printf("\r\n");
|
||
iap_write_appbin(IapStuct.BinWriteAdd,(u8 *)BIN_RX_BUF[IapStuct.bit2K_Select],IapStuct.bit2K_Pointer);//写入剩下的代码
|
||
}
|
||
if( IapStuct.binLength <= (Bin2KCount*2048+IapStuct.bit2K_Pointer))
|
||
{//判断是否接收到足够的数据
|
||
Usart2_RxCounter = 0;
|
||
if(Crc == IapStuct.iapCrc)//CRC校验通过
|
||
{
|
||
if(((*(vu32*)(FLASH_APP2_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
|
||
{
|
||
IapFlashStuct.iapCount++;//iap计数值++
|
||
IapFlashStuct.iapFlag = 1;//iap升级成功标志位置1
|
||
STMFLASH_Write(IAP_FLASH_ADDR,(u16*)&IapFlashStuct,((((sizeof(struct IAP_FLASH_Stuct))%2) == 0) ? ((sizeof(struct IAP_FLASH_Stuct))/2) : (((sizeof(struct IAP_FLASH_Stuct))/2)+1)));//写入Flash
|
||
UpdataOkFlag = 1;//标记更新成功
|
||
TIM_Cmd(TIM4,ENABLE);//打开定时器4,开始计算ping包时间
|
||
printf("固件更新完成!\r\n");
|
||
//printf("请实现跳转到BootLoader,再由BootLoader跳转到第二段程序\r\n");
|
||
printf("开始跳转到BootLoader程序!!\r\n");
|
||
if(((*(vu32*)(FLASH_BASE_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
|
||
{
|
||
printf("等待看门狗复位系统!!\r\n");
|
||
for(i=0;i<100;i++)//延时100*800ms 等待看门狗复位
|
||
{
|
||
delay_ms(800);
|
||
printf("%d ",i);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("非FLASH应用程序,无法执行!\r\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("固件校验失败\r\n");
|
||
Usart2_RxCounter = 0;
|
||
IapStuct.HttpHeadcount = 0;
|
||
IapStuct.bit2K_Pointer = 0;
|
||
IapStuct.bit2K_Select = 0;
|
||
IapStuct.HttpFlag = 0;
|
||
Bin2KCount = 0;
|
||
Crc = 0xFFFF;
|
||
IapStuct.BinWriteAdd = FLASH_APP2_ADDR;
|
||
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//使能接收中断
|
||
memset(BIN_RX_BUF,0,2048*3);
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
printf("CRC校验未通过,服务器上传的CRC是%x,由%d字节的数据计算出的CRC值是%x\r\n",IapStuct.iapCrc,(Bin2KCount*2048+IapStuct.bit2K_Pointer),Crc);
|
||
Usart2_RxCounter = 0;
|
||
IapStuct.HttpHeadcount = 0;
|
||
IapStuct.bit2K_Pointer = 0;
|
||
IapStuct.bit2K_Select = 0;
|
||
IapStuct.HttpFlag = 0;
|
||
Bin2KCount = 0;
|
||
Crc = 0xFFFF;
|
||
IapStuct.BinWriteAdd = FLASH_APP2_ADDR;
|
||
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//使能接收中断
|
||
memset(BIN_RX_BUF,0,2048*3);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("未接收到完整的程序数据,程序长度应该为%dbytes,实际收到数据长度为%dytes\r\n",IapStuct.binLength,(Bin2KCount*2048+IapStuct.bit2K_Pointer));
|
||
Usart2_RxCounter = 0;
|
||
IapStuct.HttpHeadcount = 0;
|
||
IapStuct.bit2K_Pointer = 0;
|
||
IapStuct.bit2K_Select = 0;
|
||
IapStuct.HttpFlag = 0;
|
||
Bin2KCount = 0;
|
||
Crc = 0xFFFF;
|
||
IapStuct.BinWriteAdd = FLASH_APP2_ADDR;
|
||
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//使能接收中断
|
||
memset(BIN_RX_BUF,0,2048*3);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("等待网络数据包时间过短\r\n");
|
||
}
|
||
}
|
||
return UpdataOkFlag;
|
||
}
|
||
|
||
#endif
|
||
|