can支持自定义id解析了

This commit is contained in:
2025-08-07 04:40:31 +08:00
parent 3e49722616
commit 3159d3ae1a
38 changed files with 558 additions and 350 deletions

BIN
assets/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/User_code/bsp.zip Normal file

Binary file not shown.

View File

@@ -11,32 +11,34 @@
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
typedef struct BSP_CAN_QueueNode {
uint32_t can_id;
osMessageQueueId_t queue;
uint8_t queue_size;
struct BSP_CAN_QueueNode *next;
uint32_t can_id; /* 解析后的CAN ID */
osMessageQueueId_t queue; /* 消息队列ID */
uint8_t queue_size; /* 队列大小 */
struct BSP_CAN_QueueNode *next; /* 指向下一个节点的指针 */
} BSP_CAN_QueueNode_t;
/* Private variables -------------------------------------------------------- */
static BSP_CAN_QueueNode_t *g_can_queue_list = NULL;
static osMutexId_t g_can_queue_mutex = NULL;
static void (*g_can_callbacks[BSP_CAN_NUM][BSP_CAN_CB_NUM])(void);
static bool g_can_initialized = false;
static BSP_CAN_QueueNode_t *queue_list = NULL;
static osMutexId_t queue_mutex = NULL;
static void (*CAN_Callback[BSP_CAN_NUM][BSP_CAN_CB_NUM])(void);
static bool inited = false;
static BSP_CAN_IdParser_t id_parser = NULL; /* ID解析器 */
/* Private function prototypes ---------------------------------------------- */
static BSP_CAN_t BSP_CAN_GetInstance(CAN_HandleTypeDef *hcan);
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 void BSP_CAN_RxFifo0Handler(void);
static void BSP_CAN_RxFifo1Handler(void);
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);
/* Private functions -------------------------------------------------------- */
/**
* @brief 根据CAN句柄获取BSP_CAN实例
*/
static BSP_CAN_t BSP_CAN_GetInstance(CAN_HandleTypeDef *hcan) {
static BSP_CAN_t CAN_Get(CAN_HandleTypeDef *hcan) {
if (hcan == NULL) return BSP_CAN_ERR;
/* AUTO GENERATED CAN_GET */
@@ -49,7 +51,7 @@ static BSP_CAN_t BSP_CAN_GetInstance(CAN_HandleTypeDef *hcan) {
* @note 调用前需要获取互斥锁
*/
static osMessageQueueId_t BSP_CAN_FindQueue(uint32_t can_id) {
BSP_CAN_QueueNode_t *node = g_can_queue_list;
BSP_CAN_QueueNode_t *node = queue_list;
while (node != NULL) {
if (node->can_id == can_id) {
return node->queue;
@@ -69,15 +71,15 @@ static int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size) {
}
// 获取互斥锁
if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
return BSP_ERR_TIMEOUT;
}
// 检查是否已存在
BSP_CAN_QueueNode_t *node = g_can_queue_list;
BSP_CAN_QueueNode_t *node = queue_list;
while (node != NULL) {
if (node->can_id == can_id) {
osMutexRelease(g_can_queue_mutex);
osMutexRelease(queue_mutex);
return BSP_ERR; // 已存在
}
node = node->next;
@@ -86,7 +88,7 @@ static int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size) {
// 创建新节点
BSP_CAN_QueueNode_t *new_node = (BSP_CAN_QueueNode_t *)BSP_Malloc(sizeof(BSP_CAN_QueueNode_t));
if (new_node == NULL) {
osMutexRelease(g_can_queue_mutex);
osMutexRelease(queue_mutex);
return BSP_ERR_NULL;
}
@@ -94,17 +96,17 @@ static int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size) {
new_node->queue = osMessageQueueNew(queue_size, sizeof(BSP_CAN_Message_t), NULL);
if (new_node->queue == NULL) {
BSP_Free(new_node);
osMutexRelease(g_can_queue_mutex);
osMutexRelease(queue_mutex);
return BSP_ERR;
}
// 初始化节点
new_node->can_id = can_id;
new_node->queue_size = queue_size;
new_node->next = g_can_queue_list;
g_can_queue_list = new_node;
new_node->next = queue_list;
queue_list = new_node;
osMutexRelease(g_can_queue_mutex);
osMutexRelease(queue_mutex);
return BSP_OK;
}
@@ -114,11 +116,11 @@ static int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size) {
*/
static int8_t BSP_CAN_DeleteIdQueue(uint32_t can_id) {
// 获取互斥锁
if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
return BSP_ERR_TIMEOUT;
}
BSP_CAN_QueueNode_t **current = &g_can_queue_list;
BSP_CAN_QueueNode_t **current = &queue_list;
while (*current != NULL) {
if ((*current)->can_id == can_id) {
BSP_CAN_QueueNode_t *to_delete = *current;
@@ -128,20 +130,39 @@ static int8_t BSP_CAN_DeleteIdQueue(uint32_t can_id) {
osMessageQueueDelete(to_delete->queue);
BSP_Free(to_delete);
osMutexRelease(g_can_queue_mutex);
osMutexRelease(queue_mutex);
return BSP_OK;
}
current = &(*current)->next;
}
osMutexRelease(g_can_queue_mutex);
osMutexRelease(queue_mutex);
return BSP_ERR; // 未找到
}
/**
* @brief FIFO0接收处理函数
* @brief 获取帧类型
*/
static void BSP_CAN_RxFifo0Handler(void) {
static BSP_CAN_FrameType_t BSP_CAN_GetFrameType(CAN_RxHeaderTypeDef *header) {
if (header->RTR == CAN_RTR_REMOTE) {
return (header->IDE == CAN_ID_EXT) ? BSP_CAN_FRAME_EXT_REMOTE : BSP_CAN_FRAME_STD_REMOTE;
} else {
return (header->IDE == CAN_ID_EXT) ? BSP_CAN_FRAME_EXT_DATA : BSP_CAN_FRAME_STD_DATA;
}
}
/**
* @brief 默认ID解析器直接返回原始ID
*/
static uint32_t BSP_CAN_DefaultIdParser(uint32_t original_id, BSP_CAN_FrameType_t frame_type) {
(void)frame_type; // 避免未使用参数警告
return original_id;
}
/**
* @brief FIFO接收处理函数
*/
static void BSP_CAN_RxFifoCallback(void) {
CAN_RxHeaderTypeDef rx_header;
uint8_t rx_data[BSP_CAN_MAX_DLC];
@@ -152,59 +173,32 @@ static void BSP_CAN_RxFifo0Handler(void) {
while (HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO0) > 0) {
if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, rx_data) == HAL_OK) {
uint32_t can_id = (rx_header.IDE == CAN_ID_STD) ? rx_header.StdId : rx_header.ExtId;
// 获取原始ID
uint32_t original_id = (rx_header.IDE == CAN_ID_STD) ? rx_header.StdId : rx_header.ExtId;
// 线程安全地查找队列
if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) == osOK) {
osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id);
osMutexRelease(g_can_queue_mutex);
if (queue != NULL) {
BSP_CAN_Message_t msg;
msg.header = rx_header;
memcpy(msg.data, rx_data, BSP_CAN_MAX_DLC);
// 非阻塞发送,如果队列满了就丢弃
osMessageQueuePut(queue, &msg, 0, BSP_CAN_TIMEOUT_IMMEDIATE);
}
}
// 如果没有找到对应的队列或获取互斥锁超时,消息被直接丢弃
}
}
}
}
/**
* @brief FIFO1接收处理函数
*/
static void BSP_CAN_RxFifo1Handler(void) {
CAN_RxHeaderTypeDef rx_header;
uint8_t rx_data[BSP_CAN_MAX_DLC];
// 遍历所有CAN接口处理FIFO1
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_FIFO1) > 0) {
if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO1, &rx_header, rx_data) == HAL_OK) {
uint32_t can_id = (rx_header.IDE == CAN_ID_STD) ? rx_header.StdId : rx_header.ExtId;
// 获取帧类型
BSP_CAN_FrameType_t frame_type = BSP_CAN_GetFrameType(&rx_header);
// 线程安全地查找队列
if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) == osOK) {
osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id);
osMutexRelease(g_can_queue_mutex);
if (queue != NULL) {
BSP_CAN_Message_t msg;
msg.header = rx_header;
memcpy(msg.data, rx_data, BSP_CAN_MAX_DLC);
// 非阻塞发送,如果队列满了就丢弃
osMessageQueuePut(queue, &msg, 0, BSP_CAN_TIMEOUT_IMMEDIATE);
// 解析ID
uint32_t parsed_id = BSP_CAN_ParseId(original_id, frame_type);
// 直接查找队列,不使用互斥锁(中断中快速执行)
osMessageQueueId_t queue = BSP_CAN_FindQueue(parsed_id);
if (queue != NULL) {
BSP_CAN_Message_t msg = {0};
msg.frame_type = frame_type;
msg.original_id = original_id;
msg.parsed_id = parsed_id;
msg.dlc = rx_header.DLC;
if (rx_header.RTR == CAN_RTR_DATA) {
memcpy(msg.data, rx_data, rx_header.DLC);
}
msg.timestamp = HAL_GetTick(); // 添加时间戳
// 非阻塞发送,如果队列满了就丢弃
osMessageQueuePut(queue, &msg, 0, BSP_CAN_TIMEOUT_IMMEDIATE);
}
// 如果没有找到对应的队列或获取互斥锁超时,消息被直接丢弃
}
}
}
@@ -212,178 +206,165 @@ static void BSP_CAN_RxFifo1Handler(void) {
/* HAL Callback Functions --------------------------------------------------- */
void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX0_CPLT_CB] != NULL) {
g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX0_CPLT_CB]();
}
}
BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_CPLT_CB])
CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_CPLT_CB]();
}
}
void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX1_CPLT_CB] != NULL) {
g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX1_CPLT_CB]();
}
}
BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_CPLT_CB])
CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_CPLT_CB]();
}
}
void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX2_CPLT_CB] != NULL) {
g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX2_CPLT_CB]();
}
}
BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_CPLT_CB])
CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_CPLT_CB]();
}
}
void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX0_ABORT_CB] != NULL) {
g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX0_ABORT_CB]();
}
}
BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_ABORT_CB])
CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_ABORT_CB]();
}
}
void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX1_ABORT_CB] != NULL) {
g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX1_ABORT_CB]();
}
}
BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_ABORT_CB])
CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_ABORT_CB]();
}
}
void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX2_ABORT_CB] != NULL) {
g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX2_ABORT_CB]();
}
}
BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_ABORT_CB])
CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_ABORT_CB]();
}
}
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_MSG_PENDING_CB] != NULL) {
g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_MSG_PENDING_CB]();
}
}
BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_MSG_PENDING_CB])
CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_MSG_PENDING_CB]();
}
}
void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_FULL_CB] != NULL) {
g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_FULL_CB]();
}
}
BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_FULL_CB])
CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_FULL_CB]();
}
}
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_MSG_PENDING_CB] != NULL) {
g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_MSG_PENDING_CB]();
}
}
BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_MSG_PENDING_CB])
CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_MSG_PENDING_CB]();
}
}
void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_FULL_CB] != NULL) {
g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_FULL_CB]();
}
}
BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_FULL_CB])
CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_FULL_CB]();
}
}
void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_SLEEP_CB] != NULL) {
g_can_callbacks[bsp_can][BSP_CAN_SLEEP_CB]();
}
}
BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (CAN_Callback[bsp_can][HAL_CAN_SLEEP_CB])
CAN_Callback[bsp_can][HAL_CAN_SLEEP_CB]();
}
}
void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_WAKEUP_FROM_RX_MSG_CB] != NULL) {
g_can_callbacks[bsp_can][BSP_CAN_WAKEUP_FROM_RX_MSG_CB]();
}
}
BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (CAN_Callback[bsp_can][HAL_CAN_WAKEUP_FROM_RX_MSG_CB])
CAN_Callback[bsp_can][HAL_CAN_WAKEUP_FROM_RX_MSG_CB]();
}
}
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_ERROR_CB] != NULL) {
g_can_callbacks[bsp_can][BSP_CAN_ERROR_CB]();
}
}
BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) {
if (CAN_Callback[bsp_can][HAL_CAN_ERROR_CB])
CAN_Callback[bsp_can][HAL_CAN_ERROR_CB]();
}
}
/* Exported functions ------------------------------------------------------- */
int8_t BSP_CAN_Init(void) {
if (g_can_initialized) {
if (inited) {
return BSP_ERR_INITED;
}
// 清零回调函数数组
memset(g_can_callbacks, 0, sizeof(g_can_callbacks));
memset(CAN_Callback, 0, sizeof(CAN_Callback));
// 初始化ID解析器为默认解析器
id_parser = BSP_CAN_DefaultIdParser;
// 创建互斥锁
g_can_queue_mutex = osMutexNew(NULL);
if (g_can_queue_mutex == NULL) {
queue_mutex = osMutexNew(NULL);
if (queue_mutex == NULL) {
return BSP_ERR;
}
/* AUTO GENERATED CAN_INIT */
// 注册默认的接收中断处理函数
for (int can_idx = 0; can_idx < BSP_CAN_NUM; can_idx++) {
BSP_CAN_RegisterCallback((BSP_CAN_t)can_idx, BSP_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifo0Handler);
BSP_CAN_RegisterCallback((BSP_CAN_t)can_idx, BSP_CAN_RX_FIFO1_MSG_PENDING_CB, BSP_CAN_RxFifo1Handler);
}
g_can_initialized = true;
inited = true;
return BSP_OK;
}
int8_t BSP_CAN_DeInit(void) {
if (!g_can_initialized) {
if (!inited) {
return BSP_ERR;
}
// 删除所有队列
if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) == osOK) {
BSP_CAN_QueueNode_t *current = g_can_queue_list;
if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) == osOK) {
BSP_CAN_QueueNode_t *current = queue_list;
while (current != NULL) {
BSP_CAN_QueueNode_t *next = current->next;
osMessageQueueDelete(current->queue);
BSP_Free(current);
current = next;
}
g_can_queue_list = NULL;
osMutexRelease(g_can_queue_mutex);
queue_list = NULL;
osMutexRelease(queue_mutex);
}
// 删除互斥锁
if (g_can_queue_mutex != NULL) {
osMutexDelete(g_can_queue_mutex);
g_can_queue_mutex = NULL;
if (queue_mutex != NULL) {
osMutexDelete(queue_mutex);
queue_mutex = NULL;
}
// 清零回调函数数组
memset(g_can_callbacks, 0, sizeof(g_can_callbacks));
memset(CAN_Callback, 0, sizeof(CAN_Callback));
g_can_initialized = false;
// 重置ID解析器
id_parser = NULL;
inited = false;
return BSP_OK;
}
@@ -401,7 +382,7 @@ CAN_HandleTypeDef *BSP_CAN_GetHandle(BSP_CAN_t can) {
int8_t BSP_CAN_RegisterCallback(BSP_CAN_t can, BSP_CAN_Callback_t type,
void (*callback)(void)) {
if (!g_can_initialized) {
if (!inited) {
return BSP_ERR_INITED;
}
if (callback == NULL) {
@@ -414,19 +395,19 @@ int8_t BSP_CAN_RegisterCallback(BSP_CAN_t can, BSP_CAN_Callback_t type,
return BSP_ERR;
}
g_can_callbacks[can][type] = callback;
CAN_Callback[can][type] = callback;
return BSP_OK;
}
int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format,
uint32_t id, uint8_t *data, uint8_t dlc) {
if (!g_can_initialized) {
if (!inited) {
return BSP_ERR_INITED;
}
if (can >= BSP_CAN_NUM) {
return BSP_ERR;
}
if (data == NULL) {
if (data == NULL && format != BSP_CAN_FORMAT_STD_REMOTE && format != BSP_CAN_FORMAT_EXT_REMOTE) {
return BSP_ERR_NULL;
}
if (dlc > BSP_CAN_MAX_DLC) {
@@ -473,8 +454,30 @@ int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format,
return (result == HAL_OK) ? BSP_OK : BSP_ERR;
}
int8_t BSP_CAN_TransmitStdDataFrame(BSP_CAN_t can, BSP_CAN_StdDataFrame_t *frame) {
if (frame == NULL) {
return BSP_ERR_NULL;
}
return BSP_CAN_Transmit(can, BSP_CAN_FORMAT_STD_DATA, frame->id, frame->data, frame->dlc);
}
int8_t BSP_CAN_TransmitExtDataFrame(BSP_CAN_t can, BSP_CAN_ExtDataFrame_t *frame) {
if (frame == NULL) {
return BSP_ERR_NULL;
}
return BSP_CAN_Transmit(can, BSP_CAN_FORMAT_EXT_DATA, frame->id, frame->data, frame->dlc);
}
int8_t BSP_CAN_TransmitRemoteFrame(BSP_CAN_t can, BSP_CAN_RemoteFrame_t *frame) {
if (frame == NULL) {
return BSP_ERR_NULL;
}
BSP_CAN_Format_t format = frame->is_extended ? BSP_CAN_FORMAT_EXT_REMOTE : BSP_CAN_FORMAT_STD_REMOTE;
return BSP_CAN_Transmit(can, format, frame->id, NULL, frame->dlc);
}
int8_t BSP_CAN_RegisterId(uint32_t can_id, uint8_t queue_size) {
if (!g_can_initialized) {
if (!inited) {
return BSP_ERR_INITED;
}
@@ -482,7 +485,7 @@ int8_t BSP_CAN_RegisterId(uint32_t can_id, uint8_t queue_size) {
}
int8_t BSP_CAN_UnregisterIdQueue(uint32_t can_id) {
if (!g_can_initialized) {
if (!inited) {
return BSP_ERR_INITED;
}
@@ -490,7 +493,7 @@ int8_t BSP_CAN_UnregisterIdQueue(uint32_t can_id) {
}
int8_t BSP_CAN_GetMessage(uint32_t can_id, BSP_CAN_Message_t *msg, uint32_t timeout) {
if (!g_can_initialized) {
if (!inited) {
return BSP_ERR_INITED;
}
if (msg == NULL) {
@@ -498,12 +501,12 @@ int8_t BSP_CAN_GetMessage(uint32_t can_id, BSP_CAN_Message_t *msg, uint32_t time
}
// 线程安全地查找队列
if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
return BSP_ERR_TIMEOUT;
}
osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id);
osMutexRelease(g_can_queue_mutex);
osMutexRelease(queue_mutex);
if (queue == NULL) {
return BSP_ERR_NO_DEV; // 队列不存在
@@ -514,17 +517,17 @@ int8_t BSP_CAN_GetMessage(uint32_t can_id, BSP_CAN_Message_t *msg, uint32_t time
}
int32_t BSP_CAN_GetQueueCount(uint32_t can_id) {
if (!g_can_initialized) {
if (!inited) {
return -1;
}
// 线程安全地查找队列
if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
return -1;
}
osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id);
osMutexRelease(g_can_queue_mutex);
osMutexRelease(queue_mutex);
if (queue == NULL) {
return -1; // 队列不存在
@@ -534,17 +537,17 @@ int32_t BSP_CAN_GetQueueCount(uint32_t can_id) {
}
int8_t BSP_CAN_FlushQueue(uint32_t can_id) {
if (!g_can_initialized) {
if (!inited) {
return BSP_ERR_INITED;
}
// 线程安全地查找队列
if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
return BSP_ERR_TIMEOUT;
}
osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id);
osMutexRelease(g_can_queue_mutex);
osMutexRelease(queue_mutex);
if (queue == NULL) {
return BSP_ERR_NO_DEV; // 队列不存在
@@ -559,5 +562,33 @@ int8_t BSP_CAN_FlushQueue(uint32_t can_id) {
return BSP_OK;
}
int8_t BSP_CAN_RegisterIdParser(BSP_CAN_IdParser_t parser) {
if (!inited) {
return BSP_ERR_INITED;
}
if (parser == NULL) {
return BSP_ERR_NULL;
}
id_parser = parser;
return BSP_OK;
}
int8_t BSP_CAN_UnregisterIdParser(void) {
if (!inited) {
return BSP_ERR_INITED;
}
id_parser = BSP_CAN_DefaultIdParser;
return BSP_OK;
}
uint32_t BSP_CAN_ParseId(uint32_t original_id, BSP_CAN_FrameType_t frame_type) {
if (id_parser != NULL) {
return id_parser(original_id, frame_type);
}
return BSP_CAN_DefaultIdParser(original_id, frame_type);
}
/* USER CAN FUNCTIONS BEGIN */
/* USER CAN FUNCTIONS END */

View File

@@ -23,26 +23,27 @@ extern "C" {
typedef enum {
/* AUTO GENERATED BSP_CAN_NAME */
BSP_CAN_NUM,
BSP_CAN_ERR = 0xFF,
BSP_CAN_ERR,
} BSP_CAN_t;
typedef enum {
BSP_CAN_TX_MAILBOX0_CPLT_CB,
BSP_CAN_TX_MAILBOX1_CPLT_CB,
BSP_CAN_TX_MAILBOX2_CPLT_CB,
BSP_CAN_TX_MAILBOX0_ABORT_CB,
BSP_CAN_TX_MAILBOX1_ABORT_CB,
BSP_CAN_TX_MAILBOX2_ABORT_CB,
BSP_CAN_RX_FIFO0_MSG_PENDING_CB,
BSP_CAN_RX_FIFO0_FULL_CB,
BSP_CAN_RX_FIFO1_MSG_PENDING_CB,
BSP_CAN_RX_FIFO1_FULL_CB,
BSP_CAN_SLEEP_CB,
BSP_CAN_WAKEUP_FROM_RX_MSG_CB,
BSP_CAN_ERROR_CB,
BSP_CAN_CB_NUM
HAL_CAN_TX_MAILBOX0_CPLT_CB,
HAL_CAN_TX_MAILBOX1_CPLT_CB,
HAL_CAN_TX_MAILBOX2_CPLT_CB,
HAL_CAN_TX_MAILBOX0_ABORT_CB,
HAL_CAN_TX_MAILBOX1_ABORT_CB,
HAL_CAN_TX_MAILBOX2_ABORT_CB,
HAL_CAN_RX_FIFO0_MSG_PENDING_CB,
HAL_CAN_RX_FIFO0_FULL_CB,
HAL_CAN_RX_FIFO1_MSG_PENDING_CB,
HAL_CAN_RX_FIFO1_FULL_CB,
HAL_CAN_SLEEP_CB,
HAL_CAN_WAKEUP_FROM_RX_MSG_CB,
HAL_CAN_ERROR_CB,
BSP_CAN_CB_NUM,
} BSP_CAN_Callback_t;
/* CAN消息格式枚举 - 用于发送和接收消息时指定格式 */
typedef enum {
BSP_CAN_FORMAT_STD_DATA, /* 标准数据帧 */
BSP_CAN_FORMAT_EXT_DATA, /* 扩展数据帧 */
@@ -50,11 +51,48 @@ typedef enum {
BSP_CAN_FORMAT_EXT_REMOTE, /* 扩展远程帧 */
} BSP_CAN_Format_t;
/* CAN帧类型枚举 - 用于区分不同类型的CAN帧 */
typedef enum {
BSP_CAN_FRAME_STD_DATA, /* 标准数据帧 */
BSP_CAN_FRAME_EXT_DATA, /* 扩展数据帧 */
BSP_CAN_FRAME_STD_REMOTE, /* 标准远程帧 */
BSP_CAN_FRAME_EXT_REMOTE, /* 扩展远程帧 */
} BSP_CAN_FrameType_t;
/* CAN消息结构体 - 支持不同类型帧 */
typedef struct {
CAN_RxHeaderTypeDef header;
uint8_t data[BSP_CAN_MAX_DLC];
BSP_CAN_FrameType_t frame_type; /* 帧类型 */
uint32_t original_id; /* 原始ID未解析 */
uint32_t parsed_id; /* 解析后的实际ID */
uint8_t dlc; /* 数据长度 */
uint8_t data[BSP_CAN_MAX_DLC]; /* 数据 */
uint32_t timestamp; /* 时间戳(可选) */
} BSP_CAN_Message_t;
/* 标准数据帧结构 */
typedef struct {
uint32_t id; /* CAN ID */
uint8_t dlc; /* 数据长度 */
uint8_t data[BSP_CAN_MAX_DLC]; /* 数据 */
} BSP_CAN_StdDataFrame_t;
/* 扩展数据帧结构 */
typedef struct {
uint32_t id; /* 扩展CAN ID */
uint8_t dlc; /* 数据长度 */
uint8_t data[BSP_CAN_MAX_DLC]; /* 数据 */
} BSP_CAN_ExtDataFrame_t;
/* 远程帧结构 */
typedef struct {
uint32_t id; /* CAN ID */
uint8_t dlc; /* 请求的数据长度 */
bool is_extended; /* 是否为扩展帧 */
} BSP_CAN_RemoteFrame_t;
/* ID解析回调函数类型 */
typedef uint32_t (*BSP_CAN_IdParser_t)(uint32_t original_id, BSP_CAN_FrameType_t frame_type);
/* Exported functions prototypes -------------------------------------------- */
/**
@@ -98,9 +136,33 @@ int8_t BSP_CAN_RegisterCallback(BSP_CAN_t can, BSP_CAN_Callback_t type,
int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format,
uint32_t id, uint8_t *data, uint8_t dlc);
/**
* @brief 发送标准数据帧
* @param can CAN 枚举
* @param frame 标准数据帧指针
* @return BSP_OK 成功,其他值失败
*/
int8_t BSP_CAN_TransmitStdDataFrame(BSP_CAN_t can, BSP_CAN_StdDataFrame_t *frame);
/**
* @brief 发送扩展数据帧
* @param can CAN 枚举
* @param frame 扩展数据帧指针
* @return BSP_OK 成功,其他值失败
*/
int8_t BSP_CAN_TransmitExtDataFrame(BSP_CAN_t can, BSP_CAN_ExtDataFrame_t *frame);
/**
* @brief 发送远程帧
* @param can CAN 枚举
* @param frame 远程帧指针
* @return BSP_OK 成功,其他值失败
*/
int8_t BSP_CAN_TransmitRemoteFrame(BSP_CAN_t can, BSP_CAN_RemoteFrame_t *frame);
/**
* @brief 注册 CAN ID 接收队列
* @param can_id CAN ID
* @param can_id 解析后的CAN ID
* @param queue_size 队列大小0使用默认值
* @return BSP_OK 成功,其他值失败
*/
@@ -108,14 +170,14 @@ int8_t BSP_CAN_RegisterId(uint32_t can_id, uint8_t queue_size);
/**
* @brief 注销 CAN ID 接收队列
* @param can_id CAN ID
* @param can_id 解析后的CAN ID
* @return BSP_OK 成功,其他值失败
*/
int8_t BSP_CAN_UnregisterIdQueue(uint32_t can_id);
/**
* @brief 获取 CAN 消息(阻塞方式)
* @param can_id CAN ID
* @param can_id 解析后的CAN ID
* @param msg 存储消息的结构体指针
* @param timeout 超时时间毫秒0为立即返回osWaitForever为永久等待
* @return BSP_OK 成功,其他值失败
@@ -124,18 +186,39 @@ int8_t BSP_CAN_GetMessage(uint32_t can_id, BSP_CAN_Message_t *msg, uint32_t time
/**
* @brief 获取指定ID队列中的消息数量
* @param can_id CAN ID
* @param can_id 解析后的CAN ID
* @return 消息数量,-1表示队列不存在
*/
int32_t BSP_CAN_GetQueueCount(uint32_t can_id);
/**
* @brief 清空指定ID队列中的所有消息
* @param can_id CAN ID
* @param can_id 解析后的CAN ID
* @return BSP_OK 成功,其他值失败
*/
int8_t BSP_CAN_FlushQueue(uint32_t can_id);
/**
* @brief 注册ID解析器
* @param parser ID解析回调函数
* @return BSP_OK 成功,其他值失败
*/
int8_t BSP_CAN_RegisterIdParser(BSP_CAN_IdParser_t parser);
/**
* @brief 注销ID解析器
* @return BSP_OK 成功,其他值失败
*/
int8_t BSP_CAN_UnregisterIdParser(void);
/**
* @brief 解析CAN ID
* @param original_id 原始ID
* @param frame_type 帧类型
* @return 解析后的ID
*/
uint32_t BSP_CAN_ParseId(uint32_t original_id, BSP_CAN_FrameType_t frame_type);
/* USER CAN FUNCTIONS BEGIN */
/* USER CAN FUNCTIONS END */

View File

@@ -43,8 +43,8 @@ int8_t BSP_GPIO_RegisterCallback(uint16_t pin, void (*callback)(void)) {
return BSP_OK;
}
int8_t BSP_GPIO_EnableIRQ(uint16_t pin) {
switch (pin) {
int8_t BSP_GPIO_EnableIRQ(BSP_GPIO_t gpio) {
switch (gpio) {
/* AUTO GENERATED BSP_GPIO_ENABLE_IRQ */
default:
return BSP_ERR;
@@ -52,15 +52,14 @@ int8_t BSP_GPIO_EnableIRQ(uint16_t pin) {
return BSP_OK;
}
int8_t BSP_GPIO_DisableIRQ(uint16_t pin) {
switch (pin) {
int8_t BSP_GPIO_DisableIRQ(BSP_GPIO_t gpio) {
switch (gpio) {
/* AUTO GENERATED BSP_GPIO_DISABLE_IRQ */
default:
return BSP_ERR;
}
return BSP_OK;
}
int8_t BSP_GPIO_WritePin(BSP_GPIO_t gpio, bool value){
if (gpio >= BSP_GPIO_NUM) return BSP_ERR;
HAL_GPIO_WritePin(GPIO_Map[gpio].gpio, GPIO_Map[gpio].pin, value);

View File

@@ -22,8 +22,8 @@ typedef enum {
/* Exported functions prototypes -------------------------------------------- */
int8_t BSP_GPIO_RegisterCallback(uint16_t pin, void (*callback)(void));
int8_t BSP_GPIO_EnableIRQ(uint16_t pin);
int8_t BSP_GPIO_DisableIRQ(uint16_t pin);
int8_t BSP_GPIO_EnableIRQ(BSP_GPIO_t gpio);
int8_t BSP_GPIO_DisableIRQ(BSP_GPIO_t gpio);
int8_t BSP_GPIO_WritePin(BSP_GPIO_t gpio, bool value);
int8_t BSP_GPIO_TogglePin(BSP_GPIO_t gpio);

View File

@@ -1,4 +1,5 @@
/* Includes ----------------------------------------------------------------- */
#include <spi.h>
#include "bsp\spi.h"
/* Private define ----------------------------------------------------------- */
@@ -134,34 +135,29 @@ int8_t BSP_SPI_TransmitReceive(BSP_SPI_t spi, uint8_t *txData, uint8_t *rxData,
uint8_t BSP_SPI_MemReadByte(BSP_SPI_t spi, uint8_t reg) {
if (spi >= BSP_SPI_NUM) return 0xFF;
SPI_HandleTypeDef *hspi = BSP_SPI_GetHandle(spi);
if (hspi == NULL) return 0xFF;
uint8_t data = 0;
HAL_SPI_Mem_Read(hspi, reg, &data, sizeof(data));
return data;
uint8_t tmp[2] = {reg | 0x80, 0x00};
BSP_SPI_TransmitReceive(spi, tmp, tmp, 2u, true);
return tmp[1];
}
int8_t BSP_SPI_MemWriteByte(BSP_SPI_t spi, uint8_t reg, uint8_t data) {
if (spi >= BSP_SPI_NUM) return BSP_ERR;
SPI_HandleTypeDef *hspi = BSP_SPI_GetHandle(spi);
if (hspi == NULL) return BSP_ERR;
return HAL_SPI_Mem_Write(hspi, reg, &data, sizeof(data));
uint8_t tmp[2] = {reg & 0x7f, data};
return BSP_SPI_Transmit(spi, tmp, 2u, true);
}
int8_t BSP_SPI_MemRead(BSP_SPI_t spi, uint8_t reg, uint8_t *data, uint16_t size) {
if (spi >= BSP_SPI_NUM) return BSP_ERR;
SPI_HandleTypeDef *hspi = BSP_SPI_GetHandle(spi);
if (hspi == NULL || data == NULL || size == 0) return BSP_ERR_NULL;
return HAL_SPI_Mem_Read(hspi, reg, data, size);
if (data == NULL || size == 0) return BSP_ERR_NULL;
reg = reg | 0x80;
BSP_SPI_Transmit(spi, &reg, 1u, true);
return BSP_SPI_Receive(spi, data, size, true);
}
int8_t BSP_SPI_MemWrite(BSP_SPI_t spi, uint8_t reg, uint8_t *data, uint16_t size) {
if (spi >= BSP_SPI_NUM) return BSP_ERR;
SPI_HandleTypeDef *hspi = BSP_SPI_GetHandle(spi);
if (hspi == NULL || data == NULL || size == 0) return BSP_ERR_NULL;
return HAL_SPI_Mem_Write(hspi, reg, data, size);
if (data == NULL || size == 0) return BSP_ERR_NULL;
reg = reg & 0x7f;
BSP_SPI_Transmit(spi, &reg, 1u, true);
return BSP_SPI_Transmit(spi, data, size, true);
}

View File

@@ -1,5 +1,5 @@
/* Includes ----------------------------------------------------------------- */
#include <uart.h>
#include <usart.h>
#include "bsp/uart.h"

View File

@@ -45,12 +45,12 @@ typedef enum {
WHITE
} UI_Color_t;
typedef struct __packed {
typedef __Packed struct {
uint8_t op;
uint8_t num_layer;
} UI_InterStudent_UIDel_t;
typedef struct __packed {
typedef __Packed struct {
uint8_t name[3];
uint8_t type_op : 3;
uint8_t type_ele : 3;
@@ -66,28 +66,28 @@ typedef struct __packed {
uint16_t y_end : 11;
} UI_Ele_t;
typedef struct __packed {
typedef __Packed struct {
UI_Ele_t grapic;
} UI_Drawgrapic_1_t;
typedef struct __packed {
typedef __Packed struct {
UI_Ele_t grapic[2];
} UI_Drawgrapic_2_t;
typedef struct __packed {
typedef __Packed struct {
UI_Ele_t grapic[5];
} UI_Drawgrapic_5_t;
typedef struct __packed {
typedef __Packed struct {
UI_Ele_t grapic[7];
} UI_Drawgrapic_7_t;
typedef struct __packed {
typedef __Packed struct {
UI_Ele_t grapic;
uint8_t character[30];
} UI_Drawcharacter_t;
typedef struct __packed {
typedef __Packed struct {
uint8_t del_operation;
uint8_t layer;
} UI_Del_t;

View File

@@ -117,16 +117,16 @@ inline float CalculateRpm(float bullet_speed, float fric_radius, bool is17mm) {
return 60.0f * (float)bullet_speed / (M_2PI * fric_radius);
}
/**
* @brief 断言失败处理
*
* @param file 文件名
* @param line 行号
*/
void VerifyFailed(const char *file, uint32_t line) {
UNUSED(file);
UNUSED(line);
while (1) {
__NOP();
}
}
// /**
// * @brief 断言失败处理
// *
// * @param file 文件名
// * @param line 行号
// */
// void VerifyFailed(const char *file, uint32_t line) {
// UNUSED(file);
// UNUSED(line);
// while (1) {
// __NOP();
// }
// }

View File

@@ -8,12 +8,11 @@
extern "C" {
#endif
#include "stm32f4xx.h"
#define ARM_MATH_CM4
#include <float.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#define M_DEG2RAD_MULT (0.01745329251f)
#define M_RAD2DEG_MULT (57.2957795131f)
@@ -149,10 +148,10 @@ float CalculateRpm(float bullet_speed, float fric_radius, bool is17mm);
#define VERIFY(expr) ((void)(expr))
#endif
/**
* @brief 断言失败处理
*
* @param file 文件名
* @param line 行号
*/
void VerifyFailed(const char *file, uint32_t line);
// /**
// * @brief 断言失败处理
// *
// * @param file 文件名
// * @param line 行号
// */
// void VerifyFailed(const char *file, uint32_t line);

View File

@@ -1,4 +1,4 @@
bsp,can,dwt,gpio,i2c,mm,spi,uart,pwm,time
component,pid,filter,ahrs
component,ahrs,ballistics,capacity,cmd,crc8,crc16,error_detect,filter,FreeRTOS_CLI,limiter,mixer,pid,ui,user_math
device,dr16,ai,nuc
module,chassis,gimbal,arm,shoot
1 bsp,can,dwt,gpio,i2c,mm,spi,uart,pwm,time
2 component,pid,filter,ahrs component,ahrs,ballistics,capacity,cmd,crc8,crc16,error_detect,filter,FreeRTOS_CLI,limiter,mixer,pid,ui,user_math
3 device,dr16,ai,nuc
4 module,chassis,gimbal,arm,shoot