feat(spi): 更新SPI命令v2,处理逻辑和项目配置
- 在cproject.yml中添加spi_link模块组和相关头文件路径 - 修改boot_request.cpp中的ACK响应机制,改用标准帧格式并优化CAN反馈处理 - 重构ping.cpp响应payload结构,包含版本信息、运行时间等16字节数据 - 添加systick.h依赖用于获取系统运行时间 - 优化启动bootloader流程,避免SPI中断阻塞问题
This commit is contained in:
@@ -90,6 +90,7 @@ static bool requestMagicValid(const uint8_t *data, uint8_t length)
|
||||
/** @brief 已写入 OTA 标志并等待软复位的挂起标志。 */
|
||||
volatile bool OtaBootRequest::s_rebootPending = false;
|
||||
volatile bool OtaBootRequest::s_bootRequestPending = false;
|
||||
volatile bool OtaBootRequest::s_spiFrozenForBoot = false;
|
||||
|
||||
/**
|
||||
* @brief 初始化进入 Bootloader 请求模块的运行态。
|
||||
@@ -98,6 +99,7 @@ void OtaBootRequest::init()
|
||||
{
|
||||
s_rebootPending = false;
|
||||
s_bootRequestPending = false;
|
||||
s_spiFrozenForBoot = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,6 +117,9 @@ bool OtaBootRequest::requestEnterBoot()
|
||||
|
||||
if(ok) {
|
||||
s_rebootPending = true;
|
||||
} else {
|
||||
/* 写配置页失败则永远停在 APP,ESP32 会看到持续 role=1 */
|
||||
/* 无 printf 依赖:由调用方 process() 恢复 SPI 后继续运行 */
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
@@ -127,6 +132,9 @@ bool OtaBootRequest::requestEnterBoot()
|
||||
void OtaBootRequest::requestEnterBootAsync()
|
||||
{
|
||||
s_bootRequestPending = true;
|
||||
/* 立即冻结 SPI 业务:不必等 process()(原依赖 1Hz 心跳,最坏拖 ~1s)。
|
||||
* 否则 ESP32 紧跟着 HELLO/0xC1 会继续进 processCommand,干扰擦页/复位。 */
|
||||
s_spiFrozenForBoot = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,13 +165,25 @@ bool OtaBootRequest::handleCanFrame(uint8_t channel, uint32_t id, const uint8_t
|
||||
*/
|
||||
void OtaBootRequest::process()
|
||||
{
|
||||
/* 异步处理 0xB0 请求:在主循环执行 Flash 操作(20-30ms),不阻塞 SPI ISR */
|
||||
/* 异步处理 0xB0:主循环写 Flash(可能擦页 20–30ms)。
|
||||
* 期间冻结 SPI 业务处理,避免 ESP32 紧跟着 HELLO/按铃读 打断擦写。 */
|
||||
if(s_bootRequestPending) {
|
||||
s_bootRequestPending = false;
|
||||
s_spiFrozenForBoot = true;
|
||||
nvic_irq_disable(SPI0_IRQn);
|
||||
nvic_irq_disable(EXTI10_15_IRQn);
|
||||
nvic_irq_disable(EXTI5_9_IRQn);
|
||||
|
||||
const bool ok = requestEnterBoot();
|
||||
if(ok) {
|
||||
s_rebootPending = true;
|
||||
if(!ok) {
|
||||
s_spiFrozenForBoot = false;
|
||||
nvic_irq_enable(SPI0_IRQn, 2U, 0U);
|
||||
nvic_irq_enable(EXTI10_15_IRQn, 1U, 1U);
|
||||
nvic_irq_enable(EXTI5_9_IRQn, CONFIG_IRQ_PREEMPT_SPI_USART, 1U);
|
||||
/* requestEnterBoot 失败时 s_rebootPending 仍为 false */
|
||||
return;
|
||||
}
|
||||
s_rebootPending = true;
|
||||
}
|
||||
|
||||
if(!s_rebootPending) {
|
||||
@@ -171,13 +191,14 @@ void OtaBootRequest::process()
|
||||
}
|
||||
|
||||
s_rebootPending = false;
|
||||
s_spiFrozenForBoot = true;
|
||||
nvic_irq_disable(SPI0_IRQn);
|
||||
nvic_irq_disable(EXTI10_15_IRQn);
|
||||
nvic_irq_disable(EXTI5_9_IRQn);
|
||||
|
||||
/* 方案A: 拉低 PB6 通知 ESP32 "即将复位"。
|
||||
* ESP32 通过 LOW→HIGH 序列识别 Bootloader 就绪:
|
||||
* APP 拉低 → 复位(μs级HIGH) → Bootloader极早拉低 → init完成释放HIGH
|
||||
* 20ms 延时确保 ESP32 5ms 轮询能捕获到 LOW 信号后再复位。 */
|
||||
gpio_bit_reset(CONFIG_SPI_READY_PORT, CONFIG_SPI_READY_PIN);
|
||||
|
||||
/* v2 DATA_READY: Boot 切换不再用 PB6 通知对端,
|
||||
* BOOT 起机后再由 HELLO role=boot 确认。 */
|
||||
/* SysTick 中断仍开,delayMs 可用;SPI 相关 IRQ 已关。 */
|
||||
SysTickTimer::delayMs(kRebootDelayMs);
|
||||
__disable_irq();
|
||||
NVIC_SystemReset();
|
||||
|
||||
Reference in New Issue
Block a user