使用VS Code实现编辑,编译,下载,调试
一起学嵌入式 2025-01-09


在刚开始接触STM32的时候,使用的keil作为IDE,由于在这之前,使用过VS, 使用过eclipse,因而在使用keil之后,实在难以忍受keil编辑器简陋的功能,可以说是极其糟糕的写代码体验。

之后,尝试过各种IDE,使用eclipse+keil,结果发现eclipse对C语言的支持也是鸡肋,使用emBits+gcc,需要和其他人协同的话就比较麻烦,之后发现了platformIO,也是使用gcc作为编译器,不过只支持HAL库,而且还有一个重要的原因,同事都是用的keil,如果我使用gcc,就不能协同工作了。

最后,通过使用VS Code + keil的方式,完美解决了写代码的体验问题,以及工程协作问题,其实网上使用VS Code作为编辑器,keil作为编译器的教程很多,不过基本都是需要在VS Code中编辑,然后在keil中编译,下载,调试,本文就要实现编辑,编译,下载,调试,全部使用VS Code。

Part1环境

(1)VS Code;
(2)keil;python;
(3)GNU Arm Embedded Toolchain(arm gcc工具链);
(4)C/C++(VS Code 插件);
(5)Cortex-Debug(VS Code 插件);
(6)其他VS Code插件(提升体验)。

Part2前提

正式写代码之前,首先需要建立好一个工程,这个需要使用keil完成,包括工程配置,文件添加…

Part3编辑

在安装好VS Code插件之后,VS Code编写C代码本身体验就已经很好了,

但是,因为我们使用的是keil环境,所以需要配置头文件包含,宏定义等,在工程路径的.vscode文件夹下打开c_cpp_properties.json文件,没有自己新建一个,内容配置如下:

{
    "configurations": [
        {
            "name": "STM32",
            "includePath": [
                "D:/Program Files/MDK5/ARM/ARMCC/**",
                "${workspaceFolder}/**",
                ""
            ],
            "browse": {
                "limitSymbolsToIncludedHeaders": true,
                "databaseFilename": "${workspaceRoot}/.vscode/.browse.c_cpp.db",
                "path": [
                    "D:/Program Files/MDK5/ARM/ARMCC/**",
                    "${workspaceFolder}/**",
                    ""
                ]
            },
            "defines": [
                "_DEBUG",
                "UNICODE",
                "_UNICODE",
                "__CC_ARM",
                "USE_STDPERIPH_DRIVER",
                "STM32F10X_MD"
            ],
            "intelliSenseMode": "msvc-x64"
        }
    ],
    "version": 4
}

