uio驱动编写 实例2 //增加了中断部分

2023-05-16

http://blog.csdn.net/ganggexiongqi/article/details/6794215

AUTHOR: Joseph Yang (杨红刚) <ganggexiongqi@gmail.com>
CONTENT: uio驱动编写 实例2
NOTE: Linux-3.0
LAST MODIFIED:09-20-2011
-----------------------------------------------------------------------------------------------------------
Distributed and Embedded System Lab (分布式嵌入式系统实验室,兰州大学)
===============================================================

第一个例子: uio驱动编写 实例


原理简述:

在第一个例子的基础上,增加了中断部分。但是,我们没有实际产生中断的硬件。但是我们可以”模拟“硬件中断。

每当中断发生时,uio_event_notify 将被调用,用来对设备的中断事件计数器()增一,并通知各读进程,
有数据可读。所以,我们通过内核定时器,来周期性的产生中断,而在定时器的处理程序中

调用uio_event_notify,从而产生的效果和有硬件是相同。


如下,是内核部分 simple1.c

[cpp] view plain copy print ?
  1. /** 
  2. *  This is a simple demon of uio driver. 
  3. *  Last modified by  
  4.         09-20-2011   Joseph Yang(Yang Honggang)<ganggexiongqi@gmail.com> 
  5. * 
  6. * Compile:   
  7. *   Save this file name it simple.c 
  8. *   # echo "obj-m := simpleX.o" > Makefile 
  9. *   # make -Wall -C /lib/modules/`uname -r`/build M=`pwd` modules 
  10. * Load the module: 
  11. *   #modprobe uio 
  12. *   #insmod simpleX.ko 
  13. */  
  14.   
  15. #include <linux/module.h>  
  16. #include <linux/platform_device.h>  
  17. #include <linux/uio_driver.h>  
  18. #include <linux/slab.h> /* kmalloc, kfree */  
  19. #include <linux/device.h> /* class_create */  
  20. #include <linux/kobject.h> /* kobject_uevent */  
  21. #define FREQ HZ   
  22.   
  23. static long freq = FREQ;  
  24. static long my_event_count = 0;  
  25.   
  26. struct uio_info kpart_info = {  
  27.         .name = "kpart",  
  28.         .version = "0.1",  
  29.         .irq = UIO_IRQ_NONE,  
  30. };  
  31.   
  32. static int drv_kpart_probe(struct device *dev);  
  33. static int drv_kpart_remove(struct device *dev);  
  34. static struct device_driver uio_dummy_driver = {  
  35.         .name = "kpart",  
  36.         .bus = &platform_bus_type,  
  37.         .probe = drv_kpart_probe,  
  38.         .remove = drv_kpart_remove,  
  39. };  
  40.   
  41. static struct timer_list poll_timer;// generate interruption   
  42.   
  43. static void drv_kpart_timer(unsigned long data)  
  44. {  
  45.         struct uio_info *info = (struct uio_info *)data;  
  46.         unsigned long *addr = (unsigned long *)info->mem[0].addr;  
  47.          unsigned long swap = 0;  
  48.    
  49.         if (my_event_count == 0) {  
  50.                 printk(KERN_EMERG"first timer interrupt \n");  
  51.                 *addr = my_event_count;  
  52.         } else if (my_event_count == 10){  
  53.                 printk(KERN_EMERG"timer interrupt happened 10 times\n"  
  54.                                 "it works well\n");  
  55.         }  
  56.         swap = *addr;  
  57.         if ( swap != my_event_count){  
  58.                 printk(KERN_EMERG"counter reset\n");  
  59.                 my_event_count = swap;  
  60.         } else {  
  61.                my_event_count++;  
  62.                *addr = my_event_count;  
  63. //             printk(KERN_EMERG"update counter \n");  
  64.         }  
  65. //      *addr = my_event_count;  
  66.         uio_event_notify(&kpart_info); // gernerate a interrupt here  
  67.         mod_timer(&poll_timer, jiffies + freq); // reset the timer  
  68. }  
  69.   
  70. static int drv_kpart_probe(struct device *dev)  
  71. {  
  72.   
  73.         printk(KERN_EMERG"----->  /// drv_kpart_probe( %p)\n", dev);  
  74.         kpart_info.mem[0].addr = (unsigned long)kmalloc(1024,GFP_KERNEL);  
  75.   
  76.         if(kpart_info.mem[0].addr == 0)  
  77.                 return -ENOMEM;  
  78.         kpart_info.mem[0].memtype = UIO_MEM_LOGICAL;  
  79.         kpart_info.mem[0].size = 1024;  
  80.         // for the timer interruption  
  81.         kpart_info.irq_flags = UIO_IRQ_CUSTOM;   
  82.   
  83.         if( uio_register_device(dev, &kpart_info)){  
  84.                 kfree((void *)kpart_info.mem[0].addr);  
  85.                 return -ENODEV;  
  86.         }  
  87.         //initiate and add the timer  
  88.         init_timer(&poll_timer);  
  89.         poll_timer.data = (unsigned long)&kpart_info;  
  90.         poll_timer.function = drv_kpart_timer;  
  91.         mod_timer(&poll_timer, jiffies + freq);//set timer  
  92.   
  93.         return 0;  
  94. }  
  95.   
  96. static int drv_kpart_remove(struct device *dev)  
  97. {  
  98.     uio_unregister_device(&kpart_info);  
  99.       
  100.     //delet the timer  
  101.     del_timer_sync(&poll_timer);  
  102.   
  103.     return 0;  
  104. }  
  105.   
  106. static struct platform_device * uio_dummy_device;  
  107.   
  108. static int __init uio_kpart_init(void)  
  109. {  
  110.         uio_dummy_device = platform_device_register_simple("kpart", -1,  
  111.                         NULL, 0);  
  112.         printk("&platform_device->dev = (%p)\n", &uio_dummy_device->dev);  
  113.         return driver_register(&uio_dummy_driver);  
  114.   
  115. }  
  116.   
  117. static void __exit uio_kpart_exit(void)  
  118. {  
  119.         platform_device_unregister(uio_dummy_device);  
  120.         driver_unregister(&uio_dummy_driver);  
  121. }  
  122.   
  123. module_init(uio_kpart_init);  
  124. module_exit(uio_kpart_exit);  
  125.   
  126. MODULE_LICENSE("GPL");  
  127. MODULE_AUTHOR("Benedikt Spranger");  
  128. MODULE_DESCRIPTION("UIO dummy driver");  

