VSCode+gcc开发STM32教程

Linux环境下STM32开发

1.前言

最近在使用Keil开发STM32的时候总感觉代码写起来很很费劲,然后打算用vscode试试,刚开始用的是KeilAssitance这个插件,本质还是使用Keil进行配置,vscode写代码,体验了一下感觉还是不方便。后来想到了Linux,毕竟在写代码这方面,Linux的体验还是非常棒的。综合考虑加查资料,最终决定使用Linux+vscode+STN32CubeMX+gnu-arm编译工具+openocd烧录工具的方式进行stm32的开发,花了我好几天才搞好,期间学了vscode复习了一下makefile和cmake,还有linux。希望能给大家一些帮助。

下面这一段对我启发很大,在此记录一下,以下转自知乎:
工具链一般用gcc-arm-none-eabi,可以用包管理装,也可以到arm官网下,也可以自己编译,毕竟gnu源有这个配置。如果keil自带的armcc就比较缺乏调试工具。纯用命令行的话,cubemx可以生成makefile工程,改下编译器路径就能make,会生成bin文件。
用IDE的话,可以用eclipse,参考wiced sdk。可以用vscode,体验要优于sublime。网上搜搜怎么配环境,主要就是设置工具链的目录。烧录程序,如果烧的是bin的话需要一个烧录程序。用jlink的话可以用segger官网下的jlinkexe工具。用stlink的话可以用github上的stutils什么的。用cmsis-dap或者ft2232的话就只能配openocd了。如果想直接烧elf,那么就要先搭好gdb server或者jtag bridge之类的东西,比方说jlink的就是jlinkgdbserver,然后xxxx-gdb连上,用load命令下载。keil的axf没研究过怎么用。
调试的话可以用IDE,关键还是先搭好gdb server然后让IDE里的gdb连上它。剩下的体验就跟调自家程序那样了,只是这些IDE没有像keil那样的看外设寄存器之类的功能了。

工程模板已经上传至我的git仓库,欢迎star

2.环境搭建

  1. 安装ubuntu虚拟机,用vmware即可,教程自行搜索。硬盘最好分配30G以上。

  2. 除此之外也可以安装双系统,本人使用的是双系统,因为用虚拟机运行太多东西会很卡,安装参考:Win10安装Ubuntu18.04双系统,图文详解,全网最详细教程

  3. 第三种方法是使用WSL,WSL安装过程去百度即可

系统装好以后需要安装一些必要的软件

sudo apt-get update\
sudo apt-get upgrade\
sudo apt install gcc git vim -y
  1. 安装vscode Linux版,安装过程自行搜索。
  2. 安装STM32CubeMX Linux版,去ST官网下载安装即可。
  3. 安装gcc-arm-none-eabi编译工具,当执行CubeMX生成的makefile时会调用该编译工具链。
    安装方法:
    • 在线安装:sudo apt install gcc-arm-none-eabi,不推荐,因为在线安装的版本会缺少gdb调试工具。推荐下载工具包的方式
    • 下载工具包:参考这篇。我的是ubunut下载这个,国外网站下载比较慢,有网盘会员的可以用我分享的网盘链接:百度网盘链接
      下载完成后tar -xvf arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi.tar.xz进行解压
      解压完成后切换到解压目录下的bin目录下可以看到编译器arm-none-eabi-gcc,但是需要把编译器添加到环境变量中:
      在这里插入图片描述
      在添加环境变量之前最好把解压文件放到/usr/local目录,使用命令cp -r arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi的路径 /usr/local
      vi /etc/profile
      添加以下环境变量到配置文件中
export PATH=$PATH:/usr/local/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/lib

然后更新一下环境变量
source /etc/profile
在终端输入arm-none再按两下tab,如果出现在这里插入图片描述
说明配置成功

  1. 安装openocd,openocd是一个开源的烧录程序, 这个在线下载就可以sudo apt install openocd -y
    下载链接

3.编译烧录调试:

  1. 生成代码框架

