流程:
init
{
}
exit
{
}
申请设备号 (动态注册/静态注册) 创建一个字符设备 cdev_alloc
初始化字符设备 cdev_init
设备号和字符设备关联 cdev_add
销毁字符设备 cdev_del
解注册设备号 unregister_chrdev_region
1 设备号
设备号分为主设备号和次设备号主设备号表示一类设备
次设备号表示一类设备中的一个设备
#include
#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)) typedef u_long dev_t;
2 申请设备号
静态注册
#include
extern int register_chrdev_region(dev_t, unsigned, const char *);
函数实现在char_dev.c
int register_chrdev_region(dev_t from, unsigned count, const char *name)
from : 设备号 通过 MKDEV 生成count : 子设备个数
name : 设备名
返回值: 成功返回0, 失败返回负数错误码
动态注册
#include
extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *);
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
const char *name) dev : 设备号指针
baseminor : 子设备第一个编号count : 子设备个数
name : 设备名
返回值: 成功返回0, 失败返回负数错误码
注销设备号
#include
void unregister_chrdev_region(dev_t from, unsigned count) from : 设备号
count: 子设备个数
3 创建字符设备
struct cdev *cdev_alloc(void)
分配一个cdev结构体,使用此结构体描述一个字符设备成功返回一个指针,否则返回NULL
#include
void cdev_del(struct cdev *p) 删除字符设备结构体#include
void cdev_init(struct cdev *cdev, const struct file_operations
*fops)
初始化一个字符设备
cdev :被初始化的字符设备指针fops :字符设备操作函数指针集
int cdev_add(struct cdev *p, dev_t dev, unsigned count) 讲字符设备添加到内核
体指针
p :字符设备结构体指针,cdev_alloc函数成功返回的结构
dev : 设备号 通过动态或静态成功分配的设备号count :子设备个数
返回值:成功返回0, 出错返回负数的错误码
4 创建设备文件
sudo mknod /dev/haha0 c 250 0
/dev/haha0 创建的子设备文件名
c 字符设备
250 主设备号
0 次设备号
会在 /dev 下创建一个haha0的一个字符设备文件,主设备号
250,次设备号0
5 数据拷贝
char user *buf : user 指用户空间的指针
从内核空间向用户空间拷贝数据
static inline long copy_to_user(void user *to, const void *from, unsigned long n)
to :用户空间指针( user) from :数据源
n :拷贝的字节数返回值 0 成功
从用户空间向内核空间拷贝数据
static inline long copy_from_user(void *to, const void user * from, unsigned long n) to :内核buf指针
form:用户空间数据源指针n : 拷贝字节数
返回值 0 成功
注:字符设备驱动测试步骤:
1 编译出hello.ko(make)和test 2 sudo insmod hello.ko
3 cat /proc/devices 查看设备号
4 sudo mknod /dev/haha0 c 250 0
5 sudo ./test
如果打印open /dev/haha0 ok 则驱动正常否则驱动有错,需改正
6 sudo rmmod hello
7 sudo rm -rf /dev/haha0