feat(cproject): 移除CAN DMA相关代码并优化编译配置
- 移除了CAN模块中的DMA相关代码,包括can_dma_init函数、 DMA中断处理函数以及相关的全局变量和头文件包含 - 更新了项目构建配置,将优化级别从balanced改为size以减小 固件体积 - 添加了-fno-exceptions和-fno-rtti编译选项以进一步优化代码 - 升级了GD32C10x_DFP包版本至1.5.0 - 调整了OTA跳转逻辑,增加了更安全的中断和外设关闭处理 - 修复了Flash写入时的重复包处理逻辑,增加错误标志清理机制 - 将AES加密算法中的gf_mul函数标记为noinline属性
This commit is contained in:
+43
-10
@@ -156,9 +156,6 @@ void OTAHandler::process() {
|
||||
ota_time = 0; // 重置计时器
|
||||
static u8 zero[1] = {0};
|
||||
CAN0_transmiter.CANFD_AsyncSend(CANFD_OTA_WAIT_ID, 0, zero);
|
||||
#if DEBUG_OTA
|
||||
printf("OTA status:%d\r\n", ota_state);
|
||||
#endif
|
||||
delay_1ms(10);
|
||||
return;
|
||||
} else {
|
||||
@@ -224,9 +221,11 @@ bool validateApplication() {
|
||||
void OTAHandler::jumpToApplication() {
|
||||
#if DEBUG_OTA
|
||||
printf("try jump to app\r\n");
|
||||
#endif
|
||||
if (!validateApplication()) {
|
||||
return;
|
||||
}
|
||||
#if DEBUG_OTA
|
||||
printf("jumping1\r\n");
|
||||
#endif
|
||||
fmc_unlock();
|
||||
@@ -234,10 +233,18 @@ void OTAHandler::jumpToApplication() {
|
||||
OTA_SET(n_APP_LATEST_EN_ADDR, OTA_AVAL); // 设置APP为激活
|
||||
fmc_lock();
|
||||
|
||||
/* 1. 关闭 SysTick:VTOR 重指到 APP 后若 SysTick 仍在跑,
|
||||
* 下一拍会打进 APP 尚未就绪的 SysTick_Handler → 硬错误。 */
|
||||
SysTick->CTRL = 0U;
|
||||
SysTick->VAL = 0U;
|
||||
|
||||
/* 2. 关闭并清除所有 NVIC 中断:ICER 只禁能,ICPR 清挂起,
|
||||
* 否则 OTA 期间残留的 CAN RX 挂起会在 APP 使能中断瞬间误触发。 */
|
||||
for (int i = 0; i < 8; i++) {
|
||||
NVIC->ICER[i] = 0xFFFFFFFF;
|
||||
NVIC->ICPR[i] = 0xFFFFFFFF;
|
||||
}
|
||||
// 2. 重置外设(特别是CAN,防止冲突)
|
||||
// 重置外设(特别是CAN,防止冲突)
|
||||
can_deinit(CAN0);
|
||||
|
||||
// 3. 重置系统时钟到默认状态
|
||||
@@ -260,6 +267,8 @@ void OTAHandler::jumpToApplication() {
|
||||
#endif
|
||||
// 5. 设置中断向量表偏移到应用程序起始地址
|
||||
SCB->VTOR = APPLATEST_START_ADDR;
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
// 6. 设置MSP并跳转
|
||||
uint32_t msp_value = *(__IO uint32_t *)APPLATEST_START_ADDR;
|
||||
@@ -271,8 +280,13 @@ void OTAHandler::jumpToApplication() {
|
||||
reset_handler);
|
||||
#endif
|
||||
__set_MSP(msp_value);
|
||||
__DSB();
|
||||
__ISB();
|
||||
// 在跳转前清除复位标志
|
||||
rcu_all_reset_flag_clear();
|
||||
/* 确保全局中断使能:APP 的 Reset_Handler 不会碰 PRIMASK,
|
||||
* 若 BOOT 侧遗留 PRIMASK=1,APP 将永远收不到中断。 */
|
||||
__enable_irq();
|
||||
// 7. 跳转
|
||||
app_entry();
|
||||
|
||||
@@ -340,25 +354,44 @@ void OTAHandler::writeApplicationData(u32 offset, u8 *data, u32 size) {
|
||||
u8 *src = data;
|
||||
|
||||
// 32位对齐写入 - 处理完整的32位字
|
||||
for (; i <= size - 4; i += 4) {
|
||||
fmc_state = fmc_word_program(write_addr + i, *(u32 *)&src[i]);
|
||||
for (; i + 4 <= size; i += 4) {
|
||||
u32 word = *(u32 *)&src[i];
|
||||
volatile u32 *dst = (volatile u32 *)(write_addr + i);
|
||||
/* 重复包幂等:ACK 丢失导致 DCU 重发已写入的包时,目标已是目标值,
|
||||
* 直接跳过。否则对非擦除态 flash 编程会触发 PGERR。 */
|
||||
if (*dst == word) {
|
||||
continue;
|
||||
}
|
||||
/* 每字写前清 FMC 错误标志:一旦 PGERR/WPERR 残留,
|
||||
* fmc_ready_wait 会让后续所有 program 直接返回错误(雪崩)。 */
|
||||
fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_PGAERR | FMC_FLAG_WPERR);
|
||||
fmc_state = fmc_word_program(write_addr + i, word);
|
||||
if (fmc_state != FMC_READY) {
|
||||
printf("FMC_WRITE_ERROR\r\n");
|
||||
/* 清掉本次错误标志,避免毒化后续字的编程 */
|
||||
fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_PGAERR | FMC_FLAG_WPERR);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理剩余字节(如果有的话)
|
||||
// 处理剩余字节(size 非4的倍数时),未用字节补 0xFF(擦除态)
|
||||
if (i < size) {
|
||||
u32 word = 0;
|
||||
u32 word = 0xFFFFFFFF;
|
||||
u8 *word_ptr = (u8 *)&word;
|
||||
u32 remaining_bytes = size - i;
|
||||
|
||||
// 直接复制剩余字节到word变量
|
||||
for (u32 j = 0; j < remaining_bytes; j++) {
|
||||
word_ptr[j] = src[i + j];
|
||||
}
|
||||
|
||||
fmc_word_program(write_addr + i, word);
|
||||
volatile u32 *dst = (volatile u32 *)(write_addr + i);
|
||||
if (*dst != word) {
|
||||
fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_PGAERR | FMC_FLAG_WPERR);
|
||||
fmc_state = fmc_word_program(write_addr + i, word);
|
||||
if (fmc_state != FMC_READY) {
|
||||
printf("FMC_WRITE_ERROR\r\n");
|
||||
fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_PGAERR | FMC_FLAG_WPERR);
|
||||
}
|
||||
}
|
||||
}
|
||||
fmc_lock();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user