AM335x | How To Fix 4G Module Serial Port Via udev

This article takes Forlinx embedded AM335x platform as an example to explain. When using the 4G module, it is necessary to detect the network in an environment where the 4G signal is not ideal. When the device is disconnected from the network, restart the 4G module and dial up the network again. However, after the system runs for a long time, restarting the module will cause the serial number of the device node ttyusb generated by the 4G module in the /dev directory to change, resulting in an error when the application dials up. We can fix this problem by modifying the udev rules file.


There are many variables defined in udev's rule file, such as KERNELS, SUBSYSTEMS, DRIVERS, etc. We can use several of these variables to determine our device, and modify our NAME and SYMLINK variables, so that we can change our The name and link of the device in the /dev directory.

Use the udevadm info command to query device information in the udev database. Device properties can also be queried from the sysfs file system to assist in creating udev rules.


udevadm info -q path -n /dev/ttyUSB0 You can view the system device path of the ttyUSB0 device


root@ok335x:~# udevadm info -q path -n /dev/ttyUSB0
/devices/platform/omap/musb-ti81xx/musb-hdrc.1/usb1/1-1/1-1.2/1-1.2:2.2/ttyUSB0/tty/ttyUSB0

udevadm info -a -p $(udevadm info -q path -n /dev/ttyUSB0) Query /dev/ttyUSB0 device, you can print out the parent-child relationship of all positions on the device bus, as follows:

root@am335x:~# udevadm info -a -p $(udevadm info -q path -n /dev/ttyUSB4)


Udevadm info starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device.


looking at device '/devices/platform/omap/musb-ti81xx/musb-hdrc.1/usb1/1-1/1-1.2/1-1.2:2.2/ttyUSB0':

KERNEL=="ttyUSB0"

SUBSYSTEM=="usb-serial"

DRIVER=="option1"

ATTR{port_number}=="0"


looking at parent device '/devices/platform/omap/musb-ti81xx/musb-hdrc.1/usb1/1-1/1-1.2/1-1.2:2.2':

KERNELS=="1-1.2:2.2"

SUBSYSTEMS=="usb"

DRIVERS=="option"

ATTRS{bInterfaceNumber}"02"

ATTRS{bAlternateSetting}"0"

ATTRS{bNumEndpoints}"03"

ATTRS{bInterfaceClass}"ff"

ATTRS{bInterfaceSubClass}"06"

ATTRS{bInterfaceProtocol}"10"

ATTRS{modalias}"usb:v12D1p15C1d0102dc00dsc00dpFFicFFisc06ip10"

ATTRS{supports_autosuspend}"1"

ATTRS{interface}=="Huawei Mobile Connect - Modem"


looking at parent device '/devices/platform/omap/musb-ti81xx/musb-hdrc.1/usb1/1-1/1-1.2':

KERNELS=="1-1.2"

SUBSYSTEMS=="usb"

DRIVERS=="usb"

ATTRS{configuration}""

ATTRS{bNumInterfaces}" 7"

ATTRS{bConfigurationValue}"2"

ATTRS{bmAttributes}"a0"

ATTRS{bMaxPower}" 2mA"

ATTRS{urbnum}"26"

ATTRS{idVendor}"12d1"

ATTRS{idProduct}"15c1"

ATTRS{bcdDevice}"0102"

ATTRS{bDeviceClass}"00"

ATTRS{bDeviceSubClass}"00"

ATTRS{bDeviceProtocol}"ff"

ATTRS{bNumConfigurations}"3"

ATTRS{bMaxPacketSize0}"64"

ATTRS{speed}"480"

ATTRS{busnum}"1"

ATTRS{devnum}"6"

ATTRS{devpath}"1.2"

ATTRS{version}" 2.00"

ATTRS{maxchild}"0"

ATTRS{quirks}"0x0"

ATTRS{avoid_reset_quirk}"0"

ATTRS{authorized}"1"

ATTRS{manufacturer}"Huawei Technologies Co., Ltd."

ATTRS{product}"HUAWEI Mobile V7R11"

ATTRS{serial}"0123456789ABCDEF"


looking at parent device '/devices/platform/omap/musb-ti81xx/musb-hdrc.1/usb1/1-1':

KERNELS=="1-1"

SUBSYSTEMS=="usb"

DRIVERS=="usb"

ATTRS{configuration}""

ATTRS{bNumInterfaces}" 1"

ATTRS{bConfigurationValue}"1"

ATTRS{bmAttributes}"e0"

ATTRS{bMaxPower}" 2mA"

ATTRS{urbnum}"100"

ATTRS{idVendor}"0424"

ATTRS{idProduct}"2514"

ATTRS{bcdDevice}"0bb3"

ATTRS{bDeviceClass}"09"

ATTRS{bDeviceSubClass}"00"

ATTRS{bDeviceProtocol}"02"

ATTRS{bNumConfigurations}"1"

ATTRS{bMaxPacketSize0}"64"

