创建USB设备udev

大家在使用USB设备进行通信时是否都会遇到这样的问题:Permission denied,或者是多个usb设备在每次重启时字符设备号都会发生变化。这里我们使用udev规则来定义USB设备,保证设备的读写权限,同时每次加载USB设备时都有固定的名称。

UDEV规则

首先,Ubuntu系统中的udev规则文件都保存在/etc/udev/rules.d/目录下,我们可以查看系统中已有的udev文件。

$ cd /etc/udev/rules.d/
$ ls -l
-rw-r--r-- 1 root root 58549 Aug 25  2019 70-snap.core.rules

70-snap.core.rules是系统本身的一个udev文件,70代表启动顺序,数值越大随系统加载的时间越晚。我们创建udev文件时同样需要按照这个规则命名rules文件,例如80-serials.rules、665-usbcan.rules。
其次,udev rules文件是通过定义设备的关键信息完成匹配的,如下是部分常用的关键字段:键
udev 规则的匹配键:

KERNEL  		设备的内核名称,如sda
SUBSYSTEM 		设备的子系统名称,如tty、block
BUS 			总线名称,如usb
SYSFS{filename} 设备的 devpath 路径下,设备的属性文件“filename”里的内容。
         	例如:SYSFS{model}==“ST936701SS”表示:如果设备的型号为ST936701SS,
         	则该设备匹配该匹配键。在一条规则中,可以设定最多五条 SYSFS 的 匹配键。
ENV{key}  		环境变量。在一条规则中,可以设定最多五条环境变量的 匹配键       

udev 的重要赋值键 :

NAME			在 /dev下产生的设备文件名。
SYMLINK			为 /dev/下的设备文件产生符号链接。由于 udev 只能为某个设备产生一个设备文件,
				所以为了不覆盖系统默认的 udev 规则所产生的文件,推荐使用符号链接。
OWNER, GROUP, MODE	为设备设定权限

上述所有关键字段可以采用如下udev 规则的操作符进行匹配或赋值:

“==” 	 	比较键、值,若等于,则该条件满足;
“!=”   	比较键、值,若不等于,则该条件满足;
“=”    	对一个键赋值;
“+=”  		为一个表示多个条目的键赋值。
“:=”  		对一个键赋值,并拒绝之后所有对该键的改动。目的是防止后面的规则文件对该键赋值。

编写UDEV文件

了解了udev文件的语法规则之后,我们来看下如何编写udev规则文件。
首先,我们需要知道插入设备的相关信息,用于编写udev的匹配信息。udevadm指令专门用于获取设备的相关信息。例如:当我们插入一个usb串口设备时默认系统给这个串口的描述文件时/dev/ttyUSB0,接下来我们通过udevadm指令来获取相关信息。

$ udevadm info /dev/ttyUSB0			#/dev/ttyUSB0是我们想获取设备的名称

在运行指令之后我们会得到如下图所示的信息:

根据上述信息编写rules文件:

$ cd /etc/udev/rules.d
$ sudo gedit 80-serials.rules

在打开的文本中输入如下内容:

SUBSYSTEM == "tty" , ENV{ID_VENDOR_ID} == "0403", ENV{ID_MODEL_ID} == "6001", 
ENV{ID_SERIAL_SHORT}="FT9O69ON",MODE="0666",GROUP="dialout",SYMLINK+="ttyUSBImu"

我们将ID_VENDOR_ID、ID_MODEL_ID、ID_SERIAL_SHORT设定为判断条件,MODE设置为0666,GROUP设置为dialout,SYMLINK定义为我们想要的设备名称。
保存并退出文本编辑器,然后运行以下命令重新加载udev规则:

$ sudo service udev restart
$ ls -l /dev/ttyUSB*

显示如下信息,定义成功:

当我们再次插入该设备时就可以直接使用/dev/ttyUSBImu进行设备操作。