代码学习inux内核驱动(六)

代码学习inux内核驱动(六)

字符驱动设备

#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/delay.h>


MODULE_AUTHOR("xyzeng");
MODULE_LICENSE("Dual BSD/GPL");
/********************************************************
字符设备驱动:
linux系统将设备分为3类:字符设备、块设备、网络设备
字符设备是面向流的设备、只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据


int register_chrdev_region(dev_t from, unsigned count, const char *name) //静态注册dev_id

dev_t MKDEV(ma,mi)
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
struct cdev *cdev_alloc(void)
int alloc_chrdev_region(dev_t * dev, unsigned baseminor, unsigned count, const char * name) //分配+注册dev_id
int cdev_add(struct cdev *p, dev_t dev, unsigned count)

void cdev_del(struct cdev *p)
void unregister_chrdev_region(dev_t from, unsigned count)
inline int register_chrdev(unsigned int major, const char *name,const struct file_operations *fops)  //  alloc_chrdev_region + cdev_add

手动创建设备节点:mknod filename type major minor


udev设备文件系统:
devtmpfs 文件系统,即/dev 目录,
udev 是一个工作在用户空间的工具,udev 必须内核中的sysfs和tmpfs支持,根据sysfs事件进行设备节点的创建删除
(devfs文件系统工作在内核,被抛弃)
自动创建设备节点:
1、调用class_create(...)为该设备创建一个class,
2、再为每个设备调用device_create(...)创建对应的设备。

void device_destroy(struct class *class, dev_t devt)
void class_destroy(struct class *cls)

struct device *device_create(struct class *class, struct device *parent,
            dev_t devt, void *drvdata, const char *fmt, ...)

int class_create_file(struct class *class,const struct class_attribute *attr)

//1 实现多个进程间文件描述符的传递
//2 实现 一个进程 打开的是同一个struct file
********************************************************/


int hello_open (struct inode * node, struct file * pfile)
{
    return 0;
}

ssize_t hello_read (struct file * pfile, char __user * pchar, size_t size, loff_t * off)
{
    
   char * pstr = "hello fdfdf hell dfdfdffdfdf\n";
   copy_to_user(pchar,pstr,strlen(pstr));
    // printk("copy_to_user :%d\n",strlen(pstr));
    *off +=  strlen(pstr);
    static long temp = 1024*2;
    temp -= *off;
 
    if((temp -64) > 0) 
        return temp;
     else{
        temp = 1024*2;
        *off =0;
        return 0 ;
     }
     
}
ssize_t hello_write (struct file * pfile , const char __user * pchar, size_t size , loff_t * off)
{
  
    char hello[64] ={0};
   // int offset = get_user(*off, offset)
    
    copy_from_user(hello,pchar,size);
    printk("hello_write off:%d,size:%d,pchar:%s\n",*off,size,hello);
    return size;
}
long hello_unlocked_ioctl (struct file * pfile, unsigned int cmd , unsigned long arg)
{
    printk("hello_read :pfile:%p\n",pfile);
    msleep(10*10000);
    return 0;
}

struct file_operations hello_fop = {
    //.open = hello_open,
    .read = hello_read,
    .write = hello_write,
    .unlocked_ioctl = hello_unlocked_ioctl, //32位应用对32kernel,64位应用对64kernel
    // .compat_ioctl = hello_compat_ioctl,   //支持32位应用对64位kernel的调用
};

static struct cdev hello_cdev ={
    .owner = THIS_MODULE,
    .ops = &hello_fop,
};

static struct class *cls;
dev_t devid;

static int code_case_cdev_init( void )
{
#if 0
    major = register_chrdev(0, "hello", &fop);
    printk("register_chrdev :major :%d\n",major);
#else       
    devid = MKDEV(0,0); 
    //int ret = register_chrdev_region(devid,1,"hello_hello");
    cdev_init(&hello_cdev,&hello_fop);
    //向系统申请并注册设备号
    int ret = alloc_chrdev_region(&devid,0,1,"hello_hello");    
    ret = cdev_add(&hello_cdev,devid,1);
    printk("ret=%d,devid:%x\n",ret,devid);
       
    cls = class_create(THIS_MODULE, "hello_ko");
    //class_create_file
    if(cls != NULL){
        device_create(cls, NULL,devid, NULL, "hello0"); /* /dev/hello0 */
    } else {
        printk("class_create: NULL\n");
    }
   
   return 0;

#endif
}
static void code_case_cdev_exit( void )
{  

    device_destroy(cls, devid);
    class_destroy(cls); 
    cdev_del(&hello_cdev);
    unregister_chrdev_region(devid, 1);    
}


module_init(code_case_cdev_init);
module_exit(code_case_cdev_exit);




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值