修改文档文件夹位置,添加部分文档

This commit is contained in:
NeoZng
2023-06-14 20:07:39 +08:00
parent 12796f8e70
commit 0eec5d762b
64 changed files with 107 additions and 164 deletions

View File

@@ -9,8 +9,6 @@
> 1. 添加一键编译+启用ozone调试脚本使得整个进一步流程自动化
> 2. 增加更多的背景知识介绍
## 前言
了解过嵌入式开发的你一定接触过Keil这款20世纪风格UI的IDE伴随很多人度过了学习单片机的岁月。然而由于其缺少代码补全、高亮和静态检查的支持以及为人诟病的一系列逆天的设置、极慢的编译速度特别是在开发HAL库时很多开发者开始转向其他IDE。
@@ -57,7 +55,7 @@ CubeMX进行初始化 --> VSCode编写代/进行编译/简单调试 --> Ozone变
```shell
# 网盘中的文件:
basic_framework.zip # 本仓库文件,注意,可能不为最新,建议从仓库clone并定时pull
daplink_register_license.rar # daplink license注册机
daplink_register_license.rar # daplink license注册机
gcc-arm-none-eabi-10.3-2021.10-win32.zip # arm-gnu-toolchain
JLinkARM.dll # 修改过的jlink运行链接库
JLink_Windows_V722b.exe # JLink软件包
@@ -86,7 +84,7 @@ C语言代码由固定的词汇关键字按照固定的格式语法
对于单个.c文件从C语言开始到单片机可识别的.bin文件一般要经历以下几步
![img](assets/v2-2797ea99d0d38eb9996993bb0ad77ab2_720w.webp)
![img](.assets/v2-2797ea99d0d38eb9996993bb0ad77ab2_720w.webp)
首先是编译**预处理**Preprocessing这一步会展开宏并删除注释将多余的空格去除。预处理之后会生成.i文件。
@@ -102,7 +100,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语言的代码块以及运行时使用的内存包括函数、变量等的组织方式。
@@ -112,7 +110,7 @@ C语言代码由固定的词汇关键字按照固定的格式语法
然后就是最重要的**堆**和**栈**。在一个代码块内定义的变量会被放在栈区,一旦离开作用域(出了它被定义的`{}`的区域),就会立刻被销毁。在调用函数或进入一个用户自定义的`{}`块都会在栈上开辟一块新的空间空间的大小和内存分配由操作系统或C库自动管理。**一般来说,直接通过变量访问栈内存,速度最快**(对于单片机)。而堆则是存储程序员自行分配的变量的地方,即使用`malloc(),realloc() ,new`等方法获取的空间,都被分配在这里。
> 在CubeMX初始化的时候Project mananger标签页下有一个Linker Setting的选项这里是设置最小堆内存和栈内存的地方。如果你的程序里写了大规模的数组或使用`malloc()`等分配了大量的空间可能出现栈溢出或堆挤占栈空间的情况。需要根据MCU的资源大小设置合适的stack size和heap size。
> 在CubeMX初始化的时候Project mananger标签页下有一个Linker Setting的选项这里是设置最小堆内存和栈内存的地方。如果你的程序里写了大规模的数组或使用`malloc()`等分配了大量的空间可能出现栈溢出或堆挤占栈空间的情况。需要根据MCU的资源大小设置合适的stack size和heap size。
RTOS创建任务的时候也会为每个任务分配一定的栈空间它会替代MCU的硬件裸机进行内存的分配。可以在CubeMX中设置。如果一个任务里定义了大量的变量可能导致实时系统运行异常请增大栈空间。
@@ -132,7 +130,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的资源并将这些数据通过专用外设总线发送给调试器进而在上位机中读取。
@@ -146,7 +144,7 @@ ITM是instrument trace macrocell指令追踪宏单元的缩写它用于提供
### GDB调试MCU原理
![image-20221117121323757](assets/image-20221117121323757.png)
![image-20221117121323757](.assets/image-20221117121323757.png)
不论使用MDKKEIL还是VSCode还是Ozone实际上背后的流程相同。首先GDB会建立TCP/IP端口并提供接口调试服务器Server作为硬件调试器和GDB软件的桥梁将硬件调试器的相关功能也就是DBG外设支持的那些功能映射到GDB的接口上通过连接到GDB建立的端口。之后启动调试将可执行文件下载到目标MCU上然后从main开始执行
@@ -154,8 +152,6 @@ ITM是instrument trace macrocell指令追踪宏单元的缩写它用于提供
> 而对于直接运行在电脑上的程序(.exe就不需要GDBserver和物理调试器GDB程序可以直接访问电脑上运行的程序和CPU的寄存器等。
### 字节对齐
这是内存硬件设计和汇编语言设计的结果。在使用结构体的时候如果你不做任何事情编译器会自动帮助你完成字节对齐以提高内存访问的效率。stm32是4字节地址和数据总线的设计单词可以传输32位数据因此访问4字节数据也就是stm32的“字”“字长”效率最高。然而历史的缘由导致一个内存地址只存储8位的数据如果你要访问float数据则一次需要读取4个地址。当这四个地址是连续的时候你只需要一次就可以将数据读出。然而如果一个float数据被存放在0x03-0x07这四个地址cpu首先要读出0x00-0x03这四个连续的地址然后再取出最后一个字节随后读取0x04-0x07这四个连续的字节再取出前三个字节最后将最后一个字节和前三个字节拼接在一起形成我们需要的float数据。
@@ -178,17 +174,15 @@ typedef struct
如果您有兴趣,可以了解一下内存硬件的组织和连接方式,包括奇偶地址/片选/行列扩展等,可以帮助你更好地理解字节对齐。
## 环境配置
> ***所有需要编辑的配置文件都已经在basic_framework的仓库中提供如果不会写照猫画虎。***
> 2022-12-01更新
>
> **VSCode上线了一款新的插件**
> **VSCode上线了一款新的插件**
>
> ![image-20221201134906999](assets/image-20221201134906999.png)
> ![image-20221201134906999](.assets/image-20221201134906999.png)
>
> 支持一键配置Arm GNU工具链、MinGW64make工具和OpenOCD可以尝试使用这个插件替代下面的配置流程。并且此插件还提供了一键下载、一键调试的支持只需要选择合适的下载器配置即可全部都是图形化界面的操作
>
@@ -206,17 +200,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)
> MinGW、Arm GNU toolchain和OpenOCD也可以通过**MSYS2**使用pacman包管理器和apt/yum类似直接安装这种方法一步到位**==这是更推荐使用的方式==**,请参看[附录5](##附录5利用MSYS2安装依赖环境)。
>
@@ -224,17 +216,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)
图片看不清请打开原图。验证安装:
@@ -244,7 +236,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>
@@ -256,17 +248,15 @@ typedef struct
- **将OpenOCD解压到一个文件夹里**稍后需要在VSCode的插件中设置这个路径。will be deprecated soon请注意这种方法将会在主分支发布正式版的时候删除
- **CubeMX生成代码**
在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就是我们要使用的构建规则文件。
@@ -296,7 +286,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下自动寻找对应项
@@ -322,7 +312,7 @@ mingw32-make -j24 # -j参数表示参与编译的线程数,一般使用-j12
>
> 我对make的编译命令进行了静默处理只输出error和warning以及最后的生成文件信息。如果想要解除静默就是下面所说的“你可以看到大致如下的输出”需要修改Makefile。**本仓库下的makefile中已经用注释标明。**
![image-20221112191712534](assets/image-20221112191712534.png)
![image-20221112191712534](.assets/image-20221112191712534.png)
就会开始编译了。你可以看到大致如下的输出:
@@ -342,6 +332,7 @@ arm-none-eabi-objcopy -O binary -S build/basic_framework.elf build/basic_framewo
```
由于使用了多线程编译比KEIL的蜗牛单线程要快了不少。以上内容代表了生成的可执行文件的大小以及格式和内容。.elf文件就是我们需要传递给调试器的东西在[使用VSCode调试](###简单调试)部分会介绍。典型的编译时间大致如下:
1. 从零开始重新编译:~10s
2. 修改文件后编译:~3s
@@ -368,23 +359,23 @@ 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文件。
>
> P.S. VSCode中的大部分配置都是通过json文件保存的。当前工作区的配置在项目文件夹中的.vscode下全局配置在设置中修改。全局配置在当前工作区没有配置的时候会生效反之被前者覆盖。
### 如果你编写了新的代码文件...
### 如果你编写了新的代码文件
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)
换行需要在行尾加反斜杠\\
@@ -392,13 +383,11 @@ Makefile的大部分内容在CubeMX初始化的时候就会帮你生成。如果
> 和KEIL新增文件的方式很相似但是更方便。
### 简单的调试配置
> 在VSCode中调试不能像Keil一样查看变量动态变化但是支持以外的所有操作如查看外设和反汇编代码设置断点触发方式等。
> 在VSCode中调试不能像Keil一样查看变量动态变化但是支持以外的所有操作如查看外设和反汇编代码设置断点触发方式等。
>
> **用于调试的配置参考这篇博客**[Cortex-debug 调试器使用介绍](https://blog.csdn.net/qq_40833810/article/details/106713462),这里包含了一些背景知识的介绍。你也可以直接查看下面的教程。
> **用于调试的配置参考这篇博客**[Cortex-debug 调试器使用介绍](https://blog.csdn.net/qq_40833810/article/details/106713462),这里包含了一些背景知识的介绍。你也可以直接查看下面的教程。
> ❗❗❗***==注意==***❗❗❗
>
@@ -418,7 +407,7 @@ VSCode `ctrl+,`进入设置,通过`搜索`找到cortex-debug插件的设置。
***其他配置需要的文件已经全部在basic_framework中提供***,包括`openocd.cfg STM32F407.svd .vscode/launch.json`。
![image-20221115215531879](assets/image-20221115215531879.png)
![image-20221115215531879](.assets/image-20221115215531879.png)
<center>主要需要配置这三个路径第四个gdbPath可以选配</center>
@@ -428,7 +417,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
@@ -436,13 +425,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。
@@ -450,7 +439,7 @@ VSCode `ctrl+,`进入设置,通过`搜索`找到cortex-debug插件的设置。
VSCode提供的一个最大的便利就是你可以将鼠标悬停在需要查看的变量上**不需要添加到watch就能观察变量值。**如果是指针还可以自动解析,获取解引用后的值。结构体也支持直接展开。
![image-20221113133624273](assets/image-20221113133624273.png)
![image-20221113133624273](.assets/image-20221113133624273.png)
3. 调用栈。表明在进入当前代码块之前调用了哪些函数,称之为栈也是因为调用的顺序从下至上。当前函数结束之后栈指针会减小,控制权会返还给上一级的调用者。通过调用栈可以确认程序是**如何**(按怎样的顺序)运行到当前位置的。
@@ -478,14 +467,10 @@ VSCode `ctrl+,`进入设置,通过`搜索`找到cortex-debug插件的设置。
>
> 如果想直接下载代码不想调试,参阅[附录4](##附录4VSCode直接烧录代码)。
### RTT Viewer日志功能
本框架添加了vscode下Segger RTT client的支持。在`.vscode/task.json`中已经添加了启动rtt viewer client的任务。你也可以将此任务作为附加启动任务和调试一起启动方便查看日志。要使用日志请包含`bsp_log.h`。注意需要将jlink的安装目录添加到环境变量中。
### 更好的编辑体验
建议安装以下插件:
@@ -508,16 +493,10 @@ VSCode `ctrl+,`进入设置,通过`搜索`找到cortex-debug插件的设置。
9. live share和你的小伙伴一起结对编程
---
---
## Ozone可视化调试和LOG功能
> ~~Ozone暂时只支持jlink。~~
@@ -530,19 +509,19 @@ VSCode `ctrl+,`进入设置,通过`搜索`找到cortex-debug插件的设置。
**注意如果希望支持daplink包括正点原子无线调试器请务必安装网盘对应的版本Ozone3.24 32-bit和J-Link7.22b)。**
> 经过测试发现只有32位的ozone3.24支持daplink。
> 经过测试发现只有32位的ozone3.24支持daplink。
应该先安装Ozone再安装jlink。以下为步骤
1. 安装Ozone
![image-20221116150122397](assets/image-20221116150122397.png)
![image-20221116150122397](.assets/image-20221116150122397.png)
这一步注意选择install a new instance安装一个新的实例。后续一路确认即可。
2. 安装jlink
![image-20221116193340770](assets/image-20221116193340770.png)
![image-20221116193340770](.assets/image-20221116193340770.png)
这一步注意不要勾选update dll in other application否则jlink会把ozone里面老的驱动和启动项替代掉。choose destination和ozone一样选择install a new instance。如果安装了老的相同版本的jlink请先卸载版本相同不用管直接新装一个
@@ -556,19 +535,19 @@ 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都在图中的文件夹里提供当然你也可以使用我们仓库根目录下的文件。
![image-20221116150901418](assets/image-20221116150901418.png)
![image-20221116150901418](.assets/image-20221116150901418.png)
接口选择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的调试日志最后一个选项选择一个文件或者新建一个日志文件。
@@ -586,7 +565,7 @@ Project.SetOSPlugin(“plugin_name”)
支持的插件在Ozone的安装目录下的`Plugins/OS`目录:
![image-20221119174445067](assets/image-20221119174445067.png)
![image-20221119174445067](.assets/image-20221119174445067.png)
我们的项目是F4的板子内核时Cortex-M4CM4因此选用`FreeRTOSPlugin_CM4.js`输入的时候js后缀不用输。 ozone默认输入的命令似乎有误需要手动修改这好像和ozone的版本有关请留意
@@ -594,7 +573,7 @@ Project.SetOSPlugin(“plugin_name”)
下图的配置是笔者常用的layout。每个窗口是否显示、放在什么位置等都是可以自己定义的。通过工具栏的view选项卡可以自行选择需要展示的窗口。
![](assets/ozone.png)
![](.assets/ozone.png)
1. 调试控制和vscode类似
@@ -602,11 +581,11 @@ Project.SetOSPlugin(“plugin_name”)
如果不需要可视化查看变量变化的趋势但是想不暂停查看变量的值请右键点击变量选择一个合适的refresh rate
![image-20221119173731119](assets/image-20221119173731119.png)
![image-20221119173731119](.assets/image-20221119173731119.png)
如果是一个结构体,你可以为整个结构体都进行刷新率的配置,不需要手动一个个修改。**或直接右键点击窗口**将refresh打勾
![image-20221119173918340](assets/image-20221119173918340.png)
![image-20221119173918340](.assets/image-20221119173918340.png)
3. 断点和运行追踪管理
@@ -630,8 +609,6 @@ Project.SetOSPlugin(“plugin_name”)
如果在调试过程中发现bug或者需要更改代码不需要终止调试或者关闭窗口。直接前往vscode修改并重新编译Ozone会自动检测到.elf文件的变化询问你是否重新加载项目。选择是后会自动开始下载并进入调试。
- **变量动态查看(可视化)**
- **在变量的watch窗口右键点击变量选择一个refresh rate也可以实时查看变量和keil一样。**
@@ -653,7 +630,7 @@ Project.SetOSPlugin(“plugin_name”)
- 如果当前文件没有你要的变量你想查看项目中的其他文件夹在view-> source files中可以打开该项目所有的源文件双击可以打开源文件。
![image-20221113142448939](assets/image-20221113142448939.png)
![image-20221113142448939](.assets/image-20221113142448939.png)
- **日志打印**
@@ -697,22 +674,16 @@ CPU选项卡可以查看CPU的寄存器。
退出时可以将调试项目保存在项目的根目录下方便下次调试使用不需要重新设置。可以为jlink和daplink分别保存一套调试配置。
## 附录1为daplink添加license
在网盘上下载`daplink_register_license.rar`,解压出来之后打开。**请关闭杀毒软件。**
![image-20221116152032104](assets/image-20221116152032104.png)
![image-20221116152032104](.assets/image-20221116152032104.png)
根据Ozone打开时提示的daplink的序列号将其输入注册机电机generate就会生成5个license。
windows菜单搜索J-link license manager点击添加license将注册机生成的五个license依次复制黏贴并添加到的license manager中即可。
## 附录2在VSCode中启用SEGGER RTT日志
若使用Jlink进行调试只需要在开始调试之前把`log`任务启动便可以在终端中看到jlink rtt viewer的日志输出。
@@ -721,8 +692,6 @@ windows菜单搜索J-link license manager点击添加license将注册机
`bsp_log.h`中提供了不同的日志输出接口包括封装好的三种层级的日志info warning error和用户可以自定义输出格式的`PrintLog()`。还提供了一些简单的将浮点数据转化为字符串的函数方便进行日志输出。
## 附录3Makefile指令介绍
> 如果想要进一步学习Makefile可以参考这个链接[Makefile Tutorial By Example](https://makefiletutorial.com/)。你会发现当项目越来越大的时候makefile也会变得复杂起来这就有了后继者**CMake**。cmake可以根据一定的规则生成makefile然后再利用make命令调用gcc进行程序的编译。~~也许以后还会有ccccmake~~
@@ -881,31 +850,31 @@ vpath %.s $(sort $(dir $(ASM_SOURCES))) # 对.s文件的文件名也进行排序
# 意味根据makefile,在BUILD_DIR变量指定的路径下将参与编译的所有.c文件编译成.o文件
$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
@$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
# 上面这句话翻译一下实际上是gcc -c -many_param build/xxx -o build
# 意思是将所有参与编译的文件都列出来,传递一堆编译参数,让他们生成.o文件,并且放在build文件夹下
@$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
# 上面这句话翻译一下实际上是gcc -c -many_param build/xxx -o build
# 意思是将所有参与编译的文件都列出来,传递一堆编译参数,让他们生成.o文件,并且放在build文件夹下
# 意为根据makefile,将.s文件编译成.o文件,具体和上一条命令差不多
$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
@$(AS) -c $(CFLAGS) $< -o $@
@$(AS) -c $(CFLAGS) $< -o $@
# 根据前两步生成的目标文件(.o,这些文件的名字保存在OBJECTS变量里),进行链接生成最终的.elf
$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
@$(CC) $(OBJECTS) $(LDFLAGS) -o $@
@$(SZ) $@ # 输出生成的.elf文件的大小和格式信息
@$(CC) $(OBJECTS) $(LDFLAGS) -o $@
@$(SZ) $@ # 输出生成的.elf文件的大小和格式信息
$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
$(HEX) $< $@ # elf转换成hex
$(HEX) $< $@ # elf转换成hex
$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
$(BIN) $< $@ # 转换成bin
$(BIN) $< $@ # 转换成bin
$(BUILD_DIR): # 如果makefile所处的文件目录下没有build文件夹,这里会新建一个build文件夹.
@mkdir $@
@mkdir $@
#######################################
# clean up,清除编译信息,可以在命令行中通过rm -r build执行,实际上就是把build文件夹删掉
#######################################
clean:
rm -r $(BUILD_DIR)
rm -r $(BUILD_DIR)
# 你的makefile可能会使用cmd而不是powershell来调用内核,而cmd不支持rm命令,因此可能要修改为rd (remove directory),cmd传入参数的方式为 /x ,x为要传入的参数
@@ -930,8 +899,6 @@ clean:
| -Os | O2基础上进一步优化代码尺寸 | 去掉了那些会导致最终可执行程序增大的优化,如果想要更小的可执行程序,可选择这个参数。 |
| -Ofast | 优化到破坏标准合规性的点(等效于-O3 -ffast-math ) | 是在 -O3 的基础上,添加了一些非常规优化,这些优化是通过打破一些国际标准(比如一些数学函数的实现标准)来实现的,所以一般不推荐使用该参数。 |
## 附录4VSCode直接烧录代码
有时候你对自己的代码特别自信不想debug想直接下载代码那么直接通过openocd或J-Flash即可随jlink一起安装。要是觉得这样有点麻烦还要再开一个软件他们两者都支持通过命令行执行。你可以在vscode的tasks.json中编写一个额外的任务来实现。这里我通过给Makefile添加伪构建目标来利用make命令执行下载操作
@@ -943,10 +910,10 @@ clean:
OPENOCD_FLASH_START = 0x08000000 # 如果切换芯片可能需要修改此值
download_dap:
openocd -f openocd_dap.cfg -c init -c halt -c "flash write_image erase $(BUILD_DIR)/$(TARGET).hex $(OPENOCD_FLASH_START)" -c reset -c shutdown
openocd -f openocd_dap.cfg -c init -c halt -c "flash write_image erase $(BUILD_DIR)/$(TARGET).hex $(OPENOCD_FLASH_START)" -c reset -c shutdown
download_jlink:
openocd -f openocd_jlink.cfg -c init -c halt -c "flash write_image erase $(BUILD_DIR)/$(TARGET).hex $(OPENOCD_FLASH_START)" -c reset -c shutdown
openocd -f openocd_jlink.cfg -c init -c halt -c "flash write_image erase $(BUILD_DIR)/$(TARGET).hex $(OPENOCD_FLASH_START)" -c reset -c shutdown
```
首先设定了flash烧录区的起始地址下面两个构建目标分别用于daplink和jlink的下载。我们统一使用openocd进行烧录。命令中`-c`表明的是启动openocd之后要执行的命令openocd作为一个gdbserver是用作调试的因此这里我们在`flash write_image`之后直接`reset`让单片机复位开始运行程序,然后立刻退出调试,从而达到下载程序运行但不调试的目的。
@@ -959,9 +926,9 @@ download_jlink:
"type": "shell",
"command":"make download_dap",
"group": {
"kind": "build",
"isDefault": false,
},
"kind": "build",
"isDefault": false,
},
},
{
"label": "download jlink",
@@ -979,15 +946,13 @@ download_jlink:
> 实际上换用arm gnu工具链之后可以指定多线程编译因此消耗的时间非常短建议都加上先编译的选项不会占用额外的时间。可以把默认task设置成编译后下载把默认debug设置成编译后调试提升开发效率。
## 附录5利用MSYS2安装依赖环境
之所以要使用Linux进行C++开发是因为在开发环境中配置依赖包、依赖应用和库非常的方便。Debian系有aptFedora和Redhat系有yum他们都可以方便地帮助我们下载开发软件必须的一些文件和工具。在windows的宇宙最强IDEVisual Studio中配置头文件和动态链接库可以称得上是最折磨的事。好在现在Windows下也有可以使用的包管理工具了[MSYS2](https://www.msys2.org/)。
安装包已经上传到了网盘的`EC/VSCode+Ozone环境配置/msys2-x86_64-20221028.exe`下。安装之后打开MSYS2 MSYS软件他是一个类shell的界面
![image-20221119222946103](assets/image-20221119222946103.png)
![image-20221119222946103](.assets/image-20221119222946103.png)
输入以下命令然后一路回车即可:
@@ -996,7 +961,7 @@ pacman -S mingw-w64-x86_64-toolchain mingw-w64-x86_64-arm-none-eabi-toolchain mi
# 需要注意ctrl+V不是黏贴快捷键,而是Ins+Shift.或者右键点击空白处选择黏贴也可以.
```
![image-20221119223148604](assets/image-20221119223148604.png)
![image-20221119223148604](.assets/image-20221119223148604.png)
<center>比如上面这样,会让你选择,直接敲回车即可,等待安装</center>
@@ -1008,8 +973,6 @@ pacman -S mingw-w64-x86_64-toolchain mingw-w64-x86_64-arm-none-eabi-toolchain mi
通过这种方式安装之后还可以选用ccache加速编译。ccache会根据之前的编译输出建立缓存使得之后编译时可以直接读取缓存。要开启这个功能直接在Makefile中搜索PREFIX将下面一行的内容替代原有内容即增加ccache在arm-none-eabi-之前)。
## 附录6Windows修改用户名为英文
1. 右键【任务栏win徽标】->【计算机管理】->【本地用户和组】->【用户】->右键【中文用户名】->【重命名】
@@ -1045,4 +1008,3 @@ pacman -S mingw-w64-x86_64-toolchain mingw-w64-x86_64-arm-none-eabi-toolchain mi
```
如果杀毒软件提示恶意修改请放行。这会关闭Administator账户。