bsp写的差不多了

This commit is contained in:
Robofish 2025-08-05 03:47:11 +08:00
parent af7529b529
commit bebfbd716c
29 changed files with 946 additions and 410 deletions

View File

@ -1,6 +1,12 @@
from PyQt5.QtWidgets import QWidget, QVBoxLayout from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QSizePolicy, QTreeWidget, QTreeWidgetItem, QStackedWidget
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt
from qfluentwidgets import TitleLabel, BodyLabel from qfluentwidgets import TitleLabel, BodyLabel, PushButton
from app.tools.analyzing_ioc import analyzing_ioc
from app.code_page.bsp_interface import bsp
import os
import csv
import importlib
class CodeGenerateInterface(QWidget): class CodeGenerateInterface(QWidget):
def __init__(self, project_path, parent=None): def __init__(self, project_path, parent=None):
@ -8,14 +14,137 @@ class CodeGenerateInterface(QWidget):
self.setObjectName("CodeGenerateInterface") self.setObjectName("CodeGenerateInterface")
self.project_path = project_path self.project_path = project_path
layout = QVBoxLayout(self) self._init_ui()
layout.setAlignment(Qt.AlignTop)
layout.setContentsMargins(10, 10, 10, 10)
title = TitleLabel("代码生成页面") def _init_ui(self):
title.setAlignment(Qt.AlignCenter) """初始化界面布局"""
layout.addWidget(title) main_layout = QVBoxLayout(self)
main_layout.setAlignment(Qt.AlignTop)
main_layout.setContentsMargins(10, 10, 10, 10)
desc = BodyLabel(f"当前工程路径: {self.project_path}") top_layout = self._create_top_layout()
desc.setAlignment(Qt.AlignCenter) main_layout.addLayout(top_layout)
layout.addWidget(desc)
# 下方主区域,左右分栏
content_layout = QHBoxLayout()
content_layout.setContentsMargins(0, 10, 0, 0)
main_layout.addLayout(content_layout)
# 左侧树形列表
self.tree = QTreeWidget()
self.tree.setHeaderHidden(True)
self.tree.setMaximumWidth(250)
content_layout.addWidget(self.tree)
# 右侧内容区
self.stack = QStackedWidget()
content_layout.addWidget(self.stack)
self._load_csv_and_build_tree()
self.tree.itemClicked.connect(self.on_tree_item_clicked)
def _create_top_layout(self):
"""创建顶部横向布局"""
top_layout = QHBoxLayout()
top_layout.setAlignment(Qt.AlignTop)
# 项目名称标签
project_name = os.path.basename(self.project_path)
name_label = BodyLabel(f"项目名称: {project_name}")
name_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
top_layout.addWidget(name_label)
# FreeRTOS状态标签
freertos_label = BodyLabel(f"FreeRTOS: {self._get_freertos_status()}")
freertos_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
top_layout.addWidget(freertos_label)
# 生成代码按钮
generate_btn = PushButton("Generate Code")
generate_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
generate_btn.clicked.connect(self.generate_code)
top_layout.addWidget(generate_btn, alignment=Qt.AlignRight)
return top_layout
def generate_code(self):
"""生成代码逻辑"""
# 收集所有已加载的页面对象
pages = []
for i in range(self.stack.count()):
widget = self.stack.widget(i)
pages.append(widget)
bsp.generate_bsp(self.project_path, pages)
# component.generate_component(self.project_path)
# device.generate_device(self.project_path)
def _get_freertos_status(self):
"""获取FreeRTOS状态"""
ioc_files = [f for f in os.listdir(self.project_path) if f.endswith('.ioc')]
if ioc_files:
ioc_path = os.path.join(self.project_path, ioc_files[0])
return "开启" if analyzing_ioc.is_freertos_enabled_from_ioc(ioc_path) else "未开启"
return "未找到.ioc文件"
def _load_csv_and_build_tree(self):
# 获取脚本目录
script_dir = os.path.dirname(os.path.abspath(__file__))
csv_path = os.path.join(script_dir, "../assets/User_code/config.csv")
csv_path = os.path.abspath(csv_path)
print(f"加载CSV路径: {csv_path}")
if not os.path.exists(csv_path):
print(f"配置文件未找到: {csv_path}")
return
self.tree.clear()
with open(csv_path, newline='', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
row = [cell.strip() for cell in row if cell.strip()]
if not row:
continue
main_title = row[0]
main_item = QTreeWidgetItem([main_title])
for sub in row[1:]:
sub_item = QTreeWidgetItem([sub])
main_item.addChild(sub_item)
self.tree.addTopLevelItem(main_item)
self.tree.repaint()
def on_tree_item_clicked(self, item, column):
if item.parent():
main_title = item.parent().text(0)
sub_title = item.text(0)
class_name = f"{main_title}_{sub_title}".replace("-", "_")
widget = self._get_or_create_page(class_name)
if widget:
self.stack.setCurrentWidget(widget)
def _get_or_create_page(self, class_name):
for i in range(self.stack.count()):
w = self.stack.widget(i)
if w.objectName() == class_name:
return w
try:
module_name = f"app.code_page.{class_name.split('_')[0]}_interface"
module = importlib.import_module(module_name)
cls = getattr(module, class_name)
widget = cls(self.project_path)
widget.setObjectName(class_name)
self.stack.addWidget(widget)
print(f"加载页面类: {class_name} 来自模块: {module_name}")
return widget
except Exception as e:
# 自动识别通用外设页面
from app.code_page.bsp_interface import BspSimplePeripheral
peripheral_name = class_name.split('_')[1] if '_' in class_name else class_name
# 模板文件名自动推断
template_names = {
'header': f"{peripheral_name.lower()}.h",
'source': f"{peripheral_name.lower()}.c"
}
widget = BspSimplePeripheral(self.project_path, peripheral_name, template_names)
widget.setObjectName(class_name)
self.stack.addWidget(widget)
print(f"自动加载通用外设页面: {class_name}")
return widget

View File

@ -0,0 +1,453 @@
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLineEdit, QCheckBox, QComboBox, QTableWidget, QHeaderView, QMessageBox
from qfluentwidgets import TitleLabel, BodyLabel, PushButton
from app.tools.analyzing_ioc import analyzing_ioc
from app.tools.code_generator import CodeGenerator
import os
import csv
class BspSimplePeripheral(QWidget):
def __init__(self, project_path, peripheral_name, template_names):
super().__init__()
self.project_path = project_path
self.peripheral_name = peripheral_name
self.template_names = template_names
# 加载描述
describe_path = os.path.join(os.path.dirname(__file__), "../../assets/User_code/bsp/describe.csv")
self.descriptions = load_descriptions(describe_path)
self._init_ui()
self._load_config()
def _init_ui(self):
layout = QVBoxLayout(self)
layout.addWidget(TitleLabel(f"{self.peripheral_name} 配置"))
desc = self.descriptions.get(self.peripheral_name.lower(), "")
if desc:
layout.addWidget(BodyLabel(f"功能说明:{desc}"))
self.generate_checkbox = QCheckBox(f"启用 {self.peripheral_name}")
layout.addWidget(self.generate_checkbox)
def is_need_generate(self):
return self.generate_checkbox.isChecked()
def _generate_bsp_code_internal(self):
if not self.is_need_generate():
return False
template_dir = CodeGenerator.get_template_dir()
# 直接拷贝模板,无需特殊处理
for key, filename in self.template_names.items():
template_path = os.path.join(template_dir, filename)
template_content = CodeGenerator.load_template(template_path)
if not template_content:
return False
output_path = os.path.join(self.project_path, f"User/bsp/{filename}")
if not CodeGenerator.save_file(template_content, output_path):
return False
self._save_config()
return True
def _save_config(self):
config_path = os.path.join(self.project_path, "User/bsp/bsp_config.yaml")
config_data = CodeGenerator.load_config(config_path)
config_data[self.peripheral_name.lower()] = {'enabled': True}
CodeGenerator.save_config(config_data, config_path)
def _load_config(self):
config_path = os.path.join(self.project_path, "User/bsp/bsp_config.yaml")
config_data = CodeGenerator.load_config(config_path)
conf = config_data.get(self.peripheral_name.lower(), {})
if conf.get('enabled', False):
self.generate_checkbox.setChecked(True)
class BspPeripheralBase(QWidget):
def __init__(self, project_path, peripheral_name, template_names, enum_prefix, handle_prefix, yaml_key, get_available_func):
super().__init__()
self.project_path = project_path
self.peripheral_name = peripheral_name
self.template_names = template_names
self.enum_prefix = enum_prefix
self.handle_prefix = handle_prefix
self.yaml_key = yaml_key
self.get_available_func = get_available_func
self.available_list = []
# 新增:加载描述
describe_path = os.path.join(os.path.dirname(__file__), "../../assets/User_code/bsp/describe.csv")
self.descriptions = load_descriptions(describe_path)
self._init_ui()
self._load_config()
def _init_ui(self):
layout = QVBoxLayout(self)
layout.addWidget(TitleLabel(f"{self.peripheral_name} 配置"))
desc = self.descriptions.get(self.peripheral_name.lower(), "")
if desc:
layout.addWidget(BodyLabel(f"功能说明:{desc}"))
self.generate_checkbox = QCheckBox(f"生成 {self.peripheral_name} 代码")
self.generate_checkbox = QCheckBox(f"生成 {self.peripheral_name} 代码")
self.generate_checkbox.stateChanged.connect(self._on_generate_changed)
layout.addWidget(self.generate_checkbox)
self.content_widget = QWidget()
content_layout = QVBoxLayout(self.content_widget)
self._get_available_list()
if not self.available_list:
content_layout.addWidget(BodyLabel(f"在 .ioc 文件中未找到已启用的 {self.peripheral_name}"))
else:
content_layout.addWidget(BodyLabel(f"可用的 {self.peripheral_name}: {', '.join(self.available_list)}"))
self.table = QTableWidget(0, 3)
self.table.setHorizontalHeaderLabels(["设备名称", f"{self.peripheral_name}选择", "操作"])
self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
content_layout.addWidget(self.table)
add_btn = PushButton(f"添加 {self.peripheral_name} 设备")
add_btn.clicked.connect(self._add_device)
content_layout.addWidget(add_btn)
layout.addWidget(self.content_widget)
self.content_widget.setEnabled(False)
def _get_available_list(self):
self.available_list = self.get_available_func(self.project_path)
def _on_generate_changed(self, state):
self.content_widget.setEnabled(state == 2)
def _add_device(self):
row = self.table.rowCount()
self.table.insertRow(row)
name_edit = QLineEdit()
name_edit.setPlaceholderText(f"输入设备名称")
self.table.setCellWidget(row, 0, name_edit)
combo = QComboBox()
combo.addItems(self.available_list)
self.table.setCellWidget(row, 1, combo)
del_btn = PushButton("删除")
del_btn.clicked.connect(lambda: self._delete_device(row))
self.table.setCellWidget(row, 2, del_btn)
def _delete_device(self, row):
self.table.removeRow(row)
def _collect_configs(self):
configs = []
for row in range(self.table.rowCount()):
name_widget = self.table.cellWidget(row, 0)
sel_widget = self.table.cellWidget(row, 1)
if name_widget and sel_widget:
name = name_widget.text().strip()
sel = sel_widget.currentText()
if name and sel:
configs.append((name.upper(), sel))
return configs
def is_need_generate(self):
return self.generate_checkbox.isChecked() and bool(self._collect_configs())
def generate_bsp_code(self):
if not self.is_need_generate():
return False
configs = self._collect_configs()
if not configs:
return False
template_dir = CodeGenerator.get_template_dir()
if not self._generate_header_file(configs, template_dir):
return False
if not self._generate_source_file(configs, template_dir):
return False
self._save_config(configs)
QMessageBox.information(self, "成功", f"{self.peripheral_name} 代码生成成功!")
return True
def _generate_header_file(self, configs, template_dir):
template_path = os.path.join(template_dir, self.template_names['header'])
template_content = CodeGenerator.load_template(template_path)
if not template_content:
return False
enum_lines = [f" {self.enum_prefix}_{name}," for name, _ in configs]
content = CodeGenerator.replace_auto_generated(
template_content, f"AUTO GENERATED {self.enum_prefix}_NAME", "\n".join(enum_lines)
)
output_path = os.path.join(self.project_path, f"User/bsp/{self.template_names['header']}")
return CodeGenerator.save_file(content, output_path)
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函数
get_lines = []
for idx, (name, instance) in enumerate(configs):
if idx == 0:
get_lines.append(f" if ({self.handle_prefix}->Instance == {instance})")
else:
get_lines.append(f" else if ({self.handle_prefix}->Instance == {instance})")
get_lines.append(f" return {self.enum_prefix}_{name};")
content = CodeGenerator.replace_auto_generated(
template_content, f"AUTO GENERATED {self.enum_prefix.split('_')[1]}_GET", "\n".join(get_lines)
)
# Handle函数
handle_lines = []
for name, instance in configs:
handle_lines.append(f" case {self.enum_prefix}_{name}:")
handle_lines.append(f" return &h{instance.lower()};")
content = CodeGenerator.replace_auto_generated(
content, f"AUTO GENERATED {self.enum_prefix}_GET_HANDLE", "\n".join(handle_lines)
)
output_path = os.path.join(self.project_path, f"User/bsp/{self.template_names['source']}")
return CodeGenerator.save_file(content, output_path)
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)
config_data[self.yaml_key] = {
'enabled': True,
'devices': [{'name': name, 'instance': instance} for name, instance in configs]
}
CodeGenerator.save_config(config_data, config_path)
def _load_config(self):
config_path = os.path.join(self.project_path, "User/bsp/bsp_config.yaml")
config_data = CodeGenerator.load_config(config_path)
conf = config_data.get(self.yaml_key, {})
if conf.get('enabled', False):
self.generate_checkbox.setChecked(True)
devices = conf.get('devices', [])
for device in devices:
if self.available_list:
self._add_device()
row = self.table.rowCount() - 1
name_widget = self.table.cellWidget(row, 0)
sel_widget = self.table.cellWidget(row, 1)
if name_widget:
name_widget.setText(device.get('name', ''))
if sel_widget:
instance = device.get('instance', '')
if instance in self.available_list:
sel_widget.setCurrentText(instance)
def _generate_bsp_code_internal(self):
if not self.is_need_generate():
return False
configs = self._collect_configs()
if not configs:
return False
template_dir = CodeGenerator.get_template_dir()
if not self._generate_header_file(configs, template_dir):
return False
if not self._generate_source_file(configs, template_dir):
return False
self._save_config(configs)
return True
def load_descriptions(csv_path):
descriptions = {}
if os.path.exists(csv_path):
with open(csv_path, encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
if len(row) >= 2:
key, desc = row[0].strip(), row[1].strip()
descriptions[key.lower()] = desc
return descriptions
# 各外设的可用列表获取函数
def get_available_i2c(project_path):
ioc_files = [f for f in os.listdir(project_path) if f.endswith('.ioc')]
if ioc_files:
ioc_path = os.path.join(project_path, ioc_files[0])
return analyzing_ioc.get_enabled_i2c_from_ioc(ioc_path)
return []
def get_available_can(project_path):
ioc_files = [f for f in os.listdir(project_path) if f.endswith('.ioc')]
if ioc_files:
ioc_path = os.path.join(project_path, ioc_files[0])
return analyzing_ioc.get_enabled_can_from_ioc(ioc_path)
return []
def get_available_spi(project_path):
ioc_files = [f for f in os.listdir(project_path) if f.endswith('.ioc')]
if ioc_files:
ioc_path = os.path.join(project_path, ioc_files[0])
return analyzing_ioc.get_enabled_spi_from_ioc(ioc_path)
return []
def get_available_uart(project_path):
ioc_files = [f for f in os.listdir(project_path) if f.endswith('.ioc')]
if ioc_files:
ioc_path = os.path.join(project_path, ioc_files[0])
return analyzing_ioc.get_enabled_uart_from_ioc(ioc_path)
return []
def get_available_gpio(project_path):
ioc_files = [f for f in os.listdir(project_path) if f.endswith('.ioc')]
if ioc_files:
ioc_path = os.path.join(project_path, ioc_files[0])
return analyzing_ioc.get_enabled_gpio_from_ioc(ioc_path)
return []
# 具体外设类
class bsp_i2c(BspPeripheralBase):
def __init__(self, project_path):
super().__init__(
project_path,
"I2C",
{'header': 'i2c.h', 'source': 'i2c.c'},
"BSP_I2C",
"hi2c",
"i2c",
get_available_i2c
)
class bsp_can(BspPeripheralBase):
def __init__(self, project_path):
super().__init__(
project_path,
"CAN",
{'header': 'can.h', 'source': 'can.c'},
"BSP_CAN",
"hcan",
"can",
get_available_can
)
class bsp_spi(BspPeripheralBase):
def __init__(self, project_path):
super().__init__(
project_path,
"SPI",
{'header': 'spi.h', 'source': 'spi.c'},
"BSP_SPI",
"hspi",
"spi",
get_available_spi
)
class bsp_uart(BspPeripheralBase):
def __init__(self, project_path):
super().__init__(
project_path,
"UART",
{'header': 'uart.h', 'source': 'uart.c'},
"BSP_UART",
"huart",
"uart",
get_available_uart
)
class bsp_gpio(QWidget):
def __init__(self, project_path):
super().__init__()
self.project_path = project_path
self.available_list = get_available_gpio(project_path)
# 新增:加载描述
describe_path = os.path.join(os.path.dirname(__file__), "../../assets/User_code/bsp/describe.csv")
self.descriptions = load_descriptions(describe_path)
self._init_ui()
def _init_ui(self):
layout = QVBoxLayout(self)
layout.addWidget(TitleLabel("GPIO 配置"))
# 新增:显示描述
desc = self.descriptions.get("gpio", "")
if desc:
layout.addWidget(BodyLabel(f"功能说明:{desc}"))
self.generate_checkbox = QCheckBox("生成 GPIO 代码")
layout.addWidget(self.generate_checkbox)
if not self.available_list:
layout.addWidget(BodyLabel("在 .ioc 文件中未找到可用的 GPIO"))
else:
self.table = QTableWidget(len(self.available_list), 1)
self.table.setHorizontalHeaderLabels(["Label"])
self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
for row, item in enumerate(self.available_list):
from PyQt5.QtWidgets import QTableWidgetItem
self.table.setItem(row, 0, QTableWidgetItem(item['label']))
self.table.setEditTriggers(QTableWidget.NoEditTriggers)
layout.addWidget(self.table)
def is_need_generate(self):
return self.generate_checkbox.isChecked() and bool(self.available_list)
def _generate_bsp_code_internal(self):
if not self.is_need_generate():
return False
template_dir = CodeGenerator.get_template_dir()
if not self._generate_header_file(template_dir):
return False
if not self._generate_source_file(template_dir):
return False
self._save_config()
return True
def _generate_header_file(self, template_dir):
template_path = os.path.join(template_dir, "gpio.h")
template_content = CodeGenerator.load_template(template_path)
if not template_content:
return False
# 如有需要可在此处插入自动生成内容
output_path = os.path.join(self.project_path, "User/bsp/gpio.h")
return CodeGenerator.save_file(template_content, output_path)
def _generate_source_file(self, template_dir):
template_path = os.path.join(template_dir, "gpio.c")
template_content = CodeGenerator.load_template(template_path)
if not template_content:
return False
# 生成 IRQ 使能/禁用代码
enable_lines = []
disable_lines = []
for item in self.available_list:
label = item['label']
enable_lines.append(f" case {label}_Pin:")
enable_lines.append(f" HAL_NVIC_EnableIRQ({label}_EXTI_IRQn);")
enable_lines.append(f" break;")
disable_lines.append(f" case {label}_Pin:")
disable_lines.append(f" HAL_NVIC_DisableIRQ({label}_EXTI_IRQn);")
disable_lines.append(f" break;")
content = CodeGenerator.replace_auto_generated(
template_content, "AUTO GENERATED BSP_GPIO_ENABLE_IRQ", "\n".join(enable_lines)
)
content = CodeGenerator.replace_auto_generated(
content, "AUTO GENERATED BSP_GPIO_DISABLE_IRQ", "\n".join(disable_lines)
)
output_path = os.path.join(self.project_path, "User/bsp/gpio.c")
return CodeGenerator.save_file(content, output_path)
def _save_config(self):
config_path = os.path.join(self.project_path, "User/bsp/bsp_config.yaml")
config_data = CodeGenerator.load_config(config_path)
config_data['gpio'] = {
'enabled': True,
'labels': [item['label'] for item in self.available_list]
}
CodeGenerator.save_config(config_data, config_path)
class bsp(QWidget):
def __init__(self, project_path):
super().__init__()
self.project_path = project_path
@staticmethod
def generate_bsp(project_path, pages):
total = 0
success_count = 0
fail_count = 0
fail_list = []
for page in pages:
name = page.objectName() if hasattr(page, "objectName") else str(page)
if hasattr(page, "is_need_generate") and page.is_need_generate():
total += 1
try:
result = page._generate_bsp_code_internal()
if result:
success_count += 1
else:
fail_count += 1
fail_list.append(name)
except Exception as e:
fail_count += 1
fail_list.append(f"{name} (异常: {e})")
msg = f"总共尝试生成 {total} 项,成功 {success_count} 项,失败 {fail_count} 项。"
if fail_list:
msg += "\n失败项:\n" + "\n".join(fail_list)
QMessageBox.information(None, "代码生成结果", msg)

View File

View File

View File

@ -1,7 +1,146 @@
class analyzing_ioc: class analyzing_ioc:
def __init__(self, ioc_data): # 初始化方法接收IOC数据 @staticmethod
self.ioc_data = ioc_data # 存储IOC数据 def is_freertos_enabled_from_ioc(ioc_path):
"""
检查指定 .ioc 文件是否开启了 FreeRTOS
"""
config = {}
with open(ioc_path, encoding='utf-8') as f:
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
if '=' in line:
key, value = line.split('=', 1)
config[key.strip()] = value.strip()
ip_keys = [k for k in config if k.startswith('Mcu.IP')]
for k in ip_keys:
if config[k] == 'FREERTOS':
return True
for k in config:
if k.startswith('FREERTOS.'):
return True
return False
@staticmethod
def get_enabled_i2c_from_ioc(ioc_path):
"""
.ioc文件中获取已启用的I2C列表
返回格式: ['I2C1', 'I2C3']
"""
enabled_i2c = []
with open(ioc_path, encoding='utf-8', errors='ignore') as f:
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
if '=' in line:
key, value = line.split('=', 1)
key = key.strip()
value = value.strip()
# 检查是否启用了I2C
if key.startswith('Mcu.IP') and value.startswith('I2C'):
# 提取I2C编号如I2C1, I2C2等
i2c_name = value.split('.')[0] if '.' in value else value
if i2c_name not in enabled_i2c:
enabled_i2c.append(i2c_name)
return sorted(enabled_i2c)
@staticmethod
def get_enabled_spi_from_ioc(ioc_path):
"""
获取已启用的SPI列表
返回格式: ['SPI1', 'SPI2']
"""
enabled_spi = []
with open(ioc_path, encoding='utf-8', errors='ignore') as f:
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
if '=' in line:
key, value = line.split('=', 1)
key = key.strip()
value = value.strip()
if key.startswith('Mcu.IP') and value.startswith('SPI'):
spi_name = value.split('.')[0] if '.' in value else value
if spi_name not in enabled_spi:
enabled_spi.append(spi_name)
return sorted(enabled_spi)
@staticmethod
def get_enabled_can_from_ioc(ioc_path):
"""
获取已启用的CAN列表
返回格式: ['CAN1', 'CAN2']
"""
enabled_can = []
with open(ioc_path, encoding='utf-8', errors='ignore') as f:
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
if '=' in line:
key, value = line.split('=', 1)
key = key.strip()
value = value.strip()
if key.startswith('Mcu.IP') and value.startswith('CAN'):
can_name = value.split('.')[0] if '.' in value else value
if can_name not in enabled_can:
enabled_can.append(can_name)
return sorted(enabled_can)
@staticmethod
def get_enabled_uart_from_ioc(ioc_path):
"""
获取已启用的UART/USART列表
返回格式: ['USART1', 'USART2', 'UART4']
"""
enabled_uart = []
with open(ioc_path, encoding='utf-8', errors='ignore') as f:
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
if '=' in line:
key, value = line.split('=', 1)
key = key.strip()
value = value.strip()
# 检查是否启用了UART或USART
if key.startswith('Mcu.IP') and (value.startswith('USART') or value.startswith('UART')):
uart_name = value.split('.')[0] if '.' in value else value
if uart_name not in enabled_uart:
enabled_uart.append(uart_name)
return sorted(enabled_uart)
@staticmethod
def get_enabled_gpio_from_ioc(ioc_path):
"""
获取所有带 EXTI 且有 Label GPIO返回 [{'pin': 'PC4', 'label': 'ACCL_INT'}, ...]
"""
gpio_list = []
gpio_params = {}
with open(ioc_path, encoding='utf-8', errors='ignore') as f:
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
if '=' in line:
key, value = line.split('=', 1)
key = key.strip()
value = value.strip()
if '.GPIOParameters' in key:
gpio_params[key.split('.')[0]] = value
elif '.GPIO_Label' in key:
pin = key.split('.')[0]
gpio_params[f"{pin}_label"] = value
elif '.GPIO_ModeDefaultEXTI' in key:
pin = key.split('.')[0]
gpio_params[f"{pin}_exti"] = value
for pin in gpio_params:
if not pin.endswith('_label') and not pin.endswith('_exti'):
label = gpio_params.get(f"{pin}_label", None)
exti = gpio_params.get(f"{pin}_exti", None)
if label and exti:
gpio_list.append({'pin': pin, 'label': label})
return gpio_list

View File

@ -0,0 +1,75 @@
import os
import yaml
import shutil
from typing import Dict, List, Tuple
class CodeGenerator:
"""通用代码生成器"""
@staticmethod
def load_template(template_path: str) -> str:
"""加载代码模板"""
try:
with open(template_path, 'r', encoding='utf-8') as f:
return f.read()
except Exception as e:
print(f"加载模板失败: {template_path}, 错误: {e}")
return ""
@staticmethod
def replace_auto_generated(content: str, marker: str, replacement: str) -> str:
"""替换自动生成的代码标记"""
marker_line = f"/* {marker} */"
if marker_line in content:
return content.replace(marker_line, replacement)
return content
@staticmethod
def save_file(content: str, file_path: str) -> bool:
"""保存文件"""
try:
os.makedirs(os.path.dirname(file_path), exist_ok=True)
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
return True
except Exception as e:
print(f"保存文件失败: {file_path}, 错误: {e}")
return False
@staticmethod
def load_config(config_path: str) -> Dict:
"""加载配置文件"""
if os.path.exists(config_path):
try:
with open(config_path, 'r', encoding='utf-8') as f:
return yaml.safe_load(f) or {}
except Exception as e:
print(f"加载配置失败: {config_path}, 错误: {e}")
return {}
@staticmethod
def save_config(config: Dict, config_path: str) -> bool:
"""保存配置文件"""
try:
os.makedirs(os.path.dirname(config_path), exist_ok=True)
with open(config_path, 'w', encoding='utf-8') as f:
yaml.safe_dump(config, f, allow_unicode=True, default_flow_style=False)
return True
except Exception as e:
print(f"保存配置失败: {config_path}, 错误: {e}")
return False
@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")
else:
# 如果找不到,使用相对路径作为备选
return os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "assets/User_code/bsp")

