美文网首页
itop4412驱动笔记2

itop4412驱动笔记2

作者: 嵌入式工作 | 来源:发表于2018-08-06 11:22 被阅读0次

    1.生产设备节点

    这里讲解的是杂项设备,杂项设备的主设备固定为10
    misc源代码:“drivers/char/ misc.c,这个是在makefile中强制编译的

    1.1杂项设备注册头文件

    – include/linux/miscdevice.h
    vim include/linux/miscdevice.h

    struct miscdevice  {
            int minor;
            const char *name;
            const struct file_operations *fops;
            struct list_head list;
            struct device *parent;
            struct device *this_device;
            const char *nodename;
            mode_t mode;
    };
    
    extern int misc_register(struct miscdevice * misc);
    extern int misc_deregister(struct miscdevice *misc);
    

    代码添加

    #define MISC_NAME  "hello_misc"//在/dev中显示的名字/
    
    
    MODULE_LICENSE("Dual BSD/GPL");
    MODULE_AUTHOR("TOPEET");
    
    
    struct miscdevice hello_misc= {
            .minor=MISC_DYNAMIC_MINOR;//自动自动生产minor
            .name=MISC_NAME;
            .fops=;
      
    };
    
    int hello_probe(struct platform_device *pdev)
    {
        
      misc_register(&hello_misc);
      printk(KERN_EMERG "hello_probe call \n");
      return 0;
      
    }
    
    int hello_remove(struct platform_device *pdev)
    {
    
        misc_deregister(&hello_misc);
        printk(KERN_EMERG"remove call \n");
        return 0;
    }
    

    2 在misc中加入fs

    include/linux/fs.h

    vim include/linux/fs

    /*
     * NOTE:
     * all file operations except setlease can be called without
     * the big kernel lock held in all filesystems.
     */
    struct file_operations {
            struct module *owner;
            loff_t (*llseek) (struct file *, loff_t, int);
            ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
            ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
            ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
            ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
            int (*readdir) (struct file *, void *, filldir_t);
            unsigned int (*poll) (struct file *, struct poll_table_struct *);
    /* remove by cym 20130408 support for MT660.ko */
    #if 0
    //#ifdef CONFIG_SMM6260_MODEM
    #if 1// liang, Pixtree also need to use ioctl interface...
            int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
    #endif
    #endif
    /* end remove */
            long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
            long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
            int (*mmap) (struct file *, struct vm_area_struct *);
            int (*open) (struct inode *, struct file *);
            int (*flush) (struct file *, fl_owner_t id);
            int (*release) (struct inode *, struct file *);
            int (*fsync) (struct file *, int datasync);
            int (*aio_fsync) (struct kiocb *, int datasync);
            int (*fasync) (int, struct file *, int);
            int (*lock) (struct file *, int, struct file_lock *);
            ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
            unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
            int (*check_flags)(int);
            int (*flock) (struct file *, int, struct file_lock *);
            ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
            ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
            int (*setlease)(struct file *, long, struct file_lock **);
            long (*fallocate)(struct file *file, int mode, loff_t offset,
                              loff_t len);
    /* add by cym 20130408 support for MT6260 and Pixtree */
    #if defined(CONFIG_SMM6260_MODEM) || defined(CONFIG_USE_GPIO_AS_I2C)
            int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
    #endif
    /* end add */
    };
    
    #define IPERM_FLAG_RCU  0x0001
    
                   
    
    

    2.1填充fs

    #include <linux/init.h>
    #include <linux/module.h>
    
    
    /*驱动注册的头文件,包含驱动的结构体和注册和卸载的函数*/
    #include <linux/platform_device.h>
    
    
    #include <linux/miscdevice.h>
    
    #include <linux/fs.h>
    #define DRIVER_NAME "hello"  //必须和设备注册的一致
    #define MISC_NAME  "hello_misc"//在/dev中显示的名字/
    
    
    MODULE_LICENSE("Dual BSD/GPL");
    MODULE_AUTHOR("TOPEET");
    
     long hello_unlocked_ioctl(struct file *pfd, unsigned int cmd, unsigned long arg)
     {
    printk(KERN_EMERG "fs unlocked_ioctl call file:%s cmd:%d  arg:%d \n",pfd,cmd,arg);
     return 0;
     }
     
     int hello_release(struct inode *nd, struct file *pfd)
     {
     printk(KERN_EMERG "fs release call nd:%s file: \n",nd,pfd);
     return 0;    
          
     }
      int hello_open(struct inode *nd, struct file *pfd)
      {
          
           printk(KERN_EMERG "fs open call nd:%s file: \n",nd,pfd);
     return 0;    
      }
     
    struct file_operations hello_fs={
    .owner=THIS_MODULE,
    .open=hello_open,
    .release=hello_release,
    .unlocked_ioctl=hello_unlocked_ioctl,
    };
    
    struct miscdevice hello_misc={
            .minor=MISC_DYNAMIC_MINOR,
            .name=MISC_NAME,
            .fops=&hello_fs,
      
    };
    
    int hello_probe(struct platform_device *pdev)
    {
        
      misc_register(&hello_misc);
      printk(KERN_EMERG "hello_probe call \n");
      return 0;
      
    }
    
    int hello_remove(struct platform_device *pdev)
    {
    
        misc_deregister(&hello_misc);
        printk(KERN_EMERG"remove call \n");
        return 0;
    }
    void hello_shutdown(struct platform_device *pdev)
    {
       printk(KERN_EMERG"shutdown call \n");
    }
    int hello_suspend(struct platform_device *pdev, pm_message_t state)
    {
         printk(KERN_EMERG"suspend call \n");
        return 0;
    }
    int hello_resume(struct platform_device * pdev)
    {
        
         printk(KERN_EMERG"resume call \n");
        return 0;
    }
    
    struct platform_driver  stu_hello={
            .probe=hello_probe,
            .remove=hello_remove,
            .shutdown=hello_shutdown,
            .suspend=hello_suspend,
            .resume=hello_resume,
           .driver={
               .name = DRIVER_NAME,
               .owner = THIS_MODULE,
           },
        
    };
    
    static int hello_init(void)
    {
        int err;
        printk(KERN_EMERG "hello world enter\n");
        err=platform_driver_register(&stu_hello);
         printk(KERN_EMERG "register result:%d\n",err);
        return 0;
    }
    
    static void hello_exit(void)
    {
        printk(KERN_EMERG "hello world exit\n");
        platform_driver_unregister(&stu_hello);
    
    }
    module_init(hello_init);
    module_exit(hello_exit);
    
    
    
    

    2.2运行结果 insmode 和 rmmod

    中间在dev中可以看到hello_misc

    ls /dev/


    image.png
    [root@iTOP-4412]# insmod /mnt/udisk/hello_driver.ko 
    [ 3768.651034] hello world enter
    [ 3768.660692] hello_probe call 
    [ 3768.670667] register result:0
    
    
    
    hello_driver 2109 0 - Live 0xbf000000
    [root@iTOP-4412]# rmmod hello_driver
    [ 4077.111126] hello world exit
    [ 4077.113711] remove call 
    

    2.3编写应用程序测试

    打印头文件
    – include <stdio.h>调用打印函数printf
    • 应用中调用文件需要的头文件
    – #include <sys/types.h>基本系统数据类型。系统的基本数据类型在 32 编译
    环境中保持为 32 位值,并会在 64 编译环境中增长为 64 位值。
    – #include <sys/stat.h>系统调用函数头文件。可以调用普通文件,目录,管
    道,socket,字符,块的属性
    – #include <fcntl.h>定义了open函数
    – #include <unistd.h>定义了close函数
    – #include <sys/ioctl.h>定义了ioctl函数

    #include "stdio.h"
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>//定义了open函数
    #include <unistd.h>//定义了close函数
    #include <sys/ioctl.h>//定义了ioctl函数
    
    
    int main()
    {
         char *device="/dev/hello_misc";
        int fd = open(device,O_RDWR|O_NDELAY);
        if(fd<0)
        {
            printf("open file %s err \n",device);
            
        }else
        {
            
            printf("open file %s seuccess \n",device);
            ioctl(fd,123,678);
            
        }
    
    
        
        
        close(fd);
        
    }
    

    相关文章

      网友评论

          本文标题:itop4412驱动笔记2

          本文链接:https://www.haomeiwen.com/subject/jwrwvftx.html