1.16 技巧16添加USB串行控制台
按理来说访问类似树莓派这样的嵌入式设备的最常用方式应该是通过内置的串行设备访问。这个简单的技巧可以让你从树莓派中得到一个USB串行控制台。
今天几乎所有可用的通用嵌入式计算机和微控制器都有内置的通用异步接收/发送器(UARTs)。UART对接收和发送串行数据提供了一个机制,同一时间只发送一个bit,串行通信的这种方法有时被称作晶体管-晶体管逻辑(TTL,transistor-transistor logic)序列。其数据速率因设备而异,但测量单位都是比特每秒。树莓派有一个内置的UART,连接到BCM引脚14(TXD)和15(RXD),数据速率为115200bps(或波特率)。
嗨,这不是真正的波特率!
OK,从语义的角度来看波特率是信号速率的单位,其并不总是和总bit速率(bps)相同。维基百科说波特率是“在一个数字调制信号或一个行编码上由传输介质造成的每秒显著的符号变化(信令事件)的数量”,然后它又花了好几页描述波特率的数学上的差异,这可能对你来说很迷人,也可能把你弄睡着。
关键之处是这样的:在计算机和电子行业泛滥成灾的术语波特率被使用已经有大约40年了,其结果是大量的软件和硬件不加区分的互换使用bps和波特率。对于树莓派上的USB串行控制台的具体情况来说,在数据速率方面使用bps和波特率是相同的,在这里单位对我们并不重要,我们需要尽可能保证你有一个功能正常的串行控制台,为此,你需要知道数据速率是115200。比特、波特率还是末日的大仓鼠,你愿意用哪个就用哪个,但是115200是树莓派UART串行设备的真正有魔法的数字。
如果你使用计算机已经有几年了,你也许还记得几乎每一台计算机都带有一个RS-232串口的时候。但在过去的几年中,这些端口已经消失了,大多数笔记本电脑中已经不再包括它们(或者它们只在可选的笔记本电脑底座中才存在)。不管你信不信,对于用于连接到树莓派的UART串口来说,这实际上是件好事。树莓派采用的Broadcom芯片使用0和3.3V的逻辑电平,而不是PC机的RS-232串口所使用的+/- 3到15V范围的电平。这意味着如果你的计算机有了一个RS-232串行端口,你将需要有一个转换板或适配器,以在它可以工作之前先转换信号电平。
RS-232或转换
这里有一个关于如何建立3.3V到RS-232电平转换器1的相当不错的教程。
好消息是有更好的方法连接树莓派的UART串口到你的计算机:USB!Adafruit出售一种绝佳的USB-to-ttl串行线2,它可以直接连接到树莓派的GPIO引脚上,并在另一端提供一个USB串行设备。这根线在一端(不具有USB接口的一端)有四个母头跳线连接器,这些跳线具有颜色编码:红色是5V电源,黑色是地线(GND),绿色用于树莓派接收数据(RXD),白色用于树莓派发送数据(TXD)。你可能也注意到了USB连接器这端比正常的要大,这是因为它里面有一个USB到串口的转换芯片。
要进行物理连接,只需要简单地将三个母头跳线连接器直接连接到树莓派的GPIO相应引脚即可。白色的发送线连接到TXD端口(BCM引脚14(P1-08)),而绿色的接收线连接到RXD端口(BCM引脚15(P1-10)),最后黑色的底线可以接到任何一个GND引脚,不过为了简单起见,我们建议你把它立刻连到TXD端口的左侧GND引脚(P1-06)。你可以通过比较图1-10来确认接线。
红线的技巧
你可能已经注意到我们没有要求你连接红线,这是因为USB串行设备将直接通过USB端口的5V 500mA启动自己。你可能也注意到我们曾经说过树莓派的UART使用3.3V逻辑电平,而不是5V。这千真万确,而接收和发送线已经转换成3.3V。现在一切正常,让我们放下这些并继续前进。
不过,你可以用这根红色电源线完成一个很酷的小技巧。因为红线能传输5V电压,因此你可以用它来驱动树莓派,而不是用正常的mini B型USB连接器。只需要将红线连接到5V引脚(P1-04),然后不需要连接任何其他电源,将USB-to-TTL串口线插上你的笔记本电脑,树莓派就可以启动了!
这其实只是个小把戏,因为从红线供电并不是启动树莓派的理想方式,这有好几个原因,我们已经在1.9.1小节“使用GPIO供电Pi之前请三思”中讨论过。
现在继续前进,将USB连接器连接到你的计算机上。
要连接UART串行设备,你首先需要知道它的设备名。当USB串行驱动加载成功(在你插入线缆的USB端时,应该已经完成了加载)后,内核会为设备分配一个设备名,因此你只需去翻看dmesg的输出即可。
具体来说,我们知道设备名可能是ttyUSB#,这里#是一个数字,可能是ttyUSB0,但是我们还是要确认看看。如果你有多个USB串行设备在你的系统上(你真是个淘气的超级黑客啊),你要找的是带有pl2303 converter这样的输出。如果你有一个以上的pl2303 converter类型的USB串行设备存在,请一次拔出一个反复尝试,直到你找到了合适的设备名。总而言之,下面就是关于你如何检查的:
不出所料,我们的设备是ttyUSB0。这意味着完整的设备节点名是/dev/ttyUSB0。未经授权的用户不能正常访问到/dev/ttyUSB#设备,你需要位于特别的组中。如果你拥有查看设备节点名的文件权限,你将看到它的拥有者是root,访问权被授予了dialout组中的用户:
你可以使用root账户(通过su或sudo命令)连接到/dev/ttyUSB0设备,也可以添加你的普通用户到dialout组中。要添加你的用户到dialout组,运行:
除非你重启终端会话,否则这将不会在你当前的终端会话中生效。你也可以登出并再次登录进系统,或者重启你的Linux系统。
不要使用Linux连接到串口?
你可以想象作者现在的表情一定是满脸都写着不同意。ಠ_ಠ不过,我们还是可以给出一些这方面的提示。
据供应商称,Windows 8不支持此设备。如果你是一个Windows 8用户,也许这是一个很好的时机可以考虑安装一个双系统并启动到Linux?
至于老生常谈的终端软件,如果你使用的是Windows XP或更老的版本,其会自带一个名为超级终端的程序,你可以使用它连接到串行控制台。
现在是时候连接树莓派的UART串行设备了。你需要使用一个支持串行连接的客户端,关于客户端有许多许多的工具,不过最常见的两个是minicom和screen。
1.16.1 Minicom
Minicom被设计成看上去很像Telix,一个流行的MS-DOS终端程序,它很可能是在你出生之前编写的,我们现在觉得自己都够老了(呃)。它具有MS-DOS的外观和感觉,换句话说,它的风格是旧式的、不清晰且让人困惑的,不过它确实可以工作。如果你要在Fedora中安装它:
或者在Debian/Ubuntu中:
安装好之后,使用minicom连接树莓派UART串行设备,运行:
为了测试效果,重新启动树莓派,当它连接上时,你应该可以看到Linux内核信息向下卷过屏幕,看上去类似于如图1-11所示。
你可以使用Control-A X退出minicom,或者使用Control-A Z进入帮助菜单获得某些有用的帮助。如果你要结束手工配置的mincom,只要保持奇偶校验、数据位为8N1,并禁用软件流控这些设置不变即可,你并不需要进入设置。
1.16.2 Screen
Screen是一个强大的工具,通常用于复用多个虚拟控制台。如果这是一本Linux介绍,我们就会用一整章来介绍如何使用screen。由于这是一本其他类型的书,我们只关注如何将之作为一个串行终端的客户端来使用。
要在Fedora中安装screen,运行:
或者在Debian/Ubuntu中:
安装好之后,使用screen连接树莓派UART串行设备,运行:
要退出屏幕会话,按Control-A K。
1.16.3 使用串行设备作为登录控制台
Raspbian预配置了UART串行设备作为一个登录功能的控制台,不过Pidora没有这么做。要想在Pidora中将UART串口设备作为一个登录控制台会话,可以运行:
这会立刻将会话打开。如果你已经连接了一个串行线缆,你应该会看到登录提示出现。如果想要让这个登录提示一直出现(且在启动时自动加载),只需要简单地运行:
通过创建到systemd目录树的符号链接,你告诉systemd启动ttyAMA0设备作为一个“getty”或登录控制台。
有趣的串行控制台花絮
“getty”这个名字来自“得到电传(get teletype)”。电传打字机最初是一台使用打字机做输入及打印机做输出并用来作为电报机的设备,但当计算机出现之后,这些设备找到了一个用途,即成为给计算机输入数据的一种方法。同时电传打字机也在20世纪40年代和50年代被广泛用在新闻编辑室中,仅用于“接收数据”,“咔嗒”声响起就表示有新闻“通过线路”传了过来,这就是电传打字机。最终,这些设备成为了完全的串行控制台,这就是我们在Linux中称控制台设备为“TTYs”的原因。
Pidora和Raspbian都把UART串行设备预配置成内核消息的控制台。你可以在 /boot/cmdline.txt文件中看到这些配置:
console值告诉Linux内核启动时往哪里输出消息,kgdboc值在控制台上启动了内核调试。
如果你现在正在进行的项目想要访问UART串行设备,你可能想要从/boot/cmdline.txt文件中移除console=ttyAMA0,115200和kgdboc=ttyAMA0,115200项,并重新启动树莓派。如果你不这样做,你可能会从Linux内核收到串行线路上的意想不到的输出行噪音,而你的程序/项目可能并不准备处理这些输出行。
如果你已经启用了串行设备作为登录控制台,你也可能会希望禁用它。要在Raspbian中禁用,在 /etc/inittab文件中注释掉下列行(通过在行的开头处添加一个#号)
在Pidora上,你只需要简单地删除掉ttyAMA0设备的systemd getty service符号链接,通过运行如下命令即可:
无论是哪个Linux发行版,在做了以上改变后,都需要重新启动让改动生效。
1.16.4 串行连接上的奇怪噪音(或信号丢失)
无论是Ubuntu还是Fedora都包括了一个名叫ModemManager的软件,它处理所有种类的调制解调器(modem)设备的设置,这些设备涵盖了从老式的拨号调制解调器到更现代的3G/4G设备。不幸的是,现在有相当多的调制解调器都采用了和我们的USB串行接口线路相同的通用转换芯片(pl2303),从而成为了调制解调器前面的陷阱。
其结果是,ModemManager会尝试访问它(并不断尝试,不断尝试……)。因为它没有办法知道在 /dev/ttyUSB0后面的设备是调制解调器还是盲文终端,或者在我们的例子中,它只是一个树莓派。这可能会造成你无法打开 /dev/ttyUSB0,也可能仅仅造成控制台上出现了噪音。
因为我们知道正在连上的USB设备究竟是什么,所以我们可以告诉ModemManager不用管它,并使用udev规则明确地将我们连上的设备列入黑名单。
以root用户编辑/lib/udev/rules.d/77-mm-usb-device-blacklist.rules文件,在文件底部LABEL="mm_usb_device_blacklist_end"这一行之前添加如下行:
如果你使用的USB串行线与Adafruit线不同,而你正想修复这个问题。你应该可以运行lsusb应用程序(从usbutils软件包)来确定idVendor(供应商id)和idProduct(产品id)字符串(它们在输出中按照XXXX:YYYY这样的语法,这里XXXX是idVendor,而YYYY是idProduct)。
例如,Adafruit USB串行线的lsusb值看起来像这样:
Udev自动检测规则文件的变化,因此更改立即生效,无需udev重新启动。这就是说,有时候你需要重新启动Linux系统来让udev重新读取其规则。无论哪种方式,只要udev读取了它的新规则,USB串口转换设备就进入了它的黑名单,ModemManager自此就会忽略这个设备。