refactor(main): 移除ota_mutex.h全局变量并重构ESP32 OTA互斥锁管理
- 将全局变量g_esp32OtaMutex和g_esp32OtaOccupied内聚到Esp32OtaCore类中 - 通过Esp32OtaCore::initMutex()方法初始化互斥锁替代原main.cpp中的全局初始化 - 重构HealthMonitor中WiFi连接状态管理,推送连接状态到本地成员而非直接查询 - 优化OtaCoordinator中const方法的线程安全实现,移除不必要的const_cast转换 - 封装OtaRelay的队列访问器,提供getDispatchQueue()和getResultQueue()方法 - 解决BLE与WiFi之间的横向耦合问题,通过OtaCoordinator进行射频共存管理 - 移除transport/spi_master.cpp中的CANFD接口实现到独立的canfd_bridge模块 - 优化BLE OTA中ESP32会话的幂等性和新会话处理逻辑 BREAKING CHANGE: 移除了ota_mutex.h全局头文件,相关功能迁移至Esp32OtaCore类中管理
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* canfd_bridge.cpp - CANFD 3通道通信桥接实现(M4: 从 SpiMaster 提取)
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "canfd_bridge.h"
|
||||
#include "spi_master.h"
|
||||
|
||||
/**
|
||||
* @brief 发送一帧 CANFD 数据,可选等待并读取响应。
|
||||
* 通过 SpiMaster 的公共 syncTransfer() 完成 SPI 传输。
|
||||
* 注意: syncTransfer 内部会加 SPI 互斥锁,FreeRTOS mutex 为递归锁故安全。
|
||||
*/
|
||||
int canFdSend(can_channel_t channel, uint32_t ext_id,
|
||||
const uint8_t *data, uint8_t dlc,
|
||||
uint8_t *recv_buf, uint8_t recv_max,
|
||||
uint32_t timeout_ms)
|
||||
{
|
||||
if (channel >= CAN_CHANNEL_MAX || dlc > CAN_MAX_DLC || !data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t tx_buf[72];
|
||||
size_t tx_len = 0;
|
||||
|
||||
tx_buf[tx_len++] = (uint8_t)(channel & CAN_CHANNEL_MASK);
|
||||
tx_buf[tx_len++] = (uint8_t)((ext_id >> 24) & 0xFF);
|
||||
tx_buf[tx_len++] = (uint8_t)((ext_id >> 16) & 0xFF);
|
||||
tx_buf[tx_len++] = (uint8_t)((ext_id >> 8) & 0xFF);
|
||||
tx_buf[tx_len++] = (uint8_t)(ext_id & 0xFF);
|
||||
memcpy(&tx_buf[tx_len], data, dlc);
|
||||
tx_len += dlc;
|
||||
|
||||
esp_err_t ret = SpiMaster::instance().syncTransfer(
|
||||
0, tx_buf, tx_len, recv_buf, recv_max, timeout_ms);
|
||||
if (ret != ESP_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int)recv_max;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 发送一帧无需响应的 CANFD 数据。
|
||||
*/
|
||||
int canFdSendNoReply(can_channel_t channel, uint32_t ext_id,
|
||||
const uint8_t *data, uint8_t dlc)
|
||||
{
|
||||
if (channel >= CAN_CHANNEL_MAX || dlc > CAN_MAX_DLC || !data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t tx_buf[72];
|
||||
size_t tx_len = 0;
|
||||
|
||||
tx_buf[tx_len++] = (uint8_t)(channel & CAN_CHANNEL_MASK);
|
||||
tx_buf[tx_len++] = (uint8_t)((ext_id >> 24) & 0xFF);
|
||||
tx_buf[tx_len++] = (uint8_t)((ext_id >> 16) & 0xFF);
|
||||
tx_buf[tx_len++] = (uint8_t)((ext_id >> 8) & 0xFF);
|
||||
tx_buf[tx_len++] = (uint8_t)(ext_id & 0xFF);
|
||||
memcpy(&tx_buf[tx_len], data, dlc);
|
||||
tx_len += dlc;
|
||||
|
||||
esp_err_t ret = SpiMaster::instance().send(0, tx_buf, tx_len);
|
||||
if (ret != ESP_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* canfd_bridge.h - CANFD 3通道通信桥接(M4: 从 SpiMaster 提取)
|
||||
*
|
||||
* 封装 CANFD 帧格式构建 + SPI 传输,与 SpiMaster 的 OTA 协议职责解耦。
|
||||
* 通过 SpiMaster 的公共 SPI 接口完成底层传输。
|
||||
*/
|
||||
#ifndef CANFD_BRIDGE_H
|
||||
#define CANFD_BRIDGE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// ============================================================
|
||||
// CANFD 帧格式(3通道)
|
||||
// [通道编号: 1B] [扩展帧ID: 4B BE] [数据: 1~64B]
|
||||
// ============================================================
|
||||
#define CAN_EXTENDED_ID_BITS (29) ///< CAN 扩展帧 ID 位数
|
||||
#define CAN_MAX_DLC (64) ///< 最大数据长度
|
||||
#define CAN_CHANNEL_MASK (0x03) ///< 通道号掩码 (0~2)
|
||||
|
||||
// 通道定义
|
||||
typedef enum {
|
||||
CAN_CHANNEL_0 = 0,
|
||||
CAN_CHANNEL_1 = 1,
|
||||
CAN_CHANNEL_2 = 2,
|
||||
CAN_CHANNEL_MAX = 3,
|
||||
} can_channel_t;
|
||||
|
||||
// CANFD 帧结构
|
||||
typedef struct {
|
||||
can_channel_t channel; ///< CAN 通道 (0~2)
|
||||
uint32_t ext_id; ///< 扩展帧 ID (29bit, Big-Endian 存储)
|
||||
uint8_t data[CAN_MAX_DLC]; ///< CAN 数据负载 (最大 64 字节)
|
||||
uint8_t dlc; ///< 数据长度 (1~64)
|
||||
} can_frame_t;
|
||||
|
||||
/**
|
||||
* @brief 发送一帧 CANFD 数据,可选等待并读取响应。
|
||||
* 内部通过 SpiMaster 的公共 SPI 接口完成传输。
|
||||
* @param channel CAN 通道编号(0~2)。
|
||||
* @param ext_id 扩展帧 ID(29 位)。
|
||||
* @param data CAN 数据负载。
|
||||
* @param dlc 数据长度。
|
||||
* @param recv_buf 接收数据缓冲区(可为 nullptr)。
|
||||
* @param recv_max 接收缓冲区最大长度。
|
||||
* @param timeout_ms 超时时间(毫秒)。
|
||||
* @return 成功时返回接收数据长度,失败返回 -1。
|
||||
*/
|
||||
int canFdSend(can_channel_t channel, uint32_t ext_id,
|
||||
const uint8_t *data, uint8_t dlc,
|
||||
uint8_t *recv_buf, uint8_t recv_max,
|
||||
uint32_t timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief 发送一帧无需响应的 CANFD 数据。
|
||||
* @param channel CAN 通道编号(0~2)。
|
||||
* @param ext_id 扩展帧 ID(29 位)。
|
||||
* @param data CAN 数据负载。
|
||||
* @param dlc 数据长度。
|
||||
* @return 成功返回 0,失败返回 -1。
|
||||
*/
|
||||
int canFdSendNoReply(can_channel_t channel, uint32_t ext_id,
|
||||
const uint8_t *data, uint8_t dlc);
|
||||
|
||||
#endif // CANFD_BRIDGE_H
|
||||
@@ -14,10 +14,12 @@
|
||||
#include "driver/spi_master.h"
|
||||
#include "soc/spi_struct.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "spi_master.h"
|
||||
#include "monitor/debug_log.h"
|
||||
|
||||
|
||||
static constexpr size_t kSpiTransferMaxBytes = 256U;
|
||||
|
||||
// ============================================================
|
||||
@@ -724,83 +726,7 @@ esp_err_t SpiMaster::transferWithRetry(uint8_t cmd, const uint8_t *payload,
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// CANFD 接口
|
||||
// ============================================================
|
||||
/**
|
||||
* @brief 发送一帧 CANFD 数据,可选等待并读取响应内容。
|
||||
* @param channel CAN 通道编号(0~2)。
|
||||
* @param ext_id 扩展帧 ID(29 位)。
|
||||
* @param data CAN 数据负载。
|
||||
* @param dlc 数据长度。
|
||||
* @param recv_buf 接收数据缓冲区。
|
||||
* @param recv_max 接收缓冲区最大长度。
|
||||
* @param timeout_ms 超时时间(毫秒)。
|
||||
* @return 成功时返回接收数据长度,失败返回 -1。
|
||||
*/
|
||||
int SpiMaster::canSend(can_channel_t channel, uint32_t ext_id,
|
||||
const uint8_t *data, uint8_t dlc,
|
||||
uint8_t *recv_buf, uint8_t recv_max,
|
||||
uint32_t timeout_ms)
|
||||
{
|
||||
LockGuard lock(m_mutex);
|
||||
if (channel >= CAN_CHANNEL_MAX || dlc > CAN_MAX_DLC || !data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t tx_buf[72];
|
||||
size_t tx_len = 0;
|
||||
|
||||
tx_buf[tx_len++] = (uint8_t)(channel & CAN_CHANNEL_MASK);
|
||||
tx_buf[tx_len++] = (uint8_t)((ext_id >> 24) & 0xFF);
|
||||
tx_buf[tx_len++] = (uint8_t)((ext_id >> 16) & 0xFF);
|
||||
tx_buf[tx_len++] = (uint8_t)((ext_id >> 8) & 0xFF);
|
||||
tx_buf[tx_len++] = (uint8_t)(ext_id & 0xFF);
|
||||
memcpy(&tx_buf[tx_len], data, dlc);
|
||||
tx_len += dlc;
|
||||
|
||||
esp_err_t ret = syncTransferUnlocked(0, tx_buf, tx_len, recv_buf, recv_max, timeout_ms);
|
||||
if (ret != ESP_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int)recv_max;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 发送一帧无需响应的 CANFD 数据。
|
||||
* @param channel CAN 通道编号(0~2)。
|
||||
* @param ext_id 扩展帧 ID(29 位)。
|
||||
* @param data CAN 数据负载。
|
||||
* @param dlc 数据长度。
|
||||
* @return 成功返回 0,失败返回 -1。
|
||||
*/
|
||||
int SpiMaster::canSendNoReply(can_channel_t channel, uint32_t ext_id,
|
||||
const uint8_t *data, uint8_t dlc)
|
||||
{
|
||||
LockGuard lock(m_mutex);
|
||||
if (channel >= CAN_CHANNEL_MAX || dlc > CAN_MAX_DLC || !data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t tx_buf[72];
|
||||
size_t tx_len = 0;
|
||||
|
||||
tx_buf[tx_len++] = (uint8_t)(channel & CAN_CHANNEL_MASK);
|
||||
tx_buf[tx_len++] = (uint8_t)((ext_id >> 24) & 0xFF);
|
||||
tx_buf[tx_len++] = (uint8_t)((ext_id >> 16) & 0xFF);
|
||||
tx_buf[tx_len++] = (uint8_t)((ext_id >> 8) & 0xFF);
|
||||
tx_buf[tx_len++] = (uint8_t)(ext_id & 0xFF);
|
||||
memcpy(&tx_buf[tx_len], data, dlc);
|
||||
tx_len += dlc;
|
||||
|
||||
esp_err_t ret = sendUnlocked(0, tx_buf, tx_len);
|
||||
if (ret != ESP_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
// CANFD 接口已迁移至 transport/canfd_bridge.cpp(M4 解耦)
|
||||
|
||||
// ============================================================
|
||||
// 无锁内部版本实现
|
||||
|
||||
@@ -30,30 +30,7 @@
|
||||
#define SPI_OTA_RSP_WAIT (0x81)
|
||||
#define SPI_OTA_RSP_ERROR (0x82)
|
||||
|
||||
// ============================================================
|
||||
// CANFD 帧格式(3通道)
|
||||
// [通道编号: 1B] [扩展帧ID: 4B BE] [数据: 1~64B]
|
||||
// 长度自动识别,无需发送 DLC
|
||||
// ============================================================
|
||||
#define CAN_EXTENDED_ID_BITS (29) // CAN 扩展帧 ID 位数
|
||||
#define CAN_MAX_DLC (64) // 最大数据长度
|
||||
#define CAN_CHANNEL_MASK (0x03) // 通道号掩码 (0~2)
|
||||
|
||||
// 通道定义
|
||||
typedef enum {
|
||||
CAN_CHANNEL_0 = 0,
|
||||
CAN_CHANNEL_1 = 1,
|
||||
CAN_CHANNEL_2 = 2,
|
||||
CAN_CHANNEL_MAX = 3,
|
||||
} can_channel_t;
|
||||
|
||||
// CANFD 帧结构
|
||||
typedef struct {
|
||||
can_channel_t channel; // CAN 通道 (0~2)
|
||||
uint32_t ext_id; // 扩展帧 ID (29bit, Big-Endian 存储)
|
||||
uint8_t data[CAN_MAX_DLC]; // CAN 数据负载 (最大 64 字节)
|
||||
uint8_t dlc; // 数据长度 (1~64)
|
||||
} can_frame_t;
|
||||
// CANFD 类型已迁移至 transport/canfd_bridge.h(M4 解耦)
|
||||
|
||||
// GD32 版本信息(从 APP PING 响应解析)
|
||||
typedef struct {
|
||||
@@ -122,19 +99,7 @@ public:
|
||||
size_t payload_len, uint8_t *recv_buf,
|
||||
size_t recv_len, int max_retries);
|
||||
|
||||
// ============================================================
|
||||
// CANFD 接口
|
||||
// ============================================================
|
||||
|
||||
/** @brief 发送一帧 CANFD 数据,可选等待并读取响应内容。 */
|
||||
int canSend(can_channel_t channel, uint32_t ext_id,
|
||||
const uint8_t *data, uint8_t dlc,
|
||||
uint8_t *recv_buf, uint8_t recv_max,
|
||||
uint32_t timeout_ms);
|
||||
|
||||
/** @brief 发送一帧无需响应的 CANFD 数据。 */
|
||||
int canSendNoReply(can_channel_t channel, uint32_t ext_id,
|
||||
const uint8_t *data, uint8_t dlc);
|
||||
// ── CANFD 接口已迁移至 transport/canfd_bridge.h(M4 解耦)──
|
||||
|
||||
/** @brief 获取 SPI 设备句柄(供外部状态查询)。 */
|
||||
spi_device_handle_t deviceHandle() const { return m_spiDevice; }
|
||||
|
||||
Reference in New Issue
Block a user