这是用户空间的测试部分。

我们通过mmap返回的地址addr跟驱动的内核部分进行交互。在用户空间写入addr的值0,可以重新设置驱动内核部分的

内部变量my_event_count。从而驱动程序会打印出”update counter“提示。

[cpp] view plain copy print ?
  1. #include <stdio.h>  
  2. #include <fcntl.h>  
  3. #include <stdlib.h>  
  4. #include <unistd.h>  
  5. #include <sys/mman.h>  
  6. #include <errno.h>  
  7.   
  8. #define UIO_DEV "/dev/uio0"  
  9. #define UIO_ADDR "/sys/class/uio/uio0/maps/map0/addr"  
  10. #define UIO_SIZE "/sys/class/uio/uio0/maps/map0/size"  
  11.   
  12. static char uio_addr_buf[16], uio_size_buf[16];  
  13.   
  14. int main(void)  
  15. {  
  16.   int uio_fd, addr_fd, size_fd;  
  17.   int uio_size;  
  18.   void* uio_addr, *access_address;  
  19.    
  20.   uio_fd = open(UIO_DEV, /*O_RDONLY*/O_RDWR);  
  21.   addr_fd = open(UIO_ADDR, O_RDONLY);  
  22.   size_fd = open(UIO_SIZE, O_RDONLY);  
  23.   if( addr_fd < 0 || size_fd < 0 || uio_fd < 0) {  
  24.        fprintf(stderr, "open: %s\n", strerror(errno));  
  25.        exit(-1);  
  26.   }  
  27.   read(addr_fd, uio_addr_buf, sizeof(uio_addr_buf));  
  28.   close(addr_fd);  
  29.   read(size_fd, uio_size_buf, sizeof(uio_size_buf));  
  30.   close(size_fd);  
  31.   uio_addr = (void*)strtoul(uio_addr_buf, NULL, 0);  
  32.   uio_size = (int)strtol(uio_size_buf, NULL, 0);  
  33.   
  34.   access_address = mmap(NULL, uio_size, PROT_READ | PROT_WRITE,  
  35.                      MAP_SHARED, uio_fd, 0);  
  36.   if ( access_address == (void*) -1) {  
  37.       fprintf(stderr, "mmap: %s\n", strerror(errno));  
  38.       exit(-1);  
  39.   }  
  40.   printf("The device address %p (lenth %d)\n"  
  41.          "can be accessed over\n"  
  42.          "logical address %p\n", uio_addr, uio_size, access_address);  
  43.   
  44.   printf("*access_address = %u\n",*((unsigned long*) access_address));  
  45.     
  46.   unsigned long * addr = (unsigned long*) access_address;  
  47.   
  48.   printf("1: read addr:%u\n", *addr);  
  49.   printf("1: write 0 to access_address\n");  
  50.  //读写操作  
  51.   *addr = 0;  
  52. //  sleep(10);  
  53. //  printf("2: read addr:%u\n", *addr);  
  54.  // read out the timer interuption times    
  55. /*  unsigned long counter = 0; 
  56.   int ret; 
  57.   while ((ret = read(uio_fd, &counter, sizeof(counter))) 
  58.                   == sizeof(counter)) { 
  59.           printf("Interrupt number is %d\n", 
  60.                           counter); 
  61.   } 
  62.    
  63.   if(ret < 0)  
  64.           fprintf(stderr, "read error: %s\n", strerror(errno)); 
  65.   printf("exit: counter is %d\n", counter); 
  66. */  
  67.   munmap(access_address, uio_size);  
  68.   close(uio_fd);  
  69.   return 0;  


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

uio驱动编写 实例2 //增加了中断部分 的相关文章

  • SLAM8-后端的其他方法,BA与图优化,Pose Graph优化的理论与公式详解、因子图优化

    1 BA方法 Bundle Adjustment翻译过来是 光束调整 xff0c 意思是每个特征反射的光束 xff0c 通过调整它们的空间位置和相机姿态 xff0c 使它们都汇聚到相机光心 xff0c 这个过程叫BA 假定世界坐标系下的点p
  • 【动手学深度学习】 2预备知识

    李沫 动手学习深度学习 课程学习 需要预备的知识原因重点线性代数处理表格数据矩阵运算微积分决定以何种方式调整参数 损失函数 xff08 loss function xff09 衡量 模型有多糟糕 这个问题的分数 梯度 xff08 gradi
  • JDK源码之-java.lang.Object

    JDK源码之 java lang Object public final native Class lt gt getClass public native int hashCode public boolean equals Object
  • Apm飞控学习笔记之-电机解锁和故障保护-Cxm

    前言 CSDN https mp csdn net mp blog creation editor 122115245 这边说的解锁是指的非自动解锁和地面站解锁 常规解锁流程 61 安全开关 gt 内八解锁 这一篇会介绍整个解锁流程以及飞控
  • https://gns3.com/community/discussion/gns3-doesn-t-work-on-vmware-play

    swered Question GNS3 doesn t work on VMWARE player 15 Hi guys today I try to install GNS3 on new VMWARE player 15 with V
  • 基于stm32的数控线性稳压电源,恒压恒流电源资料

    基于stm32的数控线性稳压电源 xff0c 恒压恒流电源资料 极具学习和设计参考价值 xff0c 已验证 xff0c 可做实物 xff0c 送资料 xff0c 此价格仅为资料 xff0c 资料包括源程序 xff0c 原理图 xff0c p
  • Docker安装Elasticsearch的遇到的那些坑

    1 根据百度到的一篇文章 https segmentfault com a 1190000004376504 下载其最新镜像 hangxin1940 docker elasticsearch cn v2 1 0 使用 docker run
  • Spring boot + Spring Security + Thymeleaf 认证失败返回错误信息

    Spring boot 43 Spring Security 43 Thymeleaf 认证失败返回错误信息 Spring boot以其众多友谊的特性 xff0c 如零配置 微服务等 xff0c 吸引了很多的粉丝 而其与Spring Sec
  • Java经典面试题(其三)——JVM原理和调优

    Java经典面试题 xff08 其三 xff09 JVM原理和调优 一 什么是JVM JVM是Java Virtual Machine xff08 Java虚拟机 xff09 的缩写 xff0c JVM是一种用于计算设备的规范 xff0c
  • Spring Boot Starter的面试题

    Spring Boot Starter的面试题 1 常见的starter会包几个方面的内容 xff1f 分别是什么 xff1f span class hljs comment 常见的starter会包括下面四个方面的内容 span span
  • 个人经历:谈一谈的程序员求职途径

    个人经历 xff1a 谈一谈的程序员求职途径 互联网招聘网站的确是五花八门 xff0c 种类繁多 xff0c 在投递简历 xff0c 接听面试电话的过程中 xff0c 要擦亮眼睛 xff0c 慎重选择和沟通 我是去年跳槽的 xff0c 下面
  • JVM调优再学习

    JVM调优再学习 堆大小设置 JVM中最大堆大小有三方面限制 xff1a 相关操作系统的数据模型 xff08 32 bit还是64 bit xff09 限制 xff1b 系统的可用虚拟内存限制 xff1b 系统的可用物理内存限制 32位系统
  • Dubbo源码学习基础

    dubbo源码学习基础 Dubbo源码学习基础Java RMI 基本概念在 Dubbo 中使用注解自定义容错策略正确加载MyFilter类Dubbo可扩展机制实战Dubbo的SPI机制自定义一个LoadBalance扩展Dubbo 外部化配
  • DXP软件使用快捷键

    1 PCB 设计快捷键 xff08 单次按键 xff09 单次按键是指按下该键并放开 1 01 在 PCB 电气层之间切换 xff08 小键盘上的 xff09 在交互布线的过程中 xff0c 按此键则换层并自动添加过孔 这很常用 1 02
  • 将一个字节数据进行高低位镜像对调的实现函数

    unsigned char swap unsigned char pData unsigned char value 61 0 tmp 61 0 unsigned char ii jj for ii 61 0x80 jj 61 0 ii 6
  • PX4-做飞控二次开发需要知道的事情-Cxm

    前言 废话 来了 之前一直在做APM飞控的开发 发现除了企业用APM 在比赛方面还是PX4居多一点 加上最近也有这个需求所以又重拾了PX4 这两个飞控最大的区别应该就是系统了吧 PX4学习起来还是比较简单的 比较系统和模块化 在重拾PX4之
  • 指针函数和函数指针的区别

    1 指针函数 xff1a 带指针的函数 xff0c 其本质是一个函数 xff0c 函数返回是某一类型的指针 例如 xff1a int f x xff0c y 其结构为 类型标识符 函数名 参数 首先你要从心里承认这是一个函数 xff0c 只
  • 什么是中断?

    中断嘛 xff0c 对于很多新手来讲 xff0c 有点难以理解 xff0c 举个容易的现实的例子吧 如果还不懂 xff0c 骚年 xff0c 考虑换行吧 xff0c 或许这不是你的方向呢 xff0c 诗和远方在前面岔路左拐 比如小明和老丈人
  • 什么是看门狗?

    一样采用简单明了的例子来解释 条件 xff1a 你家有条狗 事件 xff1a 让他看门 xff0c 报警 结果 xff1a 1到点不给吃饭 xff0c 会叫 xff0c 2到点喂他吃东西 xff0c 等待下次开饭 影响 xff1a 叫了 x
  • BUG的烦恼

    在我们这个行业的学习和工作中 xff0c bug是个逃不掉的话题 最近两天 xff0c 在调试一个程序 xff0c 程序本来是完整的 xff0c 只是我需要把它移植到另一个平台上 框架是没有动的 xff0c 连平台的架构都很像 xff0c

随机推荐