添加了前置知识

This commit is contained in:
NeoZng 2023-01-12 21:38:42 +08:00
parent 7b5512fb92
commit bcf7755a8a
3 changed files with 21 additions and 33 deletions

View File

@ -1,30 +1,29 @@
# 2023 EC-basic-frameworkC语言版说明 # 2023 EC basic-framework
> **代码参考了哈工深南宫小樱战队的框架设计,在此鸣谢。**
当前版本更新日期2023.01.11
当前版本更新日期2022.11.03 **==由于当前仍然处在测试开发阶段,请定期拉取(`git pull`)获取最新更新。==**
本说明仅针对电控组2023赛季框架如有变动以日期靠后的版本为准。**==由于当前仍然处在测试开发阶段,请定期拉取(`git pull`)获取最新更新。==**
## 基本信息和开发规范 ## 基本信息和开发规范
- **开发方式** - **开发方式**
本框架使用stm32cubemx生成基于makefile使用gcc-arm-none-eabi编译make命令)。 本框架使用stm32cubemx生成基于makefile使用arm gnu工具链开发利用arm-none-eabi-gcc编译make命令,命令行为mingw32-make)。
> deprecated若需使用keil5开发请在stm32cubemx的`project manager`标签页下将工具链改为MDK然后在keil中自行添加所需包含的.c文件和头文件。关于如何在keil下添加dsplib请参考文档。 > deprecated若需使用keil5开发请在stm32cubemx的`project manager`标签页下将工具链改为MDK然后在keil中自行添加所需包含的.c文件和头文件。关于如何在keil下添加dsplib请参考文档。在vscode中也有**KEIL assistant**和**Embedded IDE**插件可供使用。
> >
> ***强烈推荐使用VSCode进行开发Ozone进行调试。*** > ***强烈推荐使用VSCode进行开发Ozone进行调试。***
VSCode可通过Cortex-Debug利用OpenOCD进行调试jlink/stlink/dap-link都支持具体的使用方法和环境配置教程在[VSCode+Ozone使用方法](./VSCode+Ozone使用方法.md)中。**请使用UTF-8编码查看\&编辑此项目**。 VSCode可通过Cortex-Debug利用OpenOCD进行调试jlink/stlink/dap-link都支持具体的使用方法和环境配置教程在[VSCode+Ozone使用方法](./VSCode+Ozone使用方法.md)中。**请使用UTF-8编码查看\&编辑此项目**。
推荐使用 **SEGGER ozone** 进行调试。
- **分层** - **分层**
本框架主要代码分为**BSP、Module、APP**三层。三层的代码分别存放在同名的三个文件夹中这三个文件夹存放在根目录下。开发过程中主要编写APP层代码Module层与BSP层不建议修改。如需添加module如oled屏幕、其他传感器和外设等请按照规范编写并联系组长提交commit到dev分支完善后合并至主分支。在配置git的时候将自己的`user.name`配置成英文缩写或易懂的nick name。 本框架主要代码分为**BSP、Module、APP**三层。三层的代码分别存放在同名的三个文件夹中这三个文件夹存放在根目录下。开发过程中主要编写APP层代码Module层与BSP层不建议修改。如需添加module如oled屏幕、其他传感器和外设等请按照规范编写并联系组长提交commit到dev分支或对应的功能名分支完善后合并至主分支。在配置git的时候将自己的`user.name`配置成英文缩写或易懂的nick name。
BSP层构建与HAL之上。HAL库和实时系统、DSP支持等文件都在`HAL_N_Middlewares`文件夹下包括Cube生成的外设初始化的Inc和Src文件夹 BSP层构建于ST的HAL硬件抽象层之上。为了方便使用已经将CMSIS相关、HAL库和实时系统、DSP支持等文件都放在`HAL_N_Middlewares`文件夹下包括Cube生成的外设初始化的Inc和Src文件夹
**main.c的位置在**`HAL_N_Middlewares/Src/main.c` **main.c的位置在**`HAL_N_Middlewares/Src/main.c`
@ -111,28 +110,23 @@
- TODO - TODO
- 主要功能:实现映射功能。 - 主要功能:实现映射功能。
- 在本框架中BSP层与cube高度耦合,对该层的修改可能需要使用cube重新生成工程主要是外设的配置通信速度时钟频率和分频数等。该层也是唯一允许直接出现stm32HAL库函数的代码层**在非BSP层编写代码时如需使用HAL_...函数请思考是否有同功能的BSP_...函数**。不过由于ST的HAL已经对硬件进行较高的抽象如以handle_xxx的方式描述一个硬件外设或功能引脚因此更换开发板需要修改的内容极少。 - 在本框架中BSP层与cubeMX初始化有一定程度的耦合若没有在CUBEMX中开启某个外设则在application不能初始化使用了对应外设的module。对该层的修改可能需要使用cube重新生成工程主要是外设的配置通信速度时钟频率和分频数等。该层也是唯一允许直接出现stm32HAL库函数的代码层**在非BSP层编写代码时如需使用HAL_...函数请思考是否有同功能的BSP_...函数**。不过由于ST的HAL已经对硬件进行较高的抽象如以handle_xxx的方式描述一个硬件外设或功能引脚因此即使需要更换开发板,必须修改的内容也极少。
- 最简单的(如gpio)仅是对HAL库函数的封装。较为复杂的则会进行一定程度的处理(如can) - 最简单的(如gpio)仅是对HAL库函数的封装。较为复杂的则会进行一定程度的处理(如can)
- 补充与修改某款主控对应的BSP层应保持相同当认为该层可能缺少部分功能或有错误时请联系组长确认后解决并更新整个框架**请勿自行修改**。
**编写和使用指南**
- 补充与修改某款主控对应的BSP层应保持相同当认为该层可能缺少部分功能或有错误时请联系组长确认后解决并更新整个框架**请勿自行修改提交**。
- 代码移植BSP层也是在不同系列、型号的stm32间执行代码移植时主要需要关注的代码层。向功能更强系列移植一般只需要重配cube并重新组织BSP层的映射关系而向功能较少的系列移植还需要去掉其不支持的功能。如果仅是对同一型号的开发板进行HAL初始化配置的修改则BSP层**不需要**变动。 - 代码移植BSP层也是在不同系列、型号的stm32间执行代码移植时主要需要关注的代码层。向功能更强系列移植一般只需要重配cube并重新组织BSP层的映射关系而向功能较少的系列移植还需要去掉其不支持的功能。如果仅是对同一型号的开发板进行HAL初始化配置的修改则BSP层**不需要**变动。
- 子文件与文件夹: - 子文件与文件夹:
- bsp.c/h该层核心文件其中.h被include至main.c中以实现整个代码层的初始化。include了该层所有模块的.h并调用各模块的初始化函数。**注意**有些外设如串口和CAN不需要在bsp.c中进行模块层的初始化他们会在module层生成实例即C语言中的结构体并注册到bsp层时自动进行初始化。以此达到提高运行速度避免未使用的模块被加载的问题。 - bsp.c/h该层用于bsp基础功能初始化的文件,其中.h被include至main.c中以实现整个代码层的初始化。include了该层所有模块的.h并调用各模块的初始化函数。**注意**有些外设如串口和CAN不需要在bsp.c中进行模块层的初始化他们会在module层生成实例即C语言中的结构体并注册到bsp层时自动进行初始化。以此达到提高运行速度避免未使用的模块被加载的问题。
- bsp_xxx.c/h每一个成对的.c/h对应一种外设当上面两个代码层需要使用某个外设时这里的文件就是对应的交互接口。 - bsp_xxx.c/h每一个成对的.c/h对应一种外设当上面两个代码层需要使用某个外设时这里的文件就是对应的交互接口。
- 注册回调函数与接收:通信类外设模块有的定义了回调函数类型(函数指针类型)若调用bsp...h中的回调函数注册函数将其他位置(HAL层)定义的符合形式的函数注册为回调函数该函数在接收到数据后或其他设定位置会被调用。在module对模块进行初始化的时候需要将对应的协议解析函数进行设置代码中注释有对应提示。 - 注册回调函数与接收:通信类外设模块有的定义了回调函数类型(函数指针类型)若调用bsp...h中的回调函数注册函数将其他位置(HAL层)定义的符合形式的函数注册为回调函数该函数在接收到数据后或其他设定位置会被调用。在module对模块进行初始化的时候需要将对应的协议解析函数进行设置代码中注释有对应提示。
## Module层 ## Module层
- TODO
1. 增加模块离线/错误检测模块(官方例程中的`deteck_task`)。
3. 增加步进电机模块
4. 增加裁判系统多机通信、UI绘制模块
5. 增加舵机模块
6. 增加单点激光模块
- 主要功能实现对设备的封装如将IMU、PC、电机等视为一个完整的功能模块让应用层不需要关心其底层的具体实现直接使用接口。 - 主要功能实现对设备的封装如将IMU、PC、电机等视为一个完整的功能模块让应用层不需要关心其底层的具体实现直接使用接口。
- 子文件与子文件夹 - 文件夹
- **注意module层没有也不需要进行统一初始化**。app层的应用会包含一些模块因此由app来调用各个模块的init或register函数只有当一个module被app实例化这个模块才会存在。 - **注意module层没有也不需要进行统一初始化**。app层的应用会包含一些模块因此由app来调用各个模块的init或register函数只有当一个module被app实例化这个模块才会存在。
@ -142,7 +136,7 @@
- algorithm:该层软件库存放位置,这些功能与硬件无关,而是提供通用的数据结构和“算子”以供该层的其他部分调用,主要是算法、控制器、底盘和位姿解算等。 - algorithm:该层软件库存放位置,这些功能与硬件无关,而是提供通用的数据结构和“算子”以供该层的其他部分调用,主要是算法、控制器、底盘和位姿解算等。
- module要点 - module编写和使用指南
- 初始化: - 初始化:
@ -171,14 +165,9 @@ Module层主要存放的是类型定义和实例指针数组在该层没有
## APP层(application) ## APP层(application)
- TODO - 功能:实现机器人的控制,对机器人**控制**结构进行抽象。
1. 完成麦克纳姆轮/全向轮底盘的功能
2. 完成发射应用
3. 完成云台控制应用
4. 增加机器人整车控制应用
- 主要功能:实现机器人的控制
在完成BSP层和Module层后如果在APP层没有控制代码则代码并无实际功能。换言之BSP层与Module层的存在是为了APP层更简单、更合理、更易于扩展和移植。本框架的初始目标即是实现在APP层仅需思考逻辑并用无关硬件的C语言代码实现即可完成整个机器人的控制。所有需要使用的模块和算法都在Module层提供硬件的抽象在bsp层完成。 在完成BSP层和Module层后如果在APP层没有控制代码则代码并无实际功能。换言之BSP层与Module层的存在是为了APP层更简单、更合理、更易于扩展和移植。本框架的初始目标即是实现在APP层仅需思考逻辑并用无关硬件的C语言代码实现即可完成整个机器人的控制。所有需要使用的模块和算法都在Module层提供硬件的抽象在bsp层完成。**所有使用到的模块都在APP层初始化**因此不需要module自行初始化。
- APP层按照机械设计结构如云台、发射、底盘建立对应的子文件夹在其中完成初始化和相关逻辑功能的编写。还有用于发布指令的云台指令应用和底盘指令应用前者应该包含一个遥控器模块和一个视觉通信模块后者包含裁判系统模块。它们包含的模块都会处理一些指令和控制信息因此将这两个应用从云台和底盘应用中隔离出来。这样还可以方便兼容双板。 - APP层按照机械设计结构如云台、发射、底盘建立对应的子文件夹在其中完成初始化和相关逻辑功能的编写。还有用于发布指令的云台指令应用和底盘指令应用前者应该包含一个遥控器模块和一个视觉通信模块后者包含裁判系统模块。它们包含的模块都会处理一些指令和控制信息因此将这两个应用从云台和底盘应用中隔离出来。这样还可以方便兼容双板。
@ -190,7 +179,7 @@ Module层主要存放的是类型定义和实例指针数组在该层没有
## 文件树 ## 文件树
板级支持包的每个组件,每个moduel,每个app都有对应的说明文档. 板级支持包的每个组件,每个moduel,以及每个app都有对应的说明文档.
```shell ```shell
ROOT:. ROOT:.
│ .gitignore # git版本管理忽略文件 │ .gitignore # git版本管理忽略文件
@ -436,6 +425,3 @@ APP会调用其所有的模块的初始化函数注册函数这是因
main函数唯一需要的函数是app层的`robot.c`中的`RobotInit()`函数它首先会调用BSP初始化然后进行所有应用的初始化每个应用会调用对应模块的初始化一些依赖通信外设的模块会将通信支持相关的bsp进行初始化。初始化结束之后实时系统启动。 main函数唯一需要的函数是app层的`robot.c`中的`RobotInit()`函数它首先会调用BSP初始化然后进行所有应用的初始化每个应用会调用对应模块的初始化一些依赖通信外设的模块会将通信支持相关的bsp进行初始化。初始化结束之后实时系统启动。
> **代码参考了哈工深南宫小樱战队的框架设计,在此鸣谢。**

