博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
嵌入式学习笔记(十七)- 字符驱动
阅读量:3739 次
发布时间:2019-05-22

本文共 4531 字,大约阅读时间需要 15 分钟。

字符驱动

  • 如果需要不同设备节点有不同的功能,只需要在注册设备的时候添加不同的file_operations 结构体即可
#include 
#include
// 定义module_param module_param_arrary 函数的头文件#include
// 定义参数函数中perm 参数的枚举量头文件#include
// MKDEV 转换设备号数据类型的宏定义#include
// 三个字符设备号函数#include
// 定义字符设备的结构体#include
// 分配内存空间的函数#include
#defind DEVICE_NAME "dcdev";#defind DEVICE_MINOR_NUM 2;#defind DEVICE_MAJOR 0;// 主设备号#defind DEVICE_MINOR 0;#defind REGDEV_SIZE 3000;#include
;static struct class *myClass;module_init(sdev_init);module_exit(sdev_exit);static int module_arg1,module_arg2;static int int_array[50];static int int_num;int numdev_major = DEVICE_MAJOR;int numdev_minor = DEVICE_MINOR;/**/// 输入主设备号module_param(numdev_major,int,S_IRUSR);// 输入次设备号module_param(numdev_minor,int,S_IRUSR);struct reg_dev{ char* data; unsigned long size; struct cdev cdev;};struct file_operations my_fops = { .owner = THIS_MODULE, .open = chardevnode_open, .release = chardevnode_release, .unlock_ioctl = chardevnode_ioctl, .read = chardevnode_read, .write = chardevnode_write, .llseek = chardevnode_llseek, };/*打开操作*/static int chardevnode_open (struct inode* inode,struct file *file){ printk(KERN_EMERG,"\t chardevnode_open ! \n" ); return 0;}/*关闭操作*/static int chardevnode_release (struct inode* inode,struct file *file){ printk(KERN_EMERG,"\t chardevnode_release ! \n" ); return 0;}/*IO操作*/static long chardevnode_ioctl (struct file *file,unsigned int cmd,unsigned long arg){ printk(KERN_EMERG,"\t chardevnode_ioctl cmd is %d arg is %d! \n",cmd,arg ); return 0;} size_t chardevnode_read (struct file *file,char _user *buf,size_t count,loff_t *f_ops){ printk(KERN_EMERG,"\t chardevnode_read ! \n" ); return 0;} size_t chardevnode_write (struct file *file,const char _user *buf,size_t count,loff_t *f_ops){ printk(KERN_EMERG,"\t chardevnode_write ! \n" ); return 0;} size_t chardevnode_llseek (struct file *file,loff_t offset,int ence){ printk(KERN_EMERG,"\t chardevnode_llseek ! \n" ); return 0;}static void ret_init_cdev(struct reg_dev * dev,int index){ int error; /*数据初始化*/ int devno = MKDEV(numdev_major,numdev_minor+index); cdev_init(&dev->cdev,&my_fops); dev->cdev.owner = THIS_MODULE; dev->cdev.ops = &my_fops; err = cdev_add(&dev->cdev,devno,1); if(err){ printk(KERN_EMERG,"\t cdev_add is fail err is %d \n ",err); }else{ printk(KERN_EMERG,"\t cdev_add success! \n" ); }}struct reg_dev* my_devices;static int sdev_init(void){ int ret = -1; dev_t num_dev; if(numdev_major){ // 如果0 则动态申请 num_dev = MKDEV(numdev_major,numdev_minor); ret = register_chrdev_region(num_dev,DEVICE_MINOR_NUM,DEVICE_NAME); }else{ ret = allo_chrdev_region(&num_dev,numdev_minor,DEVICE_MINOR_NUM,DEVICE_NAME); numdev_major = MAJOR(num_dev); printk(KERN_EMERG,"\t numdev_major %d is failed\n ",numdev_major); } if(!ret){ printk(KERN_EMERG,"\t register_chrdev_region req %d is failed\n ",numdev_major); } myClass = class_create(THIS_MODULE,DEVICE_NAME); my_devices = kmalloc(DEVICE_MINOR_NUM*sizeof(struct reg_dev),GPF_KERNEL); if(!my_devices){ ret = -ENOMEM; goto fail; return 0; } /*初始化设备*/ for(int i = 0 ;i < DEVICE_MINOR_NUM;i++){ my_devices[i].data = kmalloc(REGDEV_SIZE,GFP_KERNEL); memset(my_devices[i].data,0,REGDEV_SIZE); /*设备注册到系统*/ ret_init_cdev(&my_devices[i],i); /*创建设备节点*/ device_create(myClass,NULL,MKDEV(numdev_major,numdev_minor+i),NULL,DEVICE_NAME"%d",i); } memset(my_devices,0,DEVICE_MINOR_NUM * sizeof(struct reg_dev)); printk(KERN_EMERG,"\ dcdev enter!\n "); return 0;fail: /*注销设备号*/ unregister_chrdev_region(MKDEV(numdev_major,numdev_minor),DEVICE_MINOR_NUM); printk(KERN_EMERG,"\kmalloc is fail!\n "); return 0;}static int sdev_exit(void){ int i = 0; printk(KERN_EMERG,"\t cdev is:%d\n ",module_arg2); /*除去字符设备*/ for(i = 0;i < DEVICE_MINOR_NUM;i++){ cdev_del(&(my_devices[i]->cdev)); device_destory(myClass,MKDEV(numdev_major,numdev_minor+i)); } class_destory(myClass); kfree(my_devices); unregister_chrdev_region(MKDEV(numdev_major,numdev_minor),DEVICE_MINOR_NUM); return 0;}

应用程序

#include 
#include
#include
#include
#include
static void main(){
int fd; char *hello_node0 = "/dev/chardevnode0"; char *hello_node1 = "/dev/chardevnode1"; if(fd = open(hello_node0,O_RDWR|O_NDELAY)<0){
printf("APP open %s failed!",hello_node0); }else{
printf("APP open %s success!",hello_node0); } close(fd); if(fd = open(hello_node1,O_RDWR|O_NDELAY)<0){
printf("APP open %s failed!",hello_node1); }else{
printf("APP open %s success!",hello_node1); } close(fd);}

转载地址:http://thoin.baihongyu.com/

你可能感兴趣的文章
LeetCode(SQL)难度-中等
查看>>
Vue.js学习笔记—插值的操作(1)
查看>>
CSS的四种方式实现水平居中
查看>>
RISC-V生态架构浅析(认识RISC-V)
查看>>
? 精美图文带你掌握 JVM 内存布局
查看>>
谈谈go.sum
查看>>
tls 1.2 example
查看>>
GitHub 计划登陆中国,将产生哪些影响与意义?
查看>>
2019 我是怎样熬过来的?
查看>>
【C++学习计划】深入浅出——变量作用域(Day3)
查看>>
策略模式
查看>>
Spring Boot 实战 入门
查看>>
关于web系统整体优化提速总结
查看>>
稳定性三十六计-幂等设计
查看>>
分布式文件系统 - fastDFS
查看>>
BUAA OO 2019 第一单元作业总结
查看>>
格网编码查询方案在项目运用上的进一步探索
查看>>
Matlab适配器模式
查看>>
BUAA-OO-2019 第三单元总结
查看>>
Matlab策略模式
查看>>