zoukankan      html  css  js  c++  java
  • uio中断简化版

    1、内核态
    struct uio_info irq_info =
    {
    .name = "fpga_irq2",
    .version = "0.1",
    .irq = 155,
    .irq_flags = IRQ_TYPE_LEVEL_HIGH | IRQF_SHARED | IRQF_DISABLED,
    .handler = irq2_handler, //disable_irq_nosync(irq);uio_event_notify(info);
    .irqcontrol = irq_irqcontrol,//case: enable_irq(info->irq);disable_irq_nosync
    };
    uio_register_device(pdev, &irq_info); //pdev指向一个字符设备

    2、用户态
    fd = open(xx)
    while(1) { read , handle, write}

    内核态:

    #include <linux/init.h>  
    #include <linux/version.h>  
    #include <linux/module.h>  
    #include <linux/mm.h>  
    #include <linux/cdev.h>  
    #include <linux/sched.h>
    #include <linux/uaccess.h>  
    #include <linux/proc_fs.h>  
    #include <linux/fs.h>  
    #include <linux/seq_file.h>   
    #include <linux/platform_device.h>
    #include <linux/uio_driver.h>
    #include <asm/io.h>
    #include <linux/slab.h> /* kmalloc, kfree */
    #include <linux/irq.h> /* IRQ_TYPE_EDGE_BOTH */
    #include <asm/uaccess.h>  
    
    
    #if 1
    static irqreturn_t my_interrupt(int irq, void *dev_id)
    {
        struct uio_info *info = (struct uio_info *)dev_id;
    
        disable_irq_nosync(info->irq);
        
        uio_event_notify(info);
    
        return IRQ_RETVAL(IRQ_HANDLED);
    }
    
    static int irq_control(struct uio_info *info, s32 irq_on)
    {
        if(irq_on) 
            enable_irq(info->irq);
        else 
            disable_irq_nosync(info->irq);
    
        return 0;
    }
    
    struct uio_info irq_info = {  
        .name = "uio_irq",
        .version = "0.1",
        .irq = 10, 
        .handler = my_interrupt,
        .irq_flags = IRQ_TYPE_EDGE_RISING, 
        .irqcontrol = irq_control, 
    };
    #endif
    
    #if 1
    
    #define IO_CMD_LEN      256  
    #define CHAR_DEV_NAME   "kdev"
    
    static int user_cmd_proc(char *user_cmd, char *out_str)
    {
        if(strncmp(user_cmd, "sendsig", 7) == 0) {
            uio_event_notify(&irq_info);
            sprintf(out_str, "send ok
    ");
        }
        
        return 0;
    }
      
    int mem_open(struct inode *inode, struct file *filp)  
    {  
        return 0;   
    }  
      
    int mem_release(struct inode *inode, struct file *filp)  
    {  
        return 0;  
    }  
    
    char user_cmd[IO_CMD_LEN] = {0};
    char out_str[IO_CMD_LEN] = {0};
    
    static int mem_ioctl( struct file *file, unsigned int cmd, unsigned long arg)
    {    
        printk("mem_ioctl: %d 
    ", cmd);    
        
        if(copy_from_user(user_cmd,  (int *)arg, IO_CMD_LEN)) 
            return -EFAULT;
        
        user_cmd_proc(user_cmd, out_str);
        
        if(copy_to_user( (int *)arg, out_str, IO_CMD_LEN)) 
            return -EFAULT;
        
        return 0;
    }
    
    static int mem_major = 0;
    struct class *pclass = NULL;  
    struct cdev my_dev;   
    struct device *pdev;   
    
    static const struct file_operations mem_fops =  
    {  
        .owner = THIS_MODULE,  
        .unlocked_ioctl = mem_ioctl,
        .open = mem_open,  
        .release = mem_release,  
    };  
    
    static int memdev_init(void)  
    {  
        int result;  
    
        dev_t devno = MKDEV(mem_major, 0);  
    
        if (mem_major) { /* 静态申请设备号*/  
            result = register_chrdev_region(devno, 2, CHAR_DEV_NAME);  
        } else { /* 动态分配设备号 */  
            result = alloc_chrdev_region(&devno, 0, 2, CHAR_DEV_NAME);  
            mem_major = MAJOR(devno);  
        }   
    
        if (result < 0)  {  
            printk("alloc_chrdev failed!
    ");  
            return result;  
        }  
    
        cdev_init(&my_dev, &mem_fops);  
        my_dev.owner = THIS_MODULE;  
        my_dev.ops = &mem_fops;  
        cdev_add(&my_dev, MKDEV(mem_major, 0), 2);   /*设备数2*/  
    
        pclass = class_create(THIS_MODULE, CHAR_DEV_NAME);  
        if (IS_ERR(pclass))  {  
            printk("class_create failed!
    ");  
            goto failed;  
        }  
    
        pdev = device_create(pclass, NULL, devno, NULL, CHAR_DEV_NAME);  
        uio_register_device(pdev, &irq_info); //todo
        
        return 0;  
    
    failed:   
        cdev_del(&my_dev);
        unregister_chrdev_region(devno, 1);  
        return result;  
    }  
      
    static void memdev_exit(void)  
    {  
        uio_unregister_device(&irq_info); //todo
        device_destroy(pclass, MKDEV(mem_major, 0));  
        class_destroy(pclass);
        
        cdev_del(&my_dev);
        unregister_chrdev_region(MKDEV(mem_major, 0), 2); 
    }  
    #endif
      
    MODULE_AUTHOR("derek yi");  
    MODULE_LICENSE("GPL");  
      
    module_init(memdev_init);  
    module_exit(memdev_exit);  

    用户态:

    #include <stdio.h>  
    #include <fcntl.h>  
    #include <stdlib.h>  
    #include <pthread.h>
    #include <string.h>
    #include <sys/syscall.h>
    #include <sys/types.h>  
    #include <sys/stat.h>
    #include <unistd.h>
    #include <sys/ioctl.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <signal.h>
    #include <sys/syscall.h>
    #include <sys/mman.h>  
    
    int thread_1(void)  
    {
        int uio_fd;
        int c, ret;
    
        uio_fd  = open("/dev/uio0", O_RDWR); ///sys/class/uio/uio0/name: uio_irq
        if(uio_fd < 0) {
            fprintf(stderr, "open: %s
    ", strerror(errno));
            exit(-1);
        }
    
        while (1) {
            ret = read(uio_fd, &c, sizeof(int));
            if (ret > 0) {
                printf("current event count %d
    ", c);
                c = 1;
                write(uio_fd, &c, sizeof(int));
            }
        }
    
        close(uio_fd);
    
        return 0;
    }  
    
    #define IO_CMD_LEN      256  
    char kdev_io_buf[IO_CMD_LEN] = {0};
    
    int main()
    {
        pthread_t my_thread;
        int char_fd, ret, i;
    
        char_fd  = open("/dev/kdev", O_RDWR);
        if(char_fd < 0) {
            fprintf(stderr, "open: %s
    ", strerror(errno));
            exit(-1);
        }
    
        ret = pthread_create(&my_thread, NULL, (void *)thread_1, NULL);  
        if(ret != 0)  
        {  
            printf("Create pthread error!
    ");  
            return -1;  
        }  
        sleep(1);
    
        for(i = 0; i < 10; i++){
            sprintf(kdev_io_buf, "sendsig");
            ret = ioctl(char_fd, 0, kdev_io_buf);
            printf("ioctl: ret=%d rdata:%s
    ", ret, kdev_io_buf);
            sleep(1);
        }
    
        close(char_fd);
    
        return 0;
    }

    测试:

    derek@ubox:~/share/ldd5$ sudo insmod myuio.ko 
    derek@ubox:~/share/ldd5$ gcc app.c -lpthread
    derek@ubox:~/share/ldd5$ sudo ./a.out 
    ioctl: ret=0 rdata:send ok
    
    current event count 1
    ioctl: ret=0 rdata:send ok
    
    current event count 2
    ioctl: ret=0 rdata:send ok
    
    current event count 3
    ioctl: ret=0 rdata:send ok
    
    current event count 4
    ioctl: ret=0 rdata:send ok
    
    current event count 5
    ioctl: ret=0 rdata:send ok
    
    current event count 6
    ioctl: ret=0 rdata:send ok
    
    current event count 7
    ioctl: ret=0 rdata:send ok
    
    current event count 8
    ioctl: ret=0 rdata:send ok
    
    current event count 9
    ioctl: ret=0 rdata:send ok
    
    current event count 10
  • 相关阅读:
    React学习笔记
    士兵杀敌(一)
    网络爬虫Java实现抓取网页内容
    德莱联盟
    计算球体积
    在页面上 获取键盘事件
    一起玩转mysql
    腾讯云 做出的 不错的 动画 chrome小插件
    jquery MD5
    json to xml
  • 原文地址:https://www.cnblogs.com/soul-stone/p/6721371.html
Copyright © 2011-2022 走看看