Files
GD32_BOOT/Robot_V2/main.cpp
T
cbb 46d4bfe8ef feat(bootloader): 实现APP延迟启动模式支持OTA请求检测
当APP可用但未激活时,系统现在会进入延迟启动模式,在指定时间内
监听CAN总线上的OTA请求。如果在此期间收到OTA请求,则进入OTA模式;
否则超时后自动跳转到APP。

新增配置参数APP_DELAY_BOOT_TIME用于设置延迟启动时间,默认为10秒。
在延迟期间,系统持续进行CAN通信检查和OTA心跳消息发送,确保能够
及时响应OTA更新请求。

此功能增强了系统的OTA更新灵活性,允许在启动过程中动态决定
是否进行固件更新而不是强制进入OTA模式。
2026-04-26 03:36:45 +08:00

111 lines
2.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"
#include "Can.h"
#include "config.h"
#include "gd32c10x.h"
#include "initial.h"
#include "sys/OTA.h"
#include "sys/initial.h"
#include "sys/systick.h"
#include <cstdio>
#include <gd32c10x_fmc.h>
extern CAN_transmiter CAN0_transmiter; // CAN初始化
BootloaderSystem sys;
extern OTAHandler ota;
void BootloaderSystem::initHardware() {
systick_config(); // 系统时钟初始化
USART0_init(); // 调试串口初始化
CAN0_transmiter.init();
check_sleep();
}
void BootloaderSystem::run() {
volatile u32 *flash_ptr = (volatile u32 *)n_APP_LATEST_EN_ADDR;
u32 app_enable = *flash_ptr;
flash_ptr = (volatile u32 *)n_APP_LATEST_CHECK_ADDR;
u32 app_check = *flash_ptr;
if (app_check == OTA_AVAL and
app_enable == OTA_AVAL) { // APP已确认且激活,直接进入
#if DEBUG_OTA
printf("Normal Mode\r\n");
#endif
// 正常模式:跳转到APP
ota.jumpToApplication();
} else if (app_check == OTA_AVAL and
app_enable == OTA_NOT_AVAL) { // APP可用但未激活,延迟进入APP
#if DEBUG_OTA
printf("Delay Boot Mode: APP available but not enabled, jumping in %d ms...\r\n", APP_DELAY_BOOT_TIME);
#endif
// 延迟启动模式:倒计时期间监听CAN,收到OTA请求则进入OTA模式
u32 delay_count = 0;
bool ota_requested = false;
while (delay_count < APP_DELAY_BOOT_TIME) {
// 检查CAN通信并处理接收到的消息
CAN0_transmiter.communication_check();
// 调用ota.process()发送心跳消息(IDAEL状态下会发送CANFD_OTA_WAIT_ID)
ota.process();
// 检查是否收到OTA请求
if (ota.isActive()) {
ota_requested = true;
break;
}
delay_count+=10;
}
if (ota_requested) {
#if DEBUG_OTA
printf("OTA request received during delay, entering OTA mode...\r\n");
#endif
// 收到OTA请求,进入OTA模式
while (1) {
CAN0_transmiter.communication_check();
ota.process();
}
} else {
#if DEBUG_OTA
printf("Delay timeout, jumping to APP...\r\n");
#endif
// 超时未收到OTA请求,跳转APP
ota.jumpToApplication();
}
} else { // APP无效,确认backup
volatile u32 *flash_ptr = (volatile u32 *)n_APP_BACKUP_AVAL_ADDR;
u32 back_aval = *flash_ptr;
flash_ptr = (volatile u32 *)n_APP_BACKUP_CHECK_ADDR;
u32 back_check = *flash_ptr;
if (back_check == OTA_AVAL and
back_aval == OTA_AVAL) { // backup已确认且激活,复制到主APP区域
#if DEBUG_OTA
printf("OTA Mode3\r\n");
#endif
CAN0_transmiter.sendBackup();
move_app_data(); // 恢复BACKUP
ota.jumpToApplication(); // 跳转到APP
} else { // backup无效,进入OTA模式
#if DEBUG_OTA
printf("OTA Mode4\r\n");
#endif
// OTA模式
while (1) {
CAN0_transmiter.communication_check();
ota.process();
}
}
}
}
int main(void) {
sys.initHardware();
// test_decrypt();
sys.run();
while (1)
; // 不应该执行到这里
}