能用了

This commit is contained in:
2025-08-09 03:30:14 +08:00
parent f9f0d93b95
commit 62549172dd
9 changed files with 559 additions and 84 deletions

View File

@@ -11,6 +11,7 @@
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
typedef struct BSP_CAN_QueueNode {
BSP_CAN_t can; /* CAN通道 */
uint32_t can_id; /* 解析后的CAN ID */
osMessageQueueId_t queue; /* 消息队列ID */
uint8_t queue_size; /* 队列大小 */
@@ -26,9 +27,9 @@ static BSP_CAN_IdParser_t id_parser = NULL; /* ID解析器 */
/* Private function prototypes ---------------------------------------------- */
static BSP_CAN_t CAN_Get(CAN_HandleTypeDef *hcan);
static osMessageQueueId_t BSP_CAN_FindQueue(uint32_t can_id);
static int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size);
static int8_t BSP_CAN_DeleteIdQueue(uint32_t can_id);
static osMessageQueueId_t BSP_CAN_FindQueue(BSP_CAN_t can, uint32_t can_id);
static int8_t BSP_CAN_CreateIdQueue(BSP_CAN_t can, uint32_t can_id, uint8_t queue_size);
static int8_t BSP_CAN_DeleteIdQueue(BSP_CAN_t can, uint32_t can_id);
static void BSP_CAN_RxFifoCallback(void);
static BSP_CAN_FrameType_t BSP_CAN_GetFrameType(CAN_RxHeaderTypeDef *header);
static uint32_t BSP_CAN_DefaultIdParser(uint32_t original_id, BSP_CAN_FrameType_t frame_type);
@@ -50,10 +51,10 @@ static BSP_CAN_t CAN_Get(CAN_HandleTypeDef *hcan) {
* @brief 查找指定CAN ID的消息队列
* @note 调用前需要获取互斥锁
*/
static osMessageQueueId_t BSP_CAN_FindQueue(uint32_t can_id) {
static osMessageQueueId_t BSP_CAN_FindQueue(BSP_CAN_t can, uint32_t can_id) {
BSP_CAN_QueueNode_t *node = queue_list;
while (node != NULL) {
if (node->can_id == can_id) {
if (node->can == can && node->can_id == can_id) {
return node->queue;
}
node = node->next;
@@ -65,47 +66,37 @@ static osMessageQueueId_t BSP_CAN_FindQueue(uint32_t can_id) {
* @brief 创建指定CAN ID的消息队列
* @note 内部函数,已包含互斥锁保护
*/
static int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size) {
static int8_t BSP_CAN_CreateIdQueue(BSP_CAN_t can, uint32_t can_id, uint8_t queue_size) {
if (queue_size == 0) {
queue_size = BSP_CAN_DEFAULT_QUEUE_SIZE;
}
// 获取互斥锁
if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
return BSP_ERR_TIMEOUT;
}
// 检查是否已存在
BSP_CAN_QueueNode_t *node = queue_list;
while (node != NULL) {
if (node->can_id == can_id) {
if (node->can == can && node->can_id == can_id) {
osMutexRelease(queue_mutex);
return BSP_ERR; // 已存在
}
node = node->next;
}
// 创建新节点
BSP_CAN_QueueNode_t *new_node = (BSP_CAN_QueueNode_t *)BSP_Malloc(sizeof(BSP_CAN_QueueNode_t));
if (new_node == NULL) {
osMutexRelease(queue_mutex);
return BSP_ERR_NULL;
}
// 创建消息队列
new_node->queue = osMessageQueueNew(queue_size, sizeof(BSP_CAN_Message_t), NULL);
if (new_node->queue == NULL) {
BSP_Free(new_node);
osMutexRelease(queue_mutex);
return BSP_ERR;
}
// 初始化节点
new_node->can = can;
new_node->can_id = can_id;
new_node->queue_size = queue_size;
new_node->next = queue_list;
queue_list = new_node;
osMutexRelease(queue_mutex);
return BSP_OK;
}
@@ -114,32 +105,25 @@ static int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size) {
* @brief 删除指定CAN ID的消息队列
* @note 内部函数,已包含互斥锁保护
*/
static int8_t BSP_CAN_DeleteIdQueue(uint32_t can_id) {
// 获取互斥锁
static int8_t BSP_CAN_DeleteIdQueue(BSP_CAN_t can, uint32_t can_id) {
if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
return BSP_ERR_TIMEOUT;
}
BSP_CAN_QueueNode_t **current = &queue_list;
while (*current != NULL) {
if ((*current)->can_id == can_id) {
if ((*current)->can == can && (*current)->can_id == can_id) {
BSP_CAN_QueueNode_t *to_delete = *current;
*current = (*current)->next;
// 删除队列和节点
osMessageQueueDelete(to_delete->queue);
BSP_Free(to_delete);
osMutexRelease(queue_mutex);
return BSP_OK;
}
current = &(*current)->next;
}
osMutexRelease(queue_mutex);
return BSP_ERR; // 未找到
}
/**
* @brief 获取帧类型
*/
@@ -165,26 +149,15 @@ static uint32_t BSP_CAN_DefaultIdParser(uint32_t original_id, BSP_CAN_FrameType_
static void BSP_CAN_RxFifoCallback(void) {
CAN_RxHeaderTypeDef rx_header;
uint8_t rx_data[BSP_CAN_MAX_DLC];
// 遍历所有CAN接口处理FIFO0
for (int can_idx = 0; can_idx < BSP_CAN_NUM; can_idx++) {
CAN_HandleTypeDef *hcan = BSP_CAN_GetHandle((BSP_CAN_t)can_idx);
if (hcan == NULL) continue;
while (HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO0) > 0) {
if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, rx_data) == HAL_OK) {
// 获取原始ID
uint32_t original_id = (rx_header.IDE == CAN_ID_STD) ? rx_header.StdId : rx_header.ExtId;
// 获取帧类型
BSP_CAN_FrameType_t frame_type = BSP_CAN_GetFrameType(&rx_header);
// 解析ID
uint32_t parsed_id = BSP_CAN_ParseId(original_id, frame_type);
// 直接查找队列,不使用互斥锁(中断中快速执行)
osMessageQueueId_t queue = BSP_CAN_FindQueue(parsed_id);
osMessageQueueId_t queue = BSP_CAN_FindQueue((BSP_CAN_t)can_idx, parsed_id);
if (queue != NULL) {
BSP_CAN_Message_t msg = {0};
msg.frame_type = frame_type;
@@ -194,9 +167,7 @@ static void BSP_CAN_RxFifoCallback(void) {
if (rx_header.RTR == CAN_RTR_DATA) {
memcpy(msg.data, rx_data, rx_header.DLC);
}
msg.timestamp = HAL_GetTick(); // 添加时间戳
// 非阻塞发送,如果队列满了就丢弃
msg.timestamp = HAL_GetTick();
osMessageQueuePut(queue, &msg, 0, BSP_CAN_TIMEOUT_IMMEDIATE);
}
}
@@ -476,89 +447,70 @@ int8_t BSP_CAN_TransmitRemoteFrame(BSP_CAN_t can, BSP_CAN_RemoteFrame_t *frame)
return BSP_CAN_Transmit(can, format, frame->id, NULL, frame->dlc);
}
int8_t BSP_CAN_RegisterId(uint32_t can_id, uint8_t queue_size) {
int8_t BSP_CAN_RegisterId(BSP_CAN_t can, uint32_t can_id, uint8_t queue_size) {
if (!inited) {
return BSP_ERR_INITED;
}
return BSP_CAN_CreateIdQueue(can_id, queue_size);
return BSP_CAN_CreateIdQueue(can, can_id, queue_size);
}
int8_t BSP_CAN_UnregisterIdQueue(uint32_t can_id) {
int8_t BSP_CAN_UnregisterIdQueue(BSP_CAN_t can, uint32_t can_id) {
if (!inited) {
return BSP_ERR_INITED;
}
return BSP_CAN_DeleteIdQueue(can_id);
return BSP_CAN_DeleteIdQueue(can, can_id);
}
int8_t BSP_CAN_GetMessage(uint32_t can_id, BSP_CAN_Message_t *msg, uint32_t timeout) {
int8_t BSP_CAN_GetMessage(BSP_CAN_t can, uint32_t can_id, BSP_CAN_Message_t *msg, uint32_t timeout) {
if (!inited) {
return BSP_ERR_INITED;
}
if (msg == NULL) {
return BSP_ERR_NULL;
}
// 线程安全地查找队列
if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
return BSP_ERR_TIMEOUT;
}
osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id);
osMessageQueueId_t queue = BSP_CAN_FindQueue(can, can_id);
osMutexRelease(queue_mutex);
if (queue == NULL) {
return BSP_ERR_NO_DEV; // 队列不存在
return BSP_ERR_NO_DEV;
}
osStatus_t result = osMessageQueueGet(queue, msg, NULL, timeout);
return (result == osOK) ? BSP_OK : BSP_ERR;
}
int32_t BSP_CAN_GetQueueCount(uint32_t can_id) {
int32_t BSP_CAN_GetQueueCount(BSP_CAN_t can, uint32_t can_id) {
if (!inited) {
return -1;
}
// 线程安全地查找队列
if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
return -1;
}
osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id);
osMessageQueueId_t queue = BSP_CAN_FindQueue(can, can_id);
osMutexRelease(queue_mutex);
if (queue == NULL) {
return -1; // 队列不存在
return -1;
}
return (int32_t)osMessageQueueGetCount(queue);
}
int8_t BSP_CAN_FlushQueue(uint32_t can_id) {
int8_t BSP_CAN_FlushQueue(BSP_CAN_t can, uint32_t can_id) {
if (!inited) {
return BSP_ERR_INITED;
}
// 线程安全地查找队列
if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
return BSP_ERR_TIMEOUT;
}
osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id);
osMessageQueueId_t queue = BSP_CAN_FindQueue(can, can_id);
osMutexRelease(queue_mutex);
if (queue == NULL) {
return BSP_ERR_NO_DEV; // 队列不存在
return BSP_ERR_NO_DEV;
}
// 清空队列中的所有消息
BSP_CAN_Message_t temp_msg;
while (osMessageQueueGet(queue, &temp_msg, NULL, BSP_CAN_TIMEOUT_IMMEDIATE) == osOK) {
// 继续取出消息直到队列为
//
}
return BSP_OK;
}

View File

@@ -162,41 +162,46 @@ int8_t BSP_CAN_TransmitRemoteFrame(BSP_CAN_t can, BSP_CAN_RemoteFrame_t *frame);
/**
* @brief 注册 CAN ID 接收队列
* @param can CAN 枚举
* @param can_id 解析后的CAN ID
* @param queue_size 队列大小0使用默认值
* @return BSP_OK 成功,其他值失败
*/
int8_t BSP_CAN_RegisterId(uint32_t can_id, uint8_t queue_size);
int8_t BSP_CAN_RegisterId(BSP_CAN_t can, uint32_t can_id, uint8_t queue_size);
/**
* @brief 注销 CAN ID 接收队列
* @param can CAN 枚举
* @param can_id 解析后的CAN ID
* @return BSP_OK 成功,其他值失败
*/
int8_t BSP_CAN_UnregisterIdQueue(uint32_t can_id);
int8_t BSP_CAN_UnregisterIdQueue(BSP_CAN_t can, uint32_t can_id);
/**
* @brief 获取 CAN 消息(阻塞方式)
* @brief 获取 CAN 消息
* @param can CAN 枚举
* @param can_id 解析后的CAN ID
* @param msg 存储消息的结构体指针
* @param timeout 超时时间毫秒0为立即返回osWaitForever为永久等待
* @return BSP_OK 成功,其他值失败
*/
int8_t BSP_CAN_GetMessage(uint32_t can_id, BSP_CAN_Message_t *msg, uint32_t timeout);
int8_t BSP_CAN_GetMessage(BSP_CAN_t can, uint32_t can_id, BSP_CAN_Message_t *msg, uint32_t timeout);
/**
* @brief 获取指定ID队列中的消息数量
* @param can CAN 枚举
* @param can_id 解析后的CAN ID
* @return 消息数量,-1表示队列不存在
*/
int32_t BSP_CAN_GetQueueCount(uint32_t can_id);
int32_t BSP_CAN_GetQueueCount(BSP_CAN_t can, uint32_t can_id);
/**
* @brief 清空指定ID队列中的所有消息
* @param can CAN 枚举
* @param can_id 解析后的CAN ID
* @return BSP_OK 成功,其他值失败
*/
int8_t BSP_CAN_FlushQueue(uint32_t can_id);
int8_t BSP_CAN_FlushQueue(BSP_CAN_t can, uint32_t can_id);
/**
* @brief 注册ID解析器