ATTRS{speed}"480"

ATTRS{busnum}"1"

ATTRS{devnum}"2"

ATTRS{devpath}"1"

ATTRS{version}" 2.00"

ATTRS{maxchild}"4"

ATTRS{quirks}"0x0"

ATTRS{avoid_reset_quirk}"0"

ATTRS{authorized}=="1"


looking at parent device '/devices/platform/omap/musb-ti81xx/musb-hdrc.1/usb1':

KERNELS=="usb1"

SUBSYSTEMS=="usb"

DRIVERS=="usb"

ATTRS{configuration}""

ATTRS{bNumInterfaces}" 1"

ATTRS{bConfigurationValue}"1"

ATTRS{bmAttributes}"e0"

ATTRS{bMaxPower}" 0mA"

ATTRS{urbnum}"26"

ATTRS{idVendor}"1d6b"

ATTRS{idProduct}"0002"

ATTRS{bcdDevice}"0302"

ATTRS{bDeviceClass}"09"

ATTRS{bDeviceSubClass}"00"

ATTRS{bDeviceProtocol}"01"

ATTRS{bNumConfigurations}"1"

ATTRS{bMaxPacketSize0}"64"

ATTRS{speed}"480"

ATTRS{busnum}"1"

ATTRS{devnum}"1"

ATTRS{devpath}"0"

ATTRS{version}" 2.00"

ATTRS{maxchild}"1"

ATTRS{quirks}"0x0"

ATTRS{avoid_reset_quirk}"0"

ATTRS{authorized}"1"

ATTRS{manufacturer}"Linux 3.2.0-dirty musb-hcd"

ATTRS{product}"MUSB HDRC host driver"

ATTRS{serial}"musb-hdrc.1"

ATTRS{authorized_default}=="1"


looking at parent device '/devices/platform/omap/musb-ti81xx/musb-hdrc.1':

KERNELS=="musb-hdrc.1"

SUBSYSTEMS=="platform"

DRIVERS=="musb-hdrc"

ATTRS{modalias}"platform:musb-hdrc"

ATTRS{mode}"a_host"

ATTRS{vbus}=="Vbus off, timeout 1100"


looking at parent device '/devices/platform/omap/musb-ti81xx':

KERNELS=="musb-ti81xx"

SUBSYSTEMS=="platform"

DRIVERS=="musb-ti81xx"

ATTRS{modalias}=="platform:musb-ti81xx"


looking at parent device '/devices/platform/omap':

KERNELS=="omap"

SUBSYSTEMS==""

DRIVERS==""


looking at parent device '/devices/platform':

KERNELS=="platform"

SUBSYSTEMS==""

DRIVERS==""


We check the information of each USB serial device node, and the corresponding device information is as follows:


root@am335x:~# udevadm info -a -p $(udevadm info -q path -n /dev/ttyUSB1)



root@am335x:~# udevadm info -a -p $(udevadm info -q path -n /dev/ttyUSB2)



root@am335x:~# udevadm info -a -p $(udevadm info -q path -n /dev/ttyUSB3)



root@am335x:~# udevadm info -a -p $(udevadm info -q path -n /dev/ttyUSB4)



By observing the information of each device node, we can distinguish each device node by returning ATTRS{interface}

So we use SUBSYSTEMS=="usb" ATTRS{interface}=="Huawei Mobile Connect - Modem" as the filter condition.


Add the following to /etc/udev/rules.d/local.rules. Make ttyUSB0-4 the corresponding soft link as ttyusb0-4

ATTRS{interface}"Huawei Mobile Connect - Serial B",SUBSYSTEMS"usb",SYMLINK+="ttyusb4"

ATTRS{interface}"Huawei Mobile Connect - Ctrl",SUBSYSTEMS"usb",SYMLINK+="ttyusb3"

ATTRS{interface}"Huawei Mobile Connect - Pcui",SUBSYSTEMS"usb",SYMLINK+="ttyusb2"

ATTRS{interface}"Huawei Mobile Connect - Application",SUBSYSTEMS"usb",SYMLINK+="ttyusb1"

ATTRS{interface}"Huawei Mobile Connect - Modem",SUBSYSTEMS"usb",SYMLINK+="ttyusb0"


We restart the system and enter to view the device node



By viewing, the soft link of the device node is completed



If we dial up the Internet through /dev/ttyusb2 in a specific application. In the actual long-term operation process, when our 4g network daemon detects that 4g is off the network, it will restart the 4g module, which may cause the ttyUSB serial number to change, as follows


By comparing the device information of /dev/ttyUSB10 with the previous device information, it is found that the device node of the interface with the attribute ATTRS{interface}=="Huawei Mobile Connect - Pcui" in the /dev directory is restarted repeatedly. ttyUSB2 becomes ttyUSB10, as shown below:




If our application continues to use ttyUSB2, there will definitely be problems, but we use the soft link ttyusb2 made by the USB serial port, and there will be no problems.