Compare commits

..

No commits in common. "843936525ffaaba73d9efb2435c55ccdea853724" and "4a3e0d8391f0720ed5f129dcad3d96ac090acf69" have entirely different histories.

29 changed files with 59 additions and 4244 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -2,11 +2,8 @@ from PyQt5.QtWidgets import QWidget, QVBoxLayout, QStackedWidget, QSizePolicy
from PyQt5.QtCore import Qt
from qfluentwidgets import PushSettingCard, FluentIcon, TabBar
from qfluentwidgets import TitleLabel, BodyLabel, PushButton, FluentIcon
from PyQt5.QtWidgets import QFileDialog, QDialog, QHBoxLayout
from qfluentwidgets import ComboBox, PrimaryPushButton, SubtitleLabel
from PyQt5.QtWidgets import QFileDialog
import os
import shutil
import tempfile
from .function_fit_interface import FunctionFitInterface
from .ai_interface import AIInterface
from qfluentwidgets import InfoBar
@ -59,10 +56,6 @@ class CodeConfigurationInterface(QWidget):
self.update_template_btn.setFixedWidth(200)
mainLayout.addWidget(self.update_template_btn, alignment=Qt.AlignmentFlag.AlignCenter)
self.preset_ioc_btn = PushButton(FluentIcon.LIBRARY, "获取预设IOC")
self.preset_ioc_btn.setFixedWidth(200)
mainLayout.addWidget(self.preset_ioc_btn, alignment=Qt.AlignmentFlag.AlignCenter)
mainLayout.addSpacing(10)
mainLayout.addStretch()
@ -76,7 +69,6 @@ class CodeConfigurationInterface(QWidget):
self.tabBar.tabCloseRequested.connect(self.onCloseTab)
self.choose_btn.clicked.connect(self.choose_project_folder) # 启用选择项目路径按钮
self.update_template_btn.clicked.connect(self.on_update_template)
self.preset_ioc_btn.clicked.connect(self.use_preset_ioc) # 启用预设工程按钮
def on_update_template(self):
@ -96,170 +88,6 @@ class CodeConfigurationInterface(QWidget):
)
update_code(parent=self, info_callback=info, error_callback=error)
def get_preset_ioc_files(self):
"""获取预设的ioc文件列表"""
try:
preset_ioc_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "assets", "User_code", "ioc")
if not os.path.exists(preset_ioc_dir):
return []
ioc_files = []
for filename in os.listdir(preset_ioc_dir):
if filename.endswith('.ioc'):
ioc_files.append({
'name': os.path.splitext(filename)[0],
'filename': filename,
'path': os.path.join(preset_ioc_dir, filename)
})
return ioc_files
except Exception as e:
print(f"获取预设ioc文件失败: {e}")
return []
def use_preset_ioc(self):
"""使用预设ioc文件"""
preset_files = self.get_preset_ioc_files()
if not preset_files:
InfoBar.warning(
title="无预设工程",
content="未找到可用的预设工程文件",
parent=self,
duration=2000
)
return
# 创建选择对话框
dialog = QDialog(self)
dialog.setWindowTitle("获取预设IOC")
dialog.resize(400, 200)
dialog.setModal(True)
layout = QVBoxLayout(dialog)
layout.setContentsMargins(24, 24, 24, 24)
layout.setSpacing(16)
# 标题
title_label = SubtitleLabel("选择要使用的IOC模版")
layout.addWidget(title_label)
# 选择下拉框
select_layout = QHBoxLayout()
select_label = BodyLabel("预设IOC")
preset_combo = ComboBox()
# 修复ComboBox数据问题
for i, preset in enumerate(preset_files):
preset_combo.addItem(preset['name'])
select_layout.addWidget(select_label)
select_layout.addWidget(preset_combo)
layout.addLayout(select_layout)
layout.addSpacing(16)
# 按钮区域
btn_layout = QHBoxLayout()
btn_layout.addStretch()
cancel_btn = PushButton("取消")
ok_btn = PrimaryPushButton("保存到")
cancel_btn.clicked.connect(dialog.reject)
ok_btn.clicked.connect(dialog.accept)
btn_layout.addWidget(cancel_btn)
btn_layout.addWidget(ok_btn)
layout.addLayout(btn_layout)
# 显示对话框
if dialog.exec() == QDialog.Accepted:
selected_index = preset_combo.currentIndex()
if selected_index >= 0 and selected_index < len(preset_files):
selected_preset = preset_files[selected_index]
self.save_preset_template(selected_preset)
def save_preset_template(self, preset_info):
"""保存预设模板到用户指定位置"""
try:
# 让用户选择保存位置
save_dir = QFileDialog.getExistingDirectory(
self,
f"选择保存 {preset_info['name']} 模板的位置",
os.path.expanduser("~")
)
if not save_dir:
return
# 复制ioc文件到用户选择的目录
target_path = os.path.join(save_dir, preset_info['filename'])
# 检查目标文件是否已存在
if os.path.exists(target_path):
from qfluentwidgets import Dialog
dialog = Dialog("文件已存在", f"目标位置已存在 {preset_info['filename']},是否覆盖?", self)
if dialog.exec() != Dialog.Accepted:
return
# 复制文件
shutil.copy2(preset_info['path'], target_path)
InfoBar.success(
title="模板保存成功",
content=f"预设模板 {preset_info['name']} 已保存到:\n{target_path}",
parent=self,
duration=3000
)
except Exception as e:
InfoBar.error(
title="保存失败",
content=f"保存预设模板失败: {str(e)}",
parent=self,
duration=3000
)
def open_project_from_path(self, folder_path):
"""从指定路径打开工程"""
try:
if not os.path.exists(folder_path):
return
ioc_files = [f for f in os.listdir(folder_path) if f.endswith('.ioc')]
if ioc_files:
# 检查是否已存在 codeGenPage 标签页
for i in range(self.stackedWidget.count()):
widget = self.stackedWidget.widget(i)
if widget is not None and widget.objectName() == "codeGenPage":
# 如果已存在,则切换到该标签页,并更新路径显示
if hasattr(widget, "project_path"):
widget.project_path = folder_path
if hasattr(widget, "refresh"):
widget.refresh()
self.stackedWidget.setCurrentWidget(widget)
self.tabBar.setCurrentTab("codeGenPage")
return
# 不存在则新建
code_gen_page = CodeGenerateInterface(folder_path, self)
self.addSubInterface(code_gen_page, "codeGenPage", "代码生成")
self.stackedWidget.setCurrentWidget(code_gen_page)
self.tabBar.setCurrentTab("codeGenPage")
else:
InfoBar.error(
title="未找到.ioc文件",
content="所选文件夹不是有效的CUBEMX工程目录",
parent=self,
duration=3000
)
except Exception as e:
InfoBar.error(
title="打开工程失败",
content=f"打开工程失败: {str(e)}",
parent=self,
duration=3000
)
def choose_project_folder(self):
folder = QFileDialog.getExistingDirectory(self, "选择CUBEMX工程目录")
if not folder:

View File

@ -917,48 +917,10 @@ class bsp_spi(BspPeripheralBase):
def patch_uart_interrupts(project_path, uart_instances):
"""自动修改中断文件,插入 UART BSP 相关代码(支持 F1/F4/H7 等系列)"""
# 检测MCU型号确定正确的中断文件
ioc_files = [f for f in os.listdir(project_path) if f.endswith('.ioc')]
if not ioc_files:
return
ioc_path = os.path.join(project_path, ioc_files[0])
mcu_name = analyzing_ioc.get_mcu_name_from_ioc(ioc_path)
if not mcu_name:
return
# 根据MCU型号确定中断文件名
mcu_upper = mcu_name.upper()
if 'STM32F1' in mcu_upper:
it_file = "stm32f1xx_it.c"
elif 'STM32F4' in mcu_upper:
it_file = "stm32f4xx_it.c"
elif 'STM32H7' in mcu_upper:
it_file = "stm32h7xx_it.c"
elif 'STM32F7' in mcu_upper:
it_file = "stm32f7xx_it.c"
elif 'STM32G4' in mcu_upper:
it_file = "stm32g4xx_it.c"
elif 'STM32L4' in mcu_upper:
it_file = "stm32l4xx_it.c"
else:
# 通用处理尝试从MCU名称提取系列信息
# 格式通常为 STM32X0XXX提取 X0 部分
import re as regex
match = regex.match(r'STM32([A-Z]\d)', mcu_upper)
if match:
series = match.group(1).lower()
it_file = f"stm32{series}xx_it.c"
else:
# 默认尝试 F4
it_file = "stm32f4xx_it.c"
it_path = os.path.join(project_path, f"Core/Src/{it_file}")
"""自动修改 stm32f4xx_it.c插入 UART BSP 相关代码"""
it_path = os.path.join(project_path, "Core/Src/stm32f4xx_it.c")
if not os.path.exists(it_path):
return
with open(it_path, "r", encoding="utf-8") as f:
code = f.read()

View File

@ -637,31 +637,6 @@ class DataInterface(QWidget):
for t in task_list:
desc = t.get("description", "")
desc_wrapped = "\n ".join(textwrap.wrap(desc, 20))
# 检查是否是预设任务
if t.get("preset_task"):
# 使用预设任务的代码
preset_task_name = t["preset_task"]
from app.tools.code_generator import CodeGenerator
task_template_dir = CodeGenerator.get_assets_dir("User_code/task/template_task")
preset_task_file = os.path.join(task_template_dir, f"{preset_task_name}.c")
if os.path.exists(preset_task_file):
# 直接复制预设任务文件
task_c_path = os.path.join(output_dir, f"{t['name']}.c")
with open(preset_task_file, 'r', encoding='utf-8') as f:
preset_code = f.read()
# 如果任务名称不同,需要替换函数名
if preset_task_name != t["name"]:
# 替换任务函数名
preset_code = preset_code.replace(f"Task_{preset_task_name}", t["function"])
preset_code = preset_code.replace(f" {preset_task_name} Task", f" {t['name']} Task")
save_with_preserve(task_c_path, preset_code)
continue
# 使用默认模板生成任务代码
context_task = {
"task_name": t["name"],
"task_function": t["function"],

View File

@ -1,7 +1,7 @@
from PyQt5.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QWidget, QScrollArea
from qfluentwidgets import (
BodyLabel, TitleLabel, HorizontalSeparator, PushButton, PrimaryPushButton,
LineEdit, SpinBox, DoubleSpinBox, CheckBox, TextEdit, ComboBox
LineEdit, SpinBox, DoubleSpinBox, CheckBox, TextEdit
)
from qfluentwidgets import theme, Theme
import yaml
@ -76,20 +76,12 @@ class TaskConfigDialog(QDialog):
self.add_btn = PrimaryPushButton("创建新任务")
self.add_btn.setAutoDefault(False) # 禁止回车触发
self.add_btn.setDefault(False)
# 新增:预设任务按钮
self.preset_btn = PushButton("使用预设任务")
self.preset_btn.setAutoDefault(False)
self.preset_btn.setDefault(False)
self.del_btn = PushButton("删除当前任务")
self.del_btn.setAutoDefault(False) # 禁止回车触发
self.del_btn.setDefault(False)
self.add_btn.clicked.connect(self.add_task)
self.preset_btn.clicked.connect(self.add_preset_task)
self.del_btn.clicked.connect(self.delete_current_task)
btn_layout.addWidget(self.add_btn)
btn_layout.addWidget(self.preset_btn)
btn_layout.addWidget(self.del_btn)
btn_layout.addStretch() # 添加/删除靠左stretch在中间
@ -143,274 +135,6 @@ class TaskConfigDialog(QDialog):
self.task_btn_layout.addWidget(btn)
self.task_btn_layout.addStretch()
def get_preset_tasks(self):
"""获取所有可用的预设任务"""
from app.tools.code_generator import CodeGenerator
task_dir = CodeGenerator.get_assets_dir("User_code/task/template_task")
preset_tasks = []
if not os.path.exists(task_dir):
return preset_tasks
for filename in os.listdir(task_dir):
if filename.endswith('.c') and not filename.endswith('.template'):
task_name = os.path.splitext(filename)[0]
preset_tasks.append(task_name)
return preset_tasks
def load_preset_task_config(self, task_name):
"""从 yaml 配置文件中加载预设任务的配置"""
try:
from app.tools.code_generator import CodeGenerator
template_dir = CodeGenerator.get_assets_dir("User_code/task/template_task")
config_file = os.path.join(template_dir, "task.yaml")
if not os.path.exists(config_file):
return None
with open(config_file, 'r', encoding='utf-8') as f:
config_data = yaml.safe_load(f)
if config_data and task_name in config_data:
return config_data[task_name]
return None
except Exception as e:
print(f"加载预设任务配置失败: {e}")
return None
def load_preset_task_code(self, task_name):
"""加载预设任务的代码内容"""
from app.tools.code_generator import CodeGenerator
task_dir = CodeGenerator.get_assets_dir("User_code/task/template_task")
task_file = os.path.join(task_dir, f"{task_name}.c")
if os.path.exists(task_file):
with open(task_file, 'r', encoding='utf-8') as f:
return f.read()
return None
def add_preset_task(self):
"""添加预设任务"""
preset_tasks = self.get_preset_tasks()
if not preset_tasks:
InfoBar.warning(
title="无预设任务",
content="未找到可用的预设任务模板",
parent=self,
duration=2000
)
return
# 创建自适应主题的对话框
dialog = QDialog(self)
dialog.setWindowTitle("选择预设任务")
dialog.resize(600, 500)
dialog.setModal(True)
layout = QVBoxLayout(dialog)
layout.setContentsMargins(24, 24, 24, 24)
layout.setSpacing(18)
# 固定内容区域
fixed_content = QWidget()
fixed_content.setFixedHeight(180) # 减少固定高度
fixed_layout = QVBoxLayout(fixed_content)
fixed_layout.setContentsMargins(0, 0, 0, 0)
fixed_layout.setSpacing(18)
# 标题
title_label = TitleLabel("选择预设任务模板")
fixed_layout.addWidget(title_label)
# 说明文字
desc_label = BodyLabel("选择一个预设任务模板,系统将自动复制相应的代码和配置")
fixed_layout.addWidget(desc_label)
fixed_layout.addWidget(HorizontalSeparator())
# 任务选择
select_layout = QHBoxLayout()
select_layout.setSpacing(12)
select_label = BodyLabel("预设任务:")
preset_combo = ComboBox()
preset_combo.addItems(preset_tasks)
preset_combo.setCurrentIndex(0)
preset_combo.setMinimumWidth(160)
select_layout.addWidget(select_label)
select_layout.addWidget(preset_combo)
select_layout.addStretch()
fixed_layout.addLayout(select_layout)
# 参数信息 - 单行显示
params_layout = QHBoxLayout()
params_layout.setSpacing(24) # 适中的间距
self.info_freq = BodyLabel("")
self.info_delay = BodyLabel("")
self.info_stack = BodyLabel("")
self.info_ctrl = BodyLabel("")
self.info_freq.setMinimumWidth(120)
self.info_delay.setMinimumWidth(100)
self.info_stack.setMinimumWidth(120)
self.info_ctrl.setMinimumWidth(100)
params_layout.addWidget(self.info_freq)
params_layout.addWidget(self.info_delay)
params_layout.addWidget(self.info_stack)
params_layout.addWidget(self.info_ctrl)
params_layout.addStretch()
fixed_layout.addLayout(params_layout)
fixed_layout.addStretch() # 在固定区域内保持紧凑
layout.addWidget(fixed_content)
# 弹性描述区域
desc_layout = QVBoxLayout()
desc_layout.setSpacing(8)
desc_title = BodyLabel("描述:")
desc_title.setStyleSheet("font-weight: bold;")
desc_layout.addWidget(desc_title)
self.preview_desc = TextEdit()
self.preview_desc.setReadOnly(True)
self.preview_desc.setMinimumHeight(60) # 最小高度
desc_layout.addWidget(self.preview_desc)
layout.addLayout(desc_layout, stretch=1) # 弹性伸缩
# 按钮区域
layout.addWidget(HorizontalSeparator())
btn_layout = QHBoxLayout()
btn_layout.addStretch()
cancel_btn = PushButton("取消")
ok_btn = PrimaryPushButton("确定添加")
cancel_btn.clicked.connect(dialog.reject)
ok_btn.clicked.connect(dialog.accept)
btn_layout.addWidget(cancel_btn)
btn_layout.addWidget(ok_btn)
layout.addLayout(btn_layout)
# 预览更新函数
def update_preview():
selected = preset_combo.currentText()
self.update_preset_preview(selected)
preset_combo.currentTextChanged.connect(update_preview)
# 存储对话框状态
self.current_preview_dialog = dialog
self.preview_combo = preset_combo
# 初始化预览
if preset_tasks:
update_preview()
# 显示对话框
if dialog.exec() == QDialog.Accepted:
selected_task = preset_combo.currentText()
self.save_form()
new_idx = len(self.tasks)
# 从配置文件加载预设任务参数
config = self.load_preset_task_config(selected_task)
if config:
new_task = self._make_task_obj({
"name": config.get("name", selected_task),
"frequency": config.get("frequency", 500),
"delay": config.get("delay", 0),
"stack": config.get("stack", 256),
"description": config.get("description", ""),
"freq_control": config.get("freq_control", True)
})
else:
new_task = self._make_task_obj({"name": selected_task})
new_task["preset_task"] = selected_task
self.tasks.append(new_task)
self.current_index = new_idx
self.refresh_task_btns()
self.show_task_form(self.tasks[self.current_index])
InfoBar.success(
title="添加成功",
content=f"已添加预设任务:{selected_task}",
parent=self,
duration=2000
)
def update_preset_preview(self, task_name):
"""更新预设任务预览信息"""
# 从配置加载信息
config = self.load_preset_task_config(task_name)
if config:
self.info_freq.setText(f"频率: {config.get('frequency', 500)} Hz")
self.info_delay.setText(f"延时: {config.get('delay', 0)} ms")
self.info_stack.setText(f"堆栈: {config.get('stack', 256)} Bytes")
freq_ctrl = "启用" if config.get('freq_control', True) else "禁用"
self.info_ctrl.setText(f"频率控制: {freq_ctrl}")
description = config.get('description', f'预设任务:{task_name}')
self.preview_desc.setText(description)
else:
self.info_freq.setText("频率: 500 Hz")
self.info_delay.setText("延时: 0 ms")
self.info_stack.setText("堆栈: 256 Bytes")
self.info_ctrl.setText("频率控制: 启用")
self.preview_desc.setText(f"预设任务:{task_name}")
def on_preset_task_selected(self, task_name):
"""预设任务选择事件(向后兼容)"""
pass
def get_preset_task_description(self, task_name):
"""获取预设任务的描述信息"""
# 首先尝试从 yaml 配置中获取描述
config = self.load_preset_task_config(task_name)
if config and 'description' in config:
return f"预设任务:{task_name}\n\n{config['description']}\n\n频率控制:{'启用' if config.get('freq_control', True) else '禁用'}\n运行频率:{config.get('frequency', 500)} Hz\n堆栈大小:{config.get('stack', 256)} Bytes\n初始延时:{config.get('delay', 0)} ms"
# 如果没有配置文件,则从代码注释中提取
try:
task_code = self.load_preset_task_code(task_name)
if task_code:
# 尝试从注释中提取描述
lines = task_code.split('\n')
description_lines = []
in_comment = False
for line in lines[:20]: # 只检查前20行
line = line.strip()
if line.startswith('/*'):
in_comment = True
if 'Task' in line and line != '/*':
description_lines.append(line.replace('/*', '').strip())
continue
elif line.endswith('*/'):
in_comment = False
break
elif in_comment and line and not line.startswith('*'):
description_lines.append(line)
if description_lines:
return '\n'.join(description_lines)
else:
return f"预设任务:{task_name}\n这是一个预定义的任务模板,包含完整的实现代码。"
else:
return f"预设任务:{task_name}\n无法读取任务描述。"
except Exception as e:
return f"预设任务:{task_name}\n读取描述时出现错误:{str(e)}"
def add_task(self):
self.save_form()
new_idx = len(self.tasks)
@ -578,10 +302,5 @@ class TaskConfigDialog(QDialog):
}
if freq_ctrl:
task["frequency"] = freq
# 保留预设任务信息
if "preset_task" in t:
task["preset_task"] = t["preset_task"]
tasks.append(task)
return tasks

BIN
assets/.DS_Store vendored

Binary file not shown.

View File

@ -21,19 +21,19 @@
#define FDCAN1_FILTER_CONFIG_TABLE(X) \
X(0, FDCAN_STANDARD_ID, FDCAN_FILTER_MASK, 0x000 , 0x000 , 0) \
X(1, FDCAN_EXTENDED_ID, FDCAN_FILTER_MASK, 0x00000000, 0x00000000, 0)
#define FDCAN1_GLOBAL_FILTER FDCAN_ACCEPT_IN_RX_FIFO0, FDCAN_ACCEPT_IN_RX_FIFO0, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE
#define FDCAN1_GLOBAL_FILTER FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE/* 全局过滤器参数(用于 HAL_FDCAN_ConfigGlobalFilter */
#endif
#ifdef FDCAN2_EN
#define FDCAN2_FILTER_CONFIG_TABLE(X) \
X(0, FDCAN_STANDARD_ID, FDCAN_FILTER_MASK, 0x000 , 0x000 , 0) \
X(1, FDCAN_EXTENDED_ID, FDCAN_FILTER_MASK, 0x00000000, 0x00000000, 0)
#define FDCAN2_GLOBAL_FILTER FDCAN_ACCEPT_IN_RX_FIFO1, FDCAN_ACCEPT_IN_RX_FIFO1, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE
#define FDCAN2_GLOBAL_FILTER FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE/* 全局过滤器参数(用于 HAL_FDCAN_ConfigGlobalFilter */
#endif
#ifdef FDCAN3_EN
#define FDCAN3_FILTER_CONFIG_TABLE(X) \
X(0, FDCAN_STANDARD_ID, FDCAN_FILTER_MASK, 0x000 , 0x000 , 0) \
X(1, FDCAN_EXTENDED_ID, FDCAN_FILTER_MASK, 0x00000000, 0x00000000, 0)
#define FDCAN3_GLOBAL_FILTER FDCAN_ACCEPT_IN_RX_FIFO1, FDCAN_ACCEPT_IN_RX_FIFO1, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE
#define FDCAN3_GLOBAL_FILTER FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE/* 全局过滤器参数(用于 HAL_FDCAN_ConfigGlobalFilter */
#endif
/* ====宏展开实现==== */

View File

