339 lines
7.3 KiB
C
339 lines
7.3 KiB
C
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include "main.h"
|
|
|
|
//设备唯一编码,固定在0x00002800位置
|
|
const uint8_t DevMac[6] __attribute__((section(".ARM.__at_0x00002800"))) = {DEVICE_TYPE & 0xFF, (DEVICE_TYPE >> 8) & 0xFF, COMM_WAY, (ADD_NUMBER >> 16) & 0xFF, (ADD_NUMBER >> 8) & 0xFF, ADD_NUMBER & 0xFF};
|
|
//const uint8_t DevMac[6] __attribute__((at(DEV_MAC_ADDRESS)))= {0x19, 0x00, 0x02, 0x00, 0x00, 0x01};
|
|
uint32_t pdwCrc32Tbl[256];
|
|
|
|
void InitCrc32Table(uint32_t* Crc32Tbl)
|
|
{
|
|
for (int wCnt = 0; wCnt!= 256; wCnt++){
|
|
uint32_t dwCrc = wCnt;
|
|
for (int ucCnt = 0; ucCnt != 8; ucCnt++){
|
|
if (dwCrc & 1){
|
|
dwCrc = (dwCrc >> 1) ^ 0xEDB88320;
|
|
}
|
|
else{
|
|
dwCrc >>= 1;
|
|
}
|
|
}
|
|
Crc32Tbl[wCnt] = dwCrc;
|
|
}
|
|
}
|
|
|
|
uint32_t GetCrc32(int dwLen)
|
|
{
|
|
uint32_t Data;
|
|
uint32_t dwCrc32Data = 0xFFFFFFFF;
|
|
for (int dwCnt = 0; dwCnt!= dwLen; ++dwCnt){
|
|
Data = *((volatile uint8_t*)(APP_ADDRESS + dwCnt));
|
|
uint32_t dwTbl = (dwCrc32Data ^ Data) & 0xFF;
|
|
dwCrc32Data = ((dwCrc32Data >> 8) & 0xFFFFFF) ^ pdwCrc32Tbl[dwTbl];
|
|
}
|
|
return ~dwCrc32Data;
|
|
}
|
|
|
|
uint16_t CRC_Modbus(uint16_t wBase, __IO uint8_t *para, uint16_t length)
|
|
{
|
|
uint16_t crc = 0xffff;
|
|
|
|
uint16_t index,i;
|
|
|
|
for(index = 0 ; index < length;index++) {
|
|
crc ^= para[index];
|
|
for(i = 0; i < 8; i++) {
|
|
if(crc & 1) {
|
|
crc >>= 1;
|
|
crc ^= wBase;
|
|
}
|
|
else
|
|
crc >>= 1;
|
|
}
|
|
}
|
|
return crc;
|
|
}
|
|
|
|
uint32_t JumpAddress;
|
|
func_ptr_t JumpToApplication;
|
|
BootLoader_t BL;
|
|
|
|
static void BootLoader1mSRoutine(void)
|
|
{
|
|
if(BL.BootLoader1mSDlyCnt)
|
|
BL.BootLoader1mSDlyCnt--;
|
|
|
|
if(BL.UartRevTimeOutCnt > 0)
|
|
BL.UartRevTimeOutCnt--;
|
|
|
|
BL.FeedDogDlyCnt++;
|
|
}
|
|
|
|
void FeedDogHandler(void)
|
|
{
|
|
if(BL.FeedDogDlyCnt >= 200) {
|
|
FeedDog();
|
|
BL.FeedDogDlyCnt = 0;
|
|
}
|
|
}
|
|
|
|
void AppWriteFlash(uint32_t AddrOffset, uint8_t *wData, int wLen)
|
|
{
|
|
FlashWrite(APP_ADDRESS + AddrOffset, (uint32_t *)wData, wLen / 4);
|
|
}
|
|
|
|
//static bool JumpToApp(uint32_t AppAddr)
|
|
//{
|
|
// uint32_t u32StackTop = *((__IO uint32_t *)AppAddr);
|
|
|
|
// if ((u32StackTop > SRAM_BASE) && (u32StackTop <= (SRAM_BASE + RAM_SIZE))) {
|
|
// JumpAddress = *(__IO uint32_t *)(AppAddr + 4);
|
|
// JumpToApplication = (func_ptr_t)JumpAddress;
|
|
// __set_MSP(*(__IO uint32_t *)AppAddr);
|
|
// JumpToApplication();
|
|
// }
|
|
// return Error;
|
|
//}
|
|
|
|
|
|
static bool JumpToApp(uint32_t AppAddr)
|
|
{
|
|
uint32_t u32StackTop = *((__IO uint32_t *)AppAddr);
|
|
|
|
if ((u32StackTop > SRAM_BASE) && (u32StackTop <= (SRAM_BASE + SRAM_SIZE))) {
|
|
JumpAddress = *(__IO uint32_t *)(AppAddr + 4);
|
|
JumpToApplication = (func_ptr_t)JumpAddress;
|
|
__set_MSP(*(__IO uint32_t *)AppAddr);
|
|
JumpToApplication();
|
|
}
|
|
return Error;
|
|
}
|
|
|
|
void SendGetCmd(uint8_t Cmd, uint16_t PayLoad)
|
|
{
|
|
uint8_t sData[20], sLen;
|
|
uint16_t crc16;
|
|
|
|
FrameH Frame = (FrameH)sData;
|
|
|
|
Frame->Header = 0x7a;
|
|
Frame->SlvAddr = 0x01;
|
|
Frame->Cmd = Cmd;
|
|
|
|
if(Cmd == 0x01) {
|
|
Frame->PayloadLen = 1;
|
|
sData[sizeof(FrameHeader_t)] = PayLoad;
|
|
}
|
|
else if(Cmd == 0x02) {
|
|
Frame->PayloadLen = 4;
|
|
GDReq GDData = (GDReq)&sData[sizeof(FrameHeader_t)];
|
|
GDData->PackageIndex = PayLoad;
|
|
GDData->PackageNum = BL.AppPackageCnt;
|
|
}
|
|
sLen = sizeof(FrameHeader_t) + Frame->PayloadLen;
|
|
crc16 = CRC_Modbus(CRC16_BASE, sData, sLen);
|
|
sData[sLen++] = crc16;
|
|
sData[sLen++] = (crc16 >> 8) & 0x00ff;
|
|
|
|
DebugUartSend(sData, sLen);
|
|
}
|
|
|
|
bool AnalyzeData(uint8_t *rData, uint16_t rLen)
|
|
{
|
|
uint16_t crc16, check;
|
|
|
|
check = CRC_Modbus(CRC16_BASE, rData, rLen - 2);
|
|
crc16 = (rData[rLen - 1] << 8) | rData[rLen - 2];
|
|
|
|
if(check != crc16) {
|
|
return false;
|
|
}
|
|
|
|
FrameH Frame = (FrameH)rData;
|
|
if(Frame->Cmd == 0x81) {
|
|
UDReq UpData = (UDReq)&rData[sizeof(FrameHeader_t)];
|
|
BL.Para.AppFlag = 0;
|
|
BL.Para.UpdateFlag = APP_UPDATE_FLAG;
|
|
BL.Para.Crc32Check = UpData->AppCrc32;
|
|
BL.Para.PackageCnt = UpData->PackageNum;
|
|
BL.Para.AppSize = UpData->AppSize;
|
|
WriteBootPara(&BL.Para);
|
|
BL.BootLoader1mSDlyCnt = 20;
|
|
BL.Status = BL_RESET;
|
|
SendGetCmd(0x01, 1);
|
|
}
|
|
else if(Frame->Cmd == 0x82) {
|
|
if(BL.UpDateFlag == false)
|
|
return false;
|
|
DownRes DownData = (DownRes)&rData[sizeof(FrameHeader_t)];
|
|
if(BL.AppPackageIdx != DownData->PackageIndex) {
|
|
return false;
|
|
}
|
|
AppWriteFlash(BL.AppPackageIdx * 200, &BL.RxBuff[sizeof(FrameHeader_t) + sizeof(DownResponse_t)], DownData->DataLen);
|
|
BL.AppPackageIdx++;
|
|
BL.RevErrCnt = 0;
|
|
if(BL.AppPackageIdx < BL.AppPackageCnt) {
|
|
BL.Status = BL_GET_DATA;
|
|
BL.BootLoader1mSDlyCnt = 5;
|
|
//BuzzCtrl(10, 0, 1);
|
|
}
|
|
else {
|
|
uint32_t crc32 = GetCrc32(BL.Para.AppSize);
|
|
if(crc32 == BL.Para.Crc32Check) {
|
|
BL.Status = BL_START_APP;
|
|
BL.Para.AppFlag = 0; //升级成功首次启动时,把APP启动标志清除,由APP置位,下次启动便按标志启动
|
|
BL.Para.UpdateFlag = 0;
|
|
BL.Para.DevType = DEV_TYPE;
|
|
WriteBootPara(&BL.Para);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
void BootLoaderLoopHandler(void)
|
|
{
|
|
if(BL.RxFlag) {
|
|
BL.RxFlag = false;
|
|
AnalyzeData(BL.RxBuff, BL.RxLen);
|
|
TURN_OFF_STATE_LED();
|
|
}
|
|
|
|
switch(BL.Status){
|
|
case BL_IDLE:
|
|
break;
|
|
|
|
case BL_RESET:
|
|
if(BL.BootLoader1mSDlyCnt > 0) {
|
|
break;
|
|
}
|
|
NVIC_SystemReset();
|
|
break;
|
|
|
|
case BL_START_APP:
|
|
enIrqResign(DBGUART_IRQn);
|
|
enIrqResign(DBGUART_EI_IRQn);
|
|
JumpToApp(APP_ADDRESS);
|
|
break;
|
|
|
|
case BL_ERASE_FLASH:
|
|
FeedDog();
|
|
EraseFlash();
|
|
FeedDog();
|
|
BL.Status = BL_GET_DATA;
|
|
BL.BootLoader1mSDlyCnt = 200;
|
|
BL.AppPackageCnt = BL.Para.PackageCnt;
|
|
BL.RevErrCnt = 0;
|
|
BL.UpDateFlag = true;
|
|
break;
|
|
|
|
case BL_GET_DATA:
|
|
if(BL.BootLoader1mSDlyCnt > 0)
|
|
break;
|
|
SendGetCmd(0x02, BL.AppPackageIdx);
|
|
BL.Status = BL_WAIT_REV;
|
|
BL.BootLoader1mSDlyCnt = 500;
|
|
break;
|
|
|
|
case BL_WAIT_REV:
|
|
if(BL.BootLoader1mSDlyCnt == 0) {
|
|
BL.Status = BL_GET_DATA_TIMEOUT;
|
|
}
|
|
break;
|
|
|
|
case BL_GET_DATA_TIMEOUT:
|
|
BL.RevErrCnt++;
|
|
if(BL.RevErrCnt < 3) {
|
|
BL.Status = BL_GET_DATA;
|
|
}
|
|
else {
|
|
BL.Status = BL_IDLE;
|
|
BL.Para.AppFlag = 0;
|
|
BL.RevErrCnt = 0;
|
|
BL.Para.UpdateFlag = 0;
|
|
WriteBootPara(&BL.Para);
|
|
BL.UpDateFlag = false;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
int32_t main(void)
|
|
{
|
|
BSP_Init();
|
|
InitCrc32Table(pdwCrc32Tbl);
|
|
|
|
ReadBootPara(&BL.Para);
|
|
if(BL.Para.DevType != DEV_TYPE) { //设备类型错误,清除升级参数
|
|
BL.Status = BL_IDLE;
|
|
BL.Para.AppFlag = 0;
|
|
BL.Para.UpdateFlag = 0;
|
|
BL.Para.DevAddr = 0x01;
|
|
BL.Para.DevType = DEV_TYPE;
|
|
WriteBootPara(&BL.Para);
|
|
}
|
|
else if(BL.Para.AppFlag == APP_START_FLAG) {
|
|
BL.Status = BL_START_APP;
|
|
}
|
|
else if(BL.Para.UpdateFlag == APP_UPDATE_FLAG) {
|
|
BL.Status = BL_ERASE_FLASH;
|
|
}
|
|
while (1) {
|
|
FeedDogHandler();
|
|
BootLoaderLoopHandler();
|
|
}
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
* 中断服务函数
|
|
******************************************************************************/
|
|
void SysTick_IrqHandler(void)
|
|
{
|
|
BootLoader1mSRoutine();
|
|
}
|
|
|
|
static uint16_t rLen;
|
|
static uint8_t rBuff[300];
|
|
static bool Header;
|
|
static uint16_t PayLen;
|
|
|
|
void DbgRxIrqCallback(uint8_t RxData)
|
|
{
|
|
if(BL.UartRevTimeOutCnt == 0) {
|
|
Header = false;
|
|
rLen = 0;
|
|
PayLen = 0;
|
|
}
|
|
BL.UartRevTimeOutCnt = 3;
|
|
|
|
if(Header == false && RxData == 0x7a) {
|
|
Header = true;
|
|
rLen = 0;
|
|
PayLen = 0;
|
|
rBuff[rLen++] = RxData;
|
|
}
|
|
else {
|
|
rBuff[rLen++] = RxData;
|
|
if(rLen == 4) {
|
|
PayLen = rBuff[3];
|
|
if(PayLen > 256) {
|
|
Header = false;
|
|
return;
|
|
}
|
|
}
|
|
else if(rLen == sizeof(FrameHeader_t) + PayLen + 2) {
|
|
BL.RxLen = rLen;
|
|
memcpy(BL.RxBuff, rBuff, BL.RxLen);
|
|
BL.RxFlag = true;
|
|
Header = false;
|
|
TURN_ON_STATE_LED_GREEN();
|
|
}
|
|
}
|
|
}
|
|
|
|
|