This is a collection of different linux kernel driver (can be use as a template):
- an absolute minimal driver
- char driver (use ioctl and write to define a new read buffer)
- i2c-gpio driver_simple (PCF8574 based)
- i2c-gpio driver (PCF8574 based with check of IRQ line)
- i2c-gpio driver for hd44780 based display (PCF8574 based)
- gpio irq driver_simple (bind a PIN to an irq)
- gpio irq driver (use write to define PIN)
- gpio driver (use ioctl to define PIN for read/write)
- gpio irg driver for hd44780 based displays
- spi driver (MAX7119 based)
It's an playground for different topics like I2C. Therefore i implement a userspace example based on what is already available within the kernel/userspace (like i2c-tools) and a driver with a specialized interface (and a example of how to use it). You find also schematics and pics about my test setup.
But be aware: this is work in progress! Don't expect things to be complete in any dimension! See the State info below to get an idea of what is working.
The simple user interface to this repository is a Makefile. So type
make
to get more info.
You can install all driver and userspace examples via
make install
To get rid of them use
make uninstall
The make install tag will install all modules to /lib/modules/$(shell uname -r)/kernel. So you can simple type
modprobe char_driver
to load it. Depending on your distribution you can see info message from the driver in /var/log/messages.
(sudo) tail -n 50 -f /var/log/messages
The userspace example (usage_$(DRIVER_NAME)) will be installed in $(HOME)/bin. If you have it in your $PATH, then you can simply tape
usage_char_driver -a
and see in /var/log/messages what the driver is doing.
Every driver tries to implement a single topic.
Nearly all drivers in this repository have the same structure:
Below the usage directory you can find one or more examples on how to access the driver.
The purpose for this driver is simply to check an crosstool enviroment. If you work with embedded device you often need to crossbuild drivers. With that simple driver you can check if your toolchain works and if you have the correct versions. Simply crossbuild it vi make ARCH=... CROSS_COMPILE=... KDIR=... and transfer minimal_driver.ko to your device and then insmod it, check syslog entry and rmmod it. If everthing works fine, then your environment should be also fine, otherwise you have to check.
State: finished
Basic character driver with open, close, read, write and ioctl support (PM-support prepared).
The driver implements a simple char_driver. It creates a dev-node (/dev/char_driver), on which you can use read, write and ioctl. The simple example shows how to use the driver:
- open char_driver
- read driver default string from driver
- write TO_WRITE to driver
- read new string from driver
- set IOCTL_TO_WRITE via ioctl
- read new string from driver
Build and load the driver:
Example usage of the driver:
State: finished
Simple (write) driver to demonstrate the usage of a PCF8574 controlled via I2C (no IRQ). The examples uses the led line of the userspace example below.
The first byte of a write syscall defines which pins to write, the others will be ignored (simple byte AND operation).
Used hardware: Bananapi-M1
Feartures:
Control apdapter and addr via ioctl
Pin configuration via first byte of write
State: started
A more advanced driver to demonstrate the usage of a PCF8574 controlled via I2C. Possible base for drivers like https://github.com/tjohann/pcf8574_gpio.git and https://github.com/tjohann/lcd160x_driver.git
Feartures:
Interrupt handler for PIN13/IO-0/PI18 (IRQ line of PCF8574)
Read/write all pins (8 bit)
Control apdapter and addr via ioctl
Configure input/output via ioctl
Control mapping of A20-GPIO to PCF8574-IRQ-line via ioctl
default: interrupt handler for PIN13/IO-0/PI18 (IRQ line of PCF8574)
Used defaults:
PIN13 (IO-0/PI18) for input (IRQ-line)
Used hardware: Bananapi-M1
State: not started
Simple driver to show the usage of gpios to connect a hd44780 based lcd display like LCD1602 in 4 bit mode via PCF8574. The size and the pinning to the display can be configured via ioctl. Possible codebase for https://github.com/tjohann/lcd160x_driver.git .
Example usage of the driver:
TODO: ADD PICS
State: not started
Simple(st) driver to show the usage of an IRQ connected PIN (PIN13/IO-0/PI18 -> bananapi-m1).
Used defaults:
PIN16 (IO-4/PH20) for input
The driver doesn't support more than one instance and it uses only the default PIN.
State: finished
An int based driver to show the usage of an IRQ connected PIN. Via write syscall you can define a input PIN, otherwise it will use the defaults.
Used hardware: Olimex-A20-SOM-EVB
Feartures:
Control the IRQ pin via write syscall
Usage:
usage_gpio_irq_driver (read from default PIN PH20/244)
usage_gpio_irq_driver -p 123 (read from to PIN 123)
Example usage of the driver (with 3/4 instance) using PH8, PH16, PH20 and PH21:
State: finished
Simple (fd based) driver to show the usage of an IRQ connected PIN (PIN13/IO-0/PI18). It behaves in the same way like gpio_irq_driver, but it uses the new file descriptor gpio framework of the kernel
State: not started
Simple (interrupt based) driver to show the usage of gpio for read and write from a PIN. Via ioctl syscall you can change the PIN for in/output. It doesn't bind a PIN to an IRQ!
Used defaults:
PIN11 (IO-0/PI19) for output
PIN13 (IO-0/PI18) for input
Used hardware: Bananapi-M1
Usage:
usage_gpio_driver -r (read from default pin)
usage_gpio_driver -w (write to default pin)
usage_gpio_driver -rp 321 (read from pin 321)
usage_gpio_driver -w -p 123 (write to pin 123)
Note: The driver configured the default pin after open. So to use more than one instance you have to use ioctl to change the pin.
Example usage of the driver:
State: finished
Simple (fd based) driver to show the usage of gpio for read and write from a PIN. It behaves in the same way like gpio_driver, but it uses the new file descriptor gpio framework of the kernel.
State: not started
Simple driver to show the usage of gpios to connect a hd44780 based lcd display like LCD1602 in 4 and 8 bit mode. The irq handler checks the response of the display. This is rarely used because it`s not really needed if you add proper waits between the commands. The size and the pinning to the display can be configured via ioctl.
Example usage of the driver:
TODO: ADD PICS
State: not started
Basic for drivers like https://github.com/tjohann/max7119_array.git
State: not started
Below the directory userspace_examples you find my basic userspace playground. In most cases the userspace parts are the starting point for the driver development and the functionality provided by "normal" userspace will be implemented within a special driver(s). They are the basic for my blog entrys about embedded linux (https://tjohann.wordpress.com/category/embedded-realtime/) and linux realtime topics (https://github.com/tjohann/time_triggert_env.git).
To implement an I2C driver you normally also have to implement the protocol which is specific to the IC and it's functionlity. As example think of the LCD1602 connected via PCF8574 portexpander with the I2C bus. All example use the i2c-dev driver (http://lxr.free-electrons.com/source/Documentation/i2c/dev-interface) and i2c-tools (http://www.lm-sensors.org).
These userspace examples are really simple and should only show howto use i2c-dev (https://www.kernel.org/doc/Documentation/i2c/dev-interface). Therefore I connect a LED line to the PCF8574 and implement a moving light with it. Another examples shows howto read from a pin via switches.
TODO: ADD PICS
State (pcf8574_cyclon): started
State (pcf8574_input): not started
This example shows howto access a lcd1602 display via pc8574 i2c gpio port expander (a version for a lcd2004 see https://github.com/tjohann/ambient_tracking_with_raspi/tree/main/lcd2004_i2c). There you can see the steps needed to perform access.
State (pcf8574_lcd1062): started
This is a simple demonstration about the usage of sysfs-gpio interface. This scripts toogle PIN11(IO-0/PI19) of a bananapi. See ./Documentation/gpio_bananapi.txt about calculation gpio value and PIN.
Another script reads PIN13(IO-2/PI18) and switch PIN11(IO-0/PI19) on/off.
State (gpio_script): finished
Below the directory Documentation you can find useful information about the used IC or the protocol or ... take a look at it.
Here you find some pictures of the wiring and my test setup.
The gpio test environment:
The gpio IRQ test environment:
Here you find some simple schematics of my test setup.