当前位置: 首页 > news >正文

实现vscode上用gdb调试stm32

实现vscode上用gdb调试stm32

这周负责编写设备的某个模块,其中遇到了一些变量地址不正确的错误,按理这种底层变量错误用gdb一类的调试器就能很快查到,可是初入嵌入式一行,此C语言非彼C语言,对于gdb怎么对接到项目上根本一无所知,问了下周边同事,发现他们居然都是直接打串口日志来调试的,那岂不是每次遇到问题都得在代码上留一堆丑陋的printf? 我对如此原始的调试方式实在不服气,便想找到相关的对接工具,我的开发习惯是在vscode上写好代码后再在keil上编译烧录,由于keil的界面和操作实在令我难以接受,因此我的需求就是找到在vscode上找到调试单片机的方法,一开始我以为占工作时间一两小时就调通了,结果发现课题复杂度远超出自己的预期,只好乖乖放弃,在代码上不断加入丑陋的printf。。。。。。

等到周末,终于有时间研究了,总之就是不断搜索踩坑,整了两天,总算完事,现作记录。

我使用的是江科大的stm32c8t6开发板,仿真器用的st-link-v2。

1.下载openocd

gdb对于stm32的调试需要借助一个gdb server, st-link和Jlink都有自带的gdbserver, 我这里选择用openocd作为板子的gdbserver,实际上openocd除了调试还可以烧录,感兴趣的可以自己深入研究下,附一张板子,openocd,pc机之间的关系:

v2-aac3a16fbd3a81fc5de0a1e76d9ae483_1440w

openocd尽量选新的,我这里是windows平台,用的xpack-0.11.0版本,之前用的0.10.0版本跟cotrexDebug扩展组合莫名会出行gdb server超时的错误。

这里附openocd的下载地址:https://github.com/xpack-dev-tools/openocd-xpack/releases

后面关于如何烧录及开gdb server可自行查找。

2.下载arm-gnu-toolchains

arm平台有专属的gcc,gdb,make等工具用于arm系列开发板的开发,stm32的开发和调试工具就靠这些,下载:https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads

windows平台用户可选择:

image-20230806164552347

3.MinGW

在windows下作C/C++开发的同学应该很熟,不作赘述,这里记个坑,官方下载的时候总是遇到The file has been downloaded incorrectly,据说是网络问题导致,直接下官网的压缩包又太慢,真的无力。好在已经有好心人贴了百度链接,如下:https://pan.baidu.com/s/1mIq_Vbn2w45L_B-AGJk0ww?pwd=gv1s

参考:

Mingw快捷安装教程 并完美解决出现的下载错误:The file has been downloaded incorrectly

4.Cotrex-Debug下载及配置

参考:https://blog.csdn.net/qq_40833810/article/details/106713462

注意那个configFile可根据相对路径来填,另外别把单词写错了,当时由于把interface写成interfaces卡了一整晚。。。。

executable部分写keil的axf文件或者bin文件都可以,前者确保output选项打勾了Debug Information!

5.STM32CubeMX

对于STM32,Cotrex-Debug只支持调试其HAL库的代码,对于板子相关的库函数的代码貌似不支持,我试过,拿江科大的库代码版本烧进板子后vscode F5调试,gdb没响应,显然是不兼容。目前stm32开发已经是HAL库的天下了,一个HAL库兼容st下所有型号的板子,这么高效的开发,怎么能不学呢?看来当时应该买正点的板子的,然而太贵了。。。。

STM32CubeMX是ST公司为其开发板做的专属项目生成工具,支持MDK-ARM和makefile两种编译方法,各位同学可根据自身需求选择自己的编译方式, 它就是用的HAL库,而且似乎只能用HAL库,如果学的板子相关标准库的同学(江科大就是stm32f103的标准库)得多做点功课。。。。

另外这东西可以图形化配置芯片的IO口和时钟,最后生成相关的配置代码,还挺方便的。。。

拿江科大的LED闪烁实验来说,原代码是这样:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"int main(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);while (1){GPIO_ResetBits(GPIOA, GPIO_Pin_0);Delay_ms(500);GPIO_SetBits(GPIOA, GPIO_Pin_0);Delay_ms(500);GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);Delay_ms(500);GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);Delay_ms(500);GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)0);Delay_ms(500);GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)1);Delay_ms(500);}
}

