Files
BLV_MD203_Bootload/Source/SYSTEM/Bootload_fun.c
caocong 2815979c8a fix:修改RS485通讯引脚
RS485通讯引脚改为串口2,引脚:RX:PB05 TX:PB04 RS485_DR:PB03
2026-02-25 10:29:57 +08:00

1028 lines
33 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.
/*
******************************************************************************
* @file Bootload.c
* @author caocong
* @version V1.00
* @date 2025/04/03
* @Description
* MCU空间规划
* Boot 0x0000 ~ 0x27FF 10K
* APP 0x2800 ~ 0xFEFF 53.8K
* APP_FEATURE 0xFF00 ~ 0xFFFF 256Byte
* EEPROM空间规划
* APP设备信息 0x10000000 - Size:0x40 - 64Byte
*
*/
#include "includes.h"
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
BOOT_INFO_T g_boot;
APP_FEATURE_INFO_T g_app_feature;
void Boot_Function_Init(void)
{
U8_T app_ready = 0;
U16_T sys_reset_sta = 0;
memset(&g_boot,0,sizeof(BOOT_INFO_T));
memset(&g_app_feature,0,sizeof(APP_FEATURE_INFO_T));
g_boot.ackValidity = 1000; //数据默认有效期为1000ms
EEPROM_Init();
/*读取APP 特征区*/
app_ready = Check_APP_Feature();
#if DBG_LOG_EN
if(app_ready == 0x00)
{
Dbg_Println(DBG_BIT_SYS_STATUS,"APP Feature SUCC");
Dbg_Println(DBG_BIT_SYS_STATUS,"APP app_flag:%d",g_app_feature.app_flag);
Dbg_Println(DBG_BIT_SYS_STATUS,"APP app_start_addr:%08x",g_app_feature.app_start_addr);
Dbg_Println(DBG_BIT_SYS_STATUS,"APP app_end_addr:%08x",g_app_feature.app_end_addr);
Dbg_Println(DBG_BIT_SYS_STATUS,"APP app_crc_size:%d",g_app_feature.app_crc_size);
Dbg_Println(DBG_BIT_SYS_STATUS,"APP app_crc_len:%d",g_app_feature.app_crc_len);
Dbg_Print_Buff(DBG_BIT_SYS_STATUS,"APP app_crc:",g_app_feature.app_crc,g_app_feature.app_crc_len);
}else {
Dbg_Println(DBG_BIT_SYS_STATUS,"APP Feature Fail!");
}
#endif
sys_reset_sta = Read_Reset_Status();
if(sys_reset_sta == 0x100) //软件复位 -- 升级开始复位源
{
g_boot.bootTimeout = SYSCON->UREG3 & 0xFFFF; //16位寄存器数据 - APP传递给Boot 参数信息
SYSCON->UREG3 = sys_reset_sta;
if( g_boot.bootTimeout <= 5000) g_boot.bootTimeout = 5000; //最短时间为5S
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"software reset");
#endif
}else if(sys_reset_sta == 0x01) //上电复位RPOR
{
g_boot.bootTimeout = 500;
SYSCON->UREG3 = sys_reset_sta;
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"power on reset");
#endif
}else if(sys_reset_sta == 0x04) //外部手动复位
{
g_boot.bootTimeout = 2000;
SYSCON->UREG3 = sys_reset_sta;
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"ex-pin reset");
#endif
}else if(sys_reset_sta == 0x10) //看门狗超时复位 --升级完成复位源
{
g_boot.bootTimeout = 2000;
if(app_ready == 0x00) {
//SYSCON->UREG3 = sys_reset_sta;
Jump_To_APP();
}
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"wdt reset");
#endif
}else if(sys_reset_sta == 0x40) //外部时钟无效复位
{
g_boot.bootTimeout = 2000;
SYSCON->UREG3 = sys_reset_sta;
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"ex clock invalid reset");
#endif
}else if(sys_reset_sta == 0x80) //CPU请求复位 - link调试复位
{
g_boot.bootTimeout = 2000;
SYSCON->UREG3 = sys_reset_sta;
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"cpu request reset");
#endif
}else
{
g_boot.bootTimeout = 2000;
SYSCON->UREG3 = sys_reset_sta;
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"other reset 0x%x",sys_reset_sta);
#endif
}
}
U8_T Boot_Comm_CheckSum(U8_T * buffer, U16_T len)
{
U8_T sum = 0;
U16_T i=0;
while(len--)
{
sum += buffer[i];
i++;
}
return (~sum);
}
U16_T NetCRC16(U8_T * aStr, U16_T len)
{
U16_T xda , xdapoly ;
U16_T i, j, xdabit ;
xda = 0xFFFF ;
xdapoly = 0xA001 ; // (X**16 + X**15 + X**2 + 1)
for (i = 0; i < len; i++)
{
xda ^= aStr[i] ;
for (j = 0; j < 8; j++)
{
xdabit = (unsigned char)(xda & 0x01) ;
xda >>= 1 ;
if ( xdabit ) xda ^= xdapoly ;
}
}
return xda;
}
void Boot_Comm_FillReplyPack(BOOT_INFO_T *ack_uart)
{
U16_T data_len = ack_uart->ackLen + BCOMM_FMT_PARAM;
ack_uart->ackBuffer[BCOMM_FMT_TXAddr] = g_mcu_dev.dev_addr;
ack_uart->ackBuffer[BCOMM_FMT_SN] = ack_uart->sn;
ack_uart->ackBuffer[BCOMM_FMT_TYPE] = g_mcu_dev.dev_type;
ack_uart->ackBuffer[BCOMM_FMT_RXAddr] = g_boot.pc_addr;
ack_uart->ackBuffer[BCOMM_FMT_CMD] = ack_uart->cmd;
ack_uart->ackBuffer[BCOMM_FMT_LEN_L] = data_len & 0xFF;
ack_uart->ackBuffer[BCOMM_FMT_LEN_H] = (data_len >> 8) & 0xFF;
ack_uart->ackBuffer[BCOMM_FMT_CKS] = 0;
ack_uart->ackBuffer[BCOMM_FMT_CKS] = Boot_Comm_CheckSum(ack_uart->ackBuffer, data_len);
#if DBG_LOG_EN
Dbg_Print_Buff(DBG_BIT_SYS_STATUS,"ACKBuff ",ack_uart->ackBuffer,data_len);
#endif
//MCU485_SendData(ack_uart->ackBuffer, data_len);
Set_GroupSend(ack_uart->ackBuffer,data_len,0x01,ack_uart->ackValidity,100);
//ack_uart->ackLen = 0x00;
}
/*******************************************************************************
* Function Name : APP_Flash_AllEase
* Description : 擦除APP Flash空间
*******************************************************************************/
void APP_Flash_AllEase(void)
{
for(U32_T index = APP_Flash_StartAddr; index < APP_Flash_EndAddr;index+=APP_Flash_PageSize){
SYSCON_IWDCNT_Reload();
PageErase(index);
}
}
/*******************************************************************************
* Function Name : MCU_EEPROM_AllEase
* Description : 擦除EEPROM 空间
*******************************************************************************/
void MCU_EEPROM_AllEase(void)
{
for(U32_T index = MCU_EEPROM_StartAddr; index < MCU_EEPROM_EndAddr;index+=MCU_EEPROM_PageSize){
SYSCON_IWDCNT_Reload();
PageErase(index);
}
}
/*******************************************************************************
* Function Name : APP_FEATURE_Flash_Ease
* Description : 擦除APP特征区 Flash空间
*******************************************************************************/
void APP_FEATURE_Flash_Ease(void)
{
PageErase(APP_FEATURE_Flash_Addr);
}
/*******************************************************************************
* Function Name : Boot_Comm_UpgradeProcess
* Description : Boot通讯数据处理函数
*******************************************************************************/
U8_T Boot_Comm_UpgradeProcess(U8_T *data,U16_T len)
{
U8_T deal_flag = 0,group_flag = 0,reply_flag = 0,setinfo_flag = 0,crcResultFlag = 0;
U16_T data_len = 0,crcNumIndex = 0;
U32_T temp_data = 0,temp_data_2 = 0;
data_len = data[BCOMM_FMT_LEN_H];
data_len <<= 8;
data_len |= data[BCOMM_FMT_LEN_L];
if(len != data_len) {
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"Len Fail ");
#endif
return 0x01;
}
if(Boot_Comm_CheckSum(data,len) != 0) {
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"Boot_Comm_CheckSum Fail ");
#endif
return 0x02;
}
if( (data[BCOMM_FMT_SN] & 0x80) == 0x80){
//群发标志位
group_flag = 0x01;
if( (data[BCOMM_FMT_SN] & 0x0F) != g_boot.sn){
deal_flag = 0x01;
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"Group Data SN Disaffinity,Processing Data");
#endif
}else {
deal_flag = 0x00;
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"Group Data SN The Same,No Processing Data");
#endif
}
}else {
//单发标志位
group_flag = 0x00;
if( (data[BCOMM_FMT_SN] & 0x0F) != g_boot.sn){
//包序号不太相同,需要处理
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"Single Data SN Disaffinity,Processing Data");
#endif
deal_flag = 0x01;
reply_flag = 0x01;
}else if( (data[BCOMM_FMT_SN] & 0x40) == 0x40 ){
//包序号相同,重发标志位置位,不处理,但是需要回复数据,回复上次的数据内容
deal_flag = 0x00;
/*重发数据包命令与上一次的命令相同的话,直接回复上一次的数据内容*/
if(data[BCOMM_FMT_CMD] == g_boot.ackBuffer[BCOMM_FMT_CMD] ){
reply_flag = 0x01;
}
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"Single Data SN The Same,No Processing Data");
#endif
}
}
/*判断类型是否相同,且不是广播类型*/
if( (data[BCOMM_FMT_TYPE] != g_mcu_dev.dev_type) && (data[BCOMM_FMT_TYPE] != 0xFF) ){
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"Boot_Comm_RecvType %d - %d ",g_mcu_dev.dev_type,data[BCOMM_FMT_TYPE]);
#endif
return 0x03;
}
/*判断是否广播类型与广播地址*/
if( (data[BCOMM_FMT_RXAddr] != g_mcu_dev.dev_addr) && (data[BCOMM_FMT_RXAddr] != 0xFF) ){
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"Boot_Comm_RecvAddr %d - %d ",g_mcu_dev.dev_addr,data[BCOMM_FMT_RXAddr]);
#endif
return 0x04;
}
Boot_Time_Refresh();
g_boot.pc_addr = data[BCOMM_FMT_TXAddr];
g_boot.sn = data[BCOMM_FMT_SN] & 0x0F;
g_boot.cmd = data[BCOMM_FMT_CMD];
switch(g_boot.cmd){
case BCOMM_CMD_Handshake: //握手命令
if( (deal_flag == 0x01) && (data_len >= (BCOMM_FMT_PARAM + 4) ) ){
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_Handshake Proecessing ");
#endif
/*设置Boot 超时时间*/
temp_data = data[BCOMM_FMT_PARAM + 1];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM];
if(temp_data != g_boot.bootTimeout){
g_boot.bootTimeout = temp_data;
if(g_boot.bootTimeout < 10) g_boot.bootTimeout = 10;
g_boot.bootTimeout = g_boot.bootTimeout * 1000;
}
/*回复数据的有效期*/
temp_data = data[BCOMM_FMT_PARAM + 3];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM + 2];
g_boot.ackValidity = temp_data;
}
//握手命令 - 需要回复的数据,正常回复
if(reply_flag != 0x01) break; //不回复,直接退出
g_boot.ackBuffer[BCOMM_FMT_PARAM] = Project_Area; //当前处于Bootload区域 0x01Boot;0x02APP
g_boot.ackBuffer[BCOMM_FMT_PARAM + 1] = g_mcu_dev.dev_boot_ver; //Boot 软件版本号
g_boot.ackBuffer[BCOMM_FMT_PARAM + 2] = g_mcu_dev.dev_app_ver; //APP 软件版本号
//MCU UID
g_boot.ackBuffer[BCOMM_FMT_PARAM + 3] = 0x0C; //UUID 长度 MD203 UID 3Byte
g_boot.ackBuffer[BCOMM_FMT_PARAM + 4] = SYSCON->UID0 & 0xFF;
g_boot.ackBuffer[BCOMM_FMT_PARAM + 5] = (SYSCON->UID0 >> 8) & 0xFF;
g_boot.ackBuffer[BCOMM_FMT_PARAM + 6] = (SYSCON->UID0 >> 16) & 0xFF;
g_boot.ackBuffer[BCOMM_FMT_PARAM + 7] = (SYSCON->UID0 >> 24) & 0xFF;
g_boot.ackBuffer[BCOMM_FMT_PARAM + 8] = SYSCON->UID1 & 0xFF;
g_boot.ackBuffer[BCOMM_FMT_PARAM + 9] = (SYSCON->UID1 >> 8) & 0xFF;
g_boot.ackBuffer[BCOMM_FMT_PARAM + 10] = (SYSCON->UID1 >> 16) & 0xFF;
g_boot.ackBuffer[BCOMM_FMT_PARAM + 11] = (SYSCON->UID1 >> 24) & 0xFF;
g_boot.ackBuffer[BCOMM_FMT_PARAM + 12] = SYSCON->UID2 & 0xFF;
g_boot.ackBuffer[BCOMM_FMT_PARAM + 13] = (SYSCON->UID2 >> 8) & 0xFF;
g_boot.ackBuffer[BCOMM_FMT_PARAM + 14] = (SYSCON->UID2 >> 16) & 0xFF;
g_boot.ackBuffer[BCOMM_FMT_PARAM + 15] = (SYSCON->UID2 >> 24) & 0xFF;
//机型编号 - 32Byte 最长32Byte
if(g_mcu_dev.dev_name_len > EEPROM_DEV_NAME_Size) g_mcu_dev.dev_name_len = EEPROM_DEV_NAME_Size;
g_boot.ackBuffer[BCOMM_FMT_PARAM + 16] = g_mcu_dev.dev_name_len;
for(U8_T i=0;i<EEPROM_DEV_NAME_Size;i++){
g_boot.ackBuffer[BCOMM_FMT_PARAM + i + 17] = g_mcu_dev.dev_name[i];
}
g_boot.ackLen = 0x11 + EEPROM_DEV_NAME_Size;
break;
case BCOMM_CMD_Jump: //跳转命令
if(deal_flag != 0x01) break; //不处理直接退出
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_Jump Proecessing ");
#endif
if(data[BCOMM_FMT_PARAM] == 0x02){
/*跳转至APP区域*/
g_boot.bootTimeout = 200; //在Boot超时中跳转
g_boot.bootTick = SysTick_1ms;
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplySUCC;
}else {
/*参数错误*/
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"ERR:Jump_boot");
#endif
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplyFAIL;
}
g_boot.ackLen = 1;
break;
case BCOMM_CMD_SetInfo: //设置参数
if(deal_flag != 0x01) break; //不处理直接退出
if(data_len < (BCOMM_FMT_PARAM + 4) ) {
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_SetInfo Para Error ");
#endif
break;
}
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_SetInfo Proecessing ");
#endif
/*设置波特率参数*/
temp_data = data[BCOMM_FMT_PARAM + 1];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM];
temp_data *= 100;
/*设置Boot 超时时间*/
g_boot.bootTimeout = data[BCOMM_FMT_PARAM + 3];
g_boot.bootTimeout <<= 8;
g_boot.bootTimeout |= data[BCOMM_FMT_PARAM + 2];
if(g_boot.bootTimeout < 10) g_boot.bootTimeout = 10;
g_boot.bootTimeout = g_boot.bootTimeout * 1000;
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BaudSet: %d",temp_data);
Dbg_Println(DBG_BIT_SYS_STATUS,"bootTimeout: %d",g_boot.bootTimeout);
#endif
if(Get_Uart_BaudCnt(temp_data) != 0x00) {
/*设置波特率支持*/
if(group_flag == 0x01){
//群发 - 直接设置波特率
UARTx_ChangeBaud(UART_1,temp_data);
}else{
//单发 - 等待本包数据回复完成后设置波特率
BUS485_SetBaud(temp_data);
}
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplySUCC;
}else {
/*设置波特率不支持*/
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplyFAIL;
}
g_boot.ackLen = 1;
break;
case BCOMM_CMD_WriteFlash: //写Flash
if(deal_flag != 0x01) break; //不处理直接退出
if(data_len < (BCOMM_FMT_PARAM + 6) ) {
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_WriteFlash Para Error ");
#endif
break;
}
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_WriteFlash Proecessing ");
#endif
/*写入Flash地址 */
temp_data = data[BCOMM_FMT_PARAM + 3];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM + 2];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM + 1];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM];
/*写入Flash长度 */
temp_data_2 = data[BCOMM_FMT_PARAM + 5];
temp_data_2 <<= 8;
temp_data_2 |= data[BCOMM_FMT_PARAM + 4];
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"WAddr: 0x%08x Len:%d",temp_data,temp_data_2);
#endif
if ( (temp_data_2 != 0x00) && ( temp_data_2 == (data_len - BCOMM_FMT_PARAM - 6) ) ){
if( (APP_Flash_StartAddr <= temp_data) && ( (temp_data + temp_data_2) <= APP_Flash_EndAddr ) ){
Page_ProgramData(temp_data,temp_data_2,&data[BCOMM_FMT_PARAM + 6]);
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplySUCC;
}else {
/*写入Flash 不在地址范围内 */
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplyFAIL;
}
}
g_boot.ackLen = 1;
break;
case BCOMM_CMD_ReadFlash: //读取Flash
if(deal_flag != 0x01) break; //不处理直接退出
if(data_len < (BCOMM_FMT_PARAM + 6) ) {
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_ReadFlash Para Error ");
#endif
break;
}
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_ReadFlash Proecessing ");
#endif
/*读取Flash地址 */
temp_data = data[BCOMM_FMT_PARAM + 3];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM + 2];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM + 1];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM];
/*读取Flash长度 */
temp_data_2 = data[BCOMM_FMT_PARAM + 5];
temp_data_2 <<= 8;
temp_data_2 |= data[BCOMM_FMT_PARAM + 4];
if(temp_data_2 > BCOMM_ParaSize) temp_data_2 = BCOMM_ParaSize; //参数最长不能超过ACK BUFF大小
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"Read Addr:%08x Len:%04x %08x",temp_data,temp_data_2, (APP_Flash_EndAddr + APP_Flash_PageSize) );
#endif
if( (temp_data_2 != 0x00) && (APP_Flash_StartAddr <= temp_data) && ( (temp_data + temp_data_2) <= (APP_Flash_EndAddr + APP_Flash_PageSize) ) ){
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplySUCC;
ReadDataArry_U8(temp_data,temp_data_2,&g_boot.ackBuffer[BCOMM_FMT_PARAM + 1]);
g_boot.ackLen = temp_data_2 + 1;
}else {
/*写入Flash 不在地址范围内 */
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplyFAIL;
g_boot.ackLen = 1;
}
break;
case BCOMM_CMD_EraseFlash: //擦除Flash
if(deal_flag != 0x01) break; //不处理直接退出
if(data_len < (BCOMM_FMT_PARAM + 1) ) {
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_EraseFlash Para Error ");
#endif
break;
}
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_EraseFlash Proecessing ");
#endif
if(data[BCOMM_FMT_PARAM] == 0x01){
/*擦除APP Flash 指定区域*/
if(data_len < (BCOMM_FMT_PARAM + 7) ) {
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_EraseFlash Para Error ");
#endif
break;
}
/*擦除Flash地址 */
temp_data = data[BCOMM_FMT_PARAM + 4];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM + 3];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM + 2];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM + 1];
/*擦除Flash 长度*/
temp_data_2 = data[BCOMM_FMT_PARAM + 6];
temp_data_2 <<= 8;
temp_data_2 |= data[BCOMM_FMT_PARAM + 5];
if( (temp_data_2 != 0x00) && ( APP_Flash_StartAddr <= temp_data ) && ( (temp_data + temp_data_2) <= (APP_Flash_EndAddr + APP_Flash_PageSize) ) ){
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"EraseFlash Addr:%x Len:%d ",temp_data,temp_data_2);
#endif
temp_data = temp_data - (temp_data % APP_Flash_PageSize);
for(U32_T i = temp_data;i<(temp_data + temp_data_2) ;i+=APP_Flash_PageSize){
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"PageErase Addr:%x ",i);
#endif
SYSCON_IWDCNT_Reload();
PageErase(i);
}
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplySUCC;
g_boot.ackLen = 1;
}else {
/*写入Flash 不在地址范围内 */
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplyFAIL;
g_boot.ackLen = 1;
}
}else if(data[BCOMM_FMT_PARAM] == 0x02){
/*擦除全部APP Flash 同时也有APP 特征区*/
APP_Flash_AllEase();
APP_FEATURE_Flash_Ease();
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplySUCC;
g_boot.ackLen = 1;
}else {
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplyFAIL;
g_boot.ackLen = 1;
}
break;
case BCOMM_CMD_WriteEEPROM: //写EEPROM
if(deal_flag != 0x01) break; //不处理直接退出
if(data_len < (BCOMM_FMT_PARAM + 6) ) {
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_WriteEEPROM Para Error ");
#endif
break;
}
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_WriteEEPROM Proecessing ");
#endif
/*写入EEPROM 的偏移地址 */
temp_data = data[BCOMM_FMT_PARAM + 3];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM + 2];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM + 1];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM];
temp_data += MCU_EEPROM_StartAddr; //加上EEPROM起始地址
/*写入EEPROM长度 */
temp_data_2 = data[BCOMM_FMT_PARAM + 5];
temp_data_2 <<= 8;
temp_data_2 |= data[BCOMM_FMT_PARAM + 4];
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"WriteEEPROM Address%08x Len:%d",temp_data,temp_data_2);
#endif
if ( (temp_data_2 != 0x00) && (temp_data_2 == (data_len - BCOMM_FMT_PARAM - 6) ) ){
if( (MCU_EEPROM_StartAddr <= temp_data) && ( (temp_data + temp_data_2) <= MCU_EEPROM_EndAddr ) ){
Page_ProgramData(temp_data,temp_data_2,&data[BCOMM_FMT_PARAM + 6]);
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplySUCC;
}else {
/*写入Flash 不在地址范围内 */
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplyFAIL;
}
}
g_boot.ackLen = 1;
break;
case BCOMM_CMD_ReadEEPROM: //读取EEPROM
if(deal_flag != 0x01) break; //不处理直接退出
if(data_len < (BCOMM_FMT_PARAM + 6) ) {
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_ReadEEPROM Para Error ");
#endif
break;
}
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_ReadEEPROM Proecessing ");
#endif
/*读取EEPROM地址 */
temp_data = data[BCOMM_FMT_PARAM + 3];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM + 2];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM + 1];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM];
temp_data += MCU_EEPROM_StartAddr; //加上EEPROM起始地址
/*读取EEPROM长度 */
temp_data_2 = data[BCOMM_FMT_PARAM + 5];
temp_data_2 <<= 8;
temp_data_2 |= data[BCOMM_FMT_PARAM + 4];
Dbg_Println(DBG_BIT_SYS_STATUS,"ReadEEPROM Address%08x Len:%d",temp_data,temp_data_2);
if(temp_data_2 > BCOMM_ParaSize) temp_data_2 = BCOMM_ParaSize; //参数最长不能超过ACK BUFF大小
if( (temp_data_2 != 0x00) && ( MCU_EEPROM_StartAddr <= temp_data ) && ( (temp_data + temp_data_2) <= MCU_EEPROM_EndAddr ) ){
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplySUCC;
ReadDataArry_U8(temp_data,temp_data_2,&g_boot.ackBuffer[BCOMM_FMT_PARAM + 1]);
g_boot.ackLen = temp_data_2 + 1;
}else {
/*写入Flash 不在地址范围内 */
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplyFAIL;
g_boot.ackLen = 1;
}
break;
case BCOMM_CMD_EraseEEPROM: //擦除EEPROM
if(deal_flag != 0x01) break; //不处理直接退出
if(data_len < (BCOMM_FMT_PARAM + 1) ) {
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_EraseEEPROM Para Error ");
#endif
break;
}
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_EraseEEPROM Proecessing ");
#endif
if(data[BCOMM_FMT_PARAM] == 0x01){
if(data_len < (BCOMM_FMT_PARAM + 7) ) {
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_EraseEEPROM Para Error ");
#endif
break;
}
/*擦除EEPROM 指定区域*/
/*擦除EEPROM地址 */
temp_data = data[BCOMM_FMT_PARAM + 4];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM + 3];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM + 2];
temp_data <<= 8;
temp_data |= data[BCOMM_FMT_PARAM + 1];
temp_data += MCU_EEPROM_StartAddr; //加上EEPROM起始地址
/*擦除EEPROM 长度*/
temp_data_2 = data[BCOMM_FMT_PARAM + 6];
temp_data_2 <<= 8;
temp_data_2 |= data[BCOMM_FMT_PARAM + 5];
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_EraseFlash Addr:%x Len:%d ",temp_data,temp_data_2);
#endif
temp_data_2 = temp_data_2 + temp_data;
if( (temp_data_2 != 0x00) && (MCU_EEPROM_StartAddr <= temp_data) && ( temp_data_2 <= MCU_EEPROM_EndAddr ) ){
temp_data = temp_data - (temp_data % MCU_EEPROM_PageSize); //将擦除地址 首地址取整
for(U32_T i = temp_data;i < temp_data_2 ;i += MCU_EEPROM_PageSize){
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"PageErase Addr:%x ",i);
#endif
SYSCON_IWDCNT_Reload();
PageErase(i);
}
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplySUCC;
g_boot.ackLen = 1;
}else {
/*写入EEPROM 不在地址范围内 */
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_EraseFlash Error ");
#endif
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplyFAIL;
g_boot.ackLen = 1;
}
}else if(data[BCOMM_FMT_PARAM] == 0x02){
/*擦除全部EEPROM 区域*/
MCU_EEPROM_AllEase();
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplySUCC;
g_boot.ackLen = 1;
}else {
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplyFAIL;
g_boot.ackLen = 1;
}
break;
case BCOMM_CMD_CheckData: //校验
if(deal_flag != 0x01) break; //不处理直接退出
if(data_len < (BCOMM_FMT_PARAM + 10) ) {
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_CheckData Para Error ");
#endif
break;
}
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BCOMM_CMD_CheckData Proecessing ");
#endif
memset(&g_app_feature,0,sizeof(APP_FEATURE_INFO_T));
/* 校验CRC 起始地址*/
g_app_feature.app_start_addr = data[BCOMM_FMT_PARAM + 3];
g_app_feature.app_start_addr <<= 8;
g_app_feature.app_start_addr |= data[BCOMM_FMT_PARAM + 2];
g_app_feature.app_start_addr <<= 8;
g_app_feature.app_start_addr |= data[BCOMM_FMT_PARAM + 1];
g_app_feature.app_start_addr <<= 8;
g_app_feature.app_start_addr |= data[BCOMM_FMT_PARAM];
/* 校验CRC 结束地址*/
g_app_feature.app_end_addr = data[BCOMM_FMT_PARAM + 7];
g_app_feature.app_end_addr <<= 8;
g_app_feature.app_end_addr |= data[BCOMM_FMT_PARAM + 6];
g_app_feature.app_end_addr <<= 8;
g_app_feature.app_end_addr |= data[BCOMM_FMT_PARAM + 5];
g_app_feature.app_end_addr <<= 8;
g_app_feature.app_end_addr |= data[BCOMM_FMT_PARAM + 4];
/* 校验CRC 大小*/
g_app_feature.app_crc_size = data[BCOMM_FMT_PARAM + 9];
g_app_feature.app_crc_size <<= 8;
g_app_feature.app_crc_size |= data[BCOMM_FMT_PARAM + 8];
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"App Start_addr :%08x ",g_app_feature.app_start_addr);
Dbg_Println(DBG_BIT_SYS_STATUS,"App End_addr :%08x ",g_app_feature.app_end_addr);
Dbg_Println(DBG_BIT_SYS_STATUS,"App CRC Block_Size :%d ",g_app_feature.app_crc_size);
#endif
if( (g_app_feature.app_start_addr >= APP_Flash_StartAddr)
&& (g_app_feature.app_end_addr < APP_Flash_EndAddr)
&& (g_app_feature.app_end_addr > g_app_feature.app_start_addr)
&& (g_app_feature.app_crc_size == 512) )
{
temp_data = g_app_feature.app_end_addr - g_app_feature.app_start_addr;
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"App Len :%d ",temp_data);
#endif
if( (temp_data % g_app_feature.app_crc_size ) != 0x00 ){
g_app_feature.app_crc_len = ((temp_data / g_app_feature.app_crc_size) + 1) * 2;
}else {
g_app_feature.app_crc_len = (temp_data / g_app_feature.app_crc_size) * 2;
}
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"App CRC BLock:%d ",g_app_feature.app_crc_len);
#endif
/*比对校验的数据包长 对不对 */
if( (BCOMM_FMT_PARAM + 10 + g_app_feature.app_crc_len ) == data_len ){
U8_T temp_buff[530];
U32_T crc_data_len = 0;
crcNumIndex = 0;
memcpy(g_app_feature.app_crc,&data[BCOMM_FMT_PARAM + 10],(data_len - 10 - BCOMM_FMT_PARAM) );
for(U32_T crc_addr = g_app_feature.app_start_addr; crc_addr < g_app_feature.app_end_addr;crc_addr += g_app_feature.app_crc_size)
{
SYSCON_IWDCNT_Reload();
if( g_app_feature.app_end_addr - crc_addr >= g_app_feature.app_crc_size) {
crc_data_len = g_app_feature.app_crc_size;
}else {
crc_data_len = g_app_feature.app_end_addr - crc_addr;
}
ReadDataArry_U8(crc_addr,crc_data_len,temp_buff);
temp_data = NetCRC16(temp_buff,crc_data_len);
temp_data_2 = g_app_feature.app_crc[crcNumIndex + 1];
temp_data_2 <<= 8;
temp_data_2 |= g_app_feature.app_crc[crcNumIndex];
if(temp_data != temp_data_2){
/*校验失败 - */
g_boot.ackBuffer[BCOMM_FMT_PARAM ] = BCOMM_CMD_ReplyFAIL;
g_boot.ackBuffer[BCOMM_FMT_PARAM + 5 + crcResultFlag*4] = ((crc_addr >> 24) & 0xFF);
g_boot.ackBuffer[BCOMM_FMT_PARAM + 4 + crcResultFlag*4] = ((crc_addr >> 16) & 0xFF);
g_boot.ackBuffer[BCOMM_FMT_PARAM + 3 + crcResultFlag*4] = ((crc_addr >> 8) & 0xFF);
g_boot.ackBuffer[BCOMM_FMT_PARAM + 2 + crcResultFlag*4] = (crc_addr & 0xFF);
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"App CRC Fail ADDR:%08X %04X-%04X",crc_addr,temp_data,temp_data_2);
#endif
crcResultFlag++;
if(crcResultFlag >= 20) break;
}
crcNumIndex += 2;
}
if(crcResultFlag == 0x00){
/*校验成功 - 写入APP 特征区*/
g_app_feature.app_flag = App_Procedure_Ready;
g_app_feature.crcL_check = 0x00;
g_app_feature.crcH_check = 0x00;
temp_data = NetCRC16((U8_T *)&g_app_feature,sizeof(APP_FEATURE_INFO_T));
g_app_feature.crcL_check = temp_data & 0xFF;
g_app_feature.crcH_check = (temp_data >> 8) & 0xFF;
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"APP Feature Save");
Dbg_Println(DBG_BIT_SYS_STATUS,"APP crc_check:%04x",temp_data);
Dbg_Println(DBG_BIT_SYS_STATUS,"APP app_flag:%02x",g_app_feature.app_flag);
Dbg_Println(DBG_BIT_SYS_STATUS,"APP app_start_addr:%08x",g_app_feature.app_start_addr);
Dbg_Println(DBG_BIT_SYS_STATUS,"APP app_end_addr:%08x",g_app_feature.app_end_addr);
Dbg_Println(DBG_BIT_SYS_STATUS,"APP app_crc_size:%d",g_app_feature.app_crc_size);
Dbg_Println(DBG_BIT_SYS_STATUS,"APP app_crc_len:%d",g_app_feature.app_crc_len);
Dbg_Print_Buff(DBG_BIT_SYS_STATUS,"APP app_crc:",g_app_feature.app_crc,g_app_feature.app_crc_len);
#endif
Page_ProgramData(APP_FEATURE_Flash_Addr,sizeof(APP_FEATURE_INFO_T),(U8_T *)&g_app_feature);
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplySUCC;
}
g_boot.ackBuffer[BCOMM_FMT_PARAM + 1] = crcResultFlag;
g_boot.ackLen = 2 + crcResultFlag*4;
}else {
/*数据包长不对*/
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"App CRC BLock ERROR:%d %d",temp_data,data_len);
#endif
g_boot.ackBuffer[BCOMM_FMT_PARAM] = 0x02;
g_boot.ackLen = 1;
}
}else{
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"App CRC Para ERROR");
#endif
g_boot.ackBuffer[BCOMM_FMT_PARAM] = 0x01;
g_boot.ackLen = 1;
}
break;
default: //未知命令
g_boot.ackBuffer[BCOMM_FMT_PARAM] = BCOMM_CMD_ReplyFAIL;
g_boot.ackLen = 1;
break;
}
/*回复通讯数据*/
if( (group_flag == 0x00) && (reply_flag == 0x01) )
{
Boot_Comm_FillReplyPack(&g_boot);
}
}
void Boot_Time_Refresh(void)
{
g_boot.bootTick = SysTick_1ms;
}
void Boot_TimeOut_Task(void)
{
if(SysTick_1ms - g_boot.bootTick >= g_boot.bootTimeout)
{
while(1); //执行看门狗复位
}
}
void Jump_To_APP(void)
{
volatile U32_T EIPaddr = g_app_feature.app_start_addr + 0x010C;
asm("mov r0,%0\n"::"r"(EIPaddr):); // APP入口地址 __start label的值
asm(" jmp r0 ");
}
U8_T Check_APP_Feature(void)
{
U8_T temp_buff[530];
U16_T crcNumIndex = 0,temp_data = 0,temp_data_2 = 0;
U32_T crc_data_len = 0,crc_feature_len = 0;
/*读取APP 特征区*/
ReadDataArry_U8(APP_FEATURE_Flash_Addr,sizeof(APP_FEATURE_INFO_T),temp_buff);
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"App Feature Size:%d",sizeof(APP_FEATURE_INFO_T));
Dbg_Print_Buff(DBG_BIT_SYS_STATUS,"App Feature Buff:",temp_buff,sizeof(APP_FEATURE_INFO_T));
#endif
crc_data_len = temp_buff[1];
crc_data_len <<= 8;
crc_data_len |= temp_buff[0];
temp_buff[0] = 0x00;
temp_buff[1] = 0x00;
if( NetCRC16((U8_T *)temp_buff,sizeof(APP_FEATURE_INFO_T)) != crc_data_len )
{
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"App Feature CRC ERROR");
#endif
return 0x01;
}
memcpy(&g_app_feature,temp_buff,sizeof(APP_FEATURE_INFO_T));
g_app_feature.crcL_check = crc_data_len & 0xFF;
g_app_feature.crcH_check = (crc_data_len >> 8) & 0xFF;
if(g_app_feature.app_flag != App_Procedure_Ready)
{
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"App Feature Flag ERROR");
#endif
return 0x02; //没有APP标志位
}
if( (g_app_feature.app_start_addr >= APP_Flash_StartAddr)
&& (g_app_feature.app_end_addr < APP_Flash_EndAddr)
&& (g_app_feature.app_end_addr > g_app_feature.app_start_addr)
&& (g_app_feature.app_crc_size == 512) )
{
crc_data_len = g_app_feature.app_end_addr - g_app_feature.app_start_addr;
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"App Len :%d ",crc_data_len);
#endif
if( (crc_data_len % g_app_feature.app_crc_size ) != 0x00 ){
crc_feature_len = ((crc_data_len / g_app_feature.app_crc_size) + 1) * 2;
}else {
crc_feature_len = (crc_data_len / g_app_feature.app_crc_size) * 2;
}
if(g_app_feature.app_crc_len != crc_feature_len) {
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"App CRC Len :%d - %d",crc_feature_len,g_app_feature.app_crc_len);
#endif
return 0x03; //APP CRC长度不对
}
for(U32_T crc_addr = g_app_feature.app_start_addr; crc_addr < g_app_feature.app_end_addr;crc_addr += g_app_feature.app_crc_size)
{
SYSCON_IWDCNT_Reload();
if( g_app_feature.app_end_addr - crc_addr >= g_app_feature.app_crc_size) {
crc_data_len = g_app_feature.app_crc_size;
}else {
crc_data_len = g_app_feature.app_end_addr - crc_addr;
}
ReadDataArry_U8(crc_addr,crc_data_len,temp_buff);
temp_data = NetCRC16(temp_buff,crc_data_len);
temp_data_2 = g_app_feature.app_crc[crcNumIndex + 1];
temp_data_2 <<= 8;
temp_data_2 |= g_app_feature.app_crc[crcNumIndex];
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"App CRC ADDR:%08x %04x-%04x",crc_addr,temp_data,temp_data_2);
#endif
if(temp_data != temp_data_2){
/*校验失败 - */
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"App CRC Fail ADDR:%08X %04X-%04X",crc_addr,temp_data,temp_data_2);
#endif
return 0x04; //校验失败
}
crcNumIndex += 2;
}
}else {
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"App Feature StartAddr ERROR");
Dbg_Println(DBG_BIT_SYS_STATUS,"APP app_start_addr:%08x",g_app_feature.app_start_addr);
Dbg_Println(DBG_BIT_SYS_STATUS,"APP app_end_addr:%08x",g_app_feature.app_end_addr);
Dbg_Println(DBG_BIT_SYS_STATUS,"APP app_crc_len:%d",g_app_feature.app_crc_len);
#endif
return 0x05; //起始地址不正确
}
return 0x00;
}