494 lines
9.5 KiB
C
494 lines
9.5 KiB
C
|
||
#define _IN_STAPP_C
|
||
#include "stapp.h"
|
||
|
||
#if (APP_SAVE_TO != APP_SAVE_NONE)
|
||
|
||
#include "crc32.h"
|
||
#include "cpuid.h"
|
||
#include "stiap.h"
|
||
|
||
#include "stflash.h"
|
||
|
||
//-------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
|
||
|
||
//-------------------------------------------------------------------------------
|
||
|
||
// 升级程序文件管理
|
||
|
||
//-------------------------------------------------------------------------------
|
||
|
||
typedef struct
|
||
{
|
||
char xorbuf[8];
|
||
u8 xchgbuf[8];
|
||
u32 datalen;
|
||
u32 bincrc;
|
||
u32 rnpucrc;
|
||
u32 hddatcrc;
|
||
u8 rev[1024-8-8-8-8];
|
||
}GNPUHead;
|
||
|
||
GNPUHead g_gnpuHead =
|
||
{
|
||
#if (CUR_UPFL == GAUF_PMB1) // 绘图仪主板
|
||
{
|
||
'G', 'O', 'A', 'P', 'M', 'B', 'O', 'S',
|
||
},
|
||
{
|
||
4, 6, 7, 2, 3, 5, 8, 1,
|
||
},
|
||
#elif (CUR_UPFL == GAUF_EMB1) // 绣花机/布线机主板
|
||
{
|
||
'G', 'O', 'A', 'E', 'M', 'B', 'O', 'S',
|
||
},
|
||
{
|
||
1, 3, 5, 2, 4, 8, 6, 7,
|
||
},
|
||
#elif (CUR_UPFL == GAUF_EHA1) // 平绣机头板
|
||
{
|
||
'G', 'O', 'A', 'E', 'H', 'A', 'O', 'S',
|
||
},
|
||
{
|
||
5, 1, 3, 2, 7, 4, 8, 6,
|
||
},
|
||
#elif (CUR_UPFL == GAUF_EHB1) // 布线机机头板
|
||
{
|
||
'G', 'O', 'A', 'E', 'H', 'B', 'O', 'S',
|
||
},
|
||
{
|
||
1, 5, 2, 4, 3, 7, 6, 8,
|
||
},
|
||
#elif (CUR_UPFL == GAUF_EMCLA1) // 平绣换色板
|
||
{
|
||
'G', 'O', 'A', 'E', 'C', 'L', 'A', '1',
|
||
},
|
||
{
|
||
6, 1, 7, 4, 2, 5, 3, 8,
|
||
},
|
||
#elif (CUR_UPFL == GAUF_EXTIO) // 扩展IO板卡
|
||
#else
|
||
{
|
||
'R', 'P', 'U', 'P', 'D', 'A', 'T', 'E',
|
||
},
|
||
{
|
||
1, 2, 3, 4, 5, 6, 7, 8,
|
||
},
|
||
#endif
|
||
0, 0, 0, 0,
|
||
{
|
||
0,
|
||
},
|
||
};
|
||
|
||
// 解码RNPU数据
|
||
int DecodeData(u8 * pBuf, int len)
|
||
{
|
||
int i, j, k, num1;
|
||
u8 tpbuf[8], opbuf[8];
|
||
u8 temp, mod;
|
||
|
||
if (pBuf == NULL || len == 0)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
for (i = 0; i < len && ((len - i) >= 8); i += 8)
|
||
{
|
||
// 每8个字节一组数据,如果不足8字节的数据,不做处理。
|
||
memcpy(tpbuf, &(pBuf[i]), 8);
|
||
|
||
// 根据交换表交换8个字节的顺序。
|
||
memcpy(opbuf, tpbuf, 8);
|
||
for (j = 0; j < 8; j++)
|
||
{
|
||
tpbuf[g_gnpuHead.xchgbuf[j]-1] = opbuf[j];
|
||
}
|
||
|
||
// 计算数组中数据位1的个数
|
||
num1 = 0;
|
||
for (j = 0; j < 8; j++)
|
||
{
|
||
mod = 0x01;
|
||
for (k = 0; k < 8; k++)
|
||
{
|
||
if ((tpbuf[j] & mod) != 0)
|
||
{
|
||
num1++;
|
||
}
|
||
mod *= 2;
|
||
}
|
||
}
|
||
|
||
// 根据个数的做循环移位操作(奇数右移,偶数左移)。
|
||
if ((num1 & 0x01) != 0) // 奇数
|
||
{
|
||
// 循环右移
|
||
for (j = 0; j < num1; j++)
|
||
{
|
||
mod = tpbuf[7];
|
||
for (k = 0; k < 8; k++)
|
||
{
|
||
temp = tpbuf[k];
|
||
tpbuf[k] >>= 1; // 右移
|
||
if ((mod & 0x01) != 0)
|
||
{
|
||
tpbuf[k] |= 0x80;
|
||
}
|
||
mod = temp;
|
||
}
|
||
}
|
||
}
|
||
else // 偶数
|
||
{
|
||
// 循环左移
|
||
for (j = 0; j < num1; j++)
|
||
{
|
||
mod = tpbuf[0];
|
||
for (k = 7; k >= 0; k--)
|
||
{
|
||
temp = tpbuf[k];
|
||
tpbuf[k] <<= 1; // 左移
|
||
if ((mod & 0x80) != 0)
|
||
{
|
||
tpbuf[k] |= 0x01;
|
||
}
|
||
mod = temp;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 数组数据和加密字符串做异或运算
|
||
for (j = 0; j < 8; j++)
|
||
{
|
||
tpbuf[j] ^= g_gnpuHead.xorbuf[j];
|
||
}
|
||
|
||
// 得到最终的解密数组
|
||
memcpy(&(pBuf[i]), tpbuf, 8);
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
//-------------------------------------------------------------------------------
|
||
|
||
typedef struct
|
||
{
|
||
int enFlag;
|
||
int saveOffset;
|
||
int isrnpufile;
|
||
u32 bincrc;
|
||
u32 rnpucrc;
|
||
int rsvCounter;
|
||
|
||
}SaveAppCtrl;
|
||
|
||
SaveAppCtrl g_saveAppCtrl;
|
||
|
||
void InitSaveApp(void)
|
||
{
|
||
g_gnpuHead.datalen = 0;
|
||
g_gnpuHead.bincrc = 0;
|
||
g_gnpuHead.rnpucrc = 0;
|
||
g_gnpuHead.hddatcrc = 0;
|
||
|
||
g_saveAppCtrl.saveOffset = 0;
|
||
g_saveAppCtrl.isrnpufile = 0;
|
||
|
||
g_saveAppCtrl.bincrc = CRC32_INIT;
|
||
g_saveAppCtrl.rnpucrc = CRC32_INIT;
|
||
g_saveAppCtrl.rsvCounter = 0;
|
||
|
||
IAPCleanUpdateArea(); // 清空NORflash文件区域
|
||
}
|
||
|
||
// 保存一段数据到app区域
|
||
int SaveAppData(int idx, u8 * pBuf, int len, u32 ofst)
|
||
{
|
||
u32 addr, wtlen;
|
||
int i, thislen;
|
||
//printf("SaveAppData idx=%d, len=%d, ofst=0x%x\r\n", idx, len, ofst);
|
||
|
||
if (idx < 0 ||
|
||
pBuf == NULL ||
|
||
(len != SUPPORT_LEN_1 && len != SUPPORT_LEN_2) ||
|
||
0 )
|
||
{
|
||
printf("SaveAppData para err\r\n");
|
||
return -1;
|
||
}
|
||
|
||
// 文件头
|
||
if (ofst == 0 && idx == 0 && g_saveAppCtrl.saveOffset < sizeof(g_gnpuHead))
|
||
{
|
||
if (ofst == 0 && idx == 0)
|
||
{
|
||
printf("process file head\r\n");
|
||
|
||
if (memcmp(pBuf, g_gnpuHead.xorbuf, 8) == 0 &&
|
||
memcmp(&(pBuf[8]), g_gnpuHead.xchgbuf, 8) == 0 &&
|
||
1 )
|
||
{
|
||
u32 hdcrc, hddatsize;
|
||
g_saveAppCtrl.isrnpufile = 1;
|
||
// 填充校验
|
||
g_saveAppCtrl.bincrc = CRC32_INIT;
|
||
g_saveAppCtrl.rnpucrc = CRC32_INIT;
|
||
|
||
g_gnpuHead.datalen = *((u32*)&(pBuf[16]));
|
||
g_gnpuHead.bincrc = *((u32*)&(pBuf[20]));
|
||
g_gnpuHead.rnpucrc = *((u32*)&(pBuf[24]));
|
||
g_gnpuHead.hddatcrc = *((u32*)&(pBuf[28]));
|
||
|
||
hddatsize = sizeof(g_gnpuHead) - sizeof(g_gnpuHead.rev) - 4;
|
||
hdcrc = CalcCrc32((u8*)(&g_gnpuHead), hddatsize);
|
||
|
||
if (hdcrc == g_gnpuHead.hddatcrc)
|
||
{
|
||
g_saveAppCtrl.rsvCounter = g_gnpuHead.datalen;
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
printf("file head crc error\r\n");
|
||
return -2;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("bin file not support\r\n"); // 作为bin文件升级,不安全
|
||
return -1;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("file not correct\r\n");
|
||
return 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
}
|
||
|
||
#if (APP_SAVE_TO == APP_SAVE_NORFLASH)
|
||
addr = NOR_APP_ADDR;
|
||
#elif (APP_SAVE_TO == APP_SAVE_EXRAM)
|
||
addr = EXRAM_APP_ADDR;
|
||
#elif (APP_SAVE_TO == APP_SAVE_INFLASH)
|
||
addr = APP_ADDR_BEG;
|
||
#else
|
||
addr = 0;
|
||
#endif
|
||
|
||
addr += ofst;
|
||
addr += ((idx-1)*len); // 写入地址务必使用idx*len; 否则在丢包,或者处理补发数据包时地址会产生偏差
|
||
wtlen = len;
|
||
|
||
g_saveAppCtrl.saveOffset += len;
|
||
|
||
if (g_saveAppCtrl.isrnpufile != 0)
|
||
{
|
||
if (g_saveAppCtrl.rsvCounter > len)
|
||
{
|
||
thislen = len;
|
||
g_saveAppCtrl.rsvCounter -= len;
|
||
}
|
||
else
|
||
{
|
||
thislen = g_saveAppCtrl.rsvCounter;
|
||
g_saveAppCtrl.rsvCounter = 0;
|
||
}
|
||
for (i = 0; i < thislen; i++)
|
||
{
|
||
g_saveAppCtrl.rnpucrc = AddCrc32(g_saveAppCtrl.rnpucrc, pBuf[i]);
|
||
}
|
||
|
||
DecodeData(pBuf, thislen); // 解码
|
||
|
||
for (i = 0; i < thislen; i++)
|
||
{
|
||
g_saveAppCtrl.bincrc = AddCrc32(g_saveAppCtrl.bincrc, pBuf[i]);
|
||
}
|
||
|
||
for (i = thislen; i < len; i++)
|
||
{
|
||
pBuf[i] = 0xff;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
thislen = len;
|
||
}
|
||
|
||
#if (APP_SAVE_TO == APP_SAVE_NORFLASH)
|
||
printf("save to norflash, addr=0x%lx, wtlen=%d\r\n", addr, wtlen);
|
||
DatFlashWrData(addr, pBuf, wtlen);
|
||
#elif (APP_SAVE_TO == APP_SAVE_EXRAM)
|
||
printf("save to exram, addr=0x%lx, wtlen=%d\r\n", addr, wtlen);
|
||
memcpy((void*)addr, (void*)pBuf, wtlen);
|
||
#elif (APP_SAVE_TO == APP_SAVE_INFLASH)
|
||
printf("save to in flash addr=0x%lx, wtlen=%d\r\n", addr, wtlen);
|
||
STMFlashWrite(addr, (u16*)pBuf, wtlen/2, 1);
|
||
#else
|
||
printf("not support addr=0x%lx, wtlen=%d\r\n", addr, wtlen);
|
||
#endif
|
||
return thislen;
|
||
}
|
||
|
||
// 判断接收是否完成
|
||
// 返回接收到的数据量
|
||
int IsAppReceiveDone(void)
|
||
{
|
||
return (int)g_gnpuHead.datalen - (int)g_saveAppCtrl.rsvCounter;
|
||
}
|
||
|
||
u32 GetAppSaveDataCrc(u32 addr, u32 size)
|
||
{
|
||
#define RD_DAT_BUF_LEN (1024) // 字节数
|
||
|
||
// 从flash读出数据再次验证
|
||
u32 crc;
|
||
|
||
#if (APP_SAVE_TO == APP_SAVE_EXRAM)
|
||
u8 rdata[RD_DAT_BUF_LEN];
|
||
#else
|
||
u8 volatile rdata[RD_DAT_BUF_LEN];
|
||
#endif
|
||
|
||
int i, thislen, rsvlen;
|
||
rsvlen = size;
|
||
crc = CRC32_INIT;
|
||
|
||
while(addr < APP_ADDR_BEG+size)
|
||
{
|
||
if (rsvlen > RD_DAT_BUF_LEN)
|
||
{
|
||
thislen = RD_DAT_BUF_LEN;
|
||
rsvlen -= RD_DAT_BUF_LEN;
|
||
}
|
||
else
|
||
{
|
||
thislen = rsvlen;
|
||
rsvlen = 0;
|
||
}
|
||
#if (APP_SAVE_TO == APP_SAVE_NORFLASH)
|
||
DatFlashRdData(addr, rdata, RD_DAT_BUF_LEN); // 读取一个扇区
|
||
#elif (APP_SAVE_TO == APP_SAVE_EXRAM)
|
||
memcpy(rdata, (void*)addr, RD_DAT_BUF_LEN);
|
||
#elif (APP_SAVE_TO == APP_SAVE_INFLASH)
|
||
STMFlashRead(addr, (u16*)rdata, RD_DAT_BUF_LEN/2);
|
||
#else
|
||
#endif
|
||
|
||
for (i = 0; i < thislen; i++)
|
||
{
|
||
crc = AddCrc32(crc, rdata[i]);
|
||
}
|
||
|
||
addr += RD_DAT_BUF_LEN; // 地址增加
|
||
}
|
||
return crc;
|
||
}
|
||
|
||
|
||
int IsSaveDataCorrect(void)
|
||
{
|
||
u32 crc, hddatsize;
|
||
int rslt;
|
||
|
||
if (g_saveAppCtrl.isrnpufile == 0)
|
||
{
|
||
printf("g_isrnpufile == 0\r\n");
|
||
return 0;
|
||
}
|
||
|
||
hddatsize = sizeof(g_gnpuHead) - sizeof(g_gnpuHead.rev) - 4; //
|
||
crc = CalcCrc32((u8*)(&g_gnpuHead), hddatsize);
|
||
|
||
rslt = -1;
|
||
|
||
printf("check g_gnpuHead crc = 0x%lx \r\n",crc);
|
||
printf("g_gnpuHead.hddatcrc = 0x%lx \r\n",g_gnpuHead.hddatcrc);
|
||
printf("g_gnpuHead.bincrc = 0x%lx \r\n",g_gnpuHead.bincrc);
|
||
printf("g_saveAppCtrl.bincrc = 0x%lx \r\n",g_saveAppCtrl.bincrc);
|
||
printf("g_gnpuHead.rnpucrc = 0x%lx \r\n",g_gnpuHead.rnpucrc);
|
||
printf("g_saveAppCtrl.rnpucrc = 0x%lx \r\n",g_saveAppCtrl.rnpucrc);
|
||
printf("g_gnpuHead.datalen = 0x%lx \r\n",g_gnpuHead.datalen);
|
||
printf("g_saveAppCtrl.rsvCounter = 0x%lx \r\n",g_saveAppCtrl.rsvCounter);
|
||
|
||
if (g_gnpuHead.hddatcrc == crc &&
|
||
g_gnpuHead.bincrc == g_saveAppCtrl.bincrc &&
|
||
g_gnpuHead.rnpucrc == g_saveAppCtrl.rnpucrc &&
|
||
1 )
|
||
{
|
||
crc = GetAppSaveDataCrc(APP_ADDR_BEG, g_gnpuHead.datalen);
|
||
|
||
printf("calc crc = 0x%x, g_gnpuHead.bincrc = 0x%x\r\n", crc, g_gnpuHead.bincrc);
|
||
|
||
if (g_gnpuHead.bincrc == crc)
|
||
{
|
||
rslt = 0;
|
||
}
|
||
else
|
||
{
|
||
printf("re calc file data crc error\r\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("receive file crc error\r\n");
|
||
}
|
||
|
||
return rslt;
|
||
}
|
||
|
||
|
||
// 启动APP升级任务
|
||
void StartAppUpdate(int reboot)
|
||
{
|
||
if (IsSaveDataCorrect() == 0)
|
||
{
|
||
u32 rdstart, wrstart, len, wtlen, check;
|
||
|
||
rdstart = (APP_ADDR_BEG - APP_SAVE_BASE);
|
||
wrstart = (STM32_APP_ADDR - STM32_FLASH_BASE); // 文件起始地址
|
||
len = g_gnpuHead.datalen;
|
||
wtlen = (g_gnpuHead.datalen + STM32_FLASH_RW_SIZE - 1) / STM32_FLASH_RW_SIZE;
|
||
wtlen *= STM32_FLASH_RW_SIZE;
|
||
check = g_gnpuHead.bincrc;
|
||
|
||
printf("StartAppUpdate rdstart = 0x%x, wrstart = 0x%x, len = %d, wtlen = %d, wcrc=0x%x\r\n", rdstart, wrstart, len, wtlen, check);
|
||
|
||
IapWritePara(rdstart, wrstart, len, wtlen, check);
|
||
|
||
#if (1) // 改为不再区分,都需要重启升级
|
||
RestartMcu(); // 重启MCU
|
||
#else
|
||
if (reboot != 0)
|
||
{
|
||
RestartMcu(); // 重启MCU
|
||
}
|
||
else
|
||
{
|
||
UpdateApp(); // 升级主控文件
|
||
JumpToApp(); // 进入APP
|
||
}
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
printf("IsSaveDataCorrect failed\r\n");
|
||
}
|
||
}
|
||
|
||
|
||
#endif
|
||
|
||
|
||
|