一颗电阻的旅行

最近一直在开发ARM系统的JTAG调试器,这是个不小的工程,有很多事要做。更准确的说,这个工作从去年4月份就开始了,当时是探索道路,做可行性验证,可谓是第一轮努力。

春节前开始的是最后一轮努力,在做产品化的工作,这涉及到要开发一个小的电路板,上面包含一个ARM M系列的微处理器,任务是实现ARM公司的SWD协议,访问目标系统。

我们把这个小的嵌入式系统取名为Nano Target Probe,简称NTP,中文名为“挥码枪”,指挥01010这样的二进制码流之意。

一颗电阻的旅行_第1张图片

因为大家都知道的原因,最近一两年一直有个芯片缺货的问题,几乎整个IT业都受到影响。前些天和INTEL的老同事聊天,就连以生产芯片为主业的INTEL都受到影响,因为INTEL也需要其它公司的芯片。

于是乎,本来十几元的STM32已经涨到从百元到几百元不等。

但涨价也没有办法,该上的项目还是要上。

长话短说,选定了一块开发板之后,我们开始为M核的“挥码枪”准备软件。ARM的处理器分为A、R、M三大系列,A系列最强大,是可以跑Linux或者Android这样的操作系统的,M系列最弱,不支持虚拟内存,主频一般不到100M Hz,内存和外存一般也比较小。我们为挥码枪选择的M核最大频率为72MHz。

简单来说,格蠹在做的就是用M核的挥码枪来调试A核的GDK8。

一颗电阻的旅行_第2张图片

软件编译和刷到“挥码枪”后,下一步是要调试了,委托硬件公司设计的板子还没有回来,为了赶时间,我们只好自己在开发板上搭一些电路。有些电路容易搭,只要用杜邦线连上就可以了,但是下面这个电路却难倒格蠹的软件小伙伴了。

3e555962b5d1ce2a3a6cdae573456f89.png

简单说,这个电路是把一个输入和一个输出合并为一个既可以做输入又可以做输出的信号,也就是SWD的三个信号中的SWDIO。

SWD是Serial Wire Debug的缩写,意思是通过串行通信来实现调试。经典的JTAG接口有TDI、TDO、TMS等9个信号,SWD把它缩小为3个,这是ARM公司的杰作。

我在英特尔工作了十几年,当时不太理解ARM。创业后慢慢认识了ARM。如果有人问我,英特尔平台和ARM平台最大的区别是什么?简单说,二者的哲学不同,定位不同。

就拿调试接口这件事来说,标准的JTAG接口是9个信号,而英特尔的ITP接口是25个信号,后来进一步扩展的XDP是60针的特制接头。

5d4146bd9ddf4ba489bf5d4e937da7f6.png

不要小看这个接头,这个接头一公一母,加上特制的扁平连接线,可是不便宜。

而ARM呢,觉得JTAG标准的9针信号已经太多,要做少,少到三根,一个必不可少的地、一个时钟,一个输入和输出。其实定义为4个就比工业标准节约了一半,而且I/O分开,但是ARM硬是把它定义为三个,一根线既做输入又做输出,或者说一会做输入,一会做输出,频繁的改方向。

上面的一个小小电路,里面蕴含的东西挺多的。有人问,既然右边的SoC是拿这一个信号既做输入又做输出,那么左边的M核为啥要用两个信号呢?

因为M核慢,SoC的主频一般都是1G以上,而M核只有几十M。对于上G主频的A核SoC来说,一个信号既做输入又做输出,频繁切换没有问题,它速度快。但对于M核来说,如果用一个信号既做输入,又作输出,频繁更换模式,那么就很慢。所以这个三叉形状的电路是精心设计的,也是ARM公司的杰作。

有人说,多几个信号,少几个信号重要么?

对于定位于高端的英特尔平台来说,确实不那么重要,而对于定位于低端的ARM平台来说这就是重要的,这便是两个公司和两大平台的差别。

为了节约成本,降低价格,ARM平台可谓用足了脑筋。每个地方都要找优化的机会,几十年下来,不断积累,不断优化。所以到了今天,英特尔平台的一个调试接口可以买很多块ARM的M核芯片了。

但是节约成本也是有代价的,有时会导致一些不方便,比如上面这个三叉电路是把两个信号混合为一个,用赵本山的话说是“两排毁(混)为一排”。但为了把左侧芯片的两个信号直接相连导致短路,所以加了个电阻,即电路图中的R1,阻值为100欧姆。

对于硬件工程师来说,这个电路太简单了,找个电阻搭一下也太容易了。但对于软件团队来说,这就不容易了,不能直接用杜邦线简单搞定了。

