mirror of
https://github.com/goldenfishs/MRobot.git
synced 2026-03-31 21:07:14 +08:00
can支持自定义id解析了
This commit is contained in:
Binary file not shown.
Binary file not shown.
BIN
app/__pycache__/code_configuration_interface.cpython-39.pyc
Normal file
BIN
app/__pycache__/code_configuration_interface.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/__pycache__/code_generate_interface.cpython-39.pyc
Normal file
BIN
app/__pycache__/code_generate_interface.cpython-39.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -155,30 +155,49 @@ class CodeGenerateInterface(QWidget):
|
||||
|
||||
|
||||
def generate_code(self):
|
||||
"""生成代码逻辑"""
|
||||
# 收集所有已加载的页面对象
|
||||
pages = []
|
||||
for i in range(self.stack.count()):
|
||||
widget = self.stack.widget(i)
|
||||
pages.append(widget)
|
||||
|
||||
# 生成 BSP 代码
|
||||
bsp_result = bsp.generate_bsp(self.project_path, pages)
|
||||
|
||||
# 生成 Component 代码
|
||||
from app.code_page.component_interface import component
|
||||
component_result = component.generate_component(self.project_path, pages)
|
||||
|
||||
# 合并结果信息
|
||||
combined_result = f"BSP代码生成:\n{bsp_result}\n\nComponent代码生成:\n{component_result}"
|
||||
|
||||
# 用 InfoBar 在主界面弹出
|
||||
InfoBar.success(
|
||||
title="代码生成结果",
|
||||
content=combined_result,
|
||||
parent=self,
|
||||
duration=5000 # 增加显示时间,因为内容更多
|
||||
)
|
||||
"""生成代码逻辑 - 修复导入问题"""
|
||||
try:
|
||||
# 收集所有已加载的页面对象
|
||||
pages = []
|
||||
for i in range(self.stack.count()):
|
||||
widget = self.stack.widget(i)
|
||||
pages.append(widget)
|
||||
|
||||
# 确保导入成功
|
||||
from app.code_page.bsp_interface import bsp
|
||||
from app.code_page.component_interface import component
|
||||
|
||||
# 生成 BSP 代码
|
||||
bsp_result = bsp.generate_bsp(self.project_path, pages)
|
||||
|
||||
# 生成 Component 代码
|
||||
component_result = component.generate_component(self.project_path, pages)
|
||||
|
||||
# 合并结果信息
|
||||
combined_result = f"BSP代码生成:\n{bsp_result}\n\nComponent代码生成:\n{component_result}"
|
||||
|
||||
# 用 InfoBar 在主界面弹出
|
||||
InfoBar.success(
|
||||
title="代码生成结果",
|
||||
content=combined_result,
|
||||
parent=self,
|
||||
duration=5000
|
||||
)
|
||||
|
||||
except ImportError as e:
|
||||
InfoBar.error(
|
||||
title="导入错误",
|
||||
content=f"模块导入失败: {str(e)}",
|
||||
parent=self,
|
||||
duration=3000
|
||||
)
|
||||
except Exception as e:
|
||||
InfoBar.error(
|
||||
title="生成失败",
|
||||
content=f"代码生成过程中出现错误: {str(e)}",
|
||||
parent=self,
|
||||
duration=3000
|
||||
)
|
||||
|
||||
def _get_freertos_status(self):
|
||||
"""获取FreeRTOS状态"""
|
||||
@@ -220,7 +239,6 @@ class CodeGenerateInterface(QWidget):
|
||||
if widget:
|
||||
self.stack.setCurrentWidget(widget)
|
||||
|
||||
# ...existing code...
|
||||
def _get_or_create_page(self, class_name):
|
||||
"""获取或创建页面"""
|
||||
if class_name in self.page_cache:
|
||||
@@ -235,12 +253,12 @@ class CodeGenerateInterface(QWidget):
|
||||
if class_name.startswith('bsp_'):
|
||||
# BSP页面
|
||||
from app.code_page.bsp_interface import get_bsp_page
|
||||
# 提取外设名,如 bsp_delay -> delay
|
||||
periph_name = class_name[len('bsp_'):].replace("_", " ")
|
||||
# 提取外设名,如 bsp_error_detect -> error_detect
|
||||
periph_name = class_name[len('bsp_'):] # 移除 .replace("_", " ")
|
||||
page = get_bsp_page(periph_name, self.project_path)
|
||||
elif class_name.startswith('component_'):
|
||||
from app.code_page.component_interface import get_component_page
|
||||
comp_name = class_name[len('component_'):].replace("_", " ")
|
||||
comp_name = class_name[len('component_'):] # 移除 .replace("_", " ")
|
||||
page = get_component_page(comp_name, self.project_path, self.component_manager)
|
||||
self.component_manager.register_component(page.component_name, page)
|
||||
else:
|
||||
@@ -253,5 +271,4 @@ class CodeGenerateInterface(QWidget):
|
||||
except Exception as e:
|
||||
print(f"创建页面 {class_name} 失败: {e}")
|
||||
return None
|
||||
|
||||
# ...existing code...
|
||||
|
||||
|
||||
BIN
app/code_page/__pycache__/bsp_interface.cpython-39.pyc
Normal file
BIN
app/code_page/__pycache__/bsp_interface.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/code_page/__pycache__/component_interface.cpython-39.pyc
Normal file
BIN
app/code_page/__pycache__/component_interface.cpython-39.pyc
Normal file
Binary file not shown.
@@ -399,20 +399,21 @@ class bsp_can(BspPeripheralBase):
|
||||
get_available_can
|
||||
)
|
||||
|
||||
|
||||
def _generate_source_file(self, configs, template_dir):
|
||||
template_path = os.path.join(template_dir, self.template_names['source'])
|
||||
template_content = CodeGenerator.load_template(template_path)
|
||||
if not template_content:
|
||||
return False
|
||||
|
||||
# Get函数
|
||||
# CAN_Get函数
|
||||
get_lines = []
|
||||
for idx, (name, instance) in enumerate(configs):
|
||||
if idx == 0:
|
||||
get_lines.append(f" if (hcan->Instance == {instance})")
|
||||
get_lines.append(f" if (hcan->Instance == {instance})")
|
||||
else:
|
||||
get_lines.append(f" else if (hcan->Instance == {instance})")
|
||||
get_lines.append(f" return {self.enum_prefix}_{name};")
|
||||
get_lines.append(f" else if (hcan->Instance == {instance})")
|
||||
get_lines.append(f" return {self.enum_prefix}_{name};")
|
||||
content = CodeGenerator.replace_auto_generated(
|
||||
template_content, "AUTO GENERATED CAN_GET", "\n".join(get_lines)
|
||||
)
|
||||
@@ -420,41 +421,106 @@ class bsp_can(BspPeripheralBase):
|
||||
# Handle函数
|
||||
handle_lines = []
|
||||
for name, instance in configs:
|
||||
num = ''.join(filter(str.isdigit, instance)) # 提取数字
|
||||
handle_lines.append(f" case {self.enum_prefix}_{name}:")
|
||||
handle_lines.append(f" return &h{instance.lower()};")
|
||||
handle_lines.append(f" return &hcan{num};")
|
||||
content = CodeGenerator.replace_auto_generated(
|
||||
content, f"AUTO GENERATED {self.enum_prefix}_GET_HANDLE", "\n".join(handle_lines)
|
||||
)
|
||||
|
||||
# 生成CAN初始化代码
|
||||
init_lines = []
|
||||
for idx, (name, instance) in enumerate(configs):
|
||||
can_num = instance[-1] # CAN1 -> 1, CAN2 -> 2
|
||||
|
||||
init_lines.append(f" // 初始化 {instance}")
|
||||
init_lines.append(f" CAN_FilterTypeDef can{can_num}_filter = {{0}};")
|
||||
init_lines.append(f" can{can_num}_filter.FilterBank = {0 if can_num == '1' else 14};")
|
||||
init_lines.append(f" can{can_num}_filter.FilterIdHigh = 0;")
|
||||
init_lines.append(f" can{can_num}_filter.FilterIdLow = 0;")
|
||||
init_lines.append(f" can{can_num}_filter.FilterMode = CAN_FILTERMODE_IDMASK;")
|
||||
init_lines.append(f" can{can_num}_filter.FilterScale = CAN_FILTERSCALE_32BIT;")
|
||||
init_lines.append(f" can{can_num}_filter.FilterMaskIdHigh = 0;")
|
||||
init_lines.append(f" can{can_num}_filter.FilterMaskIdLow = 0;")
|
||||
init_lines.append(f" can{can_num}_filter.FilterActivation = ENABLE;")
|
||||
if can_num == '1':
|
||||
init_lines.append(f" can{can_num}_filter.SlaveStartFilterBank = 14;")
|
||||
init_lines.append(f" can{can_num}_filter.FilterFIFOAssignment = CAN_RX_FIFO0;")
|
||||
else:
|
||||
init_lines.append(f" can{can_num}_filter.FilterFIFOAssignment = CAN_RX_FIFO1;")
|
||||
|
||||
init_lines.append(f" HAL_CAN_ConfigFilter(BSP_CAN_GetHandle({self.enum_prefix}_{name}), &can{can_num}_filter);")
|
||||
init_lines.append(f" HAL_CAN_Start(BSP_CAN_GetHandle({self.enum_prefix}_{name}));")
|
||||
|
||||
# 注册回调和激活中断
|
||||
fifo = "FIFO0" if can_num == '1' else "FIFO1"
|
||||
init_lines.append(f" HAL_CAN_ActivateNotification(BSP_CAN_GetHandle({self.enum_prefix}_{name}), CAN_IT_RX_{fifo}_MSG_PENDING);")
|
||||
init_lines.append("")
|
||||
|
||||
# 先设置初始化标志
|
||||
init_lines.append(" // 先设置初始化标志,以便后续回调注册能通过检查")
|
||||
init_lines.append(" inited = true;")
|
||||
init_lines.append("")
|
||||
|
||||
# 检查是否同时有CAN1和CAN2
|
||||
has_can1 = any(instance == 'CAN1' for _, instance in configs)
|
||||
has_can2 = any(instance == 'CAN2' for _, instance in configs)
|
||||
|
||||
if has_can1 and has_can2:
|
||||
# 同时配置CAN1和CAN2的情况 - 统一使用FIFO0
|
||||
init_lines.extend([
|
||||
" // 初始化 CAN1 - 使用 FIFO0",
|
||||
" CAN_FilterTypeDef can1_filter = {0};",
|
||||
" can1_filter.FilterBank = 0;",
|
||||
" can1_filter.FilterIdHigh = 0;",
|
||||
" can1_filter.FilterIdLow = 0;",
|
||||
" can1_filter.FilterMode = CAN_FILTERMODE_IDMASK;",
|
||||
" can1_filter.FilterScale = CAN_FILTERSCALE_32BIT;",
|
||||
" can1_filter.FilterMaskIdHigh = 0;",
|
||||
" can1_filter.FilterMaskIdLow = 0;",
|
||||
" can1_filter.FilterActivation = ENABLE;",
|
||||
" can1_filter.SlaveStartFilterBank = 14; // 重要:设置从过滤器起始组",
|
||||
" can1_filter.FilterFIFOAssignment = CAN_RX_FIFO0;",
|
||||
" HAL_CAN_ConfigFilter(&hcan1, &can1_filter);",
|
||||
" HAL_CAN_Start(&hcan1);",
|
||||
" HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);",
|
||||
"",
|
||||
" // 初始化 CAN2 - 使用 FIFO0(注意:通过 CAN1 配置 CAN2 的过滤器)",
|
||||
" CAN_FilterTypeDef can2_filter = {0};",
|
||||
" can2_filter.FilterBank = 14; // CAN2 使用过滤器组 14",
|
||||
" can2_filter.FilterIdHigh = 0;",
|
||||
" can2_filter.FilterIdLow = 0;",
|
||||
" can2_filter.FilterMode = CAN_FILTERMODE_IDMASK;",
|
||||
" can2_filter.FilterScale = CAN_FILTERSCALE_32BIT;",
|
||||
" can2_filter.FilterMaskIdHigh = 0;",
|
||||
" can2_filter.FilterMaskIdLow = 0;",
|
||||
" can2_filter.FilterActivation = ENABLE;",
|
||||
" can2_filter.FilterFIFOAssignment = CAN_RX_FIFO0; // 改为 FIFO0",
|
||||
" HAL_CAN_ConfigFilter(&hcan1, &can2_filter); // 通过 CAN1 配置",
|
||||
" HAL_CAN_Start(&hcan2);",
|
||||
" HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_MSG_PENDING); // 激活 FIFO0 中断",
|
||||
"",
|
||||
" // 注册回调函数",
|
||||
f" BSP_CAN_RegisterCallback({self.enum_prefix}_CAN1, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifoCallback);",
|
||||
f" BSP_CAN_RegisterCallback({self.enum_prefix}_CAN2, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifoCallback);",
|
||||
])
|
||||
else:
|
||||
# 只有单个CAN的情况
|
||||
for idx, (name, instance) in enumerate(configs):
|
||||
can_num = instance[-1] # CAN1 -> 1, CAN2 -> 2
|
||||
|
||||
init_lines.append(f" // 初始化 {instance}")
|
||||
init_lines.append(f" CAN_FilterTypeDef can{can_num}_filter = {{0}};")
|
||||
|
||||
if instance == 'CAN1':
|
||||
init_lines.extend([
|
||||
f" can{can_num}_filter.FilterBank = 0;",
|
||||
f" can{can_num}_filter.SlaveStartFilterBank = 14;",
|
||||
f" can{can_num}_filter.FilterFIFOAssignment = CAN_RX_FIFO0;",
|
||||
])
|
||||
else: # CAN2
|
||||
init_lines.extend([
|
||||
f" can{can_num}_filter.FilterBank = 14;",
|
||||
f" can{can_num}_filter.FilterFIFOAssignment = CAN_RX_FIFO0;",
|
||||
])
|
||||
|
||||
init_lines.extend([
|
||||
f" can{can_num}_filter.FilterIdHigh = 0;",
|
||||
f" can{can_num}_filter.FilterIdLow = 0;",
|
||||
f" can{can_num}_filter.FilterMode = CAN_FILTERMODE_IDMASK;",
|
||||
f" can{can_num}_filter.FilterScale = CAN_FILTERSCALE_32BIT;",
|
||||
f" can{can_num}_filter.FilterMaskIdHigh = 0;",
|
||||
f" can{can_num}_filter.FilterMaskIdLow = 0;",
|
||||
f" can{can_num}_filter.FilterActivation = ENABLE;",
|
||||
])
|
||||
|
||||
if instance == 'CAN2':
|
||||
init_lines.append(f" HAL_CAN_ConfigFilter(&hcan1, &can{can_num}_filter); // 通过 CAN1 配置")
|
||||
else:
|
||||
init_lines.append(f" HAL_CAN_ConfigFilter(&hcan{can_num}, &can{can_num}_filter);")
|
||||
|
||||
init_lines.extend([
|
||||
f" HAL_CAN_Start(&hcan{can_num});",
|
||||
f" HAL_CAN_ActivateNotification(&hcan{can_num}, CAN_IT_RX_FIFO0_MSG_PENDING);",
|
||||
"",
|
||||
f" // 注册回调函数",
|
||||
f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifoCallback);",
|
||||
""
|
||||
])
|
||||
|
||||
content = CodeGenerator.replace_auto_generated(
|
||||
content, "AUTO GENERATED CAN_INIT", "\n".join(init_lines)
|
||||
)
|
||||
@@ -463,6 +529,8 @@ class bsp_can(BspPeripheralBase):
|
||||
save_with_preserve(output_path, content)
|
||||
return True
|
||||
|
||||
|
||||
|
||||
class bsp_spi(BspPeripheralBase):
|
||||
def __init__(self, project_path):
|
||||
super().__init__(
|
||||
@@ -654,16 +722,17 @@ class bsp_gpio(QWidget):
|
||||
template_content, "AUTO GENERATED BSP_GPIO_MAP", "\n".join(map_lines)
|
||||
)
|
||||
|
||||
# 生成EXTI使能代码
|
||||
# 生成EXTI使能代码 - 使用用户自定义的BSP枚举名称
|
||||
enable_lines = []
|
||||
disable_lines = []
|
||||
for config in configs:
|
||||
if config['has_exti']:
|
||||
ioc_label = config['ioc_label']
|
||||
enable_lines.append(f" case {ioc_label}_Pin:")
|
||||
custom_name = config['custom_name']
|
||||
enable_lines.append(f" case BSP_GPIO_{custom_name}:")
|
||||
enable_lines.append(f" HAL_NVIC_EnableIRQ({ioc_label}_EXTI_IRQn);")
|
||||
enable_lines.append(f" break;")
|
||||
disable_lines.append(f" case {ioc_label}_Pin:")
|
||||
disable_lines.append(f" case BSP_GPIO_{custom_name}:")
|
||||
disable_lines.append(f" HAL_NVIC_DisableIRQ({ioc_label}_EXTI_IRQn);")
|
||||
disable_lines.append(f" break;")
|
||||
|
||||
@@ -678,6 +747,8 @@ class bsp_gpio(QWidget):
|
||||
save_with_preserve(output_path, content)
|
||||
return True
|
||||
|
||||
|
||||
|
||||
def _save_config(self, configs):
|
||||
config_path = os.path.join(self.project_path, "User/bsp/bsp_config.yaml")
|
||||
config_data = CodeGenerator.load_config(config_path)
|
||||
|
||||
BIN
app/tools/__pycache__/analyzing_ioc.cpython-39.pyc
Normal file
BIN
app/tools/__pycache__/analyzing_ioc.cpython-39.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
app/tools/__pycache__/code_generator.cpython-39.pyc
Normal file
BIN
app/tools/__pycache__/code_generator.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/tools/__pycache__/code_task_config.cpython-39.pyc
Normal file
BIN
app/tools/__pycache__/code_task_config.cpython-39.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
app/tools/__pycache__/update_code.cpython-39.pyc
Normal file
BIN
app/tools/__pycache__/update_code.cpython-39.pyc
Normal file
Binary file not shown.
@@ -2,7 +2,8 @@ import os
|
||||
import yaml
|
||||
import shutil
|
||||
from typing import Dict, List, Tuple
|
||||
|
||||
import sys
|
||||
import os
|
||||
class CodeGenerator:
|
||||
"""通用代码生成器"""
|
||||
|
||||
@@ -61,15 +62,20 @@ class CodeGenerator:
|
||||
|
||||
@staticmethod
|
||||
def get_template_dir():
|
||||
"""获取模板文件目录"""
|
||||
# 从当前文件向上找到 MRobot 目录,然后定位到模板目录
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
# 向上找到 MRobot 根目录
|
||||
while os.path.basename(current_dir) != 'MRobot' and current_dir != '/':
|
||||
current_dir = os.path.dirname(current_dir)
|
||||
|
||||
if os.path.basename(current_dir) == 'MRobot':
|
||||
return os.path.join(current_dir, "assets/User_code/bsp")
|
||||
"""获取模板目录路径,兼容打包环境"""
|
||||
if getattr(sys, 'frozen', False):
|
||||
# 打包后的环境
|
||||
base_path = sys._MEIPASS
|
||||
template_dir = os.path.join(base_path, "assets", "User_code", "bsp")
|
||||
else:
|
||||
# 如果找不到,使用相对路径作为备选
|
||||
return os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "assets/User_code/bsp")
|
||||
# 开发环境
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
while os.path.basename(current_dir) != 'MRobot' and current_dir != '/':
|
||||
current_dir = os.path.dirname(current_dir)
|
||||
template_dir = os.path.join(current_dir, "assets", "User_code", "bsp")
|
||||
|
||||
print(f"模板目录路径: {template_dir}")
|
||||
if not os.path.exists(template_dir):
|
||||
print(f"警告:模板目录不存在: {template_dir}")
|
||||
|
||||
return template_dir
|
||||
Reference in New Issue
Block a user