mirror of
https://gitee.com/dlmu-cone/bf_original_balance_chassis
synced 2026-07-25 03:47:47 +08:00
增加了debug文档和一些todo
This commit is contained in:
@@ -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文件,一般要经历以下几步:
|
||||
|
||||

|
||||

|
||||
|
||||
首先是编译**预处理**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外设工作原理
|
||||
|
||||

|
||||

|
||||
|
||||
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**:提供代码高亮支持
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
|
||||
@@ -219,17 +225,17 @@ typedef struct
|
||||
|
||||
- 安装MinGW,等待界面如下:(will be deprecated soon,请注意这种方法将会在主分支发布正式版的时候删除)
|
||||
|
||||

|
||||

|
||||
|
||||
安装好后,打开MinGW后将所有的支持包勾选,然后安装:
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
安装完以后,将MinGW的bin文件夹添加到环境变量中的path下,按下菜单键搜索**编辑系统环境变量**打开之后:
|
||||
|
||||

|
||||

|
||||
|
||||
图片看不清请打开原图。验证安装:
|
||||
|
||||
@@ -239,7 +245,7 @@ typedef struct
|
||||
|
||||
- 配置gcc-arm-none-eabi环境变量,**把压缩包解压以后放在某个地方**,然后同上,将工具链的bin添加到PATH:(will be deprecated soon,请注意这种方法将会在主分支发布正式版的时候删除)
|
||||
|
||||

|
||||

|
||||
|
||||
<center>安装路径可能不一样,这里要使用你自己的路径而不是直接抄</center>
|
||||
|
||||
@@ -257,11 +263,11 @@ typedef struct
|
||||
|
||||
在project manager标签页工具链选择makefile
|
||||
|
||||

|
||||

|
||||
|
||||
生成的目录结构如下:
|
||||
|
||||

|
||||

|
||||
|
||||
Makefile就是我们要使用的构建规则文件。
|
||||
|
||||
@@ -291,7 +297,7 @@ VSCode常用快捷键包括:
|
||||
|
||||
为了提供完整的代码高亮支持,需要配置Makefile tools插件的make程序路径,`ctrl+,`打开设置,搜索make path找到设置并填写:
|
||||
|
||||

|
||||

|
||||
|
||||
> mingw32-make就是下面介绍的make工具(配合makefile替代手动调用gcc)。这里之所以只要输入mingw32-make而不用完整路径,是因为我们将mingw的bin文件夹加入环境变量了,因此系统会在PATH下自动寻找对应项
|
||||
|
||||
@@ -317,7 +323,7 @@ mingw32-make -j24 # -j参数表示参与编译的线程数,一般使用-j12
|
||||
>
|
||||
> 我对make的编译命令进行了静默处理,只输出error和warning以及最后的生成文件信息。如果想要解除静默(就是下面所说的“你可以看到大致如下的输出”),需要修改Makefile。**本仓库下的makefile中已经用注释标明。**
|
||||
|
||||

|
||||

|
||||
|
||||
就会开始编译了。你可以看到大致如下的输出:
|
||||
|
||||
@@ -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,实现一键下载、一键调试等。
|
||||
|
||||

|
||||