怎么办呢?

正在这时,我突然想起前几天整理旧物时,看到一个小电路板,是女儿上信息课时的小作品,几年前做的,电池的电已经用完,已经没什么用了。

但当时我没有把这个小电路板扔掉,而是把它放到了背包里,第二天上班时带到了办公室。

于是很快我就在办公室里找到了这个电路板。

更重要的是,看看上面的元器件,刚好有一个100欧姆的电阻,也就是R3。

一颗电阻的旅行_第3张图片

真是巧,正缺少一个100欧姆的电阻时,刚好找到了一个100欧姆的电阻。而且这个电阻是老式的,个头比较大,是用于手工焊接的,不像新式的给贴片机用的那么小。

接下来便是老程序员给年轻程序员展示硬件手艺的时候。找出电烙铁,加热,然后把焊点融化,把100欧姆的电阻从废旧电路板上取下来。

一颗电阻的旅行_第4张图片

下一步是找一段铜线,然后焊接出前面讨论的三叉戟电路。前后用了不到五分钟,三叉戟电路搞定了。

一颗电阻的旅行_第5张图片

实现了这个三叉电路后,本来停滞的测试任务可以继续了。而且进展的很快,在春节前就打通了通信,实现了中断和恢复运行。

春节前一边忙着这个“挥码枪”,一边忙着发布GDK8的武城版本,还是没有做彻底。一个较大问题是USB协议,挥码枪与上位机之间是USB接口,但是主机上识别USB设备不稳定,很多时候识别不出来。

不稳定是不可以接受的,于是春节后一上班,我们就调试挥码枪的USB识别逻辑,这个也是不好调,特别是没有USB分析仪。尝试找了几个软件的分析仪,但是很不给力。

努力了一周后,USB的问题解决了,一个主要原因是电源管理。前面说了ARM平台的一大特色,价格低,便宜。还有一个有关的特点就是功耗低,省电。

为了省电,很多电路都是可以动态开关的,包括USBD(USB的设备端)。春节前不稳定的原因是有时USBD被下电(Power off)或者挂起(Suspend)了,为了省电。有时碰巧能工作是因为没有休眠前就让它开始工作了。找到了根源之后,可以稳定识别了,百发百中。

但是又出了另一个问题,那就是主机端发给挥码枪的命令,没有回复,仿佛石沉入大海。

在昨天将近下班的时候,终于找到了原因,不是挥码枪的问题,而是主机端的问题,主机端的代码也是新的,在枚举主机上的很多个USB设备时,搞错了,把另一个烧录器设备当成挥码枪了,所以NDB发的所有命令都发给烧录器了,根本没有发给挥码枪。

昨晚找到问题就赶紧收工下班了。

今天是周六,我又到办公室加班,想把昨天找到的问题改掉。本以为很快就搞定的,但是改掉了之后又有新问题,主机端使用的libusb库无法打开挥码枪设备,报告No Entity Found。

于是又是一番追踪,libusb的代码也是写得风格独特,很多个超大的函数,一个函数动辄几百行。但是也没有办法,别人免费开源出来的,已经很好了。

打不开的原因是libusb没有找到合适的后端。挥码枪是个USB复合设备,一个硬件上有几个USB设备,但操作系统给它安装了WinUSB驱动,不是一般复合设备使用的usbccgp.sys,这个变化就把libusb搞晕头了。在匹配后端的操作函数时没有给装上合适的winusb函数。

看着动辄几百行的大函数,我不大想改它。于是先升级了一下,从1.0.21升级到1.0.25,但是问题依旧。

在夜幕降临的时候,我想出了个解决方案,还是修改了挥码枪上的固件,修改,烧录,再试,成功了。

一颗电阻的旅行_第6张图片

望一眼窗外,魔都已经灯火阑珊。

顺便预报一下,下周六有公益课程——《在调试器下体会编程》,节前开始的,春节休息了几周。

另外,格蠹继续代理三月份的C++技术大会(官网http://cpp-summit.org/),欢迎老朋友们从格蠹买票,格蠹会有额外的礼物给各位(^_^)。

(写文章很辛苦,恳请各位读者点击“在看”,也欢迎转发)

*************************************************

正心诚意,格物致知,以人文情怀审视软件,以软件技术改变人生

扫描下方二维码或者在微信中搜索“盛格塾”小程序,可以阅读更多文章和有声读物

一颗电阻的旅行_第7张图片

也欢迎关注格友公众号

一颗电阻的旅行_第8张图片

你可能感兴趣的:(芯片,java,嵌入式,人工智能,python)