在STM32CubeMX里面可以预先把IO口设置好,我这里由于PA0和System-WKUP冲突改选了PA1,将PA1设置为推挽输出的操作如图:

image-20230806170425314

最后generate code可在MX_GPIO_Init()一行看到, 自己的配置已经被落实了:

static void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 *//* GPIO Ports Clock Enable */__HAL_RCC_GPIOD_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);/*Configure GPIO pin : PA1 */GPIO_InitStruct.Pin = GPIO_PIN_1;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;	//HAL库中LOW,MEDIUM,HIGH三档分别对应库函数的2MHZ,10MHZ,50MHZHAL_GPIO_Init(GPIOA, &GPIO_InitStruct);/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

闪烁灯代码如下:

int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE */HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);HAL_Delay(500);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);HAL_Delay(500);/* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

6.最终效果

在vscode的launch.json上配置好:

{// 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": "Cortex Debug","cwd": "${workspaceFolder}","request": "launch","type": "cortex-debug","runToEntryPoint": "main","servertype": "openocd","configFiles": ["interface/stlink.cfg","target/stm32f1x.cfg"],"executable":"build/mdk_arm_test.axf","svdFile": "D:/Arm/Packs/Keil/STM32F1xx_DFP/2.2.0/SVD/STM32F103xx.svd",}]
}

用之前STM32CubeMX生成的HAL库的代码直接在keil上面编译烧录。

image-20230806172855964

然后上vscode, F5开启调试,成功!尽情享受吧!

image-20230806171846136

相关文章:

实现vscode上用gdb调试stm32

实现vscode上用gdb调试stm32 这周负责编写设备的某个模块,其中遇到了一些变量地址不正确的错误,按理这种底层变量错误用gdb一类的调试器就能很快查到,可是初入嵌入式一行,此C语言非彼C语言,对于gdb怎么对接到项目上根…...

第4章 变量、作用域与内存

引言 由于js是一门只有在声明变量后才能明确类型的语言,并且在任意时刻都可以改变数据类型。这也引起了一些问题 原始值与引用值 原始值就是基本数据类型,引言值就是复杂数据类型 变量在赋值的时候。js会判断如果是原始值,访问时就是按值访问…...

Python爬虫遇到重定向问题解决办法汇总

在进行Python爬虫任务时,遇到重定向问题是常见的问题之一。重定向是指在发送请求时,服务器会返回一个新的URL,将请求重新定向到该URL。为了帮助您解决这个问题,本文将提供一些实用的解决办法,并给出相关的代码示例&…...

R并行计算

1-lapply()函数介绍: 为什么介绍这个函数呢?因为在windows中使用parLapply()函数和lapply()的结构和用法是非常相似的,我们只需要将原本用lapply(x, fun)迭代函数 直接改写成 parLapply(makeCluster(c1), x, fun)即可,这里的直接…...

STM32 低功耗-待机模式

STM32 待机模式 文章目录 STM32 待机模式第1章 低功耗模式简介第2章 待机模式简介2.1 进入待机模式2.1 退出待机模式 第3章 待机模式代码部分总结 第1章 低功耗模式简介 在 STM32 的正常工作中,具有四种工作模式:运行、睡眠、停止和待机模式。 在系统或…...

极海APM32F003F6P6烧写问题解决记录

工作中遇到的,折腾了好久,因为电脑重装过一遍系统,软件也都重新安装了,所以不知道之前的配置是什么,旧项目代码编译没问题,烧写时疯狂报错,用的是JLink。 keil版本v5.14 win10版本 JLink版本…...

【大数据】Flink 详解(一):基础篇

Flink 详解(一):基础篇 1、什么是 Flink ? Flink 是一个以 流 为核心的高可用、高性能的分布式计算引擎。具备 流批一体,高吞吐、低延迟,容错能力,大规模复杂计算等特点,在数据流上提…...

ChatGPT 作为 Python 编程助手

推荐:使用 NSDT场景编辑器 助你快速搭建可编辑的3D应用场景 简单的数据处理脚本 我认为一个好的起点是某种数据处理脚本。由于我打算让 ChatGPT 之后使用各种 Python 库编写一些机器学习脚本,这似乎是一个合理的起点。 目标 首先,我想尝试…...

饿了么输入框限制只能输入数字,并且保留小数

可以使用饿了么ui中的input-number组件实现输入框只能输入数字,这样就不能输入数字以外的,controls隐藏输入框左右俩边的加减按钮,precision小数点保留多少位,2则是俩位,但是会导致默认值为0.00的情况,俩种…...

kylin-Desktop gsettings 获取或设置系统配置

gsettings提供了对GSetings的命令行操作。GSetings实际上是一套高级API,用来操作dconf。 dconf存储着GNOME3的配置,是二进制格式。它做为GSettings的后端系统存在,暴露出低级API。在GNOME2时代,类似的角色是gconf,但它是以XML文本形式存储。 更接地气的说法是,dconf是G…...

setmap使用

目录 set使用 set的模板参数 构造函数 成员函数 insert iterator ​编辑 find count pair pair 的模板参数 make_pair multiset使用 multiset 的模板参数 set 与 multiset 的区别 count map使用 map 的模板参数 构造函数 insert iterator find ​编辑 cou…...

Python3 网络爬虫开发实战

JavaScript逆向爬虫 JavaScript接口加密技术,JavaScript有以下两个特点: JS代码运行在客户端,所以它必须在用户浏览器加载并运行JS代码公开透明,所以浏览器可以直接获取到正在运行的JS源码。 所以JS代码不安全,任何…...

docker: CMD和ENTRYPOINT的区别

ENTRYPOINT: 容器的执行命令(属于正统命令) 可以使用--build-arg ENVIROMENTintegration参数覆盖 ocker build --build-arg ENVIROMENTintegration 两者同时存在时 CMD作为ENTRYPOINT的默认参数使用外部提供参数会覆盖CMD提供的参数。 CMD单…...

DC电源模块对于定制的要求主要有这几点

BOSHIDA DC电源模块对于定制的要求主要有这几点 DC电源模块是一种将交流电转换成为稳定的直流电的装置。在现代工业生产中,DC电源模块被广泛应用于各种电子设备中,例如计算机、手机、电视等。为了满足不同用户需求,DC电源模块的定制需求也是…...

Kubernetes高可用集群二进制部署(六)Kubernetes集群节点添加

Kubernetes概述 使用kubeadm快速部署一个k8s集群 Kubernetes高可用集群二进制部署(一)主机准备和负载均衡器安装 Kubernetes高可用集群二进制部署(二)ETCD集群部署 Kubernetes高可用集群二进制部署(三)部署…...

网关 GateWay 的使用详解、路由、过滤器、跨域配置

一、网关的基本概念 SpringCloudGateway网关是所有微服务的统一入口。 1.1 它的主要作用是: 反向代理(请求的转发) 路由和负载均衡 身份认证和权限控制 对请求限流 1.2 相比于Zuul的优势: SpringCloudGateway基于Spring5中…...

vsocde里面远程连接服务器报could not esatablish connection xxxx

我在vscode里面远程连接服务器编辑代码时,正常我按F1选择了服务器IP地址,然后让我选在Linux,然后我再输入服务器密码,但是当我选择Linux系统之后直接没出让我输入服务器密码的输入框,而是直接报错 could not esatablis…...

Hi3798MV200 恩兔N2 NS-1 (二): HiNAS海纳思使用和修改

目录 Hi3798MV200 恩兔N2 NS-1 (一): 设备介绍和刷机说明Hi3798MV200 恩兔N2 NS-1 (二): HiNAS海纳思使用和修改Hi3798MV200 恩兔N2 NS-1 (三): 制作 Ubuntu rootfsHi3798MV200 恩兔N2 NS-1 (四): 制作 Debian rootfs 关于 海纳思全称是海思机顶盒NAS系统, 网站 https://www…...

无涯教程-Perl - foreach 语句函数

foreach 循环遍历列表值,并将控制变量(var)依次设置为列表的每个元素- foreach - 语法 Perl编程语言中的 foreach 循环的语法是- foreach var (list) { ... } foreach - 流程图 foreach - 示例 #!/usr/local/bin/perllist(2, 20, 30, 40, 50);# foreach loop ex…...

easyWechat 5.x 复写代码 获取企业微信授权用户敏感信息

复写 (new SocialiteManager($config))->extend(wework, function ($config) {return new \App\Extend\EasyWechat\Work\WeWork($config);});创建的 \App\Extend\EasyWechat\Work\WeWork是我们需要复写的类 <?phpnamespace App\Extend\EasyWechat\Work;use Overtrue\So…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...