Linux 驅(qū)動(dòng)開(kāi)發(fā)2: IOCTL 操作

IOCTL 示例

  • hello.c

    #include <linux/module.h>
    #include <linux/fs.h>
    #include <linux/cdev.h>
    
    static int major = 0;
    
    static struct cdev mycdev;
    
    #define HELLO_IOC_MAGIC 'W'
    #define HELLO_IOC_NUMMAX 12
    
    #define HELLO_IOC_GET _IO(HELLO_IOC_MAGIC, 1)
    
    long hello_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
    {
        int ret = 0;
    
        if(_IOC_TYPE(cmd) != HELLO_IOC_MAGIC) return -ENOTTY;
        if(_IOC_NR(cmd) >= HELLO_IOC_NUMMAX)  return -ENOTTY;
    
        switch (cmd)
        {
        case HELLO_IOC_GET:
            ret = __put_user(6666, (int __user *)arg);
            printk("HELLO_IOC_GET");
            break;
      
        default:
            break;
        }
      
        return ret;
    }
    
    static struct file_operations fops = {
        .owner = THIS_MODULE,
        .unlocked_ioctl = hello_ioctl
    };
    
    static int hello_init(void)
    {
        int result;
        dev_t dev;
    
        /* 動(dòng)態(tài)創(chuàng)建 */
        result = alloc_chrdev_region(&dev, 0, 1, "hello");
        major = MAJOR(dev);
    
        if(result < 0)
        {
            printk("register device error\n");
            return result;
        }
    
        printk("register device major %d\n", major);
    
        /* 添加字符設(shè)備 */
        cdev_init(&mycdev, &fops);
        mycdev.owner = THIS_MODULE;
        cdev_add(&mycdev, dev, 1);
    
        return 0;
    }
    
    static void hello_exit(void)
    {
        cdev_del(&mycdev);
        unregister_chrdev_region(MKDEV(major, 0), 1);
        printk("unregister device major %d\n", major);
    }
    
    module_init(hello_init);
    module_exit(hello_exit);
    
    MODULE_LICENSE("GPL");
    
  • Makefile

    KDIR ?= /lib/modules/$(shell uname -r)/build
    
    obj-m   := hello.o
    
    modules:
        $(MAKE) -C $(KDIR) M=$(PWD) modules
    
    clean:
        make -C $(KDIR) M=$(PWD) clean
    
  • test.c

    #include <stdio.h>
    #include <sys/ioctl.h>
    #include <fcntl.h>
    
    #define HELLO_IOC_MAGIC 'W'
    #define HELLO_IOC_NUMMAX 12
    
    #define HELLO_IOC_GET _IO(HELLO_IOC_MAGIC, 1)
     
    int main(int argc, char** argv)
    {
      if(argc != 2) 
      {
          printf("usage: %s device (example /dev/hello) \n", argv[0]);
          return -1;
      }
        
      int fd = open(argv[1], O_RDONLY);
      if(fd < 0)
        {
          perror("failed to open device");
          return -1;
      }
    
      int num = 0;
      if(ioctl(fd, HELLO_IOC_GET, &num))
      {
          perror("failed to get num");
          return -1;
      }
    
        printf("get num %d\n", num);
        
      return 0;
    }
    
  • 運(yùn)行

    $ make 
    $ gcc test.c
    $ sudo insmod 
    $ dmesg | tail
    # 獲取主設(shè)備號(hào)
    $ sudo mknod /dev/hello c 244 0
    $ ./a.out /dev/hello
    get num 6666
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容