新增了教程和注释以及文档

This commit is contained in:
NeoZng 2023-02-09 00:09:28 +08:00
parent 637d7de114
commit 4e2b750037
6 changed files with 66 additions and 18 deletions

View File

@ -31,6 +31,7 @@
#include "daemon.h"
#include "robot.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@ -145,6 +146,8 @@ void MX_FREERTOS_Init(void) {
void StartDefaultTask(void const * argument)
{
/* init code for USB_DEVICE */
USB_ResetPort(USB_OTG_FS);
USBD_FS_SPEED
MX_USB_DEVICE_Init();
/* USER CODE BEGIN StartDefaultTask */
/* Infinite loop */

View File

@ -10,9 +10,9 @@
- **开发方式**
本框架使用stm32cubemx生成基于makefile使用arm gnu工具链开发利用arm-none-eabi-gcc编译make命令,命令行为mingw32-make
本框架使用stm32cubemx生成基于makefile编译系统后期拟修改为cmake+nijna+makefile以提高编译速度对于目前的版本您可以考虑自行安装ccache以提高编译速度使用arm gnu工具链开发利用arm-none-eabi-gcc编译make命令,命令行为mingw32-make
> deprecated若需使用keil5开发请在stm32cubemx的`project manager`标签页下将工具链改为MDK然后在keil中自行添加所需包含的.c文件和头文件。关于如何在keil下添加dsplib请参考文档。在vscode中也有**KEIL assistant**和**Embedded IDE**插件可供使用。
> ***==deprecated==***若需使用keil5开发请在stm32cubemx的`project manager`标签页下将工具链改为MDK然后在keil中自行添加所需包含的.c文件和头文件。关于如何在keil下添加dsplib请参考文档。在vscode中也有**KEIL assistant**和**Embedded IDE**插件可供使用。
>
> ***强烈推荐使用VSCode进行开发Ozone进行调试。***

14
TODO.md
View File

@ -30,7 +30,7 @@
#### bsp_gpio
- [ ] 增加GPIO引脚的控制有待商榷是否需要单独添加HAL实际上已经提供较好的封装
- [x] 增加GPIO引脚的控制有待商榷是否需要单独添加HAL实际上已经提供较好的封装
#### bsp_usb
@ -76,8 +76,8 @@
#### refereeUI
- [ ] 提供UI绘制封装
- [ ] 绘制电容剩余容量/当前底盘状态/当前云台状态/底盘位置/射表
- [x] 提供UI绘制封装
- [x] 绘制电容剩余容量/当前底盘状态/当前云台状态/底盘位置/射表
- [ ] 绘制视觉识别UI/识别状态/击打状态
#### ==master_machine==
@ -113,7 +113,7 @@
需要重写部分数据结构并在bsp_spi完成之后移植到新的bsp上。等待bsp_spi的测试
- [ ] 重构imu模块
- [x] 重构imu模块
#### remote_control
@ -133,7 +133,7 @@
#### controller
- [ ] 增加前馈数据
- [x] 增加前馈数据
#### user_lib
@ -154,7 +154,7 @@
#### referee_communication
- [ ] 增加裁判系统多机通信功能
- [x] 增加裁判系统多机通信功能
#### controller
@ -204,7 +204,7 @@
#### robot_cmd
- [ ] 解耦各个应用的运行模式
- [x] 解耦各个应用的运行模式
- [ ] 优化消息发布和接收性能
#### gimbal

View File

@ -6,7 +6,7 @@
> TODO
>
> 1. 添加一键编译+启用ozone调试d 脚本,使得整个进一步流程自动化
> 1. 添加一键编译+启用ozone调试脚本使得整个进一步流程自动化
> 2. 增加更多的背景知识介绍
> 3. 增加VSCode下RTT viewer的支持
@ -149,6 +149,32 @@ ITM是instrument trace macrocell指令追踪宏单元的缩写它用于提供
> 而对于直接运行在电脑上的程序(.exe就不需要GDBserver和物理调试器GDB程序可以直接访问电脑上运行的程序和CPU的寄存器等。
### 字节对齐
这是内存硬件设计和汇编语言设计的结果。在使用结构体的时候如果你不做任何事情编译器会自动帮助你完成字节对齐以提高内存访问的效率。stm32是4字节地址和数据总线的设计单词可以传输32位数据因此访问4字节数据也就是stm32的“字”“字长”效率最高。然而历史的缘由导致i一个内存地址只存储8位的数据如果你要访问float数据则一次需要读取4个地址。当这四个地址是连续的时候你只需要一次就可以将数据读出。然而如果一个float数据被存放在0x03-0x07这四个地址cpu首先要读出0x00-0x03这四个连续的地址然后再取出最后一个字节随后读取0x04-0x07这四个连续的字节再取出前三个字节最后将最后一个字节和前三个字节拼接在一起形成我们需要的float数据。
`#pragma`可能是最复杂的预编译指令,不同的编译器支持不同的`#pragma`指令,如常用的`#pragma once`可以替代header guard。arm gnu gcc编译器支持通过`#pragma pack()`来设置字节对齐,支持的对齐参数包括空/1/2/4/8会启动对应长度的对齐方式。用于通信的结构体串口/CAN/spi等外设接收数据的时候都是连续的不会像结构体一样被编译器对齐在声明时采用如下的方式
```c
#pragma pack(1) // 从这句话开始,使用字节对齐(1),即紧凑,关闭对齐
typedef struct
{
uint8_t id;
// ...
} CANInstance;
#pragma pack() // 从这里开始,恢复默认配置,一般来说默认配置是 pack(4),如果遇到double/longlong等也会变为8字节对齐
// 使用两个#pragma包裹你的结构体声明
```
如果您有兴趣,可以了解一下内存硬件的组织和连接方式,包括奇偶地址/片选/行列扩展等,可以帮助你更好地理解字节对齐。
## 环境配置
> ***所有需要编辑的配置文件都已经在basic_framework的仓库中提供如果不会写照猫画虎。***
@ -172,7 +198,7 @@ ITM是instrument trace macrocell指令追踪宏单元的缩写它用于提供
- **C/C++**提供C/C++的调试和代码高亮支持
- **Better C++ Syntax**:提供更丰富的代码高亮和智能提示
- **C/C++ Snippets**:提供代码块(关键字)补全
- **Cortex-Debug****Cortex-Debug: Device Support Pack - STM32F4**:提供调试支持
- **Cortex-Debug****Cortex-Debug: Device Support Pack - STM32F4**:提供调试支持。cortex debug还会自动帮助你安装一些调试相关的插件。
- **IntelliCode****Makfile Tools**:提供代码高亮支持
![image-20221112172157533](assets\image-20221112172157533.png)
@ -425,7 +451,9 @@ VSCode `ctrl+,`进入设置,通过`搜索`找到cortex-debug插件的设置。
4. 片上外设。这里可以查看外设的**控制寄存器**和**状态寄存器**的值如果通过断点无法定位bug则需要查找数据手册和Cortex M4指南的相关内容根据寄存器值来判断程序当前的情况。
5. 断点。所有添加的断点都会显示于此注意不像我们自己的电脑单片机的DBG外设对断点的数量有限制资源所限超过5个断点会导致debug失败此时将断点减少即可。
5. 断点。所有添加的断点都会显示于此注意不像我们自己的电脑单片机的DBG外设对断点的数量有限制资源所限超过5个断点会导致debug失败此时将断点减少即可。由于单行代码编译之后可能会对应多条汇编指令或一条表达式由多个表达式构成你还可以插入**行内断点**以逐个执行表达式或汇编语句,你还可以在汇编窗口插入断点调试汇编代码,帮助你发现错误。
对于不方便判断何时需要停止代码执行进行观察和测试的情况,你可以右键行号左侧的断点栏插入条件断点,输入表达式,当表达式满足时才会进入断点。
6. 调试控制台。调试器输出的信息会显示在这里,要**查看**和**追踪**的变量的信息也会显示在这里。如果调试出现问题报错信息同样也会在这里显示。要是出现异常可以复制这里的信息在搜索引擎里查找答案不过最好的方法是查询gdb和openocd的官方文档。
@ -452,9 +480,23 @@ VSCode `ctrl+,`进入设置,通过`搜索`找到cortex-debug插件的设置。
建议安装以下插件:
1. Hex Hover Converter鼠标悬停在数值上的时候会自动显示其对应的16、2、10进制值和编码
2. Hex Editor在查看汇编代码和机器代码的时候提供2、10、16进制转换并且可以以16进制或2进制的格式编辑文件。
3. GitLens提供强大的可视化Git支持
4. Blockman - Highlight Nested Code Blocks 此插件会高亮嵌套的代码块即花括号包围的部分或for/while/ifelse代码块
5. bookmark提供代码中插入书签的功能从而快速在页面间跳转。
6. Code Issue Manager为团队提供issues和todo管理方便协同开发
7. github copilot超强超快需要一些小钱
8. `ctrl+k ctrl+s`配置属于你的快捷键,提高效率!
---
@ -885,7 +927,7 @@ download_jlink:
首先设定了flash烧录区的起始地址下面两个构建目标分别用于daplink和jlink的下载。我们统一使用openocd进行烧录。命令中`-c`表明的是启动openocd之后要执行的命令openocd作为一个gdbserver是用作调试的因此这里我们在`flash write_image`之后直接`reset`让单片机复位开始运行程序,然后立刻退出调试,从而达到下载程序运行但不调试的目的。
接下来我们希望能够直接下载,不要在命令行里面输入`make download_dap`这么复杂的指令因此在tasks.json中添加如下两个任务
接下来我们希望能够直接下载,不要在命令行里面输入`make download_dap`这么复杂的指令,我们可以利用make构建伪造目标来实现命令行命令执行因此在tasks.json中添加如下两个任务
```json
{
@ -906,6 +948,7 @@ download_jlink:
"isDefault": false,
}
},
// 实际上也可以直接编写命令行指令,他们是等效的
```
这样在工具栏的Terminal页面就可以选择对应的任务直接下载执行了。你也可以通过快捷键`ctrl+shift+B`唤起任务执行页面进行选择。如果你希望立刻检验你代码修改的效果,在下载之前进行编译,那么在`command`信息下新增加一个`mingw32-make -j24`即可,或者添加一个`preLaunchTask`。对于调试如果不想点两下想在修改代码之后直接调试也可以在launch.json中增加`preLaunchTask`(文件中已经添加,需要的话取消注释即可)。

View File

@ -12,7 +12,7 @@ __weak void USBTransmitCpltCallback(uint32_t len)
uint8_t *USBInit()
{
USB_ResetPort(USB_OTG_FS); // 上电后重新枚举usb设备
// 上电后重新枚举usb设备
USBTransmit((uint8_t *)"USB DEVICE READY", sizeof("USB DEVICE READY")); // 发送初始化完成信息
bsp_usb_rx_buffer = CDCInitRxbufferNcallback(USBTransmitCpltCallback); // 获取接收数据指针

View File

@ -3,10 +3,12 @@
> 仅修改引脚位置和外设配置时
1. 在generate code之前保存Makefile的副本 (因为修改了makefile的内容,添加了注释和伪构建目标,HAL无法正确识别格式导致直接其将整个文件清空)
2. 生成之后将原makefile的内容替换到新的makefile中
3. 将原main.c和freertos.c以及stm32f4xx_it.c替换到新的Src文件夹下 (Src的内容不用修改,**除非你新增了功能,那么需要将新增的初始化头文件`xxx.h`包含到main函数中,然后调用其对应的`MX_xxx_Init()`函数对硬件进行初始化**)
4. 将新生成的Src,Inc,Driver/STM32F4xx_HAL_Driver放入HAL_N_Middlewares下的对应位置(第三个目录只有新增了功能的时候才需要添加)
2. 生成之后将原makefile的内容替换到新的makefile中,注意保留新添加的src code和include path.
3. 将原main.c和freertos.c以及stm32f4xx_it.c替换到新的Src文件夹下 (Src的内容不用修改,**除非你新增了功能,那么需要将新增的初始化头文件`xxx.h`包含到main函数中,然后调用其对应的`MX_xxx_Init()`函数对硬件进行初始化**)如果在cubemx中配置了新的硬件,则main.c将会包含新的头文件并添加MX_xxx_Init()以供外设初始化.freertos中会新增任务的声明和定义. 对于这两个文件将之前的内容覆写到新的文件中即可(注意不要把新生成的东西覆盖).
4. 将新生成的Src,Inc,Driver/STM32F4xx_HAL_Driver放入HAL_N_Middlewares下的对应位置(第三个目录只有新增了功能的时候才需要添加).Middlewares在大部分时候不需要更新,直接删除根目录下的Middlewares文件夹.(内部包含ST的usb库和segger的rtt viewer支持,如果新增了usb功能则需要将st的部分复制到HAL_N_Middlewares/Middletowns/ST下)
5. 删除根目录下的Drivers & Src & Inc & Middlewares文件夹.
6. 一切搞定之后,重新编译你的代码
> Q:为什么这么做?
> A:CubeMX生成的依赖库和文件有很大的冗余,占用空间较多.为了方便pull&push已经将Driver和Middlewares中不需要的文件全部删除. 修改HAL的配置(在没有新增其他库和依赖的情况下,大部分我们的更改都属于这种情况)大多是对初始化配置,即放在Inc和Src下的文件进行修改;若新增了功能,可能还会新增Driver/STM32F4xx_HAL_Driver的内容(比如新添加了flash或iic,原来没有这两个功能).
> A:CubeMX生成的依赖库和文件有很大的冗余,占用空间较多.为了方便pull&push并精简仓库,已经将Driver和Middlewares中不需要的文件全部删除. 修改HAL的配置(在没有新增其他库和依赖的情况下,大部分我们的更改都属于这种情况)大多是对初始化配置,即放在Inc和Src下的文件进行修改;若新增了功能,可能还会新增Driver/STM32F4xx_HAL_Driver的内容(比如新添加了flash或iic,原来没有这两个功能). 实际上最节省空间的方式是生成软链接(快捷方式),将你需要的依赖文件在必要的时候链接到你的可执行文件中(你在cubemx内部已经下载了f4开发包,应该放在"用户名/STM32Cubemx/"下)