字符设备驱动基本框架
分享一篇博客该框架里的知识点都有详解:
linux字符设备驱动详解
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#define NEWCHRLED_NAME "newchrled"
#define NEWCHRLED_CNT 1
/*LED设备结构体*/
struct newchrled_dev{
struct cdev cdev;
dev_t devid;
int major;
int minor;
};
static int led_open(struct inode *inode, struct file *filp){
return 0;
}
static ssize_t led_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt){
return 0;
}
static ssize_t led_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt){
return 0;
}
static int led_release(struct inode *inode, struct file *filp){
return 0;
}
static struct file_operations newcheled_fops = {
.owner = THIS_MODULE,
.open = led_open;
.read = led_read,
.write = led_write,
.release = led_release,
};
struct newchrled_dev newchrled;
/*入口*/
static int __init led_init(void){
/*初始化LED*/
/*注册字符设备*/
/* 1、创建设备号 */
if (newchrled.major) { /* 定义了设备号 */
newchrled.devid = MKDEV(newchrled.major, 0);
register_chrdev_region(newchrled.devid, NEWCHRLED_CNT, NEWCHRLED_NAME);
} else { /* 没有定义设备号 */
alloc_chrdev_region(&newchrled.devid, 0, NEWCHRLED_CNT, NEWCHRLED_NAME); /* 申请设备号 */
newchrled.major = MAJOR(newchrled.devid); /* 获取分配号的主设备号 */
newchrled.minor = MINOR(newchrled.devid); /* 获取分配号的次设备号 */
}
printk("newcheled major=%d,minor=%d\r\n",newchrled.major, newchrled.minor);
/* 2、初始化cdev */
newchrled.cdev.owner = THIS_MODULE;
cdev_init(&newchrled.cdev, &newchrled_fops);
/* 3、添加一个cdev */
cdev_add(&newchrled.cdev, newchrled.devid, NEWCHRLED_CNT);
return 0;
}
/*出口*/
static void __exit led_exit(void){
cdev_del(&newcheled.cdev);
unregister_chrdev_region(newchrled.devid, NEWCHRLED_CNT); /* 注销设备号 */
return 0;
}
/*注册和卸载函数*/
module_init();
module_exit();
MODULE_LICENSE("GPL");
MODULE_AUTHOR("gyf");