字符驱动模板

来源:互联网 发布:淘宝网十字绣架子 编辑:程序博客网 时间:2024/05/22 06:48

led_app.c

#include <stdio.h>#include <stdlib.h>#include <sys/types.h>  #include <sys/stat.h>  #include <fcntl.h> #include <linux/ioctl.h> //定义命令需要加此头文件#include <sys/epoll.h>//#include <poll.h>//#include <fcntl.h>//#include <stdio.h>//#include <stdlib.h>//#include <sys/epoll.h>#include <unistd.h>#include <sys/poll.h>#define LED_IO_MAGIC 'k'#define LED_READ _IO(LED_IO_MAGIC,0x10)#define LED_WRITE _IO(LED_IO_MAGIC,0x11)static intepoll_register( int  epoll_fd, int  fd )//epoll登记{    struct epoll_event  ev;    int ret, flags;    /* important: make the fd non-blocking 重要:使fd为非阻塞*/    flags = fcntl(fd, F_GETFL);    fcntl(fd, F_SETFL, flags | O_NONBLOCK);    ev.events  = EPOLLIN;    ev.data.fd = fd;//    do {        ret = epoll_ctl( epoll_fd, EPOLL_CTL_ADD, fd, &ev );//注册新的fd到epoll_fd中 //   } while (ret < 0);    return ret;}static intepoll_deregister( int  epoll_fd, int  fd )//epoll注销{    int  ret;//    do {        ret = epoll_ctl( epoll_fd, EPOLL_CTL_DEL, fd, NULL );//从epoll_fd中删除一个fd//    } while (ret < 0);    return ret;}int main(void){int fd = 0;unsigned int cmd = 0;int arg = 0;fd = open("/dev/ledtest",O_RDWR);if(fd < 0){printf("open led dev error !\n");return -1;}else{printf("open led ok !\n");}/**********************************/char Buf[128];memset(Buf,0,sizeof(Buf));int fd1,fd2,fd3,fd4,fd5;fd1 = open("./txt01.txt",O_RDWR);fd2 = open("./txt02.txt",O_RDWR);fd3 = open("./txt03.txt",O_RDWR);fd4 = open("./txt04.txt",O_RDWR);fd5 = open("./txt05.txt",O_RDWR);if(fd1 < 0){printf("open txt01.txt failed !\n");return 0;}else{printf("open txt(1-5).txt success !\n");//return -1;}int epoll_fd   = epoll_create(5);//创建一个epoll句柄,内核需监听2个fd    epoll_register( epoll_fd, fd1 );    epoll_register( epoll_fd, fd2 );    epoll_register( epoll_fd, fd3 );    epoll_register( epoll_fd, fd4 );    epoll_register( epoll_fd, fd5 );    printf("<-----call cmd test----->\n");cmd = LED_READ;printf("cmd = 0x%x\n",cmd);if(ioctl(fd, cmd, &arg) < 0){printf("Call cmd LED_COMMAND1 fail\n");  return -1;}cmd = LED_WRITE;printf("cmd = 0x%x\n",cmd);if(ioctl(fd, cmd, &arg) < 0){printf("Call cmd LED_COMMAND2 fail\n");  return -1;}printf("led cmd test success ! \n"); /*检测结果*/read(fd, Buf, 10);printf("Read BUF: %s\n",Buf);    epoll_deregister( epoll_fd, fd1 );    epoll_deregister( epoll_fd, fd2 );    epoll_deregister( epoll_fd, fd3 );    epoll_deregister( epoll_fd, fd4 );    epoll_deregister( epoll_fd, fd5 );close(fd);return 0;}


led_drv.c

