SPI TX Time Variability

I successfully applied the recommended patch to the SPI driver (spi-tegra114.c), along with the CS pin patch, and built a custom kernel on JetPack 5.1 (L4T 35.2.1). The kernel was compiled directly on the Jetson, without cross-compilation

Here are the steps taken:

  1. Download sources from https://developer.nvidia.com/embedded/jetson-linux-r3521:

    • copy link from Driver Package (BSP) Sources
  2. On the Jetson:

    mkdir custom-kernel
    cd custom-kernel
    
    wget https://developer.nvidia.com/downloads/public-sourcestbz2 # copied on prev step
    tar -xvf public-sourcestbz2
    
    cd Linux_for_Tegra/source/public/kernel
    tar -xvf kernel_src.tbz2
    
    cd kernel-5.10
    

    These steps will make files available such as the SPI driver we want to patch (Linux_for_Tegra/source/public/kernel/kernel-5.10/drivers/spi/spi-tegra114.c).

  3. After applying the suggest patch for JP 5.1 in Orin NX SPI delay between transfers - #21 by KevinFFF and the CS pin patch from Jetson orin nano SPI Speed not changing - #9 by KevinFFF we get the resulting file:

spi-tegra114-patch-JP5.1-l4t35.2.1.c.txt (57.5 KB)
(note that I had to change the file extension to .txt to upload, but that is a .c file)

  1. Copy the contents of that file into Linux_for_Tegra/source/public/kernel/kernel-5.10/drivers/spi/spi-tegra114.c and save it.

  2. Get possible default kernel configurations:

    $ ls custom-kernel/Linux_for_Tegra/source/public/kernel/kernel-5.10/arch/arm/configs/
    defconfig                tegra_defconfig
    defconfig_debug.config   tegra_defconfig_debug.config
    tegra_android_defconfig
    
  3. Kernel build and installation:

	cd custom-kernel/Linux_for_Tegra/source/public/kernel

	# Load the correct kernel configuration
	sudo make O=../build/ tegra_defconfig

	# Prepare the kernel build environment
	sudo make O=../build/ modules_prepare

	# Compile the full kernel (including changes to SPI driver)
	sudo make O=../build/ -j$(nproc)

	# Compile and install kernel modules (including spi-tegra114.ko)
	sudo make O=../build/ modules_install

	# Update module dependencies
	sudo depmod -a

	# Copy the new kernel Image to the boot directory
	sudo cp ../build/arch/arm64/boot/Image /boot/Image-Custom-Kernel
  1. Update the boot configuration
  • Check the current contents of /boot/extlinux/extlinux.conf. In my case, there was a config labelled as JetsonIO that was being used and running successfully. So I copied that and only changed the boot label and path to the new kernel image:

TIMEOUT 30
#DEFAULT JetsonIO
DEFAULT CustomKernelTest

LABEL CustomKernelTest
     MENU LABEL Custom Kernel Test
     LINUX /boot/Image-Custom-Kernel
     FDT /boot/kernel_tegra234-p3701-0000-p3737-0000-user-custom.dtb
     INITRD /boot/initrd
     APPEND ${cbootargs} root=PARTUUID=4c1c9478-c986-4839-8cc2-f773fbfac931 rw rootwait rootfstype=ext4 mminit_loglevel=4 console=ttyTCU0,115200 console=ttyAMA0,115200 console=tty0 firmware_class.path=/etc/firmware fbcon=map:0 net.ifnames=0

LABEL JetsonIO
	MENU LABEL Custom Header Config: <HDR40 User Custom [2024-10-08-125801]>
	LINUX /boot/Image
	FDT /boot/kernel_tegra234-p3701-0000-p3737-0000-user-custom.dtb
	INITRD /boot/initrd
	APPEND ${cbootargs} root=PARTUUID=4c1c9478-c986-4839-8cc2-f773fbfac931 rw rootwait rootfstype=ext4 mminit_loglevel=4 console=ttyTCU0,115200 console=ttyAMA0,115200 console=tty0 firmware_class.path=/etc/firmware fbcon=map:0 net.ifnames=0

Be aware that if the kernel image used by CustomKernelTest is faulty, the Jetson may fail to boot. In such a case, you’ll need to connect a monitor and keyboard to manually roll back to the JetsonIO option (in this example) during boot.
It appears that /boot/extlinux/extlinux.conf supports configuring a fallback kernel, based on the default comments in the file. However, I have not explored this option.

  1. Make a note of what uname -r returns to compare after rebooting.

  2. Reboot the Jetson.

  3. Run uname -r, it should have changed from the previous value. In my case it changed from 5.10.104-tegra to 5.10.104 (I basically used this to flag that something had actually changed after the reboot).

  4. When back up:

	# Enable spidev
	sudo modprobe spidev
	$ lsmod | grep spi
	spidev                 28672  0
	spi_tegra114           28672  0

Which I believe is what’s required to run SPI applications on the Jetson.

  1. Run your application.

Before:

Avg: ~240 µs
Median: 240 µs
Stdev: ~51 µs

After

Avg: ~58 µs
Median: 56 µs
Stdev: ~31 µs

The patch seemed to result in better SPI performance and more consistent write times.

As a sanity check confirmed on a logic analyser that the code was indeed writing out data via SPI and got the expected byte sequence:

I will try next on Jetpack 6.2.

Extra: Deploying a Kernel image to multiple devices

  • It’s also possible to reuse the new kernel image in other Jetson Orin devices running the same Jetpack and L4T versions. On the target device:

    • copy the newly created kernel image to /boot
    • if the source device is currently running the new kernel image, get (maybe zip) the contents of ls /lib/modules/$(uname -r)/ from the source device and copy (and unzip) to /lib/modules/ on the target device
    • edit /boot/extlinux/extlinux.conf accordingly as explained above
    • reboot the target device
1 Like