Job_SignsPads/STM32/Code/STM32-IAP/Application/app.c
2025-04-22 10:29:37 +08:00

377 lines
8.8 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.

#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;
}
}
}