@ -69,7 +69,6 @@ int8_t BSP_GPIO_EnableIRQ(BSP_GPIO_t gpio) {
default:
return BSP_ERR;
}
return BSP_OK;
}
int8_t BSP_GPIO_DisableIRQ(BSP_GPIO_t gpio) {
@ -78,7 +77,6 @@ int8_t BSP_GPIO_DisableIRQ(BSP_GPIO_t gpio) {
default:
return BSP_ERR;
}
return BSP_OK;
}
int8_t BSP_GPIO_WritePin(BSP_GPIO_t gpio, bool value){
if (gpio >= BSP_GPIO_NUM) return BSP_ERR;

View File

@ -5,5 +5,4 @@ error_detect,bsp/mm
pid,component/filter
filter,component/ahrs
mixer,component/user_math.h
ui,component/user_math.h
kalman_filter,arm_math.h
ui,component/user_math.h
1 ahrs component/user_math.h
5 pid component/filter
6 filter component/ahrs
7 mixer component/user_math.h
8 ui component/user_math.h
kalman_filter arm_math.h

View File

@ -11,5 +11,4 @@ limiter,限幅器
mixer,混控器
ui,用户交互
user_math,用户自定义数学函数
pid,PID控制器
kalman_filter,卡尔曼滤波器
pid,PID控制器
1 pid 好用的
11 mixer 混控器
12 ui 用户交互
13 user_math 用户自定义数学函数
14 pid PID控制器
kalman_filter 卡尔曼滤波器

View File

@ -28,9 +28,6 @@
#ifndef COMMAND_INTERPRETER_H
#define COMMAND_INTERPRETER_H
#include <stddef.h>
#include "FreeRTOS.h"
/* This config should be defined in FreeRTOSConfig.h. But due to the limition of CubeMX I put it here. */
#define configCOMMAND_INT_MAX_OUTPUT_SIZE 512

View File

@ -1,591 +0,0 @@
/*
modified from wang hongxi
使ARM CMSIS DSP优化矩阵运算
- HRK
-
- P
- ARM CMSIS DSP
- EKF/UKF/ESKF
使
1. PFQ 使
HR 使
2. (use_auto_adjustment = 1)
- measurement_map
- measurement_degreeH
- mat_r_diagonal_elements
3. (use_auto_adjustment = 0)
- P zHR
4.
- measured_vector
- 0
- KF 0
5.
- state_min_variance P
-
使
x =
| |
| |
| |
KF_t Height_KF;
void INS_Task_Init(void)
{
// 初始协方差矩阵 P
static float P_Init[9] =
{
10, 0, 0,
0, 30, 0,
0, 0, 10,
};
// 状态转移矩阵 F根据运动学模型
static float F_Init[9] =
{
1, dt, 0.5*dt*dt,
0, 1, dt,
0, 0, 1,
};
// 过程噪声协方差矩阵 Q
static float Q_Init[9] =
{
0.25*dt*dt*dt*dt, 0.5*dt*dt*dt, 0.5*dt*dt,
0.5*dt*dt*dt, dt*dt, dt,
0.5*dt*dt, dt, 1,
};
// 设置状态最小方差(防止过度收敛)
static float state_min_variance[3] = {0.03, 0.005, 0.1};
// 开启自动调整
Height_KF.use_auto_adjustment = 1;
// 量测映射:[气压高度对应状态1, GPS高度对应状态1, 加速度计对应状态3]
static uint8_t measurement_reference[3] = {1, 1, 3};
// 量测系数H矩阵元素值
static float measurement_degree[3] = {1, 1, 1};
// 根据 measurement_reference 与 measurement_degree 生成 H 矩阵如下
// (在当前周期全部量测数据有效的情况下)
// |1 0 0|
// |1 0 0|
// |0 0 1|
// 量测噪声方差R矩阵对角元素
static float mat_r_diagonal_elements[3] = {30, 25, 35};
// 根据 mat_r_diagonal_elements 生成 R 矩阵如下
// (在当前周期全部量测数据有效的情况下)
// |30 0 0|
// | 0 25 0|
// | 0 0 35|
// 初始化卡尔曼滤波器状态维数3控制维数0量测维数3
KF_Init(&Height_KF, 3, 0, 3);
// 设置矩阵初值
memcpy(Height_KF.P_data, P_Init, sizeof(P_Init));
memcpy(Height_KF.F_data, F_Init, sizeof(F_Init));
memcpy(Height_KF.Q_data, Q_Init, sizeof(Q_Init));
memcpy(Height_KF.measurement_map, measurement_reference,
sizeof(measurement_reference));
memcpy(Height_KF.measurement_degree, measurement_degree,
sizeof(measurement_degree));
memcpy(Height_KF.mat_r_diagonal_elements, mat_r_diagonal_elements,
sizeof(mat_r_diagonal_elements));
memcpy(Height_KF.state_min_variance, state_min_variance,
sizeof(state_min_variance));
}
void INS_Task(void const *pvParameters)
{
// 循环更新卡尔曼滤波器
KF_Update(&Height_KF);
vTaskDelay(ts);
}
// 传感器回调函数示例:在数据就绪时更新 measured_vector
void Barometer_Read_Over(void)
{
......
INS_KF.measured_vector[0] = baro_height; // 气压计高度
}
void GPS_Read_Over(void)
{
......
INS_KF.measured_vector[1] = GPS_height; // GPS高度
}
void Acc_Data_Process(void)
{
......
INS_KF.measured_vector[2] = acc.z; // Z轴加速度
}
*/
#include "kalman_filter.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* 私有函数声明 */
static void KF_AdjustHKR(KF_t *kf);
/**
* @brief
*
* @param kf
* @param xhat_size
* @param u_size 0
* @param z_size
* @return int8_t 0
*/
int8_t KF_Init(KF_t *kf, uint8_t xhat_size, uint8_t u_size, uint8_t z_size) {
if (kf == NULL) return -1;
kf->xhat_size = xhat_size;
kf->u_size = u_size;
kf->z_size = z_size;
kf->measurement_valid_num = 0;
/* 量测标志分配 */
kf->measurement_map = (uint8_t *)user_malloc(sizeof(uint8_t) * z_size);
memset(kf->measurement_map, 0, sizeof(uint8_t) * z_size);
kf->measurement_degree = (float *)user_malloc(sizeof(float) * z_size);
memset(kf->measurement_degree, 0, sizeof(float) * z_size);
kf->mat_r_diagonal_elements = (float *)user_malloc(sizeof(float) * z_size);
memset(kf->mat_r_diagonal_elements, 0, sizeof(float) * z_size);
kf->state_min_variance = (float *)user_malloc(sizeof(float) * xhat_size);
memset(kf->state_min_variance, 0, sizeof(float) * xhat_size);
kf->temp = (uint8_t *)user_malloc(sizeof(uint8_t) * z_size);
memset(kf->temp, 0, sizeof(uint8_t) * z_size);
/* 滤波数据分配 */
kf->filtered_value = (float *)user_malloc(sizeof(float) * xhat_size);
memset(kf->filtered_value, 0, sizeof(float) * xhat_size);
kf->measured_vector = (float *)user_malloc(sizeof(float) * z_size);
memset(kf->measured_vector, 0, sizeof(float) * z_size);
kf->control_vector = (float *)user_malloc(sizeof(float) * u_size);
memset(kf->control_vector, 0, sizeof(float) * u_size);
/* 状态估计 xhat x(k|k) */
kf->xhat_data = (float *)user_malloc(sizeof(float) * xhat_size);
memset(kf->xhat_data, 0, sizeof(float) * xhat_size);
KF_MatInit(&kf->xhat, kf->xhat_size, 1, kf->xhat_data);
/* 先验状态估计 xhatminus x(k|k-1) */
kf->xhatminus_data = (float *)user_malloc(sizeof(float) * xhat_size);
memset(kf->xhatminus_data, 0, sizeof(float) * xhat_size);
KF_MatInit(&kf->xhatminus, kf->xhat_size, 1, kf->xhatminus_data);
/* 控制向量 u */
if (u_size != 0) {
kf->u_data = (float *)user_malloc(sizeof(float) * u_size);
memset(kf->u_data, 0, sizeof(float) * u_size);
KF_MatInit(&kf->u, kf->u_size, 1, kf->u_data);
}
/* 量测向量 z */
kf->z_data = (float *)user_malloc(sizeof(float) * z_size);
memset(kf->z_data, 0, sizeof(float) * z_size);
KF_MatInit(&kf->z, kf->z_size, 1, kf->z_data);
/* 协方差矩阵 P(k|k) */
kf->P_data = (float *)user_malloc(sizeof(float) * xhat_size * xhat_size);
memset(kf->P_data, 0, sizeof(float) * xhat_size * xhat_size);
KF_MatInit(&kf->P, kf->xhat_size, kf->xhat_size, kf->P_data);
/* 先验协方差矩阵 P(k|k-1) */
kf->Pminus_data = (float *)user_malloc(sizeof(float) * xhat_size * xhat_size);
memset(kf->Pminus_data, 0, sizeof(float) * xhat_size * xhat_size);
KF_MatInit(&kf->Pminus, kf->xhat_size, kf->xhat_size, kf->Pminus_data);
/* 状态转移矩阵 F 及其转置 FT */
kf->F_data = (float *)user_malloc(sizeof(float) * xhat_size * xhat_size);
kf->FT_data = (float *)user_malloc(sizeof(float) * xhat_size * xhat_size);
memset(kf->F_data, 0, sizeof(float) * xhat_size * xhat_size);
memset(kf->FT_data, 0, sizeof(float) * xhat_size * xhat_size);
KF_MatInit(&kf->F, kf->xhat_size, kf->xhat_size, kf->F_data);
KF_MatInit(&kf->FT, kf->xhat_size, kf->xhat_size, kf->FT_data);
/* 控制矩阵 B */
if (u_size != 0) {
kf->B_data = (float *)user_malloc(sizeof(float) * xhat_size * u_size);
memset(kf->B_data, 0, sizeof(float) * xhat_size * u_size);
KF_MatInit(&kf->B, kf->xhat_size, kf->u_size, kf->B_data);
}
/* 量测矩阵 H 及其转置 HT */
kf->H_data = (float *)user_malloc(sizeof(float) * z_size * xhat_size);
kf->HT_data = (float *)user_malloc(sizeof(float) * xhat_size * z_size);
memset(kf->H_data, 0, sizeof(float) * z_size * xhat_size);
memset(kf->HT_data, 0, sizeof(float) * xhat_size * z_size);
KF_MatInit(&kf->H, kf->z_size, kf->xhat_size, kf->H_data);
KF_MatInit(&kf->HT, kf->xhat_size, kf->z_size, kf->HT_data);
/* 过程噪声协方差矩阵 Q */
kf->Q_data = (float *)user_malloc(sizeof(float) * xhat_size * xhat_size);
memset(kf->Q_data, 0, sizeof(float) * xhat_size * xhat_size);
KF_MatInit(&kf->Q, kf->xhat_size, kf->xhat_size, kf->Q_data);
/* 量测噪声协方差矩阵 R */
kf->R_data = (float *)user_malloc(sizeof(float) * z_size * z_size);
memset(kf->R_data, 0, sizeof(float) * z_size * z_size);
KF_MatInit(&kf->R, kf->z_size, kf->z_size, kf->R_data);
/* 卡尔曼增益 K */
kf->K_data = (float *)user_malloc(sizeof(float) * xhat_size * z_size);
memset(kf->K_data, 0, sizeof(float) * xhat_size * z_size);
KF_MatInit(&kf->K, kf->xhat_size, kf->z_size, kf->K_data);
/* 临时矩阵分配 */
kf->S_data = (float *)user_malloc(sizeof(float) * xhat_size * xhat_size);
kf->temp_matrix_data =
(float *)user_malloc(sizeof(float) * xhat_size * xhat_size);
kf->temp_matrix_data1 =
(float *)user_malloc(sizeof(float) * xhat_size * xhat_size);
kf->temp_vector_data = (float *)user_malloc(sizeof(float) * xhat_size);
kf->temp_vector_data1 = (float *)user_malloc(sizeof(float) * xhat_size);
KF_MatInit(&kf->S, kf->xhat_size, kf->xhat_size, kf->S_data);
KF_MatInit(&kf->temp_matrix, kf->xhat_size, kf->xhat_size,
kf->temp_matrix_data);
KF_MatInit(&kf->temp_matrix1, kf->xhat_size, kf->xhat_size,
kf->temp_matrix_data1);
KF_MatInit(&kf->temp_vector, kf->xhat_size, 1, kf->temp_vector_data);
KF_MatInit(&kf->temp_vector1, kf->xhat_size, 1, kf->temp_vector_data1);
/* 初始化跳过标志 */
kf->skip_eq1 = 0;
kf->skip_eq2 = 0;
kf->skip_eq3 = 0;
kf->skip_eq4 = 0;
kf->skip_eq5 = 0;
/* 初始化用户函数指针 */
kf->User_Func0_f = NULL;
kf->User_Func1_f = NULL;
kf->User_Func2_f = NULL;
kf->User_Func3_f = NULL;
kf->User_Func4_f = NULL;
kf->User_Func5_f = NULL;
kf->User_Func6_f = NULL;
return 0;
}
/**
* @brief
*
* @param kf
* @return int8_t 0
*/
int8_t KF_Measure(KF_t *kf) {
if (kf == NULL) return -1;
/* 根据量测有效性自动调整 H, K, R 矩阵 */
if (kf->use_auto_adjustment != 0) {
KF_AdjustHKR(kf);
} else {
memcpy(kf->z_data, kf->measured_vector, sizeof(float) * kf->z_size);
memset(kf->measured_vector, 0, sizeof(float) * kf->z_size);
}
memcpy(kf->u_data, kf->control_vector, sizeof(float) * kf->u_size);
return 0;
}
/**
* @brief 1 - xhat'(k) = F·xhat(k-1) + B·u
*
* @param kf
* @return int8_t 0
*/
int8_t KF_PredictState(KF_t *kf) {
if (kf == NULL) return -1;
if (!kf->skip_eq1) {
if (kf->u_size > 0) {
/* 有控制输入: xhat'(k) = F·xhat(k-1) + B·u */
kf->temp_vector.numRows = kf->xhat_size;
kf->temp_vector.numCols = 1;
kf->mat_status = KF_MatMult(&kf->F, &kf->xhat, &kf->temp_vector);
kf->temp_vector1.numRows = kf->xhat_size;
kf->temp_vector1.numCols = 1;
kf->mat_status = KF_MatMult(&kf->B, &kf->u, &kf->temp_vector1);
kf->mat_status =
KF_MatAdd(&kf->temp_vector, &kf->temp_vector1, &kf->xhatminus);
} else {
/* 无控制输入: xhat'(k) = F·xhat(k-1) */
kf->mat_status = KF_MatMult(&kf->F, &kf->xhat, &kf->xhatminus);
}
}
return 0;
}
/**
* @brief 2 - P'(k) = F·P(k-1)·F^T + Q
*
* @param kf
* @return int8_t 0
*/
int8_t KF_PredictCovariance(KF_t *kf) {
if (kf == NULL) return -1;
if (!kf->skip_eq2) {
kf->mat_status = KF_MatTrans(&kf->F, &kf->FT);
kf->mat_status = KF_MatMult(&kf->F, &kf->P, &kf->Pminus);
kf->temp_matrix.numRows = kf->Pminus.numRows;
kf->temp_matrix.numCols = kf->FT.numCols;
/* F·P(k-1)·F^T */
kf->mat_status = KF_MatMult(&kf->Pminus, &kf->FT, &kf->temp_matrix);
kf->mat_status = KF_MatAdd(&kf->temp_matrix, &kf->Q, &kf->Pminus);
}
return 0;
}
/**
* @brief 3 - K = P'(k)·H^T / (H·P'(k)·H^T + R)
*
* @param kf
* @return int8_t 0
*/
int8_t KF_CalcGain(KF_t *kf) {
if (kf == NULL) return -1;
if (!kf->skip_eq3) {
kf->mat_status = KF_MatTrans(&kf->H, &kf->HT);
kf->temp_matrix.numRows = kf->H.numRows;
kf->temp_matrix.numCols = kf->Pminus.numCols;
/* H·P'(k) */
kf->mat_status = KF_MatMult(&kf->H, &kf->Pminus, &kf->temp_matrix);
kf->temp_matrix1.numRows = kf->temp_matrix.numRows;
kf->temp_matrix1.numCols = kf->HT.numCols;
/* H·P'(k)·H^T */
kf->mat_status = KF_MatMult(&kf->temp_matrix, &kf->HT, &kf->temp_matrix1);
kf->S.numRows = kf->R.numRows;
kf->S.numCols = kf->R.numCols;
/* S = H·P'(k)·H^T + R */
kf->mat_status = KF_MatAdd(&kf->temp_matrix1, &kf->R, &kf->S);
/* S^-1 */
kf->mat_status = KF_MatInv(&kf->S, &kf->temp_matrix1);
kf->temp_matrix.numRows = kf->Pminus.numRows;
kf->temp_matrix.numCols = kf->HT.numCols;
/* P'(k)·H^T */
kf->mat_status = KF_MatMult(&kf->Pminus, &kf->HT, &kf->temp_matrix);
/* K = P'(k)·H^T·S^-1 */
kf->mat_status = KF_MatMult(&kf->temp_matrix, &kf->temp_matrix1, &kf->K);
}
return 0;
}
/**
* @brief 4 - xhat(k) = xhat'(k) + K·(z - H·xhat'(k))
*
* @param kf
* @return int8_t 0
*/
int8_t KF_UpdateState(KF_t *kf) {
if (kf == NULL) return -1;
if (!kf->skip_eq4) {
kf->temp_vector.numRows = kf->H.numRows;
kf->temp_vector.numCols = 1;
/* H·xhat'(k) */
kf->mat_status = KF_MatMult(&kf->H, &kf->xhatminus, &kf->temp_vector);
kf->temp_vector1.numRows = kf->z.numRows;
kf->temp_vector1.numCols = 1;
/* 新息: z - H·xhat'(k) */
kf->mat_status = KF_MatSub(&kf->z, &kf->temp_vector, &kf->temp_vector1);
kf->temp_vector.numRows = kf->K.numRows;
kf->temp_vector.numCols = 1;
/* K·新息 */
kf->mat_status = KF_MatMult(&kf->K, &kf->temp_vector1, &kf->temp_vector);
/* xhat = xhat' + K·新息 */
kf->mat_status = KF_MatAdd(&kf->xhatminus, &kf->temp_vector, &kf->xhat);
}
return 0;
}
/**
* @brief 5 - P(k) = P'(k) - K·H·P'(k)
*
* @param kf
* @return int8_t 0
*/
int8_t KF_UpdateCovariance(KF_t *kf) {
if (kf == NULL) return -1;
if (!kf->skip_eq5) {
kf->temp_matrix.numRows = kf->K.numRows;
kf->temp_matrix.numCols = kf->H.numCols;
kf->temp_matrix1.numRows = kf->temp_matrix.numRows;
kf->temp_matrix1.numCols = kf->Pminus.numCols;
/* K·H */
kf->mat_status = KF_MatMult(&kf->K, &kf->H, &kf->temp_matrix);
/* K·H·P'(k) */
kf->mat_status = KF_MatMult(&kf->temp_matrix, &kf->Pminus, &kf->temp_matrix1);
/* P = P' - K·H·P' */
kf->mat_status = KF_MatSub(&kf->Pminus, &kf->temp_matrix1, &kf->P);
}
return 0;
}
/**
* @brief
*
* KFEKF/UKF/ESKF/AUKF
* User_Func
*
* @param kf
* @return float*
*/
float *KF_Update(KF_t *kf) {
if (kf == NULL) return NULL;
/* 步骤0: 量测获取和矩阵调整 */
KF_Measure(kf);
if (kf->User_Func0_f != NULL) kf->User_Func0_f(kf);
/* 步骤1: 先验状态估计 - xhat'(k) = F·xhat(k-1) + B·u */
KF_PredictState(kf);
if (kf->User_Func1_f != NULL) kf->User_Func1_f(kf);
/* 步骤2: 先验协方差 - P'(k) = F·P(k-1)·F^T + Q */
KF_PredictCovariance(kf);
if (kf->User_Func2_f != NULL) kf->User_Func2_f(kf);
/* 量测更新(仅在存在有效量测时执行) */
if (kf->measurement_valid_num != 0 || kf->use_auto_adjustment == 0) {
/* 步骤3: 卡尔曼增益 - K = P'(k)·H^T / (H·P'(k)·H^T + R) */
KF_CalcGain(kf);
if (kf->User_Func3_f != NULL) kf->User_Func3_f(kf);
/* 步骤4: 状态更新 - xhat(k) = xhat'(k) + K·(z - H·xhat'(k)) */
KF_UpdateState(kf);
if (kf->User_Func4_f != NULL) kf->User_Func4_f(kf);
/* 步骤5: 协方差更新 - P(k) = P'(k) - K·H·P'(k) */
KF_UpdateCovariance(kf);
} else {
/* 无有效量测 - 仅预测 */
memcpy(kf->xhat_data, kf->xhatminus_data, sizeof(float) * kf->xhat_size);
memcpy(kf->P_data, kf->Pminus_data,
sizeof(float) * kf->xhat_size * kf->xhat_size);
}
/* 后处理钩子 */
if (kf->User_Func5_f != NULL) kf->User_Func5_f(kf);
/* 防过度收敛:强制最小方差 */
for (uint8_t i = 0; i < kf->xhat_size; i++) {
if (kf->P_data[i * kf->xhat_size + i] < kf->state_min_variance[i])
kf->P_data[i * kf->xhat_size + i] = kf->state_min_variance[i];
}
/* 复制结果到输出 */
memcpy(kf->filtered_value, kf->xhat_data, sizeof(float) * kf->xhat_size);
/* 附加后处理钩子 */
if (kf->User_Func6_f != NULL) kf->User_Func6_f(kf);
return kf->filtered_value;
}
/**
* @brief
*
* @param kf
*/
void KF_Reset(KF_t *kf) {
if (kf == NULL) return;
memset(kf->xhat_data, 0, sizeof(float) * kf->xhat_size);
memset(kf->xhatminus_data, 0, sizeof(float) * kf->xhat_size);
memset(kf->filtered_value, 0, sizeof(float) * kf->xhat_size);
kf->measurement_valid_num = 0;
}
/**
* @brief H, R, K
*
*
*
*
* @param kf
*/
static void KF_AdjustHKR(KF_t *kf) {
kf->measurement_valid_num = 0;
/* 复制并重置量测向量 */
memcpy(kf->z_data, kf->measured_vector, sizeof(float) * kf->z_size);
memset(kf->measured_vector, 0, sizeof(float) * kf->z_size);
/* 清空 H 和 R 矩阵 */
memset(kf->R_data, 0, sizeof(float) * kf->z_size * kf->z_size);
memset(kf->H_data, 0, sizeof(float) * kf->xhat_size * kf->z_size);
/* 识别有效量测并重建 z, H */
for (uint8_t i = 0; i < kf->z_size; i++) {
if (kf->z_data[i] != 0) { /* 非零表示有效量测 */
/* 将有效量测压缩到 z */
kf->z_data[kf->measurement_valid_num] = kf->z_data[i];
kf->temp[kf->measurement_valid_num] = i;
/* 重建 H 矩阵行 */
kf->H_data[kf->xhat_size * kf->measurement_valid_num +
kf->measurement_map[i] - 1] = kf->measurement_degree[i];
kf->measurement_valid_num++;
}
}
/* 用有效量测方差重建 R 矩阵 */
for (uint8_t i = 0; i < kf->measurement_valid_num; i++) {
kf->R_data[i * kf->measurement_valid_num + i] =
kf->mat_r_diagonal_elements[kf->temp[i]];
}
/* 调整矩阵维度以匹配有效量测数量 */
kf->H.numRows = kf->measurement_valid_num;
kf->H.numCols = kf->xhat_size;
kf->HT.numRows = kf->xhat_size;
kf->HT.numCols = kf->measurement_valid_num;
kf->R.numRows = kf->measurement_valid_num;
kf->R.numCols = kf->measurement_valid_num;
kf->K.numRows = kf->xhat_size;
kf->K.numCols = kf->measurement_valid_num;
kf->z.numRows = kf->measurement_valid_num;
}
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */

View File

@ -1,199 +0,0 @@
/*
使ARM CMSIS DSP优化矩阵运算
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "arm_math.h"
#include <math.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* 内存分配配置 */
#ifndef user_malloc
#ifdef _CMSIS_OS_H
#define user_malloc pvPortMalloc /* FreeRTOS堆分配 */
#else
#define user_malloc malloc /* 标准C库分配 */
#endif
#endif
/* ARM CMSIS DSP 矩阵运算别名 */
#define KF_Mat arm_matrix_instance_f32
#define KF_MatInit arm_mat_init_f32
#define KF_MatAdd arm_mat_add_f32
#define KF_MatSub arm_mat_sub_f32
#define KF_MatMult arm_mat_mult_f32
#define KF_MatTrans arm_mat_trans_f32
#define KF_MatInv arm_mat_inverse_f32
/* 卡尔曼滤波器主结构体 */
typedef struct KF_s {
/* 输出和输入向量 */
float *filtered_value; /* 滤波后的状态估计输出 */
float *measured_vector; /* 量测输入向量 */
float *control_vector; /* 控制输入向量 */
/* 维度 */
uint8_t xhat_size; /* 状态向量维度 */
uint8_t u_size; /* 控制向量维度 */
uint8_t z_size; /* 量测向量维度 */
/* 自动调整参数 */
uint8_t use_auto_adjustment; /* 启用动态 H/R/K 调整 */
uint8_t measurement_valid_num; /* 有效量测数量 */
/* 量测配置 */
uint8_t *measurement_map; /* 量测到状态的映射 */
float *measurement_degree; /* 每个量测的H矩阵元素值 */
float *mat_r_diagonal_elements; /* 量测噪声方差R对角线 */
float *state_min_variance; /* 最小状态方差(防过度收敛) */
uint8_t *temp; /* 临时缓冲区 */
/* 方程跳过标志(用于自定义用户函数) */
uint8_t skip_eq1, skip_eq2, skip_eq3, skip_eq4, skip_eq5;
/* 卡尔曼滤波器矩阵 */
KF_Mat xhat; /* 状态估计 x(k|k) */
KF_Mat xhatminus; /* 先验状态估计 x(k|k-1) */
KF_Mat u; /* 控制向量 */
KF_Mat z; /* 量测向量 */
KF_Mat P; /* 后验误差协方差 P(k|k) */
KF_Mat Pminus; /* 先验误差协方差 P(k|k-1) */
KF_Mat F, FT; /* 状态转移矩阵及其转置 */
KF_Mat B; /* 控制矩阵 */
KF_Mat H, HT; /* 量测矩阵及其转置 */
KF_Mat Q; /* 过程噪声协方差 */
KF_Mat R; /* 量测噪声协方差 */
KF_Mat K; /* 卡尔曼增益 */
KF_Mat S; /* 临时矩阵 S */
KF_Mat temp_matrix, temp_matrix1; /* 临时矩阵 */
KF_Mat temp_vector, temp_vector1; /* 临时向量 */
int8_t mat_status; /* 矩阵运算状态 */
/* 用户自定义函数指针用于EKF/UKF/ESKF扩展 */
void (*User_Func0_f)(struct KF_s *kf); /* 自定义量测处理 */
void (*User_Func1_f)(struct KF_s *kf); /* 自定义状态预测 */
void (*User_Func2_f)(struct KF_s *kf); /* 自定义协方差预测 */
void (*User_Func3_f)(struct KF_s *kf); /* 自定义卡尔曼增益计算 */
void (*User_Func4_f)(struct KF_s *kf); /* 自定义状态更新 */
void (*User_Func5_f)(struct KF_s *kf); /* 自定义后处理 */
void (*User_Func6_f)(struct KF_s *kf); /* 附加自定义函数 */
/* 矩阵数据存储指针 */
float *xhat_data, *xhatminus_data;
float *u_data;
float *z_data;
float *P_data, *Pminus_data;
float *F_data, *FT_data;
float *B_data;
float *H_data, *HT_data;
float *Q_data;
float *R_data;
float *K_data;
float *S_data;
float *temp_matrix_data, *temp_matrix_data1;
float *temp_vector_data, *temp_vector_data1;
} KF_t;
/* USER STRUCT BEGIN */
/* USER STRUCT END */
/**
* @brief
*
* @param kf
* @param xhat_size
* @param u_size 0
* @param z_size
* @return int8_t 0
*/
int8_t KF_Init(KF_t *kf, uint8_t xhat_size, uint8_t u_size, uint8_t z_size);
/**
* @brief
*
* @param kf
* @return int8_t 0
*/
int8_t KF_Measure(KF_t *kf);
/**
* @brief 1 - xhat'(k) = F·xhat(k-1) + B·u
*
* @param kf
* @return int8_t 0
*/
int8_t KF_PredictState(KF_t *kf);
/**
* @brief 2 - P'(k) = F·P(k-1)·F^T + Q
*
* @param kf
* @return int8_t 0
*/
int8_t KF_PredictCovariance(KF_t *kf);
/**
* @brief 3 - K = P'(k)·H^T / (H·P'(k)·H^T + R)
*
* @param kf
* @return int8_t 0
*/
int8_t KF_CalcGain(KF_t *kf);
/**
* @brief 4 - xhat(k) = xhat'(k) + K·(z - H·xhat'(k))
*
* @param kf
* @return int8_t 0
*/
int8_t KF_UpdateState(KF_t *kf);
/**
* @brief 5 - P(k) = P'(k) - K·H·P'(k)
*
* @param kf
* @return int8_t 0
*/
int8_t KF_UpdateCovariance(KF_t *kf);
/**
* @brief
*
* @param kf
* @return float*
*/
float *KF_Update(KF_t *kf);
/**
* @brief
*
* @param kf
*/
void KF_Reset(KF_t *kf);
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
#ifdef __cplusplus
}
#endif

