通用头文件
以下三个头文件几乎所有的linux驱动代码都需要
1 2 3
| #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h>
|
设备结构体并创建设备对象
定义设备结构体
1 2 3 4 5 6 7 8 9 10 11 12
| #define xxx_CNT 1 #define xxx_NAME "xxx"
struct xxx_dev{ dev_t devid; int major; int minor; struct cdev cdev; struct class *class; struct device *dev; }
|
cdev 需要包含头文件#include <linux/cdev.h>
class和device需要包含头文件#include <linux/devices.h>
创建设备对象
file_operation集各项函数具体实现
open函数具体实现
1 2 3 4 5
| static int xxx_open(struct inode *inode, struct file *filp) { filp->private_data = &xxx; 将设备结构体对象设为私有数据 return 0; }
|
read函数具体实现
1 2 3 4 5 6 7
| static ssize_t xxx_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt) { struct xxx_dev *dev = (xxx_dev *)filp->private_data; copy_to_user(目标buf, 源, cnt); ... return 0; }
|
copy_to_uaer函数需要包含头文件#include <asm/uaccess.h>
write函数具体实现
1 2 3 4 5 6
| static ssize_t xxx_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt) { copy_from_user(目标buf, 源, cnt); ... return 0; }
|
release函数具体实现
1 2 3 4
| static int XXX_release(struct inode *inode, struct file *filp) { return 0; }
|
设备操作函数集合 需包含头文件#include <linux/fs.h>
1 2 3 4 5 6 7 8 9
| struct file_operations xxx_fops= { .owner = THIS_MODUle, .open = xxx_open, .read = xxx_read, .write = xxx_write, .release = xxx_release, ... };
|
模块入口函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| static int __init xxx_init(void) { ... ... if(xxx.major) { xxx.devid = MKDIR(xxx.major, 0); register_chrdev_region(XXX.devid, xxx_CNT, xxx_NAME); } else { alloc_chrdev_region(&xxx.devid, 0, xxx_CNT, xxx_NAME); xxx.major = MAJOR(xxx.devid); xxx.minor = MINOR(xxx.devid); }
xxx.cdev.owner = THIS_MODULE; cdev_init(&xxx.cdev, &xxx_fops); cdev_add(&xxx.cdev, xxx.devid, xxx_CNT);
xxxx->class = class_create(THIS_MODULE, xxx_NAME); xxx->device = device_create(xxx.class, NULL, xxx.devid, NULL, xxx_NAME);
... ... return 0; }
|
出口函数形式
1 2 3 4 5 6 7 8
| static void __exit xxx_exit(void) { cdev_del(&xxx.cdev); unregister_chrdev_region(xxx.devid, xxx_CNT); device_destroy(xxx->class, xxx->device); class_destroy(xxx->class); ... }
|
模块入口和模块出口
1 2 3 4
| module_init(xxx_init); module_exit(xxx_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Hector");
|