feat(ota): 修复备份APP区域恢复功能和OTA流程优化、启用BRS、减小延时

- 添加sendBackup方法用于在备份APP激活时发送确认消息
- 优化OTA跳转逻辑,在jumpToApplication中清除复位标志
- 修复move_app_data函数中数据源地址错误,从备份区域正确读取数据
- 在OTA流程中正确设置APP状态标志,确保应用验证状态管理

refactor(can): 清理调试代码和函数签名优化

- 移除调试用的printf语句和未使用的cstdio头文件
- 统一函数参数类型为u8和u32,提高代码一致性
- 优化CAN通信检查逻辑,移除冗余的调试输出

perf(ota): 优化OTA处理中的延时函数

- 将delay_1ms(1)改为delay_1us(100),提高延时精度
- 添加微秒级延时函数delay_1us实现
- 增加OTA超时时间从10秒到100秒

fix(ota): 修复OTA状态管理和错误处理

- 在各种错误情况下正确设置ota_state为OTA_STATE_IDLE
- 在eraseApplicationArea中正确初始化APP状态标志
- 添加CRC校验失败时的调试输出选项
- 修复数据包大小验证逻辑
This commit is contained in:
cbb
2026-01-07 23:14:15 +08:00
parent c7c4451d57
commit aefb7d4ee4
18 changed files with 1384 additions and 1328 deletions
+25 -15
View File
@@ -108,7 +108,7 @@ void OTAHandler::process() {
delay_1ms(10);
return;
} else {
delay_1ms(1);
delay_1us(100);
ota_time++;
}
@@ -126,8 +126,8 @@ void OTAHandler::process() {
if (if_checked == OTA_AVAL and if_aval == OTA_AVAL) {
OTA_SET(n_APP_LATEST_AVAL_ADDR,
OTA_AVAL); // 实际可用,设置APP为启用
jumpToApplication();
}
jumpToApplication();
}
}
bool validateApplication() {
@@ -218,7 +218,11 @@ void OTAHandler::jumpToApplication() {
printf("jumping5, MSP:0x%08X, Reset Handler:0x%08X\r\n", msp_value,
reset_handler);
#endif
__set_MSP(msp_value);
// 在跳转前清除复位标志
rcu_all_reset_flag_clear();
// 7. 跳转
app_entry();
@@ -234,6 +238,9 @@ void OTAHandler::jumpToApplication() {
* @retval 无
*/
void OTAHandler::eraseApplicationArea() {
OTA_SET(n_APP_LATEST_CHECK_ADDR, OTA_NOT_AVAL); // 设置APP为未确认
OTA_SET(n_APP_LATEST_EN_ADDR, OTA_NOT_AVAL); // 设置APP为未激活
OTA_SET(n_APP_LATEST_AVAL_ADDR, OTA_NOT_AVAL); // 设置APP为不可用
// 擦除APP区域
fmc_unlock();
@@ -338,6 +345,10 @@ void OTAHandler::handleOTAMessage(u32 id, u8 *data, u8 len) {
0) {
ota_error = OTA_ERROR_INVALID_CRC;
send_error_frame(OTA_ERROR_INVALID_CRC);
#if DEBUG_OTA
std::printf("CRC32 :%x,%x!\r\n", receive_dataCRC32[0],
calculated_dataCRC32[0]);
#endif
receive_packet_num -= 1;
} else {
// 写入Flash前验证数据
@@ -347,6 +358,7 @@ void OTAHandler::handleOTAMessage(u32 id, u8 *data, u8 len) {
OTA_PACKET_SIZE);
} else {
ota_error = OTA_ERROR_INVALID_SIZE;
ota_state = OTA_STATE_IDLE;
send_error_frame(OTA_ERROR_INVALID_SIZE);
}
}
@@ -374,11 +386,13 @@ void OTAHandler::handleOTAMessage(u32 id, u8 *data, u8 len) {
received_size = 0;
} else {
ota_error = OTA_ERROR_INVALID_SIZE;
ota_state = OTA_STATE_IDLE;
send_error_frame(OTA_ERROR_INVALID_SIZE);
return;
}
u8 send_data[6] = {0xBA, 0xC0, 0x00,
0x00, 0x00, 0x00}; // 确认开始传输
eraseApplicationArea();
// 发送接收包0请求
CAN0_transmiter.CANFD_AsyncSend(CANFD_OTA_ACK_ID, 6, send_data);
@@ -393,6 +407,7 @@ void OTAHandler::handleOTAMessage(u32 id, u8 *data, u8 len) {
} else {
ota_error = OTA_ERROR_INVALID_PACKET;
ota_state = OTA_STATE_IDLE;
send_error_frame(OTA_ERROR_INVALID_PACKET);
}
} else if (id == CANFD_OTA_REQ_ID) {
@@ -471,7 +486,7 @@ void OTAHandler::handleOTAMessage(u32 id, u8 *data, u8 len) {
// 验证失败 - 可能密钥错误或攻击
ota_error = OTA_ERROR_INVALID_KEY;
send_error_frame(OTA_ERROR_INVALID_KEY); // 验证失败
// reset_ota_state();
ota_state = OTA_STATE_IDLE;
return;
}
@@ -484,6 +499,7 @@ void OTAHandler::handleOTAMessage(u32 id, u8 *data, u8 len) {
} else {
// 其他握手异常
ota_error = OTA_ERROR_INVALID_HANDSHAKE;
ota_state = OTA_STATE_IDLE;
send_error_frame(OTA_ERROR_INVALID_HANDSHAKE);
return;
}
@@ -569,17 +585,16 @@ fmc_state_enum move_app_data() {
// 复制数据 - 按字(32位)进行复制以提高效率
uint32_t offset = 0;
uint32_t write_count = 0; // 记录实际写入的字数
const uint32_t *src_ptr = (const uint32_t *)APPLATEST_START_ADDR;
uint32_t *dst_ptr = (uint32_t *)APPLATEST_START_ADDR;
const uint32_t *src_ptr = (const uint32_t *)APPBACK_START_ADDR; // 从备份区域读取
// 预计算源数据的CRC,避免重复访问内存
crc_deinit();
crc_data_register_reset();
uint32_t src_crc = crc_block_data_calculate(
(uint32_t *)APPBACK_START_ADDR, APP_MAX_SIZE / 4);
uint32_t src_crc = crc_block_data_calculate((uint32_t *)APPBACK_START_ADDR,
APP_MAX_SIZE / 4);
while (offset < APP_MAX_SIZE) {
uint32_t src_data = src_ptr[offset / 4];
uint32_t src_data = src_ptr[offset / 4]; // 从备份区域读取数据
// 检查源地址是否为有效的Flash数据(非0xFFFFFFFF表示有数据)
if (src_data != 0xFFFFFFFF) {
@@ -588,7 +603,7 @@ fmc_state_enum move_app_data() {
FMC_FLAG_PGERR);
fmc_status =
fmc_word_program(APPLATEST_START_ADDR + offset, src_data);
fmc_word_program(APPLATEST_START_ADDR + offset, src_data); // 写入到最新APP区域
// 检查写入操作是否成功
if (fmc_status != FMC_READY) {
@@ -604,11 +619,6 @@ fmc_state_enum move_app_data() {
write_count++;
}
offset += 4;
// 每写入一定数量的数据后,喂狗一次
if ((offset % 4096) == 0) { // 每4KB喂狗一次
fwdgt_counter_reload();
}
}
fmc_lock();
@@ -710,4 +720,4 @@ void calculate_crc32_with_key(const uint8_t *key, const uint8_t *data,
output[1] = (uint8_t)(crc >> 8);
output[2] = (uint8_t)(crc >> 16);
output[3] = (uint8_t)(crc >> 24);
}
}