View File

@ -38,6 +38,7 @@ Vision_Recv_s *VisionInit(UART_HandleTypeDef *_handle)
conf.module_callback = DecodeVision; conf.module_callback = DecodeVision;
conf.recv_buff_size = VISION_RECV_SIZE; conf.recv_buff_size = VISION_RECV_SIZE;
conf.usart_handle = _handle; conf.usart_handle = _handle;
vision_usart_instance = USARTRegister(&conf); vision_usart_instance = USARTRegister(&conf);
return &recv_data; return &recv_data;
} }

View File

@ -229,6 +229,7 @@ void DJIMotorControl()
static Motor_Controller_s *motor_controller; // 电机控制器 static Motor_Controller_s *motor_controller; // 电机控制器
static DJI_Motor_Measure_s *motor_measure; // 电机测量值 static DJI_Motor_Measure_s *motor_measure; // 电机测量值
static float pid_measure, pid_ref; // 电机PID测量值和设定值 static float pid_measure, pid_ref; // 电机PID测量值和设定值
// 遍历所有电机实例,进行串级PID的计算并设置发送报文的值 // 遍历所有电机实例,进行串级PID的计算并设置发送报文的值
for (size_t i = 0; i < idx; ++i) for (size_t i = 0; i < idx; ++i)
{ // 减小访存开销,先保存指针引用 { // 减小访存开销,先保存指针引用