can支持自定义id解析了

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

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -2,6 +2,11 @@
"files.associations": {
"user_math.h": "c",
"bsp.h": "c",
"stdint.h": "c"
"stdint.h": "c",
"array": "c",
"string": "c",
"string_view": "c",
"vector": "c",
"can.h": "c"
}
}

Binary file not shown.

View File

@ -155,30 +155,49 @@ class CodeGenerateInterface(QWidget):
def generate_code(self):
"""生成代码逻辑"""
# 收集所有已加载的页面对象
pages = []
for i in range(self.stack.count()):
widget = self.stack.widget(i)
pages.append(widget)
"""生成代码逻辑 - 修复导入问题"""
try:
# 收集所有已加载的页面对象
pages = []
for i in range(self.stack.count()):
widget = self.stack.widget(i)
pages.append(widget)
# 生成 BSP 代码
bsp_result = bsp.generate_bsp(self.project_path, pages)
# 确保导入成功
from app.code_page.bsp_interface import bsp
from app.code_page.component_interface import component
# 生成 Component 代码
from app.code_page.component_interface import component
component_result = component.generate_component(self.project_path, pages)
# 生成 BSP 代码
bsp_result = bsp.generate_bsp(self.project_path, pages)
# 合并结果信息
combined_result = f"BSP代码生成:\n{bsp_result}\n\nComponent代码生成:\n{component_result}"
# 生成 Component 代码
component_result = component.generate_component(self.project_path, pages)
# 用 InfoBar 在主界面弹出
InfoBar.success(
title="代码生成结果",
content=combined_result,
parent=self,
duration=5000 # 增加显示时间,因为内容更多
)
# 合并结果信息
combined_result = f"BSP代码生成:\n{bsp_result}\n\nComponent代码生成:\n{component_result}"
# 用 InfoBar 在主界面弹出
InfoBar.success(
title="代码生成结果",
content=combined_result,
parent=self,
duration=5000
)
except ImportError as e:
InfoBar.error(
title="导入错误",
content=f"模块导入失败: {str(e)}",
parent=self,
duration=3000
)
except Exception as e:
InfoBar.error(
title="生成失败",
content=f"代码生成过程中出现错误: {str(e)}",
parent=self,
duration=3000
)
def _get_freertos_status(self):
"""获取FreeRTOS状态"""
@ -220,7 +239,6 @@ class CodeGenerateInterface(QWidget):
if widget:
self.stack.setCurrentWidget(widget)
# ...existing code...
def _get_or_create_page(self, class_name):
"""获取或创建页面"""
if class_name in self.page_cache:
@ -235,12 +253,12 @@ class CodeGenerateInterface(QWidget):
if class_name.startswith('bsp_'):
# BSP页面
from app.code_page.bsp_interface import get_bsp_page
# 提取外设名,如 bsp_delay -> delay
periph_name = class_name[len('bsp_'):].replace("_", " ")
# 提取外设名,如 bsp_error_detect -> error_detect
periph_name = class_name[len('bsp_'):] # 移除 .replace("_", " ")
page = get_bsp_page(periph_name, self.project_path)
elif class_name.startswith('component_'):
from app.code_page.component_interface import get_component_page
comp_name = class_name[len('component_'):].replace("_", " ")
comp_name = class_name[len('component_'):] # 移除 .replace("_", " ")
page = get_component_page(comp_name, self.project_path, self.component_manager)
self.component_manager.register_component(page.component_name, page)
else:
@ -254,4 +272,3 @@ class CodeGenerateInterface(QWidget):
print(f"创建页面 {class_name} 失败: {e}")
return None
# ...existing code...

Binary file not shown.

View File