Binary file not shown.

View File

@ -1,32 +0,0 @@
/* Includes ----------------------------------------------------------------- */
#include <gpio.h>
#include "bsp/bsp.h"
#include "bsp/buzzer_gpio.h"
/* Private define ----------------------------------------------------------- */
#define BSP_BUZZER_GPIO GPIOA
#define BSP_BUZZER_PIN GPIO_PIN_1
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
/* Private variables -------------------------------------------------------- */
/* Private function --------------------------------------------------------- */
/* Exported functions ------------------------------------------------------- */
int8_t BSP_Buzzer_Set(BSP_Buzzer_Status_t s)
{
switch (s)
{
case BSP_BUZZER_ON:
HAL_GPIO_WritePin(BSP_BUZZER_GPIO, BSP_BUZZER_PIN, GPIO_PIN_SET); // 打开蜂鸣器
break;
case BSP_BUZZER_OFF:
HAL_GPIO_WritePin(BSP_BUZZER_GPIO, BSP_BUZZER_PIN, GPIO_PIN_RESET); // 关闭蜂鸣器
break;
case BSP_BUZZER_TAGGLE:
HAL_GPIO_TogglePin(BSP_BUZZER_GPIO, BSP_BUZZER_PIN); // 切换蜂鸣器状态
break;
default:
return BSP_ERR;
}
return BSP_OK;
}

