[bootlin/training-materials updates] master: labs/sysdev-accessing-hardware: various improvements (dd1d4e37)
Thomas Petazzoni
thomas.petazzoni at bootlin.com
Thu Sep 22 18:09:27 CEST 2022
Repository : https://github.com/bootlin/training-materials
On branch : master
Link : https://github.com/bootlin/training-materials/commit/dd1d4e371cf48baad01746bd2c937f311a0374f2
>---------------------------------------------------------------
commit dd1d4e371cf48baad01746bd2c937f311a0374f2
Author: Thomas Petazzoni <thomas.petazzoni at bootlin.com>
Date: Thu Sep 22 18:09:27 2022 +0200
labs/sysdev-accessing-hardware: various improvements
Signed-off-by: Thomas Petazzoni <thomas.petazzoni at bootlin.com>
>---------------------------------------------------------------
dd1d4e371cf48baad01746bd2c937f311a0374f2
.../sysdev-accessing-hardware.tex | 122 ++++++++++++++++-----
1 file changed, 93 insertions(+), 29 deletions(-)
diff --git a/labs/sysdev-accessing-hardware/sysdev-accessing-hardware.tex b/labs/sysdev-accessing-hardware/sysdev-accessing-hardware.tex
index 78002bd6..84d8b361 100644
--- a/labs/sysdev-accessing-hardware/sysdev-accessing-hardware.tex
+++ b/labs/sysdev-accessing-hardware/sysdev-accessing-hardware.tex
@@ -263,22 +263,29 @@ i2c-1 i2c STM32F7 I2C(0x5c002000) I2C adapter
i2c-0 i2c STM32F7 I2C(0x40012000) I2C adapter
\end{bashinput}
-Oops, I2C5 is not listed here. However, could it have a wrong name?
-Since \code{i2cdetect} shows the base addresses for the control
-registers for each bus, let's check the datasheet for the SoC
-\footnote{\url{https://www.st.com/resource/en/reference_manual/dm00327659-stm32mp157-advanced-arm-based-32-bit-mpus-stmicroelectronics.pdf}}.
-Look for \code{I2C5} and you will find that the I2C5 base register
-address is \code{0x40015000}. That's different from the addresses
-of already enabled I2C buses.
+\code{i2c-0} is the I2C controller with registers at
+\code{0x40012000}, which is \code{I2C1} in the STM32MP1
+nomenclature. \code{i2c-1} is the I2C controller with registers at
+\code{0x5c002000}, which is \code{I2C4} in the STM32MP1
+nomenclature. Refer to the STM32MP1 memory map in the datasheet for
+details. Pay attention to the numbering difference: \code{i2c-0},
+\code{i2c-1} is the Linux numbering, based on the registration order
+of enabled I2C busses. Here, because only I2C1 and I2C4 are enabled,
+they are called \code{i2c-0} and \code{i2c-1}.
+
+Using the datasheet for the SoC
+\footnote{\url{https://www.st.com/resource/en/reference_manual/dm00327659-stm32mp157-advanced-arm-based-32-bit-mpus-stmicroelectronics.pdf}},
+we can find what is the base address of the registers for the
+\code{I2C5} controller: it is \code{0x40015000}.
\subsection{Customizing the Device Tree}
Fortunately, I2C5 is already defined in the one of the DTS includes
used by the Device Tree for our board. In our case, that's in
\kfile{arch/arm/boot/dts/stm32mp151.dtsi}. Look by yourself in this
-file, and you will find its definition, but with
-\code{status = "disabled";}. This means that the device is not enabled
-yet, and it's up to boards using it to do so.
+file, and you will find its definition, but with \code{status =
+"disabled";}. This means that this I2C controller is not enabled yet,
+and it's up to boards using it to do so.
We could modify the \kfile{arch/arm/boot/dts/stm32mp157a-dk1.dts} file
for our board, but that's not a very good idea as this file is
@@ -306,10 +313,10 @@ Why the \code{/delete-property/} statement? That's because we want
to see what happens when a device doesn't have associated pin
definitions yet.
-A device like an I2C controller node is typically declared in the
-DTSI files for the SoC, without pin settings.
+A device like an I2C controller node is typically declared in the DTSI
+files for the SoC, without pin settings as these are board
+specific. Pin definitions are then usually defined at board level.
-Pin definitions are then usually defined at board level.
In our case, we don't see such definitions, but they are actually
found in the \kfile{arch/arm/boot/dts/stm32mp15xx-dkx.dtsi}
file, shared between multiple stm32mp15 DK boards, which is included
@@ -403,7 +410,7 @@ to the I2C5 bus on the board, using breadboard wires:
\end{itemize}
If you didn't do any mistake, your new device should be detected at
-address 0x52:
+address \code{0x52}:
\begin{bashinput}
# i2cdetect -r 1
@@ -422,34 +429,87 @@ Continue? [y/N] y
We will later compile an out-of-tree kernel module to support this device.
-\section{Using kernel modules}
+\section{Plugging a USB audio headset}
In the next labs, we are going to play audio using a USB audio headset.
Let's see whether our kernel supports such hardware by plugging the
headset provided by your instructor.
-In the serial console, you should see messages confirming that the
-USB device was detected. However, there should be no \code{/proc/asound}
-directory yet, which exists when sound cards are in use.
+Before plugging the device, look at the output of \code{lsusb}:
-Actually, what we need to support a generic USB audio headset is
-a kernel configured with \kconfig{CONFIG_SND_USB_AUDIO}. Look for this
-parameter in the kernel configuration, and you should find that
-it is enabled as a module.
+\begin{bashinput}
+# lsusb
+Bus 001 Device 001: ID 1d6b:0002
+Bus 001 Device 002: ID 0424:2514
+\end{bashinput}
-So, instead of compiling the corresponding driver as a built-in, that's
-a good opportunity to practice with kernel modules.
+Now, when you plug the USB headset, a number of messages should appear
+on the console, and running \code{lsusb} again should show an
+additional device:
+
+\begin{bashinput}
+# lsusb
+Bus 001 Device 001: ID 1d6b:0002
+Bus 001 Device 005: ID 1b1c:0a06
+Bus 001 Device 002: ID 0424:2514
+\end{bashinput}
+
+The device of vendor ID \code{1b1c} and product ID \code{0a06} has
+appeared.
+
+The device also appears in \code{/sys/bus/usb/devices/}, in a
+directory whose name depends on the topology of the USB bus. When the
+device is plugged in the kernel messages show:
+
+\begin{bashinput}
+usb 1-1.1: new full-speed USB device number 3 using ehci-platform
+\end{bashinput}
-\subsection{Installing and using in-tree kernel modules}
+So if we go in \code{/sys/bus/usb/devices/1-1.1}, we get the {\em
+sysfs} representation of this USB device:
+
+\begin{bashinput}
+# cd /sys/bus/usb/devices/1-1.1
+# cat idVendor
+1b1c
+# cat idProduct
+0a06
+# cat busnum
+1
+# cat devnum
+6
+# cat product
+Raptor HS40
+\end{bashinput}
+
+However, while the USB device is detected, we currently do not have
+any driver for this device, so no actual sound card is detected.
+
+\section{Enabling, installing and using in-tree kernel modules}
Go back to the kernel source directory.
+The Linux kernel has a generic driver supporting all USB audio devices
+supporting the standard USB audio class. This driver can be enabled
+using the \kconfig{CONFIG_SND_USB_AUDIO} configuration option. Look
+for this parameter in the kernel configuration, and you should find
+that it is already enabled as a module.
+
+So, instead of compiling the corresponding driver as a built-in, that's
+a good opportunity to practice with kernel modules.
+
Following details given in the lectures, compile the modules for your
kernel if necessary (in case you just compiled the \code{zImage} and
DTB files), and then install them in our NFS root filesystem
-(\code{$HOME/__SESSION_NAME__-labs/tinysystem/nfsroot}).
+(\code{$HOME/__SESSION_NAME__-labs/tinysystem/nfsroot}). Make sure to
+also reinstall the kernel image, and reboot the board. Indeed, due to
+the changes we have made to the kernel source code, the kernel version
+is now \code{5.15.<x>-dirty}, the {\em dirty} indicating that the Git
+working tree has uncommitted changes. The modules are therefore
+installed in \code{/lib/modules/5.15.<x>-dirty/}, and the version of
+the running Linux kernel must match this.
-Once this is done, try to load the module that we need:
+After rebooting, try to load the module that we need:
\begin{bashinput}
modprobe snd-usb-audio
@@ -458,6 +518,10 @@ modprobe snd-usb-audio
By running \code{lsmod}, see all the module dependencies that
were loaded too.
+You can also see that a new USB device driver in
+\code{/sys/bus/usb/drivers/snd-usb-audio}. This directory shows which
+USB devices are bound to this driver.
+
You can check that \code{/proc/asound} now exists (thanks to loading
modules for the ALSA, the Linux sound subsystem), and that one sound
card is available:
@@ -474,7 +538,7 @@ is always loaded at startup.
We cannot test the sound card yet, as we will need to build some
software first. Be patient, this is coming soon.
-\subsection{Compiling and installing an out-of-tree kernel module}
+\section{Compiling and installing an out-of-tree kernel module}
The next device we want to support is the I2C Nunchuk. There is a driver
in the kernel to support it when connected to a Wiimote controller, but
@@ -508,7 +572,7 @@ target directory through the \code{INSTALL_MOD_PATH} variable:
make -C $HOME/__SESSION_NAME__-labs/kernel/linux \
M=$PWD \
INSTALL_MOD_PATH=$HOME/__SESSION_NAME__-labs/tinysystem/nfsroot \
- modules_install
+ modules_install
\end{bashinput}
You can see that this installs out-of-tree kernel modules under
More information about the training-materials-updates
mailing list