0% found this document useful (0 votes)
74 views

Linux Device Driver Course

Uploaded by

khanhvnuet
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
74 views

Linux Device Driver Course

Uploaded by

khanhvnuet
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 489

www.fastbitlab.

com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Copyright notice
Linux device driver programming power point
presentation by BHARATI SOFTWWARE is licensed under CC BY-SA 4.0
To view a copy of this license, visit
https://creativecommons.org/licenses/by-sa/4.0

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Links
• For the full video course please visit
• https://www.udemy.com/course/linux-device-driver-programming-using-
beaglebone-black/
• Course repository
• https://github.com/niekiran/linux-device-driver-1
• Explore all Fastbit EBA courses
• http://fastbitlab.com/course1/
• For suggestions and feedback
[email protected]

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Social media
• Join our Facebook private group for technical discussion
• https://www.facebook.com/groups/fastbiteba/
• Linkedin
• https://www.linkedin.com/company/fastbiteba/
• Facebook
• https://www.facebook.com/fastbiteba/
• YouTube
• https://www.youtube.com/channel/UCa1REBV9hyrzGp2mjJCagBg
• Twitter
• https://twitter.com/fastbiteba

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

HOST and Target

Host (PC running Ubuntu 18.04 OS 32/64bit)​ Target Beaglebone Black Rev A5​

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Installing required packages on the host

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Install these packages on the HOST


sudo apt-get update
sudo apt-get install build-essential lzop u-boot-tools net-tools bison flex
libssl-dev libncurses5-dev libncursesw5-dev unzip chrpath xz-utils
minicom
• These commands are given in the text file attached with this video

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Workspace setup
• You may follow the below folder setup to work with this course

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Download boot images and Root file system


512MB

FS Type : FAT16 FS Type : EXT4


This partition holds boot This partition holds
images like MLO, u-boot debian root file system
and kernel image

Partition 1 Partition 2
BOOT ROOTFS

μSD card partitions

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Download boot images and Root file system

• Download the boot images


file attached with this
lecture
• Visit this link and download
the latest Debian image for
beglebone black
• https://beagleboard.org/late
st-images

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Cross compiler and toolchain download


• To cross-compile Linux kernel, Linux application, and kernel
modules to ARM Cortex Ax architecture, we need a cross compiler.
• The SOC AM335x from TI, is based on ARM Cortex A8 processor of
ARMv7 architecture
• Download the cross compiler from here
• https://www.linaro.org/downloads/
• Link is given in the resource section of this lecture

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Install gparted application


• This is a graphical user interface application which we will use to
partition the Micro SD card

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Tool-chain download

32bit OS

64bit OS

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Tool-chain PATH settings


• Add the tool chain binary path to home directory .bashrc file

Steps:
1.Go to you home directory
2.Open .bashrc using vim or gedit text editor
3.Copy the below export command with path information to .bashrc file
export PATH=$PATH:<path_to_tool_chain_binaries>
4. Save and close

or simply do
echo “export PATH=$PATH:<path_to_tool_chain_binaries>” > ~/.bashrc

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Target preparation

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Board components

Sitara AM3358BZCZ100

Beaglebone Black A5

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Powering

USB Cable, Type A Plug to Mini Type B Plug

USB mini port

This end goes to


PC usb port

This end goes


BBB mini usb
port

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Serial debug port connection

BBB serial port pins

This end goes to This end goes to


BBB serial pins PC usb port

USB to TTL Serial Cable

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

USB to TTL serial converter dongle

USB to TTL serial converter cable

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

USB to Serial TTL cable pins BBB J1 header pin outs


GND ( Pin 1)
VCC RXD (Pin 4)
TXD TXD (Pin 5)
RXD
GND

Important Note : RXD of the cable must be connected to TXD of the BBB serial header (pin 5)
TXD of the cable must be connected to RXD of the BBB serial header(pin 4)
GND of the cable must be connected to GND of the BBB serial header(pin 1)
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Boot sequence of BBB

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Boot button(S2) NOT pressed Boot button(S2) pressed


during power up SYSBOOT[4:0] during power up

1. MMC1(eMMC) 1. SPI0

BOOT sequence
BOOT sequence

2. MMC0 (μSD) 2. MMC0

3. UART0 3. USB0

4. USB0 4. UART0

AM335X Boot Sequence

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

(S2)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Usage of Power button , reset button and boot


button
• Power button: By press and hold this button for 10 to 20 seconds, you can power
down the board. Once you power down the board, gently pressing this button one
time will again power up the board. Instead of connecting and disconnecting
power sources to your board now and then, you can use this button to power
down and power up.

• Reset button: Pressing this button resets the board. Note that the boot sequence
is not affected by the reset action.

• Boot button: you can use this button to change the boot sequence during power-
up of the board.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

4GB mmc1 interface


DDR
eMMC
(512MB)
Memory

AM335x SOC
DDR interface

Micro SD mmc0 interface


card
connector
BBB

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Boot button(S2) NOT pressed Boot button(S2) pressed


during power up SYSBOOT[4:0] during power up

1. MMC1(eMMC) 1. SPI0

BOOT sequence
BOOT sequence

2. MMC0 (μSD) 2. MMC0(μSD)

3. UART0 3. USB0

4. USB0 4. UART0

AM335X Boot Sequence

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Preparing μSD card for SD boot

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

μSD card preparation


1. You can use 8/16/32 GB μSD card
2. Connect the μSD card to PC using card reader
3. Launch the gparted application
4. Make 2 partitions (fat16 and ext4)
5. Configure the boot, lba flags on the boot partition
6. Copy boot images on FAT16 partition ( this is boot partition)
7. Copy debian root file system on ext4 partition
8. Unmount and remove the μSD card from the PC
9. Insert the μSD card into BBB μSD card slot
10. Boot from SD card interface (mmc0 interface)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Booting from μSD card interface


1. Make sure that BBB is not powerd up
2. Connect serial debug cable between BBB and Host
3. Insert the SD card to BBB
4. Give power to the board using mini usb cable
5. Press and hold the boot button (S2)
6. Press and hold the power button (S3) until the blue LED turns off and turns ON
again. (if blue LED doesn’t turn ON, gently press the power button)
7. Release the S2 button after 2 to 5 seconds

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Serial debug port connection

BBB serial port pins

This end goes to This end goes to


BBB serial pins PC usb port

USB to TTL Serial Cable

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Linux kernel image update

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Steps to update the linux kernel image


• Clone the latest stable kernel source from BBB official github
• https://github.com/beagleboard/linux
• Compile and generate the kernel image
• Update the SD card with new kernel image and boot again

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kernel compilation steps


STEP 1:
/*removes all the temporary folder, object files, images generated during the
previous build. This step also deletes the .config file if created previously */

make ARCH=arm distclean

STEP 2:
/*creates a .config file by using default config file given by the vendor */

make ARCH=arm bb.org_defconfig

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kernel compilation steps


STEP 3:
/*This step is optional. Run this command only if you want to change some kernel settings
before compilation */

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig

STEP 4:
/*Kernel source code compilation. This stage creates a kernel image "uImage" also all the
device tree source files will be compiled, and dtbs will be generated */

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- uImage dtbs LOADADDR=0x80008000 -j4

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kernel compilation steps


STEP 5:
/*This step builds and generates in-tree loadable(M) kernel modules(.ko) */

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules -j4

STEP 6:
/* This step installs all the generated .ko files in the default path of the computer
(/lib/modules/<kernel_ver>) */

sudo make ARCH=arm modules_install

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Update kernel image and kernel modules in


SD card
• Copy uImage to board and then update the boot partition of the SD
card
• Copy newly installed 4.14.108 folder to board's /lib/modules/ folder
• Reset the board (you should see BBB boots with newly updated
kernel image )

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Enabling internet over USB

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Internet over USB


• Beaglebone board can communicate to the internet over the USB
cable by sharing your PC’s internet connection.
• You need not to use a separate ethernet cable to connect your board
to internet.
• The required drivers are enabled by default in the kernel and loaded
when Linux boots on the BBB
• But you must enable internet sharing on your HOST

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Internet over USB


• Target settings :
1. Add name server address in : /etc/resolv.conf
2. Add name server address in : /etc/network/interfaces
iface usb0 inet static
address 192.168.7.2
netmask 255.255.255.252
network 192.168.7.0
gateway 192.168.7.1
dns-nameservers 8.8.8.8
dns-nameservers 8.8.4.4
1. Add default gateway address by running the below command
• route add default gw 192.168.7.1 (Using PC as default gateway)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Internet over USB Network interface name . You must


use the name as listed by the
command ‘ifconfig’
Host settings :
Run the below commands
sudo iptables --table nat --append POSTROUTING --out-interface wlp2s0 -j MASQUERADE
sudo iptables --append FORWARD --in-interface wlp2s0 -j ACCEPT
sudo echo 1 > /proc/sys/net/ipv4/ip_forward

If you reboot your machine, again you must run these commands.
So, its better if you create a small script and execute when your machine reboots.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BBB eMMC partitions after using eMMC flasher Debian image

1MB

MBR mmcblk1p1
MLO
U-boot mmcblk1

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Hello world kernel module

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Linux Kernel module (LKM)


• Let's learn how to write a simple hello world kernel module
• Compiling the kernel module using kbuild
• Transferring kernel module to BBB, loading, and unloading

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Linux Kernel module (LKM)


• Linux supports dynamic insertion and removal of code from the kernel while the
system is up and running. The code what we add and remove at run time is called
a kernel module
• Once the LKM is loaded into the Linux kernel, you can start using new features
and functionalities exposed by the kernel module without even restarting the
device.
• LKM dynamically extends the functionality of the kernel by introducing new
features to the kernel such as security, device drivers, file system drivers, system
calls etc. (modular approach )
• Support for LKM allows your embedded Linux systems to have only minimal base
kernel image(less runtime storage) and optional device drivers and other features
are supplied on demand via module insertion
• Example: when a hot-pluggable new device is inserted the device driver which is
an LKM gets loaded automatically to the kernel

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

LKM
Running Linux Kernel

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Static and dynamic LKMs


• Static(y)
➢ When you build a Linux kernel, you can make your module statically linked to the kernel
image (module becomes part of the final Linux kernel image ). This method increases the size
of the final Linux kernel image. Since the module is ‘built-in’ into the Linux kernel image, you
can not ‘unload’ the module. It occupies the memory permanently during run time
• Dynamic(m)
➢ When you build a Linux kernel, these modules are NOT built into the final kernel image, and
rather there are compiled and linked separately to produce .ko files. You can dynamically load
and unload these modules from the kernel using user space programs such as insmod,
modprobe , rmmod.

So, when you’re building the kernel, you can either link modules directly into the kernel
or build them as separate modules that can be loaded into the kernel at some other
time.
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

First
kernel
module

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com
Header section

Your code

Registration

Module description

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Header

Every kernel module should to include this header file

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kernel header vs user-space header


• Since you write a kernel module that is going to be executed in kernel
space, you should be using kernel headers, never include any user-
space library headers like C std library header files.
• No user space library is linked to the kernel module
• Most of the relevant kernel headers live in
linux_source_base/include/linux/

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Your code

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Your code module initialization function

Module clean-up function

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Module initialization function


• Prototype: int fun_name(void);
• Must return a value ; 0 for success, nonzero means module
initialization failed. So the module will not get loaded in the kernel.
• This is an entry point to your module ( like main). This function will
get called during boot time in the case of static modules
• In the case of dynamic modules, this function will get called during
module insertion
• There should be one module initialization entry point in the module

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Module initialization function


• You may do some initialization of devices
• Initialization of device private data structures
• Requesting memory dynamically for various kernel data structures
and services
• Request for allocation of major-minor numbers
• Device file creation

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Understanding the complete syntax.

The module initialization function is module-specific and should never be called from
other modules of the kernel. It should not provide any services or functionalities
which may be requested by other modules. Hence it makes sense to make this
function private using ‘static’ though it is optional.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Module clean-up function


• Prototype
void fun_name(void);
• This is an entry point when the module is removed
• Since you can not remove static modules, clean-up function will get called
only in the case of dynamic modules when it is removed using user space
command such as rmmod
• If you write a module and you are sure that it will always be statically linked
with the kernel, then there is no need to implement this function.
• Even if your static module has a clean-up function, the kernel build system
will remove it during the build process if there is an __exit marker.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Module clean-up function


• Typically, you must do exact reverse operation what you had done in
the module init function. undoing init function.
• Free memory which are requested in init function
• De-init the devices or leave the device in the proper state

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Understanding the complete syntax.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Function section attributes


Compiler directive, which directs
the compiler to keep data or code
• __init in an output section called “.init”

• __exit

Compiler directive, which directs


the compiler to keep data or code
in an output section called “.exit”

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

__init
• __init and __exit makes sense only for static modules (built-in modules)
• __init is a macro which will be translated into compiler directive, which instructs the
compiler to put the code in .init section of the final ELF of linux kernel image.
• .init section will be freed from the memory by the kernel during boot time once all the
initialization functions get executed.
• Since the built-in driver cannot be unloaded, its init function will not be called again
until the next reboot, that’s why there is no need to keep references to its init function
anymore.
• so using __init macro is a technique, when used with a function, the kernel will free the
code memory of that function after its execution.
• Similarly, you can use __initdata with variables that will be dropped after the
initialization. __initdata, which works similarly to __init but for init variables rather than
functions.
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

__exit
• You know that for built-in modules clean-up function is not required
• So, when you use the __exit macro with a clean-up function, the
kernel build system will exclude those functions during the build
process itself.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

.init section
memory will be
Static modules
freed by the kernel
during boot.
int __init m1_init_fun (void) { …. }
m1_init_fun
module1.c m2_init_fun .init