使用STM32CubeMX生成点灯程序的代码框架及初始化代码。具体可以参考网上的教程
注意-要选择生成Makefile的工程文件。
打开STM32CubeMX
选择一款芯片进入配置
Debug这里要选择Serial Wire
在这里插入图片描述
在Project Manager这里选择ToolChain为Makefile
F:\home\make\em\stm32
再配置好时钟就可以生成工程了
用vscode打开生成的工程
在这里插入图片描述

  1. 完善代码

在main函数里加上每隔1S反转一次LED的代码。

20230305162328

这里还有vscode会有红色波浪线的错误提示,虽然也能正常编译,但是不能用vscode的智能提示以及代码跳转。(我用vscode不就是为了这个麻)
解决方法:将Makefile中包含的定义以及路径添加到c/c++插件的配置中,如果没有这个文件可以ctrl+shift+p搜索c/c++配置来生成一个配置文件,也可以自己新建一个20230310221446,除了需要添加makefile中的路径以及宏定义,还需要添加arm-gnu工具链所包含的路径,,好像不加也没多大影响。

c_cpp_properties.json

{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**",
                "Core/Inc",
                "Drivers/STM32F4xx_HAL_Driver/Inc",
                "Drivers/STM32F4xx_HAL_Driver/Inc/Legacy",
                "Drivers/CMSIS/Device/ST/STM32F4xx/Include",
                "Drivers/CMSIS/Include",
                "/usr/local/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.2.1/../../../../arm-none-eabi/include/c++/12.2.1",
                "/usr/local/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.2.1/../../../../arm-none-eabi/include/c++/12.2.1/arm-none-eabi",
                "/usr/local/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.2.1/../../../../arm-none-eabi/include/c++/12.2.1/backward",
                "/usr/local/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.2.1/include",
                "/usr/local/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.2.1/include-fixed",
                "/usr/local/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.2.1/../../../../arm-none-eabi/include"
            ],
            "defines": [
                "USE_HAL_DRIVER",
                "STM32F407xx",
                "__GUNC__"
            ],
            "compilerPath": "/usr/local/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/bin/arm-none-eabi-gcc",
            "intelliSenseMode": "gcc-arm"
        }
    ],
    "version": 4
}

如果安装在/usr/local目录下,配置文件可以这样写,但是如果版本和我的不同就需要改一下里面路径中的版本号

4. 编译

通过安装的gcc-arm-none-eabi编译工具链编译。
在新建的工程目录下的终端中,也可以用vscode打开终端,使用make命令编译工程文件,编译后在build文件夹下会生成工程名.elf,工程名.hex,工程名.bin文件。
20230305174147

当后期项目文件中增添了新文件,可以通过修改makefile文件的方式重新构建编译规则。
一文搞懂Makefile

除此之外还可以通过写cmake的方式自定义,但是用cmake构建stm32的工程有些复杂,还没太研究明白。

5. 烧录

硬件使用野火DAP仿真器和创新工坊的PWLink,两个都是CMSIS标准接口。软件使用openocd

openocd介绍:
OpenOCD是一种开放式片上调试器,可为嵌入式设备提供编程,调试和边界扫描测试。OpenOCD作为服务器,并通过端口3333接受来自GDB的传入连接或通过端口4444接受来自telnet的传入连接。GDB用于源文件步骤调试。telnet连接用于刷新。OpenOCD连接到 DAPLINK仿真器。DAPLINK适配器连接到目标。参考如下
https://zhuanlan.zhihu.com/p/41517198

下载openocdsudo apt install openocd
使用方式:
1通过openocd命令行
2把命令封装成shell脚本运行
3将命令集成到vscode的tasks.json中,也相当于脚本
三种方式的本质都是一样的,这里主要使用vscode脚本的方式

1脚本方式 (不推荐)
在gitee下载一个被人写好的脚本,直接运行脚本即可。
git clone https://gitee.com/delbertzopenocd-toolbox.git

下载完切换到该文件夹下
cd openocd-toolbox/sricpts/linux/stm32f4x # 后面这个根据自己的stm32型号选择

脚本文件如下:
20230305163231

连接好开发板和仿真器后,运行attach.sh,openocd通过端口连接DAP仿真器如下:
20230305163616