View File

@ -105,8 +105,3 @@ float HeatLimit_ShootFreq(float heat, float heat_limit, float cooling_rate,
else
return (heat_percent > 0.7f) ? stable_freq : 3.0f * stable_freq;
}
/* USER CODE BEGIN */
/* USER CODE END */

View File

@ -61,7 +61,3 @@ float PowerLimit_TargetPower(float power_limit, float power_buffer);
*/
float HeatLimit_ShootFreq(float heat, float heat_limit, float cooling_rate,
float heat_increase, bool is_big);
/* USER CODE BEGIN */
/* USER CODE END */

View File

@ -1,4 +1,4 @@
bsp,can,fdcan,dwt,gpio,i2c,mm,spi,uart,pwm,time,flash
component,ahrs,capacity,cmd,crc8,crc16,error_detect,filter,FreeRTOS_CLI,limiter,mixer,pid,ui,user_math
device,dr16,bmi088,ist8310,motor,motor_rm,motor_dm,motor_vesc,motor_lk,motor_lz,motor_odrive,dm_imu,rc_can,servo,buzzer,led,ws2812,vofa,ops9,oid,lcd_driver,mrobot
device,dr16,bmi088,ist8310,motor,motor_rm,motor_dm,motor_vesc,motor_lk,motor_lz,motor_odrive,dm_imu,rc_can,servo,buzzer,led,ws2812,vofa,ops9,oid,lcd_driver
module,
1 bsp,can,fdcan,dwt,gpio,i2c,mm,spi,uart,pwm,time,flash
2 component,ahrs,capacity,cmd,crc8,crc16,error_detect,filter,FreeRTOS_CLI,limiter,mixer,pid,ui,user_math
3 device,dr16,bmi088,ist8310,motor,motor_rm,motor_dm,motor_vesc,motor_lk,motor_lz,motor_odrive,dm_imu,rc_can,servo,buzzer,led,ws2812,vofa,ops9,oid,lcd_driver,mrobot device,dr16,bmi088,ist8310,motor,motor_rm,motor_dm,motor_vesc,motor_lk,motor_lz,motor_odrive,dm_imu,rc_can,servo,buzzer,led,ws2812,vofa,ops9,oid,lcd_driver
4 module,

View File

@ -259,19 +259,4 @@ devices:
thread_signals: []
files:
header: "lcd.h"
source: "lcd.c"
mrobot:
name: "MRobot CLI"
description: "基于 FreeRTOS CLI 的嵌入式调试命令行系统,支持设备注册与监控、类 Unix 文件系统命令、htop 风格任务监控等"
dependencies:
bsp: ["uart", "mm"]
component: ["freertos_cli"]
bsp_requirements:
- type: "uart"
var_name: "BSP_UART_MROBOT"
description: "用于 MRobot CLI 命令行交互"
thread_signals: []
files:
header: "mrobot.h"
source: "mrobot.c"
source: "lcd.c"

View File

