linux内核定义注册设备,linux字符型设备驱动 一.注册设备并创建设备文件
1.字符設(shè)備
字符設(shè)備、字符設(shè)備驅(qū)動與用戶空間訪問該設(shè)備的程序三者之間的關(guān)系
Linux內(nèi)核中:
a -- 使用cdev結(jié)構(gòu)體來描述字符設(shè)備;
b -- 通過其成員dev_t來定義設(shè)備號(分為主、次設(shè)備號)以確定字符設(shè)備的唯一性;
c -- 通過其成員file_operations來定義字符設(shè)備驅(qū)動提供給VFS的接口函數(shù),如常見的open()、read()、write()等;
在Linux字符設(shè)備驅(qū)動中:
a -- 模塊加載函數(shù)通過?register_chrdev_region( ) 或 alloc_chrdev_region( )來靜態(tài)或者動態(tài)獲取設(shè)備號;
b -- 通過 cdev_init( ) 建立cdev與 file_operations之間的連接,通過 cdev_add( ) 向系統(tǒng)添加一個(gè)cdev以完成注冊;
c -- 模塊卸載函數(shù)通過cdev_del( )來注銷cdev,通過 unregister_chrdev_region( )來釋放設(shè)備號;
用戶空間訪問該設(shè)備的程序:
a -- 通過Linux系統(tǒng)調(diào)用,如open( )、read( )、write( ),來“調(diào)用”file_operations來定義字符設(shè)備驅(qū)動提供給VFS的接口函數(shù);
2.例子
hello.c
#include #include#include#include
static int major = 99; //主設(shè)備號(用于區(qū)分設(shè)備類)
static int minor = 0; //次設(shè)備號(用于區(qū)分哪個(gè)設(shè)備)
staticdev_t devno;static structcdev cdev1;struct class *hello_class;static int hello_open(struct inode *inodep, struct file *filep)
{
printk(KERN_ALERT"hello are opened \r\n");return 0;
}static struct file_operations hello_ops ={
.open=hello_open,
};static int hello_init(void)
{intret;
printk(KERN_ALERT"hello_init\r\n");//第一步:將主設(shè)備號、次設(shè)備號轉(zhuǎn)化成dev_t類型
devno =MKDEV(major, minor);
ret= register_chrdev_region(devno, 1, "hello");if (ret < 0)
{
printk(KERN_ERR"my register_chrdev_region fail \r\n");returnret;
}
printk(KERN_INFO"register_chrdev_region success\n");//第二步:注冊字符設(shè)備驅(qū)動
cdev_init(&cdev1, &hello_ops);
ret= cdev_add(&cdev1, devno, 1);if (ret < 0)
{
printk(KERN_ERR"Uable to add dev\n");returnret;
}
printk(KERN_INFO"cdev_add success\n");//第三步:2.6內(nèi)核之后要向sys文件系統(tǒng)中添加設(shè)備
hello_class = class_create(THIS_MODULE, "hello");
device_create(hello_class, NULL, devno, NULL,"hello");
printk(KERN_INFO"device created success\n");return 0;
}static void hello_exit(void)
{
cdev_del(&cdev1);
unregister_chrdev_region(devno,1);
printk(KERN_ALERT"hell_exit\r\n");
}
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
test.c
#include #include#include#includemain()
{intfd;
fd= open("/dev/hello",O_RDWR);if(fd<0)
{
perror("open fail \n");return;
}else{
printf("open /dev/hello success! \n");
}
close(fd);
}
makefile
#General Purpose Makefile forcross compile Linux Kernel module
ifneq ($(KERNELRELEASE),)
obj-m := hello.o #+=是連接字符串elseARCH :=arm
CROSS_COMPILE := arm-linux-gnueabihf-KERN_DIR := /home/zqh/lichee/linux-zero-4.14.y #選擇內(nèi)核路徑
PWD :=$(shell pwd) #當(dāng)前路徑
all:
$(info "1st")make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KERN_DIR) M=$(PWD) modules
clean:rm -f *.ko *.o *.symvers *.mod.c *.mod.o *.order .*.o.ko.cmd .*.ko.cmd .*.mod.o.cmd .*.o.cmd
endif
總結(jié)
以上是生活随笔為你收集整理的linux内核定义注册设备,linux字符型设备驱动 一.注册设备并创建设备文件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 玖富万卡三方服务套餐消费是什么
- 下一篇: linux 其他常用命令