增加了debug文档和一些todo

This commit is contained in:
NeoZng
2023-02-22 13:53:25 +08:00
parent 7bb141af06
commit 3cf1831237
18 changed files with 248 additions and 426 deletions

View File

@@ -53,6 +53,8 @@ CubeMX进行初始化 --> VSCode编写代/进行编译/简单调试 --> Ozone变
1. 软件安装(队伍NAS和资料硬盘内提供了所有必要的依赖,安装包和插件,目录是`/EC/VSCode+Ozone环境配置`)请以公共账号登陆网盘ip地址为`49.123.113.2:5212`,账号`public@rm.cloud`,密码`public`
所有安装包也可以在此百度网盘链接下获得:[archive.zip](https://pan.baidu.com/s/1sO_EI4cToyIAcScOQx-JSg?pwd=6666)
```shell
# 网盘中的文件:
basic_framework.zip # 本仓库文件,注意,可能不为最新,建议从仓库clone并定时pull
@@ -67,11 +69,15 @@ CubeMX进行初始化 --> VSCode编写代/进行编译/简单调试 --> Ozone变
VSCodeUserSetup-x64-1.73.1.exe # VSCode安装包
```
1. C语言从源代码到.bin和.hex等机器代码的编译和链接过程
2. C语言的内存模型
3. C语言标准,动态链接库和静态编译的区别,一些编译器的常用选项
4. STM32F4系列的DBG外设工作原理
5. GDB调试器、硬件调试器和DBG的关系
2. C语言从源代码到.bin和.hex等机器代码的编译和链接过程
3. C语言的内存模型
4. C语言标准动态链接库和静态编译的区别一些编译器的常用选项
5. STM32F4系列的DBG外设工作原理
6. GDB调试器、硬件调试器和DBG的关系
### 编译全过程
@@ -81,7 +87,7 @@ C语言代码由固定的词汇关键字按照固定的格式语法
对于单个.c文件从C语言开始到单片机可识别的.bin文件一般要经历以下几步
![img](assets\v2-2797ea99d0d38eb9996993bb0ad77ab2_720w.webp)
![img](assets/v2-2797ea99d0d38eb9996993bb0ad77ab2_720w.webp)
首先是编译**预处理**Preprocessing这一步会展开宏并删除注释将多余的空格去除。预处理之后会生成.i文件。
@@ -97,7 +103,7 @@ C语言代码由固定的词汇关键字按照固定的格式语法
### C语言内存模型
<img src="assets\image-20221112160213066.png" alt="image-20221112160213066" style="zoom:80%;" />
<img src="assets/image-20221112160213066.png" alt="image-20221112160213066" style="zoom:80%;" />
以上是C语言常见的内存模型即C语言的代码块以及运行时使用的内存包括函数、变量等的组织方式。
@@ -127,7 +133,7 @@ RTOS创建任务的时候也会为每个任务分配一定的栈空间它会
### Debug外设工作原理
![image-20221112145717063](assets\image-20221112145717063.png)
![image-20221112145717063](assets/image-20221112145717063.png)
DBG支持模块红框标注部分也可以看作一个外设通过一条专用的AHB-AP总线和调试接口相连Jtag或swd并且有与**数据**和**外设**总线直接相连的桥接器。它还同时连接了中断嵌套管理器因此同样可以捕获中断并进行debug和ITM、DWT、FPB这些调试支持模块。因此DBG可以直接获取内存或片上外设内的数据而不需要占用CPU的资源并将这些数据通过专用外设总线发送给调试器进而在上位机中读取。
@@ -153,7 +159,7 @@ ITM是instrument trace macrocell指令追踪宏单元的缩写它用于提供
### 字节对齐
这是内存硬件设计和汇编语言设计的结果。在使用结构体的时候如果你不做任何事情编译器会自动帮助你完成字节对齐以提高内存访问的效率。stm32是4字节地址和数据总线的设计单词可以传输32位数据因此访问4字节数据也就是stm32的“字”“字长”效率最高。然而历史的缘由导致i一个内存地址只存储8位的数据如果你要访问float数据则一次需要读取4个地址。当这四个地址是连续的时候你只需要一次就可以将数据读出。然而如果一个float数据被存放在0x03-0x07这四个地址cpu首先要读出0x00-0x03这四个连续的地址然后再取出最后一个字节随后读取0x04-0x07这四个连续的字节再取出前三个字节最后将最后一个字节和前三个字节拼接在一起形成我们需要的float数据。
这是内存硬件设计和汇编语言设计的结果。在使用结构体的时候如果你不做任何事情编译器会自动帮助你完成字节对齐以提高内存访问的效率。stm32是4字节地址和数据总线的设计单词可以传输32位数据因此访问4字节数据也就是stm32的“字”“字长”效率最高。然而历史的缘由导致一个内存地址只存储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等外设接收数据的时候都是连续的不会像结构体一样被编译器对齐在声明时采用如下的方式
@@ -201,15 +207,15 @@ typedef struct
- **Cortex-Debug****Cortex-Debug: Device Support Pack - STM32F4**提供调试支持。cortex debug还会自动帮助你安装一些调试相关的插件。
- **IntelliCode****Makfile Tools**:提供代码高亮支持
![image-20221112172157533](assets\image-20221112172157533.png)
![image-20221112172157533](assets/image-20221112172157533.png)
![image-20221112172208749](assets\image-20221112172208749.png)
![image-20221112172208749](assets/image-20221112172208749.png)
![image-20221112172221756](assets\image-20221112172221756.png)
![image-20221112172221756](assets/image-20221112172221756.png)
![image-20221112172239386](assets\image-20221112172239386.png)
![image-20221112172239386](assets/image-20221112172239386.png)
![image-20221112172254809](assets\image-20221112172254809.png)
![image-20221112172254809](assets/image-20221112172254809.png)
@@ -219,17 +225,17 @@ typedef struct
- 安装MinGW等待界面如下will be deprecated soon请注意这种方法将会在主分支发布正式版的时候删除
![image-20221112172051589](assets\image-20221112172051589.png)
![image-20221112172051589](assets/image-20221112172051589.png)
安装好后打开MinGW后将所有的支持包勾选然后安装
![image-20221112172348408](assets\image-20221112172348408.png)
![image-20221112172348408](assets/image-20221112172348408.png)
![image-20221112172420037](assets\image-20221112172420037.png)
![image-20221112172420037](assets/image-20221112172420037.png)
安装完以后将MinGW的bin文件夹添加到环境变量中的path下按下菜单键搜索**编辑系统环境变量**打开之后:
![image-20221112172716320](assets\image-20221112172716320.png)
![image-20221112172716320](assets/image-20221112172716320.png)
图片看不清请打开原图。验证安装:
@@ -239,7 +245,7 @@ typedef struct
- 配置gcc-arm-none-eabi环境变量**把压缩包解压以后放在某个地方**然后同上将工具链的bin添加到PATHwill be deprecated soon请注意这种方法将会在主分支发布正式版的时候删除
![image-20221112172858593](assets\image-20221112172858593.png)
![image-20221112172858593](assets/image-20221112172858593.png)
<center>安装路径可能不一样,这里要使用你自己的路径而不是直接抄</center>
@@ -257,11 +263,11 @@ typedef struct
在project manager标签页工具链选择makefile
![image-20221112173534670](assets\image-20221112173534670.png)
![image-20221112173534670](assets/image-20221112173534670.png)
生成的目录结构如下:
![image-20221112174211802](assets\image-20221112174211802.png)
![image-20221112174211802](assets/image-20221112174211802.png)
Makefile就是我们要使用的构建规则文件。
@@ -291,7 +297,7 @@ VSCode常用快捷键包括
为了提供完整的代码高亮支持需要配置Makefile tools插件的make程序路径`ctrl+,`打开设置搜索make path找到设置并填写
![image-20221113152513343](assets\image-20221113152513343.png)
![image-20221113152513343](assets/image-20221113152513343.png)
> mingw32-make就是下面介绍的make工具配合makefile替代手动调用gcc。这里之所以只要输入mingw32-make而不用完整路径是因为我们将mingw的bin文件夹加入环境变量了因此系统会在PATH下自动寻找对应项
@@ -317,7 +323,7 @@ mingw32-make -j24 # -j参数表示参与编译的线程数,一般使用-j12
>
> 我对make的编译命令进行了静默处理只输出error和warning以及最后的生成文件信息。如果想要解除静默就是下面所说的“你可以看到大致如下的输出”需要修改Makefile。**本仓库下的makefile中已经用注释标明。**
![image-20221112191712534](assets\image-20221112191712534.png)
![image-20221112191712534](assets/image-20221112191712534.png)
就会开始编译了。你可以看到大致如下的输出:
@@ -363,7 +369,7 @@ arm-none-eabi-objcopy -O binary -S build/basic_framework.elf build/basic_framewo
这样你就可以点击VSCode工具栏上方的Terminal->Run task选择你刚刚配置的任务开始编译了。**更方便的方法是使用快捷键:`ctrl+shift+B`。** 之后要配置下载任务和调试任务等也可以利用这种方法新建一个xxx_task实现一键下载、一键调试等。
![image-20221112192133103](assets\image-20221112192133103.png)
![image-20221112192133103](assets/image-20221112192133103.png)
> 还没配置任务的时候需要在Terminal标签页中选择Configure Tasks... 创建一个新的.json文件。
>
@@ -373,13 +379,13 @@ arm-none-eabi-objcopy -O binary -S build/basic_framework.elf build/basic_framewo
Makefile的大部分内容在CubeMX初始化的时候就会帮你生成。如果新增了.c的源文件你需要在`C_SOURCES`中新增:
![image-20221112192509718](assets\image-20221112192509718.png)
![image-20221112192509718](assets/image-20221112192509718.png)
换行需要在行尾加反斜杠\\
如果新增了头文件,在`C_INCLUDES`中新增头文件所在的文件夹:
![image-20221112192610543](assets\image-20221112192610543.png)
![image-20221112192610543](assets/image-20221112192610543.png)
换行需要在行尾加反斜杠\\
@@ -423,7 +429,7 @@ VSCode `ctrl+,`进入设置,通过`搜索`找到cortex-debug插件的设置。
然后选择run and debug标签页在选项中选择你配置好的选项开始调试。**或者使用快捷键:`F5`。**
![image-20221112180103750](assets\image-20221112180103750.png)
![image-20221112180103750](assets/image-20221112180103750.png)
我们的仓库中默认提供了两种下载器的支持dap-link无线调试器属于这一种和j-link包括小的j-link OB和黑色大盒子jlink
@@ -431,13 +437,13 @@ VSCode `ctrl+,`进入设置,通过`搜索`找到cortex-debug插件的设置。
开始调试后,显示的界面如下:
![](assets\vscodedebug.png)
![](assets/vscodedebug.png)
1. 变量查看窗口包括当前调用栈当前作用域或代码块内的局部变量、当前文件的静态变量和全局变量。register选项卡可以查看cpu内核的寄存器数值。
2. 变量watch窗口。右键单击要查看的变量选择watch加入查看。
![image-20221113131044191](assets\image-20221113131044191.png)
![image-20221113131044191](assets/image-20221113131044191.png)
还支持直接运行到指针所选处Run to Cursor以及直接跳转到指针处执行Jump to Cursor。添加行内断点若一个表达式由多个表达式组成也是很方便的功能可以帮助进一步定位bug。
@@ -445,7 +451,7 @@ VSCode `ctrl+,`进入设置,通过`搜索`找到cortex-debug插件的设置。
VSCode提供的一个最大的便利就是你可以将鼠标悬停在需要查看的变量上**不需要添加到watch就能观察变量值。**如果是指针还可以自动解析,获取解引用后的值。结构体也支持直接展开。
![image-20221113133624273](assets\image-20221113133624273.png)
![image-20221113133624273](assets/image-20221113133624273.png)
3. 调用栈。表明在进入当前代码块之前调用了哪些函数,称之为栈也是因为调用的顺序从下至上。当前函数结束之后栈指针会减小,控制权会返还给上一级的调用者。通过调用栈可以确认程序是**如何**(按怎样的顺序)运行到当前位置的。
@@ -545,7 +551,7 @@ VSCode `ctrl+,`进入设置,通过`搜索`找到cortex-debug插件的设置。
安装好两个软件之后打开ozone后会显示一个new project wizard如果没有打开在工具栏的File-> New -> New project wizard。
![image-20221113133904084](assets\image-20221113133904084.png)
![image-20221113133904084](assets/image-20221113133904084.png)
选择M4内核为了能够查看外设寄存器的值还需要svd文件。所有mcu的svd都在图中的文件夹里提供当然你也可以使用我们仓库根目录下的文件。
@@ -553,11 +559,11 @@ VSCode `ctrl+,`进入设置,通过`搜索`找到cortex-debug插件的设置。
接口选择swd接口速度不需要太高如果调试的时候需要观察大量的变量并且使用日志功能可以调高这个值。如果连接了jlikn上面的窗口中会显示。如果链接了dap-link比如无线调试器会出现Unknown CMSIS-dap。选择你要使用的调试器然后继续。
![image-20221113134252407](assets\image-20221113134252407.png)
![image-20221113134252407](assets/image-20221113134252407.png)
选择构建之后生成的.elf文件在项目文件夹下的build中。这是调试器专用的文件格式对其内容感兴趣可以自行搜索细节。此外ozone还支持.bin .hex .axf最后一个是amr-cc也就是keil的工具链会生成的等格式。
![image-20221113134605331](assets\image-20221113134605331.png)
![image-20221113134605331](assets/image-20221113134605331.png)
这页不要动。如果希望保存jlink的调试日志最后一个选项选择一个文件或者新建一个日志文件。
@@ -583,7 +589,7 @@ Project.SetOSPlugin(“plugin_name”)
下图的配置是笔者常用的layout。每个窗口是否显示、放在什么位置等都是可以自己定义的。通过工具栏的view选项卡可以自行选择需要展示的窗口。
![](assets\ozone.png)
![](assets/ozone.png)
1. 调试控制和vscode类似
@@ -642,7 +648,7 @@ Project.SetOSPlugin(“plugin_name”)
- 如果当前文件没有你要的变量你想查看项目中的其他文件夹在view-> source files中可以打开该项目所有的源文件双击可以打开源文件。
![image-20221113142448939](assets\image-20221113142448939.png)
![image-20221113142448939](assets/image-20221113142448939.png)
- **日志打印**