@ -111,21 +111,11 @@ static int8_t MOTOR_DM_SendMITCmd(MOTOR_DM_t *motor, MOTOR_MIT_Output_t *output)
uint16_t pos_tmp,vel_tmp,kp_tmp,kd_tmp,tor_tmp;
uint16_t id = motor->param.can_id;
/* 根据 reverse 参数调整控制值 */
float angle = output->angle;
float velocity = output->velocity;
float torque = output->torque;
if (motor->param.reverse) {
angle = -angle;
velocity = -velocity;
torque = -torque;
}
pos_tmp = float_to_uint(angle, DM_P_MIN , DM_P_MAX, 16);
vel_tmp = float_to_uint(velocity, DM_V_MIN , DM_V_MAX, 12);
pos_tmp = float_to_uint(output->angle, DM_P_MIN , DM_P_MAX, 16);
vel_tmp = float_to_uint(output->velocity, DM_V_MIN , DM_V_MAX, 12);
kp_tmp = float_to_uint(output->kp, DM_KP_MIN, DM_KP_MAX, 12);
kd_tmp = float_to_uint(output->kd, DM_KD_MIN, DM_KD_MAX, 12);
tor_tmp = float_to_uint(torque, DM_T_MIN , DM_T_MAX, 12);
tor_tmp = float_to_uint(output->torque, DM_T_MIN , DM_T_MAX, 12);
/* 打包数据 */
data[0] = (pos_tmp >> 8);
@ -161,11 +151,6 @@ static int8_t MOTOR_DM_SendPosVelCmd(MOTOR_DM_t *motor, float pos, float vel) {
uint8_t data[8] = {0};
/* 根据 reverse 参数调整控制值 */
if (motor->param.reverse) {
pos = -pos;
vel = -vel;
}
/* 直接发送浮点数数据 */
memcpy(&data[0], &pos, 4); // 位置,低位在前
@ -194,11 +179,6 @@ static int8_t MOTOR_DM_SendVelCmd(MOTOR_DM_t *motor, float vel) {
uint8_t data[4] = {0};
/* 根据 reverse 参数调整控制值 */
if (motor->param.reverse) {
vel = -vel;
}
/* 直接发送浮点数数据 */
memcpy(&data[0], &vel, 4); // 速度,低位在前

View File

@ -1,874 +0,0 @@
/**
* @file mrobot.c
* @brief MRobot CLI
*/
/* Includes ----------------------------------------------------------------- */
#include "device/mrobot.h"
#include "component/freertos_cli.h"
#include "bsp/uart.h"
#include "bsp/mm.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <FreeRTOS.h>
#include <task.h>
#include <semphr.h>
#include <cmsis_os2.h>
/* Private constants -------------------------------------------------------- */
static const char *const CLI_WELCOME_MESSAGE =
"\r\n"
" __ __ _____ _ _ \r\n"
" | \\/ | __ \\ | | | | \r\n"
" | \\ / | |__) |___ | |__ ___ | |_ \r\n"
" | |\\/| | _ // _ \\| '_ \\ / _ \\| __|\r\n"
" | | | | | \\ \\ (_) | |_) | (_) | |_ \r\n"
" |_| |_|_| \\_\\___/|_.__/ \\___/ \\__|\r\n"
" ------------------------------------\r\n"
" Welcome to use MRobot CLI. Type 'help' to view a list of registered commands.\r\n"
"\r\n";
/* ANSI 转义序列 */
#define ANSI_CLEAR_SCREEN "\033[2J\033[H"
#define ANSI_CURSOR_HOME "\033[H"
#define ANSI_BACKSPACE "\b \b"
/* Private types ------------------------------------------------------------ */
/* CLI 上下文结构体 - 封装所有状态 */
typedef struct {
/* 设备管理 */
MRobot_Device_t devices[MROBOT_MAX_DEVICES];
uint8_t device_count;
/* 自定义命令 */
CLI_Command_Definition_t *custom_cmds[MROBOT_MAX_CUSTOM_COMMANDS];
uint8_t custom_cmd_count;
/* CLI 状态 */
MRobot_State_t state;
char current_path[MROBOT_PATH_MAX_LEN];
/* 命令缓冲区 */
uint8_t cmd_buffer[MROBOT_CMD_BUFFER_SIZE];
volatile uint8_t cmd_index;
volatile bool cmd_ready;
/* UART 相关 */
uint8_t uart_rx_char;
volatile bool tx_complete;
volatile bool htop_exit;
/* 输出缓冲区 */
char output_buffer[MROBOT_OUTPUT_BUFFER_SIZE];
/* 初始化标志 */
bool initialized;
/* 互斥锁 */
SemaphoreHandle_t mutex;
} MRobot_Context_t;
/* Private variables -------------------------------------------------------- */
static MRobot_Context_t ctx = {
.device_count = 0,
.custom_cmd_count = 0,
.state = MROBOT_STATE_IDLE,
.current_path = "/",
.cmd_index = 0,
.cmd_ready = false,
.tx_complete = true,
.htop_exit = false,
.initialized = false,
.mutex = NULL
};
/* Private function prototypes ---------------------------------------------- */
/* 命令处理函数 */
static BaseType_t cmd_help(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString);
static BaseType_t cmd_htop(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString);
static BaseType_t cmd_cd(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString);
static BaseType_t cmd_ls(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString);
static BaseType_t cmd_show(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString);
/* 内部辅助函数 */
static void uart_tx_callback(void);
static void uart_rx_callback(void);
static void send_string(const char *str);
static void send_prompt(void);
static int format_float_va(char *buf, size_t size, const char *fmt, va_list args);
/* CLI 命令定义表 */
static const CLI_Command_Definition_t builtin_commands[] = {
{ "help", " --help: 显示所有可用命令\r\n", cmd_help, 0 },
{ "htop", " --htop: 动态显示 FreeRTOS 任务状态 (按 'q' 退出)\r\n", cmd_htop, 0 },
{ "cd", " --cd <path>: 切换目录\r\n", cmd_cd, 1 },
{ "ls", " --ls: 列出当前目录内容\r\n", cmd_ls, 0 },
{ "show", " --show [device] [count]: 显示设备信息\r\n", cmd_show, -1 },
};
#define BUILTIN_CMD_COUNT (sizeof(builtin_commands) / sizeof(builtin_commands[0]))
/* ========================================================================== */
/* 辅助函数实现 */
/* ========================================================================== */
/**
* @brief UART
*/
static void send_string(const char *str) {
if (str == NULL || *str == '\0') return;
ctx.tx_complete = false;
BSP_UART_Transmit(BSP_UART_MROBOT, (uint8_t *)str, strlen(str), true);
while (!ctx.tx_complete) { osDelay(1); }
}
/**
* @brief
*/
static void send_prompt(void) {
char prompt[MROBOT_PATH_MAX_LEN + 32];
snprintf(prompt, sizeof(prompt), MROBOT_USER_NAME "@" MROBOT_HOST_NAME ":%s$ ", ctx.current_path);
send_string(prompt);
}
/**
* @brief UART
*/
static void uart_tx_callback(void) {
ctx.tx_complete = true;
}
/**
* @brief UART
*/
static void uart_rx_callback(void) {
uint8_t ch = ctx.uart_rx_char;
/* htop 模式下检查退出键 */
if (ctx.state == MROBOT_STATE_HTOP) {
if (ch == 'q' || ch == 'Q' || ch == 27) {
ctx.htop_exit = true;
}
BSP_UART_Receive(BSP_UART_MROBOT, &ctx.uart_rx_char, 1, false);
return;
}
/* 正常命令输入处理 */
if (ch == '\r' || ch == '\n') {
if (ctx.cmd_index > 0) {
ctx.cmd_buffer[ctx.cmd_index] = '\0';
ctx.cmd_ready = true;
BSP_UART_Transmit(BSP_UART_MROBOT, (uint8_t *)"\r\n", 2, false);
}
} else if (ch == 127 || ch == 8) { /* 退格键 */
if (ctx.cmd_index > 0) {
ctx.cmd_index--;
BSP_UART_Transmit(BSP_UART_MROBOT, (uint8_t *)ANSI_BACKSPACE, 3, false);
}
} else if (ch >= 32 && ch < 127 && ctx.cmd_index < sizeof(ctx.cmd_buffer) - 1) {
ctx.cmd_buffer[ctx.cmd_index++] = ch;
/* 回显:使用静态变量地址,避免异步发送时局部变量已失效 */
BSP_UART_Transmit(BSP_UART_MROBOT, &ctx.uart_rx_char, 1, false);
}
BSP_UART_Receive(BSP_UART_MROBOT, &ctx.uart_rx_char, 1, false);
}
/* ========================================================================== */
/* CLI 命令实现 */
/* ========================================================================== */
/**
* @brief help -
*/
static BaseType_t cmd_help(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString) {
(void)pcCommandString;
int offset = snprintf(pcWriteBuffer, xWriteBufferLen,
"MRobot CLI v2.0\r\n"
"================\r\n"
"Built-in Commands:\r\n");
for (size_t i = 0; i < BUILTIN_CMD_COUNT && offset < (int)xWriteBufferLen - 50; i++) {
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
" %s", builtin_commands[i].pcHelpString);
}
if (ctx.custom_cmd_count > 0) {
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
"\r\nCustom Commands:\r\n");
for (uint8_t i = 0; i < ctx.custom_cmd_count && offset < (int)xWriteBufferLen - 50; i++) {
if (ctx.custom_cmds[i] != NULL) {
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
" %s", ctx.custom_cmds[i]->pcHelpString);
}
}
}
return pdFALSE;
}
/**
* @brief htop - htop
*/
static BaseType_t cmd_htop(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString) {
(void)pcCommandString;
(void)pcWriteBuffer;
(void)xWriteBufferLen;
/* htop 模式在 MRobot_Run 中处理 */
return pdFALSE;
}
/**
* @brief cd -
*/
static BaseType_t cmd_cd(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString) {
const char *param;
BaseType_t param_len;
param = FreeRTOS_CLIGetParameter(pcCommandString, 1, &param_len);
if (param == NULL) {
/* 无参数时切换到根目录 */
strcpy(ctx.current_path, "/");
snprintf(pcWriteBuffer, xWriteBufferLen, "Changed to: %s\r\n", ctx.current_path);
return pdFALSE;
}
/* 安全复制路径参数 */
char path[MROBOT_PATH_MAX_LEN];
size_t copy_len = (size_t)param_len < sizeof(path) - 1 ? (size_t)param_len : sizeof(path) - 1;
strncpy(path, param, copy_len);
path[copy_len] = '\0';
/* 路径解析 */
if (strcmp(path, "/") == 0 || strcmp(path, "..") == 0 || strcmp(path, "~") == 0) {
strcpy(ctx.current_path, "/");
} else if (strcmp(path, "dev") == 0 || strcmp(path, "/dev") == 0) {
strcpy(ctx.current_path, "/dev");
} else if (strcmp(path, "modules") == 0 || strcmp(path, "/modules") == 0) {
strcpy(ctx.current_path, "/modules");
} else {
snprintf(pcWriteBuffer, xWriteBufferLen, "Error: Directory '%s' not found\r\n", path);
return pdFALSE;
}
snprintf(pcWriteBuffer, xWriteBufferLen, "Changed to: %s\r\n", ctx.current_path);
return pdFALSE;
}
/**
* @brief ls -
*/
static BaseType_t cmd_ls(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString) {
(void)pcCommandString;
int offset = 0;
if (strcmp(ctx.current_path, "/") == 0) {
snprintf(pcWriteBuffer, xWriteBufferLen,
"dev/\r\n"
"modules/\r\n");
} else if (strcmp(ctx.current_path, "/dev") == 0) {
offset = snprintf(pcWriteBuffer, xWriteBufferLen,
"Device List (%d devices)\r\n\r\n",
ctx.device_count);
if (ctx.device_count == 0) {
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
" (No devices)\r\n");
} else {
/* 直接列出所有设备 */
for (uint8_t i = 0; i < ctx.device_count && offset < (int)xWriteBufferLen - 50; i++) {
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
" - %s\r\n", ctx.devices[i].name);
}
}
} else if (strcmp(ctx.current_path, "/modules") == 0) {
snprintf(pcWriteBuffer, xWriteBufferLen,
"Module functions not yet implemented\r\n");
}
return pdFALSE;
}
/**
* @brief show -
*/
static BaseType_t cmd_show(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString) {
const char *param;
const char *count_param;
BaseType_t param_len, count_param_len;
/* 使用局部静态变量跟踪多次打印状态 */
static uint32_t print_count = 0;
static uint32_t current_iter = 0;
static char target_device[MROBOT_DEVICE_NAME_LEN] = {0};
/* 首次调用时解析参数 */
if (current_iter == 0) {
/* 检查是否在 /dev 目录 */
if (strcmp(ctx.current_path, "/dev") != 0) {
snprintf(pcWriteBuffer, xWriteBufferLen,
"Error: 'show' command only works in /dev directory\r\n"
"Hint: Use 'cd /dev' to switch to device directory\r\n");
return pdFALSE;
}
param = FreeRTOS_CLIGetParameter(pcCommandString, 1, &param_len);
count_param = FreeRTOS_CLIGetParameter(pcCommandString, 2, &count_param_len);
/* 解析打印次数 */
print_count = 1;
if (count_param != NULL) {
char count_str[16];
size_t copy_len = (size_t)count_param_len < sizeof(count_str) - 1 ?
(size_t)count_param_len : sizeof(count_str) - 1;
strncpy(count_str, count_param, copy_len);
count_str[copy_len] = '\0';
int parsed = atoi(count_str);
if (parsed > 0 && parsed <= 1000) {
print_count = (uint32_t)parsed;
}
}
/* 保存目标设备名称 */
if (param != NULL) {
size_t copy_len = (size_t)param_len < sizeof(target_device) - 1 ?
(size_t)param_len : sizeof(target_device) - 1;
strncpy(target_device, param, copy_len);
target_device[copy_len] = '\0';
} else {
target_device[0] = '\0';
}
}
int offset = 0;
/* 连续打印模式:清屏 */
if (print_count > 1) {
offset = snprintf(pcWriteBuffer, xWriteBufferLen, "%s[%lu/%lu]\r\n",
ANSI_CLEAR_SCREEN,
(unsigned long)(current_iter + 1),
(unsigned long)print_count);
}
if (target_device[0] == '\0') {
/* 显示所有设备 */
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
"=== All Devices ===\r\n\r\n");
for (uint8_t i = 0; i < ctx.device_count && offset < (int)xWriteBufferLen - 100; i++) {
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
"--- %s ---\r\n", ctx.devices[i].name);
if (ctx.devices[i].print_cb != NULL) {
int written = ctx.devices[i].print_cb(ctx.devices[i].data,
pcWriteBuffer + offset,
xWriteBufferLen - offset);
offset += (written > 0) ? written : 0;
} else {
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
" (No print function)\r\n");
}
}
if (ctx.device_count == 0) {
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
" (No devices registered)\r\n");
}
} else {
/* 显示指定设备 */
const MRobot_Device_t *dev = MRobot_FindDevice(target_device);
if (dev == NULL) {
snprintf(pcWriteBuffer, xWriteBufferLen,
"Error: Device '%s' not found\r\n",
target_device);
current_iter = 0;
return pdFALSE;
}
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
"=== %s ===\r\n", dev->name);
if (dev->print_cb != NULL) {
dev->print_cb(dev->data, pcWriteBuffer + offset, xWriteBufferLen - offset);
} else {
snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
" (No print function)\r\n");
}
}
/* 判断是否继续打印 */
current_iter++;
if (current_iter < print_count) {
osDelay(MROBOT_HTOP_REFRESH_MS);
return pdTRUE;
} else {
current_iter = 0;
return pdFALSE;
}
}
/* ============================================================================
* htop
* ========================================================================== */
static void handle_htop_mode(void) {
send_string(ANSI_CLEAR_SCREEN);
send_string("=== MRobot Task Monitor (Press 'q' to exit) ===\r\n\r\n");
/* 获取任务列表 */
char task_buffer[1024];
char display_line[128];
vTaskList(task_buffer);
/* 表头 */
send_string("Task Name State Prio Stack Num\r\n");
send_string("------------------------------------------------\r\n");
/* 解析并格式化任务列表 */
char *line = strtok(task_buffer, "\r\n");
while (line != NULL) {
char name[17] = {0};
char state_char = '?';
int prio = 0, stack = 0, num = 0;
if (sscanf(line, "%16s %c %d %d %d", name, &state_char, &prio, &stack, &num) == 5) {
const char *state_str;
switch (state_char) {
case 'R': state_str = "Running"; break;
case 'B': state_str = "Blocked"; break;
case 'S': state_str = "Suspend"; break;
case 'D': state_str = "Deleted"; break;
case 'X': state_str = "Ready "; break;
default: state_str = "Unknown"; break;
}
snprintf(display_line, sizeof(display_line),
"%-16s %-8s %-4d %-8d %-4d\r\n",
name, state_str, prio, stack, num);
send_string(display_line);
}
line = strtok(NULL, "\r\n");
}
/* 显示系统信息 */
snprintf(display_line, sizeof(display_line),
"------------------------------------------------\r\n"
"System Tick: %lu | Free Heap: %lu bytes\r\n",
(unsigned long)xTaskGetTickCount(),
(unsigned long)xPortGetFreeHeapSize());
send_string(display_line);
/* 检查退出 */
if (ctx.htop_exit) {
ctx.state = MROBOT_STATE_IDLE;
ctx.htop_exit = false;
send_string(ANSI_CLEAR_SCREEN);
send_prompt();
}
osDelay(MROBOT_HTOP_REFRESH_MS);
}
/* ========================================================================== */
/* 公共 API 实现 */
/* ========================================================================== */
void MRobot_Init(void) {
if (ctx.initialized) return;
/* 创建互斥锁 */
ctx.mutex = xSemaphoreCreateMutex();
/* 初始化状态(保留已注册的设备) */
// 注意:不清除 devices 和 device_count因为其他任务可能已经注册了设备
ctx.custom_cmd_count = 0;
ctx.state = MROBOT_STATE_IDLE;
strcpy(ctx.current_path, "/");
ctx.cmd_index = 0;
ctx.cmd_ready = false;
ctx.tx_complete = true;
ctx.htop_exit = false;
/* 注册内置命令 */
for (size_t i = 0; i < BUILTIN_CMD_COUNT; i++) {
FreeRTOS_CLIRegisterCommand(&builtin_commands[i]);
}
/* 注册 UART 回调 */
BSP_UART_RegisterCallback(BSP_UART_MROBOT, BSP_UART_RX_CPLT_CB, uart_rx_callback);
BSP_UART_RegisterCallback(BSP_UART_MROBOT, BSP_UART_TX_CPLT_CB, uart_tx_callback);
/* 启动 UART 接收 */
BSP_UART_Receive(BSP_UART_MROBOT, &ctx.uart_rx_char, 1, false);
/* 等待用户按下回车 */
while (ctx.uart_rx_char != '\r' && ctx.uart_rx_char != '\n') {
osDelay(10);
}
/* 发送欢迎消息和提示符 */
send_string(CLI_WELCOME_MESSAGE);
send_prompt();
ctx.initialized = true;
}
void MRobot_DeInit(void) {
if (!ctx.initialized) return;
/* 释放自定义命令内存 */
for (uint8_t i = 0; i < ctx.custom_cmd_count; i++) {
if (ctx.custom_cmds[i] != NULL) {
BSP_Free(ctx.custom_cmds[i]);
ctx.custom_cmds[i] = NULL;
}
}
/* 删除互斥锁 */
if (ctx.mutex != NULL) {
vSemaphoreDelete(ctx.mutex);
ctx.mutex = NULL;
}
ctx.initialized = false;
}
MRobot_State_t MRobot_GetState(void) {
return ctx.state;
}
MRobot_Error_t MRobot_RegisterDevice(const char *name, void *data, MRobot_PrintCallback_t print_cb) {
if (name == NULL || data == NULL) {
return MROBOT_ERR_NULL_PTR;
}
if (ctx.device_count >= MROBOT_MAX_DEVICES) {
return MROBOT_ERR_FULL;
}
/* 检查重名 */
for (uint8_t i = 0; i < ctx.device_count; i++) {
if (strcmp(ctx.devices[i].name, name) == 0) {
return MROBOT_ERR_INVALID_ARG; /* 设备名已存在 */
}
}
/* 线程安全写入 */
if (ctx.mutex != NULL) {
xSemaphoreTake(ctx.mutex, portMAX_DELAY);
}
strncpy(ctx.devices[ctx.device_count].name, name, MROBOT_DEVICE_NAME_LEN - 1);
ctx.devices[ctx.device_count].name[MROBOT_DEVICE_NAME_LEN - 1] = '\0';
ctx.devices[ctx.device_count].data = data;
ctx.devices[ctx.device_count].print_cb = print_cb;
ctx.device_count++;
if (ctx.mutex != NULL) {
xSemaphoreGive(ctx.mutex);
}
return MROBOT_OK;
}
MRobot_Error_t MRobot_UnregisterDevice(const char *name) {
if (name == NULL) {
return MROBOT_ERR_NULL_PTR;
}
if (ctx.mutex != NULL) {
xSemaphoreTake(ctx.mutex, portMAX_DELAY);
}
for (uint8_t i = 0; i < ctx.device_count; i++) {
if (strcmp(ctx.devices[i].name, name) == 0) {
/* 移动后续设备 */
for (uint8_t j = i; j < ctx.device_count - 1; j++) {
ctx.devices[j] = ctx.devices[j + 1];
}
ctx.device_count--;
if (ctx.mutex != NULL) {
xSemaphoreGive(ctx.mutex);
}
return MROBOT_OK;
}
}
if (ctx.mutex != NULL) {
xSemaphoreGive(ctx.mutex);
}
return MROBOT_ERR_NOT_FOUND;
}
MRobot_Error_t MRobot_RegisterCommand(const char *command, const char *help_text,
MRobot_CommandCallback_t callback, int8_t param_count) {
if (command == NULL || help_text == NULL || callback == NULL) {
return MROBOT_ERR_NULL_PTR;
}
if (ctx.custom_cmd_count >= MROBOT_MAX_CUSTOM_COMMANDS) {
return MROBOT_ERR_FULL;
}
/* 动态分配命令结构体 */
CLI_Command_Definition_t *cmd_def = BSP_Malloc(sizeof(CLI_Command_Definition_t));
if (cmd_def == NULL) {
return MROBOT_ERR_ALLOC;
}
/* 初始化命令定义 */
*(const char **)&cmd_def->pcCommand = command;
*(const char **)&cmd_def->pcHelpString = help_text;
*(pdCOMMAND_LINE_CALLBACK *)&cmd_def->pxCommandInterpreter = (pdCOMMAND_LINE_CALLBACK)callback;
cmd_def->cExpectedNumberOfParameters = param_count;
/* 注册到 FreeRTOS CLI */
FreeRTOS_CLIRegisterCommand(cmd_def);
ctx.custom_cmds[ctx.custom_cmd_count] = cmd_def;
ctx.custom_cmd_count++;
return MROBOT_OK;
}
uint8_t MRobot_GetDeviceCount(void) {
return ctx.device_count;
}
const MRobot_Device_t *MRobot_FindDevice(const char *name) {
if (name == NULL) return NULL;
for (uint8_t i = 0; i < ctx.device_count; i++) {
if (strcmp(ctx.devices[i].name, name) == 0) {
return &ctx.devices[i];
}
}
return NULL;
}
int MRobot_Printf(const char *fmt, ...) {
if (fmt == NULL || !ctx.initialized) return -1;
char buffer[MROBOT_OUTPUT_BUFFER_SIZE];
va_list args;
va_start(args, fmt);
int len = format_float_va(buffer, sizeof(buffer), fmt, args);
va_end(args);
if (len > 0) {
send_string(buffer);
}
return len;
}
/**
* @brief va_list
*/
static int format_float_va(char *buf, size_t size, const char *fmt, va_list args) {
if (buf == NULL || size == 0 || fmt == NULL) return 0;
char *buf_ptr = buf;
size_t buf_remain = size - 1;
const char *p = fmt;
while (*p && buf_remain > 0) {
if (*p != '%') {
*buf_ptr++ = *p++;
buf_remain--;
continue;
}
p++; /* 跳过 '%' */
/* 处理 %% */
if (*p == '%') {
*buf_ptr++ = '%';
buf_remain--;
p++;
continue;
}
/* 解析精度 %.Nf */
int precision = 2; /* 默认精度 */
if (*p == '.') {
p++;
precision = 0;
while (*p >= '0' && *p <= '9') {
precision = precision * 10 + (*p - '0');
p++;
}
if (precision > 6) precision = 6;
}
int written = 0;
switch (*p) {
case 'f': { /* 浮点数 */
double val = va_arg(args, double);
written = MRobot_FormatFloat(buf_ptr, buf_remain, (float)val, precision);
break;
}
case 'd':
case 'i': {
int val = va_arg(args, int);
written = snprintf(buf_ptr, buf_remain, "%d", val);
break;
}
case 'u': {
unsigned int val = va_arg(args, unsigned int);
written = snprintf(buf_ptr, buf_remain, "%u", val);
break;
}
case 'x': {
unsigned int val = va_arg(args, unsigned int);
written = snprintf(buf_ptr, buf_remain, "%x", val);
break;
}
case 'X': {
unsigned int val = va_arg(args, unsigned int);
written = snprintf(buf_ptr, buf_remain, "%X", val);
break;
}
case 's': {
const char *str = va_arg(args, const char *);
if (str == NULL) str = "(null)";
written = snprintf(buf_ptr, buf_remain, "%s", str);
break;
}
case 'c': {
int ch = va_arg(args, int);
*buf_ptr = (char)ch;
written = 1;
break;
}
case 'l': {
p++;
if (*p == 'd' || *p == 'i') {
long val = va_arg(args, long);
written = snprintf(buf_ptr, buf_remain, "%ld", val);
} else if (*p == 'u') {
unsigned long val = va_arg(args, unsigned long);
written = snprintf(buf_ptr, buf_remain, "%lu", val);
} else if (*p == 'x' || *p == 'X') {
unsigned long val = va_arg(args, unsigned long);
written = snprintf(buf_ptr, buf_remain, *p == 'x' ? "%lx" : "%lX", val);
} else {
p--;
}
break;
}
default: {
*buf_ptr++ = '%';
buf_remain--;
if (buf_remain > 0) {
*buf_ptr++ = *p;
buf_remain--;
}
written = 0;
break;
}
}
if (written > 0) {
buf_ptr += written;
buf_remain -= (size_t)written;
}
p++;
}
*buf_ptr = '\0';
return (int)(buf_ptr - buf);
}
int MRobot_Snprintf(char *buf, size_t size, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
int len = format_float_va(buf, size, fmt, args);
va_end(args);
return len;
}
int MRobot_FormatFloat(char *buf, size_t size, float val, int precision) {
if (buf == NULL || size == 0) return 0;
int offset = 0;
/* 处理负数 */
if (val < 0) {
if (offset < (int)size - 1) buf[offset++] = '-';
val = -val;
}
/* 限制精度范围 */
if (precision < 0) precision = 0;
if (precision > 6) precision = 6;
/* 计算乘数 */
int multiplier = 1;
for (int i = 0; i < precision; i++) multiplier *= 10;
int int_part = (int)val;
int frac_part = (int)((val - int_part) * multiplier + 0.5f);
/* 处理进位 */
if (frac_part >= multiplier) {
int_part++;
frac_part -= multiplier;
}
/* 格式化输出 */
int written;
if (precision > 0) {
written = snprintf(buf + offset, size - offset, "%d.%0*d", int_part, precision, frac_part);
} else {
written = snprintf(buf + offset, size - offset, "%d", int_part);
}
return (written > 0) ? (offset + written) : offset;
}
void MRobot_Run(void) {
if (!ctx.initialized) return;
/* htop 模式 */
if (ctx.state == MROBOT_STATE_HTOP) {
handle_htop_mode();
return;
}
/* 处理命令 */
if (ctx.cmd_ready) {
ctx.state = MROBOT_STATE_PROCESSING;
/* 检查是否是 htop 命令 */
if (strcmp((char *)ctx.cmd_buffer, "htop") == 0) {
ctx.state = MROBOT_STATE_HTOP;
ctx.htop_exit = false;
} else {
/* 处理其他命令 */
BaseType_t more;
do {
ctx.output_buffer[0] = '\0';
more = FreeRTOS_CLIProcessCommand((char *)ctx.cmd_buffer,
ctx.output_buffer,
sizeof(ctx.output_buffer));
if (ctx.output_buffer[0] != '\0') {
send_string(ctx.output_buffer);
}
} while (more != pdFALSE);
send_prompt();
ctx.state = MROBOT_STATE_IDLE;
}
ctx.cmd_index = 0;
ctx.cmd_ready = false;
}
osDelay(10);
}

View File

@ -1,313 +0,0 @@
/**
* @file mrobot.h
* @brief MRobot CLI - FreeRTOS CLI
*
* :
* - IMU
* - Unix cd, ls, pwd
* - htop
* -
* - 线
*
* @example IMU
* @code
* // 1. 定义 IMU 数据结构
* typedef struct {
* bool online;
* float accl[3];
* float gyro[3];
* float euler[3]; // roll, pitch, yaw (deg)
* float temp;
* } MyIMU_t;
*
* MyIMU_t my_imu;
*
* // 2. 实现打印回调
* static int print_imu(const void *data, char *buf, size_t size) {
* const MyIMU_t *imu = (const MyIMU_t *)data;
* return MRobot_Snprintf(buf, size,
* " Status: %s\r\n"
* " Accel : X=%.3f Y=%.3f Z=%.3f\r\n"
* " Euler : R=%.2f P=%.2f Y=%.2f\r\n"
* " Temp : %.1f C\r\n",
* imu->online ? "Online" : "Offline",
* imu->accl[0], imu->accl[1], imu->accl[2],
* imu->euler[0], imu->euler[1], imu->euler[2],
* imu->temp);
* }
*
* // 3. 注册设备
* MRobot_RegisterDevice("imu", &my_imu, print_imu);
* @endcode
*
* @example
* @code
* typedef struct {
* bool online;
* float angle; // deg
* float speed; // RPM
* float current; // A
* } MyMotor_t;
*
* MyMotor_t motor[4];
*
* static int print_motor(const void *data, char *buf, size_t size) {
* const MyMotor_t *m = (const MyMotor_t *)data;
* return MRobot_Snprintf(buf, size,
* " Status : %s\r\n"
* " Angle : %.2f deg\r\n"
* " Speed : %.1f RPM\r\n"
* " Current: %.3f A\r\n",
* m->online ? "Online" : "Offline",
* m->angle, m->speed, m->current);
* }
*
* // 注册 4 个电机
* MRobot_RegisterDevice("motor0", &motor[0], print_motor);
* MRobot_RegisterDevice("motor1", &motor[1], print_motor);
* MRobot_RegisterDevice("motor2", &motor[2], print_motor);
* MRobot_RegisterDevice("motor3", &motor[3], print_motor);
* @endcode
*
* @example
* @code
* // 校准数据
* static float gyro_offset[3] = {0};
*
* // 命令回调: cali gyro / cali accel / cali save
* static long cmd_cali(char *buf, size_t size, const char *cmd) {
* const char *param = FreeRTOS_CLIGetParameter(cmd, 1, NULL);
*
* if (param == NULL) {
* return MRobot_Snprintf(buf, size, "Usage: cali <gyro|accel|save>\r\n");
* }
* if (strncmp(param, "gyro", 4) == 0) {
* // 采集 1000 次陀螺仪数据求平均
* MRobot_Snprintf(buf, size, "Calibrating gyro... keep IMU still!\r\n");
* // ... 校准逻辑 ...
* return 0;
* }
* if (strncmp(param, "save", 4) == 0) {
* // 保存到 Flash
* MRobot_Snprintf(buf, size, "Calibration saved to flash.\r\n");
* return 0;
* }
* return MRobot_Snprintf(buf, size, "Unknown: %s\r\n", param);
* }
*
* // 注册命令
* MRobot_RegisterCommand("cali", "cali <gyro|accel|save>: IMU calibration\r\n", cmd_cali, -1);
* @endcode
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "bsp/uart.h"
/* Configuration ------------------------------------------------------------ */
/* 可在编译时通过 -D 选项覆盖这些默认值 */
#ifndef MROBOT_MAX_DEVICES
#define MROBOT_MAX_DEVICES 64 /* 最大设备数 */
#endif
#ifndef MROBOT_MAX_CUSTOM_COMMANDS
#define MROBOT_MAX_CUSTOM_COMMANDS 16 /* 最大自定义命令数 */
#endif
#ifndef MROBOT_CMD_BUFFER_SIZE
#define MROBOT_CMD_BUFFER_SIZE 128 /* 命令缓冲区大小 */
#endif
#ifndef MROBOT_OUTPUT_BUFFER_SIZE
#define MROBOT_OUTPUT_BUFFER_SIZE 512 /* 输出缓冲区大小 */
#endif
#ifndef MROBOT_DEVICE_NAME_LEN
#define MROBOT_DEVICE_NAME_LEN 32 /* 设备名最大长度 */
#endif
#ifndef MROBOT_PATH_MAX_LEN
#define MROBOT_PATH_MAX_LEN 64 /* 路径最大长度 */
#endif
#ifndef MROBOT_HTOP_REFRESH_MS
#define MROBOT_HTOP_REFRESH_MS 200 /* htop 刷新间隔 (ms) */
#endif
#ifndef MROBOT_USER_NAME
#define MROBOT_USER_NAME "root" /* CLI 用户名 */
#endif
#ifndef MROBOT_HOST_NAME
#define MROBOT_HOST_NAME "MRobot" /* CLI 主机名 */
#endif
/* Error codes -------------------------------------------------------------- */
typedef enum {
MROBOT_OK = 0, /* 成功 */
MROBOT_ERR_FULL = -1, /* 容量已满 */
MROBOT_ERR_NULL_PTR = -2, /* 空指针 */
MROBOT_ERR_INVALID_ARG = -3, /* 无效参数 */
MROBOT_ERR_NOT_FOUND = -4, /* 未找到 */
MROBOT_ERR_ALLOC = -5, /* 内存分配失败 */
MROBOT_ERR_BUSY = -6, /* 设备忙 */
MROBOT_ERR_NOT_INIT = -7, /* 未初始化 */
} MRobot_Error_t;
/* CLI 运行状态 */
typedef enum {
MROBOT_STATE_IDLE, /* 空闲状态,等待输入 */
MROBOT_STATE_HTOP, /* htop 模式 */
MROBOT_STATE_PROCESSING, /* 正在处理命令 */
} MRobot_State_t;
/* Callback types ----------------------------------------------------------- */
/**
* @brief
* @param device_data
* @param buffer
* @param buffer_size
* @return
* @note
*/
typedef int (*MRobot_PrintCallback_t)(const void *device_data, char *buffer, size_t buffer_size);
/**
* @brief FreeRTOS CLI
*/
typedef long (*MRobot_CommandCallback_t)(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString);
/* Device structure --------------------------------------------------------- */
typedef struct {
char name[MROBOT_DEVICE_NAME_LEN]; /* 设备名称 */
void *data; /* 用户设备数据指针 */
MRobot_PrintCallback_t print_cb; /* 用户打印回调函数 */
} MRobot_Device_t;
/* Public API --------------------------------------------------------------- */
/**
* @brief MRobot CLI
* @note FreeRTOS
*/
void MRobot_Init(void);
/**
* @brief MRobot CLI
*/
void MRobot_DeInit(void);
/**
* @brief CLI
* @return MRobot_State_t
*/
MRobot_State_t MRobot_GetState(void);
/**
* @brief MRobot
* @param name MROBOT_DEVICE_NAME_LEN-1
* @param data NULL
* @param print_cb NULL show
* @return MRobot_Error_t
*/
MRobot_Error_t MRobot_RegisterDevice(const char *name, void *data, MRobot_PrintCallback_t print_cb);
/**
* @brief
* @param name
* @return MRobot_Error_t
*/
MRobot_Error_t MRobot_UnregisterDevice(const char *name);
/**
* @brief
* @param command
* @param help_text
* @param callback
* @param param_count -1
* @return MRobot_Error_t
*/
MRobot_Error_t MRobot_RegisterCommand(const char *command, const char *help_text,
MRobot_CommandCallback_t callback, int8_t param_count);
/**
* @brief
* @return
*/
uint8_t MRobot_GetDeviceCount(void);
/**
* @brief
* @param name
* @return NULL
*/
const MRobot_Device_t *MRobot_FindDevice(const char *name);
/**
* @brief MRobot CLI
* @note 10ms
*/
void MRobot_Run(void);
/**
* @brief CLI 线
* @param fmt
* @param ...
* @return
*
* @note :
* - %d, %i, %u, %x, %X, %ld, %lu, %lx :
* - %s, %c : /
* - %f : (2)
* - %.Nf : (N位小数, N=0-6)
* - %% :
*
* @example
* MRobot_Printf("Euler: R=%.2f P=%.2f Y=%.2f\\r\\n", roll, pitch, yaw);
*/
int MRobot_Printf(const char *fmt, ...);
/**
* @brief
* @note MRobot_Printf
*
* @example
* static int print_imu(const void *data, char *buf, size_t size) {
* const BMI088_t *imu = (const BMI088_t *)data;
* return MRobot_Snprintf(buf, size,
* " Accel: X=%.3f Y=%.3f Z=%.3f\\r\\n",
* imu->accl.x, imu->accl.y, imu->accl.z);
* }
*/
int MRobot_Snprintf(char *buf, size_t size, const char *fmt, ...);
/* Utility functions -------------------------------------------------------- */
/**
* @brief %f
* @param buf
* @param size
* @param val
* @param precision (0-6)
* @return
*
* @example
* char buf[16];
* MRobot_FormatFloat(buf, sizeof(buf), 3.14159f, 2); // "3.14"
* MRobot_FormatFloat(buf, sizeof(buf), -0.001f, 4); // "-0.0010"
*/
int MRobot_FormatFloat(char *buf, size_t size, float val, int precision);
#ifdef __cplusplus
}
#endif