在vscode中 ctrl+ ` 调出终端,运行命令
program hex文件所在的路径
程序开始烧录

  • telnet localhost 4444 通过telnet连接openocd,DAP仿真器灯变红表示开始工作
  • program /home/lps/stm32/test01/build/test01.hex 烧录hex文件
  • reset 复位STM32
  • exit 关闭连接

2命令行操作方式(不推荐)

通过运行<scripts>带参脚本命令运行Server,通用格式为
-f <interface> -f <target>
<interface>仿真器配置: 代表你的仿真器类型,DAPLINK就是interface/cmsis-dap.cfg
<target>目标板配置: 代表你的烧录的单片机类型,如STM32F407就是target/stm32f4x.cfg

支持的烧录器在/usr/share/openocd/scripts/interface
支持的芯片在/usr/share/openocd/scripts/target
如下:
20230305174736

首先连接板子执行命令

openocd -f interface/cmsis-dap.cfg -f target/stm32f4x.cfg

通过以上命令openocd打开4444端口
打开vscode ctrl + `打开终端,接下来的操作和脚本的方式一样了,参考上面脚本的方式。

3vscode 配置tasks.json (*推荐)
vscode通过tasks.json这个配置文件的形式,提供了类似shell脚本的方式执行自动任务。具体参考:
https://code.visualstudio.com/Docs/editor/tasks

在.vscode文件夹下新建task.json文件内容如下:
关于vscode中的tasks.json文件,具体可以参考vscode对tasks的介绍
tasks.json

{
    "version": "2.0.0",
    "options": {
        "cwd": "${workspaceFolder}" //cwd的作用是切换到目标路径下
    },
    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "command": [
                "make"
            ],
            "args": [
                "-f",
                "${workspaceFolder}/Makefile"
            ],
            "problemMatcher": "$gcc",
            "group": {
                "kind": "build",
                //"isDefault":true // 当选项为true时ctrl+b会自动执行该条任务,无法选择其他任务
            },
            "detail": "build"
        },
        {
            "label": "download",
            "type": "shell",
            "command": [
                "openocd.exe"
            ],
            "args": [
                "-f",
                "interface/cmsis-dap.cfg",
                "-f",
                "target/stm32f4x.cfg",
                "-c",
                "program build/${workspaceFolderBasename}.elf verify reset exit"
            ],
            "problemMatcher": "$gcc",
            "group": "build",
            "detail": "download"
        },
        {
            "label": "Launch OpenOCD",
            "command": "openocd.exe",
            "args": [
                "-f",
                "interface/cmsis-dap.cfg",
                "-f",
                "target/stm32f4x.cfg",
                "-c",
                "\"bindto 0.0.0.0\""
            ],
            "type": "shell",
            "isBackground": true,
            "problemMatcher": [],
            "group": "build",
            "detail": "debug"
        }
    ]
}

  • 这里面比如.elf文件,都用vscode中的变量替代了,不需要修改,前提是需要用vscode打开工程目录而不是别的文件夹。
  • 具体内容根据自己的路径设置即可
  • 以上文件就是对之前用命令行的方式进行封装,只需要ctrl+shift+b即可快速执行一个任务,非常方便。

ctrl+shift+b选择build后即可开始编译,出现下图说明编译成功在这里插入图片描述
ctrl+shift+b执行download任务即可开始下载

注意:在WSL2中需要在windows中安装openocd并添加到环境变量中,并在wsl中使用windows中安装的openocd.exe并且把tasks.json文件中的
"command": [ "openocd" ],改为 "command": [ "openocd.exe" ],
具体方法如下:打开openocd的下载链接:https://github.com/openocd-org/openocd/releases,下载后放到windows目录中进行解压,解压完成后复制解压文件夹下的bin目录路径,打开我的电脑->右键->属性->高级系统设置->环境变量->双击path->新建 把复制的路径粘贴进去确定即可

6. 调试

首先需要确定arm-none-eabi-gdb能否运行
如果出现下图错误
在这里插入图片描述

  1. 尝试
sudo apt install libncursesw5-dev