Kernel build
int __init m2_init_fun (void) { …. } system m3_init_fun .text
(Kbuild)
module2.c

All __exit marked functions will


be dropped by the kernel build
int m3_init_fun (void) { …. }
system hence they will not be
part of final image.
module3.c Linux kernel image
(ELF)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Module entry points registration

• These are the macros used to register your module’s init function and clean-up
function with the kernel.
• Here module_init/module_exit is not a function, but a macro defined in linux/module.h
• For example, module_init() will add its parameter to the init entry point database of the
kernel
• module_exit() will add its parameter to exit entry point database of the kernel

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Module description

• MODULE_LICENSE is a macro used by the kernel module to announce its license type .
• If you a load module whose license parameter is non-GPL(General Public License), then kernel
triggers warning of being tainted. Its way of kernel letting the users and developers know its non-
free license based module.
• The developer community may ignore the bug reports you submit after loading the proprietary
licensed module
• The declared module license is also used to decide whether a given module can have access to the
small number of "GPL-only" symbols in the kernel.
• Go to linux/module.h to find out what are the allowed parameters which can be used with this
macro to load the module without tainting the kernel.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

MODULE_INFO

MODULE_INFO(name, “string_value");
• MODULE_INFO(board,”Beagle bone”);

You can see the module information by running the below command on the .ko file
arm-linux-gnueabihf-objdump -d -j .modinfo hellowrold.ko

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Building a kernel module


• Kernel module can be built in 2 ways
• Statically linked against the kernel image
• Dynamically loadable.
• In most of the exercises in this course we will be writing and using
dynamically loadable kernel modules.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

dynamically loadable kernel module

In tree module Out of tree module


(internal to the linux kernel tree) (external to the linux kernel tree)

This method taints the kernel.


Kernel issues a warning saying out of tree
module has been loaded.
We can safely ignore the warning !

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

In-tree and out of tree


• Basically, out of tree means outside of the Linux kernel source tree.
• The modules which are already part of the Linux kernel are called in-
tree modules. (approved by the kernel developers and maintainers )
• When you write a module separately(which is not approved and may
be buggy), build and link it against the running kernel, then its called
as out of the tree module.
• Hence when you load an out of tree kernel module, kernel throws a
warning message saying it got tainted.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Building a kernel module(out of tree)


• Modules are built using "kbuild" which is the build system used by the
Linux kernel
• Modules must use "kbuild" to stay compatible with changes in the build
infrastructure and to pick up the right flags to GCC
• To build external modules, you must have a prebuilt kernel source available
that contains the configuration and header files used in the build
• This ensures that as the developer changes the kernel configuration, his
custom driver is automatically rebuilt with the correct kernel configuration

Reference : https://www.kernel.org/doc/Documentation/kbuild/modules.txt

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Important note:
• When you are building out of tree(external ) module, you need to have a
complete and precompiled kernel source tree on your system
• The reason is, modules are linked against object files found in the kernel source
tree
• You can not compile your module against one Linux kernel version and load it into
the system, which is running kernel of different version. The module load may not
be successful, and even if it is successful, you will encounter run time issues with
the symbols.
• Thumb rule: “Have a precompiled Linux kernel source tree on your machine and
build your module against that “
• There are two ways to obtain a prebuilt kernel version
• Download kernel from your distributor and build it by yourself
• Install the Linux-headers- of the target Linux kernel

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Building a kernel module(out of tree)


The command to build an external module is:
make -C <path to linux kernel tree> M=<path to your module> [target]

Kbuild rules Linux kernel source tree


• Compiler switches Top level Makefile
• Dependency list
• Version string

Your working directory


Local Makefile Where external modules to
be compiled are stored

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Command syntax
make -C $KDIR M=$PWD [Targets]

-C $KDIR: The directory where the kernel


source is located. "make" will actually M=$PWD: Informs kbuild that an
change to the specified directory when external module is being built. The value
executing and will change back when given to "M" is the absolute path of the
finished directory where the external module
(kbuild file) is located.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Command syntax
make -C $KDIR M=$PWD [Targets]

• modules :The default target for external modules. It has the same functionality
as if no target was specified.
• modules_install: Install the external module(s). The default location is
/lib/modules/<kernel_release>/extra/, but a prefix may be added with
INSTALL_MOD_PATH
• clean : Remove all generated files in the module directory only.
• help:List the available targets for external modules

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Creating a local Makefile


In the local makefile you should define a kbuild variable like below
obj-<X> := <module_name>.o

Here obj-<X> is kbuild variable and ‘X’ takes one of the below values
X = n , Do not compile the module
X= y, Compile the module and link with kernel image
X = m , Compile as dynamically loadable kernel module

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Creating a local Makefile

obj-m := main.o

The kbuild system will build main.o from main.c and after linking, will result in the
kernel module main.ko.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

In-tree building
• You have to add the Linux kernel module inside the Linux kernel
source tree and let the Linux build system builds that.
• If you want to list your kernel module selection in kernel menuconfig,
then create and use a Kconfig file

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Steps to add in-tree module to kernel menu configuration


1. create a folder in drivers/char/my_c_dev
2. copy main.c
3. create Kconfig file and add the below entries
menu "my custom modules"
config CUSTOM_HELLOWORLD
tristate "hello world module support"
default m
endmenu

4. add the local Kconfig entry to upper level Kconfig

5. create a local Makefile

6. add obj-$(config_item) += <module>.o in to local Makefile

7. add the local level makefile to higher level makefile

Ref :- https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Debugging with printk


• printf is one of the best debugging tool we have in user-level
applications.
• When you work in kernel space, you will not have any access to the C
standard library to access functions like printf or scanf.
• But don’t worry kernel has its own printf like kernel API called printk,
where the letter ‘k’ signifies kernel space printing.
• printf(“Hello this is user application running \n”);
• printk(“Hello this is kernel code running \n”);
• printf(“ value of data1 = %d data = %d\n” , d1,d2);
• printk(“ value of data1 = %d data = %d\n” , d1,d2);

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Debugging with printk


• When using printk , the message will go into the kernel ring buffer
simply we call “Kernel log,” and we can print and control the kernel
ring buffer using the command dmesg.
• So if you want to check the latest 5 kernel messages, just run
dmesg | tail -5
dmesg | head -20
• The printk does not support floating-point formats (%e, %f, %g )

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

linux/Documentation/printk-formats.txt

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kernel log levels


Based on the kernel log level you can control the priority of your printk messages. There are 8 such log
levels. A lower number indicates a higher priority. And the default printk log level or priority is usually set
to 4. i.e., KERN_WARNING

include/linux/kern_levels.h

The log level will be used by the kernel to understand the priority of the message .
Based on the priority kernel decides whether the message should be presented to
the user immediately, by printing directly on to the console.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kernel log levels


• All kernel messages will have their own log level
• You may have to specify the log level while using printk
printk(“Hello this is kernel code running \n”);
• in the above printk , there is no log level visible, right? but the kernel will
add the default log level set by the kernel config item
CONFIG_MESSAGE_LOGLEVEL_DEFAULT whose value is 4
• So, the above statement is equivalent to
• printk(KERN_WARNING “Hello this is kernel code running \n”);

Log level printf like message

Note : There is no comma(,) between log level and message

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Significance of kernel log level


printk(KERN_ALERT “Hello this action should be taken immediately \n“);
printk(KERN_INFO “Hello this is jut for your information\n”);

The kernel message log level will be compared with the current console log level. If the kernel message log level
is lower than the current console log level, then the message will be directly printed on the current console.

By default console log level will have the value of config item: CONFIG_CONSOLE_LOGLEVEL_DEFAULT
Its default value is set to 7. You can change it via kernel menuconfig or running commands.

To know the current log level status just run


cat /proc/sys/kerne/printk

At run time you can change the log level values using the below command
echo 6 > /proc/sys/kernel/printk

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

printk wrappers
Name Log Alias function
level
KERN_EMERG “0” pr_emerg
KERN_ALERT “1” pr_alert
KERN_CRIT “2” pr_crit printk(KERN_INFO “Hello this is jut for your information\n”);
KERN_ERR “3” pr_err
pr_info(“Hello this is jut for your information\n”);
KERN_WARNING “4” pr_warning
KERN_NOTICE “5” pr_notice
KERN_INFO “6” pr_info
KERN_DEBUG “7” pr_debug (works
only if DEBUG is
defined)
KERN_DEFAULT “”

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

printk wrappers

Include/linux/printk.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kernel hexdump facilities

lib/hexdump.c

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device driver

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

What is device driver ?


• A device driver is a piece of code that configures and manages a device.

• The device driver code knows, how to configure the device, sending data to the
device, and it knows how to process requests which originate from the device.

• When the device driver code is loaded into the operating system such as Linux, it
exposes interfaces to the user-space so that the user application can communicate
with the device.

• Without the device driver, the OS/Application will not have a clear picture of how to
deal with a device

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

User space Vs Kernel Space

User space Kernel space


CPU

Restricted Mode Privileged Mode


Kernel level code
User level programs
( linux kernel, subsystems and LKMs)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Applications

User space

Kernel subsystems

Kernel space Kernel services

Device drivers

Hardware space

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

write
User level programs App2 open
cp
read
User space App1 echo

Device files /dev/xyz

Device driver takes the burden of interacting


Kernel Space Device driver of XYZ with the hardware devices and export
interfaces that applications and other modules
of the kernel can use to access the devices.

Hardware XYZ

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kernel Space

Character Block Network


device device device
drivers drivers drivers

Char. Devices Storage devices Network devices


Hardware (RTC, keyboard (sdmmc, eeprom, (ethernet , wifi,
space ,sensors,etc) flash, harddisk ) Bluetooth)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Character driver (char driver)


• Character driver accesses data from the device sequentially. i.e., byte
by byte(like a stream of characters) not as a chunk of data
• Sophisticated buffering strategies are usually not involved in char
drivers. Because when you write 1 byte, it directly goes to the device
without any intermediate buffering, delayed write back, dirty buffer
management.
• Char devices: sensors, RTC, keyboard, serial port, parallel port, etc.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

User Application Kernel space Hardware

0xAB
write(fd,0xAB); RTC driver RTC device
echo 0xAB > /dev/rtc

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Block drivers
• The device which handles data in chunks or blocks is called a block
device.
• Block drivers are more complicated than char drivers because block
drivers should implement advanced buffering strategies to read and
write to the block devices, and disk caches are involved.
• Examples: mass storage devices such as hard disks, SDMMC, Nand
flash, USB camera, etc

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device files
• Devices are accessed as a file in Unix/Linux systems.
• A device file is a special file or a node which gets populated in /dev
directory during kernel boot time or device/driver hot plug events
• By using device file, user application and drivers communicate with each
other.
• Device files are managed as part of VFS subsystem of the kernel

/dev/xyz Kernel
Device files
User program
module/Driver

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device files

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Exercise : pseudo character driver

• Write a character driver to deal with a pseudo character device


• The pseudo-device is a memory buffer of some size
• The driver what you write must support reading, writing and seeking to
this device
• Test the driver functionality by running user-level command such as
echo, dd, cat and by writing user lever programs

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

User application
open( “/dev/rtc” ,….);
read(fd,….);
write(fd….);

User space
GNU C library

System call handlers and service routines


Kernel space
open() {
……
}

read(){ Hardware
….. rtc
VFS
}

write()
{
…….
}
Kernel module/Driver
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Device number (Major & minor)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

User space
/dev/rtc

Kernel space open() {


……
}
Hardware
read(){
VFS ….. (RTC)
}

write()
{
…….
}
Kernel module/Driver
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

4:0 4:1 4:2 4:3


User space /dev/rtc0 /dev/rtc1 /dev/rtc2 /dev/rtc3

Kernel space open() { Hardware


……
}
4 (RTC)
Hardware
read(){
VFS ….. (RTC)
}
Hardware
write() (RTC)
{
……. Hardware
} (RTC)
Kernel module/Driver
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

127:0 127:1 127:2 127:3 127:4 127:5 127:6

First device number will be updated in this variable

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Major and minor numbers

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Connection establishment between device


file access and the driver
• Create device number
• Create device files
• Make a char device registration with the VFS (CDEV_ADD)
• Implement the driver’s file operation methods for open, read, write,
llseek , etc.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kernel APIs and utilities to be used in driver code

alloc_chrdev_region(); 1.Create device number

cdev_init(); 2. Make a char device registration


cdev_add(); with the VFS

class_create();
3. Create device files
device_create();

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kernel APIs and utilities to be used in driver code

Creation Deletion
alloc_chrdev_region(); unregister_chrdev_region();

cdev_init(); cdev_del();
cdev_add();

class_create(); class_destroy();
device_create(); device_destroy();

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kernel Header file details


Kernel functions and data structures Kernel header file
alloc_chrdev_region() include/linux/fs.h
unregister_chrdev_region()

cdev_init() include/linux/cdev.h
cdev_add()
cdev_del()
device_create() include/linux/device.h
class_create()
device_destroy()
class_destroy()
copy_to_user() include/linux/uaccess.h
copy_from_user()
VFS structure definitions inclue/linux/fs.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Dynamically register a range of char device numbers

first of the
requested range of
output parameter
minor numbers
for first assigned
number

number of minor
numbers required

name of the associated


device or driver

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Example

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Example
Name of this device numbers “eeprom”

127:0 127:1 127:2 127:3 127:4 127:5 127:6


Total seven device
First minor numbers created

First device number


will be updated in
this variable

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device number representation


• The device number is a combination of major and minor numbers
• In Linux kernel, dev_t (typedef of u32) type is used to represent the device number.
• Out of 32 bits, 12 bits to store major number and remaining 20 bits to store minor
number
• You can use the below macros to extract major and minor parts of dev_t type variable
dev_t device_number;
int minor_no = MINOR(device_number);
int major_no = MAJOR(device_number);
• You can find these macros in linux/kdev_t.h
• If you have, major and minor numbers , use the below macro to turn them into dev_t
type device number
MKDEV(int major, int minor);

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kernel APIs and utilities to be used in driver code

alloc_chrdev_region(); 1.Create device number

cdev_init(); 2. Make a char device registration


cdev_add(); with the VFS

class_create();
3. Create device files
device_create();

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Initialize a cdev structure

structure to initialize

File operations for this device

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Example

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com
fs/char_dev.c

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

VFS file operation structure

Include/linux/fs.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Structure member elements initialization


struct CarModel
{
unsigned int carNumber;
uint32_t carPrice;
uint16_t carMaxSpeed;
float carWeight;

};
struct CarModel CarBMW ={2021,15000,220,1330 }; // C89 method . Order is important

struct CarModel CarBMW ={.carNumber= 2021,.carWeight =1330 ,.carMaxSpeed =220,.carPrice =15000 };


//C99 method using designated initializers

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pointer to file operation structure of


the driver

A pointer to the module that owns this


structure; it should usually be initialized
to THIS_MODULE.
This field is used to prevent the module from
being unloaded while the structure is in use.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

THIS_MODULE
• THIS_MODULE is a macro which resolves in to ‘pointer to a struct
module variable which corresponds to our current module”
• You can find this macro in linux/export.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Add a char device to the Kernel VFS


number of consecutive minor
numbers corresponding to this
device
cdev structure for the device

first device number for


which this device is
responsible

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Example

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kernel APIs and utilities to be used in driver code

alloc_chrdev_region(); 1.Create device number

cdev_init(); 2. Make a char device registration


cdev_add(); with the VFS (CDEV_ADD)

class_create();
3. Create device files
device_create();

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Dynamic device file creation in Linux


• In Linux, you can create a device file dynamically(on demand), i.e you need not manually
create the device files under /dev directory to access your hardware.
• User-level program such as udevd can populate /dev directory with device files
dynamically
• udev program listens to the uevents generated by hot plug events or kernel modules.
When udev receives the uevents, it scans the subdirectories of /sys/class looking for the
‘dev’ files to create device files.
• For each such 'dev' file, which represents a combination of major and minor number for
a device, the udev program creates a corresponding device file in /dev directory

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

udev
• So, udev relies on device information being exported to user space
through sysfs
• uevents are generated when device driver takes the help of kernel
APIs to trigger the dynamic creation of device files or when a hot-
pluggable device such as a USB peripheral is plugged into the system

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Dynamic device file creation in Linux


• All that a device driver needs to do , for udev to work properly with it, is ensure that
any major and minor numbers assigned to a device controlled by the driver are
exported to user space through sysfs

• The driver exports all the information regarding the device such as device file name,
major , minor number to sysfs by calling the function device_create

• udev looks for a file called ‘dev’ in the /sys/class/ tree of sysfs, to determine what the
major and minor number is assigned to a specific device

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

class_create and device_create

class_Create:
Create a directory in sysfs : /sys/class/<your_class_name>

device_create :
This function creates a subdirectory under
/sys/class/<your_class_name> with your device name.
This function also populates sysfs entry with dev file which consists of
the major and minor numbers, separated by a : character

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

/sys/class/your_class_name/your_device_name/dev /dev/your_device_name

/sys/class/your_class_name
dev file contains major and minor
numbers, separated by a : character.
udevd udev scans and reads this file to create a
User space device node for your device under /dev
directory
1 2

uevents
3
Kernel space

class_create(“your_class_name”);
Your driver should add all the info regarding
the device (such as device file name, major ,
device_Create(your_calss_name, device_number, “your_device_name”) minor number) to sysfs by calling the function
device_create

Driver/Kernel module
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Create and register a class with sysfs

pointer to the module


that is to “own” this
struct class

string for the


name of this
class

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Example

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Populates the sysfs class you created in previous step


with device numbers and device names

pointer to the parent struct


pointer to the struct class device of this new device
that this device should be
registered to

dev_t for the char


device to be added
string for the device's name
data to be added to the
device for callbacks

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Example

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Character driver file operation methods

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Character driver file operation methods


• In this character driver we will give support to handle the below user
level system calls
• open
• close
• read
• write
• llseek

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

VFS file operation structure

Include/linux/fs.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

User space /dev/pcd

Kernel space open() {


……
}

read(){ pcd memory


VFS …..
}

write()
{
…….
}
pcd driver
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Open
fd = open(“/dev/pcd”,O_RDWR);

User space /dev/pcd

Kernel space

Pointer of Inode
VFS associated with
filename Pointer of file object

Opens a file by creating a


new file object and linking
it to the corresponding pcd driver
inode object BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

VFS data structures involved


fd = open(“/dev/pcd”,O_RDWR);

User space /dev/pcd

Kernel space

struct inode struct file

Struct
struct cdev
file_ops
VFS
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Inode object
• Unix makes a clear distinction between the contents of a file and the information
about a file
• An inode is a VFS data structure(struct inode) that holds general information about a
file.
• Whereas VFS ‘file’ data structure (struct file) tracks interaction on an opened file by
the user process
• Inode contains all the information needed by the filesystem to handle a file.
• Each file has its own inode object, which the filesystem uses to identify the file
• Each inode object is associated with an inode number, which uniquely identifies the
file within the filesystem.
• The inode object is created and stored in memory as and when a new file (regular or
device ) gets created

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

File object
• Whenever a file is opened a file object is created in the kernel space .
There will one file object for every open of a regular or device file.

• Stores information about the interaction between an open file and a


process

• This information exists only in kernel memory during the period when
a process has the file open. The contents of file object is NOT written
back to disks unlike inode.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Inode object initialization

• Whenever device file is created(udev or mknod)


init_special_inode() gets called
• Here, inode object’s i_rdev is initliazed ( i_rdev
is device number )
• inode->i_fop field is initialized with default file
operations (def_chr_fops )

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

open User space

Return ‘fd’ to user space ( -1 means failure )


do_sys_open Kernel space

‘file’ object allocation do_filp_open

Using default fops


do_dentry_open

Replacing default fops with ‘cdev’ fops


chrdev_open

your driver open


method

For more details refer Understanding linux kernel 3rd edition, page 524 “The open( ) System Call “

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Copying ‘inode’s’ fops into ‘file’ object’s fops

Calling open method of default fops

Note: Partial code of the function is shown


BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

This is a dummy open


which calls your driver’s
real open method

Note: Partial code of the function is shown


BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

open User space

File object Kernel space


Inode object close

f_op write
i_cdev read
Open
File object

f_op
cdev Driver

F_ops

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

When a process opens the file, the VFS


initializes the f_op field of the new file
object with the address stored in the inode
so that further calls to file operations can
use these functions.

The main information stored in a file object is the


current file offset—the current position in the file
from which the next operation will take place.

Because several processes may access the same file


concurrently, the file pointer must be kept in the file
object rather than the inode object.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Summary
When device file gets created
1) create device file using udev
2) inode object gets created in memory and inode’s i_rdev field is initialized with device number
3) inode object’s i_fop field is set to dummy default file operations (def_chr_fops )

