mirror of
https://github.com/goldenfishs/MRobot.git
synced 2025-09-14 12:54:33 +08:00
更新can
This commit is contained in:
parent
50cfcb0693
commit
bbb521654c
@ -9,6 +9,7 @@ extern "C" {
|
|||||||
#define BSP_ERR_NULL (-2)
|
#define BSP_ERR_NULL (-2)
|
||||||
#define BSP_ERR_INITED (-3)
|
#define BSP_ERR_INITED (-3)
|
||||||
#define BSP_ERR_NO_DEV (-4)
|
#define BSP_ERR_NO_DEV (-4)
|
||||||
|
#define BSP_ERR_TIMEOUT (-5)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -3,47 +3,147 @@
|
|||||||
#include "bsp/bsp.h"
|
#include "bsp/bsp.h"
|
||||||
#include <can.h>
|
#include <can.h>
|
||||||
#include <cmsis_os.h>
|
#include <cmsis_os.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* Private define ----------------------------------------------------------- */
|
/* Private define ----------------------------------------------------------- */
|
||||||
|
#define CAN_QUEUE_MUTEX_TIMEOUT 100 /* 队列互斥锁超时时间(ms) */
|
||||||
|
|
||||||
/* Private macro ------------------------------------------------------------ */
|
/* Private macro ------------------------------------------------------------ */
|
||||||
/* Private typedef ---------------------------------------------------------- */
|
/* Private typedef ---------------------------------------------------------- */
|
||||||
typedef struct CAN_QueueNode {
|
typedef struct BSP_CAN_QueueNode {
|
||||||
uint32_t can_id;
|
uint32_t can_id;
|
||||||
osMessageQueueId_t queue;
|
osMessageQueueId_t queue;
|
||||||
uint8_t queue_size;
|
uint8_t queue_size;
|
||||||
struct CAN_QueueNode *next;
|
struct BSP_CAN_QueueNode *next;
|
||||||
} CAN_QueueNode_t;
|
} BSP_CAN_QueueNode_t;
|
||||||
|
|
||||||
/* Private variables -------------------------------------------------------- */
|
/* Private variables -------------------------------------------------------- */
|
||||||
static CAN_QueueNode_t *can_queue_list = NULL;
|
static BSP_CAN_QueueNode_t *g_can_queue_list = NULL;
|
||||||
static void (*CAN_Callback[BSP_CAN_NUM][BSP_CAN_CB_NUM])(void);
|
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;
|
||||||
|
|
||||||
/* Private function prototypes ---------------------------------------------- */
|
/* Private function prototypes ---------------------------------------------- */
|
||||||
static BSP_CAN_t CAN_Get(CAN_HandleTypeDef *hcan);
|
static BSP_CAN_t BSP_CAN_GetInstance(CAN_HandleTypeDef *hcan);
|
||||||
static osMessageQueueId_t find_queue(uint32_t can_id);
|
static osMessageQueueId_t BSP_CAN_FindQueue(uint32_t can_id);
|
||||||
static void can_rx_fifo0_handler(void);
|
static int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size);
|
||||||
static void can_rx_fifo1_handler(void);
|
static int8_t BSP_CAN_DeleteIdQueue(uint32_t can_id);
|
||||||
|
static void BSP_CAN_RxFifo0Handler(void);
|
||||||
|
static void BSP_CAN_RxFifo1Handler(void);
|
||||||
|
|
||||||
/* AUTO GENERATED CAN_RX_CALLBACKS */
|
/* Private functions -------------------------------------------------------- */
|
||||||
/* Private function -------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* 查找指定CAN ID的队列 */
|
/**
|
||||||
static osMessageQueueId_t find_queue(uint32_t can_id) {
|
* @brief 根据CAN句柄获取BSP_CAN实例
|
||||||
CAN_QueueNode_t *node = can_queue_list;
|
*/
|
||||||
while (node) {
|
static BSP_CAN_t BSP_CAN_GetInstance(CAN_HandleTypeDef *hcan) {
|
||||||
if (node->can_id == can_id) return node->queue;
|
if (hcan == NULL) return BSP_CAN_ERR;
|
||||||
|
|
||||||
|
/* AUTO GENERATED CAN_GET */
|
||||||
|
else
|
||||||
|
return BSP_CAN_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 查找指定CAN ID的消息队列
|
||||||
|
* @note 调用前需要获取互斥锁
|
||||||
|
*/
|
||||||
|
static osMessageQueueId_t BSP_CAN_FindQueue(uint32_t can_id) {
|
||||||
|
BSP_CAN_QueueNode_t *node = g_can_queue_list;
|
||||||
|
while (node != NULL) {
|
||||||
|
if (node->can_id == can_id) {
|
||||||
|
return node->queue;
|
||||||
|
}
|
||||||
node = node->next;
|
node = node->next;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIFO0接收处理函数 */
|
/**
|
||||||
static void can_rx_fifo0_handler(void) {
|
* @brief 创建指定CAN ID的消息队列
|
||||||
|
* @note 内部函数,已包含互斥锁保护
|
||||||
|
*/
|
||||||
|
static int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size) {
|
||||||
|
if (queue_size == 0) {
|
||||||
|
queue_size = BSP_CAN_DEFAULT_QUEUE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取互斥锁
|
||||||
|
if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
|
||||||
|
return BSP_ERR_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否已存在
|
||||||
|
BSP_CAN_QueueNode_t *node = g_can_queue_list;
|
||||||
|
while (node != NULL) {
|
||||||
|
if (node->can_id == can_id) {
|
||||||
|
osMutexRelease(g_can_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(g_can_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(g_can_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;
|
||||||
|
|
||||||
|
osMutexRelease(g_can_queue_mutex);
|
||||||
|
return BSP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 删除指定CAN ID的消息队列
|
||||||
|
* @note 内部函数,已包含互斥锁保护
|
||||||
|
*/
|
||||||
|
static int8_t BSP_CAN_DeleteIdQueue(uint32_t can_id) {
|
||||||
|
// 获取互斥锁
|
||||||
|
if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
|
||||||
|
return BSP_ERR_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
BSP_CAN_QueueNode_t **current = &g_can_queue_list;
|
||||||
|
while (*current != NULL) {
|
||||||
|
if ((*current)->can_id == can_id) {
|
||||||
|
BSP_CAN_QueueNode_t *to_delete = *current;
|
||||||
|
*current = (*current)->next;
|
||||||
|
|
||||||
|
// 删除队列和节点
|
||||||
|
osMessageQueueDelete(to_delete->queue);
|
||||||
|
BSP_Free(to_delete);
|
||||||
|
|
||||||
|
osMutexRelease(g_can_queue_mutex);
|
||||||
|
return BSP_OK;
|
||||||
|
}
|
||||||
|
current = &(*current)->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
osMutexRelease(g_can_queue_mutex);
|
||||||
|
return BSP_ERR; // 未找到
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief FIFO0接收处理函数
|
||||||
|
*/
|
||||||
|
static void BSP_CAN_RxFifo0Handler(void) {
|
||||||
CAN_RxHeaderTypeDef rx_header;
|
CAN_RxHeaderTypeDef rx_header;
|
||||||
uint8_t rx_data[8];
|
uint8_t rx_data[BSP_CAN_MAX_DLC];
|
||||||
|
|
||||||
// 遍历所有CAN接口处理FIFO0
|
// 遍历所有CAN接口处理FIFO0
|
||||||
for (int can_idx = 0; can_idx < BSP_CAN_NUM; can_idx++) {
|
for (int can_idx = 0; can_idx < BSP_CAN_NUM; can_idx++) {
|
||||||
@ -53,24 +153,33 @@ static void can_rx_fifo0_handler(void) {
|
|||||||
while (HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO0) > 0) {
|
while (HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO0) > 0) {
|
||||||
if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, rx_data) == HAL_OK) {
|
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;
|
uint32_t can_id = (rx_header.IDE == CAN_ID_STD) ? rx_header.StdId : rx_header.ExtId;
|
||||||
osMessageQueueId_t queue = find_queue(can_id);
|
|
||||||
if (queue) {
|
// 线程安全地查找队列
|
||||||
CAN_Message_t msg;
|
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;
|
msg.header = rx_header;
|
||||||
memcpy(msg.data, rx_data, 8);
|
memcpy(msg.data, rx_data, BSP_CAN_MAX_DLC);
|
||||||
|
|
||||||
// 非阻塞发送,如果队列满了就丢弃
|
// 非阻塞发送,如果队列满了就丢弃
|
||||||
osMessageQueuePut(queue, &msg, 0, 0);
|
osMessageQueuePut(queue, &msg, 0, BSP_CAN_TIMEOUT_IMMEDIATE);
|
||||||
}
|
}
|
||||||
// 如果没有找到对应的队列,消息被直接丢弃
|
}
|
||||||
|
// 如果没有找到对应的队列或获取互斥锁超时,消息被直接丢弃
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIFO1接收处理函数 */
|
/**
|
||||||
static void can_rx_fifo1_handler(void) {
|
* @brief FIFO1接收处理函数
|
||||||
|
*/
|
||||||
|
static void BSP_CAN_RxFifo1Handler(void) {
|
||||||
CAN_RxHeaderTypeDef rx_header;
|
CAN_RxHeaderTypeDef rx_header;
|
||||||
uint8_t rx_data[8];
|
uint8_t rx_data[BSP_CAN_MAX_DLC];
|
||||||
|
|
||||||
// 遍历所有CAN接口处理FIFO1
|
// 遍历所有CAN接口处理FIFO1
|
||||||
for (int can_idx = 0; can_idx < BSP_CAN_NUM; can_idx++) {
|
for (int can_idx = 0; can_idx < BSP_CAN_NUM; can_idx++) {
|
||||||
@ -80,133 +189,209 @@ static void can_rx_fifo1_handler(void) {
|
|||||||
while (HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO1) > 0) {
|
while (HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO1) > 0) {
|
||||||
if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO1, &rx_header, rx_data) == HAL_OK) {
|
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;
|
uint32_t can_id = (rx_header.IDE == CAN_ID_STD) ? rx_header.StdId : rx_header.ExtId;
|
||||||
osMessageQueueId_t queue = find_queue(can_id);
|
|
||||||
if (queue) {
|
|
||||||
CAN_Message_t msg;
|
|
||||||
msg.header = rx_header;
|
|
||||||
memcpy(msg.data, rx_data, 8);
|
|
||||||
// 非阻塞发送,如果队列满了就丢弃
|
|
||||||
osMessageQueuePut(queue, &msg, 0, 0);
|
|
||||||
}
|
|
||||||
// 如果没有找到对应的队列,消息被直接丢弃
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static BSP_CAN_t CAN_Get(CAN_HandleTypeDef *hcan) {
|
// 线程安全地查找队列
|
||||||
/* AUTO GENERATED CAN_GET */
|
if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) == osOK) {
|
||||||
else
|
osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id);
|
||||||
return BSP_CAN_ERR;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 如果没有找到对应的队列或获取互斥锁超时,消息被直接丢弃
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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 = BSP_CAN_GetInstance(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 (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX0_CPLT_CB] != NULL) {
|
||||||
CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_CPLT_CB]();
|
g_can_callbacks[bsp_can][BSP_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 = BSP_CAN_GetInstance(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 (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX1_CPLT_CB] != NULL) {
|
||||||
CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_CPLT_CB]();
|
g_can_callbacks[bsp_can][BSP_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 = BSP_CAN_GetInstance(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 (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX2_CPLT_CB] != NULL) {
|
||||||
CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_CPLT_CB]();
|
g_can_callbacks[bsp_can][BSP_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 = BSP_CAN_GetInstance(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 (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX0_ABORT_CB] != NULL) {
|
||||||
CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_ABORT_CB]();
|
g_can_callbacks[bsp_can][BSP_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 = BSP_CAN_GetInstance(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 (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX1_ABORT_CB] != NULL) {
|
||||||
CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_ABORT_CB]();
|
g_can_callbacks[bsp_can][BSP_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 = BSP_CAN_GetInstance(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 (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX2_ABORT_CB] != NULL) {
|
||||||
CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_ABORT_CB]();
|
g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX2_ABORT_CB]();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
|
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
|
||||||
BSP_CAN_t bsp_can = CAN_Get(hcan);
|
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
|
||||||
if (bsp_can != BSP_CAN_ERR) {
|
if (bsp_can != BSP_CAN_ERR) {
|
||||||
if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_MSG_PENDING_CB])
|
if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_MSG_PENDING_CB] != NULL) {
|
||||||
CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_MSG_PENDING_CB]();
|
g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_MSG_PENDING_CB]();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan) {
|
void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan) {
|
||||||
BSP_CAN_t bsp_can = CAN_Get(hcan);
|
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
|
||||||
if (bsp_can != BSP_CAN_ERR) {
|
if (bsp_can != BSP_CAN_ERR) {
|
||||||
if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_FULL_CB])
|
if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_FULL_CB] != NULL) {
|
||||||
CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_FULL_CB]();
|
g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_FULL_CB]();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) {
|
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) {
|
||||||
BSP_CAN_t bsp_can = CAN_Get(hcan);
|
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
|
||||||
if (bsp_can != BSP_CAN_ERR) {
|
if (bsp_can != BSP_CAN_ERR) {
|
||||||
if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_MSG_PENDING_CB])
|
if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_MSG_PENDING_CB] != NULL) {
|
||||||
CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_MSG_PENDING_CB]();
|
g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_MSG_PENDING_CB]();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan) {
|
void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan) {
|
||||||
BSP_CAN_t bsp_can = CAN_Get(hcan);
|
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
|
||||||
if (bsp_can != BSP_CAN_ERR) {
|
if (bsp_can != BSP_CAN_ERR) {
|
||||||
if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_FULL_CB])
|
if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_FULL_CB] != NULL) {
|
||||||
CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_FULL_CB]();
|
g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_FULL_CB]();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan) {
|
void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan) {
|
||||||
BSP_CAN_t bsp_can = CAN_Get(hcan);
|
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
|
||||||
if (bsp_can != BSP_CAN_ERR) {
|
if (bsp_can != BSP_CAN_ERR) {
|
||||||
if (CAN_Callback[bsp_can][HAL_CAN_SLEEP_CB])
|
if (g_can_callbacks[bsp_can][BSP_CAN_SLEEP_CB] != NULL) {
|
||||||
CAN_Callback[bsp_can][HAL_CAN_SLEEP_CB]();
|
g_can_callbacks[bsp_can][BSP_CAN_SLEEP_CB]();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan) {
|
void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan) {
|
||||||
BSP_CAN_t bsp_can = CAN_Get(hcan);
|
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
|
||||||
if (bsp_can != BSP_CAN_ERR) {
|
if (bsp_can != BSP_CAN_ERR) {
|
||||||
if (CAN_Callback[bsp_can][HAL_CAN_WAKEUP_FROM_RX_MSG_CB])
|
if (g_can_callbacks[bsp_can][BSP_CAN_WAKEUP_FROM_RX_MSG_CB] != NULL) {
|
||||||
CAN_Callback[bsp_can][HAL_CAN_WAKEUP_FROM_RX_MSG_CB]();
|
g_can_callbacks[bsp_can][BSP_CAN_WAKEUP_FROM_RX_MSG_CB]();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) {
|
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) {
|
||||||
BSP_CAN_t bsp_can = CAN_Get(hcan);
|
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan);
|
||||||
if (bsp_can != BSP_CAN_ERR) {
|
if (bsp_can != BSP_CAN_ERR) {
|
||||||
if (CAN_Callback[bsp_can][HAL_CAN_ERROR_CB])
|
if (g_can_callbacks[bsp_can][BSP_CAN_ERROR_CB] != NULL) {
|
||||||
CAN_Callback[bsp_can][HAL_CAN_ERROR_CB]();
|
g_can_callbacks[bsp_can][BSP_CAN_ERROR_CB]();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exported functions ------------------------------------------------------- */
|
/* Exported functions ------------------------------------------------------- */
|
||||||
|
|
||||||
|
int8_t BSP_CAN_Init(void) {
|
||||||
|
if (g_can_initialized) {
|
||||||
|
return BSP_ERR_INITED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清零回调函数数组
|
||||||
|
memset(g_can_callbacks, 0, sizeof(g_can_callbacks));
|
||||||
|
|
||||||
|
// 创建互斥锁
|
||||||
|
g_can_queue_mutex = osMutexNew(NULL);
|
||||||
|
if (g_can_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;
|
||||||
|
return BSP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t BSP_CAN_DeInit(void) {
|
||||||
|
if (!g_can_initialized) {
|
||||||
|
return BSP_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除所有队列
|
||||||
|
if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) == osOK) {
|
||||||
|
BSP_CAN_QueueNode_t *current = g_can_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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除互斥锁
|
||||||
|
if (g_can_queue_mutex != NULL) {
|
||||||
|
osMutexDelete(g_can_queue_mutex);
|
||||||
|
g_can_queue_mutex = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清零回调函数数组
|
||||||
|
memset(g_can_callbacks, 0, sizeof(g_can_callbacks));
|
||||||
|
|
||||||
|
g_can_initialized = false;
|
||||||
|
return BSP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
CAN_HandleTypeDef *BSP_CAN_GetHandle(BSP_CAN_t can) {
|
CAN_HandleTypeDef *BSP_CAN_GetHandle(BSP_CAN_t can) {
|
||||||
|
if (can >= BSP_CAN_NUM) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
switch (can) {
|
switch (can) {
|
||||||
/* AUTO GENERATED BSP_CAN_GET_HANDLE */
|
/* AUTO GENERATED BSP_CAN_GET_HANDLE */
|
||||||
default:
|
default:
|
||||||
@ -216,133 +401,163 @@ CAN_HandleTypeDef *BSP_CAN_GetHandle(BSP_CAN_t can) {
|
|||||||
|
|
||||||
int8_t BSP_CAN_RegisterCallback(BSP_CAN_t can, BSP_CAN_Callback_t type,
|
int8_t BSP_CAN_RegisterCallback(BSP_CAN_t can, BSP_CAN_Callback_t type,
|
||||||
void (*callback)(void)) {
|
void (*callback)(void)) {
|
||||||
if (callback == NULL) return BSP_ERR_NULL;
|
if (!g_can_initialized) {
|
||||||
if (can >= BSP_CAN_NUM) return BSP_ERR_INITED;
|
return BSP_ERR_INITED;
|
||||||
if (type >= BSP_CAN_CB_NUM) return BSP_ERR;
|
|
||||||
|
|
||||||
CAN_Callback[can][type] = callback;
|
|
||||||
return BSP_OK;
|
|
||||||
}
|
}
|
||||||
|
if (callback == NULL) {
|
||||||
int BSP_CAN_GetMessage(uint32_t can_id, CAN_Message_t *msg, uint32_t timeout) {
|
return BSP_ERR_NULL;
|
||||||
if (msg == NULL) return BSP_ERR_NULL;
|
|
||||||
osMessageQueueId_t queue = find_queue(can_id);
|
|
||||||
if (!queue) return BSP_ERR_NO_DEV; // 没有该队列
|
|
||||||
if (osMessageQueueGet(queue, msg, NULL, timeout) == osOK) {
|
|
||||||
return BSP_OK; // 成功
|
|
||||||
}
|
}
|
||||||
return BSP_ERR; // 超时或队列为空
|
if (can >= BSP_CAN_NUM) {
|
||||||
}
|
|
||||||
|
|
||||||
int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size) {
|
|
||||||
// 检查是否已存在
|
|
||||||
CAN_QueueNode_t *node = can_queue_list;
|
|
||||||
while (node) {
|
|
||||||
if (node->can_id == can_id) {
|
|
||||||
return BSP_ERR; // 已存在
|
|
||||||
}
|
|
||||||
node = node->next;
|
|
||||||
}
|
|
||||||
// 创建新节点
|
|
||||||
CAN_QueueNode_t *new_node = malloc(sizeof(CAN_QueueNode_t));
|
|
||||||
if (new_node == NULL) return BSP_ERR_NULL;
|
|
||||||
new_node->can_id = can_id;
|
|
||||||
new_node->queue_size = queue_size;
|
|
||||||
new_node->queue = osMessageQueueNew(queue_size, sizeof(CAN_Message_t), NULL);
|
|
||||||
if (new_node->queue == NULL) {
|
|
||||||
free(new_node);
|
|
||||||
return BSP_ERR;
|
return BSP_ERR;
|
||||||
}
|
}
|
||||||
new_node->next = can_queue_list;
|
if (type >= BSP_CAN_CB_NUM) {
|
||||||
can_queue_list = new_node;
|
return BSP_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_can_callbacks[can][type] = callback;
|
||||||
return BSP_OK;
|
return BSP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int8_t BSP_CAN_DeleteIdQueue(uint32_t can_id) {
|
|
||||||
CAN_QueueNode_t **current = &can_queue_list;
|
|
||||||
while (*current) {
|
|
||||||
if ((*current)->can_id == can_id) {
|
|
||||||
CAN_QueueNode_t *to_delete = *current;
|
|
||||||
*current = (*current)->next;
|
|
||||||
osMessageQueueDelete(to_delete->queue);
|
|
||||||
free(to_delete);
|
|
||||||
return BSP_OK;
|
|
||||||
}
|
|
||||||
current = &(*current)->next;
|
|
||||||
}
|
|
||||||
return BSP_ERR; // 未找到
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void BSP_CAN_RegisterId(uint32_t can_id, uint8_t queue_size) {
|
|
||||||
BSP_CAN_CreateIdQueue(can_id, queue_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format,
|
int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format,
|
||||||
uint32_t id, uint8_t *data, uint8_t dlc) {
|
uint32_t id, uint8_t *data, uint8_t dlc) {
|
||||||
if (can >= BSP_CAN_NUM) return BSP_ERR;
|
if (!g_can_initialized) {
|
||||||
if (data == NULL) return BSP_ERR_NULL;
|
return BSP_ERR_INITED;
|
||||||
if (dlc > 8) return BSP_ERR;
|
}
|
||||||
|
if (can >= BSP_CAN_NUM) {
|
||||||
|
return BSP_ERR;
|
||||||
|
}
|
||||||
|
if (data == NULL) {
|
||||||
|
return BSP_ERR_NULL;
|
||||||
|
}
|
||||||
|
if (dlc > BSP_CAN_MAX_DLC) {
|
||||||
|
return BSP_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
CAN_HandleTypeDef *hcan = BSP_CAN_GetHandle(can);
|
CAN_HandleTypeDef *hcan = BSP_CAN_GetHandle(can);
|
||||||
if (hcan == NULL) return BSP_ERR_NULL;
|
if (hcan == NULL) {
|
||||||
|
return BSP_ERR_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
CAN_TxHeaderTypeDef header;
|
CAN_TxHeaderTypeDef header = {0};
|
||||||
uint32_t mailbox;
|
uint32_t mailbox;
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case CAN_FORMAT_STD_DATA:
|
case BSP_CAN_FORMAT_STD_DATA:
|
||||||
header.StdId = id;
|
header.StdId = id;
|
||||||
header.IDE = CAN_ID_STD;
|
header.IDE = CAN_ID_STD;
|
||||||
header.RTR = CAN_RTR_DATA;
|
header.RTR = CAN_RTR_DATA;
|
||||||
header.TransmitGlobalTime = DISABLE;
|
|
||||||
header.DLC = dlc;
|
|
||||||
break;
|
break;
|
||||||
case CAN_FORMAT_EXT_DATA:
|
case BSP_CAN_FORMAT_EXT_DATA:
|
||||||
header.ExtId = id;
|
header.ExtId = id;
|
||||||
header.IDE = CAN_ID_EXT;
|
header.IDE = CAN_ID_EXT;
|
||||||
header.RTR = CAN_RTR_DATA;
|
header.RTR = CAN_RTR_DATA;
|
||||||
header.TransmitGlobalTime = DISABLE;
|
|
||||||
header.DLC = dlc;
|
|
||||||
break;
|
break;
|
||||||
case CAN_FORMAT_STD_REMOTE:
|
case BSP_CAN_FORMAT_STD_REMOTE:
|
||||||
header.StdId = id;
|
header.StdId = id;
|
||||||
header.IDE = CAN_ID_STD;
|
header.IDE = CAN_ID_STD;
|
||||||
header.RTR = CAN_RTR_REMOTE;
|
header.RTR = CAN_RTR_REMOTE;
|
||||||
header.TransmitGlobalTime = DISABLE;
|
|
||||||
header.DLC = dlc;
|
|
||||||
break;
|
break;
|
||||||
case CAN_FORMAT_EXT_REMOTE:
|
case BSP_CAN_FORMAT_EXT_REMOTE:
|
||||||
header.ExtId = id;
|
header.ExtId = id;
|
||||||
header.IDE = CAN_ID_EXT;
|
header.IDE = CAN_ID_EXT;
|
||||||
header.RTR = CAN_RTR_REMOTE;
|
header.RTR = CAN_RTR_REMOTE;
|
||||||
header.TransmitGlobalTime = DISABLE;
|
|
||||||
header.DLC = dlc;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return BSP_ERR;
|
return BSP_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
HAL_StatusTypeDef res = HAL_CAN_AddTxMessage(hcan, &header, data, &mailbox);
|
header.DLC = dlc;
|
||||||
|
header.TransmitGlobalTime = DISABLE;
|
||||||
|
|
||||||
if (res == HAL_OK) {
|
HAL_StatusTypeDef result = HAL_CAN_AddTxMessage(hcan, &header, data, &mailbox);
|
||||||
return BSP_OK;
|
return (result == HAL_OK) ? BSP_OK : BSP_ERR;
|
||||||
} else {
|
|
||||||
return BSP_ERR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t BSP_CAN_Init(void) {
|
int8_t BSP_CAN_RegisterId(uint32_t can_id, uint8_t queue_size) {
|
||||||
/* AUTO GENERATED CAN_INIT */
|
if (!g_can_initialized) {
|
||||||
|
return BSP_ERR_INITED;
|
||||||
|
}
|
||||||
|
|
||||||
// 注册接收中断处理函数
|
return BSP_CAN_CreateIdQueue(can_id, queue_size);
|
||||||
for (int can_idx = 0; can_idx < BSP_CAN_NUM; can_idx++) {
|
}
|
||||||
BSP_CAN_RegisterCallback((BSP_CAN_t)can_idx, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, can_rx_fifo0_handler);
|
|
||||||
BSP_CAN_RegisterCallback((BSP_CAN_t)can_idx, HAL_CAN_RX_FIFO1_MSG_PENDING_CB, can_rx_fifo1_handler);
|
int8_t BSP_CAN_UnregisterIdQueue(uint32_t can_id) {
|
||||||
|
if (!g_can_initialized) {
|
||||||
|
return BSP_ERR_INITED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BSP_CAN_DeleteIdQueue(can_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t BSP_CAN_GetMessage(uint32_t can_id, BSP_CAN_Message_t *msg, uint32_t timeout) {
|
||||||
|
if (!g_can_initialized) {
|
||||||
|
return BSP_ERR_INITED;
|
||||||
|
}
|
||||||
|
if (msg == NULL) {
|
||||||
|
return BSP_ERR_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 线程安全地查找队列
|
||||||
|
if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
|
||||||
|
return BSP_ERR_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id);
|
||||||
|
osMutexRelease(g_can_queue_mutex);
|
||||||
|
|
||||||
|
if (queue == NULL) {
|
||||||
|
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) {
|
||||||
|
if (!g_can_initialized) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 线程安全地查找队列
|
||||||
|
if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id);
|
||||||
|
osMutexRelease(g_can_queue_mutex);
|
||||||
|
|
||||||
|
if (queue == NULL) {
|
||||||
|
return -1; // 队列不存在
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int32_t)osMessageQueueGetCount(queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t BSP_CAN_FlushQueue(uint32_t can_id) {
|
||||||
|
if (!g_can_initialized) {
|
||||||
|
return BSP_ERR_INITED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 线程安全地查找队列
|
||||||
|
if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
|
||||||
|
return BSP_ERR_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id);
|
||||||
|
osMutexRelease(g_can_queue_mutex);
|
||||||
|
|
||||||
|
if (queue == NULL) {
|
||||||
|
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;
|
return BSP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* USER CAN FUNCTIONS BEGIN */
|
||||||
|
/* USER CAN FUNCTIONS END */
|
@ -7,117 +7,138 @@ extern "C" {
|
|||||||
/* Includes ----------------------------------------------------------------- */
|
/* Includes ----------------------------------------------------------------- */
|
||||||
#include <can.h>
|
#include <can.h>
|
||||||
#include "bsp/bsp.h"
|
#include "bsp/bsp.h"
|
||||||
|
#include "bsp/mm.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <cmsis_os.h>
|
#include <cmsis_os.h>
|
||||||
|
|
||||||
/* Exported constants ------------------------------------------------------- */
|
/* Exported constants ------------------------------------------------------- */
|
||||||
|
#define BSP_CAN_MAX_DLC 8
|
||||||
|
#define BSP_CAN_DEFAULT_QUEUE_SIZE 10
|
||||||
|
#define BSP_CAN_TIMEOUT_IMMEDIATE 0
|
||||||
|
#define BSP_CAN_TIMEOUT_FOREVER osWaitForever
|
||||||
|
|
||||||
/* Exported macro ----------------------------------------------------------- */
|
/* Exported macro ----------------------------------------------------------- */
|
||||||
/* Exported types ----------------------------------------------------------- */
|
/* Exported types ----------------------------------------------------------- */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* AUTO GENERATED BSP_CAN_NAME */
|
/* AUTO GENERATED BSP_CAN_NAME */
|
||||||
BSP_CAN_NUM,
|
BSP_CAN_NUM,
|
||||||
BSP_CAN_ERR,
|
BSP_CAN_ERR = 0xFF,
|
||||||
} BSP_CAN_t;
|
} BSP_CAN_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
HAL_CAN_TX_MAILBOX0_CPLT_CB,
|
BSP_CAN_TX_MAILBOX0_CPLT_CB,
|
||||||
HAL_CAN_TX_MAILBOX1_CPLT_CB,
|
BSP_CAN_TX_MAILBOX1_CPLT_CB,
|
||||||
HAL_CAN_TX_MAILBOX2_CPLT_CB,
|
BSP_CAN_TX_MAILBOX2_CPLT_CB,
|
||||||
HAL_CAN_TX_MAILBOX0_ABORT_CB,
|
BSP_CAN_TX_MAILBOX0_ABORT_CB,
|
||||||
HAL_CAN_TX_MAILBOX1_ABORT_CB,
|
BSP_CAN_TX_MAILBOX1_ABORT_CB,
|
||||||
HAL_CAN_TX_MAILBOX2_ABORT_CB,
|
BSP_CAN_TX_MAILBOX2_ABORT_CB,
|
||||||
HAL_CAN_RX_FIFO0_MSG_PENDING_CB,
|
BSP_CAN_RX_FIFO0_MSG_PENDING_CB,
|
||||||
HAL_CAN_RX_FIFO0_FULL_CB,
|
BSP_CAN_RX_FIFO0_FULL_CB,
|
||||||
HAL_CAN_RX_FIFO1_MSG_PENDING_CB,
|
BSP_CAN_RX_FIFO1_MSG_PENDING_CB,
|
||||||
HAL_CAN_RX_FIFO1_FULL_CB,
|
BSP_CAN_RX_FIFO1_FULL_CB,
|
||||||
HAL_CAN_SLEEP_CB,
|
BSP_CAN_SLEEP_CB,
|
||||||
HAL_CAN_WAKEUP_FROM_RX_MSG_CB,
|
BSP_CAN_WAKEUP_FROM_RX_MSG_CB,
|
||||||
HAL_CAN_ERROR_CB,
|
BSP_CAN_ERROR_CB,
|
||||||
BSP_CAN_CB_NUM
|
BSP_CAN_CB_NUM
|
||||||
} BSP_CAN_Callback_t;
|
} BSP_CAN_Callback_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CAN_FORMAT_STD_DATA, /* 标准数据帧 */
|
BSP_CAN_FORMAT_STD_DATA, /* 标准数据帧 */
|
||||||
CAN_FORMAT_EXT_DATA, /* 扩展数据帧 */
|
BSP_CAN_FORMAT_EXT_DATA, /* 扩展数据帧 */
|
||||||
CAN_FORMAT_STD_REMOTE, /* 标准远程帧 */
|
BSP_CAN_FORMAT_STD_REMOTE, /* 标准远程帧 */
|
||||||
CAN_FORMAT_EXT_REMOTE, /* 扩展远程帧 */
|
BSP_CAN_FORMAT_EXT_REMOTE, /* 扩展远程帧 */
|
||||||
} BSP_CAN_Format_t;
|
} BSP_CAN_Format_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
CAN_RxHeaderTypeDef header;
|
CAN_RxHeaderTypeDef header;
|
||||||
uint8_t data[8];
|
uint8_t data[BSP_CAN_MAX_DLC];
|
||||||
} CAN_Message_t;
|
} BSP_CAN_Message_t;
|
||||||
|
|
||||||
/* Exported functions prototypes -------------------------------------------- */
|
/* Exported functions prototypes -------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化 CAN 模块
|
||||||
|
* @return BSP_OK 成功,其他值失败
|
||||||
|
*/
|
||||||
|
int8_t BSP_CAN_Init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 反初始化 CAN 模块
|
||||||
|
* @return BSP_OK 成功,其他值失败
|
||||||
|
*/
|
||||||
|
int8_t BSP_CAN_DeInit(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 获取 CAN 句柄
|
* @brief 获取 CAN 句柄
|
||||||
* @param can CAN 枚举类型
|
* @param can CAN 枚举
|
||||||
* @return CAN_HandleTypeDef 指针,失败返回 NULL
|
* @return CAN_HandleTypeDef 指针,失败返回 NULL
|
||||||
*/
|
*/
|
||||||
CAN_HandleTypeDef *BSP_CAN_GetHandle(BSP_CAN_t can);
|
CAN_HandleTypeDef *BSP_CAN_GetHandle(BSP_CAN_t can);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 注册 CAN 回调
|
* @brief 注册 CAN 回调函数
|
||||||
* @param can CAN 枚举类型
|
* @param can CAN 枚举
|
||||||
* @param type 回调类型
|
* @param type 回调类型
|
||||||
* @param callback 回调函数指针
|
* @param callback 回调函数指针
|
||||||
* @return BSP_OK 成功,BSP_ERR_NULL/BSP_ERR_INVALID_PARAM 失败
|
* @return BSP_OK 成功,其他值失败
|
||||||
*/
|
*/
|
||||||
int8_t BSP_CAN_RegisterCallback(BSP_CAN_t can, BSP_CAN_Callback_t type,
|
int8_t BSP_CAN_RegisterCallback(BSP_CAN_t can, BSP_CAN_Callback_t type,
|
||||||
void (*callback)(void));
|
void (*callback)(void));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 发送 CAN 消息
|
* @brief 发送 CAN 消息
|
||||||
* @param can CAN 枚举类型
|
* @param can CAN 枚举
|
||||||
* @param format 消息格式
|
* @param format 消息格式
|
||||||
* @param id CAN ID
|
* @param id CAN ID
|
||||||
* @param data 数据指针
|
* @param data 数据指针
|
||||||
* @param dlc 数据长度
|
* @param dlc 数据长度
|
||||||
* @return BSP_OK 成功,BSP_ERR/BSP_ERR_NULL/BSP_ERR_INVALID_PARAM 失败
|
* @return BSP_OK 成功,其他值失败
|
||||||
*/
|
*/
|
||||||
int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format,
|
int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format,
|
||||||
uint32_t id, uint8_t *data, uint8_t dlc);
|
uint32_t id, uint8_t *data, uint8_t dlc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 初始化 CAN
|
* @brief 注册 CAN ID 接收队列
|
||||||
* @return BSP_OK 成功,BSP_ERR/BSP_ERR_NULL/BSP_ERR_INITED 失败
|
* @param can_id CAN ID
|
||||||
|
* @param queue_size 队列大小,0使用默认值
|
||||||
|
* @return BSP_OK 成功,其他值失败
|
||||||
*/
|
*/
|
||||||
int8_t BSP_CAN_Init(void);
|
int8_t BSP_CAN_RegisterId(uint32_t can_id, uint8_t queue_size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 获取 CAN 消息
|
* @brief 注销 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 msg 存储消息的结构体指针
|
||||||
* @param timeout 超时时间(毫秒)
|
* @param timeout 超时时间(毫秒),0为立即返回,osWaitForever为永久等待
|
||||||
* @return BSP_OK 成功,BSP_ERR/BSP_ERR_NULL/BSP_ERR_NO_DEV 失败
|
* @return BSP_OK 成功,其他值失败
|
||||||
*/
|
*/
|
||||||
int BSP_CAN_GetMessage(uint32_t can_id, CAN_Message_t *msg, uint32_t timeout);
|
int8_t BSP_CAN_GetMessage(uint32_t can_id, BSP_CAN_Message_t *msg, uint32_t timeout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 注册 CAN ID
|
* @brief 获取指定ID队列中的消息数量
|
||||||
* @param can_id CAN ID
|
* @param can_id CAN ID
|
||||||
* @param queue_size 队列大小
|
* @return 消息数量,-1表示队列不存在
|
||||||
* @return 无
|
|
||||||
*/
|
*/
|
||||||
void BSP_CAN_RegisterId(uint32_t can_id, uint8_t queue_size);
|
int32_t BSP_CAN_GetQueueCount(uint32_t can_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 创建指定 CAN ID 的队列
|
* @brief 清空指定ID队列中的所有消息
|
||||||
* @param can_id CAN ID
|
* @param can_id CAN ID
|
||||||
* @param queue_size 队列大小
|
* @return BSP_OK 成功,其他值失败
|
||||||
* @return BSP_OK 成功,BSP_ERR/BSP_ERR_NULL/BSP_ERR_INVALID_PARAM 失败
|
|
||||||
*/
|
*/
|
||||||
int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size);
|
int8_t BSP_CAN_FlushQueue(uint32_t can_id);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 删除指定 CAN ID 的队列
|
|
||||||
* @param can_id CAN ID
|
|
||||||
* @return BSP_OK 成功,BSP_ERR/BSP_ERR_INVALID_PARAM 失败
|
|
||||||
*/
|
|
||||||
int8_t BSP_CAN_DeleteIdQueue(uint32_t can_id);
|
|
||||||
|
|
||||||
/* USER CAN FUNCTIONS BEGIN */
|
/* USER CAN FUNCTIONS BEGIN */
|
||||||
/* USER CAN FUNCTIONS END */
|
/* USER CAN FUNCTIONS END */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user