BootLoader重构: 适配HC32F460KETA并按传感器通用串口升级协议V1.1改造
主要修改事项: 1. 器件更换: HC32F460PETB改为HC32F460KETA, 更新MDK工程(uvprojx/uvoptx/RTE), 调试器切换为Segger J-Link 2. 新增自定义分散加载文件MDK/BootLoader_custom.sct 3. 新增传感器通用串口升级协议V1.1.xlsx(协议文档) 4. 时钟系统: 取消外部晶振, 改用内部HRC 16MHz -> MPLL 200MHz 5. 删除未使用模块: FatFS/SDCard/SHT20/SX127x(Lora)/AD7924/spiflash/ADS1231/Encryption及LoraTask/CatOneTask/RS485Task/DebugCmd/AppTask, 清理工程IncludePath 6. bsp: BootPara_t参数结构体与GateWay APP对齐(新增GwMac/SvrAddr/SvrPort/LoraFreq/通道配置), 新增RS485 Ch1(USART2)升级通道及RS485 Ch2(USART3)配置, GPIO仅保留RS485方向控制(PC7/PB13) 7. main: 设备MAC固定地址由0x2800改为0x4000并按宏构造(VerInfo/PrjNum/GwNum), 帧头由0x7a改为0x7D并带DevMac字段, 增加MAC匹配(支持0xFF广播), 升级命令更新(0x01 ACK/0x02请求数据/0x81请求/0x82下发), CRC32校验后写参数并复位 8. 跳转APP前关闭全局中断/停SysTick/禁用NVIC中断, 避免残留中断干扰APP 9. Flash擦除仅擦APP区(不擦参数区), 首次运行检测及旧参数区默认值补齐 10. 修复驱动头文件乱码注释(hc32f460_dcu.h/hc32f460_icg.h)
This commit is contained in:
+308
-167
@@ -1,21 +1,36 @@
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.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];
|
||||
/*设备唯一编码 - 固定在Flash 0x4000位置(协议规定: Mac[0]=VerInfo, Mac[1:3]=PrjNum, Mac[4:5]=GwNum)
|
||||
参照hc32l170_boot方式用宏构造6字节MAC, 网关APP从该地址读取本机MAC编码*/
|
||||
const uint8_t GwMacConst[6] __attribute__((section(".ARM.__at_0x00004000"))) = {
|
||||
(0x80 | GATEWAY_VER_INFO), // Mac[0] = VerInfo: Bit7固定1, Bit6:0版本
|
||||
(GATEWAY_PRJ_NUM >> 16) & 0xFF, // Mac[1]
|
||||
(GATEWAY_PRJ_NUM >> 8) & 0xFF, // Mac[2]
|
||||
GATEWAY_PRJ_NUM & 0xFF, // Mac[3]
|
||||
(GATEWAY_GW_NUM >> 8) & 0xFF, // Mac[4]
|
||||
GATEWAY_GW_NUM & 0xFF // Mac[5]
|
||||
};
|
||||
/*运行用MAC, 首次从0x4000读入, 之后从参数区同步*/
|
||||
static uint8_t s_DevMac[6] = {0};
|
||||
|
||||
uint32_t pdwCrc32Tbl[256];
|
||||
BootLoader_t BL;
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: InitCrc32Table
|
||||
* 功能描述: CRC32查表初始化
|
||||
*****************************************************************************************/
|
||||
void InitCrc32Table(uint32_t* Crc32Tbl)
|
||||
{
|
||||
for (int wCnt = 0; wCnt!= 256; wCnt++){
|
||||
for(int wCnt = 0; wCnt < 256; wCnt++) {
|
||||
uint32_t dwCrc = wCnt;
|
||||
for (int ucCnt = 0; ucCnt != 8; ucCnt++){
|
||||
if (dwCrc & 1){
|
||||
for(int ucCnt = 0; ucCnt < 8; ucCnt++) {
|
||||
if(dwCrc & 1) {
|
||||
dwCrc = (dwCrc >> 1) ^ 0xEDB88320;
|
||||
}
|
||||
else{
|
||||
else {
|
||||
dwCrc >>= 1;
|
||||
}
|
||||
}
|
||||
@@ -23,11 +38,15 @@ void InitCrc32Table(uint32_t* Crc32Tbl)
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: GetCrc32
|
||||
* 功能描述: 计算APP区CRC32校验值
|
||||
*****************************************************************************************/
|
||||
uint32_t GetCrc32(int dwLen)
|
||||
{
|
||||
uint32_t Data;
|
||||
uint32_t dwCrc32Data = 0xFFFFFFFF;
|
||||
for (int dwCnt = 0; dwCnt!= dwLen; ++dwCnt){
|
||||
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];
|
||||
@@ -35,97 +54,89 @@ uint32_t GetCrc32(int dwLen)
|
||||
return ~dwCrc32Data;
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: CRC_Modbus
|
||||
* 功能描述: Modbus CRC16校验
|
||||
*****************************************************************************************/
|
||||
uint16_t CRC_Modbus(uint16_t wBase, __IO uint8_t *para, uint16_t length)
|
||||
{
|
||||
uint16_t crc = 0xffff;
|
||||
uint16_t crc = 0xFFFF;
|
||||
uint16_t index, i;
|
||||
|
||||
uint16_t index,i;
|
||||
|
||||
for(index = 0 ; index < length;index++) {
|
||||
for(index = 0; index < length; index++) {
|
||||
crc ^= para[index];
|
||||
for(i = 0; i < 8; i++) {
|
||||
if(crc & 1) {
|
||||
crc >>= 1;
|
||||
crc ^= wBase;
|
||||
}
|
||||
else
|
||||
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;
|
||||
//}
|
||||
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: JumpToApp
|
||||
* 功能描述: 跳转APP
|
||||
*****************************************************************************************/
|
||||
static bool JumpToApp(uint32_t AppAddr)
|
||||
{
|
||||
uint32_t u32StackTop = *((__IO uint32_t *)AppAddr);
|
||||
uint32_t u32StackTop = *((__IO uint32_t *)AppAddr);
|
||||
uint32_t JumpAddress;
|
||||
func_ptr_t JumpToApplication;
|
||||
|
||||
if ((u32StackTop > SRAM_BASE) && (u32StackTop <= (SRAM_BASE + SRAM_SIZE))) {
|
||||
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);
|
||||
|
||||
/*关闭全局中断, 停SysTick, 禁用Boot用过的NVIC中断, 避免跳转后残留中断干扰APP启动*/
|
||||
__disable_irq();
|
||||
SysTick->CTRL = 0;
|
||||
SysTick->LOAD = 0;
|
||||
SysTick->VAL = 0;
|
||||
NVIC_DisableIRQ(RS485CH1_UART_IRQn);
|
||||
NVIC_DisableIRQ(RS485CH1_UART_EI_IRQn);
|
||||
NVIC_ClearPendingIRQ(RS485CH1_UART_IRQn);
|
||||
NVIC_ClearPendingIRQ(RS485CH1_UART_EI_IRQn);
|
||||
__set_MSP(*((__IO uint32_t *)AppAddr));
|
||||
JumpToApplication();
|
||||
return true;
|
||||
}
|
||||
return Error;
|
||||
return false;
|
||||
}
|
||||
|
||||
void SendGetCmd(uint8_t Cmd, uint16_t PayLoad)
|
||||
/*****************************************************************************************
|
||||
* 函数名称: AppWriteFlash
|
||||
* 功能描述: 写APP数据到Flash (每包200字节)
|
||||
*****************************************************************************************/
|
||||
void AppWriteFlash(uint32_t AddrOffset, uint8_t *wData, int wLen)
|
||||
{
|
||||
uint8_t sData[20], sLen;
|
||||
FlashWrite(APP_ADDRESS + AddrOffset, (uint32_t *)wData, wLen / 4);
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: SendResponseCmd
|
||||
* 功能描述: 发送响应帧 (0x7D + DevMac)
|
||||
*****************************************************************************************/
|
||||
static void SendResponseCmd(uint8_t Cmd, uint16_t PayLoad)
|
||||
{
|
||||
uint8_t sData[24];
|
||||
uint16_t sLen;
|
||||
uint16_t crc16;
|
||||
|
||||
FrameH Frame = (FrameH)sData;
|
||||
|
||||
Frame->Header = 0x7a;
|
||||
Frame->SlvAddr = 0x01;
|
||||
|
||||
Frame->Header = 0x7D;
|
||||
memcpy(Frame->DevMac, s_DevMac, 6);
|
||||
Frame->Cmd = Cmd;
|
||||
|
||||
if(Cmd == 0x01) {
|
||||
|
||||
if(Cmd == UPDATE_CMD_SLAVE_RES) {
|
||||
Frame->PayloadLen = 1;
|
||||
sData[sizeof(FrameHeader_t)] = PayLoad;
|
||||
sData[sizeof(FrameHeader_t)] = (uint8_t)PayLoad;
|
||||
}
|
||||
else if(Cmd == 0x02) {
|
||||
else if(Cmd == UPDATE_CMD_SLAVE_REQ_DATA) {
|
||||
Frame->PayloadLen = 4;
|
||||
GDReq GDData = (GDReq)&sData[sizeof(FrameHeader_t)];
|
||||
GDData->PackageIndex = PayLoad;
|
||||
@@ -133,25 +144,49 @@ void SendGetCmd(uint8_t Cmd, uint16_t PayLoad)
|
||||
}
|
||||
sLen = sizeof(FrameHeader_t) + Frame->PayloadLen;
|
||||
crc16 = CRC_Modbus(CRC16_BASE, sData, sLen);
|
||||
sData[sLen++] = crc16;
|
||||
sData[sLen++] = (crc16 >> 8) & 0x00ff;
|
||||
|
||||
DebugUartSend(sData, sLen);
|
||||
sData[sLen++] = crc16 & 0xFF;
|
||||
sData[sLen++] = (crc16 >> 8) & 0xFF;
|
||||
|
||||
RS485Ch1UartSend(sData, sLen);
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: AnalyzeData
|
||||
* 功能描述: 解析接收帧 (0x81升级请求 / 0x82数据包)
|
||||
*****************************************************************************************/
|
||||
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) {
|
||||
|
||||
/*校验MAC地址是否匹配(支持广播全0xFF)*/
|
||||
int ret = memcmp(Frame->DevMac, s_DevMac, 6);
|
||||
if(ret != 0) {
|
||||
bool isBroadcast = true;
|
||||
for(int i = 0; i < 6; i++) {
|
||||
if(Frame->DevMac[i] != 0xFF) {
|
||||
isBroadcast = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!isBroadcast) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*命令处理*/
|
||||
if(Frame->Cmd == UPDATE_CMD_MASTER_REQ) {
|
||||
if(BL.Status != BL_IDLE) {
|
||||
return false;
|
||||
}
|
||||
UDReq UpData = (UDReq)&rData[sizeof(FrameHeader_t)];
|
||||
BL.Para.AppFlag = 0;
|
||||
BL.Para.UpdateFlag = APP_UPDATE_FLAG;
|
||||
@@ -159,66 +194,169 @@ bool AnalyzeData(uint8_t *rData, uint16_t rLen)
|
||||
BL.Para.PackageCnt = UpData->PackageNum;
|
||||
BL.Para.AppSize = UpData->AppSize;
|
||||
WriteBootPara(&BL.Para);
|
||||
/*回0x01 ACK应答, 确认收到升级请求, 载荷=0x20*/
|
||||
SendResponseCmd(UPDATE_CMD_SLAVE_RES, 0x20);
|
||||
BL.BootLoader1mSDlyCnt = 20;
|
||||
BL.Status = BL_RESET;
|
||||
SendGetCmd(0x01, 1);
|
||||
return true;
|
||||
}
|
||||
else if(Frame->Cmd == 0x82) {
|
||||
if(BL.UpDateFlag == false)
|
||||
else if(Frame->Cmd == UPDATE_CMD_MASTRE_RES_DATA) {
|
||||
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);
|
||||
/*写数据到Flash*/
|
||||
AppWriteFlash(BL.AppPackageIdx * 200, &rData[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 {
|
||||
/*全部数据处理完成, 校验CRC32*/
|
||||
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.AppFlag = APP_START_FLAG;
|
||||
BL.Para.UpdateFlag = 0;
|
||||
BL.Para.DevType = DEV_TYPE;
|
||||
WriteBootPara(&BL.Para);
|
||||
BL.BootLoader1mSDlyCnt = 100;
|
||||
BL.Status = BL_RESET;
|
||||
}
|
||||
else {
|
||||
BL.Para.AppFlag = 0;
|
||||
BL.Para.UpdateFlag = 0;
|
||||
WriteBootPara(&BL.Para);
|
||||
BL.UpDateFlag = false;
|
||||
BL.Status = BL_IDLE;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: BootLoader1mSRoutine
|
||||
* 功能描述: BootLoader 1ms定时(由SysTick中断调用)
|
||||
*****************************************************************************************/
|
||||
static void BootLoader1mSRoutine(void)
|
||||
{
|
||||
if(BL.BootLoader1mSDlyCnt) {
|
||||
BL.BootLoader1mSDlyCnt--;
|
||||
}
|
||||
|
||||
if(BL.UartRevTimeOutCnt > 0) {
|
||||
BL.UartRevTimeOutCnt--;
|
||||
}
|
||||
|
||||
BL.FeedDogDlyCnt++;
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: SysTick_IrqHandler
|
||||
* 功能描述: SysTick中断
|
||||
*****************************************************************************************/
|
||||
void SysTick_IrqHandler(void)
|
||||
{
|
||||
BootLoader1mSRoutine();
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: FeedDogHandler
|
||||
* 功能描述: 看门狗喂狗
|
||||
*****************************************************************************************/
|
||||
void FeedDogHandler(void)
|
||||
{
|
||||
if(BL.FeedDogDlyCnt >= 200) {
|
||||
FeedDog();
|
||||
BL.FeedDogDlyCnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: RS485Ch1RxIrqCallback
|
||||
* 功能描述: RS485通道1接收中断回调(每字节), 组帧(0x7D)
|
||||
*****************************************************************************************/
|
||||
static uint16_t rLen;
|
||||
static uint8_t rBuff[300];
|
||||
static bool Header;
|
||||
static uint16_t PayLen;
|
||||
|
||||
void RS485Ch1RxIrqCallback(uint8_t RxData)
|
||||
{
|
||||
if(BL.UartRevTimeOutCnt == 0) {
|
||||
Header = false;
|
||||
rLen = 0;
|
||||
PayLen = 0;
|
||||
}
|
||||
BL.UartRevTimeOutCnt = 3;
|
||||
|
||||
if(Header == false && (RxData == 0x7D)) {
|
||||
Header = true;
|
||||
rLen = 0;
|
||||
PayLen = 0;
|
||||
rBuff[rLen++] = RxData;
|
||||
}
|
||||
else if(Header == true) {
|
||||
if(rLen >= sizeof(rBuff)) {
|
||||
Header = false;
|
||||
rLen = 0;
|
||||
return;
|
||||
}
|
||||
rBuff[rLen++] = RxData;
|
||||
if(rLen == 9) {
|
||||
PayLen = RxData;
|
||||
if(PayLen > 256) {
|
||||
Header = false;
|
||||
rLen = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(rLen == sizeof(FrameHeader_t) + PayLen + 2) {
|
||||
BL.RxLen = rLen;
|
||||
memcpy(BL.RxBuff, rBuff, BL.RxLen);
|
||||
BL.RxFlag = true;
|
||||
Header = false;
|
||||
rLen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: BootLoaderLoopHandler
|
||||
* 功能描述: BootLoader主循环
|
||||
*****************************************************************************************/
|
||||
void BootLoaderLoopHandler(void)
|
||||
{
|
||||
if(BL.RxFlag) {
|
||||
{
|
||||
/*帧解析 - BL_RESET状态下不处理新帧, 避免复位等待期被0x81打断*/
|
||||
if(BL.RxFlag && BL.Status != BL_RESET) {
|
||||
BL.RxFlag = false;
|
||||
AnalyzeData(BL.RxBuff, BL.RxLen);
|
||||
TURN_OFF_STATE_LED();
|
||||
}
|
||||
|
||||
switch(BL.Status){
|
||||
|
||||
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;
|
||||
|
||||
if(JumpToApp(APP_ADDRESS) == false) {
|
||||
BL.Status = BL_IDLE;
|
||||
}
|
||||
break;
|
||||
|
||||
case BL_ERASE_FLASH:
|
||||
FeedDog();
|
||||
EraseFlash();
|
||||
@@ -229,21 +367,23 @@ void BootLoaderLoopHandler(void)
|
||||
BL.RevErrCnt = 0;
|
||||
BL.UpDateFlag = true;
|
||||
break;
|
||||
|
||||
|
||||
case BL_GET_DATA:
|
||||
if(BL.BootLoader1mSDlyCnt > 0)
|
||||
if(BL.BootLoader1mSDlyCnt > 0) {
|
||||
break;
|
||||
SendGetCmd(0x02, BL.AppPackageIdx);
|
||||
}
|
||||
/*请求下一包数据 - 通过RS485应答*/
|
||||
SendResponseCmd(UPDATE_CMD_SLAVE_REQ_DATA, 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) {
|
||||
@@ -261,78 +401,79 @@ void BootLoaderLoopHandler(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: SetDefaultBootPara
|
||||
* 功能描述: 填充BootPara_t中所有默认配置(服务器/Lora/通道/RS485), 由Boot直接配置
|
||||
*****************************************************************************************/
|
||||
static void SetDefaultBootPara(BootPara_t *Para)
|
||||
{
|
||||
Para->SvrAddr[0] = GATEWAY_SVR_ADDR0;
|
||||
Para->SvrAddr[1] = GATEWAY_SVR_ADDR1;
|
||||
Para->SvrAddr[2] = GATEWAY_SVR_ADDR2;
|
||||
Para->SvrAddr[3] = GATEWAY_SVR_ADDR3;
|
||||
Para->SvrPort = GATEWAY_SVR_PORT;
|
||||
Para->LoraFreq = GATEWAY_LORA_FREQ;
|
||||
Para->Much = GATEWAY_MUCH;
|
||||
Para->Auch = GATEWAY_AUCH;
|
||||
Para->Duch = GATEWAY_DUCH;
|
||||
Para->CuchMask = GATEWAY_CUCH_MASK;
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: main
|
||||
* 功能描述: 主函数
|
||||
*****************************************************************************************/
|
||||
int32_t main(void)
|
||||
{
|
||||
BSP_Init();
|
||||
InitCrc32Table(pdwCrc32Tbl);
|
||||
|
||||
|
||||
/*从固定地址0x4000读入网关MAC编码*/
|
||||
memcpy(&s_DevMac[0], &GwMacConst[0], 6);
|
||||
|
||||
/*读取boot参数*/
|
||||
ReadBootPara(&BL.Para);
|
||||
if(BL.Para.DevType != DEV_TYPE) { //设备类型错误,清除升级参数
|
||||
BL.Status = BL_IDLE;
|
||||
|
||||
/*设备判断*/
|
||||
if(BL.Para.GwMac[0] == 0xFF && BL.Para.GwMac[1] == 0xFF) {
|
||||
/*首次运行GwMac无效*/
|
||||
if(BL.Para.FirstRunFlag == 0xFFFFFFFF) {
|
||||
BL.Status = BL_START_APP;
|
||||
}
|
||||
else {
|
||||
BL.Status = BL_IDLE;
|
||||
}
|
||||
BL.Para.AppFlag = 0;
|
||||
BL.Para.UpdateFlag = 0;
|
||||
BL.Para.DevAddr = 0x01;
|
||||
BL.Para.DevType = DEV_TYPE;
|
||||
BL.Para.FirstRunFlag = 0;
|
||||
memcpy(&BL.Para.GwMac[0], &s_DevMac[0], 6);
|
||||
SetDefaultBootPara(&BL.Para);
|
||||
WriteBootPara(&BL.Para);
|
||||
}
|
||||
else if(BL.Para.AppFlag == APP_START_FLAG) {
|
||||
BL.Status = BL_START_APP;
|
||||
else {
|
||||
/*更新MAC地址*/
|
||||
memcpy(&s_DevMac[0], &BL.Para.GwMac[0], 6);
|
||||
|
||||
/*兼容旧参数区: 默认配置未写入(0xFF)时补默认值*/
|
||||
if(BL.Para.SvrAddr[0] == 0xFF && BL.Para.SvrAddr[1] == 0xFF) {
|
||||
SetDefaultBootPara(&BL.Para);
|
||||
WriteBootPara(&BL.Para);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
else {
|
||||
BL.Status = BL_IDLE;
|
||||
}
|
||||
}
|
||||
else if(BL.Para.UpdateFlag == APP_UPDATE_FLAG) {
|
||||
BL.Status = BL_ERASE_FLASH;
|
||||
}
|
||||
while (1) {
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user