View File

@ -9,10 +9,7 @@ static void (*CAN_Callback[BSP_CAN_NUM][BSP_CAN_CB_NUM])(void);
/* Private function -------------------------------------------------------- */ /* Private function -------------------------------------------------------- */
static BSP_CAN_t CAN_Get(CAN_HandleTypeDef *hcan) { static BSP_CAN_t CAN_Get(CAN_HandleTypeDef *hcan) {
if (hcan->Instance == CAN2) /* AUTO GENERATED CAN_GET */
return BSP_CAN_2;
else if (hcan->Instance == CAN1)
return BSP_CAN_1;
else else
return BSP_CAN_ERR; return BSP_CAN_ERR;
} }
@ -124,10 +121,7 @@ void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) {
/* Exported functions ------------------------------------------------------- */ /* Exported functions ------------------------------------------------------- */
CAN_HandleTypeDef *BSP_CAN_GetHandle(BSP_CAN_t can) { CAN_HandleTypeDef *BSP_CAN_GetHandle(BSP_CAN_t can) {
switch (can) { switch (can) {
case BSP_CAN_2: /* AUTO GENERATED BSP_CAN_GET_HANDLE */
return &hcan2;
case BSP_CAN_1:
return &hcan1;
default: default:
return NULL; return NULL;
} }

View File

@ -13,8 +13,7 @@ extern "C" {
/* Exported macro ----------------------------------------------------------- */ /* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */ /* Exported types ----------------------------------------------------------- */
typedef enum { typedef enum {
BSP_CAN_1, /* AUTO GENERATED BSP_CAN_NAME */
BSP_CAN_2,
BSP_CAN_NUM, BSP_CAN_NUM,
BSP_CAN_ERR, BSP_CAN_ERR,
} BSP_CAN_t; } BSP_CAN_t;

View File

@ -1,118 +1,34 @@
#include "bsp_delay.h" /* Includes ----------------------------------------------------------------- */
#include "bsp/delay.h"
#include "cmsis_os.h" #include <cmsis_os2.h>
#include "main.h" #include <main.h>
/* Private define ----------------------------------------------------------- */ /* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */ /* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */ /* Private typedef ---------------------------------------------------------- */
/* Private variables -------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */
static uint8_t fac_us = 0;
static uint32_t fac_ms = 0;
/* Private function -------------------------------------------------------- */ /* Private function -------------------------------------------------------- */
static void delay_ticks(uint32_t ticks)
{
uint32_t told = SysTick->VAL;
uint32_t tnow = 0;
uint32_t tcnt = 0;
uint32_t reload = SysTick->LOAD;
while (1)
{
tnow = SysTick->VAL;
if (tnow != told)
{
if (tnow < told)
{
tcnt += told - tnow;
}
else
{
tcnt += reload - tnow + told;
}
told = tnow;
if (tcnt >= ticks)
{
break;
}
}
}
}
/* Exported functions ------------------------------------------------------- */ /* Exported functions ------------------------------------------------------- */
int8_t BSP_Delay(uint32_t ms) {
uint32_t tick_period = 1000u / osKernelGetTickFreq();
uint32_t ticks = ms / tick_period;
/** switch (osKernelGetState()) {
* @brief
* @param ms
* @return
*/
int8_t BSP_Delay(uint32_t ms)
{
uint32_t tick_period = 1000u / osKernelGetTickFreq();
uint32_t ticks = ms / tick_period;
switch (osKernelGetState())
{
case osKernelError: case osKernelError:
case osKernelReserved: case osKernelReserved:
case osKernelLocked: case osKernelLocked:
case osKernelSuspended: case osKernelSuspended:
return BSP_ERR; return BSP_ERR;
case osKernelRunning: case osKernelRunning:
osDelay(ticks ? ticks : 1); osDelay(ticks ? ticks : 1);
break; break;
case osKernelInactive: case osKernelInactive:
case osKernelReady: case osKernelReady:
HAL_Delay(ms); HAL_Delay(ms);
break; break;
} }
return BSP_OK; return BSP_OK;
}
/**
* @brief
* @param
* @return
*/
int8_t BSP_Delay_Init(void)
{
if (SystemCoreClock == 0)
{
return BSP_ERR;
}
fac_us = SystemCoreClock / 1000000;
fac_ms = SystemCoreClock / 1000;
return BSP_OK;
}
/**
* @brief 线
* @param us
* @return
*/
int8_t BSP_Delay_us(uint32_t us)
{
if (fac_us == 0)
{
return BSP_ERR;
}
uint32_t ticks = us * fac_us;
delay_ticks(ticks);
return BSP_OK;
}
/**
* @brief 线
* @param ms
* @return
*/
int8_t BSP_Delay_ms(uint32_t ms)
{
if (fac_ms == 0)
{
return BSP_ERR;
}
uint32_t ticks = ms * fac_ms;
delay_ticks(ticks);
return BSP_OK;
} }

View File

@ -1,34 +1,20 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */ /* Includes ----------------------------------------------------------------- */
#include "bsp\delay.h" #include <stdint.h>
#include <cmsis_os2.h> #include "bsp/bsp.h"
#include <main.h>
/* Private define ----------------------------------------------------------- */ /* Exported constants ------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */ /* Exported macro ----------------------------------------------------------- */
/* Private typedef ---------------------------------------------------------- */ /* Exported types ----------------------------------------------------------- */
/* Private variables -------------------------------------------------------- */ /* Exported functions prototypes -------------------------------------------- */
/* Private function -------------------------------------------------------- */ int8_t BSP_Delay(uint32_t ms);
/* Exported functions ------------------------------------------------------- */
int8_t BSP_Delay(uint32_t ms) {
uint32_t tick_period = 1000u / osKernelGetTickFreq();
uint32_t ticks = ms / tick_period;
switch (osKernelGetState()) { #ifdef __cplusplus
case osKernelError:
case osKernelReserved:
case osKernelLocked:
case osKernelSuspended:
return BSP_ERR;
case osKernelRunning:
osDelay(ticks ? ticks : 1);
break;
case osKernelInactive:
case osKernelReady:
HAL_Delay(ms);
break;
}
return BSP_OK;
} }
#endif

View File

@ -1,2 +0,0 @@
i2c,I2C
uart,USART,UART
1 i2c,I2C
2 uart,USART,UART

View File

@ -1,3 +1,5 @@
uart,要求开启dma和中断 uart,要求开启dma和中断
can,要求开启can的中断 can,要求开启can的中断
delay,暂时只有delay_ms函数 gpio,要求设置label开启中断
spi,要求开启spi中断
i2c,要求开始spi中断
1 uart 要求开启dma和中断
2 can 要求开启can的中断
3 delay gpio 暂时只有delay_ms函数 要求设置label开启中断
4 spi 要求开启spi中断
5 i2c 要求开始spi中断

View File

@ -0,0 +1,53 @@
/* Includes ----------------------------------------------------------------- */
#include "bsp/gpio.h"
#include <gpio.h>
#include <main.h>
/* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
/* Private variables -------------------------------------------------------- */
static void (*GPIO_Callback[16])(void);
/* Private function -------------------------------------------------------- */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
for (uint8_t i = 0; i < 16; i++) {
if (GPIO_Pin & (1 << i)) {
if (GPIO_Callback[i]) {
GPIO_Callback[i]();
}
}
}
}
/* Exported functions ------------------------------------------------------- */
int8_t BSP_GPIO_RegisterCallback(uint16_t pin, void (*callback)(void)) {
if (callback == NULL) return BSP_ERR_NULL;
for (uint8_t i = 0; i < 16; i++) {
if (pin & (1 << i)) {
GPIO_Callback[i] = callback;
break;
}
}
return BSP_OK;
}
int8_t BSP_GPIO_EnableIRQ(uint16_t pin) {
switch (pin) {
/* AUTO GENERATED BSP_GPIO_ENABLE_IRQ */
default:
return BSP_ERR;
}
return BSP_OK;
}
int8_t BSP_GPIO_DisableIRQ(uint16_t pin) {
switch (pin) {
/* AUTO GENERATED BSP_GPIO_DISABLE_IRQ */
default:
return BSP_ERR;
}
return BSP_OK;
}

View File

@ -12,26 +12,12 @@ extern "C" {
/* Exported constants ------------------------------------------------------- */ /* Exported constants ------------------------------------------------------- */
/* Exported macro ----------------------------------------------------------- */ /* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */ /* Exported types ----------------------------------------------------------- */
/* GPIO设备枚举与设备对应 */
typedef enum {
BSP_GPIO_USER_KEY,
/* BSP_GPIO_XXX, */
BSP_GPIO_NUM,
BSP_GPIO_ERR,
} BSP_GPIO_t;
/* GPIO支持的中断回调函数类型 */
typedef enum {
BSP_GPIO_EXTI_CB,
BSP_GPIO_CB_NUM,
} BSP_GPIO_Callback_t;
/* Exported functions prototypes -------------------------------------------- */ /* Exported functions prototypes -------------------------------------------- */
int8_t BSP_GPIO_RegisterCallback(BSP_GPIO_t gpio, BSP_GPIO_Callback_t type, void (*callback)(void)); int8_t BSP_GPIO_RegisterCallback(uint16_t pin, void (*callback)(void));
int8_t BSP_GPIO_EnableIRQ(BSP_GPIO_t gpio);
int8_t BSP_GPIO_DisableIRQ(BSP_GPIO_t gpio); int8_t BSP_GPIO_EnableIRQ(uint16_t pin);
int8_t BSP_GPIO_DisableIRQ(uint16_t pin);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,72 +0,0 @@
/* Includes ----------------------------------------------------------------- */
#include "bsp\gpio.h"
#include <gpio.h>
#include <main.h>
/* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
/* Private variables -------------------------------------------------------- */
static void (*GPIO_Callback[BSP_GPIO_NUM][BSP_GPIO_CB_NUM])(void);
/* Private function -------------------------------------------------------- */
static BSP_GPIO_t GPIO_Get(uint16_t pin) {
switch (pin) {
case USER_KEY_Pin:
return BSP_GPIO_USER_KEY;
/* case XXX_Pin:
return BSP_GPIO_XXX; */
default:
return BSP_GPIO_ERR;
}
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
BSP_GPIO_t gpio = GPIO_Get(GPIO_Pin);
if (gpio != BSP_GPIO_ERR) {
if (GPIO_Callback[gpio][BSP_GPIO_EXTI_CB]) {
GPIO_Callback[gpio][BSP_GPIO_EXTI_CB]();
}
}
}
/* Exported functions ------------------------------------------------------- */
int8_t BSP_GPIO_RegisterCallback(BSP_GPIO_t gpio, BSP_GPIO_Callback_t type, void (*callback)(void)) {
if (callback == NULL || gpio >= BSP_GPIO_NUM || type >= BSP_GPIO_CB_NUM) return BSP_ERR_NULL;
GPIO_Callback[gpio][type] = callback;
return BSP_OK;
}
int8_t BSP_GPIO_EnableIRQ(BSP_GPIO_t gpio) {
switch (gpio) {
case BSP_GPIO_USER_KEY:
HAL_NVIC_EnableIRQ(USER_KEY_EXTI_IRQn);
break;
/* case BSP_GPIO_XXX:
HAL_NVIC_EnableIRQ(XXX_IRQn);
break; */
default:
return BSP_ERR;
}
return BSP_OK;
}
int8_t BSP_GPIO_DisableIRQ(BSP_GPIO_t gpio) {
switch (gpio) {
case BSP_GPIO_USER_KEY:
HAL_NVIC_DisableIRQ(USER_KEY_EXTI_IRQn);
break;
/* case BSP_GPIO_XXX:
HAL_NVIC_DisableIRQ(XXX_IRQn);
break; */
default:
return BSP_ERR;
}
return BSP_OK;
}

View File

@ -9,10 +9,7 @@ static void (*I2C_Callback[BSP_I2C_NUM][BSP_I2C_CB_NUM])(void);
/* Private function -------------------------------------------------------- */ /* Private function -------------------------------------------------------- */
static BSP_I2C_t I2C_Get(I2C_HandleTypeDef *hi2c) { static BSP_I2C_t I2C_Get(I2C_HandleTypeDef *hi2c) {
if (hi2c->Instance == I2C1) /* AUTO GENERATED I2C_GET */
return BSP_I2C_EXAMPLE;
// else if (hi2c->Instance == I2CX)
// return BSP_I2C_XXX;
else else
return BSP_I2C_ERR; return BSP_I2C_ERR;
} }
@ -92,10 +89,7 @@ void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c) {
/* Exported functions ------------------------------------------------------- */ /* Exported functions ------------------------------------------------------- */
I2C_HandleTypeDef *BSP_I2C_GetHandle(BSP_I2C_t i2c) { I2C_HandleTypeDef *BSP_I2C_GetHandle(BSP_I2C_t i2c) {
switch (i2c) { switch (i2c) {
case BSP_I2C_EXAMPLE: /* AUTO GENERATED BSP_I2C_GET_HANDLE */
return &hi2c1;
// case BSP_I2C_XXX:
// return &hi2cX;
default: default:
return NULL; return NULL;
} }

View File

@ -17,8 +17,10 @@ extern "C" {
/* I2C实体枚举与设备对应 */ /* I2C实体枚举与设备对应 */
typedef enum { typedef enum {
BSP_I2C_EXAMPLE, /* AUTO GENERATED BSP_I2C_NAME */
/* BSP_I2C_XXX,*/ /* USER BSP_I2C END*/
/* USER_I2C_XXX */
/* USER BSP_I2C END */
BSP_I2C_NUM, BSP_I2C_NUM,
BSP_I2C_ERR, BSP_I2C_ERR,
} BSP_I2C_t; } BSP_I2C_t;

View File

@ -1,50 +0,0 @@
/* Includes ----------------------------------------------------------------- */
#include "bsp/led_gpio.h"
#include "bsp/bsp.h"
#include <gpio.h>
/* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
/* Private variables -------------------------------------------------------- */
static uint32_t led_stats; // 使用位掩码记录每个通道的状态最多支持32LED
// 定义 LED 引脚和端口映射表:需要根据自己的修改,添加,或删减。
static const BSP_LED_Config_t LED_CONFIGS[] = {
{GPIOA, GPIO_PIN_2}, // BSP_LED_1
{GPIOA, GPIO_PIN_3}, // BSP_LED_2
{GPIOA, GPIO_PIN_4}, // BSP_LED_3
};
#define LED_CHANNEL_COUNT (sizeof(LED_CONFIGS) / sizeof(LED_CONFIGS[0])) // 通道数量
/* Private function --------------------------------------------------------- */
/* Exported functions ------------------------------------------------------- */
int8_t BSP_LED_Set(BSP_LED_Channel_t ch, BSP_LED_Status_t s)
{
if (ch < LED_CHANNEL_COUNT)
{
GPIO_TypeDef *port = LED_CONFIGS[ch].port;
uint16_t pin = LED_CONFIGS[ch].pin;
switch (s)
{
case BSP_LED_ON:
led_stats |= (1 << ch);
HAL_GPIO_WritePin(port, pin, GPIO_PIN_SET); // 点亮LED
break;
case BSP_LED_OFF:
led_stats &= ~(1 << ch);
HAL_GPIO_WritePin(port, pin, GPIO_PIN_RESET); // 熄灭LED
break;
case BSP_LED_TAGGLE:
led_stats ^= (1 << ch);
HAL_GPIO_TogglePin(port, pin); // 切换LED状态
break;
default:
return BSP_ERR;
}
return BSP_OK;
}
return BSP_ERR;
}

View File

@ -1,36 +0,0 @@
#pragma once
/* Includes ----------------------------------------------------------------- */
#include <stdint.h>
#include "gpio.h"
/* Exported constants ------------------------------------------------------- */
/* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */
/* LED灯状态设置用 */
typedef enum
{
BSP_LED_ON,
BSP_LED_OFF,
BSP_LED_TAGGLE,
} BSP_LED_Status_t;
/* LED通道 */
typedef enum
{
BSP_LED_1,
BSP_LED_2,
BSP_LED_3,
/*BSP_LED_XXX*/
} BSP_LED_Channel_t;
/* LED GPIO 配置 */
typedef struct
{
GPIO_TypeDef *port; // GPIO 端口 (如 GPIOA, GPIOB)
uint16_t pin; // GPIO 引脚
} BSP_LED_Config_t;
/* Exported functions prototypes -------------------------------------------- */
int8_t BSP_LED_Set(BSP_LED_Channel_t ch, BSP_LED_Status_t s);

14
assets/User_code/bsp/mm.c Normal file
View File

@ -0,0 +1,14 @@
/* Includes ----------------------------------------------------------------- */
#include "bsp\mm.h"
#include "FreeRTOS.h"
/* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
/* Private variables -------------------------------------------------------- */
/* Private function -------------------------------------------------------- */
/* Exported functions ------------------------------------------------------- */
inline void *BSP_Malloc(size_t size) { return pvPortMalloc(size); }
inline void BSP_Free(void *pv) { vPortFree(pv); }

View File

@ -1,20 +1,20 @@
#pragma once #pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */ /* Includes ----------------------------------------------------------------- */
#include <stddef.h>
#include <stdint.h> #include <stdint.h>
/* Exported constants ------------------------------------------------------- */ /* Exported constants ------------------------------------------------------- */
/* Exported macro ----------------------------------------------------------- */ /* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */ /* Exported types ----------------------------------------------------------- */
/* 设置BUZZER状态 */
typedef enum
{
BSP_BUZZER_ON,
BSP_BUZZER_OFF,
BSP_BUZZER_TAGGLE,
} BSP_Buzzer_Status_t;
/* Exported functions prototypes -------------------------------------------- */ /* Exported functions prototypes -------------------------------------------- */
void *BSP_Malloc(size_t size);
void BSP_Free(void *pv);
int8_t BSP_Buzzer_Set(BSP_Buzzer_Status_t s); #ifdef __cplusplus
}
#endif

View File

@ -9,12 +9,7 @@ static void (*SPI_Callback[BSP_SPI_NUM][BSP_SPI_CB_NUM])(void);
/* Private function -------------------------------------------------------- */ /* Private function -------------------------------------------------------- */
static BSP_SPI_t SPI_Get(SPI_HandleTypeDef *hspi) { static BSP_SPI_t SPI_Get(SPI_HandleTypeDef *hspi) {
if (hspi->Instance == SPI1) /* AUTO GENERATED SPI_GET */
return BSP_SPI_EXAMPLE;
/*
else if (hspi->Instance == SPIX)
return BSP_SPI_XXX;
*/
else else
return BSP_SPI_ERR; return BSP_SPI_ERR;
} }
@ -87,12 +82,7 @@ void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi) {
/* Exported functions ------------------------------------------------------- */ /* Exported functions ------------------------------------------------------- */
SPI_HandleTypeDef *BSP_SPI_GetHandle(BSP_SPI_t spi) { SPI_HandleTypeDef *BSP_SPI_GetHandle(BSP_SPI_t spi) {
switch (spi) { switch (spi) {
case BSP_SPI_EXAMPLE: /* AUTO GENERATED BSP_SPI_GET_HANDLE */
return &hspi1;
/*
case BSP_SPI_XXX:
return &hspiX;
*/
default: default:
return NULL; return NULL;
} }

View File

@ -17,8 +17,7 @@ extern "C" {
/* SPI实体枚举与设备对应 */ /* SPI实体枚举与设备对应 */
typedef enum { typedef enum {
BSP_SPI_EXAMPLE, /* AUTO GENERATED BSP_SPI_NAME */
/* BSP_SPI_XXX,*/
BSP_SPI_NUM, BSP_SPI_NUM,
BSP_SPI_ERR, BSP_SPI_ERR,
} BSP_SPI_t; } BSP_SPI_t;

View File

@ -9,10 +9,7 @@ static void (*UART_Callback[BSP_UART_NUM][BSP_UART_CB_NUM])(void);
/* Private function -------------------------------------------------------- */ /* Private function -------------------------------------------------------- */
static BSP_UART_t UART_Get(UART_HandleTypeDef *huart) { static BSP_UART_t UART_Get(UART_HandleTypeDef *huart) {
if (huart->Instance == USART1) /* AUTO GENERATED UART_GET */
return BSP_UART_EXAMPLE;
// else if (huart->Instance == USARTX)
// return BSP_UART_XXX;
else else
return BSP_UART_ERR; return BSP_UART_ERR;
} }
@ -101,10 +98,7 @@ void BSP_UART_IRQHandler(UART_HandleTypeDef *huart) {
UART_HandleTypeDef *BSP_UART_GetHandle(BSP_UART_t uart) { UART_HandleTypeDef *BSP_UART_GetHandle(BSP_UART_t uart) {
switch (uart) { switch (uart) {
case BSP_UART_EXAMPLE: /* AUTO GENERATED BSP_UART_GET_HANDLE */
return &huart1;
// case BSP_UART_XXX:
// return &huartX;
default: default:
return NULL; return NULL;
} }

View File

@ -17,8 +17,7 @@ extern "C" {
/* UART实体枚举与设备对应 */ /* UART实体枚举与设备对应 */
typedef enum { typedef enum {
BSP_UART_EXAMPLE, /* AUTO GENERATED BSP_UART_NAME */
/*BSP_UART_XXX*/
BSP_UART_NUM, BSP_UART_NUM,
BSP_UART_ERR, BSP_UART_ERR,
} BSP_UART_t; } BSP_UART_t;

View File

@ -0,0 +1,4 @@
bsp,can,delay,dwt,,gpio,i2c,mm,spi,uart,
component,peripheral,driver,library,hal,freertos,stm32cube
device,dr16,ai,nuc
module,chassis,gimbal,arm,shoot
1 bsp,can,delay,dwt,,gpio,i2c,mm,spi,uart,
2 component,peripheral,driver,library,hal,freertos,stm32cube
3 device,dr16,ai,nuc
4 module,chassis,gimbal,arm,shoot