Archive for July 8th, 2018

Compiling kernel module for FTDI USB-Serial on Jetson TX2

I’ve got a nice Jetson TX2 board from NVidia, which suits my goals pretty well, it has plenty of computing power with an onboard GPU for heavy graphics calculatons and CNN/ML processing.

Unfortunately, when I tried to connect my home-made sensor based on FTDI chip, that works perfectly with desktop Linux and other embedded boards, there was no kernel module for this chip, hence I had to compile one myself.

There are plenty of TK1/TX1/TX2 kernel compile guides on the net, but since the versions are different and the software contents change with time, here’s my take.

$ uname -a
Linux tegra-ubuntu 4.4.15-tegra #1 SMP PREEMPT Wed Feb 8 18:06:32 PST 2017 aarch64 aarch64 aarch64 GNU/Linux

First, check the Linux version, if it differs greatly from 4.4.15-tegra I have — take my advices with the grain of salt, maybe install the latest JetPack (mine was JetPack 2.3, I believe). Second, there are files on my system which may or may be not present on yours, beware. This is why I don’t write any “automated” scripts, that will give meaningless error message somewhere in the middle and do nothing.

Next check would be to see if the USB serial support is included in the current kernel or not:

$ zcat /proc/config.gz | grep USB_SERIAL
# CONFIG_USB_SERIAL is not set

In my case it’s not there, and if you grep for “FTDI” — there will be no results at all. A bit disconcertng, but solvable.

System related sources are usually in /usr/src, there might be folders, but in my case there was a single file for the kernel sources: kernel_src.tbz2 — let’s unpack it and copy the current config file there.

$ cd
$ mkdir tmp; cd tmp
$ tar -xjf /usr/src/kernel_src.tbz2
$ cd kernel/kernel-4.4
$ zcat /proc/config.gz >.config

Unpacking might take a minute or two. There will be two folders, “hardware” and “kernel”, go to the latter, then to “kernel-4.4″ and copy the default config there. The easiest way to edit config would be to issue “make menuconfig”, but this requires NCurses library, which is again not installed by default, so we have to do things manually a bit.

Instead of “make menuconfig” we could always use “make config” to resort to the command line, but answering hundreds if not thousands of questions is very tedious and time consuming, so let’s take a shortcut. Use your favourite text editor to open “.config” file and search for “USB_SERIAL” — if you are like me, you’ll find “# CONFIG_USB_SERIAL is not set” and the whole section for various USB serial devices is missing. Replace the line you’ve found with “CONFIG_USB_SERIAL=m”, and save file.

$ make prepare

This command will resurrect the missing section, please, be careful answering to the questions, basically you want to say “Y” to “USB Generic Serial Driver (USB_SERIAL_GENERIC) [N/y/?]“, then once again “m” (not “Y”) to “USB FTDI Single Port Serial Driver (USB_SERIAL_FTDI_SIO) [N/m/?] (NEW)”, the rest of the questions are just answered by pressing “Enter” key:

$ make modules_prepare

Nothing interesting here, just 10-15sec of file compilations.

make M=drivers/usb/serial/

This one actually compiles the kernel modules.

$ ls drivers/usb/serial/*.ko
drivers/usb/serial/ftdi_sio.ko drivers/usb/serial/usbserial.ko

Here are the files, former one is FTDI driver and the latter one is the basic USB Serial support driver the other drivers rely on. Let’s copy ‘em to the proper place (depending on your directory structure you might need or might not need to create the subfolders below:

$ mkdir /lib/modules/4.4.15-tegra/kernel/drivers/usb
$ mkdir /lib/modules/4.4.15-tegra/kernel/drivers/usb/serial
$ sudo cp drivers/usb/serial/*.ko /lib/modules/4.4.15-tegra/kernel/drivers/usb/serial/
$ sudo depmod -a

“depmod” reloads the kernel module list, so next time you insert your device, it will be recognized. Let’s start “tail -f /var/log/syslog” and see what happens there:

[ 4178.392871] usb 1-2: new full-speed USB device number 4 using xhci-tegra
[ 4178.532285] usb 1-2: New USB device found, idVendor=0403, idProduct=6001
[ 4178.539051] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 4178.546347] usb 1-2: Product: FT232R USB UART
[ 4178.550947] usb 1-2: Manufacturer: FTDI
[ 4178.554853] usb 1-2: SerialNumber: A4004H1c
[ 4178.560093] xhci-tegra 3530000.xhci: tegra_xhci_mbox_work mailbox command 6
[ 4178.569484] ftdi_sio 1-2:1.0: FTDI USB Serial Device converter detected
[ 4178.576205] usb 1-2: Detected FT232RL
[ 4178.580327] usb 1-2: FTDI USB Serial Device converter now attached to ttyUSB0

Sometimes, there might be an error message, like

[ 4232.645711] ftdi_sio: version magic '4.4.15 SMP preempt ' should be '4.4.15-tegra SMP preempt '

This means that we’ve missed the minor detail during configuration, take a note of “-tegra” suffix after the version number. We have to add it to our configuration file and recompile things again. Open .config file in the text editor, page down to “* General setup” section and change CONFIG_LOCALVERSION=”" to CONFIG_LOCALVERSION=”-tegra” or whatever suffix you find in the error message. Then the usual routine:

$ make clean
$ make prepare
$ make modules_prepare
$ make M=drivers/usb/serial

Copy the “*.ko” files as described above and don’t forget to “sudo depmod -a”.

Insert your FTDI-based device and enjoy!

No Comments