其中,需要在includePathpath中添加头文件路径,${workspaceFolder}/**是工程路径,不用改动,额外需要添加的是keil的头文件路径,

然后在defines中添加宏,也就是在keil的Options for Target的C++选项卡中配置的宏,然后就可以体验VS Code强大的代码提示,函数跳转等功能了(甩keil的编辑器一整个时代)。

Part4编译、烧录

编译和烧录通过VS Code的Task功能实现,通过Task,使用命令行的方式调用keil进行编译和烧录

keil本身就支持命令行调用,具体可以参考keil的手册,这里就不多说了,但是问题在于,使用命令行调用keil,不管是什么操作,他的输出都不会输出到控制台上!!!(要你这命令行支持有何用)

不过好在,keil支持输出到文件中,那我们就只能利用这个做点骚操作了。一边执行命令,一边读取文件内容并打印到控制台,从而就实现了输出在控制台上,我们就能直接在VS Code中看到编译过程了

为此,我编写了一个Python脚本,实现keil的命令行调用并同时读取文件输出到控制台

#!/usr/bin/python
# -*- coding:UTF-8 -*-

import os
import threading
import sys

runing = True

def readfile(logfile):
    with open(logfile, 'w') as f:
        pass
    with open(logfile, 'r') as f:
        while runing:
            line = f.readline(1000)
            if line != '':
                line = line.replace('\\', '/')
                print(line, end = '')

if __name__ == '__main__':
    modulePath = os.path.abspath(os.curdir)
    logfile = modulePath + '/build.log'
    cmd = '\"D:/Program Files/MDK5/UV4/UV4.exe\" '
    for i in range(1, len(sys.argv)):
        cmd += sys.argv[i] + ' '
    cmd += '-j0 -o ' + logfile
    thread = threading.Thread(target=readfile, args=(logfile,))
    thread.start()
    code = os.system(cmd)
    runing = False
    thread.join()
    sys.exit(code)

此脚本需要结合VS Code的Task运行,通过配置Task,我们还需要匹配输出中的错误信息(编译错误),实现在keil中,点击错误直接跳转到错误代码处,具体如何配置请参考VS Code的文档,这里给出我的Task。

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "command": "py",
            "args": [
                "-3",
                "${workspaceFolder}/scripts/build.py",
                "-b",
                "${config:uvprojxPath}"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "problemMatcher": [
                {
                    "owner": "c",
                    "fileLocation": [
                        "relative",
                        "${workspaceFolder}/Project"
                    ],
                    "pattern": {
                        "regexp": "^(.*)\\((\\d+)\\):\\s+(warning|error):\\s+(.*):\\s+(.*)$",
                        "file": 1,
                        "line": 2,
                        "severity": 3,
                        "code": 4,
                        "message": 5
                    }
                }
            ]
        },
        {
            "label": "rebuild",
            "type": "shell",
            "command": "py",
            "args": [
                "-3",
                "${workspaceFolder}/scripts/build.py",
                "-r",
                "${config:uvprojxPath}"
            ],
            "group": "build",
            "problemMatcher": [
                {
                    "owner": "c",
                    "fileLocation": [
                        "relative",
                        "${workspaceFolder}/Project"
                    ],
                    "pattern": {
                        "regexp": "^(.*)\\((\\d+)\\):\\s+(warning|error):\\s+(.*):\\s+(.*)$",
                        "file": 1,
                        "line": 2,
                        "severity": 3,
                        "code": 4,
                        "message": 5
                    }
                }
            ]
        },
        {
            "label": "download",
            "type": "shell",
            "command": "py",
            "args": [
                "-3",
                "E:\\Work\\Store\\MyWork\\STM32F1\\FreeModbus_M3\\scripts\\build.py",
                "-f",
                "${config:uvprojxPath}"
            ],
            "group": "test"
        },
        {
            "label": "open in keil",
            "type": "process",
            "command": "${config:uvPath}",
            "args": [
                "${config:uvprojxPath}"
            ],
            "group": "test"
        }
    ]
}

对于使用ARM Compiler 6编译的工程,build和rebuild中的problemMatcher应该配置为

"problemMatcher": [
    {
        "owner": "c",
        "fileLocation": ["relative", "${workspaceFolder}/MDK-ARM"],
        "pattern": {
            "regexp": "^(.*)\\((\\d+)\\):\\s+(warning|error):\\s+(.*)$",
            "file": 1,
            "line": 2,
            "severity": 3,
            "message": 4,
        }
    }
]

文件中的config:uvPathconfig:uvprojxPath分别为keil的UV4.exe文件路径和工程路径(.uvprojx),可以直接修改为具体路径,或者在VS Code的setting.json中增加对应的项,至此,我们已经完美实现了在VS Code中编辑,编译,下载了。

编译输出:

有错误时输出:

错误匹配:

Part5调试

调试需要使用到Cortex-Debug插件,以及arm gcc工具链,这部分可以参考Cortex-Debug的文档,说的比较详细;

首先安装Cortex-Debug插件和arm gcc工具链,然后配置好环境路径,如果使用Jlink调试,需要下载Jlink套件,安转好之后,找到JLinkGDBServerCL.exe这个程序,在VS Code的设置中添加"cortex-debug.JLinkGDBServerPath": "C:/Program Files (x86)/SEGGER/JLink/JLinkGDBServerCL.exe",后面的路径是你自己的路径。

这里补充一下arm gcc工具链的配置:"cortex-debug.armToolchainPath": "D:\\Program Files (x86)\\GNU Arm Embedded Toolchain\\9 2020-q2-update\\bin",后面的路径是你自己的路径。如果使用STLink调试,需要下载stutil工具,在GitHub上搜索即可找到,同样配置好路径即可。

以上步骤弄好之后,可以直接点击VS Code的调试按钮,此时会新建luanch.json文件,这个文件就是VS Code的调试配置文件,可参考我的文件进行配置。

{
    // 使用 IntelliSense 了解相关属性。
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [

        {
            "name": "Cortex Debug(JLINK)",
            "cwd": "${workspaceRoot}",
            "executable": "${workspaceRoot}/Project/Objects/Demo.axf",
            "request": "attach",
            "type": "cortex-debug",
            "servertype": "jlink",
            "device": "STM32F103C8",
            "svdFile": "D:\\Program Files\\ARM\\Packs\\Keil\\STM32F1xx_DFP\\2.3.0\\SVD\\STM32F103xx.svd",
            "interface": "swd",
            "ipAddress": null,
            "serialNumber": null
        },
        {
            "name": "Cortex Debug(ST-LINK)",
            "cwd": "${workspaceRoot}",
            "executable": "${workspaceRoot}/Project/Objects/Demo.axf",
            "request": "attach",
            "type": "cortex-debug",
            "servertype": "stutil",
            "svdFile": "D:\\Program Files\\ARM\\Packs\\Keil\\STM32F1xx_DFP\\2.3.0\\SVD\\STM32F103xx.svd",
            "device": "STM32F103C8",
            "v1": false
        }
    ]
}

注意其中几个需要修改的地方,executable修改为你的工程生成的目标文件,也就是工程的.axf文件,svdFile用于对MCU外设的监控,该文件可以在keil的安装路径中找到,可以参考我的路径去找,配置完成后,再次点击调试按钮即可进行调试。

相比keil自己的调试功能,VS Code还支持条件断点,可以设置命中条件,次数等,可以极大的方便调试。

总结

通过以上的配置,我们基本上,除了建立工程和往工程中添加文件,其他完全不需要打开keil,所以也无妨说一句,再见,智障keil! 


声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
  • 【7.24 深圳】2025国际AI+IoT生态发展大会/2025全球 MCU及嵌入式技术论坛


  • 相关技术文库
  • 单片机
  • 嵌入式
  • MCU
  • STM
  • 3AT89C51单片机引脚说明及引脚图

    AT89C51是一种带4K字节闪烁可编程可擦除只读存储器的低电压,高性能CMOS8位微处理器,俗称单片机。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU...

    前天
  • 51单片机对LCD1602液晶的驱动设计

    51单片机——LCD1602 1、1602液晶读写时序 (1)、读状态 RS=L,R/W=H,E=H。(判断忙完毕后释放总线) (2)、读数据 RS=H,R/W=H,E=H。 (3)、写指令 RS=L,R/W=L,D0~D7=指令码,E=高脉冲 (4)、写数据 RS=H,R/W=L,D0~D...

    前天
  • 单片机串口如何接收不定长数据的?

    我们在使用其他STM32的单片机的时候,会发现有些困难,会发现常用的方法并不能用,在还没有接收完数据的时候,就解决不了。于是,只能用通用的方法来解决了。 这个通用的方法,其实原理和使用IDLE的原理一样:...

    前天
  • ARM处理器的选型原则

    鉴于ARM微处理器的众多优点,随着国内外嵌入式应用领域的逐步发展,ARM微处理器必然会获得广泛的重视和应用。但是,由于ARM微处理器有多达十几种的内核结构,几十个芯片生产厂家,以及千变万化的内部功能配置组合,...

    07-10
  • 有哪些低功耗设计方法?单片机系统低功耗设计要点介绍

    功耗,已经是一个老生常谈的话题了。对于功耗,大家多多少少有所了解。目前,很多产品的宣传里便带有低功耗噱头。为增进大家对功耗的认识,本文将基于两点介绍功耗:1.低功耗主要设计方法,2.单片机系统低功耗设计...

    07-10
  • 8位32位MCU如何选择?如何选择合适的MCU?

    MCU,对于普通人而言,是一个高大上的存在。但是,在工业中,MCU确实常见产品。为增进大家对MCU的认识,本文将基于两点介绍MCU:1.8位MCU和32位MCU如何选择?2.如何选择合适的MCU。如果你对MCU具有兴趣,不妨继续往...

    07-09
  • ARM开发:一 ARM微处理器概述

    1.1ARM-Advanced RISC Machines ARM(Advanced RISC Machines),既可以认为是一个公司的名字,也可以认为是对一类微处理器的通称,还可以认为是一种技术的名字。 1991年ARM公司成立于英国剑桥,主要出售芯片设计技术...

    07-08
  • 分析C51单片机的一些误区和注意事项

    简介:常看见初学者要求使用_at_,这是一种谬误,把C当作ASM看待了。在C中变量的定位是编译器的事情,初学者只要定义变量和变量的作 用域,编译器就把一个固定地址给这个变量。怎么取得这个变量的地址?要用指针。 1) C...

    07-08
  • 51单片机几个延时程序

    简介:51单片机几个精确延时程序:在精确延时的计算当中,最容易让人忽略的是计算循环外的那部分延时,在对时间要求不高的场合,这部分对程序不会造成影响. 一. 500ms延时子程序(晶振12MHz,一个机器周期1us.) 程...

    07-08
  • 总结单片机软件抗干扰的几种办法

    简介:在提高硬件系统抗干扰能力的同时,软件抗干扰以其设计灵活、节省硬件资源、可靠性好越来越受到重视。下面以MCS-51单片机系统为例,对微机系统软件抗干扰方法进行研究。 1、软件抗干扰方法的研究 在工程实践中...

    07-08
  • 基于C51单片机实现汽车座椅自动控制系统的软硬件设计

    引言 随着人们生活水平的提高,对汽车座椅的舒适性要求也越来越高,要求对汽车座椅地调节能够更加简单、方便、快捷。目前,汽车座椅位置的调节多采用基于手动调节方式的机械和电动控制两种方式。汽车座椅位置的调节...

    07-02
  • MCS51单片机程序设计时堆栈的计算方法解析

    用C语言进行MCS51系列单片机程序设计是单片机开发和应用的必然趋势。Keil公司的C51编译器支持经典8051和8051派生产品的版本,通称为Cx51。应该说,Cx51是C语言在MCS51单片机上的扩展,既有C语言的共性,又有它自己...

    07-02
下载排行榜
更多
评测报告
更多
广告