|
||||
|
||||
> 还没配置任务的时候,需要在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`中新增:
|
||||
|
||||

|
||||

|
||||
|
||||
换行需要在行尾加反斜杠\\
|
||||
|
||||
如果新增了头文件,在`C_INCLUDES`中新增头文件所在的文件夹:
|
||||
|
||||

|
||||

|
||||
|
||||
换行需要在行尾加反斜杠\\
|
||||
|
||||
@@ -423,7 +429,7 @@ VSCode `ctrl+,`进入设置,通过`搜索`找到cortex-debug插件的设置。
|
||||
|
||||
然后选择run and debug标签页,在选项中选择你配置好的选项,开始调试。**或者使用快捷键:`F5`。**
|
||||
|
||||

|
||||

|
||||
|
||||
我们的仓库中默认提供了两种下载器的支持,dap-link(无线调试器属于这一种)和j-link(包括小的j-link OB和黑色大盒子jlink)。
|
||||
|
||||
@@ -431,13 +437,13 @@ VSCode `ctrl+,`进入设置,通过`搜索`找到cortex-debug插件的设置。
|
||||
|
||||
开始调试后,显示的界面如下:
|
||||
|
||||

|
||||

|
||||
|
||||
1. 变量查看窗口,包括当前调用栈(当前作用域或代码块)内的局部变量、当前文件的静态变量和全局变量。register选项卡可以查看cpu内核的寄存器数值。
|
||||
|
||||
2. 变量watch窗口。右键单击要查看的变量,选择watch加入查看。
|
||||
|
||||

|
||||

|
||||
|
||||
还支持直接运行到指针所选处(Run to Cursor)以及直接跳转到指针处执行(Jump to Cursor)。添加行内断点(若一个表达式由多个表达式组成)也是很方便的功能,可以帮助进一步定位bug。
|
||||
|
||||
@@ -445,7 +451,7 @@ VSCode `ctrl+,`进入设置,通过`搜索`找到cortex-debug插件的设置。
|
||||
|
||||
VSCode提供的一个最大的便利就是,你可以将鼠标悬停在需要查看的变量上,**不需要添加到watch就能观察变量值。**如果是指针还可以自动解析,获取解引用后的值。结构体也支持直接展开。
|
||||
|
||||

|
||||

|
||||
|
||||
3. 调用栈。表明在进入当前代码块之前调用了哪些函数,称之为栈也是因为调用的顺序从下至上。当前函数结束之后栈指针会减小,控制权会返还给上一级的调用者。通过调用栈可以确认程序是**如何**(按怎样的顺序)运行到当前位置的。
|
||||
|
||||
@@ -545,7 +551,7 @@ VSCode `ctrl+,`进入设置,通过`搜索`找到cortex-debug插件的设置。
|
||||
|
||||
安装好两个软件之后,打开ozone后会显示一个new project wizard,如果没有打开,在工具栏的File-> New -> New project wizard。
|
||||
|
||||

|
||||

|
||||
|
||||
选择M4内核,为了能够查看外设寄存器的值还需要svd文件。所有mcu的svd都在图中的文件夹里提供,当然你也可以使用我们仓库根目录下的文件。
|
||||
|
||||
@@ -553,11 +559,11 @@ VSCode `ctrl+,`进入设置,通过`搜索`找到cortex-debug插件的设置。
|
||||
|
||||
接口选择swd,接口速度不需要太高,如果调试的时候需要观察大量的变量并且使用日志功能,可以调高这个值。如果连接了jlikn,上面的窗口中会显示。如果链接了dap-link,比如无线调试器,会出现Unknown CMSIS-dap。选择你要使用的调试器,然后继续。
|
||||
|
||||

|
||||

|
||||
|
||||
选择构建之后生成的.elf文件(在项目文件夹下的build中)。这是调试器专用的文件格式,对其内容感兴趣可以自行搜索细节。此外ozone还支持.bin .hex .axf(最后一个是amr-cc,也就是keil的工具链会生成的)等格式。
|
||||
|
||||

|
||||

|
||||
|
||||
这页不要动。如果希望保存jlink的调试日志,最后一个选项选择一个文件或者新建一个日志文件。
|
||||
|
||||
@@ -583,7 +589,7 @@ Project.SetOSPlugin(“plugin_name”)
|
||||
|
||||
下图的配置是笔者常用的layout。每个窗口是否显示、放在什么位置等都是可以自己定义的。通过工具栏的view选项卡可以自行选择需要展示的窗口。
|
||||
|
||||

|
||||

|
||||
|
||||
1. 调试控制:和vscode类似
|
||||
|
||||
@@ -642,7 +648,7 @@ Project.SetOSPlugin(“plugin_name”)
|
||||
|
||||
- 如果当前文件没有你要的变量,你想查看项目中的其他文件夹,在view-> source files中可以打开该项目所有的源文件,双击可以打开源文件。
|
||||
|
||||

|
||||

|
||||
|
||||
- **日志打印**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user