optical/NxFuncs/stiap/stapp.c
2025-09-04 09:45:08 +08:00

494 lines
9.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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