Files
mcu-codegen-template/App/Core/app_boot.c
T

100 lines
3.3 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 app_boot.c
* @brief APP 启动流程(Bootloader 交接、时钟、IWDG、OTA 确认)
* @author cyWu <1917507415@qq.com>
* @date 2026.08.18
* @version V1.0.0
* @history
* - V1.0.0, 2026.08.18, cyWu, 从 main.c 拆出启动逻辑
******************************************************************************/
#include "app_boot.h"
#include "application.h"
#include "iwdg.h"
#include "ota_ab.h"
#include "main.h"
/**
* @brief 从 Bootloader 跳转过来后,重新打开全局中断
*
* Bootloader 跳转 APP 前会 __disable_irq(),且函数跳转不会复位芯片,
* 因此 PRIMASK 仍为 1(中断关)。APP 第一件事须 __enable_irq()
* 否则 SysTick / TIM6 / UART 等中断进不来,HAL_Delay、协议超时都会失效。
*/
static void app_boot_early_handover(void)
{
__enable_irq();
}
/**
* @brief 配置 APP 系统时钟(HSI → PLL → SYSCLK
*
* 与官网例程的差异:OscillatorType 故意不含 LSI。
* Bootloader 跳转前已启动 IWDGIWDG 运行期间 LSI 被硬件锁定关不掉;
* 若在此配置 LSI OFFHAL_RCC_OscConfig 会卡死等待 LSIRDY 变 0。
* LSI 由 IWDG 维持即可,APP 只配置 HSI/PLL 主时钟树。
*/
static void app_system_clock_config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/* 主时钟:HSI 24MHz → PLL,不含 LSI(见上方说明) */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_24MHz;
RCC_OscInitStruct.HSEState = RCC_HSE_OFF;
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
}
/**
* @brief 双备份 OTA:新固件启动确认后,上报一次升级完成(0x34)
*
* 须在 app_Init() 之后调用(依赖 uartInit / jbInit)。
* ota_boot_check_confirm() 已将 Flash 置为 IDLE0x34 仅为尽力通知云端;
* 发一次即可,丢帧由 jbSendOtaResult 内 SEND_MAX_NUM 重传兜底。
*/
static void app_boot_ota_report(void)
{
uint8_t ver[3];
if (!ota_boot_check_confirm())
{
return;
}
ver[0] = JB_MCU_SW_VERSION_MAJOR;
ver[1] = JB_MCU_SW_VERSION_MINOR;
ver[2] = JB_MCU_SW_VERSION_PATCH;
(void)jbSendOtaResult(JB_OK, ver);
appPrintf(LOG_NOTIC, "OTA upgrade complete reported\r\n");
}
void app_startup(void)
{
app_boot_early_handover();
HAL_Init();
iwdg_init();
app_system_clock_config();
app_Init();
app_boot_ota_report();
}