1. Character Device Driver runs in Beaglebone Black
Create a directory in source code and create files in this
directory:
1.Create a character device driver code:
$ vi char_drv.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
int file_open (struct inode *pinode, struct file *pfile)
{
printk(KERN_INFO "Inside the %s functionn",__FUNCTION__);
return 0;
}
size_t file_read (struct file *pfile, char __user *buffer, size_t length, loff_t *offset)
{
printk(KERN_INFO "Inside the %s functionn",__FUNCTION__);
return 0;
}
ssize_t file_write (struct file *pfile, const char __user *buffer, size_t length, loff_t *offset)
{
printk(KERN_INFO "Inside the %s functionn",__FUNCTION__);
return length;
}
int file_close (struct inode *pinode, struct file *pfile)
{
printk(KERN_INFO "Inside the %s functionn",__FUNCTION__);
return 0;
}
/* To hold the file operations performed on the device */
struct file_operations fops = {
.owner = THIS_MODULE,
.open = file_open,
.read = file_read,
.write = file_write,
.release = file_close,
};
2. Character Device Driver runs in Beaglebone Black
static int __init char_drv_init(void)
{
printk(KERN_INFO "Inside the %s functionn",__FUNCTION__);
/* Register with the kernel and indicate that we are registering character device driver */
register_chrdev(240 /* Major Number */,
"char_drv" /* Name of the driver */,
&fops /* file operations */);
return 0;
}
static void __exit char_drv_exit(void)
{
printk(KERN_INFO "Inside the %s functionn",__FUNCTION__);
/* unregister the character device driver */
unregister_chrdev(240, "char_drv");
}
module_init(char_drv_init);
module_exit(char_drv_exit);
MODULE_LICENSE("GPL");
2. Create Make file:
$ vi Makefile
obj-m += char_drv.o
3. Building the driver:
The kernel path should be given with care, the module should be created with the
same version as used in the kernel path in make command. If the version does not
match with the kernel object file, then we get errors while inserting the kernel
module.
$ make -C <kernel path> M=$PWD ARCH=arm CROSS_COMPILE=arm-linux-
gnueabi- modules
After using this command, you will get kernel object file “char_drv.ko”
3. Character Device Driver runs in Beaglebone Black
4. Contents of micro sd card:
copy following files to sd card :
# uImage from path arch/arm/boot
# am335x-boneblack.dtb from path arch/arm/boot/dts
# char_drv.ko from directory first_driver
along with these files the sd card should contain MLO, u-boot.img.
5. Boot the beaglebone black board through micro sd card:
After power up the board, stop the terminal using “space bar” to stop auto boot and
to boot u-boot.
u-boot# setenv bootargs console=tty00, 115200n8 root=/dev/mmcblk1p2 ro
rootfstype=ext4 rootwait init=/lib/systemd/systemd
u-boot# fatload mmc 0:1 0x80200000 uImage
u-boot# fatload mmc 0:1 0x82000000 am335x-boneblack.dtb
u-boot# bootm 0x80200000 – 0x82000000
after booting to kernel, it will ask beaglebone login and password:
beaglebone login: debian
password: temppwd
you will get the prompt like this “debian@beaglebone:~$”
$ cd /
$ mount /dev/mmcblk0p1 /mnt
$ cd /mnt
mnt$ ls
am335x-boneblack.dtb MLO uImage
char_drv.ko u-boot.img
4. Character Device Driver runs in Beaglebone Black
Inserting the module:
mnt$ sudo insmod ./char_drv.ko
[ 101.221609] Inside the char_drv_init function
mnt$ cat /proc/devices // displays the device number attached with driver
240 char_drv
mnt$ sudo mknode -m 666 /dev/char_drv c 240 0 // To do device entry
mnt$ ls -l /dev/char_drv
crw-rw-rw- 1 root root 240 , 0 Jun 27 17:40 /dev/char_drv
Verification of function call during the following operations:
mnt$ cat /dev/char_drv
[ 425.548044] Inside the file_open function
[ 425.554154] Inside the file_read function
[ 425.559639] Inside the file_close function
mnt$ echo “testing” > /dev/char_drv
[ 556.667994] Inside the file_open function
[ 556.674165] Inside the file_write function
[ 556.679561] Inside the file_close function
Removing the module:
mnt$ sudo rmmod char_drv.ko
[ 699.507815] Inside the char_drv_exit function