Linux中智能小开关rfkill
Rfkill,其中rf是Radio frequency(射频),主要作用是一个专门管理开关的子系统,举例说明Android手机的通知栏可以方便地开关Airplane/BT/WiFi/Data/GPS,使用起来着实很方便。但是这是Android系统上层统一实现的,对应Linux内核以前是没有统一的实现,随着这种情况的增多也有专门的子系统来集中实现这个功能。这正是rfkill的工作。
上述的几个控制例子中,或许它们每个功能被发明时都是一场革命,原理甚或配置都可能相当复杂,但是对最终的用户来说,使用最多的也就是「开关」。
使用范例,监听无线网卡硬件变化:
$ rfkill
Usage: rfkill [options] command
Options:
--version show version (0.4-1ubuntu3 (Ubuntu))
Commands:
help
event
list [IDENTIFIER]
block IDENTIFIER
unblock IDENTIFIER
where IDENTIFIER is the index no. of an rfkill switch or one of:
<idx> all wifi wlan bluetooth uwb ultrawideband wimax wwan gps fm
$ rfkill event
1412007426.882932: idx 0 type 1 op 0 soft 0 hard 0
1412007465.911313: idx 0 type 1 op 2 soft 0 hard 1
1412007605.911553: idx 0 type 1 op 2 soft 0 hard 0
1412007705.911463: idx 0 type 1 op 2 soft 0 hard 1
1412007715.911449: idx 0 type 1 op 2 soft 0 hard 0
$
驱动中实现了复杂的特性驱动后,最好完善一个rfkill驱动就再好不过了。Rfkill从原理不过是一个新的sys文件系统中的class。位于/sys/class/rfkill/。因为它小,所以所说的东西也不是特别多,但是因为它引起了一段经历让人揪心,重点写下来。
写在后面:
研究这个的源由是在移植一个BT驱动的时候,出现了一个怪异的现象。由于仅仅是系统版本的升级(从Android4.2升级到Android4.4)所以可以确定硬件是完好的。相应的驱动先配置后好,烧写系统后BT测试正常。出于「不糊弄」的心态,我决定反测试一下,在内核中将BT相关选项去掉后,测试结果BT确实是不能使用了;再将驱动配置添加上却意外发现仍然不能正常开启。然后立刻回退版本,测试之前能正常的内核,结果还是成功打开设备。我就开始乱想了,BT IC被我使用软件配置坏了?出现这种诡异的事件时,答案一般都在厕所或者去厕所的路上,我得去那里找找,顺便洗把脸,找到的概率会更高。
厕所还是给了我一些指点,先确认BT的硬件IC到底有没有问题,将系统完整地烧回Android4.2系统,测试结果是正常的。我放心一些了,然后使用第二台进行诡异事件的重新测试,把之前的系统镜像依次烧入,现象和第一台机器是一样的。到此刻就该是逗机灵的时刻了:一旦运行了不带BT驱动的的镜像,那么再烧写带BT驱动的也不能正常打开驱动了——BT芯片没有复位!!!这个是我的猜测,立刻完全断电再上电,原来包含BT驱动的不能正常打开BT的系统镜像可以正常打开了。
以之前的验证结果为起点进行思考,我重新烧写系统镜像都是直接按「重启键」(硬件上叫复位键)进行系统的重启,现在发现它会引起一个问题。BT为什么没有在按下复位键的时候进行复位呢?这个同样只是假设,万用表伺候!先不管电路怎么连接,直接测试BT的复位管脚,在按下复位键时,电压并没有由高电平变为低电平。这一点得到证实后,查看原理图得知原来BT的复位管脚并不是和总复位键相连,而是连接到了CPU的一个GPIO上,再然后根据这个GPIO的名字查出在Android4.2的内核驱动中是要注册成rfkill中BT的reset管脚的。照做后一切问题得以解决。
我以前的印象中一个电路板上的所有的IC的reset管脚都是统一连接到用户的复位开关上呢!这次认识了一直以来都仅是眼熟的rfkill。原来BT的IC一直都没有断电和RESET导致没有办法正常的开启。