refactor(protocol): 新增 comm_protocol 协议收发解析层,ble_transport 退化为纯传输
- 删除 protocol.h,帧定义和标定命令码统一迁入 comm_protocol.h - 新增 comm_protocol.c:上行组包(CoP/标定响应)、下行解析+msgq 分发 - ble_transport 剥离所有协议解析和参数 getter,仅保留字节收发+rx 回调注册 - main.c 初始化顺序:ble_transport → comm_protocol → adv_start → cal_init - 更新 README 架构图和项目结构表,补充标定流程章节 - 更新 BALANCE_BOARD_PROTOCOL.md 增加标定命令/响应帧格式文档
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
#pragma once
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/sys/crc.h>
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════
|
||||
* 帧常量
|
||||
* ═══════════════════════════════════════════════════════════════════ */
|
||||
|
||||
/* 双帧头比单字节魔数更容易在连续字节流里完成包起始判定 */
|
||||
#define PROTO_SYNC0 0xAAU
|
||||
#define PROTO_SYNC1 0x55U
|
||||
#define PROTO_TYPE_COP 0x01U /* 上行: 压力中心 (CoP) 帧 */
|
||||
#define PROTO_TYPE_ENCODER 0x02U /* 上行: 电机编码器帧(预留) */
|
||||
#define PROTO_TYPE_RESISTANCE 0x10U /* 下行: 阻力参数 (K, B, Tau) */
|
||||
#define PROTO_TYPE_SPOTTER 0x11U /* 下行: Spotter Mode 保护阈值 */
|
||||
#define PROTO_TYPE_HEARTBEAT 0x20U /* 下行: 心跳包 */
|
||||
#define PROTO_TYPE_CAL_CMD 0x30U /* 下行: 标定命令 */
|
||||
#define PROTO_TYPE_CAL_RESP 0x31U /* 上行: 标定响应 */
|
||||
|
||||
/* CoP flags 位定义 */
|
||||
#define COP_FLAG_FORCE_VALID 0x01U /* 总力 > 阈值,CoP 坐标有意义 */
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════
|
||||
* 帧结构定义
|
||||
* ═══════════════════════════════════════════════════════════════════ */
|
||||
|
||||
/* ─── 上行: CoP 帧 (11 bytes, 50 Hz) ───
|
||||
* [AA 55 01 flags cop_x(2) cop_y(2) force(2) crc]
|
||||
*/
|
||||
struct cop_frame_t {
|
||||
uint8_t sync0;
|
||||
uint8_t sync1;
|
||||
uint8_t type;
|
||||
uint8_t flags;
|
||||
int16_t cop_x;
|
||||
int16_t cop_y;
|
||||
int16_t force;
|
||||
uint8_t crc;
|
||||
} __attribute__((packed));
|
||||
|
||||
union cop_pkt_t {
|
||||
struct cop_frame_t frame;
|
||||
uint8_t bytes[sizeof(struct cop_frame_t)];
|
||||
};
|
||||
|
||||
/* ─── 上行: 电机编码器帧 (13 bytes, 预留) ───
|
||||
* [AA 55 02 flags cable_length(4) velocity(4) crc]
|
||||
*/
|
||||
struct encoder_frame_t {
|
||||
uint8_t sync0;
|
||||
uint8_t sync1;
|
||||
uint8_t type;
|
||||
uint8_t flags;
|
||||
float cable_length;
|
||||
float velocity;
|
||||
uint8_t crc;
|
||||
} __attribute__((packed));
|
||||
|
||||
union encoder_pkt_t {
|
||||
struct encoder_frame_t frame;
|
||||
uint8_t bytes[sizeof(struct encoder_frame_t)];
|
||||
};
|
||||
|
||||
/* ─── 下行: 阻力参数帧 (16 bytes) ───
|
||||
* [AA 55 10 K(4) B(4) Tau(4) crc]
|
||||
*/
|
||||
struct resistance_frame_t {
|
||||
uint8_t sync0;
|
||||
uint8_t sync1;
|
||||
uint8_t type;
|
||||
float K;
|
||||
float B;
|
||||
float Tau;
|
||||
uint8_t crc;
|
||||
} __attribute__((packed));
|
||||
|
||||
union resistance_pkt_t {
|
||||
struct resistance_frame_t frame;
|
||||
uint8_t bytes[sizeof(struct resistance_frame_t)];
|
||||
};
|
||||
|
||||
/* ─── 下行: Spotter Mode 帧 (9 bytes) ───
|
||||
* [AA 55 11 threshold(4) enable crc]
|
||||
*/
|
||||
struct spotter_frame_t {
|
||||
uint8_t sync0;
|
||||
uint8_t sync1;
|
||||
uint8_t type;
|
||||
float threshold;
|
||||
uint8_t enable;
|
||||
uint8_t crc;
|
||||
} __attribute__((packed));
|
||||
|
||||
union spotter_pkt_t {
|
||||
struct spotter_frame_t frame;
|
||||
uint8_t bytes[sizeof(struct spotter_frame_t)];
|
||||
};
|
||||
|
||||
/* ─── 下行: 心跳帧 (5 bytes, ~1 Hz) ───
|
||||
* [AA 55 20 counter crc]
|
||||
*/
|
||||
struct heartbeat_frame_t {
|
||||
uint8_t sync0;
|
||||
uint8_t sync1;
|
||||
uint8_t type;
|
||||
uint8_t counter;
|
||||
uint8_t crc;
|
||||
} __attribute__((packed));
|
||||
|
||||
union heartbeat_pkt_t {
|
||||
struct heartbeat_frame_t frame;
|
||||
uint8_t bytes[sizeof(struct heartbeat_frame_t)];
|
||||
};
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════
|
||||
* 标定子命令码 & 状态码
|
||||
* ═══════════════════════════════════════════════════════════════════ */
|
||||
|
||||
#define CAL_SUBCMD_START_L1 0x01U
|
||||
#define CAL_SUBCMD_TARE_CH 0x02U
|
||||
#define CAL_SUBCMD_GAIN_CH 0x03U
|
||||
#define CAL_SUBCMD_COMMIT_L1 0x04U
|
||||
#define CAL_SUBCMD_ABORT 0x05U
|
||||
#define CAL_SUBCMD_START_L2 0x10U
|
||||
#define CAL_SUBCMD_RECORD_GRID 0x11U
|
||||
#define CAL_SUBCMD_COMMIT_L2 0x12U
|
||||
#define CAL_SUBCMD_ERASE 0x20U
|
||||
#define CAL_SUBCMD_QUERY 0x21U
|
||||
|
||||
#define CAL_STATUS_OK 0x00U
|
||||
#define CAL_STATUS_ERR_STATE 0x01U
|
||||
#define CAL_STATUS_ERR_NVS 0x02U
|
||||
#define CAL_STATUS_ERR_PARAM 0x03U
|
||||
|
||||
/* ─── 下行: 标定命令帧 (10 bytes) ───
|
||||
* [AA 55 30 subcmd target param(4) crc]
|
||||
*/
|
||||
struct cal_cmd_frame_t {
|
||||
uint8_t sync0;
|
||||
uint8_t sync1;
|
||||
uint8_t type;
|
||||
uint8_t subcmd;
|
||||
uint8_t target;
|
||||
float param;
|
||||
uint8_t crc;
|
||||
} __attribute__((packed));
|
||||
|
||||
union cal_cmd_pkt_t {
|
||||
struct cal_cmd_frame_t frame;
|
||||
uint8_t bytes[sizeof(struct cal_cmd_frame_t)];
|
||||
};
|
||||
|
||||
/* ─── 上行: 标定响应帧 (14 bytes) ───
|
||||
* [AA 55 31 status subcmd data(8) crc]
|
||||
*/
|
||||
struct cal_resp_frame_t {
|
||||
uint8_t sync0;
|
||||
uint8_t sync1;
|
||||
uint8_t type;
|
||||
uint8_t status;
|
||||
uint8_t subcmd;
|
||||
uint8_t data[8];
|
||||
uint8_t crc;
|
||||
} __attribute__((packed));
|
||||
|
||||
union cal_resp_pkt_t {
|
||||
struct cal_resp_frame_t frame;
|
||||
uint8_t bytes[sizeof(struct cal_resp_frame_t)];
|
||||
};
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════
|
||||
* 下行消息队列 payload
|
||||
* ═══════════════════════════════════════════════════════════════════ */
|
||||
|
||||
struct comm_msg_resistance {
|
||||
float K, B, Tau;
|
||||
};
|
||||
|
||||
struct comm_msg_spotter {
|
||||
float threshold;
|
||||
bool enable;
|
||||
};
|
||||
|
||||
struct comm_msg_heartbeat {
|
||||
uint8_t counter;
|
||||
};
|
||||
|
||||
enum comm_msg_type {
|
||||
COMM_MSG_RESISTANCE,
|
||||
COMM_MSG_SPOTTER,
|
||||
COMM_MSG_HEARTBEAT,
|
||||
};
|
||||
|
||||
struct comm_msg {
|
||||
enum comm_msg_type type;
|
||||
union {
|
||||
struct comm_msg_resistance resistance;
|
||||
struct comm_msg_spotter spotter;
|
||||
struct comm_msg_heartbeat heartbeat;
|
||||
};
|
||||
};
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════
|
||||
* 协议层 API
|
||||
* ═══════════════════════════════════════════════════════════════════ */
|
||||
|
||||
/**
|
||||
* @brief 初始化协议层,注册 BLE 传输层收数据回调。
|
||||
*
|
||||
* 必须在 ble_transport_init() 之后调用。
|
||||
*
|
||||
* @retval 0 成功。
|
||||
*/
|
||||
int comm_protocol_init(void);
|
||||
|
||||
/**
|
||||
* @brief 组包并发送 CoP 上行帧。
|
||||
*
|
||||
* @param flags COP_FLAG_* 位组合。
|
||||
* @param cop_x 压力中心 X (cm)。
|
||||
* @param cop_y 压力中心 Y (cm)。
|
||||
* @param force 总力 (kg)。
|
||||
*/
|
||||
void comm_protocol_send_cop(uint8_t flags, int16_t cop_x, int16_t cop_y, int16_t force);
|
||||
|
||||
/**
|
||||
* @brief 组包并发送标定响应上行帧。
|
||||
*
|
||||
* @param status 结果状态码 (CAL_STATUS_*)。
|
||||
* @param subcmd 对应的子命令回显。
|
||||
* @param data 8 字节响应数据。
|
||||
*/
|
||||
void comm_protocol_send_cal_resp(uint8_t status, uint8_t subcmd, const uint8_t data[8]);
|
||||
|
||||
/**
|
||||
* @brief 获取下行消息队列指针,业务层通过 k_msgq_get() 消费。
|
||||
*
|
||||
* @return 指向内部 msgq 的指针。
|
||||
*/
|
||||
struct k_msgq *comm_protocol_get_msgq(void);
|
||||
Reference in New Issue
Block a user