一、字符设备驱动框架
字符设备驱动按照字节流进行访问,并且只能顺序访问
设备号一共有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; }