我近期遇到了一个奇怪的需求:有大量长得差不多的标准x86_64计算机,配置基本相同,摆在一起,需要能够快速找到某个IP地址或者MAC地址对应的那台。这种需求在服务器维护领域相当常见:基本上rack mount的服务器都有一个东西叫做位置指示灯,一般是前面板后面板各有一个,一边按下了两边都会亮起,以方便去机柜另一面找那台服务器。但是现代x86_64主板上有什么类似的东西可供利用呢?
我们最开始的思路是利用现成的灯:
- 网卡状态指示灯
- 电源指示灯
- 硬盘状态指示灯
网卡状态指示灯需要网卡硬件和驱动支持,不巧我手上的所有设备都不支持;后二者在很多设计偷懒的主板上都是hard wire的,根本不暴露给系统。另外,主板上还有一些可编程的东西,比如Intel的GPIO控制器、LDC总线(TPM模块)、PCIe总线,但是这些东西要么完全没有文档,要么非常依赖厂商实现,要么制造成本很高。我们也尝试了用软件方法控制USB口的电源,可惜Linux在很多年前就drop了对这个功能的支持,并且硬件上支持把VCC关断的USB hub也屈指可数。
那么,如果想办法从(本来不是用来控制LED的)其它数据接口上引出LED信号,是否可行呢?这里还是有几个方案的:
- 3.5mm音频接口:输出一个大约1V的信号,电压电流都太小,不足以驱动LED
- 用USB设备模拟HID:最便宜的能完成USB HID的设备也要十几块钱,大规模制造成本太高
- PC Speaker:确实有10V方波,电流也够
- 串口:30V方波(-15V到+15V),电流也够
我们用示波器做了测试,PC Speaker的输出比较奇怪,总会莫名来个脉冲。因此我们最后决定用串口来实现这个LED。主板说明书上应该会有串口连接的定义,我手上的主板是这样的:
其中DTR是Tx,DSR是Rx。RS-232定义串口在数据位为0的时候电平为-15V到-3V之间,数据位为1的时候电平为3V到15V之间,因此不同主板的电压可能不太一样,我手上这块主板正好输出-15V和+15V。知道电压以后,只需要简单地把一颗2.0V 20mA的LED和一个10KΩ电阻串联起来,正极接在DTR上,负极接在Ground上,就大功告成了。成品如下图:
然后向串口输出一些东西,灯就开始闪烁了:
1 |
while true; do echo "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" > /dev/ttyS0; sleep 0.2; done |
(如果输出的东西不够长,那么灯可能不是非常亮,至于内容是什么则无所谓。这里假设串口在 /dev/ttyS0 上,如果你不知道你主板的串口具体是哪个设备,可以用 dmesg | grep tty 找一下提示。)
用热熔胶简单处理了一下绝缘问题,上板子测试,一切完美。
==========
感谢Ben Wang对本项目提供的帮助。