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:
+25
-15
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user