除非你是设计小型模拟电子电路,不然这年头离开了计算机的帮助,在嵌入式系统设计中很难做成什么事。我觉得我应该分享一个能帮助我完成工作的软件工具列表。它们大多数都是免费的或者比较便宜的。它们大多数也和软件一起工作。如果你向来不需要设计,阅读或者编辑任何软件,那么你属于读了这篇文章不会从中受益的那一小部分人。
免责声明:“最佳”软件工具通常是一种主张。你可能不同意我的主张,那就取其精华吧。
1. 版本控制系统 不管你工作在一个100人的团队,还是独自一人干活,如果你从事设计,你应该会用到版本控制软件。这是一种可以管理文档的不同版本的软件,不管是图表还是源代码。像源代码或配置文件这样的文本文档尤其适合于版本控制,因为很容易查看版本间的差异,合并两个版本之间的改动,特别是多个人工作在一组文档上。
版本控制里的文档集合称为版本库(repository)。版本库所在的位置某种程度上取决于你用什么样的版本控制系统——基本上有两类版本控制系统:集中式和分布式。集中式版本控制包含一个存放版本库的服务器。当你方便的时候,你提交你的修改到版本库里。分布式版本控制系统(DVCS)不需要中央服务器:每个人工作在有他们自己的本地缓存的版本库上(包括整个历史记录),可能会从一个版本库传送新的提交到另一个版本库,通过在原版本库上 “push”或者在目标版本库上“pull”完成。
2012年开源社区里最流行的三个版本控制系统是Subversion(SVN),Mercurial(hg)和Git。Subversion是集中式的,而Mercurial和Git是分布式的。
我用Mercurial开发个人软件。建立版本库很简单。到你工作的根目录下输入hg init
,然后用hg add
添加你喜欢的文件,然后用hg commit
提交。我只需要花几分钟,立马就能够回退到某个文件的早期版本。我会专门为我家里PC机上的服务配置文件(例如Apache网站服务器)这样做——如果我修改了一个文件,并且这个修改引起了一个bug,我只用回退到该文件的早期版本就可以了。
如果项目只有你一个人在做,管理版本控制系统容易得不可思议——只需要在较好的暂停点时不时进行提交。如果你和别人一起工作,当你们中的一个人做出修改而另一个人做出不同的修改产生冲突时,有几种方法来协调。就是所谓的“合并”。对于文本文档,只要你经常这样做,通常很容易。对于二进制文件,几乎不可能。比较合适的处理方式是在库里的文件上放置一道锁,清楚地声明你工作在一个特殊的文件上,并且其他人不应该工作在这个文件上。
这三个系统(svn,hg和git)起先全都是命令行工具,但是它们都有各式各样的图形用户界面前端,包括Tortoise系列的用户界面。那是一个在你的操作系统的文件浏览器(如 Windows Explorer或者Mac OSX Finder)上扩展的轻量级组件。它们不如非免费的版本控制系统那样易用。我们工作中用过SurroundSCM,当我有点不太喜欢后端的行为方式时,我发现Surround UI在协调分支间的差异上更加好用。
还值得注意的是有很多版本库在线主机系统,有bitbucket.org,SourceForge,Google Code和GitHub。它们全都为公开版本库提供免费的主机服务。bitbucket免费为项目成员不超过5人的私有版本库提供主机服务。我强烈推荐使用像Mercurial或者Git这样的分布式版本控制系统,因为这意味着你可以把项目从一个主机站点转到另一个上,并且即使站点临时宕机,你依旧可以使用本地的版本库的拷贝。
2. 文件比较工具 在将代码合并到版本控制系统中,或者仅仅是想看看一个文件同另一个文件之间的差异时,你会需要文件比较工具。有命令行的工具如“diff”,还有图形用户界面的文件比较工具。我喜欢叫Beyond Compare的程序——不是免费的,但是不贵,并且易用。它还可以比较两个文件夹,可以让你做3-way文件比较。Beyond Compare有Windows和Linux的,OSX版本的正在开发但是现在还没有。其他的还有SourceGear DiffMerge(免费,跨平台 Win/OSX/Linux),Compare It!(便宜,只有Windows的),DeltaWalker(价格适中,OSX)和UltraCompare(价格适中,跨平台)。
3. 编辑器 和文本文件打交道可难可易,这取决于你用的软件。重量级的编辑器是像Eclipse,NetBeans或者Visual Studio那样的集成开发环境(IDE)。假如你用特定的软件工具和在特殊的处理器上编程,那么它们很出色。但是有时候你需要的只是快速编辑文件。操作系统自带的基本编辑器(像Windows上的记事本,Mac上的TextEdit)是轻量级的,但他们没有多少功能。我喜欢有中量级的编辑器可以用:这个类目里有一些好的免费编辑器,如Windows上的Notepad++,Mac上的TextWrangler。我还用过非免费的UltraEdit,它更强大一点,而且在Windows,OSX,Linux上都可以用。SlickEdit是专业级的编辑器,要价数百美元,可能对绝大多数任务杀伤力过大,但我的一些同事却很忠于它。(希望他们没有吐槽它)
提到编辑器不提GNU emacs就不公平了——它是免费的开源的编辑器,诞生于当大多数操作系统还是基于终端的时候。它的大多数命令都是用一串难以理解的按键发出。你喜欢这样的方式就行,我是不喜欢的。它是一个非常强大的编辑器,可以通过Lisp语言编程定制。你可以在emacs里做任何事,只要它是可以在终端显示的。
我要找的编辑器的两大功能如下:
- 大文件支持。如果很大的文件(若干兆),确保你的编辑器可以在不用把文件全部加载到内存就能打开它。记事本不行,但是Notepad++和UltraEdit可以。
- “多文件查找”功能 典型的源代码树包含多个文件,你经常会忘记把东西放哪了。(好吧,至少我会忘记把东西放哪了!)在多个文件里搜索一个单词或模式的能力是无价的。Unix 的“grep”允许你用命令行做这样的事,但是编辑器里的“多文件查找”功能可以让你双击查找结果,然后跳到编辑器里的该行上。
你可能还需要在十六进制编辑器里编辑二进制文件——可以让你查看和编辑那些不可打印字符的字符码。Notepad++和UltraEdit都有十六进制编辑模式。如果你用Mac,试试单机版的Hex Fiend——它很不错。
还有用于XML文件的特殊编辑器——在免费类目里,有XML Notepad和firstobject的XML编辑器“foxe”。foxe的用户界面有点笨拙,但是用来编辑大型文件非常非常不错。
4. Build 工具 如果你开始在IDE里写软件,只用点击”构建“,然后程序就给你编译你的源代码。这样做要注意,它意味着你在让IDE去操心那些细节。对于你正在其中学习某个东西的小系统倒还好。但是有大量的选项可以改变软件的编译方式,在IDE里它们被埋藏在菜单里,并且也不容易从一个项目转移到另一个项目。运气好的话,你可以识别出用于存储构建配置的那些文件,然后可以检入到版本控制系统,因为不然的话你保存的不是完整的项目源码。
专业的软件工程师——重申,这是一家之言——应该用一种明确的构建工具。标准的原味的(plain-vanilla)解决方案(我宁愿错打成痛苦味的pain-vanilla,并这样保持下去)是一个在70年代引入的叫做make的程序。不幸的是它现在仍被在用。makefile由像这样若干行构成:
- foo.obj: foo.c
- cc -o $@ $<
它们是一些规则,告诉make如何通过执行程序(这个例子里是“cc”)把源文件(例如上面的“foo.c”)变成目标文件(例如 “foo.obj”)来构建你的软件。它们还指示依赖关系:假设文件F3依赖于运行命令X从文件F2生成文件F3,文件F2依赖于运行命令Y从文件F1生成文件F2——构建工具要能够推断出依赖关系图,这样如果你改变了文件F1,它能够知道必须相应地重新构建文件F2和文件F3。这可能看起来微不足道,但是在任何项目里,除了那种微型软件项目,这都是相当重要的。我从事的是相对简单的软件项目,它只有数十个源文件,但是全部编译需要5分钟。有合适的构建工具正确的捕获依赖关系,根据你做的修改,让你只增量编译那些有需要的文件。
make有很多短板。别的不说,makefile的语法很含糊,你在编译时需要做特殊处理的地方,它难以处理这种特殊情况,你不去为此写一些单独的脚本是不行的。
对于Java程序而言,标准工具是ant和maven。它们让事情更容易,还可以用来构建Java程序之外的其他系统,但是在一般开发环境下不经常用到。
还有很多其他的构建工具。过去的几年里,我开始将我的偏好从陈述性语法(如makefile和ant脚本)的工具转移到更加多用途的语法的工具上。这样的想法是因为对于大多数简单的任务,你可以描述得非常简明,但是如果你想要做点复杂的事,你拥有多用途编程语言的全部威力。(举个例子,如果你想在一个特殊的构建任务里启用命令行选项“-On”,这里“n”是一个数字,等于文件的大小模以7。你可以写一个自动做这个的方法)这些工具包括rake(基于Ruby),gradle(基于Groovy),scons和waf(它俩都基于Python)。我用了scons三年,因为我懂Python。是一个同事给我推荐的scons。它在某些地方工作的很好,并且极其灵活,但是在其他地方真的难以去修改scons的默认行为,让它做你真正要做的。最近我刚开始用waf。我发现更容易让它做我需要做的,因此如果你有一个新项目,我推荐你看看waf,尽管我希望它有一个不这么神秘的名字。
5. 脚本工具 有时候你需要快速组装一段软件来做某件事。通常很难用C或者C++来实现,因为你必须花费精力写代码来解析字符串,或者读文件,或者任何别的什么。然后你得为每个计算机平台把这个C/C++程序编译成可执行文件。啊…
更好的解决方案是使用脚本语言。它们通常都是解释性的计算机语言,解释器提供了大多数操作系统的版本。所以如果你写了一个脚本,应该可以用在不同的操作系统上。
现代脚本语言的例子是Python,Ruby和Groovy。(我更喜欢Python。)早期的脚本语言包括awk和Perl。我有一些避免使用Perl的理由:它的语法非常奇特和神秘,不同的类型有不同的前缀($foo
是一个单变量,但是@foo
是一个数组),还有它鼓励使用“伪变量”(<>
和$_
),它的一些副作用隐含地依赖于程序里其他被执行的动作。这些造就了不良的编程风格:编写简短而神秘的脚本,它可以用几行标点符号聪明地完成一些事,但是别人阅读和维护都不易。我惭愧地承认10年前我大量使用awk,因为它比perl简单。awk是一种古老的文本处理脚本语言,曾经有它的地位,但是在某些角度和Perl一样糟糕,都鼓励不好的编程实践。
不管你喜欢哪个,我会强烈建议你用一种能够在调试器里测试的语言。我用awk的经历很糟糕,调试程序的时候我不得不放一些打印语句在里面,告诉我发生什么了。用Python就很开心,因为有一个很好的Eclipse的插件叫做pydev。用它你可以在脚本任何地方设置断点和单步调试。
我时不时也用一个叫做JSDB的程序。JSDB是一个独立的JavaScript的外壳程序,用创立于Firefox网页浏览器的SpiderMonkey JavaScript引擎构建。它还有一些访问文件,数据库,网络流和串行端口等等的工具类。它没有解释性的调试器(尽管有一个奇怪的调试器。该调试器有一种即时网络服务器,你可以把你的网页浏览器指向你计算机上的一个端口,它就可以让你调试程序),并且有时候有一点诡异,但是它比起Python更轻量级,对于有些事情,我发现我能更快着手。
我在这节所提到的所有脚本语言都是免费的。
6. 数值分析工具 除非你做的东西像能够联网的交通灯这种真的很简单,否则有这种可能就是你在嵌入式系统项目里的做某种数学部分。你也许要给数据作图,或者为数据拟合曲线,或者解方程,或者设计一个低通滤波器,或者观察当你修改参数后你的系统改变了多少。在这些任务上数值分析工具可以帮到你。它们包括MATLAB,Mathematica,和MathCAD这样的程序。它们都不是免费的。完全版的MATLAB还有它的全套工具箱会花掉你数千美元,不过它们提供了大量的功能。MATLAB擅长于数据分析,Mathematica擅长符号代数。MathCAD介于两者之间,是所见即所得的处理方式:用来得到你在MathCAD的工作表(worksheet)里所见到的输出的每个运算,在该工作表上你都能看到。因此它一目了然。如果你给谁打印这个工作表,他/她能看到要去复制你的工作成果所需的所有计算步骤。例如和Excel工作表比较,你看到的是运算的结果。要想看的运算步骤,你需要到每一个单元格里去看是否有公式。
MATLAB也有一些“山寨”免费软件:SciLab,Octave和PyLab。它们都提供了MATLAB提供的基本功能,语法也要么一样,要么很相似。但是没有一个像MATLAB那样优美和专业。PyLab的额外的卖点是用 Python语言实现,还有为Python提供了科学计算和作图的库。因此如果你懂Python,你可以利用这些知识去进行科学计算。
我对MATLAB是爱恨交加的关系。一方面,它是如此美丽的软件,让你做数值分析,可视化,还有额外的包罗万象的工具箱(信号处理,滤波器设计,控制回路仿真,等等)。另一方面,它不便宜,在MathWorks里的那些出售MATLAB的人们在炫耀他们最新的功能时乐呵呵的好像价格是不需要考虑的。
关于数值分析工具,我有最后一句恳求的咆哮体
不要用Excel进行数值分析!!!
1996年我开始工作时还是一个电气工程师,我还不懂MATLAB,所以当我要给数据作图时,我用我所知道的:微软Excel。Excel是主要针对商业应用的电子表格软件,但是它可以读文字分割文件(如逗号分隔值CSV文件),有某种控制绘图的方式能让你给结果作图,因此它可以用于给数据图像化。但是如果要做任何超出基本绘制的事情,你会发现要这样非常困难,并且很快就会令人沮丧。如果你有一组数据要图像化,或许不是那么糟糕,而且你可以交互式的让它变成你想要的样子。如果你有一批数据文件想要用同样的方式绘图,真的是个很大的麻烦,你要手动地反反复复去做同样的事情直到结束。当然,你可以用 Visual Basic编写宏代码。当我想要在一个页面上做多个图,并对齐坐标轴时我就这么做过。但是接着你会发现你所知道的对象模型既变态又古怪,可能不能让你做你想要做的。然后你便开始对住在华盛顿雷德蒙的某些人起了坏念头。在Excel里如果你遇到了要写宏代码的时候,停下来想想你的情况。那些你投入在让Excel做你要做的事情的时间,你可以花在学习其他能更容易绘图和分析数据的,用于科研而不是商业的软件上。记住,在微软的那些人试图制作能销售和上市的软件,人们用这样的软件可以解决他们的问题。而作为工程师,我们得到的不管什么样的功能刚好是在给自己增加困难。
7. 文档工具 你经常会和其他人交流你的想法,有很多不同类型的软件可以帮助你做这个。是的,有不免费的微软程序像用于流程图/绘图的Visio,写文档的Word,还有演讲用的PowerPoint。但是有时候你想要免费的或者更专门的东西,用于特殊类型的文档。
- 图形可视化 我们不是在此谈x-y图,而是能够可视化带有节点和边的网络。我用graphviz(基于命令行的)和yEd(交互式的)。这两个我都推荐。
- 序列图 他们让你可视化用例,即一串引起软件组件交互的事件。Quick Sequence Diagram Editor是一个很基本而又可以帮助你画这些图的工具。
- “排版”工具(不是生产文档的所见即所得的软件)——docutils和sphinx都能根据ReStructured Text(一种维基风格的标记语言)生成Python风格的文档。所需的生成代码文档的工作量是很少的,尽管两者都能为Python缩进,将它们用于任何其他文档也不难。我前不久放弃了Tex和LaTex,但那是我个人的怪癖,这两个在科研圈子里大量用到。所以你能在那里找到很多支持。还有DocBook。或者你可以寻求所见即所得软件,但是要小心。
- “自文档化”代码工具:Doxygen是其中最常见的,把你代码里的注释转为文档。Javadoc是专门用于Java的文档工具。
8. 终端和通讯软件:当你需要经由串口通讯时,到了该用终端软件的时候了。在网页浏览器之前,这更加常见。哪个软件好?朋友不会让朋友使用绑定Windows的超级终端版本——它不是那么健壮——而且微软最终发布Vista时不再捎上它了。我最喜欢的是PuTTYtel和TeraTerm Pro。
其他通讯软件处理FTP和其安全变种SFTP以及SCP。照我看Cyberduck无疑是胜者——非常易用,最开始只在Mac上,现在OSX和Windows上都有。(此外,你如何能不喜欢上一个将橡皮鸭作为logo的软件呢)
9. 软件质量保证(QA)工具:如果你写软件,并认为自己的软件没有bug的,那是自己骗自己。有很多软件工具可以帮你在bug找你之前先找到它们。好了,此处我不得不承认我还只是个新手,我还不是特别熟悉这块有些什么。(太不好意思了!)但是我确实足够了解该建议看什么地方。一些主要的类别如下:
- 静态分析工具。这类软件解析你的软件,或者通过未处理的源码,或者通过编译后的对象文件。最著名的例子是C的lint。lint像是你高中的英语老师,他/她在你的试卷上到处画红叉,抱怨你用“who”代替了“whom”,或者句子里你用的介词结尾。要用英语有效地交流,你用得着严格遵循这些规则吗?不,但是这样做有助于你预防错误。C语言里也是如此——避免写某种差劲的模式的代码可以帮助你预防错误,而lint是帮你找到那些模式的。Java有FindBugs,而其他的编程语言也有类似的程序。在这类软件里同样会计算代码复杂度——好的软件设计通常使函数保持短小。如果你发现你写的函数超过20-30行,你或许可以把它们分成更小的单元,这样更容易设计和调试。
- 单元测试和代码覆盖率。通常认为测试大型软件包是及其困难的,而在单个代码模块上写尝试各种输入模式的单元测试来测试较小的软件模块比较容易。在嵌入式系统里单元测试可以很难。一种方法是在PC上交叉编译软件,并寄希望于你的软件里的任何bug可以在PC编译版本里被检测到。当你能够写自动测试脚本也是有希望的。这样当你对你的软件做了修改,你可以运行自动测试脚本,检查是否引入了新bug。对于代码覆盖率,我在医疗工业里的同事使用Cantata++。它不便宜,但是这些可是医疗设备。
- 代码“美化器”——如果你和同事都使用相同的代码,那你可以更容易的找到低级的语法bug。正常情况我们都有自己的风格,但是这里就有软件可以自动缩进,把制表符转为空格或等价的东西。我考虑过的有一个叫做Uncrustify,附有一个图形用户界面叫做UniversalIndentGUI。
10. 基本命令行应用工具
下面的很多程序都是UNIX的命令行应用工具,它们出生在还没有图形用户界面,事情都需要靠手动去完成的日子。除非现在图形用户界面有革命性的改进,否则通过命令行,你能做的总是更多些,因为你通过脚本可以完成更多种事情的组合。如果你运行的是OSX或者Linux,你已经有这些工具了。如果你运行的是Windows,你可以去 http://unxutils.sourceforge.net/ 或 http://sourceforge.net/projects/unxutils/下载能运行在你的操作系统上的二进制版本。
- less——这也许是我用的最多的。它能够显示文件逐页显示文件内容。你还可以查找文本内容,或者如果你在看一个正在不断更新的日志文件,你可以按下F,然后它会给你显示最新加入的行。
- grep——能用正则表达式搜索一组文件。
- touch——更新文件的最近修改时间为当前日期/时间,或者如果文件不存在,它会创建一个空文件。
- tee——通过tee传送管道命令(例如
someprog | tee logfile
)让你复制那个命令的输出到文件,并同时在终端打印输出。 - which——如果你在终端运行一个程序foo.exe,你想要知道该程序在什么位置,只需要输入
which foo.exe
- head和tail——这两个让你打印出文件的头N行或后N行
- uniq——过滤输出,移除连续的相同行
- du——打印一个目录的磁盘使用率(总占用空间)
- wc——统计文件的行数,单词数和字符数。(当我给编辑写信时我会用它,这样我可以保持我的字数在新闻能允许的最大字数内)
- cp,rm,mv,ls,cat——这些都有DOS下的等价命令(copy,delete,rename,dir,type),但是这些UNIX的等价命令有时候在脚本里用到,所以我把它们安装到我的path下。
- md5sum——在对通过计算文件的MD5哈希码来验证文件完整性时有用
- gzip和gunzip——这两个是压缩和解压缩单个文件的。.gz格式较.zip普及程度低一点,但是你偶尔能见到它。
- wget和curl——这两个程序可以让你下载网页。
英文原文:Jason Sachs