一、字符设备驱动框架
字符设备驱动按照字节流进行访问,并且只能顺序访问
设备号一共有32位,主设备号(高12位)+次设备号(低20位)
二、注册/注销字符设备驱动API接口
2.1、注册字符设备驱动(入口)
#include <linux/fs.h>
int register_chrdev(unsigned int major, const char *name, const struct file_operations *fops) 函数功能:注册字符设备驱动
参数:
major:主设备号
major > 0:静态指定主设备号的值 不可以和这个目录重复linux@ubuntu:~$ cat /proc/devices
major = 0:动态分配主设备号的值
name:字符设备驱动名字
fops:操作方法结构体
返回值:
major > 0:成功返回0,失败返回1
major = 0:成功返回主设备号的值,失败返回<0的值
2.2 注销字符设备驱动(出口)
void unregister_chrdev(unsigned int major, const char *name)
函数功能:注销字符设备驱动
参数:
major:主设备号的值 name:字符设备驱动名字
返回值:无
三、编写字符设备驱动
#include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #define CNAME "myled" unsigned int major = 0; int myled_open(struct inode *inode, struct file *file) { printk("%s:%s:%d\n",__FILE__,__func__,__LINE__); return 0; } ssize_t myled_read(struct file *file, char __user *ubuf, size_t size, loff_t *loff) { printk("%s:%s:%d\n",__FILE__,__func__,__LINE__); return 0; } ssize_t myled_write(struct file *file, const char __user *ubuf, size_t size, loff_t *loff) { printk("%s:%s:%d\n",__FILE__,__func__,__LINE__); return 0; } int myled_close(struct inode *inode, struct file *file) { printk("%s:%s:%d\n",__FILE__,__func__,__LINE__); return 0; } //操作方法结构体 const struct file_operations fops = { .open = myled_open, .read = myled_read, .write = myled_write, .release = myled_close, }; //入口函数 static int __init demo_init(void) { //注册字符设备驱动 major = register_chrdev(0,CNAME,&fops); if(major < 0){ printk("register chrdev is error\n"); return -EIO; } printk("major = %d\n",major); return 0; //函数的返回值 } //出口函数 static void __exit demo_exit(void) { //注销字符设备驱动 unregister_chrdev(major,CNAME); } module_init(demo_init); //指定入口地址 module_exit(demo_exit); //指定出口地址 MODULE_LICENSE("GPL"); //许可证,遵循GPL协议
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> int main(int argc,const char * argv[]) { int fd = -1; char buf[128] = ""; fd = open("/dev/myled",O_RDWR); if(fd == -1){ perror("open is error\n"); exit(1); } write(fd,buf,sizeof(buf)); read(fd,buf,sizeof(buf)); close(fd); return 0; }