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": { "files.associations": {
"user_math.h": "c", "user_math.h": "c",
"bsp.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,18 +155,22 @@ class CodeGenerateInterface(QWidget):
def generate_code(self): def generate_code(self):
"""生成代码逻辑""" """生成代码逻辑 - 修复导入问题"""
try:
# 收集所有已加载的页面对象 # 收集所有已加载的页面对象
pages = [] pages = []
for i in range(self.stack.count()): for i in range(self.stack.count()):
widget = self.stack.widget(i) widget = self.stack.widget(i)
pages.append(widget) pages.append(widget)
# 确保导入成功
from app.code_page.bsp_interface import bsp
from app.code_page.component_interface import component
# 生成 BSP 代码 # 生成 BSP 代码
bsp_result = bsp.generate_bsp(self.project_path, pages) bsp_result = bsp.generate_bsp(self.project_path, pages)
# 生成 Component 代码 # 生成 Component 代码
from app.code_page.component_interface import component
component_result = component.generate_component(self.project_path, pages) component_result = component.generate_component(self.project_path, pages)
# 合并结果信息 # 合并结果信息
@ -177,7 +181,22 @@ class CodeGenerateInterface(QWidget):
title="代码生成结果", title="代码生成结果",
content=combined_result, content=combined_result,
parent=self, parent=self,
duration=5000 # 增加显示时间,因为内容更多 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): def _get_freertos_status(self):
@ -220,7 +239,6 @@ class CodeGenerateInterface(QWidget):
if widget: if widget:
self.stack.setCurrentWidget(widget) self.stack.setCurrentWidget(widget)
# ...existing code...
def _get_or_create_page(self, class_name): def _get_or_create_page(self, class_name):
"""获取或创建页面""" """获取或创建页面"""
if class_name in self.page_cache: if class_name in self.page_cache:
@ -235,12 +253,12 @@ class CodeGenerateInterface(QWidget):
if class_name.startswith('bsp_'): if class_name.startswith('bsp_'):
# BSP页面 # BSP页面
from app.code_page.bsp_interface import get_bsp_page from app.code_page.bsp_interface import get_bsp_page
# 提取外设名,如 bsp_delay -> delay # 提取外设名,如 bsp_error_detect -> error_detect
periph_name = class_name[len('bsp_'):].replace("_", " ") periph_name = class_name[len('bsp_'):] # 移除 .replace("_", " ")
page = get_bsp_page(periph_name, self.project_path) page = get_bsp_page(periph_name, self.project_path)
elif class_name.startswith('component_'): elif class_name.startswith('component_'):
from app.code_page.component_interface import get_component_page 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) page = get_component_page(comp_name, self.project_path, self.component_manager)
self.component_manager.register_component(page.component_name, page) self.component_manager.register_component(page.component_name, page)
else: else:
@ -254,4 +272,3 @@ class CodeGenerateInterface(QWidget):
print(f"创建页面 {class_name} 失败: {e}") print(f"创建页面 {class_name} 失败: {e}")
return None return None
# ...existing code...

Binary file not shown.

View File

