一. 简介
我们都知道在嵌入式的开发过程中,第一步就是选择开发板。然后根据开发板的使用说明书进行系统的移植,当我们的linux系统移植成功,开发板可以正常的启动,这个时候就需要开发我们的应用程序,问题来了,我们的代码在哪编写那,怎么编译那,怎么放到开发板运行那,怎么调试那?
这些问题是嵌入式开发过程中必须解决的问题,或许你已经有了自己的开发方式,但是不一定是最高效的,一个好的开发途径势必事半功倍。今天我就将我的开发方式分享给大家。
二. 编辑器的选择
至于说我们的代码在哪来编写这个问题,简单的说我们windows系统自带的记事本就可以,但肯定没人用,因为我们追求的是高效率,如果你用过很多的编辑器,相比较之下肯定用自己的选择。
1. notepad++
我们先说一下notepad++,这个软件在编写单文件代码还是比较方便的,不管是界面还是功能,唯一的不足就是在大项目的开发过程中文件比较多,查找函数等等就成了问题
2. Vs Code
再就是Vs Code这款软件,微软的一款软件,可以理解为Visual studio的缩小版,它的占用内存比较小,而且集合了各种各样的插件,比如代码的颜色,语法的提醒等等,在开发过程中还是挺不错的
3. Source insight
但是相比Source insight 的话,个人感觉还是Source insight比较好用,因为他界面的代码布局可以自己调整,主题也比较多,美化程度就不用说了,最主要的问题是在大工程的项目开发过程中,可以很方便的定位到代码中的任意一个函数,而且全局变量函数声明什么的显示很清晰,强烈推荐使用该软件。
软件下载地址
Source insight4.0 破解版下载
4. Source insight 新建项目工程
三. 代码的快速编译
Win和Linux文件共享
Source insight代码编写很是方便,但是唯一不足就是不能进行代码的编译,这一点也能够理解。在嵌入式开发过程中不同的开发板,不同厂家的芯片就会有不同的编译方式。我们的都知道嵌入式开发代码的编译都是在linux系统下进行的,应为涉及到代码的编辑,所有可以使用windows系统下安装linux虚拟机的方式。
安装好虚拟机,一般的代码编译在开发板的使用说明书中会提到用那种交叉编译工具链,也会有配置的方式。现在的问题就是windows下编辑好的代码快速移动到linux虚拟机下进行编译。
我们可以在桌面以我们的项目名称新建一个文件夹,将我们的代码放到里面,然后通过Source insight 新建一个工程,将这些文件添加到工程就可以进行代码编辑。
打开虚拟机将桌面上的该项目文件夹设置成共享文件夹,先点击此处的虚拟机,然后点击最后一项设置,也可以用快捷键“CTRL+D”
点击选项后将文件夹共享调为总是启用,然后再点击添加。
选择我们桌面的新建文件夹的路径,点击下一步。
启用此共享默认是打对勾的,我们不用管直接点击完成,后就可以实现windows系统和linux虚拟机文件共享,当然也也可以直接复制粘贴但是个人感觉太慢了。
代码编译,我们打开linux Ubuntu的shell终端,直接创建一个我们工程的文件夹“mkdir test”然后进入test目录下
mkdir test
cd test
复制我们的项目文件夹下的所有文件到linux系统新建的文件夹下,输入下面命令,然后可以通过ls来查看一下有没有复制成功
cp –r /mnt/hgfs/test/* ./
在我们的Makefile编写好编译的方式,此时就可以一键make了,直接将我们的代码进行编译生成可执行的二进制文件
四. 程序的运行
1. 网络环境的搭建
我们在虚拟机里将我们的代码编译成功如何进行上传到开发板快速运行测试那,这里我们使用ssh服务进行,一般的linux都会自动ssh服务。
我们用一根网线将我们的开发板与我们的电脑相连接,然后分别设置各自的ip,在电脑端我们打开shell终端输入一下命令设置固定IP为192.168.0.101
ifconfig eth0 192.168.0.101 netmask 255.255.255.0 up
1
提示没有权限可以输入 “sudo –s”然后输入密码,再重复上面操作
然后在开发板的串口端也输入命令设置固定ip为192.168.0.102,
ifconfig eth0 192.168.0.102 netmask 255.255.255.0 up,
然后可以通过ifconfig 命令来查看有没有设置成功,等我们的固定IP都设置成功之后就可以用Ping命令来测试网络通不通,在电脑端可以输入 ping 192.168.0.102进行测试,在开发板端可以输入 ping 192.168.0.101进行测试。
2. ssh服务使用
然后用在虚拟机的shell终端输入
ssh [email protected] //ip为开发板的ip
然后再下面提示的部分输入密码就可以连接上我们的开发板,可以用命令进行控制我们的开发板,后面我们可以将设置固定IP做为开机自动执行项,后面就可以直接给开发板供电,不需要打开串口了,直接采用网络进行连接
现在的问题是如何将我们的虚拟机中的项目文件同步到开发板的文件系统,这里我们采用ssh和nfs两种方式,推荐使用nfs
具体ssh服务的文件上传和下载调试操作参考这边文章
Linux下SSH调试工具的使用
3. NFS的使用
通过下面的命令安装 NFS 服务器
sudo apt-get install nfs-kernel-server
1
新建一个 work 目录做为 NFS 的一个工作目录,以后我们可以把交叉编译的程序放在这个目录里,开发板可以很方便共享到这个目录里的文件。
使用下面命令编辑/etc/exports 文件,配置 NFS 服务路径
sudo gedit /etc/exports
在尾部添加
/home/alinx/work *(rw,sync,no_root_squash,no_subtree_check)
配置 /home/alinx/work 目录为 NFS 的一个工作目录。
执行下面命令重启 rpcbind 服务。 nfs 是一个 RPC 程序,使用它前,需要映射好端口,通过 rpcbind 设定
sudo /etc/init.d/rpcbind restart
执行下面命令重启 nfs 服务
sudo /etc/init.d/nfs-kernel-server restart
五. 程序调试采用
Linx下调试,没有想C++一样的debug通过图形界面来调试,但是linux系统的GDB调试也是特别好用的。
下面将gdb命令总结一下
1、运行命令
run:简记为 r ,其作用是运行程序,当遇到断点后,程序会在断点处停止运行,等待用户输入下一步的命令。
continue (简写c ):继续执行,到下一个断点处(或运行结束)
next:(简写 n),单步跟踪程序,当遇到函数调用时,也不进入此函数体;此命令同 step 的主要区别是,step 遇到用户自定义的函数,将步进到函数中去运行,而 next 则直接调用函数,不会进入到函数体内。
step (简写s):单步调试如果有函数调用,则进入函数;与命令n不同,n是不进入调用的函数的
until:当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体。
until+行号: 运行至某行,不仅仅用来跳出循环
finish: 运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息。
call 函数(参数):调用程序中可见的函数,并传递“参数”,如:call gdb_test(55)
quit:简记为 q ,退出gdb
2、设置断点
break n (简写b n):在第n行处设置断点
(可以带上代码路径和代码名称: b OAGUPDATE.cpp:578)
b fn1 if a>b:条件断点设置
break func(break缩写为b):在函数func()的入口处设置断点,如:break cb_button
delete 断点号n:删除第n个断点
disable 断点号n:暂停第n个断点
enable 断点号n:开启第n个断点
clear 行号n:清除第n行的断点
info b (info breakpoints) :显示当前程序的断点设置情况
delete breakpoints:清除所有断点:
3、查看源码
list :简记为 l ,其作用就是列出程序的源代码,默认每次显示10行。
list 行号:将显示当前文件以“行号”为中心的前后10行代码,如:list 12
list 函数名:将显示“函数名”所在函数的源代码,如:list main
list :不带参数,将接着上一次 list 命令的,输出下边的内容。
4、打印表达式
print 表达式:简记为 p ,其中“表达式”可以是任何当前正在被测试程序的有效表达式,比如当前正在调试C语言的程序,那么“表达式”可以是任何C语言的有效表达式,包括数字,变量甚至是函数调用。
print a:将显示整数 a 的值
print ++a:将把 a 中的值加1,并显示出来
print name:将显示字符串 name 的值
print gdb_test(22):将以整数22作为参数调用 gdb_test() 函数
print gdb_test(a):将以变量 a 作为参数调用 gdb_test() 函数
display 表达式:在单步运行时将非常有用,使用display命令设置一个表达式后,它将在每次单步进行指令后,紧接着输出被设置的表达式及值。如: display a
watch 表达式:设置一个监视点,一旦被监视的“表达式”的值改变,gdb将强行终止正在被调试的程序。如: watch a
whatis :查询变量或函数
info function: 查询函数
扩展info locals: 显示当前堆栈页的所有变量
5、查看运行信息
where/bt :当前运行的堆栈列表;
bt backtrace 显示当前调用堆栈
up/down 改变堆栈显示的深度
set args 参数:指定运行时的参数
show args:查看设置好的参数
info program: 来查看程序的是否在运行,进程号,被暂停的原因。
6、分割窗口
layout:用于分割窗口,可以一边查看代码,一边测试:
layout src:显示源代码窗口
layout asm:显示反汇编窗口
layout regs:显示源代码/反汇编和CPU寄存器窗口
layout split:显示源代码和反汇编窗口
Ctrl + L:刷新窗口
六. 代码版本管理
代码的版本在我们项目开发过程中非常重要,一个成品不可能一次性完成,都需要代码反复的修改和优化。
之前管理代码的办法是复制一份,进行修改修改完在删除之前的这样的方法效率挺低的,而且版本一多就会出现混淆等问题,所以这里推荐大家使用 git 里管理我们的代码