When user process executes open system call


1) user invokes open system call on the device file
2) file object gets created
3) inode’s i_fop gets copied to file object’s f_op (dummy default file operations of char device file)
4) open function of dummy default file operations gets called ( chrdev_open)
5) inode object’s i_cdev field is initialized with cdev which you added during cdev_add ( lookup
happens using inode-> i_rdev field )
6) inode->cdev->fops ( this is a real file operations of your driver) gets copied to file->f_op
7) file->f_op->open method gets called (read open method of your driver )

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Open method
Pointer of file object
Pointer of Inode
associated with
filename

Return :
0 if open is successful
Negative error code if open fails

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

What you do inside the open method ?


• Initialize the device or make device respond for read/write access
• Detect device initialization errors
• Check open permission (O_RDONLY, O_WRONLY, O_RDWR)
• Identify the device being opened using minor number
• Prepare device private data structure if required
• Update f_pos if required
• Open method is optional. If not provided , open will always succeed
and driver is not notified.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Close
close(fd);

User space /dev/pcd

Kernel space

VFS

Releases the file object.


Called when the last reference to an
open file is closed— that is, when
pcd driver
the f_count field of the file object
becomes 0. BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Release method

Pointer of Inode Pointer of file object


associated with
filename

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Release method
• In release method the driver can do reverse operation of what open had
done.
• E.g. if open method brings the device out of low power mode, then release
method may send the device back to the low power mode.
• Basically you should leave the device in its default state, the state which was
before the open call.
• Free any data structures allocated by the open method
• Return 0 on success . Negative error code if any errors
• For example you try to de-initialize the device and the device doesn’t respond

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Read
read(fd,buff,20);

User space /dev/pcd

Kernel space

VFS

pcd driver
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Read method
Pointer of current file
Pointer of user buffer position from which the
read has to begin
Pointer of file object

Optional macro which alerts the Read count given by user


programmer that this is a user
level pointer . IT cannot be
trusted for direct dereferencing

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Read method
• Read ‘count’ bytes from a device starting at position ‘ f_pos’.
• Update the ‘f_pos’ by adding the number bytes successfully read
• Return number of bytes successfully read
• Return 0 if there is no bytes to read (EOF)
• Return appropriate error code (-ve value) if any error
• A return value less than ‘count’ does not mean that an error has
occurred.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

__user macro
• It’s a macro used with user level pointers which tells the developer
not to trust or assume it as a valid pointer to avoid kernel faults.
• Never try to dereference user given pointers directly in kernel level
programming . Instead use dedicated kernel functions such as
copy_to_user and copy_from_user
• GCC doesn’t care whether you use __user macro with user level
pointer or not. This is checked by sparse , a semantic checker tool of
linux kernel to find possible coding faults .

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Write
write(fd,buff,20);

User space /dev/pcd

Kernel space

VFS

pcd driver
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Write method
Pointer of current file
Pointer of user buffer position from which the
Pointer of file object write has to begin

write count given by user

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Write method
• Write ‘count’ bytes into the device starting at position ‘f_pos’.
• Update the ‘f_pos’ by adding the number bytes successfully written
• Return number of bytes successfully written
• Return appropriate error code (-ve value) if any error

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

llseek
llseek(fd,buff,20);

User space /dev/pcd

Kernel space

VFS

pcd driver
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

llseek Origin
Pointer of file object

Offset value

SEEK_SET The file offset is set to ‘off’ bytes.


SEEK_CUR The file offset is set to its current location plus ‘off’ bytes.
SEEK_END The file offset is set to the size of the file plus ‘off’ bytes.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

llseek method

• In the llseek method, driver should update the file pointer by using
‘offset’ and ‘whence’ information
• The llseek handler should return , newly updated file position or error

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Character driver clean-up function

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kernel APIs and utilities to be used in driver code

Creation Deletion
alloc_chrdev_region(); unregister_chrdev_region();

cdev_init(); cdev_del();
cdev_add();

class_create(); class_destroy();
device_create(); device_destroy();

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Remove a device that was created with device_create()

pointer to the struct class that this


device was registered with

dev_t of the device that was previously registered

Destroys a struct class structure

pointer to the struct


class that is to be
destroyed
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Remove cdev registration from the kernel VFS


cdev structure to be removed

Unregister a range of device numbers

the first in the number of


range of numbers device numbers
to unregister to unregister

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

goto statement for error handling

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Error handling of pointers during kernel


function return
• You can use some kernel macros to deal with return of error pointers
by kernel functions.
• The below macros help to understand what made kernel function to
fail.
• IS_ERR()
• PTR_ERR()
• ERR_PTR()
• These macros can be found in include include/linux/err.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Read method implementation

User buffer
read
Device memory (memory of the
buffer Copy_to_user() process address
space )

Kernel space User space


(non swappable) (swappable)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Read method implementation

1) check the user requested ‘count’ value against DEV_MEM_SIZE of the


device .
• if f_pos (current_file_pos) + count > DEV_MEM_SIZE
• Adjust the ‘count’ . count = DEV_MEM_SIZE – f_pos
2) copy 'count' number of bytes from device memory to user buffer
3) Update the f_pos
4) Return number of bytes successfully read or error code
5) If f_pos at EOF, then return 0;

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pseudo character device memory access

0 1 2 3 4 5 …. 510 511

f_pos
(current file position)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

When a process opens the file, the VFS


initializes the f_op field of the new file
object with the address stored in the inode
so that further calls to file operations can
use these functions.

The main information stored in a file object is the


current file offset—the current position in the file
from which the next operation will take place.

Because several processes may access the same file


concurrently, the file pointer must be kept in the file
object rather than the inode object.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pseudo character device memory access

After read of 6 bytes


0 1 2 3 4 5 6 …. 510 511

Previous file position f_pos


(current file position)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pseudo character device memory access

After write of 2 bytes


0 1 2 3 4 5 6 7 8 …. 510 511
w w

Previous file position


f_pos
(current file position)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pseudo character device memory access

After lseek of -2 from current position

0 1 2 3 4 5 6 7 8 …. 510 511
w w

Previous file position


f_pos
(current file position)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pseudo character device memory access

EOF Scenario
0 1 2 3 4 5 6 7 8 …. 510 511 512
w w

f_pos
(current file position)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Data copying between Kernel space and user


space
Role of these two functions
• Copying data between user space and kernel
• copy_to_user() spae
• copy_from_user() • Check whether the user space pointer is valid or
not
• If the pointer is invalid, no copy is performed.
• if an invalid address is encountered during the
copy, only part of the data is copied. In both
cases, the return value is the amount of memory
still to be copied

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Destination Number of
address, bytes to copy
in user space.

Source address,
in kernel space

Returns 0 on success or number of bytes that could not be copied


If this function returns non zero value , you should assume that
there was a problem during data copy.So return appropriate
error code (-EFAULT)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Destination address, Number of


in kernel space bytes to copy

Source address,
in user space.
Returns 0 on success or number of bytes that could not be copied
If this function returns non zero value , you should assume that
there was a problem during data copy.So return appropriate
error code (-EFAULT)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

llseek Origin
Pointer of file object

Offset value

SEEK_SET The file offset is set to ‘off’ bytes.


SEEK_CUR The file offset is set to its current location plus ‘off’ bytes.
SEEK_END The file offset is set to the size of the file plus ‘off’ bytes.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Error codes and descriptions

include/uapi/asm-generic/errno-base.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

User buffer
Device memory write (memory of the
buffer Copy_from_user() process address
space )

Kernel space User space


(non swappable) (swappable)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Write method implementation

1) check the user requested ‘count’ value against DEV_MEM_SIZE of


the device .
• if current_file_position + count > MAX_SIZE
• Adjust the ‘count’ . count = MAX_SIZE - current_file_position
2) copy 'count' number of bytes from user buffer to device memory
3) Update the current_file_positon
4) Return number of bytes successfully written or error code

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

If whence = SEEK_SET
flip->f_pos = off

If whence = SEEK_CUR
flip->f_pos = flip->f_pos + off

if whence = SEEK_END
flip->f_pos = DEV_MEM_SIZE + off

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pseudo character driver with multiple devices

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Exercise
• Modify the previous pseudo character device driver to support
four pseudo character devices.
• Implement open, release, read, write, lseek driver methods to
handle user requests.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Driver Pcdev-1
pcdrv

Pcdev-2

Pcdev-4 Pcdev-3

• The driver, which we about to write, should manage 4 devices.


• There will be single driver managing 4 devices.
• There will be only 1 implementation of open, read, write, release, and lseek driver methods.
• That also means the driver should first determine which device is being accessed
from the user space to fulfill the request

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Driver Pcdev-1
pcdrv
/dev/pcdev-1

Pcdev-2

/dev/pcdev-2

Pcdev-3
Pcdev-4
/dev/pcdev-3
/dev/pcdev-4

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Private data of a device(Device-specific information)

A memory area Permission


Serial number Pcdev-x RDONLY
WRONLY
RDWR
Size

Start address

Every device has its own private data

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

echo “Good morning” > /dev/pcdev-1 echo “Good morning” > /dev/pcdev-3

/dev/pcdev-1 /dev/pcdev-2 /dev/pcdev-3 /dev/pcdev-4

-EPERM User space

Kernel space
Driver
pcdrv

A memory area A memory area A memory area A memory area


Pcdev-1 Pcdev-2 Pcdev-3 Pcdev-4
RDONLY WRONLY RDWR RDWR

Every device represents a unique memory area.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device - Driver data structure


In the driver, we’ll maintain two structures

Structure which holds Structure which holds


driver’s private data device’s private data

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Structure to represent device’s private data

A memory area Permission


Serial number Pcdev-x RDONLY
WRONLY
RDWR
Size

Start address

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Structure to represent driver’s private data

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pcdev-1 Pcdev-2 Pcdev-3 Pcdev-4

127:0 127:1 127:2 127:3

(4)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

#define O_ACCMODE 00000003


#define O_RDONLY 00000000
#define O_WRONLY 00000001
#define O_RDWR 00000002

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

container_of macro

/include/linux/kernel.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

container_of
• Container_of macro helps you to get the address of the containing
structure by taking an address of its member element .
• As its name indicates it gives you the “container” address of the
member element of a struct
• It takes three arguments – a pointer, type of the container, and
the name of the member the pointer refers to.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pointer to the member name of the member


the ‘ptr’ refers to

#define container_of ( ptr, type, member )

Type of the container struct in


which ‘member’ is embedded in

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Address of the
member element Name of the member
to which ‘ptr’ refers to

Structure type

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Memory plot of struct variable – data

a b c d

1by
te

0x100 0x104 0x108 0x10C 0x10F


&data &data.c &data.d
&data.b
&data.a
(container address)

Padding

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Member(c) offset from beginning

a b c d

1byte

0x100 0x104 0x108 0x10C 0x10F


&data &data.c &data.d
&data.b
&data.a
(container address)

&data.c – member_offset_from_beginning = &data Padding

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

linux/kernel.h

#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif

The macro offsetof() returns the offset of the field MEMBER from
the start of the structure TYPE

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

f_mode
• This is one of the fields of struct file defined in <linux/fs.h>
• you can check this field in your driver to understand access mode
requested from the user space application
• f_mode has bit fields to indicate access modes read or write . So, use
macros FMODE_READ and FMODE_WRITE to decode this field
(defined in <linux/fs.h>)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Decoding f_mode field

(filp->f_mode & FMODE_READ ) File is opened for just read or read-write

(filp->f_mode & FMODE_WRITE ) File is opened for just write or read-write

(filp->f_mode & FMODE_READ ) && ! (filp->f_mode & FMODE_WRITE )


File is opened for read-only

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Platform devices and drivers

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Platform devices and drivers

• Platform bus
• Platform devices
• Platform drivers

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Bus
• In computer science, a bus is a collection of electrical wirings which
transfers information (data or address or control ) between devices.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

What is a platform bus ?


• Platform bus is a term used by Linux device model to represent all
non-discoverable busses of an embedded platform.
• It is a pseudo bus or Linux’s virtual bus.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

PC Scenario L2
cache
System Memory
Processor D D D
cache Memory R R R
controller A A A
M M M

Bridge

PCI bus

SCSI Audio codec


USB host Ethernet External PCI controller
controller Controller interface
speaker
Disk
controller Audio codec
Printer keyboard PCI Bus

Wifi card Mic


Serial port Disk
card

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

An Embedded platform
MCU/SoC
Bus SRAM
Processor
matrix
FLASH
Temperature
Mic

AHB
RTC sensor Headset
LCD controller
GPIO
BRIDGE

I2C bus I2C I2S CODEC

GPS UART ETH Eth connector

APB

APB
MMC card bus
SDIO USB HUB
Flash drive
connector

ADC WDG
keyboard

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com
An Embedded platform
MCU/SoC
Bus SRAM
Processor
matrix
FLASH
Temperature
Mic

AHB
RTC sensor Headset
LCD controller
GPIO
BRIDGE

I2C bus I2C I2S CODEC

GPS UART ETH Eth connector

APB

APB
MMC card bus
SDIO USB HUB
Flash drive
connector

ADC WDG
keyboard

Non-Discoverable by themselves (platform devices )


Self Discoverable
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Platform bus
Processor

Platform bus

LCD On chip peripherals


GPIO I2C UART SDIO ADC I2S ETH USB WDG
controller

Dev-1 Dev-1

Dev-2

Off chip peripherals

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Embedded
Scenario-STM32

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Embedded Scenario-OMAP4460

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Embedded Scenario-AM335x

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Discovery of devices
• Every device has its configuration data and resources, which need to be reported to the OS,
which is running on the computer system.
• An operating system such as Windows or Linux, running on the computer, can auto-discover
these data. Thus the OS learn about the connected devices automatically (Device
enumeration )
• Enumeration is a process through which the OS can inquire and receive information, such as
the type of the device, the manufacturer, device configuration, and all the devices connected
to a given bus.
• Once the OS gathers information about a device, it can autoload the appropriate driver for
the device. In the PC scenario, buses like PCI and USB support auto enumeration/hotplugging
of devices.
• However, on embedded system platforms, this may not be the case since most peripherals
are connected to the CPU over buses that don’t support auto-discovery or enumeration of
devices. We call them as platform devices.
• All these platform devices which are non-discoverable by nature, but they must be part of the
Linux device model, so the information about these devices must be fed to the Linux kernel
manually either at compile time or at boot time of the kernel.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device information
1. Memory or I/O mapped base address and range information
2. IRQ number on which the device issues interrupt to the processor
3. Device identification information
4. DMA channel information
5. Device address
6. Pin configuration
7. Power , voltage parameters
8. Other device specific data

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Adding Platform devices information to the kernel


• During compilation of kernel
• Static method
• Hardware details are part of kernel files (board file , drivers)
• Deprecated and not recommended
• Loading dynamically
• As a kernel module
• Not recommended
• During kernel boot
• Device tree blob
• Latest and recommended

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Board file approach


• This method was used before the kernel version 3.7 to add hardware
configuration details to the kernel.
• Details about the onboard peripherals
• Pin configuration details
• You have to recompile the kernel if any device property changes
• All information about hardware configuration is hardcoded in the
kernel source files and board files.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device tree method


• The DT was originally created by Open Firmware as part of the
communication method for passing data from Open Firmware to a
client program (like to an operating system).
• An operating system used the Device Tree to discover the topology of
the hardware at runtime, and thereby support a majority of available
hardware without hard coded information (assuming drivers were
available for all devices).

https://www.kernel.org/doc/Documentation/devicetree/usage-model.txt

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Platform devices
• Devices which are connected to the platform bus are called platform
devices
• A device if its parent bus doesn’t support enumeration of connected
devices then it becomes a platform device

Platform driver
• A driver who is in charge of handling a platform device is called a
platform driver

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Examples of platform drivers

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

AM335X
block diagram

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

TI AM335x On-chip peripheral support drivers

Peripheral Location of the platform driver Description


SPI drivers/spi/spi-omap2-mcspi.c OMAP2 McSPI controller driver
I2C drivers/i2c/busses/i2c-omap.c TI OMAP I2C master mode driver
USB OTG drivers/usb/musb/musb_am335x.c musb controller
CAN drivers/net/can/c_can/c_can_platform.c Platform CAN bus driver for Bosch
C_CAN controller
MMC drivers/mmc/host/omap_hsmmc.c Driver for OMAP2430/3430 MMC
controller.
GPIO drivers/gpio/gpio-omap.c Support functions for OMAP GPIO
UART drivers/tty/serial/8250/8250_omap.c 8250-core based driver for the
OMAP internal UART
LCD controller drivers/gpu/drm/tilcdc/tilcdc_drv.c LCDC DRM driver, based on
da8xx-fb
Touch screen drivers/input/touchscreen/ti_am335x_tsc.c TI Touch Screen driver
controller

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Registering platform device and driver

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Registering a platform driver


Use this ‘C’ macro to register your platform driver with the Linux platform core

/include/linux/platform_device.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Platform driver structure

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Registering a platform device

(Deprecated)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Platform device structure

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Platform device – driver matching

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Now you understood,


How to register a platform device and platform driver with the Linux kernel.
Now let's attend a very important question.
How does the driver know that you have added exactly the same device
which the driver is looking for so that it can configure the device?
Or
How do you make the correct driver gets autoloaded whenever you add the
new platform device?

The answer is due to the "matching" mechanism of the bus core

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Add new platform


driver

Platform Bus
(Linux platform core)

Device list Driver list Add new platform


Device
p.dev-1 p.drv-1

p.dev-2 p.drv-2

p.dev-3 p.drv-3
The Linux platform core implementation
maintains platform device and driver lists.
Whenever you add a new platform device or
driver, this list gets updated and matching
Every bus type has its match function, where mechanism triggers.
the device and driver list will be scanned.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

A simple “name” based matching

Add new platform device


p.dev-1

Platform Bus
Device list Driver list

p.dev-1 p.drv-1 (.name = “xyz”)


(.name = “abc”) p.drv-2 (.name = “nmo”)
p.drv-3 (.name = “abc”)
Match detected . Probe
method of this driver will get
called with pdev-1 as an
argument
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Add new platform driver


A simple “name” based
p.drv-1
matching

Platform Bus

Device list Driver list

(.name = “abc”) p.dev-1 p.drv-1

(.name = “xyz”) p.dev-2 p.drv-2

(.name = “nmo”) p.dev-3 p.drv-1 (.name = “xyz”)

Match detected . Probe method


of this driver will called with
pdev-2 as argument
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Points to remember
• Whenever a new device or a new driver is added, the matching
function of the platform bus runs, and if it finds a matching platform
device for a platform driver, the probe function of the matched driver
will get called. Inside the probe function, the driver configures the
detected device.
• Details of the matched platform device will be passed to the probe
function of the matched driver so that driver can extract the platform
data and configure it.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Platform driver structure

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Probe function of the platform driver


• Probe function must be implemented by the platform driver and should be registered during
platform_driver_register().
• When the bus matching function detects the matching device and driver, probe function of the driver
gets called with detected platform device as an input argument
• Note that probe() should in general, verify that the specified device hardware actually exists.
Sometimes platform setup code can't be sure. The probing can use device resources, including clocks,
and device platform_data.
• The the probe function is responsible for
• Device detection and initialization
• Allocation of memories for various data structures,
• Mapping i/o memory
• Registering interrupt handlers
• Registering device to kernel framework, user level access point creations, etc
• The probe may return 0(Success) or error code. If probe function returns a non-zero value, meaning
probing of a device has failed.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Remove function of the platform driver


• Remove function gets called when a platform device is removed from
the kernel to unbind a device from the driver or when the kernel no
longer uses the platform device
• Remove function is responsible for
• Unregistering the device from the kernel framework
• Free memory if allocated on behalf of a device
• Shutdown/De-initialize the device

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Other methods of platform driver


Called at shut-down time to quiesce the device

Called to put the device to sleep mode.


Called to bring a device from sleep mode Usually to a low power state

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

For more info


• https://www.kernel.org/doc/Documentation/driver-model/platform.txt

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Platform driver essential methods

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

module_platform_driver(__platform_driver);

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Include/linux/platform_device.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Code exercise:
Implementation of pseudo character driver as platform driver

• Repeat the exercise pseudo character driver with multiple devices as


a platform driver.
• The driver should support multiple pseudo character devices(pcdevs)
as platform devices
• Create device files to represent platform devices
• The driver must give open, release, read, write, lseek methods to
deal with the devices

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Add new platform


driver

Platform Bus
(Linux platform core)

Device list Driver list Add new platform


Device
Pcdev-1 pcdrv

Pcdev-2

Pcdev-3

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Implementation

Platform driver Platform device setup

Kernel module-1 Kernel module-2

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Platform device release function

• Callback to free the device after all references have gone away.
• This should be set by the allocator of the device

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Platform device setup


1. Create 2 platform devices and initialize them with required
information
1. Name of a platform device
2. Platform data
3. Id of the device
4. Release function for the device
2. Register platform devices with the Linux kernel

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Matching of platform driver and device


using platform device ids

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Use case : Different versions of a chip


Different version of a temperature sensing chip

TS-A1x TS-B1x TS-C1x

Config items of Config items of Configuration items the


Config items of
TS-B1x TS-C1x driver uses to configure the
TS-A1x
matched platform device

TS-A1x
Platform driver must support
TS-B1x
different device ids
TS-C1x

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Modify the pcd platform driver to support different version of pcdevs

pcdev-A1x pcdev-B1x pcdev-C1x

Config items of Config items of Config items of


pcdev-A1x pcdev-B1x pcdev-C1x

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device tree

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device tree
• Introduction to the device tree
• Device tree structure
• Example of a device node
• properties of device trees
• Device tree overlays

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

What is device tree(DT) ?

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

What is device tree?


• The "Open Firmware Device Tree", or simply Device Tree (DT), is a data exchange format
used for exchanging hardware description data with the software or OS.

• More specifically, it is a description of hardware that is readable by an operating system so


that the operating system doesn't need to hard code details of the machine.

• In short, it is a new and recommended way to describe non-discoverable devices(platform


devices) to the Linux kernel, which was previously hardcoded into kernel source files.

Source :
Documentation/devicetree/usage-model.txt

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device tree
• An operating system uses the Device Tree to discover the topology of
the hardware at runtime, and thereby support a majority of available
hardware without hardcoded information (assuming drivers were
available for all devices)

• The most important thing to understand is that the DT is simply a


data structure that describes the hardware. There is nothing magical
about it, and it does not magically make all hardware configuration
problems go away.
Source :
Documentation/devicetree/usage-model.txt

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device tree
• DT provides a language for decoupling the hardware configuration
from the device driver and board support files of the Linux kernel (or
any other operating system for that matter).
• Using it allows device drivers to become data-driven. To make setup
decisions based on data passed into the kernel instead of on per-
machine hardcoded selections.
• Ideally, a data-driven platform setup should result in less code
duplication and make it easier to support a wide range of hardware
with a single kernel image.

Source :
Documentation/devicetree/usage-model.txt
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Why DT is used ?
Linux uses DT for,
• Platform identification
• Device population:
• The kernel parses the device tree data and generates the
required software data structure, which will be used by the
kernel code.

Ideally, the device tree is independent of any os; when you


change the OS, you can still use the same device tree file to
describe the hardware to the new OS. That is, the device tree
makes “adding of device information “ independent of OS

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

More reading
• https://elinux.org/Device_Tree_What_It_Is
• https://www.kernel.org/doc/Documentation/devicetree/usage-
model.txt

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Writing device tree

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device tree specification


• You can get the full specification here
• https://www.devicetree.org/

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Writing device tree


• The device tree supports a hierarchical way of writing hardware description at the
soc level, common board level, and board-specific level. Most of the time, writing a
new device tree is not difficult, and you can reuse most of the common hardware
information from the device tree file of the reference board.

• For example, when you design a new board, which is slightly different from another
reference board, then you can reuse the device tree file of the reference board and
only add that information which is new in your custom board.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Describing hardware hierarchy


• It comes at various level because the board has many device blocks
• SOC
• SOC has an on-chip processor and on-chip peripherals
• The board also has various peripherals onboard, like sensors, LEDs, buttons,
joysticks, external memories, touchscreen, etc

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

3G/4G
Wifi keypad LCD+tsc
modem

Connectors
USB
LED0 HOST
Ethernet JTAG
LED1
LED2
SOC
DDR3
USER BTN
DC
power

Connectors

Ext SD CAN
AV
memory connector TXRX

An Embedded Board

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

3G/4G
Wifi keypad LCD+tsc
modem

Connectors
USB
LED0 HOST
Ethernet JTAG
LED1
LED2
SOC
DDR3
USER BTN
DC
power

Connectors

Ext SD CAN
AV
memory connector TXRX

An Embedded Board

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Modular approach to manage DT files

SOC specific device tree file


AM335x (This DT file is used as an include file
(Device tree file 1) and can be used with another board
which is based on same SOC )

Includes

AM335x Evaluation Module Board specific device tree file


(Device tree file 2)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Modular approach to manage DT files

AM335x dtsi

Beagle bone common


dtsi

Beaglebone black Beaglebone green


common dtsi common dtsi

Beaglebone black Beaglebone green


Beaglebone black Beaglebone Green
wireless dts dts wireless dts
dts

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Overview of device tree structure

✓Device tree is a collection of device nodes


✓A ‘device node’ or simply called ‘a node’ represents a device. Nodes are
organized in some systematic way inside the device tree file.
✓They also have parent and child relationship, and every device tree must
have one root node
✓A node explains itself, that is, reveals its data and resources using its
“properties.”

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

/ {
Node-1 {
a-string-property = "A string";
A-32-bit-integer-property = <800>;
string-list-property = “1ststring”,2ndstring”;
Child-Node-1 {
byte-array-property = <0x30 0x20 0xFE 0x10>;
};
};
Node-2 {

A-Boolean-property;
Child-Node-1 {
};
Child-Node-2 {
};
};
};
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Root node
• The device tree has a single root node of which all other device nodes
are descendants. The full path to the root node is /.
• All device trees shall have a root node, and the following nodes shall
be present at the root of all device trees:
• One /CPUs node
• At least one /memory node

Chapter 3 :DEVICE NODE REQUIREMENTS


Devicetree Specification Release v0.3a

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Summary
• Remember that you most probably be writing device tree addons or
overlays for your board-related changes but not for entire soc.
• The soc specific device tree will be given by the vendor in the form of
device tree inclusion file (.dtsi ) and you just need to include that in
your board-level device tree
• Follow modulatory approach while writing device tree

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device tree modularity

AM335x dtsi

Beagle bone common


dtsi

Beaglebone black Beaglebone green


common dtsi common dtsi

Beaglebone black Beaglebone green


Beaglebone black Beaglebone Green
wireless dts dts wireless dts
dts

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device tree writing syntax


• Node name
• Node Label
• Standard and non-standard property names
• Different data type representation (u32, byte, byte stream, string,
stream of strings, Boolean, etc

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Node name

• Refer device tree specification Release v0.3 from devicetree.org

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

0xFFFF_FFFF

0x4802_a000 I2c-1_register_0

I2C-0 Register set in the memory map Memory map of the SOC

0x44e0_bffC I2c-0_register_n

0x44e0_b008 I2c-0_register_2 0x1000


0x44e0_b004 I2c-0_register_1 Bytes
I2c-0_register_0 (4KB)
0x44e0_b000

0x0000_0000
32bits

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Parent and child nodes

I2c controllers of the SOC


CPU I2c addr = 0x24
I2C-0
I2C bus Power Management
TPS65217C IC (PMIC)

I2C-1
AM33xx SOC
eeprom
I2c addr = 0x50
32KB EEPROM is provided on I2C0
that holds the board information

Beagle Bone Black board

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

/ {
Parent
i2c0: i2c@44e0b000 {
I2c addr = 0x24

I2C-0 Power Child-1


TPS65217C Management
tps {
IC (PMIC)

};

Child-2 eeprom {
eeprom
};
I2c addr = 0x50
32KB EEPROM is provided on
I2C0 that holds the board
};
information

};

Explaining hardware details via device tree nodes

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Example from bbb

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

am33xx.dtsi
am335x-bone-common.dtsi BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Key points
• Node name is in the format node-name@unit-address
• This combination differentiates the node from other nodes at the
same level in the tree
• To write the “node-name” alphabet (stick to lower case), and number
combinations are allowed. So choose an appropriate name , it would
be good if it represents the general class of a device like serial, i2c,
led, etc
• The unit-address must match the first address specified in the reg
property of the node. If the node has no reg property, the @unit-
address must be omitted

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

PCD example

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Driver Pcdev-1
pcdrv

Pcdev-2

Pcdev-3
Pcdev-4 Size
device-serial-num
Perm
Properties

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Properties

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

What is a property ?
Property name(key) Value

A single property

Properties

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Different types of properties


• Standard property
• Custom property (non-standard )
• Standard properties are those which is explained by the specification
and the device-driver binding documentation
• Custom properties are specific to a particular vendor or organization
which is not documented by the specification.
• That is why, when you use custom property, always begin with your
organization name.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

• Lets check the specification to view some properties

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

'compatible' property

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Property :compatible
compatible = <string-list>
property name(Standard ) Value type

e.g. :
compatible = “string1” , “string2” , “string3”;
• Compatible property of a device node is used by the Linux kernel to match
and load an appropriate driver to handle that device node (driver
selection)
• The string list provided by the compatible property is matched against the
string list supported by the driver. If the kernel finds any match, the driver
will be loaded, and probe function is invoked

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Root compatible property of BBB

/ {
model = "TI AM335x BeagleBone Black";
compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";

}; Sorted string list from most compatible to least.

Root compatible property is used for machine identification

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Root compatible property of beaglebone bone black

/ {
model = "TI AM335x BeagleBone Black";
compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";

};
It claims that, this is an
exact compatible name
of the board for kernel to support it
It claims that, it is also compatible
It claims that, it is also compatible with
with kernel which supports only
kernel which supports bone devices
am33xx soc based board, if kernel
The machine identification fails when based on am335x, if the kernel doesn’t
doesn’t support previous options.
none of these string values matches with support previous exact model.
kernel supported compatible machine
identification string-list.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Uses of compatible property


1. Machine identification and initialization
2. Match and load the appropriate driver for the device

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device tree bindings


• How do you know which property name and value pair should be
used to describe a node in the device tree?
• Device tree binding document. The driver writer must document these details
• The properties that are necessary to describe a device in the device
tree depends on the requirements of the Linux driver for that device
• When all the required properties are provided, the driver of charge
can detect the device from the device tree and configure it.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Note:
• Compatible strings and properties are first defined by the client
program (OS , drivers ) then shared with DT writer

Driver
DT implementation
implementation

Driver decides DT writer refers to the binding


compatible strings and document and initializes
documents in device relevant values for the
tree binding document compatible property

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Some examples of device and driver binding


• Example of lm75
• mpu 6050

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device tree bindings documentation


• All device tree binding document can be found here
https://www.kernel.org/doc/Documentation/devicetree/bindings/

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device tree bindings- points to remember


• Case 1 : When the driver is already available in the Linux kernel for
the device ‘x,’ but you just need to add device ‘x’ entry in the device
tree then you must consult ‘x’ drivers binding document which guides
you through creating device tree node for device ‘x.’
• Case 2 : When the driver is not available for the device ‘x,’ then you
should write you own driver, you should decide what properties to
use (could be a combination of standard and non-standard property ),
you should then provide the device tree binding document describing
what are all the properties and compatible strings a device tree write
must include.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Linux conventions to write device tree


• hex constants are lower case
• use "0x" instead of "0X"
• use a..f instead of A..F, eg 0xf instead of 0xF
• node names
• should begin with a character in the range 'a' to 'z', 'A' to 'Z'
• unit-address does not have a leading "0x" (the number is assumed to be hexadecimal)
• unit-address does not have leading zeros
• use dash "-" instead of underscore "_"
• label names
• should begin with a character in the range 'a' to 'z', 'A' to 'Z'
• should be lowercase
• use underscore "_" instead of dash "-"
• property names
• should be lower case
• should begin with a character in the range 'a' to 'z'
• use dash "-" instead of underscore "_"

https://elinux.org/Device_Tree_Linux#Linux_vs_ePAPR_Version_1.1
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

pcdev properties
org,size = <512> ; //this is a non standard property and represents integer data ;
org,device-serial-num = “PCDEV1ABC123” ; //this is a non standard property and
represents string data
org,perm = <0x11> ; //this is a non standard property and represents integer data

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

struct platform_device

struct platform_device

struct platform_device

struct platform_device

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

platform_device

In Linux every device is


represented by an instance of
Struct device
struct device.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com Struct platform_device

Struct device

Struct device_node

associated device tree node


of_node
For every device node struct
device_node represents details
of the device node
Struct fwnode_handle
firmware device node
fwnode

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Functions to interpret device tree nodes


• Refer : include/linux/of.h
• Procedures for creating, accessing and interpreting the device tree
• Linux/drivers/of/base.c

/*associated device tree node */


struct device_node *np = dev->of_node;
int size;

if(of_property_read_u32(np,"fb,size",&size)){
dev_info(dev,"Missing size property\n");
return -EINVAL;
}

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

i2c@3000 {
#address-cells = <1>;
#size-cells = <0>;
cell-index = <0>;
we can make the following observations about this example node:
compatible = "fsl-i2c";
• The I2C controller is located at offset 0x3000 from its parent.
reg = <0x3000 0x100>;
• The driver for the I2C controller is fsl-i2c.
interrupts = <43 2>;
• The first child is named dtt, at offset 0x48 from its parent; the
interrupt-parent = <&mpic>;
driver is national lm75.
dfsrr;
• The second child is named rtc, at offset 0x68 from its parent; the
dtt@48 {
driver is Dallas ds1337.
compatible = "national,lm75";
reg = <0x48>;
};
rtc@68 {
compatible = "dallas,ds1337";
reg = <0x68>;
};
};

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Platform_device
i2c@3000 {
#address-cells = <1>;
#size-cells = <0>; Device
cell-index = <0>;
compatible = "fsl-i2c";
reg = <0x3000 0x100>; Associated Device node(of_node)
interrupts = <43 2>; device tree
interrupt-parent = <&mpic>; node
child
dfsrr;
Associated
dtt@48 {
device tree
compatible = "national,lm75"; Device_node
node
reg = <0x48>;
};
rtc@68 { Sibling
Associated
compatible = "dallas,ds1337";
device tree
reg = <0x68>; Device_node
node
};
};

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device node
struct device_node {
const char *name;
phandle phandle;
const char *full_name;
struct fwnode_handle fwnode;

structproperty *properties;
structproperty *deadprops;/* removed properties */
structdevice_node *parent;
structdevice_node *child;
structdevice_node *sibling;
#if defined(CONFIG_OF_KOBJ)
structkobject kobj;
#endif
unsigned long _flags;
void*data;
#if defined(CONFIG_SPARC)
unsigned int unique_id;
struct of_irq_controller *irq_trans;
#endif BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
};
www.fastbitlab.com

Property
struct property {
Char *name;
Int length;
Void *value;
struct property *next;
#if defined(CONFIG_OF_DYNAMIC) ||
defined(CONFIG_SPARC)
unsigned long _flags;
#endif
#if defined(CONFIG_OF_PROMTREE)
unsigned int unique_id;
#endif
#if defined(CONFIG_OF_KOBJ)
struct bin_attribute attr;
#endif
};
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Get driver data from matched device

void *of_device_get_match_data(const struct device *dev);

include/linux/of_device.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

CONFIG_OF configuration item


• In Linux, CONFIG_OF configuration item decides Device Tree and
Open Firmware support
• If CONFIG_OF is not enabled, Linux doesn’t support hardware
enumeration via device tree.
• All device tree processing functions which begin with of_* will be
excluded from the kernel build
• For latest kernel this configuration item is enabled by default

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

//if CONFIG_OF enabled


#define of_match_ptr(_ptr) (_ptr)

//if CONFIG_OF disabled

#define of_match_ptr(_ptr) NULL

Include/linux/of.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device tree overlays

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device tree overlays


DT overlays are device tree patches(dtbo) which are used to patch or
modify the existing main device tree blob(dtb)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

am335x-boneblack.dtb
( This is board specific. This explains the
hardware topology of the board )

BBB LCD cape


BBB
The main dtb doesn’t include the hardware
details (device nodes, properties , pin configs)
to configure the cape.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Two ways you can include the device nodes for the cape device in the
main dtb
1.Edit the main dtb itself (not recommended )
2.Overlay( a Patch which overlays the main dtb) (recommended )

Uses of overlays
1)To support and manage hardware configuration (properties, nodes, pin
configurations ) of various capes of the board
2)To alter the properties of already existing device nodes of the main dtb
3)Overlays approach maintains modularity and makes capes management easier

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

The main dtb doesn’t include the hardware


details (device nodes, and properties ) to
configure the cape.

BBB LCD cape


BBB
I2c-touch-lcd.dts( this is overlay source file )
am335x-boneblack.dtb ( I2c-touch-lcd.dtbo(.dtbo indicates that this is a
this is board specific. this overlay which should be used with this LCD)
explains the hardware
topology of the board )
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Overlay DTS Format


• Refer
https://www.kernel.org/doc/Documentation/devicetree/overlay-
notes.txt

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

+ =

/dts-v1/; ➔ Indicates DTS file version


/plugin/; → Indicates it’s a plugin (an overlay)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

DT Overlay exercise
Write a device tree overlay to disable/modify pcdev device nodes from
the main dts
STEPS
1. Create a device tree overlay file and add fragments to modify the
target device nodes
2. Compile the device tree overlay file to generate .dtbo file (Device
tree overlay binary)
3. Make u-boot to load the .dtbo file during board start-up

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Overlay compilation
• Make sure that device tree compiler(dtc) is installed on your system
• Run the below command to generate .dtbo from .dts file
dtc -O dtb -o <output-file-name> -I <input-file-name>

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kernel memory allocation APIs


• kmalloc ()
• kfree ()

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

void* kmalloc( size_t size, gfp_t flags);


include/linux/slab.h

Used to allocate memory in kernel space by drivers and kernel functions


Memory obtained are physically(RAM) contiguous

From the kernel documentation:


“ The maximal size of a chunk that can be allocated with kmalloc is limited. The actual limit depends
on the hardware and the kernel configuration, but it is a good practice to use kmalloc for objects
smaller than page size “
Page size = 4KiB ( 4 * 1024 Bytes)

flags : changes the behaviour of the underlying memory allocator

return = NULL if allocation fails, on success virtual address of the first page allocated

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com
/**
* kmalloc - allocate memory
* @size: how many bytes of memory are required.
* @flags: the type of memory to allocate.
*
* kmalloc is the normal method of allocating memory
* for objects smaller than page size in the kernel.
*
* The allocated object address is aligned to at least ARCH_KMALLOC_MINALIGN
* bytes. For @size of power of two bytes, the alignment is also guaranteed
* to be at least to the size.
*
* The @flags argument may be one of the GFP flags defined at
* include/linux/gfp.h and described at
* :ref:`Documentation/core-api/mm-api.rst <mm-api-gfp-flags>`
*
* The recommended usage of the @flags is described at
* :ref:`Documentation/core-api/memory-allocation.rst <memory-allocation>`
*
* Below is a brief outline of the most useful GFP flags

include/linux/slab.h
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

/*
*%GFP_KERNEL : Allocate normal kernel ram. May sleep.
*%GFP_NOWAIT : Allocation will not sleep.
*%GFP_ATOMIC Allocation will not sleep. May use emergency pools.
*%GFP_HIGHUSER Allocate memory from high memory on behalf of user.
*
* Also it is possible to set different flags by OR'ing
* in one or more of the following additional @flags:
*
* %__GFP_HIGH This allocation has high priority and may use emergency pools.
* %__GFP_NOFAIL Indicate that this allocation is in no way allowed to fail
*(think twice before using).
* %__GFP_NORETRY If memory is not immediately available, then give up at once.
* %__GFP_NOWARN If allocation fails, don't issue any warnings.
* %__GFP_RETRY_MAYFAIL Try really hard to succeed the allocation but fail
eventually.
*/
include/linux/slab.h
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Usage
struct bar *k;
k = kmalloc(sizeof(*k), GFP_KERNEL);
if (!k)
return -ENOMEM;

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

kfree
/**
* kfree - free previously allocated memory
* @objp: pointer returned by kmalloc.
*
* If @objp is NULL, no operation is performed.
*
* Don't free memory not originally allocated by kmalloc()
* or you will run into trouble.
*/
void kfree(const void *objp);

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kmalloc and friends


• kmalloc_array()
• kcalloc()
• kzalloc()
• krealloc()

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kzalloc is preferred over kmalloc


/**
* kzalloc - allocate memory. The memory is set to zero.
* @size: how many bytes of memory are required.
* @flags: the type of memory to allocate (see kmalloc).
*/
void *kzalloc(size_t size, gfp_t flags);

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

struct bar { void bar_processing_fun(struct bar *pbar)


int a ; {
int b; if(! (pbar->name) )
char *name; //allocate memory for ‘name’
} else
//memory for ‘name’ is already allocated
struct bar *pbar;
/* This may crash if pbar->name is not a valid pointer */
pbar = kmalloc( sizeof(*pbar) , GFP_KERNEL); memcpy(pbar->name, “name”,5);

bar_processing_fun(pbar); }

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

kzfree
/**
* kzfree - like kfree but zero memory
* @p: object to free memory of
*
* The memory of the object @p points to is zeroed before freed.
* If @p is %NULL, kzfree() does nothing.
*
* Note: this function zeroes the whole allocated buffer which can be a good
* deal bigger than the requested buffer size passed to kmalloc(). So be
* careful when using this function in performance sensitive code.
*/
void kzfree(const void *p);

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

/**
* krealloc - reallocate memory. The contents will remain unchanged.
* @p: object to reallocate memory for.
* @new_size: how many bytes of memory are required.
* @flags: the type of memory to allocate.
*
* The contents of the object pointed to are preserved up to the
* lesser of the new and old sizes. If @p is %NULL, krealloc()
* behaves exactly like kmalloc(). If @new_size is 0 and @p is not a
* %NULL pointer, the object pointed to is freed.
*
* Return: pointer to the allocated memory or %NULL in case of error
*/

void *krealloc(const void *p, size_t new_size, gfp_t flags);

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Resource managed kernel APIs


kmalloc() //This allocates a resource ( kernel memory)

devm_kmalloc() //This also allocates a resource but it “remembers”


what has been allocated. (This is resource managed API)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

(platform device)

Struct device

Memory is allocated
on behalf of this
device

kmalloc(); devm_kmalloc();
Programmer must Programmers using kfree() is not required.
free the memory Kernel will take care of freeing memory
using kfree(); when the “device” or managing “driver”
gets removed from the system

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Examples
Kmalloc() devm_kmalloc()
Kfree()

gpiod_get() devm_gpiod_get()
gpiod_put()

request_irq() devm_request_irq()
free_irq()

https://www.kernel.org/doc/Documentation/driver-model/devres.txt
Refer to this link to check all resource managed kernel apis

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Probe function

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

remove function

When you use devm_kamalloc() to allocate the memory


in “probe” function, using kfree() in remove function is
no longer required

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Linux Device model

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

• Linux device model is nothing but a collection of various data


structures , and helper functions that provide a unifying and
hierarchical view of all the busses, devices, drivers present on the
system. You can access the whole Linux device and driver model
through a pseudo filesystem called sysfs. Which is mounted at /sysfs.
• Different components of the Linux device model is represented as
files and directories through sysfs
• Sysfs exposes underlying bus, device, and driver details and their
relationships in the Linux device model.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Components of the device model


• Device struct device
• Device driver struct device_driver
• Bus struct bus_type
• Kobject struct kobject
• Ksets struct kset
• Kobject type struct kobj_type

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device and Driver representation


• Definition of a device
• Under Linux device driver model, anything which can be represented by an
instance of the data structure struct device is a device
• Definition of a driver
• Anything which can be represented by an instance of the data structure struct
device_driver is a driver

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Example
Consider the case of a platform device

CPU

Platform bus

Platform
device It’s a device and it’s device type is “ platform device”
(ADC) because it is hanging on platform bus type

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Include/linux/device.h

• At the lowest level, every device in a Linux system is


represented by an instance of struct device

• The device structure contains the information that the device


model core needs to model the system

• Most subsystems, however, track additional information about


the devices they host. As a result, it is rare for devices to be
represented by bare device structures; instead, that structure,
like kobject structures, is usually embedded within a higher-
level representation of the device

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Struct platform_device

Subsystem specific
information

struct device
Device specific
information

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

associated device tree node

parent bus_type
Struct device

device_driver

driver_data platform_data

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Example
Consider the case of a platform device .

CPU

I2C Bus

I2C client
device It’s a device and it’s device type is “ i2c client”
(RTC) because it is hanging on i2c bus type

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

An i2c_client identifies a single device (i.e. chip) connected to an i2c bus.


The behaviour exposed to Linux is defined by the driver managing the device.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Struct i2c_client

I2c specific information

struct device

Device specific
information

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

CPU

Platform bus

Struct platform_device I2c host controller on chip device

I2C Bus

I2C client
device It’s a device and it’s device type is “ i2c client”
Struct i2c_client
(RTC) because it is hanging on i2c bus type
Off chip device

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Struct platform_driver Struct i2c_driver

Platform specific information I2c specific information

struct device_driver struct device_driver

Device specific Device specific


information information

Each driver of the system is represented in the Linux device driver model as an object of struct device_driver

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

The shutdown, suspend, and resume methods


are invoked on a device when the kernel must
change its power state.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kobject
• Kobject stands for kernel object which is represented by struct kobject
• Kobjects are a fundamental building block of Linux device and driver
hierarchy
• Kobjects are used to represent the ‘containers’ in the sysfs virtual
filesystem
• Kobjects are also used for reference counting of the ‘containers’.
• It has got its name, type, and parent pointer to weave the Linux device and
driver hierarchy
• Using kobjects you can add attributes to the container, which can be
viewed/altered by the user space.
• The sysfs filesystem gets populated because of kobjects, sysfs is a user
space representation of the kobjects hierarchy inside the kernel

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Include/kobject.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

What are containers ?


• Kobjects are rarely or never used as stand-alone kernel objects. Most of
the time, they are embedded in some other structure that we call
container structure, which describes the device diver model's components.
• Some example of container structure could be struct bus, struct device,
struct device_driver
• The container structure's embedded kobject enables the container to
become part of an object hierarchy.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

struct kobject {
const char *name;
struct list_head entry;
struct kobject *parent; struct kref {
struct kset *kset; refcount_t refcount;
struct kobj_type *ktype; };
/* sysfs directory entry */
struct kernfs_node *sd; Kobject reference counter
struct kref kref;
unsigned int state_initialized:1;
unsigned int state_in_sysfs:1;
unsigned int state_add_uevent_sent:1;
unsigned int state_remove_uevent_sent:1;
unsigned int uevent_suppress:1;
};

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

struct kobject {
const char *name;
struct list_head entry;
struct kobject *parent;
struct kset *kset;
struct kobj_type *ktype;
/* sysfs directory entry */
struct kernfs_node *sd;
struct kref kref;
unsigned int state_initialized:1;
unsigned int state_in_sysfs:1;
unsigned int state_add_uevent_sent:1;
unsigned int state_remove_uevent_sent:1;
unsigned int uevent_suppress:1;
};

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device type
Struct platfrom_device

struct device
Container

Embedded kobject
kobj
Reference counter
kref

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kobject type and kset

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kobject type
• Type of a kobject is determined based on, type of the container in
which the kobject is embedded

struct device struct device struct device struct device

kobject kobject kobject kobject

All these kobjects are of same type

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

struct kobj_type (ktype)


Now, the type of a kobject is controlled using the structure called struct kobj_type

Struct kobj_type

struct device
This structure is used to define the
default behavior(e.g. attributes ) for a
kobject group of kobjects of same container
ktype type

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Struct kobj_type
• struct kobj_type object or simply ktype object is an object which
defines the behavior for the container object.
• Behaviors are manifested in terms of attributes and file operation
methods that handle those attributes.
• The ktype also controls what happens to the kobject when it is
created and destroyed.
• Every structure that embeds a kobject needs a corresponding ktype.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Instead of each kobject defining its own behavior, the


behavior is stored in a ktype, and kobjects of the same
“type” point at the same ktype structure, thus sharing
the same behavior.

kype

struct device struct device struct device struct device

kobject kobject kobject kobject


ktype ktype ktype ktype

All these kbojects are of same type

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

struct kobject {
const char *name;
struct list_head entry;
struct kobject *parent; If you want to assign a type to your kobject , then you have to
struct kset *kset; create an object of type ‘struct kobj_type’ and initialize the
struct kobj_type *ktype; ‘ktype’ field of the kobject.
/* sysfs directory entry */
struct kernfs_node *sd;
struct kref kref;
unsigned int state_initialized:1;
unsigned int state_in_sysfs:1;
unsigned int state_add_uevent_sent:1;
unsigned int state_remove_uevent_sent:1;
unsigned int uevent_suppress:1;
};

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

each kobject doesn't have its own release


method.
release method provided by kobj_type
object.

void my_object_release(struct kobject *kobj)


{
struct my_object *mine = container_of(kobj, struct my_object, kobj);
/* Perform any additional cleanup on this object, then... */
kfree(mine);
}

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

sysfs_ops points to sys operation structure which lists the


methods to operate on the default attributes created for the
kobject of this ktype

The default_attrs pointer is a list of default attributes that will be


automatically created for any kobject that is registered with this
ktype.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Kset
• Kset as its name indicates it’s a set of kobjects of same type and
belongs to a specific subsystem.
• Basically kset is a higher-level structure which ‘collects’ all lower level
kobjects which belong to same type

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

kobject kobject kobject kobject


parent parent parent parent

The directory associated with a


kobject always appears in the Kobj. parent
directory of the parent kobject Kset object

The list field is the head of the doubly linked


circular list of kobjects included in the kset

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Linux device driver model hierarchy

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device type
Struct platfrom_device

struct device
Container

Embedded kobject
kobj
Reference counter
kref

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Linux device driver model hierarchy


subsystem kset

kobject kobject kobject


kobject kobject kobject
kobject kobject kobject
kobject kobject kobject
kobject kobject kobject
kobject kobject kobject
kobject kobject kobject
kobject kobject kobject
kobject kobject kobject
kobject kobject

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

kobject

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Different bus_types
(bus subsystems)

Device and drivers attached


to an i2c bus type

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

bus_type (subsystem) subsystem


kset

kobjects

kset
kobject
Attribute

Attribute
Attribute

kobject
Attribute
kobject
Attribute

kobject
Attribute
kobject

Attribute

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Sysfs and creating kobject attributes

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

What is sysfs ?
Sysfs is a virtual in-memory file system which provides
1. Representation of the kobject hierarchy of the kernel.
2. The complete topology of the devices and drivers of the system in
terms of directories and attributes.
3. Attributes to help user space application to interact with devices
and drivers
4. Standard methods to access devices using ‘classes’

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Using sysfs
• sysfs is always compiled in if CONFIG_SYSFS is defined
• You can access it by doing mount -t sysfs sysfs /sys
• Documentation :
https://www.kernel.org/doc/Documentation/filesystems/sysfs.txt

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Creating kobject attributes of the


device/driver (sysfs attributes )
What is a kobject attribute?
kobject attributes are regular files or symbolic names that appear in
sysfs’s kobject directory, and they are used to expose details about
kobject’s “container” to user-space.

In short kobject attributes are files trough which device/driver data


can be exposed to sysfs so that user application can view or modify.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

kobject

Attribute Symbolic link to the parent device


Attribute
kobject
Attribute

Attribute

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

kobject kobject

Attribute

Attribute
Attribute

Attribute

Attribute

Attribute

Attribute
Attribute

Attribute

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Exercise : Creating custom attributes of a device

Create 2 sysfs attributes :


1) max_size ( world-read/owner-write)
Through this attribute user reads or changes the value of ‘size’ information
2) serial_num (world-read)
Through this attribute user just reads the serial number of the device

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Creating sysfs attributes


• sysfs atttributes are represented by the below structure
struct attribute Name of the attribute. This name will show in the sysfs
{ kobject directory as attribute’s name
const char *name;
umode_t mode;
#ifdef CONFIG_DEBUG_LOCK_ALLOC This controls the read/write permission for the
boolignore_lockdep:1; attribute file from user space programs
struct lock_class_key*key;
struct lock_class_keyskey;
#endif
};

Include/linux/sysfs.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Creating 2 device attributes


1) Create max_size attribute with mode ‘world-read and only owner
change’ (S_IRUGO|S_IWUSR)
2) Create serial_number attribute with mode ‘world-read-only’
(S_IRUGO )

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Mode of an attribute
• S_IRUGO – world-read-only
• S_IRUSR – owner read-only
• S_IRUGO | S_IWUSR : world-read and only owner write

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

APIs for managing sysfs files (Attributes)

include/linux/sysfs.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

file I/O operations on sysfs attributes


• Once you create a sysfs files (attributes), you should provide read and
write methods for them so that user can read value of the attribute or
write a new value to the attribute .
• If you see struct attribute there is no place to hook read/write
methods for an attribute. Basically it just represents name of a
attribute and the mode
/* interface for exporting device attributes */
struct device_attribute Use this structure if your goal is to
{ create attributes for a device and to
struct attribute attr; provide show/store methods
ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf);
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
};

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

/* interface for exporting device attributes */


struct device_attribute
{
struct attribute attr;
ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf);
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
};

include/linux/device.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Creating device_attribute variables


• Instead of manually creating variables of struct device_attribute and
initializing them, use the DEVICE_ATTR_XX macros given in
include/linux/device.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Usage
static struct device_attribute dev_attr_bar = {
.attr = {
.name = “bar",
.mode = S_IWUSR | S_IRUGO,
},
.show = show_bar,
.store = store_bar,
};

is equivalent to doing:

static DEVICE_ATTR(bar, S_IWUSR | S_IRUGO, show_bar, store_bar);

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Show and store methods


• Show method is used to export attribute value to the user space
• Store method is used to receive a new value from the user space for
an attribute

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Show method

Prototype:
ssize_t (*show)(struct device *dev, struct device_attribute *attr , char *buf);

This function is invoked when user space program tries to read the value of the attribute.

Here you must copy the value of the attribute in to the ‘buf’ pointer.

Note that ‘buf’ is not user level pointer .


Its provided by the kernel buffer so its size is limited to PAGE_SIZE .
For ARM architecture it is 4KB (4096 Bytes) long
So , while copying data to ‘buf’ pointer the size shouldn’t exceed 4096 bytes.
To copy data in to ‘buf’ you can either use sprintf() or scnprintf()

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Show method

Difference between drivers read method and drivers show method


1)Read method is used by the user space to read large amounts of data from the driver .
2)Show method is used for reading a single value data or an array of similar values or data
whose length is less than PAGE_SIZE
3)Use show method to read any configuration data of your driver or device.

Return value of show method :


show() methods should return the number of bytes copied into the buffer or an error code

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Store method
ssize_t (*store)(struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count);

This is invoked when user wants to modify the value of the sysfs file .
In this method , ‘buf’ points to the user data.
'count' parameter is the amount of user data being passed in.

The maximum amount of data which the ‘buf’ pointer can carry is limited PAGE_SIZE
The data carried by the ‘buf’ is NULL terminated .

store() should return the number of bytes used from the buffer.
If the entire buffer has been used, just return the count argument.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

int kstrtol(const char *s, unsigned int base, long *res)


include/linux/kernel.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Attribute grouping
• Instead of calling sysfs_create_file to create a sysfs file for every
attribute. You can finish it off in one call using attribute grouping

int sysfs_create_group(struct kobject *kobj,const struct attribute_group *grp);

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Attribute grouping

int sysfs_create_group(struct kobject *kobj,\


const struct attribute_group *grp);

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pointer to NULL terminated list of


attributes

Include/linux/sysfs.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

lib/string.c

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

APIs for managing devices inside a class


• int device_create_file(struct device *, const struct device_attribute *);
• void device_remove_file(struct device *, const struct device_attribute *);

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

sysfs interface for exporting driver attributes

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

int driver_create_file(struct device_driver *driver, \


const struct driver_attribute *attr);

void driver_remove_file(struct device_driver *driver, \


const struct driver_attribute *attr);

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

int device_create_file(struct device *device,\


const struct device_attribute *entry);
void device_remove_file(struct device *dev,\
const struct device_attribute *attr);

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Device unregister

void device_unregister(struct device *dev)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Helper macros for defining device attribute


structures
• #define DEVICE_ATTR(_name, _mode, _show, _store) \ struct
device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show,
_store)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

What's an GPIO ?

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

AM335x GPIO controllers

GPIO2 GPIO3
GPIO0 GPIO1

0 1 30 31 0 1 30 31
0 1 30 31 0 1 30 31

32 Pins 32 Pins 32 Pins 32 Pins

The AM335x soc gives in total 32 * 4 = 128 GPIO pins

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

AM335x GPIO
controllers

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Memory map
Region Name Start Address (hex) End Address (hex) Size Description
GPIO0 0x44E0_7000 0x44E0_7FFF 4KB GPIO0 Registers
GPIO1 0x4804_C000 0x4804_CFFF 4KB GPIO1 Registers
GPIO2 0x481A_C000 0x481A_CFFF 4KB GPIO2 Registers
GPIO3 0x481A_E000 0x481A_EFFF 4KB GPIO3 Registers
GPIOx register addresses

GPIO pins are configured through memory-mapped GPIO configuration registers

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

AM335x pin modes


• In a microcontroller/SOC, most of the pins have multiple
functionalities. Also called modes.
• For example, a pin of the SOC can act as a simple GPIO, or it can act as
UART_TX line, or UART_RX line or MMC_DATA line, etc. This is called
pin multiplexing.
• Pin multiplexing helps SOC designers to produce an SOC with lesser
pin counts
• When a Pin is used for one functionality, it cannot be used for
another functionality unless you reconfigure it . (mode setting or pad
configuration )

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pin multiplexing
Pin configuration register
Mode0
I2C0_CLK
Mode1
MMC_DATA
Mode2 pin of the SOC
UART_TX
Functions Mode3
CAN_TX
Mode4
I2C0_DATA
Mode5
LCD_DATA
Mode6
GPIO

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Accessing GPIOs on BBB header


• https://github.com/beagleboard/beaglebone-black/wiki/System-
Reference-Manual#section-7-1
7.1 Expansion Connectors

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BBB expansion headers

Reference : https://beagleboard.org/Support/bone101
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pad configuration register

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pin count of AM335x

Pin Package type : ZCZ


Total pin count = 324
AM3358BZCZ100

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

/sys/class/gpio/gpioN /sys/class/leds /sys/class/input


User space

Kernel space
Consumers
Keypad
Foo driver
driver

gpio led driver


drivers/leds/leds-gpio.c
gpiolib gpiolib-sysfs driver
gpio keys driver drivers/gpio/gpiolib.c drivers/gpio/gpiolib-sysfs.c
drivers/input/keyboard/gpio_keys.
c
register gpio chip

gpio_chip
drivers/gpio/gpio-omap.c gpio controller driver
producer
Linux GPIO subsystem

GPIOx controllers Hardware


BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Consumer accessing GPIO pins


Consumer
Producer

Keypad driver
GPIO controller
GPIO0

0 to 31 pins

Consumer dt node

Key-pad dt node

7pins

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

The consumer driver accesses the dt node to extract


the information about the gpois used to connect
the keypad and configures them

Representing GPIOs in consume dt node


GPIO number Keypad driver
GPIO controller number
Active high or active low status

Platform specific data

Dt node for the keypad device

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

GPIO device tree property

GPIOs being consumed are represented by <function>-gpios property

• <function> being the purpose of this GPIO for the consumer


• Omitting <function > is OK but not recommended
• <function>-gpio is OK but not recommended
• So best practice is always use in the form : <function>-gpios

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Consumer driver

consumer flags

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

phandle to the GPIO controller


to which this pin belongs to local offset to the GPIO line

gpio flags

Function name . Driver


binding document tells you
what name to use.
‘Conn-id’

A GPIO consumer dt node

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

GPIO consumer flags


flags is defined to specify the following properties:
* GPIO_ACTIVE_HIGH - GPIO line is active high
* GPIO_ACTIVE_LOW - GPIO line is active low
* GPIO_OPEN_DRAIN - GPIO line is set up as open drain
* GPIO_OPEN_SOURCE - GPIO line is set up as open source
* GPIO_PERSISTENT - GPIO line is persistent during suspend/resume and maintains its value
* GPIO_TRANSITORY - GPIO line is transitory and may loose its electrical state during suspend/resum

include/dt-bindings/gpio/gpio.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

