新增了教程和注释以及文档
This commit is contained in:
parent
637d7de114
commit
4e2b750037
|
@ -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 */
|
||||
|
|
|
@ -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
14
TODO.md
|
@ -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
|
||||
|
|
|
@ -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`(文件中已经添加,需要的话取消注释即可)。
|
||||
|
|
|
@ -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); // 获取接收数据指针
|
||||
|
||||
|
|
|
@ -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/"下)
|
Loading…
Reference in New Issue