修改了can

This commit is contained in:
Robofish 2025-09-06 12:42:38 +08:00
parent 485e25fec2
commit d626e4e656
7 changed files with 326 additions and 56 deletions

View File

@ -433,6 +433,27 @@ class bsp_can(BspPeripheralBase):
# 生成CAN初始化代码 # 生成CAN初始化代码
init_lines = [] init_lines = []
# 初始化发送信号量
init_lines.append(" // 创建发送信号量每个CAN通道有3个发送邮箱")
init_lines.append(" for (int i = 0; i < BSP_CAN_NUM; i++) {")
init_lines.append(" tx_semaphore[i] = osSemaphoreNew(CAN_TX_MAILBOX_NUM, CAN_TX_MAILBOX_NUM, NULL);")
init_lines.append(" if (tx_semaphore[i] == NULL) {")
init_lines.append(" // 清理已创建的信号量")
init_lines.append(" for (int j = 0; j < i; j++) {")
init_lines.append(" if (tx_semaphore[j] != NULL) {")
init_lines.append(" osSemaphoreDelete(tx_semaphore[j]);")
init_lines.append(" tx_semaphore[j] = NULL;")
init_lines.append(" }")
init_lines.append(" }")
init_lines.append(" if (queue_mutex != NULL) {")
init_lines.append(" osMutexDelete(queue_mutex);")
init_lines.append(" queue_mutex = NULL;")
init_lines.append(" }")
init_lines.append(" return BSP_ERR;")
init_lines.append(" }")
init_lines.append(" }")
init_lines.append("")
# 先设置初始化标志 # 先设置初始化标志
init_lines.append(" // 先设置初始化标志,以便后续回调注册能通过检查") init_lines.append(" // 先设置初始化标志,以便后续回调注册能通过检查")
init_lines.append(" inited = true;") init_lines.append(" inited = true;")
@ -482,10 +503,19 @@ class bsp_can(BspPeripheralBase):
f" HAL_CAN_ConfigFilter(&hcan{can_num}, &can{can_num}_filter);", f" HAL_CAN_ConfigFilter(&hcan{can_num}, &can{can_num}_filter);",
f" HAL_CAN_Start(&hcan{can_num});", f" HAL_CAN_Start(&hcan{can_num});",
"", "",
f" // 注册{instance}回调函数", f" // 注册{instance}发送完成回调(用于释放信号量)",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX0_CPLT_CB, BSP_CAN_TxCompleteCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX1_CPLT_CB, BSP_CAN_TxCompleteCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX2_CPLT_CB, BSP_CAN_TxCompleteCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX0_ABORT_CB, BSP_CAN_TxAbortCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX1_ABORT_CB, BSP_CAN_TxAbortCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX2_ABORT_CB, BSP_CAN_TxAbortCallback);",
"",
f" // 注册{instance}接收回调函数",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifo0Callback);", f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifo0Callback);",
"", "",
f" HAL_CAN_ActivateNotification(&hcan{can_num}, CAN_IT_RX_FIFO0_MSG_PENDING);", f" HAL_CAN_ActivateNotification(&hcan{can_num}, CAN_IT_RX_FIFO0_MSG_PENDING | ",
f" CAN_IT_TX_MAILBOX_EMPTY); // 激活发送邮箱空中断",
"" ""
]) ])
@ -513,10 +543,19 @@ class bsp_can(BspPeripheralBase):
f" HAL_CAN_ConfigFilter(&hcan1, &can1_filter);", f" HAL_CAN_ConfigFilter(&hcan1, &can1_filter);",
f" HAL_CAN_Start(&hcan1);", f" HAL_CAN_Start(&hcan1);",
"", "",
f" // 注册CAN1回调函数", f" // 注册CAN1发送完成回调用于释放信号量",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX0_CPLT_CB, BSP_CAN_TxCompleteCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX1_CPLT_CB, BSP_CAN_TxCompleteCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX2_CPLT_CB, BSP_CAN_TxCompleteCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX0_ABORT_CB, BSP_CAN_TxAbortCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX1_ABORT_CB, BSP_CAN_TxAbortCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX2_ABORT_CB, BSP_CAN_TxAbortCallback);",
"",
f" // 注册CAN1接收回调函数",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifo0Callback);", f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifo0Callback);",
"", "",
f" HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);", f" HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING | ",
f" CAN_IT_TX_MAILBOX_EMPTY); // 激活发送邮箱空中断",
"" ""
]) ])
@ -529,9 +568,18 @@ class bsp_can(BspPeripheralBase):
f" HAL_CAN_ConfigFilter(&hcan2, &can1_filter); // 通过 CAN1 配置", f" HAL_CAN_ConfigFilter(&hcan2, &can1_filter); // 通过 CAN1 配置",
f" HAL_CAN_Start(&hcan2);", f" HAL_CAN_Start(&hcan2);",
"", "",
f" // 注册CAN2回调函数", f" // 注册CAN2发送完成回调用于释放信号量",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX0_CPLT_CB, BSP_CAN_TxCompleteCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX1_CPLT_CB, BSP_CAN_TxCompleteCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX2_CPLT_CB, BSP_CAN_TxCompleteCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX0_ABORT_CB, BSP_CAN_TxAbortCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX1_ABORT_CB, BSP_CAN_TxAbortCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX2_ABORT_CB, BSP_CAN_TxAbortCallback);",
"",
f" // 注册CAN2接收回调函数",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_RX_FIFO1_MSG_PENDING_CB, BSP_CAN_RxFifo1Callback);", f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_RX_FIFO1_MSG_PENDING_CB, BSP_CAN_RxFifo1Callback);",
f" HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO1_MSG_PENDING);", f" HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO1_MSG_PENDING | ",
f" CAN_IT_TX_MAILBOX_EMPTY); // 激活发送邮箱空中断",
"" ""
]) ])
@ -560,10 +608,19 @@ class bsp_can(BspPeripheralBase):
f" HAL_CAN_ConfigFilter(&hcan1, &can1_filter);", f" HAL_CAN_ConfigFilter(&hcan1, &can1_filter);",
f" HAL_CAN_Start(&hcan1);", f" HAL_CAN_Start(&hcan1);",
"", "",
f" // 注册CAN1回调函数", f" // 注册CAN1发送完成回调用于释放信号量",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX0_CPLT_CB, BSP_CAN_TxCompleteCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX1_CPLT_CB, BSP_CAN_TxCompleteCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX2_CPLT_CB, BSP_CAN_TxCompleteCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX0_ABORT_CB, BSP_CAN_TxAbortCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX1_ABORT_CB, BSP_CAN_TxAbortCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX2_ABORT_CB, BSP_CAN_TxAbortCallback);",
"",
f" // 注册CAN1接收回调函数",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifo0Callback);", f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifo0Callback);",
"", "",
f" HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);", f" HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING | ",
f" CAN_IT_TX_MAILBOX_EMPTY); // 激活发送邮箱空中断",
"" ""
]) ])
@ -577,9 +634,18 @@ class bsp_can(BspPeripheralBase):
f" HAL_CAN_ConfigFilter(&hcan2, &can1_filter); // 通过 CAN1 配置", f" HAL_CAN_ConfigFilter(&hcan2, &can1_filter); // 通过 CAN1 配置",
f" HAL_CAN_Start(&hcan2);", f" HAL_CAN_Start(&hcan2);",
"", "",
f" // 注册CAN2回调函数", f" // 注册CAN2发送完成回调用于释放信号量",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX0_CPLT_CB, BSP_CAN_TxCompleteCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX1_CPLT_CB, BSP_CAN_TxCompleteCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX2_CPLT_CB, BSP_CAN_TxCompleteCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX0_ABORT_CB, BSP_CAN_TxAbortCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX1_ABORT_CB, BSP_CAN_TxAbortCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX2_ABORT_CB, BSP_CAN_TxAbortCallback);",
"",
f" // 注册CAN2接收回调函数",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifo0Callback);", f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifo0Callback);",
f" HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_MSG_PENDING);", f" HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_MSG_PENDING | ",
f" CAN_IT_TX_MAILBOX_EMPTY); // 激活发送邮箱空中断",
"" ""
]) ])
@ -595,9 +661,18 @@ class bsp_can(BspPeripheralBase):
f" HAL_CAN_ConfigFilter(&hcan1, &can1_filter); // 通过 CAN1 配置", f" HAL_CAN_ConfigFilter(&hcan1, &can1_filter); // 通过 CAN1 配置",
f" HAL_CAN_Start(&hcan{can_num});", f" HAL_CAN_Start(&hcan{can_num});",
"", "",
f" // 注册{instance}回调函数", f" // 注册{instance}发送完成回调(用于释放信号量)",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX0_CPLT_CB, BSP_CAN_TxCompleteCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX1_CPLT_CB, BSP_CAN_TxCompleteCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX2_CPLT_CB, BSP_CAN_TxCompleteCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX0_ABORT_CB, BSP_CAN_TxAbortCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX1_ABORT_CB, BSP_CAN_TxAbortCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_TX_MAILBOX2_ABORT_CB, BSP_CAN_TxAbortCallback);",
"",
f" // 注册{instance}接收回调函数",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_RX_FIFO1_MSG_PENDING_CB, BSP_CAN_RxFifo1Callback);", f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_RX_FIFO1_MSG_PENDING_CB, BSP_CAN_RxFifo1Callback);",
f" HAL_CAN_ActivateNotification(&hcan{can_num}, CAN_IT_RX_FIFO1_MSG_PENDING);", f" HAL_CAN_ActivateNotification(&hcan{can_num}, CAN_IT_RX_FIFO1_MSG_PENDING | ",
f" CAN_IT_TX_MAILBOX_EMPTY); // 激活发送邮箱空中断",
"" ""
]) ])
filter_bank += 1 # 为下一个CAN分配不同的过滤器组 filter_bank += 1 # 为下一个CAN分配不同的过滤器组

