ShipCentralControl/Loader_DTU/User/program.c

314 lines
8.9 KiB
C
Raw Normal View History

2025-04-03 15:56:06 +08:00
// <20><>Ϊmain.c<><63>STM32CubeMX<4D>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>
// <20><>ģ<EFBFBD><C4A3>ʵ<EFBFBD><CAB5><EFBFBD>û<EFBFBD><C3BB>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>main<69><6E><EFBFBD><EFBFBD>
#include "includes.h"
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>: 16K<36><4B><EFBFBD><EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define APROM_BASE (FLASH_BASE + 0x4000)
#pragma pack(push, 1)
// <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ͷ
typedef struct // size=12
{
unsigned short check; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>־, 0x55AA<41><41>ʾ<EFBFBD><CABE>Ч
unsigned upgrade_request : 1; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><D6BE>0-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
unsigned upgrade_result : 3; // <20><><EFBFBD><EFBFBD>ʧ<EFBFBD>ܱ<EFBFBD>־<EFBFBD><D6BE>0-<2D>ɹ<EFBFBD><C9B9><EFBFBD>1-ʧ<>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><E0B1A3>
unsigned encrypt_flag : 2; // <20><><EFBFBD>ܱ<EFBFBD>־<EFBFBD><D6BE> 0-<2D>޼<EFBFBD><DEBC>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><E0B1A3>
unsigned compress_flag : 2; // ѹ<><D1B9><EFBFBD><EFBFBD>־<EFBFBD><D6BE> 0-<2D><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD>1-<2D><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E0B1A3>
unsigned rerseved1 : 8; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ0xFF
unsigned long upgrade_length; // <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
unsigned rerseved2 : 8; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ0xFF
unsigned rerseved3 : 8; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ0xFF
unsigned short crc; // <20><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>crcУ<63><D0A3>
} TUpgradeHeader;
#pragma pack(pop)
// ʵ<><CAB5>stdout<75><74>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int stdout_putchar(int ch)
{
while(!(USART6->SR & LL_USART_SR_TXE));
USART6->DR = (uint8_t) ch;
return ch;
}
/* *************************************************************************
Bootloader<EFBFBD><EFBFBD>App<EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>
1. Bootloader<EFBFBD>ij<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD>СΪ8K<EFBFBD><EFBFBD>0x08000000~0x08001FFF)
App<EFBFBD>ij<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ں<EFBFBD><EFBFBD><EFBFBD><EFBFBD>0x08002000<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>СΪ0x3E000
2. Bootloader<EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD>СΪ2K<EFBFBD><EFBFBD>0x20000000~0x200007FF<EFBFBD><EFBFBD>
//App<70><70><EFBFBD>ڴ<EFBFBD><DAB4>ں<EFBFBD><DABA><EFBFBD><E6A3AC>0x20000800<30><30>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>СΪ0xF800
3. <EFBFBD><EFBFBD>Bootloader<EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD>App<EFBFBD><EFBFBD>
1<EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD>ȫ<EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>__disable_irq<EFBFBD><EFBFBD>
2<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹ<EFBFBD>ж<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD>
3<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϱ<EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϵı<EFBFBD>־λ<EFBFBD><EFBFBD><EFBFBD>
4) <EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD>ջ<EFBFBD><EFBFBD>MSP<EFBFBD><EFBFBD>ΪApp<EFBFBD>Ķ<EFBFBD>ջֵ
5<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD>App<EFBFBD>ij<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
4. <EFBFBD><EFBFBD>App<EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD>Bootloader<EFBFBD><EFBFBD>
ֱ<EFBFBD><EFBFBD>ϵͳ<EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Bootloader
5. Bootloader<EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Targetҳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IROM1<EFBFBD><EFBFBD>IRAM1
2<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Linkerҳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD>Use Memory Layout from Target Dialog<EFBFBD><EFBFBD>
6. App<EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Targetҳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IROM1<EFBFBD><EFBFBD>IRAM1
2<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Linkerҳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD>Use Memory Layout from Target Dialog<EFBFBD><EFBFBD>
3) <EFBFBD><EFBFBD>system_stm32l4xx.c<EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD><EFBFBD>´<EFBFBD><EFBFBD>
a. <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>VECT_TAB_OFFSET<EFBFBD><EFBFBD>Ϊ0x2000
b. <EFBFBD><EFBFBD>SystemInit<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>´<EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>__enable_irq)
7. <EFBFBD><EFBFBD>App<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD>Bootloader<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>3<EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD>δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΪҪ<EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>̫<EFBFBD>û<EFBFBD><EFBFBD>һһ<EFBFBD><EFBFBD><EFBFBD>
Ҳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΪFreeRTOS<EFBFBD><EFBFBD>CPU<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩģʽ<EFBFBD>ӹ<EFBFBD><EFBFBD>ˣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PSP<EFBFBD><EFBFBD>MSP<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD>ȡ<EFBFBD>
************************************************************************* */
// ʵ<>ִ<EFBFBD>Bootloader<65><72>ת<EFBFBD><D7AA>App
typedef void (*pIapFun_TypeDef)(void); //<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵IJ<CDB5><C4B2><EFBFBD>.
void JumpToEntry(uint32_t addr)
{
__disable_irq();
SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk);
__set_MSP(*(volatile uint32_t *) addr);
((pIapFun_TypeDef) (*(volatile uint32_t *) (addr + 4)))();
// <20><>Ӧ<EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
while(1)
PRINTF(".");
}
// <20><>Сƥ<D0A1><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
#define MIN_MATCH_LEN 3
#define MAX_MATCH_LEN (7 + MIN_MATCH_LEN) // =match_len+MIN_MATCH_LEN
// <20><>Flash<73><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
long Get_Bits(unsigned long baseAddr, long *byte_index, unsigned char *bit_index, unsigned char bit_count)
{
long word = 0;
unsigned char total_bits = 0;
unsigned short mask;
unsigned char bits;
static unsigned char buf;
while(total_bits < bit_count)
{
// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ַ<EFBFBD>
if(*bit_index == 0)
SFlash_BufferRead(baseAddr + *byte_index, &buf, 1);
bits = 8 - *bit_index;
if(bits > bit_count - total_bits)
bits = bit_count - total_bits;
mask = (1 << bits) - 1;
word |= ((buf >> (*bit_index)) & mask) << total_bits;
*bit_index += bits;
if(*bit_index == 8)
{
(*byte_index)++;
*bit_index = 0;
}
total_bits += bits;
}
return word;
}
// д<><D0B4><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Flash
void Put_Bytes(unsigned long *baseAddr, long *byte_index2, unsigned char *data_buf, unsigned char data_len)
{
unsigned char i = 0;
while(i < data_len)
{
Flash_rdBuf[*byte_index2] = data_buf[i];
(*byte_index2)++;
i++;
// <20><>һҳ<D2BB>˾<EFBFBD>д<EFBFBD><D0B4>Flash
if((*baseAddr + *byte_index2) % FLASH_ERASE_SIZE == 0)
{
Flash_BufferWrite(*baseAddr, Flash_rdBuf, *byte_index2);
if(!Flash_BufferVerify(*baseAddr, Flash_rdBuf, *byte_index2))
PRINTF("*** Verify flash failed at %08X, %d bytes\r\n", *baseAddr, *byte_index2);
*baseAddr += *byte_index2;
*byte_index2 = 0;
}
}
}
void Flash_Copy(uint32_t toAddr, uint32_t fromAddr, uint32_t nbytes)
{
uint32_t count, offset;
while(nbytes > 0)
{
// <20><><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3>ƫ<EFBFBD>ƣ<EFBFBD>ֻ<EFBFBD>е<EFBFBD>һҳ<D2BB>п<EFBFBD><D0BF>ܷ<EFBFBD>0<EFBFBD><30>
offset = toAddr % FLASH_ERASE_SIZE;
// <20><><EFBFBD><EFBFBD>һҳ<D2BB><D2B3>д<EFBFBD><D0B4><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
count = FLASH_ERASE_SIZE - offset;
if(count > nbytes)
count = nbytes;
// <20><><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SFlash_BufferRead(fromAddr, Flash_rdBuf, count);
// д<>뱾ҳ<EBB1BE><D2B3><EFBFBD><EFBFBD>
Flash_BufferWrite(toAddr, Flash_rdBuf, count);
if(!Flash_BufferVerify(toAddr, Flash_rdBuf, count))
PRINTF("*** Verify flash failed at %08X, %d bytes\r\n", toAddr, count);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һҳ
fromAddr += count;
toAddr += count;
nbytes -= count;
}
}
// <20><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void decompress_aprom(unsigned long toAddr, unsigned long fromAddr, long size)
{
long byte_index = 0;
unsigned char bit_index = 0;
long byte_index2 = 0;
unsigned char buf[MAX_MATCH_LEN];
unsigned long baseAddr = toAddr;
// ÿһ<C3BF><D2BB><EFBFBD><EFBFBD>¼Ϊ9/16bit<69><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>־λ<D6BE>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>ڶ<EFBFBD><DAB6>ֽ<EFBFBD>
while(byte_index < size - 1)
{
if(Get_Bits(fromAddr, &byte_index, &bit_index, 1) == 1)
{
// <20><>ȡһ<C8A1><D2BB><EFBFBD>ظ<EFBFBD><D8B8>ֽ<EFBFBD>
long offset = Get_Bits(fromAddr, &byte_index, &bit_index, 12) + 1;
unsigned char len = Get_Bits(fromAddr, &byte_index, &bit_index, 3) + MIN_MATCH_LEN;
if(offset <= byte_index2)
{
// ȫ<><C8AB><EFBFBD>ڻ<EFBFBD><DABB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD>δд<CEB4><D0B4>Flash
memmove(buf, Flash_rdBuf + byte_index2 - offset, len);
}
else if(offset - byte_index2 >= len)
{
// ȫ<><C8AB><EFBFBD><EFBFBD>Flash<73><68>
Flash_BufferRead(baseAddr - (offset - byte_index2), buf, len);
}
else
{
// ǰ<>沿<EFBFBD><E6B2BF><EFBFBD><EFBFBD>Flash
Flash_BufferRead(baseAddr - (offset - byte_index2), buf, offset - byte_index2);
// <20><><EFBFBD>沿<EFBFBD><E6B2BF><EFBFBD>ڻ<EFBFBD><DABB><EFBFBD><EFBFBD><EFBFBD>
memmove(buf + (offset - byte_index2), Flash_rdBuf, len - (offset - byte_index2));
}
Put_Bytes(&baseAddr, &byte_index2, buf, len);
}
else
{
// <20><>ȡһ<C8A1><D2BB>ԭʼ<D4AD>ֽ<EFBFBD>
buf[0] = Get_Bits(fromAddr, &byte_index, &bit_index, 8);
Put_Bytes(&baseAddr, &byte_index2, buf, 1);
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һҳ<D2BB><D2B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(byte_index2 > 0)
{
Flash_BufferWrite(baseAddr, Flash_rdBuf, byte_index2);
if(!Flash_BufferVerify(baseAddr, Flash_rdBuf, byte_index2))
PRINTF("*** Verify flash failed at %08X, %d bytes\r\n", baseAddr, byte_index2);
}
}
uint8_t Flash_apBuf[FLASH_ERASE_SIZE] = {0};
//#define _COPY_SFLASH_TO_APROM_
// <20><>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>main()<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void main_task(void *argument)
{
TUpgradeHeader upHeader = {0};
uint32_t nbytes, fromAddr, toAddr;
SFlash_Open();
#ifndef _COPY_SFLASH_TO_APROM_
SFlash_BufferRead(SFLASH_UPGRADE_BASE, (uint8_t *) &upHeader, sizeof(upHeader));
if(upHeader.check == 0x55AA && upHeader.upgrade_request == 1
&& do_crc_16(0, (uint8_t *) &upHeader, sizeof(upHeader)) == 0
&& do_sflash_crc(SFLASH_UPGRADE_BASE + sizeof(upHeader), upHeader.upgrade_length) == 0)
#endif
{
// <20><>ѹ
PRINTF("\r\nDecompress upgrade package ...\r\n");
HAL_FLASH_Unlock();
#ifndef _COPY_SFLASH_TO_APROM_
if(!upHeader.compress_flag)
Flash_Copy(APROM_BASE, SFLASH_UPGRADE_BASE + sizeof(upHeader), upHeader.upgrade_length - 2);
else
decompress_aprom(APROM_BASE, SFLASH_UPGRADE_BASE + sizeof(upHeader), upHeader.upgrade_length - 2);
#else
nbytes = 50 * 1024;
fromAddr = SFLASH_UPGRADE_BASE;
toAddr = APROM_BASE;
while(nbytes > 0)
{
// <20><><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SFlash_BufferRead(fromAddr, Flash_rdBuf, FLASH_ERASE_SIZE);
// д<>뱾ҳ<EBB1BE><D2B3><EFBFBD><EFBFBD>
Flash_BufferWrite(toAddr, Flash_rdBuf, FLASH_ERASE_SIZE);
if(!Flash_BufferVerify(toAddr, Flash_rdBuf, FLASH_ERASE_SIZE))
PRINTF("*** Verify flash failed at %08X, %d bytes\r\n", toAddr, FLASH_ERASE_SIZE);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һҳ
fromAddr += FLASH_ERASE_SIZE;
toAddr += FLASH_ERASE_SIZE;
nbytes -= FLASH_ERASE_SIZE;
}
PRINTF("Verify ...\r\n");
nbytes = 50 * 1024;
fromAddr = SFLASH_UPGRADE_BASE;
toAddr = APROM_BASE;
while(nbytes > 0)
{
// <20><><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SFlash_BufferRead(fromAddr, Flash_rdBuf, FLASH_ERASE_SIZE);
Flash_BufferRead(toAddr, Flash_apBuf, FLASH_ERASE_SIZE);
if(memcmp(Flash_apBuf, Flash_rdBuf, FLASH_ERASE_SIZE) != 0)
{
PRINTF("data mismatch on 0x%x\r\n", toAddr);
break;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һҳ
fromAddr += FLASH_ERASE_SIZE;
toAddr += FLASH_ERASE_SIZE;
nbytes -= FLASH_ERASE_SIZE;
}
PRINTF("OK.\r\n");
#endif
HAL_FLASH_Lock();
#ifndef _COPY_SFLASH_TO_APROM_
SFlash_UnlockBPR();
upHeader.upgrade_request = 0;
SFlash_BufferWrite(SFLASH_UPGRADE_BASE, (uint8_t *) &upHeader, sizeof(upHeader));
if(!SFlash_BufferVerify(SFLASH_UPGRADE_BASE, (uint8_t *) &upHeader, sizeof(upHeader)))
PRINTF("*** Verify SFlash failed at %08X, %d bytes\r\n", SFLASH_UPGRADE_BASE, sizeof(upHeader));
#endif
}
PRINTF("\r\nJump to APROM ...\r\n");
while(!(USART6->SR & LL_USART_SR_TC));
JumpToEntry(APROM_BASE);
// <20><>Ӧ<EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
while(1)
PRINTF(".");
}