#include <linux/module.h>//module#include <linux/kernel.h>//kernel#include <linux/init.h>//init#include <linux/fs.h>//filesystem#include <linux/device.h>//device#include <linux/cdev.h>//char device#include <linux/slab.h>//#include <linux/uaccess.h>//#include <linux/ioctl.h>//#include <asm-generic/ioctl.h>////#include <stdio.h>#include "led_drv.h"#define LED_IO_MAGIC 'k'#define LED_READ _IO(LED_IO_MAGIC,0x10)#define LED_WRITE _IO(LED_IO_MAGIC,0x11)#define LED_IOC_MAXNR 0x11 static dev_t dev_num;//static struct cdev cdev;static struct cdev *led_cdev = NULL;static struct class *myclass = NULL; struct device *device = NULL; static charbuf1[10];int fd1,fd2,fd3,fd4,fd5;static int led_open(struct inode *inode, struct file *file){printk("led_open have done ! \n ");/*fd1 = open("./txt01.txt",O_RDWR);fd2 = open("./txt02.txt",O_RDWR);fd3 = open("./txt03.txt",O_RDWR);fd4 = open("./txt04.txt",O_RDWR);fd5 = open("./txt05.txt",O_RDWR);if((fd1 && fd2 && fd3 && fd4 && fd5) == 0){printk("open txt(1-5).txt success !\n");return 0;}else{printk("open txt01.txt failed !\n");return -1;}int epoll_fd   = epoll_create(5);//创建一个epoll句柄,内核需监听2个fd    epoll_register( epoll_fd, fd1 );//登记监听类型,控制命令类消息文件    epoll_register( epoll_fd, fd2 );//登记监听类型,数据类消息文件*/return 0;}static int led_release(struct inode *inode, struct file *file){printk("led_release have done ! \n ");return 0;}/* seek文件定位函数 */static loff_t mem_llseek(struct file *filp, loff_t offset, int whence){     loff_t newpos;    switch(whence) {      case 0: /* SEEK_SET */        newpos = offset;        break;      case 1: /* SEEK_CUR */        newpos = filp->f_pos + offset;        break;      case 2: /* SEEK_END */        newpos = MEMDEV_SIZE -1 + offset;        break;      default: /* can't happen */        return -EINVAL;    }    if ((newpos<0) || (newpos>MEMDEV_SIZE))    return -EINVAL;        filp->f_pos = newpos;    return newpos;}static ssize_t led_read(struct file *file, char __user *ubuf, size_t size, loff_t *offset){struct file *fp;mm_segment_t fs;//定义一个fsloff_t pos;fp = filp_open("/home/zijixie/epoll/txt01.txt",O_RDWR|O_CREAT,0644);if(IS_ERR(fp)){printk("create file error/n");return -1;}fs=get_fs();//把当前的fs保存下来set_fs(KERNEL_DS);//设置当前fs为内核fsget_fs() == KERNEL_DS, checking is bypassed. pos=0;  vfs_read(fp,charbuf1,sizeof(charbuf1),&pos); printk("read:%s/n",charbuf1);memcpy(ubuf, charbuf1, 10);filp_close(fp,NULL);  set_fs(fs);//在读写文件后再恢复原先fsprintk("led_read have done ! \n ");return 0;}static ssize_t led_write(struct file *file,char __user *ubuf,size_t size,loff_t *offset){printk("led_write have done ! \n ");return 0;}static long led_ioctl(struct file *s_file, unsigned int cmd,unsigned long arg){/*检测命令的有效性*/   if (_IOC_TYPE(cmd) != LED_IO_MAGIC)//检验幻术{printk("MEMDEV_IOC_MAGIC ERROR ! \n");return -EINVAL;  }   if (_IOC_NR(cmd) > LED_IOC_MAXNR)   //是否越界{printk("MEMDEV_IOC_MAXNR ERROR ! \n");        return -EINVAL;  }switch(cmd){case LED_READ:printk("User send LED_READ.\n");break;case LED_WRITE:printk("User send LED_WRITE.\n");break;default:printk("COMMAND ERROR !!! \n");}printk("led_ioctl have done ! \n ");return 0;}static struct file_operations led_fops = {.open = led_open,.release = led_release,.read = led_read,.write = led_write,.owner = THIS_MODULE,.llseek = mem_llseek,//用户调用.unlocked_ioctl = led_ioctl,};static int led_init(void){int ret;led_cdev = cdev_alloc();if(led_cdev == NULL){printk("LED_cdev_alloc error\n");return -ENOMEM;}cdev_init(led_cdev, &led_fops);//step1ret = alloc_chrdev_region(&dev_num, 0, 1, "ledtest");//step2设备号名字if(ret != 0){printk("fail to alloc_chrdev_region ! \n ");goto err_alloc_chrdev_region;}ret = cdev_add(led_cdev, dev_num, 1);if(ret != 0){printk("fail to add dev_num to cdev ! \n ");goto err_cdev_add;}myclass = class_create(THIS_MODULE, "ledtest");if(IS_ERR(myclass)){printk("fail to class_create. \n");ret = PTR_ERR(myclass);goto err_class_create;}device = device_create(myclass, NULL, dev_num, NULL, "ledtest");///dev/ledtestif(IS_ERR(device)){printk("fail to deice_create \n");ret = PTR_ERR(device);goto err_device_create;}printk("ledtest driver registered ! \n");return 0;err_device_create:class_destroy(myclass);err_class_create:cdev_del(led_cdev);err_cdev_add:unregister_chrdev_region(dev_num, 1);err_alloc_chrdev_region:return ret;}static int led_exit(void){device_destroy(myclass, dev_num);//1class_destroy(myclass);//2cdev_del(led_cdev);//3unregister_chrdev_region(dev_num, 1);//4return 0 ;}MODULE_LICENSE("GPL");MODULE_AUTHOR("FU HANG");module_init(led_init);module_exit(led_exit);


led_drv.h

#ifndef _LED_DRV_H_#define _LED_DRV_H_#ifndef MEMDEV_SIZE#define MEMDEV_SIZE 4096#endif/*mem设备描述结构体*/struct mem_dev                                     {                                                          char *data;                           //数据指针  unsigned long size; //尺寸  wait_queue_head_t inq;  //等待队列};#endif /* _LED_DRV_H_ */


阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 求爱反斗星粤语 王牌快穿求爱男神要抱抱 狗求爱叫声音效试听 荒野求爱 第二季 爱情怎么喊停 爱情人 是爱情 什么的爱情 的爱情 爱情图片下载 感人的爱情 爱情像什么 轰轰烈烈的爱情 好像是爱情 为什么爱情 普通的爱情 爱情唯美图 爱情有没友 四个字爱情 适合的爱情 又来了爱情 你说的爱情 搁浅的爱情 爱情冷读术 爱情流放地 被病娇女友疯狂求爱 今天也在向白月光求爱 个人求租房屋怎么写 求租图片 求租叉车 求租写字楼办公 个人求租信息 求租一室一厅 上海厂房求租 求租店面 天津求租 仓库求租网 求租门面 求租房子一室一厅 求租车位 求租门面房无转让费的