@ -399,13 +399,14 @@ class bsp_can(BspPeripheralBase):
get_available_can get_available_can
) )
def _generate_source_file(self, configs, template_dir): def _generate_source_file(self, configs, template_dir):
template_path = os.path.join(template_dir, self.template_names['source']) template_path = os.path.join(template_dir, self.template_names['source'])
template_content = CodeGenerator.load_template(template_path) template_content = CodeGenerator.load_template(template_path)
if not template_content: if not template_content:
return False return False
# Get函数 # CAN_Get函数
get_lines = [] get_lines = []
for idx, (name, instance) in enumerate(configs): for idx, (name, instance) in enumerate(configs):
if idx == 0: if idx == 0:
@ -420,40 +421,105 @@ class bsp_can(BspPeripheralBase):
# Handle函数 # Handle函数
handle_lines = [] handle_lines = []
for name, instance in configs: for name, instance in configs:
num = ''.join(filter(str.isdigit, instance)) # 提取数字
handle_lines.append(f" case {self.enum_prefix}_{name}:") 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 = CodeGenerator.replace_auto_generated(
content, f"AUTO GENERATED {self.enum_prefix}_GET_HANDLE", "\n".join(handle_lines) content, f"AUTO GENERATED {self.enum_prefix}_GET_HANDLE", "\n".join(handle_lines)
) )
# 生成CAN初始化代码 # 生成CAN初始化代码
init_lines = [] init_lines = []
# 先设置初始化标志
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): for idx, (name, instance) in enumerate(configs):
can_num = instance[-1] # CAN1 -> 1, CAN2 -> 2 can_num = instance[-1] # CAN1 -> 1, CAN2 -> 2
init_lines.append(f" // 初始化 {instance}") init_lines.append(f" // 初始化 {instance}")
init_lines.append(f" CAN_FilterTypeDef can{can_num}_filter = {{0}};") 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;") if instance == 'CAN1':
init_lines.append(f" can{can_num}_filter.FilterIdLow = 0;") init_lines.extend([
init_lines.append(f" can{can_num}_filter.FilterMode = CAN_FILTERMODE_IDMASK;") f" can{can_num}_filter.FilterBank = 0;",
init_lines.append(f" can{can_num}_filter.FilterScale = CAN_FILTERSCALE_32BIT;") f" can{can_num}_filter.SlaveStartFilterBank = 14;",
init_lines.append(f" can{can_num}_filter.FilterMaskIdHigh = 0;") f" can{can_num}_filter.FilterFIFOAssignment = CAN_RX_FIFO0;",
init_lines.append(f" can{can_num}_filter.FilterMaskIdLow = 0;") ])
init_lines.append(f" can{can_num}_filter.FilterActivation = ENABLE;") else: # CAN2
if can_num == '1': init_lines.extend([
init_lines.append(f" can{can_num}_filter.SlaveStartFilterBank = 14;") f" can{can_num}_filter.FilterBank = 14;",
init_lines.append(f" can{can_num}_filter.FilterFIFOAssignment = CAN_RX_FIFO0;") 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: else:
init_lines.append(f" can{can_num}_filter.FilterFIFOAssignment = CAN_RX_FIFO1;") init_lines.append(f" HAL_CAN_ConfigFilter(&hcan{can_num}, &can{can_num}_filter);")
init_lines.append(f" HAL_CAN_ConfigFilter(BSP_CAN_GetHandle({self.enum_prefix}_{name}), &can{can_num}_filter);") init_lines.extend([
init_lines.append(f" HAL_CAN_Start(BSP_CAN_GetHandle({self.enum_prefix}_{name}));") f" HAL_CAN_Start(&hcan{can_num});",
f" HAL_CAN_ActivateNotification(&hcan{can_num}, CAN_IT_RX_FIFO0_MSG_PENDING);",
# 注册回调和激活中断 "",
fifo = "FIFO0" if can_num == '1' else "FIFO1" f" // 注册回调函数",
init_lines.append(f" HAL_CAN_ActivateNotification(BSP_CAN_GetHandle({self.enum_prefix}_{name}), CAN_IT_RX_{fifo}_MSG_PENDING);") f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifoCallback);",
init_lines.append("") ""
])
content = CodeGenerator.replace_auto_generated( content = CodeGenerator.replace_auto_generated(
content, "AUTO GENERATED CAN_INIT", "\n".join(init_lines) content, "AUTO GENERATED CAN_INIT", "\n".join(init_lines)
@ -463,6 +529,8 @@ class bsp_can(BspPeripheralBase):
save_with_preserve(output_path, content) save_with_preserve(output_path, content)
return True return True
class bsp_spi(BspPeripheralBase): class bsp_spi(BspPeripheralBase):
def __init__(self, project_path): def __init__(self, project_path):
super().__init__( super().__init__(
@ -654,16 +722,17 @@ class bsp_gpio(QWidget):
template_content, "AUTO GENERATED BSP_GPIO_MAP", "\n".join(map_lines) template_content, "AUTO GENERATED BSP_GPIO_MAP", "\n".join(map_lines)
) )
# 生成EXTI使能代码 # 生成EXTI使能代码 - 使用用户自定义的BSP枚举名称
enable_lines = [] enable_lines = []
disable_lines = [] disable_lines = []
for config in configs: for config in configs:
if config['has_exti']: if config['has_exti']:
ioc_label = config['ioc_label'] 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" HAL_NVIC_EnableIRQ({ioc_label}_EXTI_IRQn);")
enable_lines.append(f" break;") 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" HAL_NVIC_DisableIRQ({ioc_label}_EXTI_IRQn);")
disable_lines.append(f" break;") disable_lines.append(f" break;")
@ -678,6 +747,8 @@ class bsp_gpio(QWidget):
save_with_preserve(output_path, content) save_with_preserve(output_path, content)
return True return True
def _save_config(self, configs): def _save_config(self, configs):
config_path = os.path.join(self.project_path, "User/bsp/bsp_config.yaml") config_path = os.path.join(self.project_path, "User/bsp/bsp_config.yaml")
config_data = CodeGenerator.load_config(config_path) 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 yaml
import shutil import shutil
from typing import Dict, List, Tuple from typing import Dict, List, Tuple
import sys
import os
class CodeGenerator: class CodeGenerator:
"""通用代码生成器""" """通用代码生成器"""
@ -61,15 +62,20 @@ class CodeGenerator:
@staticmethod @staticmethod
def get_template_dir(): def get_template_dir():
"""获取模板文件目录""" """获取模板目录路径,兼容打包环境"""
# 从当前文件向上找到 MRobot 目录,然后定位到模板目录 if getattr(sys, 'frozen', False):
# 打包后的环境
base_path = sys._MEIPASS
template_dir = os.path.join(base_path, "assets", "User_code", "bsp")
else:
# 开发环境
current_dir = os.path.dirname(os.path.abspath(__file__)) current_dir = os.path.dirname(os.path.abspath(__file__))
# 向上找到 MRobot 根目录
while os.path.basename(current_dir) != 'MRobot' and current_dir != '/': while os.path.basename(current_dir) != 'MRobot' and current_dir != '/':
current_dir = os.path.dirname(current_dir) current_dir = os.path.dirname(current_dir)
template_dir = os.path.join(current_dir, "assets", "User_code", "bsp")
if os.path.basename(current_dir) == 'MRobot': print(f"模板目录路径: {template_dir}")
return os.path.join(current_dir, "assets/User_code/bsp") if not os.path.exists(template_dir):
else: print(f"警告:模板目录不存在: {template_dir}")
# 如果找不到,使用相对路径作为备选
return os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "assets/User_code/bsp") 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 macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */ /* Private typedef ---------------------------------------------------------- */
typedef struct BSP_CAN_QueueNode { typedef struct BSP_CAN_QueueNode {
uint32_t can_id; uint32_t can_id; /* 解析后的CAN ID */
osMessageQueueId_t queue; osMessageQueueId_t queue; /* 消息队列ID */
uint8_t queue_size; uint8_t queue_size; /* 队列大小 */
struct BSP_CAN_QueueNode *next; struct BSP_CAN_QueueNode *next; /* 指向下一个节点的指针 */
} BSP_CAN_QueueNode_t; } BSP_CAN_QueueNode_t;
/* Private variables -------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */
static BSP_CAN_QueueNode_t *g_can_queue_list = NULL; static BSP_CAN_QueueNode_t *queue_list = NULL;
static osMutexId_t g_can_queue_mutex = NULL; static osMutexId_t queue_mutex = NULL;
static void (*g_can_callbacks[BSP_CAN_NUM][BSP_CAN_CB_NUM])(void); static void (*CAN_Callback[BSP_CAN_NUM][BSP_CAN_CB_NUM])(void);
static bool g_can_initialized = false; static bool inited = false;
static BSP_CAN_IdParser_t id_parser = NULL; /* ID解析器 */
/* Private function prototypes ---------------------------------------------- */ /* 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 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_CreateIdQueue(uint32_t can_id, uint8_t queue_size);
static int8_t BSP_CAN_DeleteIdQueue(uint32_t can_id); static int8_t BSP_CAN_DeleteIdQueue(uint32_t can_id);
static void BSP_CAN_RxFifo0Handler(void); static void BSP_CAN_RxFifoCallback(void);
static void BSP_CAN_RxFifo1Handler(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 -------------------------------------------------------- */ /* Private functions -------------------------------------------------------- */
/** /**
* @brief CAN句柄获取BSP_CAN实例 * @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; if (hcan == NULL) return BSP_CAN_ERR;
/* AUTO GENERATED CAN_GET */ /* AUTO GENERATED CAN_GET */
@ -49,7 +51,7 @@ static BSP_CAN_t BSP_CAN_GetInstance(CAN_HandleTypeDef *hcan) {
* @note * @note
*/ */
static osMessageQueueId_t BSP_CAN_FindQueue(uint32_t can_id) { 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) { while (node != NULL) {
if (node->can_id == can_id) { if (node->can_id == can_id) {
return node->queue; 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; return BSP_ERR_TIMEOUT;
} }
// 检查是否已存在 // 检查是否已存在
BSP_CAN_QueueNode_t *node = g_can_queue_list; BSP_CAN_QueueNode_t *node = queue_list;
while (node != NULL) { while (node != NULL) {
if (node->can_id == can_id) { if (node->can_id == can_id) {
osMutexRelease(g_can_queue_mutex); osMutexRelease(queue_mutex);
return BSP_ERR; // 已存在 return BSP_ERR; // 已存在
} }
node = node->next; 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)); BSP_CAN_QueueNode_t *new_node = (BSP_CAN_QueueNode_t *)BSP_Malloc(sizeof(BSP_CAN_QueueNode_t));
if (new_node == NULL) { if (new_node == NULL) {
osMutexRelease(g_can_queue_mutex); osMutexRelease(queue_mutex);
return BSP_ERR_NULL; 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); new_node->queue = osMessageQueueNew(queue_size, sizeof(BSP_CAN_Message_t), NULL);
if (new_node->queue == NULL) { if (new_node->queue == NULL) {
BSP_Free(new_node); BSP_Free(new_node);
osMutexRelease(g_can_queue_mutex); osMutexRelease(queue_mutex);
return BSP_ERR; return BSP_ERR;
} }
// 初始化节点 // 初始化节点
new_node->can_id = can_id; new_node->can_id = can_id;
new_node->queue_size = queue_size; new_node->queue_size = queue_size;
new_node->next = g_can_queue_list; new_node->next = queue_list;
g_can_queue_list = new_node; queue_list = new_node;
osMutexRelease(g_can_queue_mutex); osMutexRelease(queue_mutex);
return BSP_OK; 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) { 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; return BSP_ERR_TIMEOUT;
} }
BSP_CAN_QueueNode_t **current = &g_can_queue_list; BSP_CAN_QueueNode_t **current = &queue_list;
while (*current != NULL) { while (*current != NULL) {
if ((*current)->can_id == can_id) { if ((*current)->can_id == can_id) {
BSP_CAN_QueueNode_t *to_delete = *current; 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); osMessageQueueDelete(to_delete->queue);
BSP_Free(to_delete); BSP_Free(to_delete);
osMutexRelease(g_can_queue_mutex); osMutexRelease(queue_mutex);
return BSP_OK; return BSP_OK;
} }
current = &(*current)->next; current = &(*current)->next;
} }
osMutexRelease(g_can_queue_mutex); osMutexRelease(queue_mutex);
return BSP_ERR; // 未找到 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; CAN_RxHeaderTypeDef rx_header;
uint8_t rx_data[BSP_CAN_MAX_DLC]; uint8_t rx_data[BSP_CAN_MAX_DLC];
@ -152,238 +173,198 @@ static void BSP_CAN_RxFifo0Handler(void) {
while (HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO0) > 0) { while (HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO0) > 0) {
if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, rx_data) == HAL_OK) { if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, rx_data) == HAL_OK) {
uint32_t can_id = (rx_header.IDE == CAN_ID_STD) ? rx_header.StdId : rx_header.ExtId; // 获取原始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) { BSP_CAN_FrameType_t frame_type = BSP_CAN_GetFrameType(&rx_header);
osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id);
osMutexRelease(g_can_queue_mutex); // 解析ID
uint32_t parsed_id = BSP_CAN_ParseId(original_id, frame_type);
// 直接查找队列,不使用互斥锁(中断中快速执行)
osMessageQueueId_t queue = BSP_CAN_FindQueue(parsed_id);
if (queue != NULL) { if (queue != NULL) {
BSP_CAN_Message_t msg; BSP_CAN_Message_t msg = {0};
msg.header = rx_header; msg.frame_type = frame_type;
memcpy(msg.data, rx_data, BSP_CAN_MAX_DLC); 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); 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);
}
}
// 如果没有找到对应的队列或获取互斥锁超时,消息被直接丢弃
}
} }
} }
} }
/* HAL Callback Functions --------------------------------------------------- */ /* HAL Callback Functions --------------------------------------------------- */
void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan) { void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) { if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX0_CPLT_CB] != NULL) { if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_CPLT_CB])
g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX0_CPLT_CB](); CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_CPLT_CB]();
}
} }
} }
void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan) { void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) { if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX1_CPLT_CB] != NULL) { if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_CPLT_CB])
g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX1_CPLT_CB](); CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_CPLT_CB]();
}
} }
} }
void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan) { void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) { if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX2_CPLT_CB] != NULL) { if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_CPLT_CB])
g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX2_CPLT_CB](); CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_CPLT_CB]();
}
} }
} }
void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan) { void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) { if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX0_ABORT_CB] != NULL) { if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_ABORT_CB])
g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX0_ABORT_CB](); CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_ABORT_CB]();
}
} }
} }
void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan) { void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) { if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX1_ABORT_CB] != NULL) { if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_ABORT_CB])
g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX1_ABORT_CB](); CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_ABORT_CB]();
}
} }
} }
void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan) { void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) { if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX2_ABORT_CB] != NULL) { if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_ABORT_CB])
g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX2_ABORT_CB](); CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_ABORT_CB]();
}
} }
} }
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) { if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_MSG_PENDING_CB] != NULL) { if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_MSG_PENDING_CB])
g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_MSG_PENDING_CB](); CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_MSG_PENDING_CB]();
}
} }
} }
void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan) { void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) { if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_FULL_CB] != NULL) { if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_FULL_CB])
g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_FULL_CB](); CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_FULL_CB]();
}
} }
} }
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) { void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) { if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_MSG_PENDING_CB] != NULL) { if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_MSG_PENDING_CB])
g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_MSG_PENDING_CB](); CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_MSG_PENDING_CB]();
}
} }
} }
void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan) { void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) { if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_FULL_CB] != NULL) { if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_FULL_CB])
g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_FULL_CB](); CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_FULL_CB]();
}
} }
} }
void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan) { void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) { if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_SLEEP_CB] != NULL) { if (CAN_Callback[bsp_can][HAL_CAN_SLEEP_CB])
g_can_callbacks[bsp_can][BSP_CAN_SLEEP_CB](); CAN_Callback[bsp_can][HAL_CAN_SLEEP_CB]();
}
} }
} }
void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan) { void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) { if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_WAKEUP_FROM_RX_MSG_CB] != NULL) { if (CAN_Callback[bsp_can][HAL_CAN_WAKEUP_FROM_RX_MSG_CB])
g_can_callbacks[bsp_can][BSP_CAN_WAKEUP_FROM_RX_MSG_CB](); CAN_Callback[bsp_can][HAL_CAN_WAKEUP_FROM_RX_MSG_CB]();
}
} }
} }
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) { void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) {
BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); BSP_CAN_t bsp_can = CAN_Get(hcan);
if (bsp_can != BSP_CAN_ERR) { if (bsp_can != BSP_CAN_ERR) {
if (g_can_callbacks[bsp_can][BSP_CAN_ERROR_CB] != NULL) { if (CAN_Callback[bsp_can][HAL_CAN_ERROR_CB])
g_can_callbacks[bsp_can][BSP_CAN_ERROR_CB](); CAN_Callback[bsp_can][HAL_CAN_ERROR_CB]();
}
} }
} }
/* Exported functions ------------------------------------------------------- */ /* Exported functions ------------------------------------------------------- */
int8_t BSP_CAN_Init(void) { int8_t BSP_CAN_Init(void) {
if (g_can_initialized) { if (inited) {
return BSP_ERR_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); queue_mutex = osMutexNew(NULL);
if (g_can_queue_mutex == NULL) { if (queue_mutex == NULL) {
return BSP_ERR; return BSP_ERR;
} }
/* AUTO GENERATED CAN_INIT */ /* AUTO GENERATED CAN_INIT */
// 注册默认的接收中断处理函数 inited = true;
for (int can_idx = 0; can_idx < BSP_CAN_NUM; can_idx++) {
BSP_CAN_RegisterCallback((BSP_CAN_t)can_idx, BSP_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifo0Handler);
BSP_CAN_RegisterCallback((BSP_CAN_t)can_idx, BSP_CAN_RX_FIFO1_MSG_PENDING_CB, BSP_CAN_RxFifo1Handler);
}
g_can_initialized = true;
return BSP_OK; return BSP_OK;
} }
int8_t BSP_CAN_DeInit(void) { int8_t BSP_CAN_DeInit(void) {
if (!g_can_initialized) { if (!inited) {
return BSP_ERR; return BSP_ERR;
} }
// 删除所有队列 // 删除所有队列
if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) == osOK) { if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) == osOK) {
BSP_CAN_QueueNode_t *current = g_can_queue_list; BSP_CAN_QueueNode_t *current = queue_list;
while (current != NULL) { while (current != NULL) {
BSP_CAN_QueueNode_t *next = current->next; BSP_CAN_QueueNode_t *next = current->next;
osMessageQueueDelete(current->queue); osMessageQueueDelete(current->queue);
BSP_Free(current); BSP_Free(current);
current = next; current = next;
} }
g_can_queue_list = NULL; queue_list = NULL;
osMutexRelease(g_can_queue_mutex); osMutexRelease(queue_mutex);
} }
// 删除互斥锁 // 删除互斥锁
if (g_can_queue_mutex != NULL) { if (queue_mutex != NULL) {
osMutexDelete(g_can_queue_mutex); osMutexDelete(queue_mutex);
g_can_queue_mutex = NULL; 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; 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, int8_t BSP_CAN_RegisterCallback(BSP_CAN_t can, BSP_CAN_Callback_t type,
void (*callback)(void)) { void (*callback)(void)) {
if (!g_can_initialized) { if (!inited) {
return BSP_ERR_INITED; return BSP_ERR_INITED;
} }
if (callback == NULL) { if (callback == NULL) {
@ -414,19 +395,19 @@ int8_t BSP_CAN_RegisterCallback(BSP_CAN_t can, BSP_CAN_Callback_t type,
return BSP_ERR; return BSP_ERR;
} }
g_can_callbacks[can][type] = callback; CAN_Callback[can][type] = callback;
return BSP_OK; return BSP_OK;
} }
int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format, int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format,
uint32_t id, uint8_t *data, uint8_t dlc) { uint32_t id, uint8_t *data, uint8_t dlc) {
if (!g_can_initialized) { if (!inited) {
return BSP_ERR_INITED; return BSP_ERR_INITED;
} }
if (can >= BSP_CAN_NUM) { if (can >= BSP_CAN_NUM) {
return BSP_ERR; 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; return BSP_ERR_NULL;
} }
if (dlc > BSP_CAN_MAX_DLC) { 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; 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) { int8_t BSP_CAN_RegisterId(uint32_t can_id, uint8_t queue_size) {
if (!g_can_initialized) { if (!inited) {
return BSP_ERR_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) { int8_t BSP_CAN_UnregisterIdQueue(uint32_t can_id) {
if (!g_can_initialized) { if (!inited) {
return BSP_ERR_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) { 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; return BSP_ERR_INITED;
} }
if (msg == NULL) { 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; return BSP_ERR_TIMEOUT;
} }
osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id); osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id);
osMutexRelease(g_can_queue_mutex); osMutexRelease(queue_mutex);
if (queue == NULL) { if (queue == NULL) {
return BSP_ERR_NO_DEV; // 队列不存在 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) { int32_t BSP_CAN_GetQueueCount(uint32_t can_id) {
if (!g_can_initialized) { if (!inited) {
return -1; return -1;
} }
// 线程安全地查找队列 // 线程安全地查找队列
if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) {
return -1; return -1;
} }
osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id); osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id);
osMutexRelease(g_can_queue_mutex); osMutexRelease(queue_mutex);
if (queue == NULL) { if (queue == NULL) {
return -1; // 队列不存在 return -1; // 队列不存在
@ -534,17 +537,17 @@ int32_t BSP_CAN_GetQueueCount(uint32_t can_id) {
} }
int8_t BSP_CAN_FlushQueue(uint32_t can_id) { int8_t BSP_CAN_FlushQueue(uint32_t can_id) {
if (!g_can_initialized) { if (!inited) {
return BSP_ERR_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; return BSP_ERR_TIMEOUT;
} }
osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id); osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id);
osMutexRelease(g_can_queue_mutex); osMutexRelease(queue_mutex);
if (queue == NULL) { if (queue == NULL) {
return BSP_ERR_NO_DEV; // 队列不存在 return BSP_ERR_NO_DEV; // 队列不存在
@ -559,5 +562,33 @@ int8_t BSP_CAN_FlushQueue(uint32_t can_id) {
return BSP_OK; 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 BEGIN */
/* USER CAN FUNCTIONS END */ /* USER CAN FUNCTIONS END */

View File

@ -23,26 +23,27 @@ extern "C" {
typedef enum { typedef enum {
/* AUTO GENERATED BSP_CAN_NAME */ /* AUTO GENERATED BSP_CAN_NAME */
BSP_CAN_NUM, BSP_CAN_NUM,
BSP_CAN_ERR = 0xFF, BSP_CAN_ERR,
} BSP_CAN_t; } BSP_CAN_t;
typedef enum { typedef enum {
BSP_CAN_TX_MAILBOX0_CPLT_CB, HAL_CAN_TX_MAILBOX0_CPLT_CB,
BSP_CAN_TX_MAILBOX1_CPLT_CB, HAL_CAN_TX_MAILBOX1_CPLT_CB,
BSP_CAN_TX_MAILBOX2_CPLT_CB, HAL_CAN_TX_MAILBOX2_CPLT_CB,
BSP_CAN_TX_MAILBOX0_ABORT_CB, HAL_CAN_TX_MAILBOX0_ABORT_CB,
BSP_CAN_TX_MAILBOX1_ABORT_CB, HAL_CAN_TX_MAILBOX1_ABORT_CB,
BSP_CAN_TX_MAILBOX2_ABORT_CB, HAL_CAN_TX_MAILBOX2_ABORT_CB,
BSP_CAN_RX_FIFO0_MSG_PENDING_CB, HAL_CAN_RX_FIFO0_MSG_PENDING_CB,
BSP_CAN_RX_FIFO0_FULL_CB, HAL_CAN_RX_FIFO0_FULL_CB,
BSP_CAN_RX_FIFO1_MSG_PENDING_CB, HAL_CAN_RX_FIFO1_MSG_PENDING_CB,
BSP_CAN_RX_FIFO1_FULL_CB, HAL_CAN_RX_FIFO1_FULL_CB,
BSP_CAN_SLEEP_CB, HAL_CAN_SLEEP_CB,
BSP_CAN_WAKEUP_FROM_RX_MSG_CB, HAL_CAN_WAKEUP_FROM_RX_MSG_CB,
BSP_CAN_ERROR_CB, HAL_CAN_ERROR_CB,
BSP_CAN_CB_NUM BSP_CAN_CB_NUM,
} BSP_CAN_Callback_t; } BSP_CAN_Callback_t;
/* CAN消息格式枚举 - 用于发送和接收消息时指定格式 */
typedef enum { typedef enum {
BSP_CAN_FORMAT_STD_DATA, /* 标准数据帧 */ BSP_CAN_FORMAT_STD_DATA, /* 标准数据帧 */
BSP_CAN_FORMAT_EXT_DATA, /* 扩展数据帧 */ BSP_CAN_FORMAT_EXT_DATA, /* 扩展数据帧 */
@ -50,11 +51,48 @@ typedef enum {
BSP_CAN_FORMAT_EXT_REMOTE, /* 扩展远程帧 */ BSP_CAN_FORMAT_EXT_REMOTE, /* 扩展远程帧 */
} BSP_CAN_Format_t; } 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 { typedef struct {
CAN_RxHeaderTypeDef header; BSP_CAN_FrameType_t frame_type; /* 帧类型 */
uint8_t data[BSP_CAN_MAX_DLC]; 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; } 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 -------------------------------------------- */ /* 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, int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format,
uint32_t id, uint8_t *data, uint8_t dlc); uint32_t id, uint8_t *data, uint8_t dlc);
/**
* @brief
* @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 * @brief CAN ID
* @param can_id CAN ID * @param can_id CAN ID
* @param queue_size 0使 * @param queue_size 0使
* @return BSP_OK * @return BSP_OK
*/ */
@ -108,14 +170,14 @@ int8_t BSP_CAN_RegisterId(uint32_t can_id, uint8_t queue_size);
/** /**
* @brief CAN ID * @brief CAN ID
* @param can_id CAN ID * @param can_id CAN ID
* @return BSP_OK * @return BSP_OK
*/ */
int8_t BSP_CAN_UnregisterIdQueue(uint32_t can_id); int8_t BSP_CAN_UnregisterIdQueue(uint32_t can_id);
/** /**
* @brief CAN * @brief CAN
* @param can_id CAN ID * @param can_id CAN ID
* @param msg * @param msg
* @param timeout 0osWaitForever为永久等待 * @param timeout 0osWaitForever为永久等待
* @return BSP_OK * @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队列中的消息数量 * @brief ID队列中的消息数量
* @param can_id CAN ID * @param can_id CAN ID
* @return -1 * @return -1
*/ */
int32_t BSP_CAN_GetQueueCount(uint32_t can_id); int32_t BSP_CAN_GetQueueCount(uint32_t can_id);
/** /**
* @brief ID队列中的所有消息 * @brief ID队列中的所有消息
* @param can_id CAN ID * @param can_id CAN ID
* @return BSP_OK * @return BSP_OK
*/ */
int8_t BSP_CAN_FlushQueue(uint32_t can_id); 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 BEGIN */
/* USER CAN FUNCTIONS END */ /* USER CAN FUNCTIONS END */

View File

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

View File

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

View File

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

View File

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

View File

@ -45,12 +45,12 @@ typedef enum {
WHITE WHITE
} UI_Color_t; } UI_Color_t;
typedef struct __packed { typedef __Packed struct {
uint8_t op; uint8_t op;
uint8_t num_layer; uint8_t num_layer;
} UI_InterStudent_UIDel_t; } UI_InterStudent_UIDel_t;
typedef struct __packed { typedef __Packed struct {
uint8_t name[3]; uint8_t name[3];
uint8_t type_op : 3; uint8_t type_op : 3;
uint8_t type_ele : 3; uint8_t type_ele : 3;
@ -66,28 +66,28 @@ typedef struct __packed {
uint16_t y_end : 11; uint16_t y_end : 11;
} UI_Ele_t; } UI_Ele_t;
typedef struct __packed { typedef __Packed struct {
UI_Ele_t grapic; UI_Ele_t grapic;
} UI_Drawgrapic_1_t; } UI_Drawgrapic_1_t;
typedef struct __packed { typedef __Packed struct {
UI_Ele_t grapic[2]; UI_Ele_t grapic[2];
} UI_Drawgrapic_2_t; } UI_Drawgrapic_2_t;
typedef struct __packed { typedef __Packed struct {
UI_Ele_t grapic[5]; UI_Ele_t grapic[5];
} UI_Drawgrapic_5_t; } UI_Drawgrapic_5_t;
typedef struct __packed { typedef __Packed struct {
UI_Ele_t grapic[7]; UI_Ele_t grapic[7];
} UI_Drawgrapic_7_t; } UI_Drawgrapic_7_t;
typedef struct __packed { typedef __Packed struct {
UI_Ele_t grapic; UI_Ele_t grapic;
uint8_t character[30]; uint8_t character[30];
} UI_Drawcharacter_t; } UI_Drawcharacter_t;
typedef struct __packed { typedef __Packed struct {
uint8_t del_operation; uint8_t del_operation;
uint8_t layer; uint8_t layer;
} UI_Del_t; } 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); return 60.0f * (float)bullet_speed / (M_2PI * fric_radius);
} }
/** // /**
* @brief // * @brief 断言失败处理
* // *
* @param file // * @param file 文件名
* @param line // * @param line 行号
*/ // */
void VerifyFailed(const char *file, uint32_t line) { // void VerifyFailed(const char *file, uint32_t line) {
UNUSED(file); // UNUSED(file);
UNUSED(line); // UNUSED(line);
while (1) { // while (1) {
__NOP(); // __NOP();
} // }
} // }

View File

@ -8,12 +8,11 @@
extern "C" { extern "C" {
#endif #endif
#include "stm32f4xx.h"
#define ARM_MATH_CM4
#include <float.h> #include <float.h>
#include <math.h> #include <math.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#define M_DEG2RAD_MULT (0.01745329251f) #define M_DEG2RAD_MULT (0.01745329251f)
#define M_RAD2DEG_MULT (57.2957795131f) #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)) #define VERIFY(expr) ((void)(expr))
#endif #endif
/** // /**
* @brief // * @brief 断言失败处理
* // *
* @param file // * @param file 文件名
* @param line // * @param line 行号
*/ // */
void VerifyFailed(const char *file, uint32_t 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 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 device,dr16,ai,nuc
module,chassis,gimbal,arm,shoot 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 -------------------------------------------- */ /* Exported functions prototypes -------------------------------------------- */
int8_t BSP_GPIO_RegisterCallback(uint16_t pin, void (*callback)(void)); int8_t BSP_GPIO_RegisterCallback(uint16_t pin, void (*callback)(void));
int8_t BSP_GPIO_EnableIRQ(uint16_t pin); int8_t BSP_GPIO_EnableIRQ(BSP_GPIO_t gpio);
int8_t BSP_GPIO_DisableIRQ(uint16_t pin); int8_t BSP_GPIO_DisableIRQ(BSP_GPIO_t gpio);
int8_t BSP_GPIO_WritePin(BSP_GPIO_t gpio, bool value); int8_t BSP_GPIO_WritePin(BSP_GPIO_t gpio, bool value);
int8_t BSP_GPIO_TogglePin(BSP_GPIO_t gpio); int8_t BSP_GPIO_TogglePin(BSP_GPIO_t gpio);