View File

@ -1,700 +0,0 @@
#MicroXplorer Configuration settings - do not modify
ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_4
ADC1.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_19
ADC1.ClockPrescaler=ADC_CLOCK_ASYNC_DIV64
ADC1.ContinuousConvMode=ENABLE
ADC1.ConversionDataManagement=ADC_CONVERSIONDATA_DMA_CIRCULAR
ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,OffsetSignedSaturation-0\#ChannelRegularConversion,NbrOfConversionFlag,master,ClockPrescaler,ContinuousConvMode,ConversionDataManagement,Rank-1\#ChannelRegularConversion,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,OffsetNumber-1\#ChannelRegularConversion,OffsetSignedSaturation-1\#ChannelRegularConversion,NbrOfConversion
ADC1.NbrOfConversion=2
ADC1.NbrOfConversionFlag=1
ADC1.OffsetNumber-0\#ChannelRegularConversion=ADC_OFFSET_NONE
ADC1.OffsetNumber-1\#ChannelRegularConversion=ADC_OFFSET_NONE
ADC1.OffsetSignedSaturation-0\#ChannelRegularConversion=DISABLE
ADC1.OffsetSignedSaturation-1\#ChannelRegularConversion=DISABLE
ADC1.Rank-0\#ChannelRegularConversion=1
ADC1.Rank-1\#ChannelRegularConversion=2
ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_32CYCLES_5
ADC1.SamplingTime-1\#ChannelRegularConversion=ADC_SAMPLETIME_32CYCLES_5
ADC1.master=1
CAD.formats=
CAD.pinconfig=
CAD.provider=
CORTEX_M7.BaseAddress-Cortex_Memory_Protection_Unit_Region0_Settings=0x24000000
CORTEX_M7.CPU_DCache=Disabled
CORTEX_M7.CPU_ICache=Disabled
CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_ENABLE
CORTEX_M7.IPParameters=CPU_DCache,CPU_ICache,MPU_Control,Enable-Cortex_Memory_Protection_Unit_Region0_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region0_Settings,Size-Cortex_Memory_Protection_Unit_Region0_Settings,TypeExtField-Cortex_Memory_Protection_Unit_Region0_Settings,IsCacheable-Cortex_Memory_Protection_Unit_Region0_Settings,IsBufferable-Cortex_Memory_Protection_Unit_Region0_Settings
CORTEX_M7.IsBufferable-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_ACCESS_BUFFERABLE
CORTEX_M7.IsCacheable-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_ACCESS_CACHEABLE
CORTEX_M7.MPU_Control=__NULL
CORTEX_M7.Size-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_SIZE_512B
CORTEX_M7.TypeExtField-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_TEX_LEVEL1
Dma.ADC1.0.Direction=DMA_PERIPH_TO_MEMORY
Dma.ADC1.0.EventEnable=DISABLE
Dma.ADC1.0.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.ADC1.0.Instance=DMA1_Stream0
Dma.ADC1.0.MemDataAlignment=DMA_MDATAALIGN_HALFWORD
Dma.ADC1.0.MemInc=DMA_MINC_ENABLE
Dma.ADC1.0.Mode=DMA_CIRCULAR
Dma.ADC1.0.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD
Dma.ADC1.0.PeriphInc=DMA_PINC_DISABLE
Dma.ADC1.0.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.ADC1.0.Priority=DMA_PRIORITY_LOW
Dma.ADC1.0.RequestNumber=1
Dma.ADC1.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.ADC1.0.SignalID=NONE
Dma.ADC1.0.SyncEnable=DISABLE
Dma.ADC1.0.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.ADC1.0.SyncRequestNumber=1
Dma.ADC1.0.SyncSignalID=NONE
Dma.Request0=ADC1
Dma.Request1=SPI2_RX
Dma.Request2=SPI2_TX
Dma.Request3=UART5_RX
Dma.RequestsNb=4
Dma.SPI2_RX.1.Direction=DMA_PERIPH_TO_MEMORY
Dma.SPI2_RX.1.EventEnable=DISABLE
Dma.SPI2_RX.1.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.SPI2_RX.1.Instance=DMA1_Stream1
Dma.SPI2_RX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.SPI2_RX.1.MemInc=DMA_MINC_ENABLE
Dma.SPI2_RX.1.Mode=DMA_NORMAL
Dma.SPI2_RX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.SPI2_RX.1.PeriphInc=DMA_PINC_DISABLE
Dma.SPI2_RX.1.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.SPI2_RX.1.Priority=DMA_PRIORITY_LOW
Dma.SPI2_RX.1.RequestNumber=1
Dma.SPI2_RX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.SPI2_RX.1.SignalID=NONE
Dma.SPI2_RX.1.SyncEnable=DISABLE
Dma.SPI2_RX.1.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.SPI2_RX.1.SyncRequestNumber=1
Dma.SPI2_RX.1.SyncSignalID=NONE
Dma.SPI2_TX.2.Direction=DMA_MEMORY_TO_PERIPH
Dma.SPI2_TX.2.EventEnable=DISABLE
Dma.SPI2_TX.2.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.SPI2_TX.2.Instance=DMA1_Stream2
Dma.SPI2_TX.2.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.SPI2_TX.2.MemInc=DMA_MINC_ENABLE
Dma.SPI2_TX.2.Mode=DMA_NORMAL
Dma.SPI2_TX.2.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.SPI2_TX.2.PeriphInc=DMA_PINC_DISABLE
Dma.SPI2_TX.2.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.SPI2_TX.2.Priority=DMA_PRIORITY_LOW
Dma.SPI2_TX.2.RequestNumber=1
Dma.SPI2_TX.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.SPI2_TX.2.SignalID=NONE
Dma.SPI2_TX.2.SyncEnable=DISABLE
Dma.SPI2_TX.2.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.SPI2_TX.2.SyncRequestNumber=1
Dma.SPI2_TX.2.SyncSignalID=NONE
Dma.UART5_RX.3.Direction=DMA_PERIPH_TO_MEMORY
Dma.UART5_RX.3.EventEnable=DISABLE
Dma.UART5_RX.3.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.UART5_RX.3.Instance=DMA1_Stream3
Dma.UART5_RX.3.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.UART5_RX.3.MemInc=DMA_MINC_ENABLE
Dma.UART5_RX.3.Mode=DMA_NORMAL
Dma.UART5_RX.3.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.UART5_RX.3.PeriphInc=DMA_PINC_DISABLE
Dma.UART5_RX.3.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.UART5_RX.3.Priority=DMA_PRIORITY_LOW
Dma.UART5_RX.3.RequestNumber=1
Dma.UART5_RX.3.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.UART5_RX.3.SignalID=NONE
Dma.UART5_RX.3.SyncEnable=DISABLE
Dma.UART5_RX.3.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.UART5_RX.3.SyncRequestNumber=1
Dma.UART5_RX.3.SyncSignalID=NONE
FDCAN1.AutoRetransmission=ENABLE
FDCAN1.CalculateBaudRateNominal=1000000
FDCAN1.CalculateTimeBitNominal=1000
FDCAN1.CalculateTimeQuantumNominal=200.0
FDCAN1.IPParameters=CalculateTimeQuantumNominal,CalculateTimeBitNominal,CalculateBaudRateNominal,RxFifo0ElmtsNbr,TxFifoQueueElmtsNbr,NominalPrescaler,StdFiltersNbr,NominalTimeSeg1,AutoRetransmission
FDCAN1.NominalPrescaler=24
FDCAN1.NominalTimeSeg1=3
FDCAN1.RxFifo0ElmtsNbr=32
FDCAN1.StdFiltersNbr=1
FDCAN1.TxFifoQueueElmtsNbr=32
FDCAN2.AutoRetransmission=ENABLE
FDCAN2.CalculateBaudRateNominal=1000000
FDCAN2.CalculateTimeBitNominal=1000
FDCAN2.CalculateTimeQuantumNominal=200.0
FDCAN2.IPParameters=CalculateTimeQuantumNominal,CalculateTimeBitNominal,CalculateBaudRateNominal,MessageRAMOffset,RxFifo0ElmtsNbr,TxFifoQueueElmtsNbr,NominalPrescaler,StdFiltersNbr,NominalTimeSeg1,AutoRetransmission,RxFifo1ElmtsNbr
FDCAN2.MessageRAMOffset=0x406
FDCAN2.NominalPrescaler=24
FDCAN2.NominalTimeSeg1=3
FDCAN2.RxFifo0ElmtsNbr=32
FDCAN2.RxFifo1ElmtsNbr=32
FDCAN2.StdFiltersNbr=1
FDCAN2.TxFifoQueueElmtsNbr=32
FDCAN3.AutoRetransmission=ENABLE
FDCAN3.CalculateBaudRateNominal=1000000
FDCAN3.CalculateTimeBitNominal=1000
FDCAN3.CalculateTimeQuantumNominal=200.0
FDCAN3.ExtFiltersNbr=1
FDCAN3.IPParameters=CalculateTimeQuantumNominal,CalculateTimeBitNominal,CalculateBaudRateNominal,MessageRAMOffset,RxFifo0ElmtsNbr,TxFifoQueueElmtsNbr,NominalPrescaler,StdFiltersNbr,NominalTimeSeg1,AutoRetransmission,RxFifo1ElmtsNbr,ExtFiltersNbr
FDCAN3.MessageRAMOffset=0x812
FDCAN3.NominalPrescaler=24
FDCAN3.NominalTimeSeg1=3
FDCAN3.RxFifo0ElmtsNbr=32
FDCAN3.RxFifo1ElmtsNbr=32
FDCAN3.StdFiltersNbr=1
FDCAN3.TxFifoQueueElmtsNbr=32
FREERTOS.IPParameters=Tasks01,configTOTAL_HEAP_SIZE
FREERTOS.Tasks01=defaultTask,24,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL
FREERTOS.configTOTAL_HEAP_SIZE=0x10000
File.Version=6
GPIO.groupedBy=Group By Peripherals
KeepUserPlacement=false
MMTAppRegionsCount=0
MMTConfigApplied=false
Mcu.CPN=STM32H723VGT6
Mcu.Family=STM32H7
Mcu.IP0=ADC1
Mcu.IP1=CORTEX_M7
Mcu.IP10=OCTOSPI1
Mcu.IP11=RCC
Mcu.IP12=SPI1
Mcu.IP13=SPI2
Mcu.IP14=SYS
Mcu.IP15=TIM1
Mcu.IP16=TIM2
Mcu.IP17=TIM3
Mcu.IP18=TIM12
Mcu.IP19=UART5
Mcu.IP2=DEBUG
Mcu.IP20=UART7
Mcu.IP21=USART1
Mcu.IP22=USART2
Mcu.IP23=USART3
Mcu.IP24=USART10
Mcu.IP25=USB_OTG_HS
Mcu.IP3=DMA
Mcu.IP4=FDCAN1
Mcu.IP5=FDCAN2
Mcu.IP6=FDCAN3
Mcu.IP7=FREERTOS
Mcu.IP8=MEMORYMAP
Mcu.IP9=NVIC
Mcu.IPNb=26
Mcu.Name=STM32H723VGTx
Mcu.Package=LQFP100
Mcu.Pin0=PE2
Mcu.Pin1=PE3
Mcu.Pin10=PC3_C
Mcu.Pin11=PA0
Mcu.Pin12=PA1
Mcu.Pin13=PA2
Mcu.Pin14=PA3
Mcu.Pin15=PA5
Mcu.Pin16=PA7
Mcu.Pin17=PC4
Mcu.Pin18=PC5
Mcu.Pin19=PB0
Mcu.Pin2=PC13
Mcu.Pin20=PB1
Mcu.Pin21=PB2
Mcu.Pin22=PE7
Mcu.Pin23=PE8
Mcu.Pin24=PE9
Mcu.Pin25=PE10
Mcu.Pin26=PE11
Mcu.Pin27=PE12
Mcu.Pin28=PE13
Mcu.Pin29=PE15
Mcu.Pin3=PC14-OSC32_IN
Mcu.Pin30=PB10
Mcu.Pin31=PB11
Mcu.Pin32=PB12
Mcu.Pin33=PB13
Mcu.Pin34=PB14
Mcu.Pin35=PB15
Mcu.Pin36=PD8
Mcu.Pin37=PD9
Mcu.Pin38=PD10
Mcu.Pin39=PD11
Mcu.Pin4=PC15-OSC32_OUT
Mcu.Pin40=PD12
Mcu.Pin41=PD13
Mcu.Pin42=PA8
Mcu.Pin43=PA9
Mcu.Pin44=PA10
Mcu.Pin45=PA11
Mcu.Pin46=PA12
Mcu.Pin47=PA13(JTMS/SWDIO)
Mcu.Pin48=PA14(JTCK/SWCLK)
Mcu.Pin49=PA15(JTDI)
Mcu.Pin5=PH0-OSC_IN
Mcu.Pin50=PC12
Mcu.Pin51=PD0
Mcu.Pin52=PD1
Mcu.Pin53=PD2
Mcu.Pin54=PD4
Mcu.Pin55=PD5
Mcu.Pin56=PD6
Mcu.Pin57=PD7
Mcu.Pin58=PB3(JTDO/TRACESWO)
Mcu.Pin59=PB5
Mcu.Pin6=PH1-OSC_OUT
Mcu.Pin60=PB6
Mcu.Pin61=VP_FREERTOS_VS_CMSIS_V2
Mcu.Pin62=VP_OCTOSPI1_VS_octo
Mcu.Pin63=VP_SYS_VS_tim23
Mcu.Pin64=VP_MEMORYMAP_VS_MEMORYMAP
Mcu.Pin7=PC0
Mcu.Pin8=PC1
Mcu.Pin9=PC2_C
Mcu.PinsNb=65
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32H723VGTx
MxCube.Version=6.15.0
MxDb.Version=DB.6.0.150
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.DMA1_Stream0_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream1_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream3_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.EXTI15_10_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN1_IT0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN1_IT1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN2_IT0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN2_IT1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN3_IT0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN3_IT1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SPI2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false
NVIC.SavedPendsvIrqHandlerGenerated=true
NVIC.SavedSvcallIrqHandlerGenerated=true
NVIC.SavedSystickIrqHandlerGenerated=true
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:true\:false
NVIC.TIM23_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:true\:true
NVIC.TimeBase=TIM23_IRQn
NVIC.TimeBaseIP=TIM23
NVIC.UART5_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.UART7_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.USART10_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.USART1_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.USART2_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.USART3_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
PA0.Locked=true
PA0.Signal=S_TIM2_CH1_ETR
PA1.Locked=true
PA1.Mode=OCTOSPI1_IOL_Port1L
PA1.Signal=OCTOSPIM_P1_IO3
PA10.Locked=true
PA10.Mode=Asynchronous
PA10.Signal=USART1_RX
PA11.Mode=Device_Only_FS
PA11.Signal=USB_OTG_HS_DM
PA12.Mode=Device_Only_FS
PA12.Signal=USB_OTG_HS_DP
PA13(JTMS/SWDIO).Locked=true
PA13(JTMS/SWDIO).Mode=Serial_Wire
PA13(JTMS/SWDIO).Signal=DEBUG_JTMS-SWDIO
PA14(JTCK/SWCLK).Locked=true
PA14(JTCK/SWCLK).Mode=Serial_Wire
PA14(JTCK/SWCLK).Signal=DEBUG_JTCK-SWCLK
PA15(JTDI).Locked=true
PA15(JTDI).Signal=GPIO_Input
PA2.Locked=true
PA2.Signal=S_TIM2_CH3
PA3.Locked=true
PA3.Mode=OCTOSPI1_IOL_Port1L
PA3.Signal=OCTOSPIM_P1_IO2
PA5.Locked=true
PA5.Signal=ADCx_INP19
PA7.GPIOParameters=GPIO_Label
PA7.GPIO_Label=WS2812
PA7.Locked=true
PA7.Signal=S_TIM3_CH2
PA8.Locked=true
PA8.Mode=Clock-out-1
PA8.Signal=RCC_MCO_1
PA9.Locked=true
PA9.Mode=Asynchronous
PA9.Signal=USART1_TX
PB0.Locked=true
PB0.Mode=OCTOSPI1_IOL_Port1L
PB0.Signal=OCTOSPIM_P1_IO1
PB1.GPIOParameters=GPIO_Label
PB1.GPIO_Label=IMU_HEAT
PB1.Locked=true
PB1.Signal=S_TIM3_CH4
PB10.GPIOParameters=GPIO_Label
PB10.GPIO_Label=LCD_BLK
PB10.Locked=true
PB10.Signal=GPIO_Output
PB11.GPIOParameters=GPIO_Label
PB11.GPIO_Label=LCD_RES
PB11.Locked=true
PB11.Signal=GPIO_Output
PB12.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
PB12.GPIO_Label=DCMI_REST
PB12.GPIO_PuPd=GPIO_PULLUP
PB12.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PB12.Locked=true
PB12.PinState=GPIO_PIN_SET
PB12.Signal=GPIO_Output
PB13.GPIOParameters=GPIO_Speed
PB13.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PB13.Locked=true
PB13.Mode=Full_Duplex_Master
PB13.Signal=SPI2_SCK
PB14.Mode=Hardware Flow Control (RS485)
PB14.Signal=USART3_DE
PB15.GPIOParameters=GPIO_Label
PB15.GPIO_Label=BUZZER
PB15.Locked=true
PB15.Signal=S_TIM12_CH2
PB2.Locked=true
PB2.Mode=O1_P1_CLK
PB2.Signal=OCTOSPIM_P1_CLK
PB3(JTDO/TRACESWO).GPIOParameters=GPIO_Speed
PB3(JTDO/TRACESWO).GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PB3(JTDO/TRACESWO).Mode=TX_Only_Simplex_Unidirect_Master
PB3(JTDO/TRACESWO).Signal=SPI1_SCK
PB5.Locked=true
PB5.Mode=FDCAN_Activate
PB5.Signal=FDCAN2_RX
PB6.Locked=true
PB6.Mode=FDCAN_Activate
PB6.Signal=FDCAN2_TX
PC0.GPIOParameters=GPIO_Speed,PinState,GPIO_Label
PC0.GPIO_Label=ACCL_CS
PC0.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PC0.Locked=true
PC0.PinState=GPIO_PIN_SET
PC0.Signal=GPIO_Output
PC1.GPIOParameters=GPIO_Speed
PC1.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PC1.Mode=Full_Duplex_Master
PC1.Signal=SPI2_MOSI
PC12.Mode=Asynchronous
PC12.Signal=UART5_TX
PC13.GPIOParameters=PinState,GPIO_Label
PC13.GPIO_Label=POWER_24V_2
PC13.Locked=true
PC13.PinState=GPIO_PIN_SET
PC13.Signal=GPIO_Output
PC14-OSC32_IN.GPIOParameters=PinState,GPIO_Label
PC14-OSC32_IN.GPIO_Label=POWER_24V_1
PC14-OSC32_IN.Locked=true
PC14-OSC32_IN.PinState=GPIO_PIN_SET
PC14-OSC32_IN.Signal=GPIO_Output
PC15-OSC32_OUT.GPIOParameters=PinState,GPIO_Label
PC15-OSC32_OUT.GPIO_Label=POWER_5V
PC15-OSC32_OUT.Locked=true
PC15-OSC32_OUT.PinState=GPIO_PIN_SET
PC15-OSC32_OUT.Signal=GPIO_Output
PC2_C.GPIOParameters=GPIO_Speed
PC2_C.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PC2_C.Mode=Full_Duplex_Master
PC2_C.Signal=SPI2_MISO
PC3_C.GPIOParameters=GPIO_Speed,PinState,GPIO_Label
PC3_C.GPIO_Label=GYRO_CS
PC3_C.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PC3_C.Locked=true
PC3_C.PinState=GPIO_PIN_SET
PC3_C.Signal=GPIO_Output
PC4.Locked=true
PC4.Signal=ADCx_INP4
PC5.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
PC5.GPIO_Label=DCMI_PWDN
PC5.GPIO_PuPd=GPIO_NOPULL
PC5.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PC5.Locked=true
PC5.PinState=GPIO_PIN_SET
PC5.Signal=GPIO_Output
PD0.Mode=FDCAN_Activate
PD0.Signal=FDCAN1_RX
PD1.Locked=true
PD1.Mode=FDCAN_Activate
PD1.Signal=FDCAN1_TX
PD10.GPIOParameters=GPIO_Label
PD10.GPIO_Label=LCD_DC
PD10.Locked=true
PD10.Signal=GPIO_Output
PD11.Locked=true
PD11.Mode=OCTOSPI1_IOL_Port1L
PD11.Signal=OCTOSPIM_P1_IO0
PD12.Mode=FDCAN_Activate
PD12.Signal=FDCAN3_RX
PD13.Locked=true
PD13.Mode=FDCAN_Activate
PD13.Signal=FDCAN3_TX
PD2.Mode=Asynchronous
PD2.Signal=UART5_RX
PD4.Locked=true
PD4.Mode=Hardware Flow Control (RS485)
PD4.Signal=USART2_DE
PD5.Locked=true
PD5.Mode=Asynchronous
PD5.Signal=USART2_TX
PD6.Locked=true
PD6.Mode=Asynchronous
PD6.Signal=USART2_RX
PD7.GPIOParameters=GPIO_Speed
PD7.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PD7.Locked=true
PD7.Mode=TX_Only_Simplex_Unidirect_Master
PD7.Signal=SPI1_MOSI
PD8.Mode=Asynchronous
PD8.Signal=USART3_TX
PD9.Mode=Asynchronous
PD9.Signal=USART3_RX
PE10.GPIOParameters=GPIO_Label
PE10.GPIO_Label=ACCL_INT
PE10.Locked=true
PE10.Signal=GPXTI10
PE11.Locked=true
PE11.Mode=OCTOSPI1_Port1_NCS
PE11.Signal=OCTOSPIM_P1_NCS
PE12.GPIOParameters=GPIO_Label
PE12.GPIO_Label=GYRO_INT
PE12.Locked=true
PE12.Signal=GPXTI12
PE13.Signal=S_TIM1_CH3
PE15.GPIOParameters=GPIO_Label
PE15.GPIO_Label=LCD_CS
PE15.Locked=true
PE15.Signal=GPIO_Output
PE2.Mode=Asynchronous
PE2.Signal=USART10_RX
PE3.Mode=Asynchronous
PE3.Signal=USART10_TX
PE7.Mode=Asynchronous
PE7.Signal=UART7_RX
PE8.Mode=Asynchronous
PE8.Signal=UART7_TX
PE9.Locked=true
PE9.Signal=S_TIM1_CH1
PH0-OSC_IN.Mode=HSE-External-Oscillator
PH0-OSC_IN.Signal=RCC_OSC_IN
PH1-OSC_OUT.Mode=HSE-External-Oscillator
PH1-OSC_OUT.Signal=RCC_OSC_OUT
PinOutPanel.RotationAngle=0
ProjectManager.AskForMigrate=true
ProjectManager.BackupPrevious=false
ProjectManager.CompilerLinker=GCC
ProjectManager.CompilerOptimize=6
ProjectManager.ComputerToolchain=false
ProjectManager.CoupleFile=true
ProjectManager.CustomerFirmwarePackage=
ProjectManager.DefaultFWLocation=true
ProjectManager.DeletePrevious=true
ProjectManager.DeviceId=STM32H723VGTx
ProjectManager.FirmwarePackage=STM32Cube FW_H7 V1.12.1
ProjectManager.FreePins=false
ProjectManager.HalAssertFull=false
ProjectManager.HeapSize=0x1000
ProjectManager.KeepUserCode=true
ProjectManager.LastFirmware=true
ProjectManager.LibraryCopy=0
ProjectManager.MainLocation=Core/Src
ProjectManager.NoMain=false
ProjectManager.PreviousToolchain=
ProjectManager.ProjectBuild=false
ProjectManager.ProjectFileName=CtrBoard-H7_ALL.ioc
ProjectManager.ProjectName=CtrBoard-H7_ALL
ProjectManager.ProjectStructure=
ProjectManager.RegisterCallBack=
ProjectManager.StackSize=0x2000
ProjectManager.TargetToolchain=MDK-ARM V5.32
ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_ADC1_Init-ADC1-false-HAL-true,5-MX_TIM12_Init-TIM12-false-HAL-true,6-MX_SPI1_Init-SPI1-false-HAL-true,7-MX_SPI2_Init-SPI2-false-HAL-true,8-MX_TIM3_Init-TIM3-false-HAL-true,9-MX_USART1_UART_Init-USART1-false-HAL-true,10-MX_USART2_UART_Init-USART2-false-HAL-true,11-MX_USART3_UART_Init-USART3-false-HAL-true,12-MX_UART7_Init-UART7-false-HAL-true,13-MX_USART10_UART_Init-USART10-false-HAL-true,14-MX_FDCAN1_Init-FDCAN1-false-HAL-true,15-MX_FDCAN2_Init-FDCAN2-false-HAL-true,16-MX_FDCAN3_Init-FDCAN3-false-HAL-true,17-MX_TIM1_Init-TIM1-false-HAL-true,18-MX_TIM2_Init-TIM2-false-HAL-true,19-MX_OCTOSPI1_Init-OCTOSPI1-false-HAL-true,20-MX_USB_OTG_HS_PCD_Init-USB_OTG_HS-false-HAL-true,21-MX_UART5_Init-UART5-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true
RCC.ADCFreq_Value=96000000
RCC.AHB12Freq_Value=240000000
RCC.AHB4Freq_Value=240000000
RCC.APB1Freq_Value=120000000
RCC.APB2Freq_Value=120000000
RCC.APB3Freq_Value=120000000
RCC.APB4Freq_Value=120000000
RCC.AXIClockFreq_Value=240000000
RCC.CECFreq_Value=32000
RCC.CKPERFreq_Value=64000000
RCC.CortexFreq_Value=480000000
RCC.CpuClockFreq_Value=480000000
RCC.D1CPREFreq_Value=480000000
RCC.D1PPRE=RCC_APB3_DIV2
RCC.D2PPRE1=RCC_APB1_DIV2
RCC.D2PPRE2=RCC_APB2_DIV2
RCC.D3PPRE=RCC_APB4_DIV2
RCC.DFSDMACLkFreq_Value=120000000
RCC.DFSDMFreq_Value=120000000
RCC.DIVM1=2
RCC.DIVM2=2
RCC.DIVN1=40
RCC.DIVN2=16
RCC.DIVP1=1
RCC.DIVP1Freq_Value=480000000
RCC.DIVP2Freq_Value=96000000
RCC.DIVP3Freq_Value=48375000
RCC.DIVQ1=4
RCC.DIVQ1Freq_Value=120000000
RCC.DIVQ2Freq_Value=96000000
RCC.DIVQ3Freq_Value=48375000
RCC.DIVR1Freq_Value=240000000
RCC.DIVR2Freq_Value=96000000
RCC.DIVR3Freq_Value=48375000
RCC.EnbaleCSS=false
RCC.FDCANFreq_Value=120000000
RCC.FMCFreq_Value=240000000
RCC.FamilyName=M
RCC.HCLK3ClockFreq_Value=240000000
RCC.HCLKFreq_Value=240000000
RCC.HPRE=RCC_HCLK_DIV2
RCC.HSE_VALUE=24000000
RCC.I2C123Freq_Value=120000000
RCC.I2C4Freq_Value=120000000
RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,D1PPRE,D2PPRE1,D2PPRE2,D3PPRE,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVM2,DIVN1,DIVN2,DIVP1,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,EnbaleCSS,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HSE_VALUE,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLL2_VCI_Range-AdvancedSettings,PLL2_VCO_SEL-AdvancedSettings,PLL3FRACN,PLL3_VCO_SEL-AdvancedSettings,PLLFRACN,PLLSourceVirtual,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6CLockSelection,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBCLockSelection,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value
RCC.LPTIM1Freq_Value=120000000
RCC.LPTIM2Freq_Value=120000000
RCC.LPTIM345Freq_Value=120000000
RCC.LPUART1Freq_Value=120000000
RCC.LTDCFreq_Value=48375000
RCC.MCO1PinFreq_Value=64000000
RCC.MCO2PinFreq_Value=480000000
RCC.PLL2FRACN=0
RCC.PLL2_VCI_Range-AdvancedSettings=RCC_PLL2VCIRANGE_0
RCC.PLL2_VCO_SEL-AdvancedSettings=RCC_PLL2VCOWIDE
RCC.PLL3FRACN=0
RCC.PLL3_VCO_SEL-AdvancedSettings=RCC_PLL3VCOMEDIUM
RCC.PLLFRACN=0
RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE
RCC.QSPIFreq_Value=240000000
RCC.RNGFreq_Value=48000000
RCC.RTCFreq_Value=32000
RCC.SAI1Freq_Value=120000000
RCC.SAI4AFreq_Value=120000000
RCC.SAI4BFreq_Value=120000000
RCC.SDMMCFreq_Value=120000000
RCC.SPDIFRXFreq_Value=120000000
RCC.SPI123Freq_Value=120000000
RCC.SPI45Freq_Value=120000000
RCC.SPI6CLockSelection=RCC_SPI6CLKSOURCE_HSE
RCC.SPI6Freq_Value=24000000
RCC.SWPMI1Freq_Value=120000000
RCC.SYSCLKFreq_VALUE=480000000
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
RCC.Tim1OutputFreq_Value=240000000
RCC.Tim2OutputFreq_Value=240000000
RCC.TraceFreq_Value=240000000
RCC.USART16Freq_Value=120000000
RCC.USART234578Freq_Value=120000000
RCC.USBCLockSelection=RCC_USBCLKSOURCE_HSI48
RCC.USBFreq_Value=48000000
RCC.VCO1OutputFreq_Value=480000000
RCC.VCO2OutputFreq_Value=192000000
RCC.VCO3OutputFreq_Value=96750000
RCC.VCOInput1Freq_Value=12000000
RCC.VCOInput2Freq_Value=12000000
RCC.VCOInput3Freq_Value=750000
SH.ADCx_INP19.0=ADC1_INP19,IN19-Single-Ended
SH.ADCx_INP19.ConfNb=1
SH.ADCx_INP4.0=ADC1_INP4,IN4-Single-Ended
SH.ADCx_INP4.ConfNb=1
SH.GPXTI10.0=GPIO_EXTI10
SH.GPXTI10.ConfNb=1
SH.GPXTI12.0=GPIO_EXTI12
SH.GPXTI12.ConfNb=1
SH.S_TIM12_CH2.0=TIM12_CH2,PWM Generation2 CH2
SH.S_TIM12_CH2.ConfNb=1
SH.S_TIM1_CH1.0=TIM1_CH1,PWM Generation1 CH1
SH.S_TIM1_CH1.ConfNb=1
SH.S_TIM1_CH3.0=TIM1_CH3,PWM Generation3 CH3
SH.S_TIM1_CH3.ConfNb=1
SH.S_TIM2_CH1_ETR.0=TIM2_CH1,PWM Generation1 CH1
SH.S_TIM2_CH1_ETR.ConfNb=1
SH.S_TIM2_CH3.0=TIM2_CH3,PWM Generation3 CH3
SH.S_TIM2_CH3.ConfNb=1
SH.S_TIM3_CH2.0=TIM3_CH2,PWM Generation2 CH2
SH.S_TIM3_CH2.ConfNb=1
SH.S_TIM3_CH4.0=TIM3_CH4,PWM Generation4 CH4
SH.S_TIM3_CH4.ConfNb=1
SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_4
SPI1.CLKPolarity=SPI_POLARITY_HIGH
SPI1.CalculateBaudRate=30.0 MBits/s
SPI1.DataSize=SPI_DATASIZE_8BIT
SPI1.Direction=SPI_DIRECTION_2LINES_TXONLY
SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,BaudRatePrescaler,CLKPolarity
SPI1.Mode=SPI_MODE_MASTER
SPI1.VirtualType=VM_MASTER
SPI2.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_32
SPI2.CLKPhase=SPI_PHASE_2EDGE
SPI2.CLKPolarity=SPI_POLARITY_HIGH
SPI2.CalculateBaudRate=3.75 MBits/s
SPI2.DataSize=SPI_DATASIZE_8BIT
SPI2.Direction=SPI_DIRECTION_2LINES
SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,BaudRatePrescaler,CLKPolarity,CLKPhase
SPI2.Mode=SPI_MODE_MASTER
SPI2.VirtualType=VM_MASTER
TIM1.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
TIM1.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
TIM1.IPParameters=Channel-PWM Generation3 CH3,Channel-PWM Generation1 CH1,Period,Pulse-PWM Generation1 CH1,Pulse-PWM Generation3 CH3,Prescaler
TIM1.Period=10000
TIM1.Prescaler=24
TIM1.Pulse-PWM\ Generation1\ CH1=5000
TIM1.Pulse-PWM\ Generation3\ CH3=5000
TIM12.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
TIM12.IPParameters=Channel-PWM Generation2 CH2,Prescaler,Period
TIM12.Period=2000-1
TIM12.Prescaler=24-1
TIM2.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
TIM2.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
TIM2.IPParameters=Channel-PWM Generation1 CH1,Channel-PWM Generation3 CH3,Period,Pulse-PWM Generation1 CH1,Pulse-PWM Generation3 CH3,Prescaler
TIM2.Period=10000
TIM2.Prescaler=24
TIM2.Pulse-PWM\ Generation1\ CH1=5000
TIM2.Pulse-PWM\ Generation3\ CH3=5000
TIM3.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE
TIM3.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
TIM3.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
TIM3.IPParameters=Channel-PWM Generation4 CH4,Prescaler,Period,AutoReloadPreload,Channel-PWM Generation2 CH2
TIM3.Period=10000-1
TIM3.Prescaler=24-1
UART5.BaudRate=100000
UART5.IPParameters=Mode,WordLength,Parity,BaudRate
UART5.Mode=MODE_RX
UART5.Parity=PARITY_EVEN
UART5.WordLength=WORDLENGTH_9B
UART7.BaudRate=921600
UART7.IPParameters=BaudRate
USART1.BaudRate=921600
USART1.IPParameters=VirtualMode-Asynchronous,BaudRate
USART1.VirtualMode-Asynchronous=VM_ASYNC
USART10.BaudRate=921600
USART10.IPParameters=VirtualMode,BaudRate
USART10.VirtualMode=VM_ASYNC
USART2.BaudRate=921600
USART2.IPParameters=VirtualMode-Asynchronous,VirtualMode-Hardware Flow Control (RS485),BaudRate
USART2.VirtualMode-Asynchronous=VM_ASYNC
USART2.VirtualMode-Hardware\ Flow\ Control\ (RS485)=VM_ASYNC
USART3.BaudRate=921600
USART3.IPParameters=VirtualMode-Asynchronous,VirtualMode-Hardware Flow Control (RS485),BaudRate
USART3.VirtualMode-Asynchronous=VM_ASYNC
USART3.VirtualMode-Hardware\ Flow\ Control\ (RS485)=VM_ASYNC
USB_OTG_HS.IPParameters=VirtualMode-Device_Only_FS
USB_OTG_HS.VirtualMode-Device_Only_FS=Device_Only_FS
VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2
VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2
VP_MEMORYMAP_VS_MEMORYMAP.Mode=CurAppReg
VP_MEMORYMAP_VS_MEMORYMAP.Signal=MEMORYMAP_VS_MEMORYMAP
VP_OCTOSPI1_VS_octo.Mode=octo_mode
VP_OCTOSPI1_VS_octo.Signal=OCTOSPI1_VS_octo
VP_SYS_VS_tim23.Mode=TIM23
VP_SYS_VS_tim23.Signal=SYS_VS_tim23
board=custom
rtos.0.ip=FREERTOS