@ -399,20 +399,21 @@ class bsp_can(BspPeripheralBase):
get_available_can
)
def _generate_source_file(self, configs, template_dir):
template_path = os.path.join(template_dir, self.template_names['source'])
template_content = CodeGenerator.load_template(template_path)
if not template_content:
return False
# Get函数
# CAN_Get函数
get_lines = []
for idx, (name, instance) in enumerate(configs):
if idx == 0:
get_lines.append(f" if (hcan->Instance == {instance})")
get_lines.append(f" if (hcan->Instance == {instance})")
else:
get_lines.append(f" else if (hcan->Instance == {instance})")
get_lines.append(f" return {self.enum_prefix}_{name};")
get_lines.append(f" else if (hcan->Instance == {instance})")
get_lines.append(f" return {self.enum_prefix}_{name};")
content = CodeGenerator.replace_auto_generated(
template_content, "AUTO GENERATED CAN_GET", "\n".join(get_lines)
)
@ -420,40 +421,105 @@ class bsp_can(BspPeripheralBase):
# Handle函数
handle_lines = []
for name, instance in configs:
num = ''.join(filter(str.isdigit, instance)) # 提取数字
handle_lines.append(f" case {self.enum_prefix}_{name}:")
handle_lines.append(f" return &h{instance.lower()};")
handle_lines.append(f" return &hcan{num};")
content = CodeGenerator.replace_auto_generated(
content, f"AUTO GENERATED {self.enum_prefix}_GET_HANDLE", "\n".join(handle_lines)
)
# 生成CAN初始化代码
init_lines = []
for idx, (name, instance) in enumerate(configs):
can_num = instance[-1] # CAN1 -> 1, CAN2 -> 2
# 先设置初始化标志
init_lines.append(" // 先设置初始化标志,以便后续回调注册能通过检查")
init_lines.append(" inited = true;")
init_lines.append("")
init_lines.append(f" // 初始化 {instance}")
init_lines.append(f" CAN_FilterTypeDef can{can_num}_filter = {{0}};")
init_lines.append(f" can{can_num}_filter.FilterBank = {0 if can_num == '1' else 14};")
init_lines.append(f" can{can_num}_filter.FilterIdHigh = 0;")
init_lines.append(f" can{can_num}_filter.FilterIdLow = 0;")
init_lines.append(f" can{can_num}_filter.FilterMode = CAN_FILTERMODE_IDMASK;")
init_lines.append(f" can{can_num}_filter.FilterScale = CAN_FILTERSCALE_32BIT;")
init_lines.append(f" can{can_num}_filter.FilterMaskIdHigh = 0;")
init_lines.append(f" can{can_num}_filter.FilterMaskIdLow = 0;")
init_lines.append(f" can{can_num}_filter.FilterActivation = ENABLE;")
if can_num == '1':
init_lines.append(f" can{can_num}_filter.SlaveStartFilterBank = 14;")
init_lines.append(f" can{can_num}_filter.FilterFIFOAssignment = CAN_RX_FIFO0;")
else:
init_lines.append(f" can{can_num}_filter.FilterFIFOAssignment = CAN_RX_FIFO1;")
# 检查是否同时有CAN1和CAN2
has_can1 = any(instance == 'CAN1' for _, instance in configs)
has_can2 = any(instance == 'CAN2' for _, instance in configs)
init_lines.append(f" HAL_CAN_ConfigFilter(BSP_CAN_GetHandle({self.enum_prefix}_{name}), &can{can_num}_filter);")
init_lines.append(f" HAL_CAN_Start(BSP_CAN_GetHandle({self.enum_prefix}_{name}));")
if has_can1 and has_can2:
# 同时配置CAN1和CAN2的情况 - 统一使用FIFO0
init_lines.extend([
" // 初始化 CAN1 - 使用 FIFO0",
" CAN_FilterTypeDef can1_filter = {0};",
" can1_filter.FilterBank = 0;",
" can1_filter.FilterIdHigh = 0;",
" can1_filter.FilterIdLow = 0;",
" can1_filter.FilterMode = CAN_FILTERMODE_IDMASK;",
" can1_filter.FilterScale = CAN_FILTERSCALE_32BIT;",
" can1_filter.FilterMaskIdHigh = 0;",
" can1_filter.FilterMaskIdLow = 0;",
" can1_filter.FilterActivation = ENABLE;",
" can1_filter.SlaveStartFilterBank = 14; // 重要:设置从过滤器起始组",
" can1_filter.FilterFIFOAssignment = CAN_RX_FIFO0;",
" HAL_CAN_ConfigFilter(&hcan1, &can1_filter);",
" HAL_CAN_Start(&hcan1);",
" HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);",
"",
" // 初始化 CAN2 - 使用 FIFO0注意通过 CAN1 配置 CAN2 的过滤器)",
" CAN_FilterTypeDef can2_filter = {0};",
" can2_filter.FilterBank = 14; // CAN2 使用过滤器组 14",
" can2_filter.FilterIdHigh = 0;",
" can2_filter.FilterIdLow = 0;",
" can2_filter.FilterMode = CAN_FILTERMODE_IDMASK;",
" can2_filter.FilterScale = CAN_FILTERSCALE_32BIT;",
" can2_filter.FilterMaskIdHigh = 0;",
" can2_filter.FilterMaskIdLow = 0;",
" can2_filter.FilterActivation = ENABLE;",
" can2_filter.FilterFIFOAssignment = CAN_RX_FIFO0; // 改为 FIFO0",
" HAL_CAN_ConfigFilter(&hcan1, &can2_filter); // 通过 CAN1 配置",
" HAL_CAN_Start(&hcan2);",
" HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_MSG_PENDING); // 激活 FIFO0 中断",
"",
" // 注册回调函数",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_CAN1, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifoCallback);",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_CAN2, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifoCallback);",
])
else:
# 只有单个CAN的情况
for idx, (name, instance) in enumerate(configs):
can_num = instance[-1] # CAN1 -> 1, CAN2 -> 2
# 注册回调和激活中断
fifo = "FIFO0" if can_num == '1' else "FIFO1"
init_lines.append(f" HAL_CAN_ActivateNotification(BSP_CAN_GetHandle({self.enum_prefix}_{name}), CAN_IT_RX_{fifo}_MSG_PENDING);")
init_lines.append("")
init_lines.append(f" // 初始化 {instance}")
init_lines.append(f" CAN_FilterTypeDef can{can_num}_filter = {{0}};")
if instance == 'CAN1':
init_lines.extend([
f" can{can_num}_filter.FilterBank = 0;",
f" can{can_num}_filter.SlaveStartFilterBank = 14;",
f" can{can_num}_filter.FilterFIFOAssignment = CAN_RX_FIFO0;",
])
else: # CAN2
init_lines.extend([
f" can{can_num}_filter.FilterBank = 14;",
f" can{can_num}_filter.FilterFIFOAssignment = CAN_RX_FIFO0;",
])
init_lines.extend([
f" can{can_num}_filter.FilterIdHigh = 0;",
f" can{can_num}_filter.FilterIdLow = 0;",
f" can{can_num}_filter.FilterMode = CAN_FILTERMODE_IDMASK;",
f" can{can_num}_filter.FilterScale = CAN_FILTERSCALE_32BIT;",
f" can{can_num}_filter.FilterMaskIdHigh = 0;",
f" can{can_num}_filter.FilterMaskIdLow = 0;",
f" can{can_num}_filter.FilterActivation = ENABLE;",
])
if instance == 'CAN2':
init_lines.append(f" HAL_CAN_ConfigFilter(&hcan1, &can{can_num}_filter); // 通过 CAN1 配置")
else:
init_lines.append(f" HAL_CAN_ConfigFilter(&hcan{can_num}, &can{can_num}_filter);")
init_lines.extend([
f" HAL_CAN_Start(&hcan{can_num});",
f" HAL_CAN_ActivateNotification(&hcan{can_num}, CAN_IT_RX_FIFO0_MSG_PENDING);",
"",
f" // 注册回调函数",
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifoCallback);",
""
])
content = CodeGenerator.replace_auto_generated(
content, "AUTO GENERATED CAN_INIT", "\n".join(init_lines)
@ -463,6 +529,8 @@ class bsp_can(BspPeripheralBase):
save_with_preserve(output_path, content)
return True
class bsp_spi(BspPeripheralBase):
def __init__(self, project_path):
super().__init__(
@ -654,16 +722,17 @@ class bsp_gpio(QWidget):
template_content, "AUTO GENERATED BSP_GPIO_MAP", "\n".join(map_lines)
)
# 生成EXTI使能代码
# 生成EXTI使能代码 - 使用用户自定义的BSP枚举名称
enable_lines = []
disable_lines = []
for config in configs:
if config['has_exti']:
ioc_label = config['ioc_label']
enable_lines.append(f" case {ioc_label}_Pin:")
custom_name = config['custom_name']
enable_lines.append(f" case BSP_GPIO_{custom_name}:")
enable_lines.append(f" HAL_NVIC_EnableIRQ({ioc_label}_EXTI_IRQn);")
enable_lines.append(f" break;")
disable_lines.append(f" case {ioc_label}_Pin:")
disable_lines.append(f" case BSP_GPIO_{custom_name}:")
disable_lines.append(f" HAL_NVIC_DisableIRQ({ioc_label}_EXTI_IRQn);")
disable_lines.append(f" break;")
@ -678,6 +747,8 @@ class bsp_gpio(QWidget):
save_with_preserve(output_path, content)
return True
def _save_config(self, configs):
config_path = os.path.join(self.project_path, "User/bsp/bsp_config.yaml")
config_data = CodeGenerator.load_config(config_path)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -2,7 +2,8 @@ import os
import yaml
import shutil
from typing import Dict, List, Tuple
import sys
import os
class CodeGenerator:
"""通用代码生成器"""
@ -61,15 +62,20 @@ class CodeGenerator:
@staticmethod
def get_template_dir():
"""获取模板文件目录"""
# 从当前文件向上找到 MRobot 目录,然后定位到模板目录
current_dir = os.path.dirname(os.path.abspath(__file__))
# 向上找到 MRobot 根目录
while os.path.basename(current_dir) != 'MRobot' and current_dir != '/':
current_dir = os.path.dirname(current_dir)
if os.path.basename(current_dir) == 'MRobot':
return os.path.join(current_dir, "assets/User_code/bsp")
"""获取模板目录路径,兼容打包环境"""
if getattr(sys, 'frozen', False):
# 打包后的环境
base_path = sys._MEIPASS
template_dir = os.path.join(base_path, "assets", "User_code", "bsp")
else:
# 如果找不到,使用相对路径作为备选
return os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "assets/User_code/bsp")
# 开发环境
current_dir = os.path.dirname(os.path.abspath(__file__))
while os.path.basename(current_dir) != 'MRobot' and current_dir != '/':
current_dir = os.path.dirname(current_dir)
template_dir = os.path.join(current_dir, "assets", "User_code", "bsp")
print(f"模板目录路径: {template_dir}")
if not os.path.exists(template_dir):
print(f"警告:模板目录不存在: {template_dir}")
return template_dir

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);
// 获取帧类型
BSP_CAN_FrameType_t frame_type = BSP_CAN_GetFrameType(&rx_header);
if (queue != NULL) {
BSP_CAN_Message_t msg;
msg.header = rx_header;
memcpy(msg.data, rx_data, BSP_CAN_MAX_DLC);
// 解析ID
uint32_t parsed_id = BSP_CAN_ParseId(original_id, frame_type);
// 非阻塞发送,如果队列满了就丢弃
osMessageQueuePut(queue, &msg, 0, BSP_CAN_TIMEOUT_IMMEDIATE);
// 直接查找队列,不使用互斥锁(中断中快速执行)
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);
}
// 如果没有找到对应的队列或获取互斥锁超时,消息被直接丢弃
}
}
}
}
/**
* @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;
// 线程安全地查找队列
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);
}
}
// 如果没有找到对应的队列或获取互斥锁超时,消息被直接丢弃
}
}
}
@ -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 0osWaitForever为永久等待
* @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

5
gpio.h
View File

@ -26,8 +26,9 @@ 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);