VSCode一直被冠以最强的编辑器,其自身是支持SSH远程连接以及Debug功能,所以在查找了相当多的资料后整理了一下远程调试设备的方法,通过SSH远程连接ubuntu(这里采用的是ubuntu18.04),直接访问编辑linux下的代码,并通过MakeFile文件进行编译,最后实现远程debug代码。
值得注意的是,现在仅仅是在linux上验证测试过,未在实体设备上验证,如有需求自行验证,原理相同,理论是可用的。
如果在之前就使用过ssh,安装openssh-server、wget、curl后可以跳过这节。
在linux上安装必要工具:
sudo apt-get update
sudo apt-get install openssh-server wget curl
配置SSH文件,允许SSH登录root权限
sudo vim /etc/ssh/sshd_config
这里的如果习惯用gedit的话也可以
在打开的文件中,分别搜索下面三项
再修改完必要的配置保存退出后,需要对ssh服务进行重启。
service ssh restart
打开本地VSCode,并安装扩展插件C/C++和remote-ssh
安装完插件remote-ssh后,在侧边栏会出现其功能按键。
点击后显示远程登陆界面。
可以发现我这里已经有一些连接记录存在了,第一次进入时是空白的。
将鼠标放在SSH TARGETS上(不点击),后面会显示出功能按键。
圈出来的三个按键分别为新建连接(Add New)、配置项、刷新。
点击"+",即点击新建连接(Add New),会弹出ssh连接框。
在里面按照固定的格式进行连接:
ssh -p 22 linux登录账户名@linux地址
其中linux登录账户名就是每次登陆账户所使用的账户名,linux地址其实就是设备的IP地址,使用ifconfig或者其他方式进行获取。
进行操作SSH时会有输入账户密码的操作,彼时输入密码回车就可以。
接下来点击显示的IP地址后面的添加按键,如果有密码输入框,输入密码就可以。
这时是打开了一个新的接口专门去处理远程的数据信息,大概就是将远程的信息映射到本机PC的VSCode中进行展示,在这个窗口中可以使用终端,也可以直接编辑代码,编译代码,debug代码,最后通过内部协议与远端进行映射改变。
当输入完密码连接成功后,操作这个界面与操作本地 VSCode是基本无异的。
这时如果你已经有了想要调试的项目,直接打开就好,如果没有也可以用终端去git clone和配置。
这个终端与设备本机打开的终端效果是相同的。
至此已经完成了远程VSCode的连接与配置,后面所有的在线编辑、编译、debug等都是基于这个VSCode界面实现的。
在打开的远程VSCode界面中可以为远程VSCode安装拓展插件,例如中文插件等
实质上操作这个VSCode界面和平时操作本地文件是一样的,所以下main涉及的编译、debug等配置过程是同样适用于VSCode编译、debug本地项目的。
编译项目的策略是通过项目本身的MakeFile文件进行,不改变项目本身的结构,使用时需要在项目目录下存在MakeFile文件。
以涂鸦IPC sdk和demo为例进行展示。
涂鸦IPC demo地址:https://github.com/tuya/tuya-iotos-embeded-multimedia-demo.git
涂鸦IPC sdk地址:https://github.com/tuya/tuya-iotos-embeded-sdk-multimedia.git
我这里先创建一个临时文件夹来装本次演示用到的文件夹:
mkdir test
cd test
使用下面的命令下载demo项目:
git clone https://github.com/tuya/tuya-iotos-embeded-multimedia-demo.git
git clone https://github.com/tuya/tuya-iotos-embeded-sdk-multimedia.git
首先创建一个空的文件夹,用来装demo与sdk,配置环境。
mkdir DEMO_TEST
CD DEMO_TEST
将demo与sdk资源拷贝进去
cp -r ../tuya-iotos-embeded-multimedia-demo/demo_for_ipc ./
由于sdk克隆下来后是md文件,所以可以进入目标sdk的md文件内获取sdk下载url:
cd ../
cd tuya-iotos-embeded-sdk-multimedia
cd Linux
由于是使用VSCode的ssh远程终端访问的,所以gedit界面编辑器是无法使用的,使用vim打开dowload_list_linux_4.8.8.md
vim dowload_list_linux_4.8.8.md
将其中的Ubuntu x64下的地址复制出来,复制下来就是这个网址:
https://images.tuyaus.com/rms-static/372d1460-50c6-11eb-bc15-27e102d5b696-1610009782438.tar.gz?tyName=tuya_ipc_sdk_4.8.8_linux-ubuntu-6.2.0_64Bit.tar.gz
然后退出vim:
1、ESC按键
2、shift按键 + :按键
3、输入q!
4、ENTER
接下来就是进入demo文件夹内,将sdk下载下来:
wget https://images.tuyaus.com/rms-static/372d1460-50c6-11eb-bc15-27e102d5b696-1610009782438.tar.gz?tyName=tuya_ipc_sdk_4.8.8_linux-ubuntu-6.2.0_64Bit.tar.gz
tar -zxvf 372d1460-50c6-11eb-bc15-27e102d5b696-1610009782438.tar.gz?tyName=tuya_ipc_sdk_4.8.8_linux-ubuntu-6.2.0_64Bit.tar.gz
rm -rf 372d1460-50c6-11eb-bc15-27e102d5b696-1610009782438.tar.gz?tyName=tuya_ipc_sdk_4.8.8_linux-ubuntu-6.2.0_64Bit.tar.gz
tree linux-ubuntu-6.2.0_64Bit
cd linux-ubuntu-6.2.0_64Bit
tar -zxvf tuya_ipc_sdk_4.8.8_wifi_linux-ubuntu-6.2.0_64Bit_2021_01_06_16_42_29.tar.gz
cp -r linux-ubuntu-6.2.0_64Bit/tuya_ipc_sdk ./sdk
然后将linux-ubuntu-6.2.0_64Bit文件夹删除:
rm -rf linux-ubuntu-6.2.0_64Bit
将资源文件复制进来:
cp -r ../../tuya-iotos-embeded-multimedia-demo/demo_resource ./resource
此时就完成了demo的配置工作,只要执行编译,将资源文件resource拷贝进生成的output文件中就可以。
使用VSCode打开这个目录:
首先Ctrl+shift+p搜索Tasks:Run Task->配置任务->使用模板创建->others。然后把下面代码替换进去
tasks.json
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "clean", // 任务名称
"command": "make", // 命令
"args": ["clean"], // 相当于make clean
"type": "shell"
},
{
"label": "Build",
"type": "shell",
"command": "make APP_NAME=demo",
"group": {
"kind": "build",
"isDefault": true
}
},
{ // 依次调试多个任务,若不配置此,则每次launch只会启动一个任务。
"label": "build-all",
"dependsOn": [
"clean",
"Build"
]
}
]
}
最主要的就是make APP_NAME=demo,这也是在命令行编译demo时使用的命令,tasks.json进行编译时依靠项目目录下的MakeFile文件,通过CTRL+SHIFT+B的快捷键唤起编译,结果与直接在命令行运行make APP_NAME=demo无异。
这里在tasks包含的三个任务(clean、Build、build-all)可以只保留前两个,甚至只保留Build。
使用快捷键CTRL+SHIFT+B编译项目。
如果使用的ubuntu版本超过了ubuntu16.10,可能会遇见下面的错误。
其发生的原因为:
解决方式为在MakeFile文件内添加参数:-no-pie:
此时再进行编译发现编译通过。
至此我们就完成了涂鸦IPC DEMO项目的编译。
点击运行和调试按键。
出现运行于调试界面:
点击蓝色字体创建launch.json文件,选则C++(GDB/LLDB)
如果没有这个选项,在插件添加页面找到C/C++在ssh重新加载。然后会提醒刷新窗口,再次添加launch.json 就有会出现C++(GDB/LLDB)。
将下面的代码复制进去。
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "2.0.0",
"configurations": [
{
"name": "tuya_ipc_demo",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/output/tuya_ipc_demo",
//workspaceFolder代表你vscode打开的工作目录,即左上角的大写字体
"args": ["-m", "2"],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
],
//"preLaunchTask": "build-all",
"miDebuggerPath": "/usr/bin/gdb", // gdb路径
}
]
}
参数名 | 参数含义 |
---|---|
name | 配置名称,将会在启动配置的下拉菜单中显示 |
type | 配置类型,这里只能为cppdbg |
request | 请求配置类型,可以为launch(启动)或attach(附加),这里为launch |
program | 将要进行调试的程序的路径 |
${workspaceFolder} | 代表vscode打开的工作目录,即左上角的大写字体 |
args | 程序调试时传递给程序的命令行参数,没有时可以设为空 |
stopAtEntry | 设为true时程序将暂停在程序入口处,一般设置为false |
cwd | 调试程序时的工作目录,一般为${workspaceRoot}即代码所在目录 |
environment | 要添加到程序环境的环境变量。示例: [ { “name”: “config”, “value”: “Debug” } ],而不是 [ { “config”: “Debug” } ],这里暂时未用到设为空 |
externalConsole | 调试时是否显示控制台窗口,一般设置为true显示控制台 |
MIMode | 指示 MIDebugEngine 要连接到的控制台调试程序。允许的值为 “gdb”、“lldb”。这里使用gdb调试 |
setupCommands | 为了安装基础调试程序而执行的一个或多个 GDB/LLDB 命令。示例: “setupCommands”: [ { “text”: “-enable-pretty-printing”, “description”: “Enable GDB pretty printing”, “ignoreFailures”: true }]。默认就好 |
miDebuggerPath | MI 调试程序(如 gdb)的路径。如果未指定,将首先在路径中搜索调试程序。 |
preLaunchTask | 调试会话开始前要运行的任务。如果想在每次调试前进行编译,可以选则打开。会掉其编译任务。 |
./tuya_ipc_demo -m 2 -p [PID] -u [UUID] -a [AUTHKEY] -r "./" -t "[TOKEN]"
但是在launch.json中,我们这么输入:"args": ["-m", "2", "-p", "gpkguYNp7yI4k413",
"-u", "tuyaOneUuidForOneDevice", "-a", "tuyaOneAuthkeyForOneUUID",
"-r", "./", "-t", ""],
对比一下就是所有的空格都被逗号代替了,以**-m 2为例,被替换为"-m", “2”**cp -r resource/ ./output
依据demo使用说明文档,获取token,放置在launch.json的args参数中,点击F5按键开始调试。
其中右侧的调试按键继续调试、单步跳过、单步调试、单步跳出、重启、停止,其中需要注意的是单步调试可以进入函数内部,但是仅限于VSCode可以查看的部分,例如这个项目中demo源码部分均可以进入,但是sdk内部静态库内源码无法进入,第三方库也无法进入。
在遇见无法访问的函数(sdk的静态库,第三方库等)时,虽然会调试这个报错,但是不影响调试,这类函数可以直接使用单步跳过按键跳过