2.如果还未解决,尝试:

ln -s /usr/lib/libncursesw.so.6 /usr/lib/libncursesw.so.5

3.如果还未解决,尝试:


sudo apt install apt-file

sudo apt-file update

sudo apt-file find libncursesw.so.5

sudo apt install libncursesw5

解决这个问题之后可能还会有python版本的问题,要求使用python3.8但是我现在的python版本为3.10在这里插入图片描述
解决方法:

sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
# install python 3.8
sudo apt install python3.8

如果你用的交叉编译工具和我用的不一样,那么所需要的python版本也会不一样,具体需要看报错信息
参考:

  • https://cloud.tencent.com/developer/ask/sof/106947809
  • https://towardsdatascience.com/installing-multiple-alternative-versions-of-python-on-ubuntu-20-04-237be5177474

解决报错之后:
出现下列信息说明gdb调试工具能够正常运行
在这里插入图片描述

下一步

调试需要vscode安装cortex-debug这个插件
20230310223147

安装完成之后需要配置launch.json文件
20230310223245
配置如下:
具体的单片机型号自行修改

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
      {
        "name": "(gdb-remote) Debug",
        "type": "cortex-debug",
        "request": "launch",
        "servertype": "external",
        "cwd": "${workspaceRoot}",
        // "runToMain": true,
        "executable": "${workspaceRoot}/build/${workspaceFolderBasename}.elf",
        "svdFile": "${workspaceRoot}/STM32F40x.svd",
        "gdbTarget": "172.22.176.1:3333",
        "armToolchainPath": "/usr/local/toolchains/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/bin"
      },
    ],
  }

gdbTarget需要使用命令cat /etc/resovl.conf查看
参考:https://github.com/Marus/cortex-debug/issues/308
在这里需要注意的是.svd文件,这是调试需要用到的文件.svd调试文件需要在windows的Keil的文件目录中找,我的路径如下/Users/用户名/AppData/Local/Arm/Packs/Keil/STM32F4xx_DFP/2.14.0/CMSIS/SVD/STM32F40x.svd
我在配置调试这里也出现了许多问题,出现问题多去搜索就好,实在不行下载一个STM32CubeIDE用来调试。

最后我把所需要的编译器还有svd文件都放在工程目录下了。

参考:

  • 10
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
以下是一个rosserial stm32的实现例子: 在STM32CubeIDE中新建一个STM32工程,选择对应的板子和处理器。 在工程中添加以下文件: 1. rosserial_stm32.c 2. rosserial_stm32.h 3. std_msgs.h 其中,std_msgs.h是ROS中的标准消息类型头文件,需要从ROS中下载并添加到工程中。rosserial_stm32.c和rosserial_stm32.h是实现ros_serial库的关键文件,需要从rosserial_stm32库中下载并添加到工程中。可以通过以下命令在终端中下载: ``` git clone https://github.com/ros-drivers/rosserial.git ``` 然后将其中的rosserial_stm32文件夹复制到工程中。 在main函数中添加以下代码: ```c #include "rosserial_stm32.h" #include "std_msgs/Int32.h" ros::NodeHandle nh; void chatterCallback(const std_msgs::Int32& msg){ // 处理接收到的消息 } ros::Subscriber<std_msgs::Int32> sub("chatter", &chatterCallback ); int main(void) { ros::NodeHandle nh; nh.initNode(); nh.subscribe(sub); while (1) { nh.spinOnce(); } } ``` 这段代码初始化ros节点,订阅名为“chatter”的话题,并在while循环中调用nh.spinOnce()函数,实现消息的接收和发送。当接收到名为“chatter”的消息时,会调用chatterCallback函数进行处理。 最后,在工程中添加以下代码,启动ros节点: ```c int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART2_UART_Init(); rosserial_init(); while (1) { rosserial_spin(); } } ``` 这段代码初始化串口和GPIO,调用rosserial_init()函数初始化ros_serial库,然后在while循环中调用rosserial_spin()函数,实现ros节点的启动和运行。 以上就是一个简单的rosserial stm32实现例子,可以根据需要进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

指针到处飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值