Update to the cp210x usb driver on balenaOS

We have a USB serial device that is not supported by the default cp210x driver. The source files need to be updated to add the VID and PID of the serial device, which can usually be done on a standard OS (Raspbian, etc.) by simply replacing the cp210x.ko module file.

I have compiled the driver in a Raspbian stretch container (build version) and that sometimes loads, but it would appear that the base balenaOS is also trying to load and there is a race condition / conflict with the containered OS trying to access the cp210x / usbserial module. No matter of how much rmmod / ins mod / modprob’ing that is done, it’s just not reliable or very repeatable.

Is there a way to have a custom module added to the base OS (which is read-only)? We have even tried to build the module with a different name to see if there is a conflict that way, but the balenaOS is still winning most of the time at grabbing the device. If the driver on the base OS could be updated, then this would not be an issue (as the container can access /dev/ttyUSB0 fine), it just does not recognise our dongle!

Any ideas on how we can progress on this, as otherwise it looks like we need to find a different solution.

Many thanks.

Hi @branchespark,

You could remove the kernel module from the hostOS.

A disadvantage will be that you need to do this once for every board. Also if you choose to do a hostOS update from the dashboard the module will appear again after the OS updates.

Do you know if this device is supported in a newer linux kernel?

Regards!

Thanks @spanceac. How do I remove the module from the hostOS, as it’s read only? Would it be possible to have this file replacement happen at build - does Balena yet support the configuration of the main hostOS?

Hi @branchespark,

You can remount the filesystem with write permissions:
mount -o remount,rw /

We don’t support this kind of hostOS modification. You could however pull the sources from our github and build your own customized image.

Regards!

@spanceac, thank you. Anywhere I can see an overview of the process of rolling our own hostOS and how to have this as an option to deploy on balenaCloud?

Hi @branchespark, is it not possible to just rmmod the problematic one and then insmod your custom built one.

We are still working on the flow for including community contributed OSes to balenaCloud, but I think even in the case where we have them, having a custom OS just for a single kernel module change might be a bit overkill, so I think another approach would be preferable. Not to mention that maintaining and testing your own OS to keep up with balenaCloud can be a pain.

@shaunmulligan - thanks for the idea.

What I have done is replaced the cp210x on the hostOS and then rammed / modprobe seems to reload it OK. Will keep testing to make sure, but it would be ace to be able to replace a file from the compose file / have the option when creating a new image.

OK, there is a simple fix for this requiring no build or hostOS changes!

The latest cp210x driver permits the dynamic adding of new VID/PID codes for devices. To do this you simple have to pop the VID and PID into a specific location within the container and the hostOS will then pick it up fine.

Let’s assume you have a VID of 0xDEAD and a PID of 0xBEEF, then the code below should help. You can find out these from looking in dmesg on the hostOS when you add / remove the USB device. Of course this only applies to cp210x-based devices!

Put the following code into your start.sh or whatever script you run within the container (not the Dockerfile):

# update the driver
if [ "$(cat /sys/bus/usb-serial/drivers/cp210x/new_id | grep -c DEAD)" -eq "0" ]; then
  echo "DEAD BEEF" > /sys/bus/usb-serial/drivers/cp210x/new_id
  modprobe cp210x
fi

The if statement is to stop the VID and PID simply being re-added all the time. Not necessary, but neater.

Hope this helps.

Thats awesome @branchespark thanks for posting your solution here!