View File

@ -7,6 +7,8 @@
/* Private define ----------------------------------------------------------- */ /* Private define ----------------------------------------------------------- */
#define CAN_QUEUE_MUTEX_TIMEOUT 100 /* 队列互斥锁超时时间(ms) */ #define CAN_QUEUE_MUTEX_TIMEOUT 100 /* 队列互斥锁超时时间(ms) */
#define CAN_TX_SEMAPHORE_TIMEOUT 1000 /* 发送信号量超时时间(ms) */
#define CAN_TX_MAILBOX_NUM 3 /* CAN发送邮箱数量 */
/* Private macro ------------------------------------------------------------ */ /* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */ /* Private typedef ---------------------------------------------------------- */
@ -21,6 +23,7 @@ typedef struct BSP_CAN_QueueNode {
/* Private variables -------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */
static BSP_CAN_QueueNode_t *queue_list = NULL; static BSP_CAN_QueueNode_t *queue_list = NULL;
static osMutexId_t queue_mutex = NULL; static osMutexId_t queue_mutex = NULL;
static osSemaphoreId_t tx_semaphore[BSP_CAN_NUM] = {NULL}; /* 发送信号量,用于控制发送邮箱访问 */
static void (*CAN_Callback[BSP_CAN_NUM][BSP_CAN_CB_NUM])(void); static void (*CAN_Callback[BSP_CAN_NUM][BSP_CAN_CB_NUM])(void);
static bool inited = false; static bool inited = false;
static BSP_CAN_IdParser_t id_parser = NULL; /* ID解析器 */ static BSP_CAN_IdParser_t id_parser = NULL; /* ID解析器 */
@ -32,6 +35,8 @@ static int8_t BSP_CAN_CreateIdQueue(BSP_CAN_t can, uint32_t can_id, uint8_t queu
static int8_t BSP_CAN_DeleteIdQueue(BSP_CAN_t can, uint32_t can_id); static int8_t BSP_CAN_DeleteIdQueue(BSP_CAN_t can, uint32_t can_id);
static void BSP_CAN_RxFifo0Callback(void); static void BSP_CAN_RxFifo0Callback(void);
static void BSP_CAN_RxFifo1Callback(void); static void BSP_CAN_RxFifo1Callback(void);
static void BSP_CAN_TxCompleteCallback(CAN_HandleTypeDef *hcan);
static void BSP_CAN_TxAbortCallback(CAN_HandleTypeDef *hcan);
static BSP_CAN_FrameType_t BSP_CAN_GetFrameType(CAN_RxHeaderTypeDef *header); 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); static uint32_t BSP_CAN_DefaultIdParser(uint32_t original_id, BSP_CAN_FrameType_t frame_type);
@ -208,53 +213,79 @@ static void BSP_CAN_RxFifo1Callback(void) {
} }
} }
/**
* @brief
*/
static void BSP_CAN_TxCompleteCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) {
// 释放发送信号量
if (tx_semaphore[bsp_can] != NULL) {
osSemaphoreRelease(tx_semaphore[bsp_can]);
}
}
}
/**
* @brief
*/
static void BSP_CAN_TxAbortCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) {
// 释放发送信号量(发送中止也要释放)
if (tx_semaphore[bsp_can] != NULL) {
osSemaphoreRelease(tx_semaphore[bsp_can]);
}
}
}
/* HAL Callback Functions --------------------------------------------------- */ /* HAL Callback Functions --------------------------------------------------- */
void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan) { void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = CAN_Get(hcan); BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) { if (bsp_can != BSP_CAN_ERR) {
if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_CPLT_CB]) if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_CPLT_CB])
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) { void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = CAN_Get(hcan); BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) { if (bsp_can != BSP_CAN_ERR) {
if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_CPLT_CB]) if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_CPLT_CB])
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) { void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = CAN_Get(hcan); BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) { if (bsp_can != BSP_CAN_ERR) {
if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_CPLT_CB]) if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_CPLT_CB])
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) { void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = CAN_Get(hcan); BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) { if (bsp_can != BSP_CAN_ERR) {
if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_ABORT_CB]) if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_ABORT_CB])
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) { void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = CAN_Get(hcan); BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) { if (bsp_can != BSP_CAN_ERR) {
if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_ABORT_CB]) if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_ABORT_CB])
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) { void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = CAN_Get(hcan); BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) { if (bsp_can != BSP_CAN_ERR) {
if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_ABORT_CB]) if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_ABORT_CB])
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) { void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
@ -332,6 +363,25 @@ int8_t BSP_CAN_Init(void) {
return BSP_ERR; return BSP_ERR;
} }
// 创建发送信号量每个CAN通道有3个发送邮箱
for (int i = 0; i < BSP_CAN_NUM; i++) {
tx_semaphore[i] = osSemaphoreNew(CAN_TX_MAILBOX_NUM, CAN_TX_MAILBOX_NUM, NULL);
if (tx_semaphore[i] == NULL) {
// 清理已创建的信号量
for (int j = 0; j < i; j++) {
if (tx_semaphore[j] != NULL) {
osSemaphoreDelete(tx_semaphore[j]);
tx_semaphore[j] = NULL;
}
}
if (queue_mutex != NULL) {
osMutexDelete(queue_mutex);
queue_mutex = NULL;
}
return BSP_ERR;
}
}
/* AUTO GENERATED CAN_INIT */ /* AUTO GENERATED CAN_INIT */
inited = true; inited = true;
@ -356,6 +406,14 @@ int8_t BSP_CAN_DeInit(void) {
osMutexRelease(queue_mutex); osMutexRelease(queue_mutex);
} }
// 删除发送信号量
for (int i = 0; i < BSP_CAN_NUM; i++) {
if (tx_semaphore[i] != NULL) {
osSemaphoreDelete(tx_semaphore[i]);
tx_semaphore[i] = NULL;
}
}
// 删除互斥锁 // 删除互斥锁
if (queue_mutex != NULL) { if (queue_mutex != NULL) {
osMutexDelete(queue_mutex); osMutexDelete(queue_mutex);
@ -418,8 +476,20 @@ int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format,
return BSP_ERR; return BSP_ERR;
} }
// 获取发送信号量,确保有可用的发送邮箱
if (tx_semaphore[can] == NULL) {
return BSP_ERR;
}
osStatus_t sem_status = osSemaphoreAcquire(tx_semaphore[can], CAN_TX_SEMAPHORE_TIMEOUT);
if (sem_status != osOK) {
return BSP_ERR_TIMEOUT; // 获取信号量超时,表示发送邮箱已满
}
CAN_HandleTypeDef *hcan = BSP_CAN_GetHandle(can); CAN_HandleTypeDef *hcan = BSP_CAN_GetHandle(can);
if (hcan == NULL) { if (hcan == NULL) {
// 如果获取句柄失败,需要释放信号量
osSemaphoreRelease(tx_semaphore[can]);
return BSP_ERR_NULL; return BSP_ERR_NULL;
} }
@ -448,6 +518,8 @@ int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format,
header.RTR = CAN_RTR_REMOTE; header.RTR = CAN_RTR_REMOTE;
break; break;
default: default:
// 如果格式错误,需要释放信号量
osSemaphoreRelease(tx_semaphore[can]);
return BSP_ERR; return BSP_ERR;
} }
@ -455,7 +527,15 @@ int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format,
header.TransmitGlobalTime = DISABLE; header.TransmitGlobalTime = DISABLE;
HAL_StatusTypeDef result = HAL_CAN_AddTxMessage(hcan, &header, data, &mailbox); HAL_StatusTypeDef result = HAL_CAN_AddTxMessage(hcan, &header, data, &mailbox);
return (result == HAL_OK) ? BSP_OK : BSP_ERR;
if (result != HAL_OK) {
// 如果发送失败,需要释放信号量
osSemaphoreRelease(tx_semaphore[can]);
return BSP_ERR;
}
// 发送成功,信号量将在发送完成回调中释放
return BSP_OK;
} }
int8_t BSP_CAN_TransmitStdDataFrame(BSP_CAN_t can, BSP_CAN_StdDataFrame_t *frame) { int8_t BSP_CAN_TransmitStdDataFrame(BSP_CAN_t can, BSP_CAN_StdDataFrame_t *frame) {
@ -574,6 +654,3 @@ uint32_t BSP_CAN_ParseId(uint32_t original_id, BSP_CAN_FrameType_t frame_type) {
} }
return BSP_CAN_DefaultIdParser(original_id, frame_type); return BSP_CAN_DefaultIdParser(original_id, frame_type);
} }
/* USER CAN FUNCTIONS BEGIN */
/* USER CAN FUNCTIONS END */

View File

@ -17,6 +17,7 @@ extern "C" {
#define BSP_CAN_DEFAULT_QUEUE_SIZE 10 #define BSP_CAN_DEFAULT_QUEUE_SIZE 10
#define BSP_CAN_TIMEOUT_IMMEDIATE 0 #define BSP_CAN_TIMEOUT_IMMEDIATE 0
#define BSP_CAN_TIMEOUT_FOREVER osWaitForever #define BSP_CAN_TIMEOUT_FOREVER osWaitForever
#define CAN_TX_SEMAPHORE_TIMEOUT 1000 /* 发送信号量超时时间(ms) */
/* Exported macro ----------------------------------------------------------- */ /* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */ /* Exported types ----------------------------------------------------------- */
@ -224,9 +225,6 @@ int8_t BSP_CAN_UnregisterIdParser(void);
*/ */
uint32_t BSP_CAN_ParseId(uint32_t original_id, BSP_CAN_FrameType_t frame_type); uint32_t BSP_CAN_ParseId(uint32_t original_id, BSP_CAN_FrameType_t frame_type);
/* USER CAN FUNCTIONS BEGIN */
/* USER CAN FUNCTIONS END */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,7 +1,11 @@
uart,要求开启dma和中断 uart,请开启uart的dma和中断
can,2222 can,请开启can中断使用函数前请确保can已经初始化。
gpio,要求设置label开启中断 gpio,会自动读取cubemx中配置为gpio的引脚并自动区分输入输出和中断。
spi,要求开启spi中断 spi,请开启spi的dma和中断
i2c,要求开始spi中断 i2c,要求开始spi中断
mm,这是套了一层的内存 mm,这是套了一层的动态内存分配
time,需要使用开启freerots time,获取时间戳函数需要开启freerots
dwt,需要开启dwt获取时间
i2c,请开启i2c的dma和中断
pwm,用于选择那些勇于输出pwm

1 uart 要求开启dma和中断 请开启uart的dma和中断
2 can 2222 请开启can中断,使用函数前请确保can已经初始化。
3 gpio 要求设置label开启中断 会自动读取cubemx中配置为gpio的引脚,并自动区分输入输出和中断。
4 spi 要求开启spi中断 请开启spi的dma和中断
5 i2c 要求开始spi中断 要求开始spi中断
6 mm 这是套了一层的内存 这是套了一层的动态内存分配
7 time 需要使用开启freerots 获取时间戳函数,需要开启freerots
8 dwt 需要开启dwt,获取时间
9 i2c 请开启i2c的dma和中断
10 pwm 用于选择那些勇于输出pwm
11

View File

@ -35,7 +35,6 @@ int8_t BSP_PWM_SetComp(BSP_PWM_Channel_t ch, float duty_cycle) {
if (duty_cycle < 0.0f) { if (duty_cycle < 0.0f) {
duty_cycle = 0.0f; duty_cycle = 0.0f;
} }
// 获取ARR值周期值 // 获取ARR值周期值
uint32_t arr = __HAL_TIM_GET_AUTORELOAD(PWM_Map[ch].tim); uint32_t arr = __HAL_TIM_GET_AUTORELOAD(PWM_Map[ch].tim);
@ -43,6 +42,7 @@ int8_t BSP_PWM_SetComp(BSP_PWM_Channel_t ch, float duty_cycle) {
uint32_t ccr = (uint32_t)(duty_cycle * (arr + 1)); uint32_t ccr = (uint32_t)(duty_cycle * (arr + 1));
__HAL_TIM_SET_COMPARE(PWM_Map[ch].tim, PWM_Map[ch].channel, ccr); __HAL_TIM_SET_COMPARE(PWM_Map[ch].tim, PWM_Map[ch].channel, ccr);
return BSP_OK; return BSP_OK;
} }

View File

@ -0,0 +1,77 @@
/* Includes ----------------------------------------------------------------- */
#include <stdio.h>
#include <string.h>
#include "vofa.h"
#include "bsp/uart.h"
/* Private define ----------------------------------------------------------- */
//#define PROTOCOL_RAWDATA
#define PROTOCOL_FIREWATER
//#define PROTOCOL_JUSTFLOAT
#define MAX_CHANNEL 64u // 根据实际最大通道数调整
#define JUSTFLOAT_TAIL 0x7F800000
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
/* Private variables -------------------------------------------------------- */
static uint8_t vofa_tx_buf[sizeof(float) * MAX_CHANNEL + sizeof(uint32_t)];
/* Private function -------------------------------------------------------- */
/************************ RawData *************************/
void VOFA_RawData_Send(const char* data, bool dma) {
BSP_UART_Transmit(BSP_UART_VOFA, (uint8_t*)data, strlen(data), dma);
}
/************************ FireWater *************************/
void VOFA_FireWater_Send(float *channels, uint8_t channel_count, bool dma)
{
if (channel_count == 0 || channel_count > MAX_CHANNEL)
return;
char *buf = (char *)vofa_tx_buf;
size_t len = 0;
for (uint8_t i = 0; i < channel_count; ++i) {
len += snprintf(buf + len,
sizeof(vofa_tx_buf) - len,
"%s%.2f",
(i ? "," : ""),
channels[i]);
}
snprintf(buf + len, sizeof(vofa_tx_buf) - len, "\n");
BSP_UART_Transmit(BSP_UART_VOFA, vofa_tx_buf, strlen(buf), dma);
}
/************************ JustFloat *************************/
void VOFA_JustFloat_Send(float *channels, uint8_t channel_count, bool dma)
{
if (channel_count == 0 || channel_count > MAX_CHANNEL)
return;
memcpy(vofa_tx_buf, channels, channel_count * sizeof(float));
uint32_t tail = JUSTFLOAT_TAIL; // 0x7F800000
memcpy(vofa_tx_buf + channel_count * sizeof(float), &tail, sizeof(tail));
BSP_UART_Transmit(BSP_UART_VOFA, vofa_tx_buf, channel_count * sizeof(float) + sizeof(tail), dma);
}
/* Exported functions ------------------------------------------------------- */
init8_t VOFA_Send(float* channels, uint8_t channel_count, bool dma) {
#ifdef PROTOCOL_RAWDATA
sprintf(vofa_tx_buf, "Channel1:%.2f,Channel2:%.2f\n", channels[0],channels[1]);
VOFA_RawData_Send(vofa_tx_buf, dma);
#elif defined(PROTOCOL_FIREWATER)
VOFA_FireWater_Send(channels, channel_count, dma);
#elif defined(PROTOCOL_JUSTFLOAT)
VOFA_JustFloat_Send(channels, channel_count, dma);
#else
// 默认使用RawData协议
char data[256];
sprintf(data, "Channel1: %.2f, Channel2: %.2f\n", channels[0], channels[1]);
VOFA_RawData_Send(data, dma);
#endif
return DEVICE_OK;
}

View File

@ -0,0 +1,39 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include "bsp/uart.h"
#include ”device/device.h“
/* Exported constants ------------------------------------------------------- */
/* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */
/* Exported functions prototypes -------------------------------------------- */
typedef enum {
VOFA_PROTOCOL_RAWDATA,
VOFA_PROTOCOL_FIREWATER,
VOFA_PROTOCOL_JUSTFLOAT,
} VOFA_Protocol_t;
/**
* @brief VOFA设备
* @param protocol
* @return
*/
int8_t VOFA_init(VOFA_Protocol_t protocol);
/**
* @brief VOFA
* @param channels
* @param channel_count
* @param dma 使DMA发送
* @return
*/
int8_t VOFA_Send(float* channels, uint8_t channel_count, bool dma);
#ifdef __cplusplus
}
#endif