View File

@ -1,743 +0,0 @@
#MicroXplorer Configuration settings - do not modify
ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_TEMPSENSOR
ADC1.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV6
ADC1.IPParameters=Rank-0\#ChannelRegularConversion,master,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,NbrOfConversionFlag,ClockPrescaler
ADC1.NbrOfConversionFlag=1
ADC1.Rank-0\#ChannelRegularConversion=1
ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_3CYCLES
ADC1.master=1
ADC3.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_8
ADC3.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV6
ADC3.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,NbrOfConversionFlag,ClockPrescaler
ADC3.NbrOfConversionFlag=1
ADC3.Rank-0\#ChannelRegularConversion=1
ADC3.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_3CYCLES
CAD.formats=
CAD.pinconfig=
CAD.provider=
CAN1.ABOM=DISABLE
CAN1.BS1=CAN_BS1_6TQ
CAN1.BS2=CAN_BS2_7TQ
CAN1.CalculateBaudRate=1000000
CAN1.CalculateTimeBit=1000
CAN1.CalculateTimeQuantum=71.42857142857143
CAN1.IPParameters=CalculateTimeQuantum,BS1,BS2,Prescaler,TXFP,ABOM,CalculateTimeBit,CalculateBaudRate,NART
CAN1.NART=ENABLE
CAN1.Prescaler=3
CAN1.TXFP=ENABLE
CAN2.BS1=CAN_BS1_6TQ
CAN2.BS2=CAN_BS2_7TQ
CAN2.CalculateBaudRate=1000000
CAN2.CalculateTimeBit=1000
CAN2.CalculateTimeQuantum=71.42857142857143
CAN2.IPParameters=CalculateTimeQuantum,BS1,BS2,Prescaler,TXFP,CalculateTimeBit,CalculateBaudRate,NART
CAN2.NART=ENABLE
CAN2.Prescaler=3
CAN2.TXFP=ENABLE
Dma.I2C2_TX.2.Direction=DMA_MEMORY_TO_PERIPH
Dma.I2C2_TX.2.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.I2C2_TX.2.Instance=DMA1_Stream7
Dma.I2C2_TX.2.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.I2C2_TX.2.MemInc=DMA_MINC_ENABLE
Dma.I2C2_TX.2.Mode=DMA_NORMAL
Dma.I2C2_TX.2.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.I2C2_TX.2.PeriphInc=DMA_PINC_DISABLE
Dma.I2C2_TX.2.Priority=DMA_PRIORITY_HIGH
Dma.I2C2_TX.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.I2C3_RX.7.Direction=DMA_PERIPH_TO_MEMORY
Dma.I2C3_RX.7.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.I2C3_RX.7.Instance=DMA1_Stream2
Dma.I2C3_RX.7.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.I2C3_RX.7.MemInc=DMA_MINC_ENABLE
Dma.I2C3_RX.7.Mode=DMA_NORMAL
Dma.I2C3_RX.7.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.I2C3_RX.7.PeriphInc=DMA_PINC_DISABLE
Dma.I2C3_RX.7.Priority=DMA_PRIORITY_LOW
Dma.I2C3_RX.7.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.Request0=SPI1_RX
Dma.Request1=SPI1_TX
Dma.Request2=I2C2_TX
Dma.Request3=USART3_RX
Dma.Request4=USART6_RX
Dma.Request5=USART6_TX
Dma.Request6=USART1_TX
Dma.Request7=I2C3_RX
Dma.Request8=USART1_RX
Dma.RequestsNb=9
Dma.SPI1_RX.0.Direction=DMA_PERIPH_TO_MEMORY
Dma.SPI1_RX.0.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.SPI1_RX.0.Instance=DMA2_Stream2
Dma.SPI1_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.SPI1_RX.0.MemInc=DMA_MINC_ENABLE
Dma.SPI1_RX.0.Mode=DMA_NORMAL
Dma.SPI1_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.SPI1_RX.0.PeriphInc=DMA_PINC_DISABLE
Dma.SPI1_RX.0.Priority=DMA_PRIORITY_VERY_HIGH
Dma.SPI1_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.SPI1_TX.1.Direction=DMA_MEMORY_TO_PERIPH
Dma.SPI1_TX.1.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.SPI1_TX.1.Instance=DMA2_Stream3
Dma.SPI1_TX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.SPI1_TX.1.MemInc=DMA_MINC_ENABLE
Dma.SPI1_TX.1.Mode=DMA_NORMAL
Dma.SPI1_TX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.SPI1_TX.1.PeriphInc=DMA_PINC_DISABLE
Dma.SPI1_TX.1.Priority=DMA_PRIORITY_HIGH
Dma.SPI1_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.USART1_RX.8.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART1_RX.8.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART1_RX.8.Instance=DMA2_Stream5
Dma.USART1_RX.8.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART1_RX.8.MemInc=DMA_MINC_ENABLE
Dma.USART1_RX.8.Mode=DMA_NORMAL
Dma.USART1_RX.8.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART1_RX.8.PeriphInc=DMA_PINC_DISABLE
Dma.USART1_RX.8.Priority=DMA_PRIORITY_MEDIUM
Dma.USART1_RX.8.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.USART1_TX.6.Direction=DMA_MEMORY_TO_PERIPH
Dma.USART1_TX.6.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART1_TX.6.Instance=DMA2_Stream7
Dma.USART1_TX.6.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART1_TX.6.MemInc=DMA_MINC_ENABLE
Dma.USART1_TX.6.Mode=DMA_NORMAL
Dma.USART1_TX.6.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART1_TX.6.PeriphInc=DMA_PINC_DISABLE
Dma.USART1_TX.6.Priority=DMA_PRIORITY_MEDIUM
Dma.USART1_TX.6.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.USART3_RX.3.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART3_RX.3.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART3_RX.3.Instance=DMA1_Stream1
Dma.USART3_RX.3.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART3_RX.3.MemInc=DMA_MINC_ENABLE
Dma.USART3_RX.3.Mode=DMA_NORMAL
Dma.USART3_RX.3.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART3_RX.3.PeriphInc=DMA_PINC_DISABLE
Dma.USART3_RX.3.Priority=DMA_PRIORITY_HIGH
Dma.USART3_RX.3.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.USART6_RX.4.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART6_RX.4.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART6_RX.4.Instance=DMA2_Stream1
Dma.USART6_RX.4.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART6_RX.4.MemInc=DMA_MINC_ENABLE
Dma.USART6_RX.4.Mode=DMA_NORMAL
Dma.USART6_RX.4.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART6_RX.4.PeriphInc=DMA_PINC_DISABLE
Dma.USART6_RX.4.Priority=DMA_PRIORITY_MEDIUM
Dma.USART6_RX.4.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.USART6_TX.5.Direction=DMA_MEMORY_TO_PERIPH
Dma.USART6_TX.5.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART6_TX.5.Instance=DMA2_Stream6
Dma.USART6_TX.5.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART6_TX.5.MemInc=DMA_MINC_ENABLE
Dma.USART6_TX.5.Mode=DMA_NORMAL
Dma.USART6_TX.5.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART6_TX.5.PeriphInc=DMA_PINC_DISABLE
Dma.USART6_TX.5.Priority=DMA_PRIORITY_MEDIUM
Dma.USART6_TX.5.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
FREERTOS.FootprintOK=true
FREERTOS.INCLUDE_pcTaskGetTaskName=1
FREERTOS.INCLUDE_uxTaskGetStackHighWaterMark2=1
FREERTOS.INCLUDE_vTaskCleanUpResources=1
FREERTOS.INCLUDE_xEventGroupSetBitFromISR=1
FREERTOS.INCLUDE_xSemaphoreGetMutexHolder=1
FREERTOS.INCLUDE_xTaskAbortDelay=1
FREERTOS.INCLUDE_xTaskGetCurrentTaskHandle=1
FREERTOS.INCLUDE_xTaskGetHandle=1
FREERTOS.IPParameters=Tasks01,FootprintOK,configENABLE_FPU,configENABLE_BACKWARD_COMPATIBILITY,configRECORD_STACK_HIGH_ADDRESS,configCHECK_FOR_STACK_OVERFLOW,configGENERATE_RUN_TIME_STATS,configUSE_STATS_FORMATTING_FUNCTIONS,configTOTAL_HEAP_SIZE,INCLUDE_xTaskGetCurrentTaskHandle,INCLUDE_xTaskGetHandle,INCLUDE_uxTaskGetStackHighWaterMark2,INCLUDE_xEventGroupSetBitFromISR,INCLUDE_xTaskAbortDelay,INCLUDE_pcTaskGetTaskName,INCLUDE_xSemaphoreGetMutexHolder,INCLUDE_vTaskCleanUpResources,configUSE_APPLICATION_TASK_TAG
FREERTOS.Tasks01=defaultTask,24,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL
FREERTOS.configCHECK_FOR_STACK_OVERFLOW=2
FREERTOS.configENABLE_BACKWARD_COMPATIBILITY=0
FREERTOS.configENABLE_FPU=1
FREERTOS.configGENERATE_RUN_TIME_STATS=1
FREERTOS.configRECORD_STACK_HIGH_ADDRESS=1
FREERTOS.configTOTAL_HEAP_SIZE=0x10000
FREERTOS.configUSE_APPLICATION_TASK_TAG=0
FREERTOS.configUSE_STATS_FORMATTING_FUNCTIONS=1
File.Version=6
GPIO.groupedBy=Group By Peripherals
I2C1.I2C_Mode=I2C_Fast
I2C1.IPParameters=I2C_Mode
I2C2.I2C_Mode=I2C_Fast
I2C2.IPParameters=I2C_Mode
I2C3.I2C_Mode=I2C_Fast
I2C3.IPParameters=I2C_Mode
KeepUserPlacement=false
Mcu.CPN=STM32F407IGH6
Mcu.Family=STM32F4
Mcu.IP0=ADC1
Mcu.IP1=ADC3
Mcu.IP10=NVIC
Mcu.IP11=RCC
Mcu.IP12=RNG
Mcu.IP13=SPI1
Mcu.IP14=SPI2
Mcu.IP15=SYS
Mcu.IP16=TIM1
Mcu.IP17=TIM3
Mcu.IP18=TIM4
Mcu.IP19=TIM5
Mcu.IP2=CAN1
Mcu.IP20=TIM7
Mcu.IP21=TIM8
Mcu.IP22=TIM10
Mcu.IP23=USART1
Mcu.IP24=USART3
Mcu.IP25=USART6
Mcu.IP26=USB_DEVICE
Mcu.IP27=USB_OTG_FS
Mcu.IP3=CAN2
Mcu.IP4=CRC
Mcu.IP5=DMA
Mcu.IP6=FREERTOS
Mcu.IP7=I2C1
Mcu.IP8=I2C2
Mcu.IP9=I2C3
Mcu.IPNb=28
Mcu.Name=STM32F407I(E-G)Hx
Mcu.Package=UFBGA176
Mcu.Pin0=PB8
Mcu.Pin1=PB5
Mcu.Pin10=PD0
Mcu.Pin11=PC11
Mcu.Pin12=PC10
Mcu.Pin13=PA12
Mcu.Pin14=PI6
Mcu.Pin15=PG9
Mcu.Pin16=PD1
Mcu.Pin17=PA11
Mcu.Pin18=PF0
Mcu.Pin19=PA9
Mcu.Pin2=PG14
Mcu.Pin20=PC9
Mcu.Pin21=PA8
Mcu.Pin22=PH0-OSC_IN
Mcu.Pin23=PC8
Mcu.Pin24=PH1-OSC_OUT
Mcu.Pin25=PF1
Mcu.Pin26=PC6
Mcu.Pin27=PG6
Mcu.Pin28=PF6
Mcu.Pin29=PH12
Mcu.Pin3=PB4
Mcu.Pin30=PG3
Mcu.Pin31=PF10
Mcu.Pin32=PH11
Mcu.Pin33=PH10
Mcu.Pin34=PC0
Mcu.Pin35=PC1
Mcu.Pin36=PC2
Mcu.Pin37=PD14
Mcu.Pin38=PA0-WKUP
Mcu.Pin39=PA4
Mcu.Pin4=PB3
Mcu.Pin40=PC4
Mcu.Pin41=PE13
Mcu.Pin42=PC5
Mcu.Pin43=PE9
Mcu.Pin44=PE11
Mcu.Pin45=PE14
Mcu.Pin46=PB12
Mcu.Pin47=PB13
Mcu.Pin48=PA7
Mcu.Pin49=PB0
Mcu.Pin5=PA14
Mcu.Pin50=PB14
Mcu.Pin51=PB15
Mcu.Pin52=VP_ADC1_TempSens_Input
Mcu.Pin53=VP_ADC1_Vref_Input
Mcu.Pin54=VP_CRC_VS_CRC
Mcu.Pin55=VP_FREERTOS_VS_CMSIS_V2
Mcu.Pin56=VP_RNG_VS_RNG
Mcu.Pin57=VP_SYS_VS_Systick
Mcu.Pin58=VP_TIM1_VS_ClockSourceINT
Mcu.Pin59=VP_TIM3_VS_ClockSourceINT
Mcu.Pin6=PA13
Mcu.Pin60=VP_TIM4_VS_ClockSourceINT
Mcu.Pin61=VP_TIM5_VS_ClockSourceINT
Mcu.Pin62=VP_TIM7_VS_ClockSourceINT
Mcu.Pin63=VP_TIM8_VS_ClockSourceINT
Mcu.Pin64=VP_TIM10_VS_ClockSourceINT
Mcu.Pin65=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
Mcu.Pin7=PB9
Mcu.Pin8=PB7
Mcu.Pin9=PB6
Mcu.PinsNb=66
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32F407IGHx
MxCube.Version=6.15.0
MxDb.Version=DB.6.0.150
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.CAN1_RX0_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.CAN1_RX1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.CAN1_TX_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.CAN2_RX0_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.CAN2_RX1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.CAN2_TX_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.DMA1_Stream1_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream7_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
NVIC.DMA2_Stream1_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
NVIC.DMA2_Stream2_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
NVIC.DMA2_Stream3_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
NVIC.DMA2_Stream5_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA2_Stream6_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
NVIC.DMA2_Stream7_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.EXTI0_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.EXTI3_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.EXTI4_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.EXTI9_5_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.OTG_FS_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false
NVIC.SavedPendsvIrqHandlerGenerated=true
NVIC.SavedSvcallIrqHandlerGenerated=true
NVIC.SavedSystickIrqHandlerGenerated=true
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:true\:false\:true\:false
NVIC.TIM1_BRK_TIM9_IRQn=true\:5\:0\:false\:false\:true\:false\:false\:true\:true
NVIC.TIM7_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.USART1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.USART6_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.UsageFault_IRQn=true\:0\:0\:true\:false\:true\:false\:false\:false\:false
PA0-WKUP.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI
PA0-WKUP.GPIO_Label=USER_KEY
PA0-WKUP.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING
PA0-WKUP.GPIO_PuPd=GPIO_PULLUP
PA0-WKUP.Locked=true
PA0-WKUP.Signal=GPXTI0
PA11.Mode=Device_Only
PA11.Signal=USB_OTG_FS_DM
PA12.Mode=Device_Only
PA12.Signal=USB_OTG_FS_DP
PA13.Mode=Serial_Wire
PA13.Signal=SYS_JTMS-SWDIO
PA14.Mode=Serial_Wire
PA14.Signal=SYS_JTCK-SWCLK
PA4.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
PA4.GPIO_Label=ACCL_CS
PA4.GPIO_PuPd=GPIO_PULLUP
PA4.GPIO_Speed=GPIO_SPEED_FREQ_MEDIUM
PA4.Locked=true
PA4.PinState=GPIO_PIN_SET
PA4.Signal=GPIO_Output
PA7.GPIOParameters=GPIO_PuPd
PA7.GPIO_PuPd=GPIO_PULLUP
PA7.Locked=true
PA7.Mode=Full_Duplex_Master
PA7.Signal=SPI1_MOSI
PA8.GPIOParameters=GPIO_Pu
PA8.GPIO_Pu=GPIO_PULLUP
PA8.Locked=true
PA8.Mode=I2C
PA8.Signal=I2C3_SCL
PA9.Locked=true
PA9.Mode=Asynchronous
PA9.Signal=USART1_TX
PB0.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
PB0.GPIO_Label=GYRO_CS
PB0.GPIO_PuPd=GPIO_PULLUP
PB0.GPIO_Speed=GPIO_SPEED_FREQ_MEDIUM
PB0.Locked=true
PB0.PinState=GPIO_PIN_SET
PB0.Signal=GPIO_Output
PB12.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
PB12.GPIO_Label=SPI2_CS
PB12.GPIO_PuPd=GPIO_PULLUP
PB12.GPIO_Speed=GPIO_SPEED_FREQ_MEDIUM
PB12.Locked=true
PB12.PinState=GPIO_PIN_SET
PB12.Signal=GPIO_Output
PB13.GPIOParameters=GPIO_PuPd
PB13.GPIO_PuPd=GPIO_PULLUP
PB13.Locked=true
PB13.Mode=Full_Duplex_Master
PB13.Signal=SPI2_SCK
PB14.GPIOParameters=GPIO_PuPd
PB14.GPIO_PuPd=GPIO_PULLUP
PB14.Locked=true
PB14.Mode=Full_Duplex_Master
PB14.Signal=SPI2_MISO
PB15.GPIOParameters=GPIO_PuPd
PB15.GPIO_PuPd=GPIO_PULLUP
PB15.Locked=true
PB15.Mode=Full_Duplex_Master
PB15.Signal=SPI2_MOSI
PB3.GPIOParameters=GPIO_PuPd
PB3.GPIO_PuPd=GPIO_PULLUP
PB3.Locked=true
PB3.Mode=Full_Duplex_Master
PB3.Signal=SPI1_SCK
PB4.GPIOParameters=GPIO_PuPd
PB4.GPIO_PuPd=GPIO_PULLUP
PB4.Locked=true
PB4.Mode=Full_Duplex_Master
PB4.Signal=SPI1_MISO
PB5.Locked=true
PB5.Mode=CAN_Activate
PB5.Signal=CAN2_RX
PB6.Locked=true
PB6.Mode=CAN_Activate
PB6.Signal=CAN2_TX
PB7.Locked=true
PB7.Mode=Asynchronous
PB7.Signal=USART1_RX
PB8.GPIOParameters=GPIO_Pu
PB8.GPIO_Pu=GPIO_PULLUP
PB8.Locked=true
PB8.Mode=I2C
PB8.Signal=I2C1_SCL
PB9.GPIOParameters=GPIO_Pu
PB9.GPIO_Pu=GPIO_PULLUP
PB9.Locked=true
PB9.Mode=I2C
PB9.Signal=I2C1_SDA
PC0.GPIOParameters=GPIO_Label
PC0.GPIO_Label=HW0
PC0.Locked=true
PC0.Signal=GPIO_Input
PC1.GPIOParameters=GPIO_Label
PC1.GPIO_Label=HW1
PC1.Locked=true
PC1.Signal=GPIO_Input
PC10.Locked=true
PC10.Mode=Asynchronous
PC10.Signal=USART3_TX
PC11.Locked=true
PC11.Mode=Asynchronous
PC11.Signal=USART3_RX
PC2.GPIOParameters=GPIO_Label
PC2.GPIO_Label=HW2
PC2.Locked=true
PC2.Signal=GPIO_Input
PC4.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI
PC4.GPIO_Label=ACCL_INT
PC4.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING
PC4.GPIO_PuPd=GPIO_PULLUP
PC4.Locked=true
PC4.Signal=GPXTI4
PC5.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI
PC5.GPIO_Label=GYRO_INT
PC5.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING
PC5.GPIO_PuPd=GPIO_PULLUP
PC5.Locked=true
PC5.Signal=GPXTI5
PC6.GPIOParameters=GPIO_Speed,GPIO_PuPd
PC6.GPIO_PuPd=GPIO_PULLUP
PC6.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PC6.Locked=true
PC6.Signal=S_TIM8_CH1
PC8.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label
PC8.GPIO_Label=LASER
PC8.GPIO_PuPd=GPIO_PULLUP
PC8.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PC8.Locked=true
PC8.Signal=S_TIM3_CH3
PC9.GPIOParameters=GPIO_Pu
PC9.GPIO_Pu=GPIO_PULLUP
PC9.Locked=true
PC9.Mode=I2C
PC9.Signal=I2C3_SDA
PD0.Locked=true
PD0.Mode=CAN_Activate
PD0.Signal=CAN1_RX
PD1.Locked=true
PD1.Mode=CAN_Activate
PD1.Signal=CAN1_TX
PD14.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label
PD14.GPIO_Label=BUZZER
PD14.GPIO_PuPd=GPIO_PULLUP
PD14.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PD14.Locked=true
PD14.Signal=S_TIM4_CH3
PE11.GPIOParameters=GPIO_Speed,GPIO_PuPd
PE11.GPIO_PuPd=GPIO_PULLUP
PE11.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PE11.Locked=true
PE11.Signal=S_TIM1_CH2
PE13.GPIOParameters=GPIO_Speed,GPIO_PuPd
PE13.GPIO_PuPd=GPIO_PULLUP
PE13.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PE13.Locked=true
PE13.Signal=S_TIM1_CH3
PE14.GPIOParameters=GPIO_Speed,GPIO_PuPd
PE14.GPIO_PuPd=GPIO_PULLUP
PE14.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PE14.Locked=true
PE14.Signal=S_TIM1_CH4
PE9.GPIOParameters=GPIO_Speed,GPIO_PuPd
PE9.GPIO_PuPd=GPIO_PULLUP
PE9.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PE9.Locked=true
PE9.Signal=S_TIM1_CH1
PF0.GPIOParameters=GPIO_Pu
PF0.GPIO_Pu=GPIO_PULLUP
PF0.Locked=true
PF0.Mode=I2C
PF0.Signal=I2C2_SDA
PF1.GPIOParameters=GPIO_Pu
PF1.GPIO_Pu=GPIO_PULLUP
PF1.Locked=true
PF1.Mode=I2C
PF1.Signal=I2C2_SCL
PF10.GPIOParameters=GPIO_Label
PF10.GPIO_Label=ADC_BAT
PF10.Locked=true
PF10.Mode=IN8
PF10.Signal=ADC3_IN8
PF6.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label
PF6.GPIO_Label=IMU_HEAT_PWM
PF6.GPIO_PuPd=GPIO_PULLDOWN
PF6.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PF6.Locked=true
PF6.Signal=S_TIM10_CH1
PG14.Locked=true
PG14.Mode=Asynchronous
PG14.Signal=USART6_TX
PG3.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI
PG3.GPIO_Label=CMPS_INT
PG3.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING
PG3.GPIO_PuPd=GPIO_PULLUP
PG3.Locked=true
PG3.Signal=GPXTI3
PG6.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
PG6.GPIO_Label=CMPS_RST
PG6.GPIO_PuPd=GPIO_PULLUP
PG6.GPIO_Speed=GPIO_SPEED_FREQ_MEDIUM
PG6.Locked=true
PG6.PinState=GPIO_PIN_RESET
PG6.Signal=GPIO_Output
PG9.Locked=true
PG9.Mode=Asynchronous
PG9.Signal=USART6_RX
PH0-OSC_IN.Mode=HSE-External-Oscillator
PH0-OSC_IN.Signal=RCC_OSC_IN
PH1-OSC_OUT.Mode=HSE-External-Oscillator
PH1-OSC_OUT.Signal=RCC_OSC_OUT
PH10.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label
PH10.GPIO_Label=LED_B
PH10.GPIO_PuPd=GPIO_PULLUP
PH10.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PH10.Locked=true
PH10.Signal=S_TIM5_CH1
PH11.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label
PH11.GPIO_Label=LED_G
PH11.GPIO_PuPd=GPIO_PULLUP
PH11.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PH11.Locked=true
PH11.Signal=S_TIM5_CH2
PH12.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label
PH12.GPIO_Label=LED_R
PH12.GPIO_PuPd=GPIO_PULLUP
PH12.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PH12.Locked=true
PH12.Signal=S_TIM5_CH3
PI6.GPIOParameters=GPIO_Speed,GPIO_PuPd
PI6.GPIO_PuPd=GPIO_PULLUP
PI6.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PI6.Signal=S_TIM8_CH2
PinOutPanel.CurrentBGAView=Top
PinOutPanel.RotationAngle=0
ProjectManager.AskForMigrate=true
ProjectManager.BackupPrevious=false
ProjectManager.CompilerLinker=GCC
ProjectManager.CompilerOptimize=6
ProjectManager.ComputerToolchain=false
ProjectManager.CoupleFile=true
ProjectManager.CustomerFirmwarePackage=
ProjectManager.DefaultFWLocation=true
ProjectManager.DeletePrevious=true
ProjectManager.DeviceId=STM32F407IGHx
ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.28.3
ProjectManager.FreePins=false
ProjectManager.HalAssertFull=true
ProjectManager.HeapSize=0x1000
ProjectManager.KeepUserCode=true
ProjectManager.LastFirmware=true
ProjectManager.LibraryCopy=0
ProjectManager.MainLocation=Core/Src
ProjectManager.NoMain=false
ProjectManager.PreviousToolchain=
ProjectManager.ProjectBuild=false
ProjectManager.ProjectFileName=DevC.ioc
ProjectManager.ProjectName=DevC
ProjectManager.ProjectStructure=
ProjectManager.RegisterCallBack=
ProjectManager.StackSize=0x1000
ProjectManager.TargetToolchain=CMake
ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-MX_DMA_Init-DMA-false-HAL-true,3-SystemClock_Config-RCC-false-HAL-false,4-MX_ADC1_Init-ADC1-false-HAL-true,5-MX_ADC3_Init-ADC3-false-HAL-true,6-MX_CAN1_Init-CAN1-false-HAL-true,7-MX_CAN2_Init-CAN2-false-HAL-true,8-MX_I2C1_Init-I2C1-false-HAL-true,9-MX_SPI1_Init-SPI1-false-HAL-true,10-MX_TIM4_Init-TIM4-false-HAL-true,11-MX_TIM5_Init-TIM5-false-HAL-true,12-MX_USART3_UART_Init-USART3-false-HAL-true,13-MX_TIM8_Init-TIM8-false-HAL-true,14-MX_CRC_Init-CRC-false-HAL-true,15-MX_RNG_Init-RNG-false-HAL-true,16-MX_I2C2_Init-I2C2-false-HAL-true,17-MX_I2C3_Init-I2C3-false-HAL-true,18-MX_SPI2_Init-SPI2-false-HAL-true,19-MX_TIM1_Init-TIM1-false-HAL-true,20-MX_TIM3_Init-TIM3-false-HAL-true,21-MX_TIM10_Init-TIM10-false-HAL-true,22-MX_USART1_UART_Init-USART1-false-HAL-true,23-MX_USART6_UART_Init-USART6-false-HAL-true,24-MX_TIM7_Init-TIM7-false-HAL-true,25-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false
RCC.48MHZClocksFreq_Value=48000000
RCC.AHBFreq_Value=168000000
RCC.APB1CLKDivider=RCC_HCLK_DIV4
RCC.APB1Freq_Value=42000000
RCC.APB1TimFreq_Value=84000000
RCC.APB2CLKDivider=RCC_HCLK_DIV2
RCC.APB2Freq_Value=84000000
RCC.APB2TimFreq_Value=168000000
RCC.CortexFreq_Value=168000000
RCC.EthernetFreq_Value=168000000
RCC.FCLKCortexFreq_Value=168000000
RCC.FamilyName=M
RCC.HCLKFreq_Value=168000000
RCC.HSE_VALUE=12000000
RCC.HSI_VALUE=16000000
RCC.I2SClocksFreq_Value=192000000
RCC.IPParameters=48MHZClocksFreq_Value,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2CLKDivider,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,EthernetFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2SClocksFreq_Value,LSE_VALUE,LSI_VALUE,MCO2PinFreq_Value,PLLCLKFreq_Value,PLLM,PLLN,PLLQ,PLLQCLKFreq_Value,RCC_RTC_Clock_Source,RCC_RTC_Clock_SourceVirtual,RCC_RTC_Clock_Source_FROM_HSE,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VcooutputI2S
RCC.LSE_VALUE=32768
RCC.LSI_VALUE=32000
RCC.MCO2PinFreq_Value=168000000
RCC.PLLCLKFreq_Value=168000000
RCC.PLLM=6
RCC.PLLN=168
RCC.PLLQ=7
RCC.PLLQCLKFreq_Value=48000000
RCC.RCC_RTC_Clock_Source=RCC_RTCCLKSOURCE_LSI
RCC.RCC_RTC_Clock_SourceVirtual=RCC_RTCCLKSOURCE_HSE_DIV30
RCC.RCC_RTC_Clock_Source_FROM_HSE=RCC_RTCCLKSOURCE_HSE_DIV30
RCC.RTCFreq_Value=32000
RCC.RTCHSEDivFreq_Value=400000
RCC.SYSCLKFreq_VALUE=168000000
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
RCC.VCOI2SOutputFreq_Value=384000000
RCC.VCOInputFreq_Value=2000000
RCC.VCOOutputFreq_Value=336000000
RCC.VcooutputI2S=192000000
SH.GPXTI0.0=GPIO_EXTI0
SH.GPXTI0.ConfNb=1
SH.GPXTI3.0=GPIO_EXTI3
SH.GPXTI3.ConfNb=1
SH.GPXTI4.0=GPIO_EXTI4
SH.GPXTI4.ConfNb=1
SH.GPXTI5.0=GPIO_EXTI5
SH.GPXTI5.ConfNb=1
SH.S_TIM10_CH1.0=TIM10_CH1,PWM Generation1 CH1
SH.S_TIM10_CH1.ConfNb=1
SH.S_TIM1_CH1.0=TIM1_CH1,PWM Generation1 CH1
SH.S_TIM1_CH1.ConfNb=1
SH.S_TIM1_CH2.0=TIM1_CH2,PWM Generation2 CH2
SH.S_TIM1_CH2.ConfNb=1
SH.S_TIM1_CH3.0=TIM1_CH3,PWM Generation3 CH3
SH.S_TIM1_CH3.ConfNb=1
SH.S_TIM1_CH4.0=TIM1_CH4,PWM Generation4 CH4
SH.S_TIM1_CH4.ConfNb=1
SH.S_TIM3_CH3.0=TIM3_CH3,PWM Generation3 CH3
SH.S_TIM3_CH3.ConfNb=1
SH.S_TIM4_CH3.0=TIM4_CH3,PWM Generation3 CH3
SH.S_TIM4_CH3.ConfNb=1
SH.S_TIM5_CH1.0=TIM5_CH1,PWM Generation1 CH1
SH.S_TIM5_CH1.ConfNb=1
SH.S_TIM5_CH2.0=TIM5_CH2,PWM Generation2 CH2
SH.S_TIM5_CH2.ConfNb=1
SH.S_TIM5_CH3.0=TIM5_CH3,PWM Generation3 CH3
SH.S_TIM5_CH3.ConfNb=1
SH.S_TIM8_CH1.0=TIM8_CH1,PWM Generation1 CH1
SH.S_TIM8_CH1.ConfNb=1
SH.S_TIM8_CH2.0=TIM8_CH2,PWM Generation2 CH2
SH.S_TIM8_CH2.ConfNb=1
SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_16
SPI1.CLKPhase=SPI_PHASE_2EDGE
SPI1.CLKPolarity=SPI_POLARITY_HIGH
SPI1.CalculateBaudRate=5.25 MBits/s
SPI1.Direction=SPI_DIRECTION_2LINES
SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler,CLKPolarity,CLKPhase
SPI1.Mode=SPI_MODE_MASTER
SPI1.VirtualType=VM_MASTER
SPI2.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_64
SPI2.CLKPhase=SPI_PHASE_1EDGE
SPI2.CLKPolarity=SPI_POLARITY_LOW
SPI2.CalculateBaudRate=656.25 KBits/s
SPI2.Direction=SPI_DIRECTION_2LINES
SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler,CLKPolarity,CLKPhase
SPI2.Mode=SPI_MODE_MASTER
SPI2.VirtualType=VM_MASTER
TIM1.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
TIM1.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
TIM1.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
TIM1.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
TIM1.IPParameters=Channel-PWM Generation1 CH1,Channel-PWM Generation2 CH2,Channel-PWM Generation3 CH3,Channel-PWM Generation4 CH4,Period,Prescaler,Pulse-PWM Generation1 CH1,Pulse-PWM Generation2 CH2,Pulse-PWM Generation3 CH3,Pulse-PWM Generation4 CH4
TIM1.Period=19999
TIM1.Prescaler=167
TIM1.Pulse-PWM\ Generation1\ CH1=0
TIM1.Pulse-PWM\ Generation2\ CH2=0
TIM1.Pulse-PWM\ Generation3\ CH3=0
TIM1.Pulse-PWM\ Generation4\ CH4=1000
TIM10.Channel=TIM_CHANNEL_1
TIM10.IPParameters=Channel,Period
TIM10.Period=4999
TIM3.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
TIM3.IPParameters=Channel-PWM Generation3 CH3,Period
TIM3.Period=65535
TIM4.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
TIM4.IPParameters=Channel-PWM Generation3 CH3,Prescaler,Period
TIM4.Period=65535
TIM4.Prescaler=167
TIM5.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
TIM5.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
TIM5.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
TIM5.IPParameters=Channel-PWM Generation1 CH1,Channel-PWM Generation2 CH2,Channel-PWM Generation3 CH3,Prescaler,Period
TIM5.Period=65535
TIM5.Prescaler=0
TIM7.IPParameters=Period,Prescaler
TIM7.Period=9
TIM7.Prescaler=83
TIM8.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
TIM8.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
TIM8.IPParameters=Channel-PWM Generation1 CH1,Channel-PWM Generation2 CH2,Prescaler,Period,Pulse-PWM Generation1 CH1,Pulse-PWM Generation2 CH2
TIM8.Period=19999
TIM8.Prescaler=167
TIM8.Pulse-PWM\ Generation1\ CH1=1000
TIM8.Pulse-PWM\ Generation2\ CH2=1000
USART1.IPParameters=VirtualMode
USART1.VirtualMode=VM_ASYNC
USART3.BaudRate=100000
USART3.IPParameters=VirtualMode,BaudRate,Parity,Mode
USART3.Mode=MODE_RX
USART3.Parity=PARITY_EVEN
USART3.VirtualMode=VM_ASYNC
USART6.IPParameters=VirtualMode
USART6.VirtualMode=VM_ASYNC
USB_DEVICE.CLASS_NAME_FS=CDC
USB_DEVICE.IPParameters=VirtualMode-CDC_FS,VirtualModeFS,CLASS_NAME_FS
USB_DEVICE.VirtualMode-CDC_FS=Cdc
USB_DEVICE.VirtualModeFS=Cdc_FS
USB_OTG_FS.IPParameters=VirtualMode
USB_OTG_FS.VirtualMode=Device_Only
VP_ADC1_TempSens_Input.Mode=IN-TempSens
VP_ADC1_TempSens_Input.Signal=ADC1_TempSens_Input
VP_ADC1_Vref_Input.Mode=IN-Vrefint
VP_ADC1_Vref_Input.Signal=ADC1_Vref_Input
VP_CRC_VS_CRC.Mode=CRC_Activate
VP_CRC_VS_CRC.Signal=CRC_VS_CRC
VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2
VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2
VP_RNG_VS_RNG.Mode=RNG_Activate
VP_RNG_VS_RNG.Signal=RNG_VS_RNG
VP_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
VP_TIM10_VS_ClockSourceINT.Mode=Enable_Timer
VP_TIM10_VS_ClockSourceINT.Signal=TIM10_VS_ClockSourceINT
VP_TIM1_VS_ClockSourceINT.Mode=Internal
VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT
VP_TIM3_VS_ClockSourceINT.Mode=Internal
VP_TIM3_VS_ClockSourceINT.Signal=TIM3_VS_ClockSourceINT
VP_TIM4_VS_ClockSourceINT.Mode=Internal
VP_TIM4_VS_ClockSourceINT.Signal=TIM4_VS_ClockSourceINT
VP_TIM5_VS_ClockSourceINT.Mode=Internal
VP_TIM5_VS_ClockSourceINT.Signal=TIM5_VS_ClockSourceINT
VP_TIM7_VS_ClockSourceINT.Mode=Enable_Timer
VP_TIM7_VS_ClockSourceINT.Signal=TIM7_VS_ClockSourceINT
VP_TIM8_VS_ClockSourceINT.Mode=Internal
VP_TIM8_VS_ClockSourceINT.Signal=TIM8_VS_ClockSourceINT
VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Mode=CDC_FS
VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Signal=USB_DEVICE_VS_USB_DEVICE_CDC_FS
board=custom
rtos.0.ip=FREERTOS

