Files

339 lines
7.5 KiB
C
Raw Permalink Normal View History

2026-05-09 17:09:52 +08:00
/******************************************************************************
* Include files
******************************************************************************/
#include <stdlib.h>
#include "main.h"
//#include "lis2hh12_app.h"
#include "flash.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)
{
for(int i = 0; i < wLen; i++) {
Flash_WriteByte(APP_ADDRESS + AddrOffset + i, wData[i]);
}
}
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;
}
void SendGetCmd(uint8_t Cmd, uint16_t PayLoad)
{
uint8_t sData[20], sLen;
uint16_t crc16;
FrameH Frame = (FrameH)sData;
Frame->Header = 0x7d;
memcpy(Frame->DevMac, DevMac, 6);
Frame->Cmd = Cmd & 0x7F;
if(Frame->Cmd == UPDATE_CMD_SLAVE_RES) {
Frame->PayloadLen = 1;
sData[sizeof(FrameHeader_t)] = PayLoad;
}
else if(Frame->Cmd == UPDATE_CMD_SLAVE_REQ_DATA) {
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;
DBGUartSend(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;
int ret = memcmp(Frame->DevMac, DevMac, 6);
if(ret != 0)
return false;
if(Frame->Cmd == UPDATE_CMD_MASTER_REQ) {
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(UPDATE_CMD_SLAVE_RES, 1);
}
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);
BL.AppPackageIdx++;
BL.RevErrCnt = 0;
if(BL.AppPackageIdx < BL.AppPackageCnt) {
BL.Status = BL_GET_DATA;
BL.BootLoader1mSDlyCnt = 5;
}
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;
WriteBootPara(&BL.Para);
}
}
}
else
return false;
return true;
}
void BootLoaderLoopHandler(void)
{
if(BL.RxFlag) {
BL.RxFlag = false;
AnalyzeData(BL.RxBuff, BL.RxLen);
}
switch(BL.Status) {
case BL_IDLE:
break;
case BL_RESET:
if(BL.BootLoader1mSDlyCnt > 0) {
break;
}
SystemReset();
break;
case BL_START_APP:
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(UPDATE_CMD_MASTRE_RES_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) {
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)
{
BspInit();
InitCrc32Table(pdwCrc32Tbl);
ReadBootPara(&BL.Para);
2026-05-11 10:02:31 +08:00
if((BL.Para.DevMac[0] | (BL.Para.DevMac[1] << 8)) != DEVICE_TYPE){ //设备类型错误,清除升级参数
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.FirstRunFlag = 0;
memcpy(&BL.Para.DevMac, &DevMac[0], 6);
BL.Para.LoraFreq = LORA_FREQ;
WriteBootPara(&BL.Para);
}
else if(BL.Para.AppFlag == APP_START_FLAG) {
2026-05-09 17:09:52 +08:00
BL.Status = BL_START_APP;
}
else if(BL.Para.UpdateFlag == APP_UPDATE_FLAG) {
BL.Status = BL_ERASE_FLASH;
}
while (1) {
FeedDogHandler();
BootLoaderLoopHandler();
}
}
/*******************************************************************************
* 中断服务函数
******************************************************************************/
void SysTick_CallBack(void)
{
BootLoader1mSRoutine();
}
void DebugUartIRQ(uint8_t RxData)
{
static uint16_t rLen = 0;
static uint8_t rBuff[300];
static bool Header = false;
static uint16_t PayLen = 0;
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 {
rBuff[rLen++] = RxData;
if(rLen == 9) {
PayLen = RxData;
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;
}
}
}
//void KeyIRQHandler(void)
//{
//
//}