1、字符设备驱动框架
1.1字符设备
定义: 只能以一个字节一个字节的方式读写的设备,不能随机读取设备中的某一段数据,读取数据需要按照先后顺序。(字符设备是面向字节流的)。
常见的字符设备:鼠标、键盘、 串口、控制台
块设备:可以从设备的任意位置读取一定长度数据的设备
常见的块设备:硬盘、磁盘、光盘、U盘 SD卡 tf卡
1.2 字符设备驱动框架
Init流程:---》HelloModule
{
申请设备号(静态申请 动态申请)
创建一个字符设备
初始化字符设备
d.将设备号和字符设备关联起来
}
Exit流程:---》HelloExit
{
1.删除字符设备
2.删除设备号
}
1.2.1 设备号
定义:设备在内核中的身份和标识,是内核区分不同设备的唯一信息,设备号是由主设备号和次设备号构成,主设备号表示一类设备,次设备号表示该类设备中的某一个设备。
设备号:是一个32bit的无符号整数,高12bit是主设备号,低20bit是次设备号。
《linux/kdev_t.h》
#define MINORBITS20
#define MINORMASK((1U << MINORBITS) - 1)
#define MAJOR(dev)((unsigned int) ((dev) >> MINORBITS))
#define MINOR(dev)((unsigned int) ((dev) & MINORMASK))
#define MKDEV(ma,mi)(((ma) << MINORBITS) | (mi))
1.2.2 申请设备号
申请设备号有两种方式:静态申请和动态申请。
静态申请设备号:
Int Register_chrdev_region(dev_t from, unsigned count,const char *name)
作用:静态申请设备号
From:设备号(由主次设备号构成)
Count:子设备个数
*name:设备名称
返回值:0成功 非0失败
Void unregister_chrdev_region(dev_t from,unsigned count)
作用:从内核中移除设备号
From:设备号(由主次设备号构成)
Count:子设备个数
//hello.c
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
int g_major=168;
int g_min=0;
int g_DevNum=0;
char *g_DevName = "test11";
int HelloModule(void)
{
int ret=0;
printk("into hello Module-----------\r\n");
g_DevNum=MKDEV(g_major, g_min);
ret = register_chrdev_region(g_DevNum,1,g_DevName);
if(ret!=0)
{
printk("register device number error----\r\n");
return ret;
}
printk("1:register device number ok!------\r\n");
return 0;
}
void HelloExit(void)
{
printk("into hello exit---------\r\n");
unregister_chrdev_region(g_DevNum, 1);
printk("leave hello exit-----------\r\n");
}
module_init(HelloModule);
module_exit(HelloExit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("test driver module by 22101");
MODULE_AUTHOR("Shixh");
MODULE_ALIAS("hehe");
cat /proc/devices 查看所有系统已经分配的设备号
动态申请设备号:
Int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count , const char*name)
作用:动态申请设备号
Dev:指向设备号的指针
Baseminor:子设备的第一个编号
*name:设备名称
·