View File

@ -197,7 +197,7 @@ int8_t CMD_Arbitrate(CMD_t *ctx) {
}
/* 自动仲裁:优先级 PC > RC > NUC */
CMD_InputSource_t candidates[] = {CMD_SRC_RC, CMD_SRC_PC, CMD_SRC_NUC};
CMD_InputSource_t candidates[] = {CMD_SRC_PC, CMD_SRC_RC, CMD_SRC_NUC};
const int num_candidates = sizeof(candidates) / sizeof(candidates[0]);
/* 如果当前输入源仍然在线且有效,保持使用 */

View File

@ -10,7 +10,7 @@
// static CMD_InputAdapter_t *g_adapters[CMD_SRC_NUM] = {0};
CMD_InputAdapter_t *g_adapters[CMD_SRC_NUM] = {0};
/* ========================================================================== */
/* DR16 适配器实现 */
/* DR16 抽象实现 */
/* ========================================================================== */
#if CMD_RC_DEVICE_TYPE == 0
@ -27,19 +27,19 @@ int8_t CMD_DR16_RC_GetInput(void *data, CMD_RawInput_t *output) {
output->online[CMD_SRC_RC] = dr16->header.online;
/* 遥控器摇杆映射 */
output->rc.joy_left.x = dr16->data.ch_l_x;
output->rc.joy_left.y = dr16->data.ch_l_y;
output->rc.joy_right.x = dr16->data.ch_r_x;
output->rc.joy_right.y = dr16->data.ch_r_y;
output->rc.joy_left.x = dr16->data.rc.ch_l_x;
output->rc.joy_left.y = dr16->data.rc.ch_l_y;
output->rc.joy_right.x = dr16->data.rc.ch_r_x;
output->rc.joy_right.y = dr16->data.rc.ch_r_y;
/* 拨杆映射 */
switch (dr16->data.sw_l) {
switch (dr16->data.rc.sw_l) {
case DR16_SW_UP: output->rc.sw[0] = CMD_SW_UP; break;
case DR16_SW_MID: output->rc.sw[0] = CMD_SW_MID; break;
case DR16_SW_DOWN: output->rc.sw[0] = CMD_SW_DOWN; break;
default: output->rc.sw[0] = CMD_SW_ERR; break;
}
switch (dr16->data.sw_r) {
switch (dr16->data.rc.sw_r) {
case DR16_SW_UP: output->rc.sw[1] = CMD_SW_UP; break;
case DR16_SW_MID: output->rc.sw[1] = CMD_SW_MID; break;
case DR16_SW_DOWN: output->rc.sw[1] = CMD_SW_DOWN; break;
@ -47,7 +47,7 @@ int8_t CMD_DR16_RC_GetInput(void *data, CMD_RawInput_t *output) {
}
/* 拨轮映射 */
output->rc.dial = dr16->data.ch_res;
output->rc.dial = dr16->data.rc.ch_res;
return CMD_OK;
}
@ -60,10 +60,10 @@ int8_t CMD_DR16_PC_GetInput(void *data, CMD_RawInput_t *output) {
output->online[CMD_SRC_PC] = dr16->header.online;
/* PC端鼠标映射 */
output->pc.mouse.x = dr16->data.mouse.x;
output->pc.mouse.y = dr16->data.mouse.y;
output->pc.mouse.l_click = dr16->data.mouse.l_click;
output->pc.mouse.r_click = dr16->data.mouse.r_click;
output->pc.mouse.x = dr16->data.pc.mouse.x;
output->pc.mouse.y = dr16->data.pc.mouse.y;
output->pc.mouse.l_click = dr16->data.pc.mouse.l_click;
output->pc.mouse.r_click = dr16->data.pc.mouse.r_click;
/* 键盘映射 */
output->pc.keyboard.bitmap = dr16->raw_data.key;
@ -83,7 +83,7 @@ CMD_DEFINE_ADAPTER(DR16_PC, cmd_dr16, CMD_SRC_PC, CMD_DR16_Init, CMD_DR16_PC_Get
#endif /* CMD_RC_DEVICE_TYPE == 0 */
/* ========================================================================== */
/* AT9S 适配器实现 (示例框架) */
/* AT9S 抽象实现 (示例框架) */
/* ========================================================================== */
#if CMD_RC_DEVICE_TYPE == 1
@ -100,10 +100,10 @@ int8_t CMD_AT9S_GetInput(void *data, CMD_RawInput_t *output) {
output->online[CMD_SRC_RC] = at9s->header.online;
/* TODO: 按照AT9S的数据格式进行映射 */
output->joy_left.x = at9s->data.ch_l_x;
output->joy_left.y = at9s->data.ch_l_y;
output->joy_right.x = at9s->data.ch_r_x;
output->joy_right.y = at9s->data.ch_r_y;
output->joy_left.x = at9s->data.rc.ch_l_x;
output->joy_left.y = at9s->data.rc.ch_l_y;
output->joy_right.x = at9s->data.rc.ch_r_x;
output->joy_right.y = at9s->data.rc.ch_r_y;
/* 拨杆映射需要根据AT9S的实际定义 */
@ -142,6 +142,10 @@ int8_t CMD_Adapter_InitAll(void) {
CMD_Adapter_Register(&g_adapter_AT9S);
#endif
/* 注册NUC适配器 */
/* 注册REF适配器 */
/* 初始化所有已注册的适配器 */
for (int i = 0; i < CMD_SRC_NUM; i++) {
if (g_adapters[i] != NULL && g_adapters[i]->init != NULL) {

View File

@ -6,7 +6,7 @@
#include "cmd.h"
/* ========================================================================== */
/* config示例 */
/* 配置示例 */
/* ========================================================================== */
/* 默认配置 */
@ -37,57 +37,34 @@
// /* CMD上下文 */
// static CMD_t g_cmd_ctx;
/* ========================================================================== */
/* 队列创建示例 */
/* ========================================================================== */
// #if CMD_RCTypeTable_Index == 0
// task_runtime.msgq.cmd.rc= osMessageQueueNew(3u, sizeof(DR16_t), NULL);
// #elif CMD_RCTypeTable_Index == 1
// task_runtime.msgq.cmd.rc= osMessageQueueNew(3u, sizeof(AT9S_t), NULL);
// #endif
/* ========================================================================== */
/* 任务示例 */
/* ========================================================================== */
// #if CMD_RCTypeTable_Index == 0
// DR16_t cmd_dr16;
// #elif CMD_RCTypeTable_Index == 1
// AT9S_t cmd_at9s;
// #endif
// Shoot_CMD_t *cmd_for_shoot;
// Chassis_CMD_t *cmd_for_chassis;
// Gimbal_CMD_t *cmd_for_gimbal;
// static CMD_t cmd;
// void Task_cmd() {
// CMD_Init(&cmd, &Config_GetRobotParam()->cmd_param);
// while (1) {
// #if CMD_RCTypeTable_Index == 0
// osMessageQueueGet(task_runtime.msgq.cmd.rc, &cmd_dr16, NULL, 0);
// #elif CMD_RCTypeTable_Index == 1
// osMessageQueueGet(task_runtime.msgq.cmd.rc, &cmd_at9s, NULL, 0);
// #endif
// CMD_Update(&cmd);
// /* 获取命令发送到各模块 */
// cmd_for_chassis = CMD_GetChassisCmd(&cmd);
// cmd_for_gimbal = CMD_GetGimbalCmd(&cmd);
// cmd_for_shoot = CMD_GetShootCmd(&cmd);
// osMessageQueueReset(task_runtime.msgq.gimbal.cmd);
// osMessageQueuePut(task_runtime.msgq.gimbal.cmd, cmd_for_gimbal, 0, 0);
// osMessageQueueReset(task_runtime.msgq.shoot.cmd);
// osMessageQueuePut(task_runtime.msgq.shoot.cmd, cmd_for_shoot, 0, 0);
// osMessageQueueReset(task_runtime.msgq.chassis.cmd);
// osMessageQueuePut(task_runtime.msgq.chassis.cmd, cmd_for_chassis, 0, 0);
// }
/*
*
*/
// void Example_CMD_Init(void) {
// CMD_Init(&g_cmd_ctx, &g_cmd_config);
// }
// /*
// * 任务循环示例
// */
// void Example_CMD_Task(void) {
// /* 一键更新 */
// CMD_Update(&g_cmd_ctx);
// /* 获取命令发送到各模块 */
// Chassis_CMD_t *chassis_cmd = CMD_GetChassisCmd(&g_cmd_ctx);
// Gimbal_CMD_t *gimbal_cmd = CMD_GetGimbalCmd(&g_cmd_ctx);
// Shoot_CMD_t *shoot_cmd = CMD_GetShootCmd(&g_cmd_ctx);
// /* 使用命令... */
// (void)chassis_cmd;
// (void)gimbal_cmd;
// (void)shoot_cmd;
// }
/* ========================================================================== */
/* 架构说明 */

View File

@ -18,9 +18,6 @@
/* USER STRUCT END */
/* Private function --------------------------------------------------------- */
/* USER PRIVATE CODE BEGIN */
/* USER PRIVATE CODE END */
/* Exported functions ------------------------------------------------------- */
void {{task_function}}(void *argument) {
(void)argument; /* 未使用argument消除警告 */

View File

@ -1,96 +0,0 @@
/*
atti_esti Task
pwm温控的纯陀螺仪BMI088姿
IMU加热到指定温度防止温漂IMU数据给AHRS算法
BMI088的数据
使bmi088_cali结构体中
*/
/* Includes ----------------------------------------------------------------- */
#include "task/user_task.h"
/* USER INCLUDE BEGIN */
#include "bsp/mm.h"
#include "bsp/pwm.h"
#include "component/ahrs.h"
#include "component/pid.h"
#include "device/bmi088.h"
/* USER INCLUDE END */
/* Private typedef ---------------------------------------------------------- */
/* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */
/* Private variables -------------------------------------------------------- */
/* USER STRUCT BEGIN */
BMI088_t bmi088;
AHRS_t gimbal_ahrs;
AHRS_Magn_t magn;
AHRS_Eulr_t eulr_to_send;
KPID_t imu_temp_ctrl_pid;
/*默认校准参数*/
BMI088_Cali_t cali_bmi088 = {
.gyro_offset = {0.0f, 0.0f, 0.0f},
};
static const KPID_Params_t imu_temp_ctrl_pid_param = {
.k = 0.15f,
.p = 1.0f,
.i = 0.0f,
.d = 0.0f,
.i_limit = 1.0f,
.out_limit = 1.0f,
};
/* USER STRUCT END */
/* Private function --------------------------------------------------------- */
/* Exported functions ------------------------------------------------------- */
void Task_atti_esti(void *argument) {
(void)argument; /* 未使用argument消除警告 */
osDelay(ATTI_ESTI_INIT_DELAY); /* 延时一段时间再开启任务 */
/* USER CODE INIT BEGIN */
BMI088_Init(&bmi088, &cali_bmi088);
AHRS_Init(&gimbal_ahrs, &magn, BMI088_GetUpdateFreq(&bmi088));
PID_Init(&imu_temp_ctrl_pid, KPID_MODE_NO_D,
1.0f / BMI088_GetUpdateFreq(&bmi088), &imu_temp_ctrl_pid_param);
BSP_PWM_Start(BSP_PWM_IMU_HEAT);
/* USER CODE INIT END */
while (1) {
/* USER CODE BEGIN */
BMI088_WaitNew();
BMI088_AcclStartDmaRecv();
BMI088_AcclWaitDmaCplt();
BMI088_GyroStartDmaRecv();
BMI088_GyroWaitDmaCplt();
/* 锁住RTOS内核防止数据解析过程中断造成错误 */
osKernelLock();
/* 接收完所有数据后,把数据从原始字节加工成方便计算的数据 */
BMI088_ParseAccl(&bmi088);
BMI088_ParseGyro(&bmi088);
/* 根据设备接收到的数据进行姿态解析 */
AHRS_Update(&gimbal_ahrs, &bmi088.accl, &bmi088.gyro, &magn);
/* 根据解析出来的四元数计算欧拉角 */
AHRS_GetEulr(&eulr_to_send, &gimbal_ahrs);
osKernelUnlock();
/* 在此处用消息队列传递imu数据 */
/* osMessageQueuePut( ... ); */
/* 控制IMU加热器 */
BSP_PWM_SetComp(BSP_PWM_IMU_HEAT, PID_Calc(&imu_temp_ctrl_pid, 40.5f,
bmi088.temp, 0.0f, 0.0f));
/* USER CODE END */
}
}

View File

@ -1,52 +0,0 @@
/*
cli Task
*/
/* Includes ----------------------------------------------------------------- */
#include "task/user_task.h"
/* USER INCLUDE BEGIN */
#include "device/mrobot.h"
/* USER INCLUDE END */
/* Private typedef ---------------------------------------------------------- */
/* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */
/* Private variables -------------------------------------------------------- */
/* USER STRUCT BEGIN */
/* USER STRUCT END */
/* Private function --------------------------------------------------------- */
/* USER PRIVATE CODE BEGIN */
/**
* @brief hello
* @note 0 (pdFALSE) 0
*/
static long Cli_Hello(char *buffer, size_t size, const char *cmd) {
(void)cmd; /* 未使用cmd消除警告 */
MRobot_Snprintf(buffer, size, "Ciallo(∠・ω< )⌒★\r\n");
return 0; /* 返回0表示命令执行完成 */
}
/* USER PRIVATE CODE END */
/* Exported functions ------------------------------------------------------- */
void Task_cli(void *argument) {
(void)argument; /* 未使用argument消除警告 */
osDelay(CLI_INIT_DELAY); /* 延时一段时间再开启任务 */
/* USER CODE INIT BEGIN */
/* 初始化 MRobot CLI 系统 */
MRobot_Init();
MRobot_RegisterCommand("hello", " --hello: 打印问候语\r\n", Cli_Hello, -1);
/* USER CODE INIT END */
while (1) {
/* USER CODE BEGIN */
/* 运行 MRobot 主循环 */
MRobot_Run();
/* USER CODE END */
}
}

View File

@ -1,28 +0,0 @@
atti_esti:
name: "atti_esti"
frequency: 1000
delay: 0
stack: 512
freq_control: false
description: |
带有PWM温控的纯陀螺仪BMI088姿态解算任务
功能特点:
- 控制IMU加热到指定温度防止温漂
- 收集BMI088数据给AHRS算法进行姿态解算
- 解算后得到四元数,转换为欧拉角放到消息队列
- 使用PID控制IMU温度到40.5°C
- 运行频率1000Hz提供高精度姿态信息
注意事项:
- 陀螺仪使用前需要校准校准结果保存在bmi088_cali结构体中
- 无磁力计版本,适用于干净的电磁环境
- 需要配置PWM通道用于IMU加热控制
cli:
name: "cli"
frequency: 500
delay: 0
stack: 1024
freq_control: false
description: |
命令行接口任务
通过串口实现的虚拟终端配合putty食用更佳
需要freertos_cli组件支持还有mrobot设备驱动