Skip to content

Use of hard-coded /dev/ttyUSB0 in fan drivers can cause conflict #118

Description

@iainaff

Problem

The code for the fan drivers, etc, uses a hard-coded device - /dev/ttyUSB0

This is very bad practice, and will cause failures if other USB serial devices are present at boot & device enumeration.

Because the fan serial device is on the USB-C bus - bus 3, device 3 - it will fall to be enumerated AFTER any other USB serial devices present, so will not be numbered as /dev/ttyUSB0, as the devices(s) on the lower buses will get that, so the drivers using the hard-coded /dev/ttyUSB0 device name will open the wrong device , thus breaking both the fan control and the other serial device.

Fix

The simplest fix for this is to use udev rules to cause creation of a symlink to the dynamically assigned /dev/ttyUSB?, and then use that instead of the hard-coded /dev/ttyUSB0.

To get udev to do this, a file /etc/udev/rules.d/20-serial.rules is created, containing:

SUBSYSTEM=="tty",ATTRS{idVendor}=="1a86",ATTRS{idProduct}=="7523",SYMLINK+="ttyFAN0"

(Note than this is a the simplest possible rule; if any other devices of the same vendor:product ID are also present, it will have to be more specific, eg identifying the bus & device, etc, to uniquely identify it, and prevent the same conflict problem happening).

This rule creates a device symlink /dev/ttyFAN0 (pointing to the dynamically assigned /dev/ttyUSB?) which the fan drivers can then safely open and use.

Other necessary changes to the C and Python code from the drivers directory are below, as a git diff:

Patch

diff --git a/drivers/c/fanStop b/drivers/c/fanStop
index f0b09f9..ff18723 100644
--- a/drivers/c/fanStop.c
+++ b/drivers/c/fanStop.c
@@ -10,9 +10,11 @@
 
 int main(void){
 	while(1){
- 		int serial_port = open("/dev/ttyUSB0", O_RDWR);
+// 		int serial_port = open("/dev/ttyUSB0", O_RDWR);
+ 		int serial_port = open("/dev/ttyFAN0", O_RDWR);
 		if (serial_port < 0){
-			printf("Can not access /dev/ttyUSB0, please check it out.\n");
+//			printf("Can not access /dev/ttyUSB0, please check it out.\n");
+			printf("Can not access /dev/ttyFAN0, please check it out.\n");
  			}
 
 	struct termios tty;
diff --git a/drivers/c/pwmControlFan.c b/drivers/c/pwmControlFan.c
index 1f7d08e..56f34aa 100644
--- a/drivers/c/pwmControlFan.c
+++ b/drivers/c/pwmControlFan.c
@@ -15,7 +15,8 @@ int init_serial( char *serial_name)
 	serial_port = open(serial_name, O_RDWR);
 
 	if (serial_port < 0){
-		printf("Can not open /dev/ttyUSB0 serial port ErrorCode: %s\n", strerror(errno));
+//		printf("Can not open /dev/ttyUSB0 serial port ErrorCode: %s\n", strerror(errno));
+		printf("Can not open /dev/ttyFAN0 serial port ErrorCode: %s\n", strerror(errno));
 		printf("Please check the /boot/config.txt file and add dtoverlay=dwc2, dr_mode=host and reboot RPi \n");
 	}
 
@@ -103,7 +104,8 @@ int main(void){
 	char data[8]={0};
 	unsigned int conf_info[8];
 	unsigned int cpu_temp=0;
-	init_serial("/dev/ttyUSB0");
+//	init_serial("/dev/ttyUSB0");
+	init_serial("/dev/ttyFAN0");
     /* default configuration if /etc/deskpi.conf dose not exist */
 	conf_info[0]=40;
 	conf_info[1]=25;

diff --git a/drivers/c/safecutoffpower.c b/drivers/c/safecutoffpower.c
index f0b09f9..0d0695b 100644
--- a/drivers/c/safecutoffpower.c
+++ b/drivers/c/safecutoffpower.c
@@ -10,9 +10,11 @@
 
 int main(void){
 	while(1){
- 		int serial_port = open("/dev/ttyUSB0", O_RDWR);
+// 		int serial_port = open("/dev/ttyUSB0", O_RDWR);
+ 		int serial_port = open("/dev/ttyFAN0", O_RDWR);
 		if (serial_port < 0){
-			printf("Can not access /dev/ttyUSB0, please check it out.\n");
+//			printf("Can not access /dev/ttyUSB0, please check it out.\n");
+			printf("Can not access /dev/ttyFAN0, please check it out.\n");	
  			}
 
 	struct termios tty;
diff --git a/drivers/python/pwmControlFan.py b/drivers/python/pwmControlFan.py
index 193c1c4..f9c551e 100644
--- a/drivers/python/pwmControlFan.py
+++ b/drivers/python/pwmControlFan.py
@@ -5,7 +5,7 @@ import time
 import subprocess 
 
 
-ser = serial.Serial("/dev/ttyUSB0", 9600, timeout=30)
+ser = serial.Serial("/dev/ttyFAN0", 9600, timeout=30)
 
 try: 
     while True:
diff --git a/drivers/python/safecutoffpower.py b/drivers/python/safecutoffpower.py
index c9a927f..134c2b2 100644
--- a/drivers/python/safecutoffpower.py
+++ b/drivers/python/safecutoffpower.py
@@ -5,7 +5,8 @@ import serial
 import time 
 
 
-ser = serial.Serial("/dev/ttyUSB0", 9600, timeout=30)
+#ser = serial.Serial("/dev/ttyUSB0", 9600, timeout=30)
+ser = serial.Serial("/dev/ttyFAN0", 9600, timeout=30)
 
 try: 
     while True:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions