AVR32743 AVR32 AP7 Linux Kernel Module Application Example
AVR32743 AVR32 AP7 Linux Kernel Module Application Example
Application Example
32-bit
Features Microcontrollers
• Linux kernel module basics
- Initialization and cleanup
- Module parameters
- Build system integration Application Note
• Platform driver example
• SPI driver example
1 Introduction
This application note explains how to write a custom loadable driver module for the
Linux® kernel. Common mechanisms like module parameters, initialization and
cleanup are explained in detail. The Linux driver model is introduced, and a short
introduction on how to write drivers for two common bus types, the platform and spi
busses, is given. This application note also explains how to build a custom module
using the Linux kernel’s internal build system.
Rev. 32098A-AVR-07/08
2 Kernel module basics
This section explains some of the basics about loadable Linux kernel modules: How
to do initialization and cleanup, how to pass parameters and how to build and execute
the module. A simple kernel module example, “simple”, is provided to demonstrate
how this works.
When trying out the examples, it is recommended to increase the kernel console log
level to at least 7. Otherwise, some of the output from the example modules may not
be shown on the console, although it will still be shown by the “dmesg” command.
The following command will set the console log level appropriately:
echo 7 4 1 7 > /proc/sys/kernel/printk
The first number indicates the console log level; setting it to 8 will show debug
messages on the console as well.
3
32098A-AVR-07/08
insmod simple.ko number=42
This results in the following being printed to the console:
Hello World!
The number is: 42
Module parameters are basically just regular global or static variables which are
subjected to a bit of preprocessor magic. The following three lines of code from the
“simple” module is all it takes to support module parameters:
static int number;
module_param(number, int, S_IRUGO);
MODULE_PARM_DESC(number, "Number to be printed on startup");
If the “number” parameter is overridden on the command line, the variable “number”,
will be initialized to the specified value before the module initialization function is
called. If the parameter is not specified on the command line, it will retain its initial
value, 0.
The second parameter to module_param() specifies the type of the parameter, which
can be one of byte, short, ushort, int, uint, long, ulong, charp (pointer to character
array), bool or invbool (same as bool, but the inverse of the specified value is stored).
The module_param() macro is defined in “include/linux/moduleparam.h”.
The third parameter to module_param() specifies the file mode of the parameter as it
appears under /sys/module. S_IRUGO means that the file should be readable for
everyone, but not writeable for anyone. This is usually a good choice since writable
module parameters need special care to be taken when implementing the module.
If the driver is built into the kernel, module parameters can still be specified on the
kernel command line using the form “module-name.parameter-name=value”. For
example, if the “simple” module is built-in, the “number” parameter can be set to 42 by
passing “simple.number=42” on the kernel command line.
4 AVR32743
32098A-AVR-07/08
AVR32743
2.4 Building a custom module
The easiest way to build a custom module is to use the kernel’s build system. This
ensures that the correct compiler flags and configuration options are being used.
To build the module using the kernel’s build system, first add a file named “Kbuild” to
the directory containing the module’s source code containing one or more lines on the
form
obj-m += my_module.o
This will instruct the kernel’s build system to take a single file named “my_module.c”
and turn it into a module named “my_module.ko”. To build more than one module in a
single directory, simply add more such lines to the Kbuild file.
Building a single module from several source files can be done by adding a few lines
on the following form:
obj-m += my_module.o
my_module-y += my_module-1.o my_module-2.o
This will instruct the kernel’s build system to compile the files “my_module-1.c” and
“my_module-2.c” into separate object files, and then link them together to produce a
module named “my_module.ko”.
For more information about the kernel’s build system, please consult the
documentation in “Documentation/kbuild”.
When an appropriate Kbuild file is in place, the modules can be built by running
make ARCH=avr32 CROSS_COMPILE=avr32-linux- –C $KERNEL_SRC_DIR \
M=`pwd` modules
Where $KERNEL_SRC_DIR should be replaced by the full path to a Linux kernel
source tree configured for AVR32. The examples distributed with this application note
include a wrapper Makefile which allows the modules to be built by simply running
“make”.
5
32098A-AVR-07/08
a pointer to the device as a parameter. This also happens if the driver is a
dynamically loadable module and the module is unloaded.
All device driver callbacks, including probe() and remove(), must follow the return
value convention described in section 2.2.2.
6 AVR32743
32098A-AVR-07/08
AVR32743
When the driver is unregistered by calling platform_driver_unregister(), usually from
the module exit function, all the devices that have previously been bound to the driver
are unbound, resulting in platform_example_remove() to be called with the device to
be unbound as a parameter. If a device bound to the driver goes away, it will be
unbound in the same way.
When the power management subsystem in Linux determines that a device is to be
suspended, for example if the system as a whole is being suspended,
platform_example_suspend() is called with the device as a parameter. When the
device is to be resumed, platform_example_resume() is called with the device as a
parameter.
Finally, the name of the driver is specified in the “driver” structure around which the
platform_driver structure is wrapped. This name determines which devices can be
bound to the driver.
7
32098A-AVR-07/08
platform_example_remove() will be discarded as well, but if it is built as a module, it
will be kept around to do any necessary cleanup when the module is unloaded.
9
32098A-AVR-07/08
Disclaimer
Headquarters International
Atmel Corporation Atmel Asia Atmel Europe Atmel Japan
2325 Orchard Parkway Room 1219 Le Krebs 9F, Tonetsu Shinkawa Bldg.
San Jose, CA 95131 Chinachem Golden Plaza 8, Rue Jean-Pierre Timbaud 1-24-8 Shinkawa
USA 77 Mody Road Tsimshatsui BP 309 Chuo-ku, Tokyo 104-0033
Tel: 1(408) 441-0311 East Kowloon 78054 Saint-Quentin-en- Japan
Fax: 1(408) 487-2600 Hong Kong Yvelines Cedex Tel: (81) 3-3523-3551
Tel: (852) 2721-9778 France Fax: (81) 3-3523-7581
Fax: (852) 2722-1369 Tel: (33) 1-30-60-70-00
Fax: (33) 1-30-60-71-11
Product Contact
Literature Request
www.atmel.com/literature
Disclaimer: The information in this document is provided in connection with Atmel products. No license, express or implied, by estoppel or otherwise, to any
intellectual property right is granted by this document or in connection with the sale of Atmel products. EXCEPT AS SET FORTH IN ATMEL’S TERMS AND
CONDITIONS OF SALE LOCATED ON ATMEL’S WEB SITE, ATMEL ASSUMES NO LIABILITY WHATSOEVER AND DISCLAIMS ANY EXPRESS, IMPLIED
OR STATUTORY WARRANTY RELATING TO ITS PRODUCTS INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTY OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
CONSEQUENTIAL, PUNITIVE, SPECIAL OR INCIDENTAL DAMAGES (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS,
BUSINESS INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF THE USE OR INABILITY TO USE THIS DOCUMENT, EVEN IF ATMEL HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. Atmel makes no representations or warranties with respect to the accuracy or completeness of the
contents of this document and reserves the right to make changes to specifications and product descriptions at any time without notice. Atmel does not make any
commitment to update the information contained herein. Unless specifically provided otherwise, Atmel products are not suitable for, and shall not be used in,
automotive applications. Atmel’s products are not intended, authorized, or warranted for use as components in applications intended to support or sustain life.
© 2008 Atmel Corporation. All rights reserved. Atmel®, logo and combinations thereof, AVR® and others, are the registered trademarks or
trademarks of Atmel Corporation or its subsidiaries. Other terms and product names may be trademarks of others.
32098A-AVR-07/08