diff --git a/.DS_Store b/.DS_Store index 6e47c2f..765ded4 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/.vscode/settings.json b/.vscode/settings.json index eaab07f..ec48fa4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -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" } } \ No newline at end of file diff --git a/app/__pycache__/about_interface.cpython-39.pyc b/app/__pycache__/about_interface.cpython-39.pyc index 8c795a0..ab4ca22 100644 Binary files a/app/__pycache__/about_interface.cpython-39.pyc and b/app/__pycache__/about_interface.cpython-39.pyc differ diff --git a/app/__pycache__/ai_interface.cpython-39.pyc b/app/__pycache__/ai_interface.cpython-39.pyc index cfeebb9..27c46c1 100644 Binary files a/app/__pycache__/ai_interface.cpython-39.pyc and b/app/__pycache__/ai_interface.cpython-39.pyc differ diff --git a/app/__pycache__/code_configuration_interface.cpython-39.pyc b/app/__pycache__/code_configuration_interface.cpython-39.pyc new file mode 100644 index 0000000..b341a88 Binary files /dev/null and b/app/__pycache__/code_configuration_interface.cpython-39.pyc differ diff --git a/app/__pycache__/code_generate_interface.cpython-39.pyc b/app/__pycache__/code_generate_interface.cpython-39.pyc new file mode 100644 index 0000000..b4cffe4 Binary files /dev/null and b/app/__pycache__/code_generate_interface.cpython-39.pyc differ diff --git a/app/__pycache__/data_interface.cpython-39.pyc b/app/__pycache__/data_interface.cpython-39.pyc index 41a0056..e389e44 100644 Binary files a/app/__pycache__/data_interface.cpython-39.pyc and b/app/__pycache__/data_interface.cpython-39.pyc differ diff --git a/app/__pycache__/function_fit_interface.cpython-39.pyc b/app/__pycache__/function_fit_interface.cpython-39.pyc index 2842399..dd6a1b8 100644 Binary files a/app/__pycache__/function_fit_interface.cpython-39.pyc and b/app/__pycache__/function_fit_interface.cpython-39.pyc differ diff --git a/app/__pycache__/home_interface.cpython-39.pyc b/app/__pycache__/home_interface.cpython-39.pyc index 1491394..7b34d20 100644 Binary files a/app/__pycache__/home_interface.cpython-39.pyc and b/app/__pycache__/home_interface.cpython-39.pyc differ diff --git a/app/__pycache__/main_window.cpython-39.pyc b/app/__pycache__/main_window.cpython-39.pyc index b02a880..e6c11c8 100644 Binary files a/app/__pycache__/main_window.cpython-39.pyc and b/app/__pycache__/main_window.cpython-39.pyc differ diff --git a/app/__pycache__/mini_tool_interface.cpython-39.pyc b/app/__pycache__/mini_tool_interface.cpython-39.pyc index f93141a..5ee51b8 100644 Binary files a/app/__pycache__/mini_tool_interface.cpython-39.pyc and b/app/__pycache__/mini_tool_interface.cpython-39.pyc differ diff --git a/app/__pycache__/part_library_interface.cpython-39.pyc b/app/__pycache__/part_library_interface.cpython-39.pyc index 3674bf6..1c409d4 100644 Binary files a/app/__pycache__/part_library_interface.cpython-39.pyc and b/app/__pycache__/part_library_interface.cpython-39.pyc differ diff --git a/app/__pycache__/serial_terminal_interface.cpython-39.pyc b/app/__pycache__/serial_terminal_interface.cpython-39.pyc index f184744..52fd265 100644 Binary files a/app/__pycache__/serial_terminal_interface.cpython-39.pyc and b/app/__pycache__/serial_terminal_interface.cpython-39.pyc differ diff --git a/app/code_generate_interface.py b/app/code_generate_interface.py index 489861f..3bbd50d 100644 --- a/app/code_generate_interface.py +++ b/app/code_generate_interface.py @@ -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) - - # 生成 BSP 代码 - bsp_result = bsp.generate_bsp(self.project_path, pages) - - # 生成 Component 代码 - from app.code_page.component_interface import component - component_result = component.generate_component(self.project_path, pages) - - # 合并结果信息 - combined_result = f"BSP代码生成:\n{bsp_result}\n\nComponent代码生成:\n{component_result}" - - # 用 InfoBar 在主界面弹出 - InfoBar.success( - title="代码生成结果", - content=combined_result, - parent=self, - duration=5000 # 增加显示时间,因为内容更多 - ) + """生成代码逻辑 - 修复导入问题""" + try: + # 收集所有已加载的页面对象 + pages = [] + for i in range(self.stack.count()): + widget = self.stack.widget(i) + pages.append(widget) + + # 确保导入成功 + from app.code_page.bsp_interface import bsp + from app.code_page.component_interface import component + + # 生成 BSP 代码 + bsp_result = bsp.generate_bsp(self.project_path, pages) + + # 生成 Component 代码 + component_result = component.generate_component(self.project_path, pages) + + # 合并结果信息 + 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: @@ -253,5 +271,4 @@ class CodeGenerateInterface(QWidget): except Exception as e: print(f"创建页面 {class_name} 失败: {e}") return None - -# ...existing code... \ No newline at end of file + diff --git a/app/code_page/__pycache__/bsp_interface.cpython-39.pyc b/app/code_page/__pycache__/bsp_interface.cpython-39.pyc new file mode 100644 index 0000000..cc9b996 Binary files /dev/null and b/app/code_page/__pycache__/bsp_interface.cpython-39.pyc differ diff --git a/app/code_page/__pycache__/component_interface.cpython-39.pyc b/app/code_page/__pycache__/component_interface.cpython-39.pyc new file mode 100644 index 0000000..174f381 Binary files /dev/null and b/app/code_page/__pycache__/component_interface.cpython-39.pyc differ diff --git a/app/code_page/bsp_interface.py b/app/code_page/bsp_interface.py index cfb5892..e3a059c 100644 --- a/app/code_page/bsp_interface.py +++ b/app/code_page/bsp_interface.py @@ -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,41 +421,106 @@ 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(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;") - - 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}));") - - # 注册回调和激活中断 - 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(" // 先设置初始化标志,以便后续回调注册能通过检查") + init_lines.append(" inited = true;") + init_lines.append("") + + # 检查是否同时有CAN1和CAN2 + has_can1 = any(instance == 'CAN1' for _, instance in configs) + has_can2 = any(instance == 'CAN2' for _, instance in configs) + + 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 + + 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) diff --git a/app/tools/__pycache__/analyzing_ioc.cpython-39.pyc b/app/tools/__pycache__/analyzing_ioc.cpython-39.pyc new file mode 100644 index 0000000..d9bf58a Binary files /dev/null and b/app/tools/__pycache__/analyzing_ioc.cpython-39.pyc differ diff --git a/app/tools/__pycache__/check_update.cpython-39.pyc b/app/tools/__pycache__/check_update.cpython-39.pyc index 7477353..de74a03 100644 Binary files a/app/tools/__pycache__/check_update.cpython-39.pyc and b/app/tools/__pycache__/check_update.cpython-39.pyc differ diff --git a/app/tools/__pycache__/code_generator.cpython-39.pyc b/app/tools/__pycache__/code_generator.cpython-39.pyc new file mode 100644 index 0000000..4449429 Binary files /dev/null and b/app/tools/__pycache__/code_generator.cpython-39.pyc differ diff --git a/app/tools/__pycache__/code_task_config.cpython-39.pyc b/app/tools/__pycache__/code_task_config.cpython-39.pyc new file mode 100644 index 0000000..cf0389f Binary files /dev/null and b/app/tools/__pycache__/code_task_config.cpython-39.pyc differ diff --git a/app/tools/__pycache__/part_download.cpython-39.pyc b/app/tools/__pycache__/part_download.cpython-39.pyc index 7e11e9c..3edd79f 100644 Binary files a/app/tools/__pycache__/part_download.cpython-39.pyc and b/app/tools/__pycache__/part_download.cpython-39.pyc differ diff --git a/app/tools/__pycache__/update_code.cpython-39.pyc b/app/tools/__pycache__/update_code.cpython-39.pyc new file mode 100644 index 0000000..9e663d2 Binary files /dev/null and b/app/tools/__pycache__/update_code.cpython-39.pyc differ diff --git a/app/tools/code_generator.py b/app/tools/code_generator.py index 8b41d68..e3a45b5 100644 --- a/app/tools/code_generator.py +++ b/app/tools/code_generator.py @@ -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") \ No newline at end of file + # 开发环境 + 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 \ No newline at end of file diff --git a/assets/.DS_Store b/assets/.DS_Store new file mode 100644 index 0000000..306d698 Binary files /dev/null and b/assets/.DS_Store differ diff --git a/assets/User_code/.DS_Store b/assets/User_code/.DS_Store index 038a997..0859137 100644 Binary files a/assets/User_code/.DS_Store and b/assets/User_code/.DS_Store differ diff --git a/assets/User_code/bsp.zip b/assets/User_code/bsp.zip new file mode 100644 index 0000000..56934e6 Binary files /dev/null and b/assets/User_code/bsp.zip differ diff --git a/assets/User_code/bsp/can.c b/assets/User_code/bsp/can.c index d30c34f..65ac35f 100644 --- a/assets/User_code/bsp/can.c +++ b/assets/User_code/bsp/can.c @@ -11,32 +11,34 @@ /* Private macro ------------------------------------------------------------ */ /* Private typedef ---------------------------------------------------------- */ typedef struct BSP_CAN_QueueNode { - uint32_t can_id; - osMessageQueueId_t queue; - uint8_t queue_size; - struct BSP_CAN_QueueNode *next; + uint32_t can_id; /* 解析后的CAN ID */ + osMessageQueueId_t queue; /* 消息队列ID */ + uint8_t queue_size; /* 队列大小 */ + struct BSP_CAN_QueueNode *next; /* 指向下一个节点的指针 */ } BSP_CAN_QueueNode_t; /* Private variables -------------------------------------------------------- */ -static BSP_CAN_QueueNode_t *g_can_queue_list = NULL; -static osMutexId_t g_can_queue_mutex = NULL; -static void (*g_can_callbacks[BSP_CAN_NUM][BSP_CAN_CB_NUM])(void); -static bool g_can_initialized = false; +static BSP_CAN_QueueNode_t *queue_list = NULL; +static osMutexId_t queue_mutex = NULL; +static void (*CAN_Callback[BSP_CAN_NUM][BSP_CAN_CB_NUM])(void); +static bool inited = false; +static BSP_CAN_IdParser_t id_parser = NULL; /* ID解析器 */ /* Private function prototypes ---------------------------------------------- */ -static BSP_CAN_t BSP_CAN_GetInstance(CAN_HandleTypeDef *hcan); +static BSP_CAN_t CAN_Get(CAN_HandleTypeDef *hcan); static osMessageQueueId_t BSP_CAN_FindQueue(uint32_t can_id); static int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size); static int8_t BSP_CAN_DeleteIdQueue(uint32_t can_id); -static void BSP_CAN_RxFifo0Handler(void); -static void BSP_CAN_RxFifo1Handler(void); +static void BSP_CAN_RxFifoCallback(void); +static BSP_CAN_FrameType_t BSP_CAN_GetFrameType(CAN_RxHeaderTypeDef *header); +static uint32_t BSP_CAN_DefaultIdParser(uint32_t original_id, BSP_CAN_FrameType_t frame_type); /* Private functions -------------------------------------------------------- */ /** * @brief 根据CAN句柄获取BSP_CAN实例 */ -static BSP_CAN_t BSP_CAN_GetInstance(CAN_HandleTypeDef *hcan) { +static BSP_CAN_t CAN_Get(CAN_HandleTypeDef *hcan) { if (hcan == NULL) return BSP_CAN_ERR; /* AUTO GENERATED CAN_GET */ @@ -49,7 +51,7 @@ static BSP_CAN_t BSP_CAN_GetInstance(CAN_HandleTypeDef *hcan) { * @note 调用前需要获取互斥锁 */ static osMessageQueueId_t BSP_CAN_FindQueue(uint32_t can_id) { - BSP_CAN_QueueNode_t *node = g_can_queue_list; + BSP_CAN_QueueNode_t *node = queue_list; while (node != NULL) { if (node->can_id == can_id) { return node->queue; @@ -69,15 +71,15 @@ static int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size) { } // 获取互斥锁 - if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { + if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { return BSP_ERR_TIMEOUT; } // 检查是否已存在 - BSP_CAN_QueueNode_t *node = g_can_queue_list; + BSP_CAN_QueueNode_t *node = queue_list; while (node != NULL) { if (node->can_id == can_id) { - osMutexRelease(g_can_queue_mutex); + osMutexRelease(queue_mutex); return BSP_ERR; // 已存在 } node = node->next; @@ -86,7 +88,7 @@ static int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size) { // 创建新节点 BSP_CAN_QueueNode_t *new_node = (BSP_CAN_QueueNode_t *)BSP_Malloc(sizeof(BSP_CAN_QueueNode_t)); if (new_node == NULL) { - osMutexRelease(g_can_queue_mutex); + osMutexRelease(queue_mutex); return BSP_ERR_NULL; } @@ -94,17 +96,17 @@ static int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size) { new_node->queue = osMessageQueueNew(queue_size, sizeof(BSP_CAN_Message_t), NULL); if (new_node->queue == NULL) { BSP_Free(new_node); - osMutexRelease(g_can_queue_mutex); + osMutexRelease(queue_mutex); return BSP_ERR; } // 初始化节点 new_node->can_id = can_id; new_node->queue_size = queue_size; - new_node->next = g_can_queue_list; - g_can_queue_list = new_node; + new_node->next = queue_list; + queue_list = new_node; - osMutexRelease(g_can_queue_mutex); + osMutexRelease(queue_mutex); return BSP_OK; } @@ -114,11 +116,11 @@ static int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size) { */ static int8_t BSP_CAN_DeleteIdQueue(uint32_t can_id) { // 获取互斥锁 - if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { + if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { return BSP_ERR_TIMEOUT; } - BSP_CAN_QueueNode_t **current = &g_can_queue_list; + BSP_CAN_QueueNode_t **current = &queue_list; while (*current != NULL) { if ((*current)->can_id == can_id) { BSP_CAN_QueueNode_t *to_delete = *current; @@ -128,20 +130,39 @@ static int8_t BSP_CAN_DeleteIdQueue(uint32_t can_id) { osMessageQueueDelete(to_delete->queue); BSP_Free(to_delete); - osMutexRelease(g_can_queue_mutex); + osMutexRelease(queue_mutex); return BSP_OK; } current = &(*current)->next; } - osMutexRelease(g_can_queue_mutex); + osMutexRelease(queue_mutex); return BSP_ERR; // 未找到 } /** - * @brief FIFO0接收处理函数 + * @brief 获取帧类型 */ -static void BSP_CAN_RxFifo0Handler(void) { +static BSP_CAN_FrameType_t BSP_CAN_GetFrameType(CAN_RxHeaderTypeDef *header) { + if (header->RTR == CAN_RTR_REMOTE) { + return (header->IDE == CAN_ID_EXT) ? BSP_CAN_FRAME_EXT_REMOTE : BSP_CAN_FRAME_STD_REMOTE; + } else { + return (header->IDE == CAN_ID_EXT) ? BSP_CAN_FRAME_EXT_DATA : BSP_CAN_FRAME_STD_DATA; + } +} + +/** + * @brief 默认ID解析器(直接返回原始ID) + */ +static uint32_t BSP_CAN_DefaultIdParser(uint32_t original_id, BSP_CAN_FrameType_t frame_type) { + (void)frame_type; // 避免未使用参数警告 + return original_id; +} + +/** + * @brief FIFO接收处理函数 + */ +static void BSP_CAN_RxFifoCallback(void) { CAN_RxHeaderTypeDef rx_header; uint8_t rx_data[BSP_CAN_MAX_DLC]; @@ -152,59 +173,32 @@ static void BSP_CAN_RxFifo0Handler(void) { while (HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO0) > 0) { if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, rx_data) == HAL_OK) { - uint32_t can_id = (rx_header.IDE == CAN_ID_STD) ? rx_header.StdId : rx_header.ExtId; + // 获取原始ID + uint32_t original_id = (rx_header.IDE == CAN_ID_STD) ? rx_header.StdId : rx_header.ExtId; - // 线程安全地查找队列 - if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) == osOK) { - osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id); - osMutexRelease(g_can_queue_mutex); - - if (queue != NULL) { - BSP_CAN_Message_t msg; - msg.header = rx_header; - memcpy(msg.data, rx_data, BSP_CAN_MAX_DLC); - - // 非阻塞发送,如果队列满了就丢弃 - osMessageQueuePut(queue, &msg, 0, BSP_CAN_TIMEOUT_IMMEDIATE); - } - } - // 如果没有找到对应的队列或获取互斥锁超时,消息被直接丢弃 - } - } - } -} - -/** - * @brief FIFO1接收处理函数 - */ -static void BSP_CAN_RxFifo1Handler(void) { - CAN_RxHeaderTypeDef rx_header; - uint8_t rx_data[BSP_CAN_MAX_DLC]; - - // 遍历所有CAN接口处理FIFO1 - for (int can_idx = 0; can_idx < BSP_CAN_NUM; can_idx++) { - CAN_HandleTypeDef *hcan = BSP_CAN_GetHandle((BSP_CAN_t)can_idx); - if (hcan == NULL) continue; - - while (HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO1) > 0) { - if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO1, &rx_header, rx_data) == HAL_OK) { - uint32_t can_id = (rx_header.IDE == CAN_ID_STD) ? rx_header.StdId : rx_header.ExtId; + // 获取帧类型 + BSP_CAN_FrameType_t frame_type = BSP_CAN_GetFrameType(&rx_header); - // 线程安全地查找队列 - if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) == osOK) { - osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id); - osMutexRelease(g_can_queue_mutex); - - if (queue != NULL) { - BSP_CAN_Message_t msg; - msg.header = rx_header; - memcpy(msg.data, rx_data, BSP_CAN_MAX_DLC); - - // 非阻塞发送,如果队列满了就丢弃 - osMessageQueuePut(queue, &msg, 0, BSP_CAN_TIMEOUT_IMMEDIATE); + // 解析ID + uint32_t parsed_id = BSP_CAN_ParseId(original_id, frame_type); + + // 直接查找队列,不使用互斥锁(中断中快速执行) + osMessageQueueId_t queue = BSP_CAN_FindQueue(parsed_id); + + if (queue != NULL) { + BSP_CAN_Message_t msg = {0}; + msg.frame_type = frame_type; + msg.original_id = original_id; + msg.parsed_id = parsed_id; + msg.dlc = rx_header.DLC; + if (rx_header.RTR == CAN_RTR_DATA) { + memcpy(msg.data, rx_data, rx_header.DLC); } + msg.timestamp = HAL_GetTick(); // 添加时间戳 + + // 非阻塞发送,如果队列满了就丢弃 + osMessageQueuePut(queue, &msg, 0, BSP_CAN_TIMEOUT_IMMEDIATE); } - // 如果没有找到对应的队列或获取互斥锁超时,消息被直接丢弃 } } } @@ -212,178 +206,165 @@ static void BSP_CAN_RxFifo1Handler(void) { /* HAL Callback Functions --------------------------------------------------- */ void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX0_CPLT_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX0_CPLT_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_CPLT_CB]) + CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_CPLT_CB](); + } } void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX1_CPLT_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX1_CPLT_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_CPLT_CB]) + CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_CPLT_CB](); + } } void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX2_CPLT_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX2_CPLT_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_CPLT_CB]) + CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_CPLT_CB](); + } } void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX0_ABORT_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX0_ABORT_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_ABORT_CB]) + CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_ABORT_CB](); + } } void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX1_ABORT_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX1_ABORT_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_ABORT_CB]) + CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_ABORT_CB](); + } } void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX2_ABORT_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX2_ABORT_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_ABORT_CB]) + CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_ABORT_CB](); + } } void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_MSG_PENDING_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_MSG_PENDING_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_MSG_PENDING_CB]) + CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_MSG_PENDING_CB](); + } } void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_FULL_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_FULL_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_FULL_CB]) + CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_FULL_CB](); + } } void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_MSG_PENDING_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_MSG_PENDING_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_MSG_PENDING_CB]) + CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_MSG_PENDING_CB](); + } } void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_FULL_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_FULL_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_FULL_CB]) + CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_FULL_CB](); + } } void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_SLEEP_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_SLEEP_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_SLEEP_CB]) + CAN_Callback[bsp_can][HAL_CAN_SLEEP_CB](); + } } void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_WAKEUP_FROM_RX_MSG_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_WAKEUP_FROM_RX_MSG_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_WAKEUP_FROM_RX_MSG_CB]) + CAN_Callback[bsp_can][HAL_CAN_WAKEUP_FROM_RX_MSG_CB](); + } } void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_ERROR_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_ERROR_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_ERROR_CB]) + CAN_Callback[bsp_can][HAL_CAN_ERROR_CB](); + } } /* Exported functions ------------------------------------------------------- */ int8_t BSP_CAN_Init(void) { - if (g_can_initialized) { + if (inited) { return BSP_ERR_INITED; } // 清零回调函数数组 - memset(g_can_callbacks, 0, sizeof(g_can_callbacks)); + memset(CAN_Callback, 0, sizeof(CAN_Callback)); + + // 初始化ID解析器为默认解析器 + id_parser = BSP_CAN_DefaultIdParser; // 创建互斥锁 - g_can_queue_mutex = osMutexNew(NULL); - if (g_can_queue_mutex == NULL) { + queue_mutex = osMutexNew(NULL); + if (queue_mutex == NULL) { return BSP_ERR; } /* AUTO GENERATED CAN_INIT */ - // 注册默认的接收中断处理函数 - for (int can_idx = 0; can_idx < BSP_CAN_NUM; can_idx++) { - BSP_CAN_RegisterCallback((BSP_CAN_t)can_idx, BSP_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifo0Handler); - BSP_CAN_RegisterCallback((BSP_CAN_t)can_idx, BSP_CAN_RX_FIFO1_MSG_PENDING_CB, BSP_CAN_RxFifo1Handler); - } - - g_can_initialized = true; + inited = true; return BSP_OK; } int8_t BSP_CAN_DeInit(void) { - if (!g_can_initialized) { + if (!inited) { return BSP_ERR; } // 删除所有队列 - if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) == osOK) { - BSP_CAN_QueueNode_t *current = g_can_queue_list; + if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) == osOK) { + BSP_CAN_QueueNode_t *current = queue_list; while (current != NULL) { BSP_CAN_QueueNode_t *next = current->next; osMessageQueueDelete(current->queue); BSP_Free(current); current = next; } - g_can_queue_list = NULL; - osMutexRelease(g_can_queue_mutex); + queue_list = NULL; + osMutexRelease(queue_mutex); } // 删除互斥锁 - if (g_can_queue_mutex != NULL) { - osMutexDelete(g_can_queue_mutex); - g_can_queue_mutex = NULL; + if (queue_mutex != NULL) { + osMutexDelete(queue_mutex); + queue_mutex = NULL; } // 清零回调函数数组 - memset(g_can_callbacks, 0, sizeof(g_can_callbacks)); + memset(CAN_Callback, 0, sizeof(CAN_Callback)); - g_can_initialized = false; + // 重置ID解析器 + id_parser = NULL; + + inited = false; return BSP_OK; } @@ -401,7 +382,7 @@ CAN_HandleTypeDef *BSP_CAN_GetHandle(BSP_CAN_t can) { int8_t BSP_CAN_RegisterCallback(BSP_CAN_t can, BSP_CAN_Callback_t type, void (*callback)(void)) { - if (!g_can_initialized) { + if (!inited) { return BSP_ERR_INITED; } if (callback == NULL) { @@ -414,19 +395,19 @@ int8_t BSP_CAN_RegisterCallback(BSP_CAN_t can, BSP_CAN_Callback_t type, return BSP_ERR; } - g_can_callbacks[can][type] = callback; + CAN_Callback[can][type] = callback; return BSP_OK; } int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format, uint32_t id, uint8_t *data, uint8_t dlc) { - if (!g_can_initialized) { + if (!inited) { return BSP_ERR_INITED; } if (can >= BSP_CAN_NUM) { return BSP_ERR; } - if (data == NULL) { + if (data == NULL && format != BSP_CAN_FORMAT_STD_REMOTE && format != BSP_CAN_FORMAT_EXT_REMOTE) { return BSP_ERR_NULL; } if (dlc > BSP_CAN_MAX_DLC) { @@ -473,8 +454,30 @@ int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format, return (result == HAL_OK) ? BSP_OK : BSP_ERR; } +int8_t BSP_CAN_TransmitStdDataFrame(BSP_CAN_t can, BSP_CAN_StdDataFrame_t *frame) { + if (frame == NULL) { + return BSP_ERR_NULL; + } + return BSP_CAN_Transmit(can, BSP_CAN_FORMAT_STD_DATA, frame->id, frame->data, frame->dlc); +} + +int8_t BSP_CAN_TransmitExtDataFrame(BSP_CAN_t can, BSP_CAN_ExtDataFrame_t *frame) { + if (frame == NULL) { + return BSP_ERR_NULL; + } + return BSP_CAN_Transmit(can, BSP_CAN_FORMAT_EXT_DATA, frame->id, frame->data, frame->dlc); +} + +int8_t BSP_CAN_TransmitRemoteFrame(BSP_CAN_t can, BSP_CAN_RemoteFrame_t *frame) { + if (frame == NULL) { + return BSP_ERR_NULL; + } + BSP_CAN_Format_t format = frame->is_extended ? BSP_CAN_FORMAT_EXT_REMOTE : BSP_CAN_FORMAT_STD_REMOTE; + return BSP_CAN_Transmit(can, format, frame->id, NULL, frame->dlc); +} + int8_t BSP_CAN_RegisterId(uint32_t can_id, uint8_t queue_size) { - if (!g_can_initialized) { + if (!inited) { return BSP_ERR_INITED; } @@ -482,7 +485,7 @@ int8_t BSP_CAN_RegisterId(uint32_t can_id, uint8_t queue_size) { } int8_t BSP_CAN_UnregisterIdQueue(uint32_t can_id) { - if (!g_can_initialized) { + if (!inited) { return BSP_ERR_INITED; } @@ -490,7 +493,7 @@ int8_t BSP_CAN_UnregisterIdQueue(uint32_t can_id) { } int8_t BSP_CAN_GetMessage(uint32_t can_id, BSP_CAN_Message_t *msg, uint32_t timeout) { - if (!g_can_initialized) { + if (!inited) { return BSP_ERR_INITED; } if (msg == NULL) { @@ -498,12 +501,12 @@ int8_t BSP_CAN_GetMessage(uint32_t can_id, BSP_CAN_Message_t *msg, uint32_t time } // 线程安全地查找队列 - if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { + if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { return BSP_ERR_TIMEOUT; } osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id); - osMutexRelease(g_can_queue_mutex); + osMutexRelease(queue_mutex); if (queue == NULL) { return BSP_ERR_NO_DEV; // 队列不存在 @@ -514,17 +517,17 @@ int8_t BSP_CAN_GetMessage(uint32_t can_id, BSP_CAN_Message_t *msg, uint32_t time } int32_t BSP_CAN_GetQueueCount(uint32_t can_id) { - if (!g_can_initialized) { + if (!inited) { return -1; } // 线程安全地查找队列 - if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { + if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { return -1; } osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id); - osMutexRelease(g_can_queue_mutex); + osMutexRelease(queue_mutex); if (queue == NULL) { return -1; // 队列不存在 @@ -534,17 +537,17 @@ int32_t BSP_CAN_GetQueueCount(uint32_t can_id) { } int8_t BSP_CAN_FlushQueue(uint32_t can_id) { - if (!g_can_initialized) { + if (!inited) { return BSP_ERR_INITED; } // 线程安全地查找队列 - if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { + if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { return BSP_ERR_TIMEOUT; } osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id); - osMutexRelease(g_can_queue_mutex); + osMutexRelease(queue_mutex); if (queue == NULL) { return BSP_ERR_NO_DEV; // 队列不存在 @@ -559,5 +562,33 @@ int8_t BSP_CAN_FlushQueue(uint32_t can_id) { return BSP_OK; } +int8_t BSP_CAN_RegisterIdParser(BSP_CAN_IdParser_t parser) { + if (!inited) { + return BSP_ERR_INITED; + } + if (parser == NULL) { + return BSP_ERR_NULL; + } + + id_parser = parser; + return BSP_OK; +} + +int8_t BSP_CAN_UnregisterIdParser(void) { + if (!inited) { + return BSP_ERR_INITED; + } + + id_parser = BSP_CAN_DefaultIdParser; + return BSP_OK; +} + +uint32_t BSP_CAN_ParseId(uint32_t original_id, BSP_CAN_FrameType_t frame_type) { + if (id_parser != NULL) { + return id_parser(original_id, frame_type); + } + return BSP_CAN_DefaultIdParser(original_id, frame_type); +} + /* USER CAN FUNCTIONS BEGIN */ /* USER CAN FUNCTIONS END */ \ No newline at end of file diff --git a/assets/User_code/bsp/can.h b/assets/User_code/bsp/can.h index c589e72..efa2c07 100644 --- a/assets/User_code/bsp/can.h +++ b/assets/User_code/bsp/can.h @@ -23,26 +23,27 @@ extern "C" { typedef enum { /* AUTO GENERATED BSP_CAN_NAME */ BSP_CAN_NUM, - BSP_CAN_ERR = 0xFF, + BSP_CAN_ERR, } BSP_CAN_t; typedef enum { - BSP_CAN_TX_MAILBOX0_CPLT_CB, - BSP_CAN_TX_MAILBOX1_CPLT_CB, - BSP_CAN_TX_MAILBOX2_CPLT_CB, - BSP_CAN_TX_MAILBOX0_ABORT_CB, - BSP_CAN_TX_MAILBOX1_ABORT_CB, - BSP_CAN_TX_MAILBOX2_ABORT_CB, - BSP_CAN_RX_FIFO0_MSG_PENDING_CB, - BSP_CAN_RX_FIFO0_FULL_CB, - BSP_CAN_RX_FIFO1_MSG_PENDING_CB, - BSP_CAN_RX_FIFO1_FULL_CB, - BSP_CAN_SLEEP_CB, - BSP_CAN_WAKEUP_FROM_RX_MSG_CB, - BSP_CAN_ERROR_CB, - BSP_CAN_CB_NUM + HAL_CAN_TX_MAILBOX0_CPLT_CB, + HAL_CAN_TX_MAILBOX1_CPLT_CB, + HAL_CAN_TX_MAILBOX2_CPLT_CB, + HAL_CAN_TX_MAILBOX0_ABORT_CB, + HAL_CAN_TX_MAILBOX1_ABORT_CB, + HAL_CAN_TX_MAILBOX2_ABORT_CB, + HAL_CAN_RX_FIFO0_MSG_PENDING_CB, + HAL_CAN_RX_FIFO0_FULL_CB, + HAL_CAN_RX_FIFO1_MSG_PENDING_CB, + HAL_CAN_RX_FIFO1_FULL_CB, + HAL_CAN_SLEEP_CB, + HAL_CAN_WAKEUP_FROM_RX_MSG_CB, + HAL_CAN_ERROR_CB, + BSP_CAN_CB_NUM, } BSP_CAN_Callback_t; +/* CAN消息格式枚举 - 用于发送和接收消息时指定格式 */ typedef enum { BSP_CAN_FORMAT_STD_DATA, /* 标准数据帧 */ BSP_CAN_FORMAT_EXT_DATA, /* 扩展数据帧 */ @@ -50,11 +51,48 @@ typedef enum { BSP_CAN_FORMAT_EXT_REMOTE, /* 扩展远程帧 */ } BSP_CAN_Format_t; +/* CAN帧类型枚举 - 用于区分不同类型的CAN帧 */ +typedef enum { + BSP_CAN_FRAME_STD_DATA, /* 标准数据帧 */ + BSP_CAN_FRAME_EXT_DATA, /* 扩展数据帧 */ + BSP_CAN_FRAME_STD_REMOTE, /* 标准远程帧 */ + BSP_CAN_FRAME_EXT_REMOTE, /* 扩展远程帧 */ +} BSP_CAN_FrameType_t; + +/* CAN消息结构体 - 支持不同类型帧 */ typedef struct { - CAN_RxHeaderTypeDef header; - uint8_t data[BSP_CAN_MAX_DLC]; + BSP_CAN_FrameType_t frame_type; /* 帧类型 */ + uint32_t original_id; /* 原始ID(未解析) */ + uint32_t parsed_id; /* 解析后的实际ID */ + uint8_t dlc; /* 数据长度 */ + uint8_t data[BSP_CAN_MAX_DLC]; /* 数据 */ + uint32_t timestamp; /* 时间戳(可选) */ } BSP_CAN_Message_t; +/* 标准数据帧结构 */ +typedef struct { + uint32_t id; /* CAN ID */ + uint8_t dlc; /* 数据长度 */ + uint8_t data[BSP_CAN_MAX_DLC]; /* 数据 */ +} BSP_CAN_StdDataFrame_t; + +/* 扩展数据帧结构 */ +typedef struct { + uint32_t id; /* 扩展CAN ID */ + uint8_t dlc; /* 数据长度 */ + uint8_t data[BSP_CAN_MAX_DLC]; /* 数据 */ +} BSP_CAN_ExtDataFrame_t; + +/* 远程帧结构 */ +typedef struct { + uint32_t id; /* CAN ID */ + uint8_t dlc; /* 请求的数据长度 */ + bool is_extended; /* 是否为扩展帧 */ +} BSP_CAN_RemoteFrame_t; + +/* ID解析回调函数类型 */ +typedef uint32_t (*BSP_CAN_IdParser_t)(uint32_t original_id, BSP_CAN_FrameType_t frame_type); + /* Exported functions prototypes -------------------------------------------- */ /** @@ -98,9 +136,33 @@ int8_t BSP_CAN_RegisterCallback(BSP_CAN_t can, BSP_CAN_Callback_t type, int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format, uint32_t id, uint8_t *data, uint8_t dlc); +/** + * @brief 发送标准数据帧 + * @param can CAN 枚举 + * @param frame 标准数据帧指针 + * @return BSP_OK 成功,其他值失败 + */ +int8_t BSP_CAN_TransmitStdDataFrame(BSP_CAN_t can, BSP_CAN_StdDataFrame_t *frame); + +/** + * @brief 发送扩展数据帧 + * @param can CAN 枚举 + * @param frame 扩展数据帧指针 + * @return BSP_OK 成功,其他值失败 + */ +int8_t BSP_CAN_TransmitExtDataFrame(BSP_CAN_t can, BSP_CAN_ExtDataFrame_t *frame); + +/** + * @brief 发送远程帧 + * @param can CAN 枚举 + * @param frame 远程帧指针 + * @return BSP_OK 成功,其他值失败 + */ +int8_t BSP_CAN_TransmitRemoteFrame(BSP_CAN_t can, BSP_CAN_RemoteFrame_t *frame); + /** * @brief 注册 CAN ID 接收队列 - * @param can_id CAN ID + * @param can_id 解析后的CAN ID * @param queue_size 队列大小,0使用默认值 * @return BSP_OK 成功,其他值失败 */ @@ -108,14 +170,14 @@ int8_t BSP_CAN_RegisterId(uint32_t can_id, uint8_t queue_size); /** * @brief 注销 CAN ID 接收队列 - * @param can_id CAN ID + * @param can_id 解析后的CAN ID * @return BSP_OK 成功,其他值失败 */ int8_t BSP_CAN_UnregisterIdQueue(uint32_t can_id); /** * @brief 获取 CAN 消息(阻塞方式) - * @param can_id CAN ID + * @param can_id 解析后的CAN ID * @param msg 存储消息的结构体指针 * @param timeout 超时时间(毫秒),0为立即返回,osWaitForever为永久等待 * @return BSP_OK 成功,其他值失败 @@ -124,18 +186,39 @@ int8_t BSP_CAN_GetMessage(uint32_t can_id, BSP_CAN_Message_t *msg, uint32_t time /** * @brief 获取指定ID队列中的消息数量 - * @param can_id CAN ID + * @param can_id 解析后的CAN ID * @return 消息数量,-1表示队列不存在 */ int32_t BSP_CAN_GetQueueCount(uint32_t can_id); /** * @brief 清空指定ID队列中的所有消息 - * @param can_id CAN ID + * @param can_id 解析后的CAN ID * @return BSP_OK 成功,其他值失败 */ int8_t BSP_CAN_FlushQueue(uint32_t can_id); +/** + * @brief 注册ID解析器 + * @param parser ID解析回调函数 + * @return BSP_OK 成功,其他值失败 + */ +int8_t BSP_CAN_RegisterIdParser(BSP_CAN_IdParser_t parser); + +/** + * @brief 注销ID解析器 + * @return BSP_OK 成功,其他值失败 + */ +int8_t BSP_CAN_UnregisterIdParser(void); + +/** + * @brief 解析CAN ID + * @param original_id 原始ID + * @param frame_type 帧类型 + * @return 解析后的ID + */ +uint32_t BSP_CAN_ParseId(uint32_t original_id, BSP_CAN_FrameType_t frame_type); + /* USER CAN FUNCTIONS BEGIN */ /* USER CAN FUNCTIONS END */ diff --git a/assets/User_code/bsp/gpio.c b/assets/User_code/bsp/gpio.c index da3a24c..59acc4f 100644 --- a/assets/User_code/bsp/gpio.c +++ b/assets/User_code/bsp/gpio.c @@ -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); diff --git a/assets/User_code/bsp/gpio.h b/assets/User_code/bsp/gpio.h index a11d717..d7e4ec1 100644 --- a/assets/User_code/bsp/gpio.h +++ b/assets/User_code/bsp/gpio.h @@ -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); diff --git a/assets/User_code/bsp/spi.c b/assets/User_code/bsp/spi.c index e545e80..26474cf 100644 --- a/assets/User_code/bsp/spi.c +++ b/assets/User_code/bsp/spi.c @@ -1,4 +1,5 @@ /* Includes ----------------------------------------------------------------- */ +#include #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, ®, 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, ®, 1u, true); + return BSP_SPI_Transmit(spi, data, size, true); } diff --git a/assets/User_code/bsp/uart.c b/assets/User_code/bsp/uart.c index d9a235d..8cde78a 100644 --- a/assets/User_code/bsp/uart.c +++ b/assets/User_code/bsp/uart.c @@ -1,5 +1,5 @@ /* Includes ----------------------------------------------------------------- */ -#include +#include #include "bsp/uart.h" diff --git a/assets/User_code/component/ui.h b/assets/User_code/component/ui.h index 5580d3e..3cfb3bb 100644 --- a/assets/User_code/component/ui.h +++ b/assets/User_code/component/ui.h @@ -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; diff --git a/assets/User_code/component/user_math.c b/assets/User_code/component/user_math.c index 1fceac2..f3f3964 100644 --- a/assets/User_code/component/user_math.c +++ b/assets/User_code/component/user_math.c @@ -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(); +// } +// } diff --git a/assets/User_code/component/user_math.h b/assets/User_code/component/user_math.h index eda0545..13e1ae5 100644 --- a/assets/User_code/component/user_math.h +++ b/assets/User_code/component/user_math.h @@ -8,12 +8,11 @@ extern "C" { #endif -#include "stm32f4xx.h" -#define ARM_MATH_CM4 - #include #include #include +#include +#include #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); diff --git a/assets/User_code/config.csv b/assets/User_code/config.csv index 66f08b4..047265b 100644 --- a/assets/User_code/config.csv +++ b/assets/User_code/config.csv @@ -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 \ No newline at end of file diff --git a/gpio.h b/gpio.h index 3ad4f46..9ed26d4 100644 --- a/gpio.h +++ b/gpio.h @@ -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);