20230731_XiaoFuZi_emb/ZheDaXiaoFuZiBoot/Src/Usr/App/XfzApp.c

175 lines
5.9 KiB
C
Raw Normal View History

#include "McuBspSys.h"
#include "McuW25Q64JvssiqDrv.h"
#include "McuBspSpi.h"
#include "McuBspGpio.h"
#include "McuBspFlash.h"
#include <string.h>
#include <stdio.h>
/* 关于升级的部分定义 */
#define MCU_TASK_FLASH_UPDATTE_FLAG_ADDRESS 0x222000 // 升级标志位存储空间
#define MCU_TASK_FLASH_UPDATTE_SIZE_ADDRESS 0x222004 // 升级文件大小存储空间
/* 程序1的保存地址 */
#define MCU_TASK_PROGRAM1_START_ADDR 0x000000
#define MCU_TASK_PROGRAM1_END_ADDR 0x07ffff
#define MCU_TASK_PROGRAM1_MAX 0x080000
#define DISABLE_INT() __set_PRIMASK(1) /* 禁止全局终端 */
#define ENABLE_INT() __set_PRIMASK(0) /* 使能全局变量 */
#define APP_ADDR 0x8010000 // 应用程序的APP地址
static uint32_t gMcuTaskFlashUpdateProgramFlag = 1; // 升级标志位
static uint64_t gMcuTaskFlashUpdateProgramSize = 0; // 升级文件大小
static W25Q64JVSSIQ_OBJ gFlashObj = {0};
static void MainDelayUs(uint32_t period);
static void MainFlashSpiCs(uint8_t flag);
static unsigned char MainFlashReadWrite(uint8_t Data);
static void McuTaskXfzBootLoaderPrep(void);
static void McuTaskXfzBootLoader(void);
static void McuTaskXfzJumpToApp(void);
int main(void)
{
/* 初始化系统 */
McuBspSysInit();
McuTaskXfzBootLoaderPrep();
McuTaskXfzBootLoader();
McuTaskXfzJumpToApp();
}
static void McuTaskXfzBootLoaderPrep(void)
{
/* 打开LED灯 */
McuBspGpioInit(GPIOE, GPIO_PIN_3, GPIO_MODE_OUTPUT_PP, GPIO_SPEED_FREQ_LOW, GPIO_PULLDOWN, 0, NULL);
McuBspGpioSetLevel(GPIOE, GPIO_PIN_3, MCU_BSP_GPIO_OUT_HIGH);
/* 初始化FLASH */
McuBspSpiInit(MCU_BSP_SPI3_ID);
gFlashObj.SpiCs = MainFlashSpiCs;
gFlashObj.SpiWriteReadByte = MainFlashReadWrite;
gFlashObj.DelayUs = MainDelayUs;
W25Q64_Init(&gFlashObj);
/* 获取升级标志位 */
W25Q64_ReadBytes(&gFlashObj, MCU_TASK_FLASH_UPDATTE_FLAG_ADDRESS, (uint8_t *)(&gMcuTaskFlashUpdateProgramFlag), sizeof(gMcuTaskFlashUpdateProgramFlag));
if (1 != gMcuTaskFlashUpdateProgramFlag) {
gMcuTaskFlashUpdateProgramFlag = 0;
gMcuTaskFlashUpdateProgramSize = 0;
} else {
/* 获取升级文件大小 */
W25Q64_ReadBytes(&gFlashObj, MCU_TASK_FLASH_UPDATTE_SIZE_ADDRESS, (uint8_t *)(&gMcuTaskFlashUpdateProgramSize), sizeof(gMcuTaskFlashUpdateProgramSize));
if (gMcuTaskFlashUpdateProgramSize == 0 || gMcuTaskFlashUpdateProgramSize >= 458752) { // 448KB
gMcuTaskFlashUpdateProgramSize = 0;
gMcuTaskFlashUpdateProgramFlag = 0;
}
}
}
static void McuTaskXfzBootLoader(void)
{
uint32_t i = 0;
uint64_t data = 0;
if (gMcuTaskFlashUpdateProgramFlag == 1) {
/* 插除应用程序的flash */
while (-1 == McuBspFlashErase(ADDR_FLASH_PAGE_32, ((ADDR_FLASH_PAGE_255 - ADDR_FLASH_PAGE_32) / FLASH_PAGE_SIZE) + 1)) {
}
/* 读取FLASH */
for (i = 0; i < (gMcuTaskFlashUpdateProgramSize / 8); i++) {
data = 0;
if (0 > W25Q64_ReadBytes(&gFlashObj, MCU_TASK_PROGRAM1_START_ADDR + 8 * i, (unsigned char *)&data, 8)) {
// /* 重启 */
// __set_FAULTMASK(1);//关闭所有中断
// NVIC_SystemReset();//复位函数
}
if (0 > McuBspFlashWrite64(ADDR_FLASH_PAGE_32 + i * 8, data)) {
// /* 重启 */
// __set_FAULTMASK(1);//关闭所有中断
// NVIC_SystemReset();//复位函数
}
}
data = 0;
if (i * 8 < gMcuTaskFlashUpdateProgramSize) {
if (0 > W25Q64_ReadBytes(&gFlashObj, MCU_TASK_PROGRAM1_START_ADDR + 8 * i, (unsigned char *)&data, gMcuTaskFlashUpdateProgramSize - (i * 8))) {
// /* 重启 */
// __set_FAULTMASK(1);//关闭所有中断
// NVIC_SystemReset();//复位函数
}
if (0 > McuBspFlashWrite64(ADDR_FLASH_PAGE_32 + i * 8, data)) {
// /* 重启 */
// __set_FAULTMASK(1);//关闭所有中断
// NVIC_SystemReset();//复位函数
}
}
/* 把Flash的标志位清空 */
gMcuTaskFlashUpdateProgramFlag = 0;
W25Q64_WriteBytes(&gFlashObj, MCU_TASK_FLASH_UPDATTE_FLAG_ADDRESS, (uint8_t *)(&gMcuTaskFlashUpdateProgramFlag), sizeof(gMcuTaskFlashUpdateProgramFlag));
}
}
/* 跳转到应用程序 */
static void McuTaskXfzJumpToApp(void)
{
uint32_t i = 0;
void (*SysJumpToApp)(void); // 声明一个函数指针
__IO uint32_t AppAddr = APP_ADDR; // APP地址
/* 反向初始化使用的外设 */
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_3); // 回复led灯的初始状态
McuBspSpiDeInit(MCU_BSP_SPI3_ID);
/* 设置所有时钟到默认状态 */
HAL_RCC_DeInit();
/* 关闭滴答定时器,回复到默认值 */
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
/* 关闭全局中断 */
DISABLE_INT();
/* 关闭所有中断,清除所有中断挂起标志 */
for(i = 0; i < 8; i++) {
NVIC->ICER[i] = 0xFFFFFFFF;
NVIC->ICPR[i] = 0xFFFFFFFF;
}
/* 使能全局中断 */
ENABLE_INT();
/* 设置SysJumpToApp为终端服务函数入口地址首地址是MSP地址+4是复位中断服务程序地址 */
SysJumpToApp = (void (*)(void))(*((uint32_t *)(AppAddr + 4)));
/* 设置主堆栈指针 */
__set_MSP(*((uint32_t *)AppAddr));
/* 设置为特权级模式SP使用MSP指针 */
__set_CONTROL(0);
/* 进行跳转 */
SysJumpToApp();
while (1) {
}
}
static void MainDelayUs(uint32_t period)
{
uint32_t i = 35; // 35 = 72 / 2 -1;
while (period) {
while (i) {
i--;
}
period--;
i = 35;
}
}
static void MainFlashSpiCs(uint8_t flag)
{
McuBspSpiCs(MCU_BSP_SPI3_ID, flag);
}
/* Flash发送 */
static unsigned char MainFlashReadWrite(uint8_t Data)
{
return McuBspSpiReadWriteByte(MCU_BSP_SPI3_ID, Data);
}