GPIO kernel functions to manage GPIOs


• The GPIO subsystem exposes many kernel function which the
consumer driver can use to manage the GPIOs.
• Consumer driver should include linux/gpio/consumer.h header file
where gpio manipulation function prototypes are available.

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Acquiring and Disposing GPIOs

A gpio consumer dt node

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Acquire and dispose a GPIO

Acquire
struct gpio_desc* gpiod_get(struct device *dev, const char *con_id, \
enum gpiod_flags flags)

Dispose
void gpiod_put(struct gpio_desc *desc)

Device-managed variants of GPIO functions are also available .


Check consumer.txt

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Acquiring GPIO using index

when the function is implemented by using several GPIOs together

struct gpio_desc* gpiod_get_index(struct device *dev, const char *con_id, \


unsigned int idx, enum gpiod_flags flags)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

GPIO initialization flags


/**
* Optional flags that can be passed to one of gpiod_* to configure direction
* and output value. These values cannot be OR'd.
*/
enum gpiod_flags {
GPIOD_ASIS = 0,
GPIOD_IN = GPIOD_FLAGS_BIT_DIR_SET,
GPIOD_OUT_LOW = GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT,
GPIOD_OUT_HIGH = GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT |
GPIOD_FLAGS_BIT_DIR_VAL,
GPIOD_OUT_LOW_OPEN_DRAIN = GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_OPEN_DRAIN,
GPIOD_OUT_HIGH_OPEN_DRAIN = GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_OPEN_DRAIN,
};

Include/linux/consumer.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

GPIO manipulations
• What you do with GPIO lines?
• Configure its direction (input or output )
• Change its output state to 0 or 1
• Read input state
• Configure output type (push-pull/open-drain)
• Enable/Disable pull-up/pull-down resistors

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Configuring direction and flags


Function note
int gpiod_direction_input(struct gpio_desc *desc); set the GPIO direction to input
int gpiod_direction_output(struct gpio_desc set the GPIO direction to output by taking initial
*desc, int value); output value of the GPIO
int gpiod_direction_output_raw (struct gpio_desc set the GPIO direction to output without regard
*desc, int value) for the ACTIVE_LOW status
int gpiod_configure_flags (struct gpio_desc helper function to configure a given GPIO
*desc, const char *con_id, unsigned long lflags,
enum gpiod_flags dflags)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Get and set


Function note
int gpiod_get_direction(struct gpio_desc *desc) return the current direction of a GPIO
Returns 0 for output, 1 for input
int gpiod_get_value(const struct gpio_desc *desc); Return the GPIO's logical value, i.e. taking the
ACTIVE_LOW status into account
int gpiod_get_raw_value(const struct gpio_desc *desc); Return the GPIO's raw value, i.e. the value of the
physical line disregarding its ACTIVE_LOW status

void gpiod_set_value(struct gpio_desc *desc, int value); Set the logical value of the GPIO, i.e. taking its
ACTIVE_LOW, OPEN_DRAIN and OPEN_SOURCE flags
into account.
void gpiod_set_raw_value(struct gpio_desc *desc, int Set the raw value of the GPIO, i.e. the value of its
value); physical line without regard for its ACTIVE_LOW
status.
int gpiod_set_debounce(struct gpio_desc *desc, unsigned sets debounce time for a GPIO
debounce);
int gpiod_is_active_low(const struct gpio_desc *desc); test whether a GPIO is active-low or not
Returns 1 if the GPIO is active-low, 0 otherwise

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Accessing GPIO value from atomic context

int gpiod_cansleep(const struct gpio_desc *desc);


void gpiod_set_value_cansleep(struct gpio_desc *desc, int value);
void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value);
int gpiod_get_value_cansleep(const struct gpio_desc *desc);
int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc);

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Exercise
Write a GPIO sysfs driver.
The goal of this exercise is to handle GPIOs of the hardware through Sysfs interface

The driver should support the below functionality


1)The driver should create a class "bone_gpios" under /sys/class (class_create)
2)For every detected GPIO in the device tree, the driver should create a device
under /sys/class/bone_gpios (device_create)
3) the driver should also create 3 sysfs files(attributes ) for every gpio device
attribute 1) direction:
used to configure the gpio direction
possible values: ‘in’ and ‘out’
mode : (read /write)
attribute 2) value:
used to enquire the state of the gpio or to write a new value to the gpio
possible values : 0 and 1 (read/write)
attribute 3) label:
used to enquire label of the gpio (read-only )

4) implement show and store methods for the attributes


BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Device-Driver binding information


The device tree for this driver must be created like below
gpio_devs
{
compatible = "org,bone-gpio-sysfs";

gpio_1 {
label = "gpio1.21"; /* optional */
bone-gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>; /* mandatory */
};

gpio_2 {
label = "gpio1.22";
bone-gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
};

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

* The function properly finds the corresponding GPIO using


whatever is the * underlying firmware interface and then makes
sure that the GPIO * descriptor is requested before it is returned
@fwnode: firmware node containing GPIO reference *
to the caller
@con_id: function within the GPIO consumer
BHARATI SOFTWARE , CC BY-SA 4.0 , 2020
www.fastbitlab.com

Pin control subsystem

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

AM335x SOC

a pin
The functionality of a pin depends
on its mode configured in
Multi purpose pin
mode/pad configuration register.
(modes) 0 1 2 3 4 5 6 7
TIMER MMC_D

I2C1_SDA GPIO

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pin count of AM335x

Pin Package type : ZCZ


Total pin count = 324
AM3358BZCZ100

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pad configuration register of AM335x

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com
Using pin-control subsystem of Linux
/sysfs debug facility
User space

eeprom driver pinctrl core apis

Any driver which uses


pinctrl core exposed apis to manage
pinctrl core
pins or for dynamic re configuration
drivers/pinctrl/core.c
register and init pin
Kernel space controller device

Pinctrl-single.c
Vendor given pin
Generic device tree
controller driver
based pinctrl driver
drivers/pinctrl/
pinctrl-single.c Pin controller driver

Pin configuration I2C2_SDA


dt node Pin controller hardware
(pad config registers) I2C2_SCL EEPROM
pin controller node AM335X Hardware
DT files AM335X
GPIO

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

• Pin control core


• Pinctrl core implementation you can find in drivers/pinctrl/core.c
• This provides pin control helper functions to any consumer drivers
• Maintains pin exclusivity for a device
• Provides debug interface to user space through sysfs

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pin control subsystem of linux


• Pin control subsystem of Linux is used to configure pins of a
microprocessor/microcontroller
• What is pin configuration ?
• Pin mode configuration for alternate functions
• Slew rate adjustment
• Driver strength
• Pull up and pull down resistor enable/disable
• Output type control (push pull, open drain)

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pins that need to be Client device


Pin controller configured
A Client device is nothing but any
hardware module whose signals are
I2C2_SDA affected by pin configuration .
Pin controller hardware Again, each client device must be
(pad config registers) I2C2_SCL EEPROM represented as a node in the device
AM335X
tree, just like any other hardware
AM335X module.
GPIO

Device tree nodes


1. Node which explains the pin controller
2. Node which explains configuration details for individual pins
3. Node which claims the pins (Client device node )

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

What is a pin-controller ?
• Hardware modules that control pin multiplexing and configuration
parameters such as pull-up/down, tri-state, drive-strength are
designated as pin controllers.
• Each pin controller must be represented as a node in the device tree,
just like any other hardware module node.
• For am335x, the pad config registers are called as pin controllers

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

How to write a pin-controller node ?


• This is explained by your pin controller driver’s binding document
• If you are using generic pinctrl driver then refer pinctrl-single.txt
under Documentation/devicetree/bindings/pinctrl/

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Example of pin controller node

am33xx-l4.dtsi

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

How to write pin configuration node ?


• Should be explained by your pin controller driver

Pins which needs to


be configured

I2C2_SDA
Pin controller hardware
(pad config registers) I2C2_SCL EEPROM
AM335X
AM335X
GPIO

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

pinctrl-single,pins

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

pinctrl-single,pins property
The pin configuration nodes for pinctrl-single are specified as pinctrl
register offset and value pairs using pinctrl-single,pins.

For example, setting a pin for a device could be done with:

pinctrl-single,pins = <0xdc 0x118>;

Where 0xdc is the offset from the pinctrl register base address for the
device pinctrl register, and 0x118 contains the desired value of the
pinctrl register. See the device example and static board pins example
below for more information.

Reference :
Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pins which needs to be Client device

Pin controller configured

I2C2_SDA
Pin controller hardware
(pad config registers) I2C2_SCL
EEPROM
AM335X
AM335X
GPIO

Client device node

Pin configuration node embedded in pin controller node

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pinctrl related properties to be used with


client device nodes
• For full discussion visit :
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt

pinctrl-names : The list of names to assign states. List entry 0 defines


the name for integer state ID 0, list entry 1 for state ID 1, and so on.
pinctrl-<id> : List of phandles, each pointing at a pin configuration node
within a pin controller

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pin state id and pin state name


You can define, different set of pin configuration values for different state of the device
A device’s state could be default, sleep, idle, active, etc
Different pin states help to achieve dynamic configurability of pins

Device’ state Device’ state


Default sleep

pins will be Pins will be


configured for i2c configured as input to
functionality save power

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Here, a pin controller has 2 nodes. The first one configures the pins for i2c
functionality and the second one configures the same pins for gpio input
functionality .
The client device will use the first one during normal operation , and when
driver decides to put device to sleep, it will use the second one to
reconfigure the pins to stop leakage of current thus achieving low power

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Client device node with 2 pin states

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

AM335x pad configuration macro

Pad configuration Pad direction and Mode(0…7)


register offset Pupd control

Include/bt-bindings/pinctrl/omap.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Address of pad-conf reg value

include/bt-bindings/pinctrl/omap.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Pad direction and


Pupd control

Pad configuration
register offset

Include/bt-bindings/pinctrl/am33xx.h

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Exercise
Interfacing 16x2 LCD to BBB and testing with gpio-sysfs driver by
writing an LCD application

7
BBB 16x2 Char LCD

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

lcd_app
User space open read/write

Sysfs gpio attributes (direction , value)

Kernel space gpio-sysfs.ko

Hardware BBB gpios 16x2 Char LCD

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

16x2 character LCD connection with BBB

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Components required
• 16x2 Character LCD (1602A HD44780 LCD)
• 10K potentiometer
• Breadboard
• Connecting wires
• Beaglebone black

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

GPIOs of BBB

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

P9
1
7
P8
45
46
43
44
41
42
39

BBB P8 and P9 headers

Note : 4 bit data mode is used. Data pin 0 to Data pin 3 are unused

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

P9
1 Gnd
7 5V

gnd
Wiper
10K Potentiometer
Power

LCD Contrast control using Potentiometer

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Steps
1. Connect LCD to BBB
2. Add required gpio entries to the gpio-sysfs device tree node
3. Recompile the dts file and make BBB boots with modified dtb
4. Load the gpio-sysfs driver
5. Make sure that all required gpio devices are formed under
/sys/class/bone_gpios
6. Download the lcd application files attached with this video.
lcd_app.c, lcd.c, gpio.c
7. Cross compile the lcd application and test it on the target

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

lcd_app.c (LCD application)

lcd.c (LCD related functions )

(File handling of sysfs attributes (open,


gpio.c read, write, close) )

sysfs gpio attributes (direction , value ) (GPIO sysfs entries with attributes)

Driver’s store methods


for attributes

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Significance of LCD pins

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

LCD commands
• Send commands to initialize and control the operation of the LCD
• Commands are 8bits long (a byte )

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

LCD commands
1. Function set
2. Display on/off, cursor on/off and blink control
3. Entry mode set
4. LCD clear display
5. Cursor return home
6. Set co-ordinates
7. Display right/left shift
8. Cursor on/off, blink on/off
9. Address counter read/write

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Sending command/data
• A command or data byte is of 8bits (1byte)
• You can send all 8 bits in one go over 8 data lines, or you can split into
2 data transmissions of 4 bits each.
• For 4-bit data transmission, you only need 4 data lines connected
between LCD and MCU
• For 4-bit data transmission, you must use data lines D4 ,D5, D6,D7

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Sending a command
1.Create the command code
2.Make RS pin low
3.Make RnW pin low
4.First send higher nibble(4-bits) of the command code to data lines
5.Make LCD enable pin high to low ( when LCD detects high to low transition on enable
pin it reads the data from the data lines )
6.Next send the lower nibble of the command code to data lines
7.Make LCD enable pin high to low ( when LCD detects high to low transition on enable
pin it reads the data from the data lines )
8. Wait for the instruction execution time before sending the next command or confirm
the LCD is not busy by reading the busy flag status on D7 pin .

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

Sending a data byte

1.Make RS high
2.Make RnW low
3.First send higher nibble of the data to data lines
4.Make LCD enable pin high to low ( when LCD detects high to low
transition on enable pin it reads the data from the data lines )
5.Next send the lower nibble of the data to data lines
6.Make LCD enable pin high to low ( when LCD detects high to low
transition on enable pin it reads the data from the data lines )

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com
7 6 5 4 3 2 1 0
0x28 0 0 1 0 1 0 0 0
Higher nibble Lower nibble

D4
D5
MCU LCD
D6
D7

Sending command/data in 4bit data transmission mode

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

7 6 5 4
0x28 0 0 1 0
Higher nibble

D4
D5
MCU LCD
D6
D7

Sending command/data in 4bit data transmission mode

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

3 2 1 0
0x28 1 0 0 0
Lower nibble

D4
D5
MCU LCD
D6
D7

Sending command/data in 4bit data transmission mode

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020


www.fastbitlab.com

BHARATI SOFTWARE , CC BY-SA 4.0 , 2020

You might also like