Compiling CH348 Driver on Raspberry Pi: Common Issues and Solutions

Compiling CH348 Driver on Raspberry Pi: Common Issues and Solutions
CH348

Main Functions and Features of CH348 Chip

  1. High-speed transmission: Built-in microcontroller with high-speed 480Mbps USB transceiver and controller.
  2. Single-port high integration: Each serial port has independent FIFO for transmission and reception, supporting baud rates up to 6Mbps.
  3. Dual power supply design: Serial IO voltage supports 3.3V/2.5V/1.8V (default 3.3V).
  4. Multifunctional: Integrates UART, Modem signals, GPIO, and RS485 transmission enable functions.
  5. USB configuration features: Supports USB device descriptors, vendor ID, product ID, serial numbers, and other configurations.
  6. Driver support: Supports operating systems such as Windows, Linux, Android, and macOS.
  7. Packaging: Available in LQFP100 and LQFP48 packages.
  8. Time To Market (TTM): Fast time to market.
  9. Technical support: Provides product manuals, drivers and application software, reference designs, chips, and evaluation boards as technical support resources.
  10. Compatible operating systems: Supports Windows, Linux, Android, and macOS operating systems.

Encountered some issues while compiling the driver on Raspberry Pi, documenting them here.

The Linux driver library is open source at https://github.com/WCHSoftGroup/ch9344ser_linux.

Compiling the Driver

Follow the method in the README to compile:

# ch9344 linux serial driver

## Description

This driver supports USB to quad serial ports chip ch9344 and USB to octal serial ports chip ch348.

1. Open "Terminal"
2. Switch to "driver" directory
3. Compile the driver using "make", you will see the module "ch9344.ko" if successful
4. Type "sudo make load" or "sudo insmod ch9344.ko" to load the driver dynamically
5. Type "sudo make unload" or "sudo rmmod ch9344.ko" to unload the driver
6. Type "sudo make install" to make the driver work permanently
7. Type "sudo make uninstall" to remove the driver
8. You can refer to the link below to acquire uart application, you can use gcc or Cross-compile with cross-gcc
   https://github.com/WCHSoftGroup/tty_uart

Before the driver works, you should make sure that the usb device has been plugged in and is working properly, you can use shell command "lsusb" or "dmesg" to confirm that, USB VID of these devices are [1A86], you can view all IDs from the id table which defined in "ch9344.c".

If the device works well, the driver will create tty devices named "ttyCH9344USBx" in /dev directory.

## Note

Any questions, you can send feedback to mail: [email protected]

Most likely, you will encounter the issue of not being able to find the specified path.

Open the Makefile in the driver directory:

CONFIG_MODULE_SIG=n

ifeq ($(KERNELRELEASE), )
KERNELDIR := /lib/modules/$(shell uname -r)/build
PWD :=$(shell pwd)
default:
 $(MAKE) -C $(KERNELDIR)  M=$(PWD)
clean:
 rm -rf *.mk .tmp_versions Module.symvers *.mod.c *.o *.ko .*.cmd Module.markers modules.order *.a *.mod
load:
 insmod ch9344.ko
unload:
 rmmod ch9344
install: default
 insmod ch9344.ko || true
 mkdir -p /lib/modules/$(shell uname -r)/kernel/drivers/usb/serial/ || true
 cp -f ./ch9344.ko /lib/modules/$(shell uname -r)/kernel/drivers/usb/serial/ || true
 depmod -a
uninstall:
 rmmod ch9344 || true
 rm -rf /lib/modules/$(shell uname -r)/kernel/drivers/usb/serial/ch9344.ko || true
 depmod -a
else
 obj-m := ch9344.o
endif

The issue should be with KERNELDIR here, as the installation paths for source headers vary across different Linux distributions, and many distributions do not install the source by default, so it needs to be installed manually.

On Raspberry Pi, you can use the following command to install:

sudo apt-get install raspberrypi-kernel-headers

When compiling kernel modules on Raspberry Pi, you need to know your Raspberry Pi’s kernel version and have the corresponding version of the kernel source code. You can obtain the kernel version using the following command:

uname -r

The source code for Raspberry Pi is installed in the /usr/src directory, so you need to modify KERNELDIR in the Makefile to /usr/src/linux-headers-$(shell uname -r).

CONFIG_MODULE_SIG=n

ifeq ($(KERNELRELEASE), )
# Modify the path according to your actual situation
KERNELDIR ?= /usr/src/linux-headers-$(shell uname -r)
PWD := $(shell pwd)
default:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) clean

...

This Makefile first attempts to use the environment variable KERNELDIR, and if not set, it uses /usr/src/linux-headers-$(shell uname -r). $(shell uname -r) will be replaced with your kernel version.

The default target will compile your kernel module, and the clean target will clean up the generated files.

Note that you may need to use sudo to run the make command, as compiling kernel modules typically requires administrative privileges.

Not all Linux distributions will set the KERNELDIR environment variable by default. In fact, KERNELDIR is usually not set by default; it is typically set explicitly by the user or script when compiling the kernel or kernel module.

In a Linux system, you can use the echo command to view the value of environment variables. If you want to check the value of the KERNELDIR environment variable, you can enter the following command in the terminal:

echo $KERNELDIR

This will print the value of the KERNELDIR environment variable. If this environment variable is not set, then this command will not output anything.

In the Makefile, KERNELDIR is used as a variable representing the location of the kernel source code. If this variable is not set in the environment, a default value needs to be provided in the Makefile, or this value can be provided via command line arguments when calling the make command.

For example, you can provide a default value in the Makefile:

KERNELDIR ?= /usr/src/linux-headers-$(shell uname -r)

Or you can provide this value when calling the make command via command line arguments:

make KERNELDIR=/usr/src/linux-headers-$(uname -r)

Then, following the remaining steps in the README should allow the driver to load properly.

Leave a Comment

×