377 lines
8.8 KiB
C
377 lines
8.8 KiB
C
#include "main.h"
|
||
|
||
uint8_t send_start_buf[6] = {0xA5, 0x5A, 0x06, 0x00, 0x10, 0x01};
|
||
uint8_t get_package_buf[14] = {0xA5, 0x5A, 0x0A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // 2022change
|
||
// uint8_t send_over_buf[9] = {0xA5, 0x5A, 0x09, 0x00, 0x12, 0x00, 0x00, 0x00,0x00};//2022change
|
||
|
||
uint32_t FlashPtr;
|
||
typedef void (*pFunction)(void);
|
||
pFunction Jump_To_Application;
|
||
|
||
uint32_t packagesSize;
|
||
uint8_t rx1_frame_OK;
|
||
uint8_t rx1_buff[rx2_buffsize];
|
||
uint32_t rx1count;
|
||
uint8_t wifi_connect_flg = 0;
|
||
uint32_t time_flg = 0;
|
||
uint8_t version[4] = {0}; // 2022change
|
||
uint32_t current_package; //当前升级包
|
||
uint8_t upgrade_hand_flg = 0;
|
||
uint32_t lastFrameCnt = 0; //最后一帧字节数
|
||
uint8_t flash_array[BinPerFrameSize];
|
||
|
||
uint32_t OPENBL_CRC32_MPEG_2(uint8_t *data, uint32_t length)
|
||
{
|
||
uint32_t i;
|
||
uint32_t crc = 0xffffffff, j = 0;
|
||
|
||
while ((length--) != 0)
|
||
{
|
||
crc ^= (uint32_t)data[j] << 24;
|
||
j++;
|
||
for (i = 0; i < 8; ++i)
|
||
{
|
||
if ((crc & 0x80000000) != 0)
|
||
{
|
||
crc = (crc << 1) ^ 0x04C11DB7;
|
||
}
|
||
else
|
||
{
|
||
crc <<= 1;
|
||
}
|
||
}
|
||
}
|
||
return crc;
|
||
}
|
||
|
||
void CRC_usart1send(uint8_t *data, uint32_t length)
|
||
{
|
||
uint32_t crc_temp, i;
|
||
uint8_t crc[4];
|
||
|
||
crc_temp = OPENBL_CRC32_MPEG_2(data, length);
|
||
crc[0] = (uint8_t)crc_temp;
|
||
crc[1] = (uint8_t)(crc_temp >> 8);
|
||
crc[2] = (uint8_t)(crc_temp >> 16);
|
||
crc[3] = (uint8_t)(crc_temp >> 24);
|
||
|
||
for (i = 0; i < length; i++)
|
||
{
|
||
UART_SendByte(USART1, (uint8_t)data[i]);
|
||
}
|
||
for (i = 0; i < 4; i++)
|
||
{
|
||
UART_SendByte(USART1, (uint8_t)crc[i]);
|
||
}
|
||
while (RESET == USART_GetFlagStatus(USART1, USART_FLAG_TC))
|
||
;
|
||
}
|
||
|
||
uint8_t flashWrite(uint8_t *data, uint_fast8_t length)
|
||
{
|
||
static uint8_t buffer;
|
||
uint16_t temp, i;
|
||
uint_fast8_t index;
|
||
uint32_t flashPtr1;
|
||
|
||
if (length == 0)
|
||
return 0;
|
||
flashPtr1 = FlashPtr;
|
||
FLASH_Unlock();
|
||
|
||
index = 0;
|
||
|
||
do
|
||
{
|
||
if (flashPtr1 & 1)
|
||
{
|
||
flashPtr1--;
|
||
temp = buffer;
|
||
}
|
||
else
|
||
{
|
||
temp = data[index++];
|
||
};
|
||
|
||
temp |= data[index++] << 8;
|
||
|
||
FLASH_ProgramHalfWord(flashPtr1, temp);
|
||
flashPtr1 += sizeof(uint16_t);
|
||
|
||
} while ((length - index) >= 2);
|
||
|
||
for (i = 0; i < length; i++) //读出flash校验是否写错
|
||
{
|
||
if (data[i] != *(uint8_t *)(FlashPtr + i))
|
||
return 1; //有错
|
||
}
|
||
FLASH_Lock();
|
||
FlashPtr += length;
|
||
return 0;
|
||
}
|
||
|
||
void page_flashErase(void) //形参为包数量
|
||
{
|
||
FLASH_Unlock();
|
||
FLASH_EraseSector(FLASH_Sector_8, VoltageRange_3);
|
||
FLASH_EraseSector(FLASH_Sector_9, VoltageRange_3);
|
||
FLASH_Lock();
|
||
}
|
||
|
||
int check_stack_head(unsigned long execAdr)
|
||
{
|
||
// MBL_APP_EXEC_ADR为新程序的起始地址,检查栈顶地址是否合法,即栈顶地址是否为0x2000xxxx(内置SRAM)
|
||
if (((*(__IO uint32_t *)execAdr) & 0x2FFE0000UL) == 0x20000000UL)
|
||
return 0;
|
||
else
|
||
return -1;
|
||
}
|
||
|
||
void flash_write_version(uint8_t *version) // version为4个字节
|
||
{
|
||
//需要flash已解锁
|
||
uint32_t value;
|
||
value = *(__IO uint32_t *)version;
|
||
FLASH_ProgramWord(FLASH_VERSION_ADDR, value);
|
||
}
|
||
|
||
void execute_app()
|
||
{
|
||
uint32_t JumpAddress = 0;
|
||
uint32_t Jumpadd = FLASH_OLDAPP_ADDR;
|
||
USART_DeInit(USART1);
|
||
|
||
if (upgrade_flag == 1) // 1111--升级完成
|
||
{
|
||
Jumpadd = FLASH_APP_ADDR;
|
||
}
|
||
|
||
JumpAddress = *(__IO uint32_t *)(Jumpadd + 4); //用户代码区第二个字存储为新程序起始地址(新程序复位向量指针)
|
||
printf("Jumpadd is %x,JumpAddress is %x,upgrade_flag is %d\r\n", Jumpadd, JumpAddress, upgrade_flag);
|
||
Jump_To_Application = (pFunction)JumpAddress;
|
||
__set_MSP(*(__IO uint32_t *)Jumpadd); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
|
||
Jump_To_Application(); // 设置PC指针为新程序复位中断函数的地址
|
||
}
|
||
|
||
void upgrade_menu(void)
|
||
{
|
||
uint8_t error;
|
||
switch (upgrade_hand_flg)
|
||
{
|
||
case 0x01: //获取数据包
|
||
upgrade_hand_flg = 0x00; //获取数据包标志位置0
|
||
|
||
get_package_buf[6] = (uint8_t)current_package;
|
||
get_package_buf[7] = (uint8_t)(current_package >> 8); // 2022change
|
||
get_package_buf[8] = (uint8_t)(current_package >> 16);
|
||
get_package_buf[9] = (uint8_t)(current_package >> 24);
|
||
// time_flg = resent_time;//重新计时
|
||
CRC_usart1send(get_package_buf, 9); // 2022change
|
||
|
||
break;
|
||
case 0x02: //写入数据包
|
||
error = flashWrite(flash_array, BinPerFrameSize); //写入flash,固定一包写256个字节
|
||
if (1 == error) //写入错误重启,重新升级
|
||
{
|
||
page_flashErase();
|
||
NVIC_SystemReset();
|
||
}
|
||
|
||
if (0 == lastFrameCnt)
|
||
{
|
||
current_package += BinPerFrameSize;
|
||
upgrade_hand_flg = 0x01; //获取数据包标志位置0
|
||
get_package_buf[5] = 0x01; //回复OK
|
||
}
|
||
else //最后一帧发完
|
||
{
|
||
current_package += lastFrameCnt;
|
||
upgrade_hand_flg = 0x44; // flash完成标志位
|
||
get_package_buf[5] = 0x03; //回复完成
|
||
}
|
||
break;
|
||
case 0x44: // Execute The New Program Enter 'D'
|
||
// MBL_APP_EXEC_ADR为新程序的起始地址,检查栈顶地址是否合法,即栈顶地址是否为0x2000xxxx(内置SRAM)
|
||
if (check_stack_head(FLASH_APP_ADDR) == 0)
|
||
{
|
||
FLASH_Unlock();
|
||
FLASH_EraseSector(FLASH_Sector_2, VoltageRange_3);
|
||
FLASH_ProgramWord(FLASH_DATA_FLAG_ADDR, FLASH_START_FLAG); //升级完成
|
||
// flash_write_version(version);
|
||
FLASH_Lock();
|
||
// send_over_buf[5] = version[0];
|
||
// send_over_buf[6] = version[1];
|
||
// send_over_buf[7] = version[2];
|
||
// send_over_buf[8] = version[3];//2022change
|
||
|
||
get_package_buf[6] = (uint8_t)current_package;
|
||
get_package_buf[7] = (uint8_t)(current_package >> 8);
|
||
get_package_buf[8] = (uint8_t)(current_package >> 16);
|
||
get_package_buf[9] = (uint8_t)(current_package >> 24);
|
||
CRC_usart1send(get_package_buf, 9); //发送完成升级
|
||
delay_ms(2);
|
||
upgrade_flag = 1;
|
||
execute_app(); /*执行用户程序*/
|
||
}
|
||
|
||
break;
|
||
case 0x1E: // wifi发的东西
|
||
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
void boot_ReceiveHdl()
|
||
{
|
||
uint32_t crcCal, i;
|
||
|
||
uint8_t crcGet[4];
|
||
uint32_t packageNO;
|
||
if (rx1_frame_OK)
|
||
{
|
||
switch (rx1_buff[4])
|
||
{
|
||
|
||
case 0x10: //已进入升级模式
|
||
get_package_buf[5] = 0x01; //回复OK
|
||
CRC_usart1send(send_start_buf, 6);
|
||
break;
|
||
case 0x11: //包头数据
|
||
//获取版本号
|
||
version[0] = rx1_buff[5];
|
||
version[1] = rx1_buff[6];
|
||
version[2] = rx1_buff[7];
|
||
version[3] = rx1_buff[8]; // 2022change
|
||
//更新请求帧的版本号
|
||
// get_package_buf[5] = version[0];
|
||
// get_package_buf[6] = version[1];
|
||
// get_package_buf[7] = version[2];
|
||
// get_package_buf[8] = version[3];//2022change
|
||
//获取bin字节数
|
||
packagesSize = (uint32_t)(rx1_buff[12]) << 24 | (uint32_t)(rx1_buff[11]) << 16 | (uint32_t)(rx1_buff[10]) << 8 | rx1_buff[9];
|
||
page_flashErase(); //擦除需要占用的flash空间
|
||
FlashPtr = FLASH_APP_ADDR; //从新地址开始启动
|
||
current_package = 0; //当前数据包从0开始
|
||
lastFrameCnt = 0;
|
||
upgrade_hand_flg = 0x01; //开始获取包标志位
|
||
wifi_connect_flg = 1; //通讯连接上
|
||
break;
|
||
case 0x12: //升级包数据
|
||
//获取当前包序号
|
||
packageNO = (uint32_t)(rx1_buff[8]) << 24 | (uint32_t)(rx1_buff[7]) << 16 | (uint32_t)(rx1_buff[6]) << 8 | rx1_buff[5];
|
||
//获取CRC
|
||
crcGet[0] = rx1_buff[rx1count - 4];
|
||
crcGet[1] = rx1_buff[rx1count - 3];
|
||
crcGet[2] = rx1_buff[rx1count - 2];
|
||
crcGet[3] = rx1_buff[rx1count - 1];
|
||
|
||
crcCal = OPENBL_CRC32_MPEG_2(rx1_buff, rx1count - 4);
|
||
if ((*(__IO uint32_t *)crcGet == crcCal) && (packageNO == current_package)) // CRC校验合格、包序号正确
|
||
{
|
||
for (i = 0; i < BinPerFrameSize; i++)
|
||
{
|
||
flash_array[i] = rx1_buff[9 + i];
|
||
}
|
||
|
||
upgrade_hand_flg = 0x02; //开始写入flash
|
||
if ((rx1count - 13 + current_package) >= packagesSize) //判断最后一帧多少字节
|
||
{
|
||
lastFrameCnt = rx1count - 13;
|
||
if (lastFrameCnt < BinPerFrameSize)
|
||
{
|
||
memset(&flash_array[lastFrameCnt], 0xff, BinPerFrameSize - lastFrameCnt);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
upgrade_hand_flg = 0x01; //开始获取包标志位--重新开始获取
|
||
get_package_buf[5] = 0x02; //回复重新获取
|
||
}
|
||
LED_B = 0;
|
||
delay_ms(10);
|
||
LED_B = 1;
|
||
break;
|
||
case 0xff: //
|
||
NVIC_SystemReset();
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
rx1count = 0;
|
||
rx1_frame_OK = 0;
|
||
}
|
||
}
|
||
|
||
void USART1_IRQHandler(void) //串口1中断服务程序--WIFI
|
||
{
|
||
static uint8_t rece_step = 0;
|
||
static uint16_t templen = 0;
|
||
uint8_t receive;
|
||
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
|
||
{
|
||
receive = USART_ReceiveData(USART1); //(USART1->DR); //读取接收到的数据
|
||
rx1_buff[rx1count++] = receive;
|
||
if (rx1_frame_OK == 1) //没处理完再发就丢弃
|
||
{
|
||
USART_ReceiveData(USART1);
|
||
return;
|
||
}
|
||
switch (rece_step)
|
||
{
|
||
case 0:
|
||
if (receive == 0xa5)
|
||
{
|
||
rece_step = 1;
|
||
rx1count = 1;
|
||
}
|
||
else
|
||
rx1count = 0;
|
||
break;
|
||
case 1:
|
||
if (receive == 0x5a)
|
||
{
|
||
|
||
rx1_buff[0] = 0xa5;
|
||
rx1_buff[1] = 0x5a;
|
||
rx1count = 2;
|
||
rece_step = 2;
|
||
}
|
||
else
|
||
{
|
||
if (receive == 0xA5)
|
||
{
|
||
rece_step = 1;
|
||
rx1count = 1;
|
||
}
|
||
else
|
||
rece_step = 0;
|
||
}
|
||
break;
|
||
|
||
case 2:
|
||
if (rx1count >= 4)
|
||
{
|
||
templen = (uint16_t)(rx1_buff[3]) << 8 | rx1_buff[2];
|
||
|
||
rece_step = 3;
|
||
}
|
||
break;
|
||
case 3:
|
||
if ((templen >= rx2_buffsize) || rx1count >= rx2_buffsize)
|
||
{
|
||
rece_step = 0;
|
||
rx1count = 0;
|
||
}
|
||
else if (rx1count >= (4 + templen))
|
||
{
|
||
rx1_frame_OK = 1;
|
||
rece_step = 0;
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|