1.介绍Comedi
  1.1Comedi是一个设备驱动开发的软件工具,它采用了一种3层组织模型:上层是用户层,Comedi提供了在用户控件编写程序的接口Comedilib,通过系统调用来控制硬件设备;中层是内核层,主要由两部分构成:linux内核空间API(在内核空间开放的统一编程接口),设备驱动程序(与特定硬件相关的设备驱动程序);下层是硬件层,包括所有系统能够支持的数据采集板卡设备。

  

  1.2 Comedi能够支持板卡的功能:模拟输入,模拟输出,数字输入,数字输出,计数器输入,计数器输出,脉冲输入,脉冲输出。
  1.3 Comedi将设备结构分为三层:
    设备:板卡本身;
    子设备:功能一致的通道集,如模拟输入模块,数字输入模块;
    通道:描述单一数据通道的属性,如模拟输入,模拟输出。
  1.4 信号采集方式:
    模拟输入输出:同步采集,异步采集;
    数字输入输出:同步采集;

2.Comedi的配置
  2.1 在大多数系统上,基于PCI和USB的电路板都被自动配置,内核会自动加载相应的驱动程序和设备文件;部分板卡不会被自动配置,例如共用一个设备id的板卡(例如研华 PCI-1710 和 PCI-1710HG)。

  2.2 comedi_board_info和comedi_soft_calibrate是两个重要的命令,前者是可以根据命令选项打印出设备文件指定的设备信息,后者是在使用模拟输入和模拟输出之前进行校准,防止传输过程出现较大误差。该校准是软件校准,硬件校准暂未测试。
  

 3.Comedi同步采集和异步采集
  3.1 Comedi库中提供了两种数据采集机制:指令机制(instruction)和命令机制(command),其中Command命令机制是Comedi规范中使用灵活,功能强大的一种数据采集方式,用它可以进行异步数据采集。指令机制与命令机制的差异主要体现在,前者在数据采集过程中,函数调用处于阻塞状态,而后者的调用是异步的,在进行数据采集的同时还可以对数据进行实时地处理。因此对于实时性较高的系统,应该采用命令机制。
  3.2 同步采集:

    3.2.1 Comedi指令机制(同步采集)所需要配置的结构体为comedi_insn和comedi_insnlist。通过设置insn参数,可以执行诸如gettimeofday函数调用、模拟输入读操作、输出数据、数字I/O位操作、数字I/O配置传输方向和延时指定时间等,同时也可以设置操作循环执行次数,指定子设备、通道等。
    

  3.3 异步采集
    3.3.1 Comedi的异步采集相比较同步采集来说,需要配置的参数更多,所使用的结构体为comedi_cmd。该结构体主要是五种事件的配置参数,分别为开始采集,开始扫描,开始转换,停止扫描,停止采集。

     

    注意:flags配置硬件缓冲区更新到comedi缓冲区的速度。

    3.3.2 数据采集板卡要实现连续实时采集数据,就需要选用Command(命令机制)的数据采集方式,因为Command是Comedi规范中最高效的数据采集方式,Command方式可以指定数据采集的序列,每个序列由若干扫描组成,而每次扫描又是由若干次A/D和D/A转换组成,下图所示。
    

4.Comedi的优缺点
  4.1 Comedi的优点:
    Comedi是一个开源的设备驱动开发工具;
    Comedi独特的分层结构,应用程序的编写就完全独立于硬件,大大地简化了驱动程序的编写;
    Comedi提供了大量知名厂家的数据采集板卡的驱动程序;
    Comedi不仅提供API来访问设备,还可以查看设备具有的功能;
    Comedi会自动修改异步采集所配置的错误参数;
  4.2 Comedi的缺点:
    Comedi的校准命令需要在程序执行开始之前进行并且每个命令只能校准一个设备;
    Comedi的使用者较少,网上查找资料困难;
    Comedi的异步采集和校准并不是所有板卡都支持;
    Comedi的异步采集读取数据的时间间隔不能过大,不然comedi的缓冲区会溢出;

 5.Comedi代码
  5.1 Command数据采集方式,程序首先要对每个通道进行初始化,然后要设置comedi_cmd数据结构中序列,扫描和转换启停触发和时间间隔等参数,调用comedi_test检测参数,正确则执行操作comedi_command,之后通过read获取数据,并进行数值转换。

  

  5.2 Insn数据采集方式,程序首先要对每个通道进行初始化,然后要设置comedi_insn数据结构中指令类型,指令和通道配置等参数,执行操作comedi_do_insn或comedi_do_insnlist,数据从结构体指针变量data中获取,并进行数值转换。

  

 6.学习Comedi遇到的问题
  6.1 最初使用指令模式去获取pci6229板卡的模拟输入,函数返回值正确,但获取到的结果却是不合常理的,后来在Comedi论坛上发现这个问题的解决办法,我使用的linux内核版本3.18-46不支持Comedi的模拟输入,换成3.18-69就可以正常采集模拟输入。
  6.2 Comedi支持单端和差分两种接线模式,pci6229板卡测试Comedi的差分模式发现模拟输入的数值不稳定,后来用NI自己的驱动测试pci6229板卡出现了相同的问题,由此确定该问题是板卡自身导致的,和Comedi无关。
  6.3 Comedi异步采集命令开始执行之后,如果一定时间不读取Comedi的缓冲区,可能导致缓冲区溢出,程序崩溃结束。
  6.4 Comedi异步采集命令开始执行后,立即调用read()读取Comedi缓冲区会有很长一段时间阻塞,而且阻塞现象是有规律出现的,经过细心的查看Comedi手册发现Comedi缓冲区的数据是从硬件设备的缓冲区传递过来的,而Comedi默认只有当硬件设备的缓冲区半满的时候才会更新到Comedi的缓冲区。
  6.5 Comedi的使用者较少,类似6.1遇到的问题并不能跟根据Comedi的手册解决,只能到Comedi的论坛上寻找维护者的帮助,因为有时差之类的因素,需要等待较长时间才能得到维护者的回信。

Comedi的学习过程的更多相关文章

  1. Java学习过程中的总结的小知识点(长期更新)

    Java学习过程中的总结的小知识点 (主要是自己不会的知识和容易搞错的东西) 计算某个程序运行的时间 long stime=System.currentTimeMillis(); copy3(file ...

  2. linux学习之九 学习过程总结

    ~写在前面 首先非常感谢孟老师的悉心讲解,使用这种新颖的教学方式(MOOC课堂+博客),也感到非常有幸随着老师的思路对linux的内核进行了初步的系统学习.结合代码和gdb调试工具跟踪分析对linux ...

  3. opnet学习过程

    学习opnet有一段时间了,走了 不少弯路,现在,想总结一下,推荐给大家一个比较好的学习过程. 因为英语不太好,所以在开始学opnet时用了很多心思去找中文资料,比如说,一些文档.书.视频等.看文档和 ...

  4. mono for android学习过程系列教程(7)

    首先说个抱歉,这段时候由于个人原因未及时更新博客.故此今天先给大家来个小料. 以后会及时更新我自己的学习过程. 不多说,终于私人生活安定下来了,可以安心学习.直接进入主体: 今天咱们摒弃所有的前面的知 ...

  5. 使用React、Node.js、MongoDB、Socket.IO开发一个角色投票应用的学习过程(三)

    这几篇都是我原来首发在 segmentfault 上的地址:https://segmentfault.com/a/1190000005040834 突然想起来我这个博客冷落了好多年了,也该更新一下,呵 ...

  6. 下面就介绍下Android NDK的入门学习过程(转)

    为何要用到NDK? 概括来说主要分为以下几种情况: 1. 代码的保护,由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大. 2. 在NDK中调用第三方C/C++库,因为大部分的开源库 ...

  7. HTML/CSS的学习过程一览

    HTML/CSS的学习过程一览 说明 调试工具使用的是Google Chrome浏览器,其余浏览器出现的问题,这锅我不背[傲娇脸 可以使用浏览器查看源代码 网页列表 HTML_CSS_1 HTML基本 ...

  8. 分享吉林大学机械科学与工程学院,zhao jun 博士的Halcon学习过程及知识分享

    分享吉林大学机械科学与工程学院,zhao jun 博士的Halcon学习过程及知识分享 全文转载zhao jun 博士的新浪博客,版权为zhaojun博士所有 原文地址:http://blog.sin ...

  9. Android 按下电源按钮关闭小学习过程的整个长度

    Android 按下电源按钮关闭小学习过程的整个长度 近期研究了一下android关机跟又一次启动功能,看了一些长按电源键到弹出关机对话框,到真正关机的一系列处理过程. 首先还是来看看这个长按电源键都 ...

随机推荐

  1. JS案例六_2:省市级联动

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. Java容器解析系列(8) Comparable Comparator

    Comparable和Comparator接口是两个用于对对象进行大小比较的接口,在java集合相关类中,也被经常地使用到. 关于其使用,可以参考网络上的其他博客(没什么好说的);这里阐述关于这两个接 ...

  3. console.log()中的运算与打印事件

    var p=function() { var i = 0; function b() { console.log(i--);//先打印再减一 //console.log(--i);先减一再打印 } f ...

  4. 音频播放器在chrome浏览器,play报错

    这个问题是谷歌浏览器的问题:https://www.oschina.net/news/96168/chrome-remove-the-autoplay-policy,可以查看这篇文章 如果你的版本没有 ...

  5. js中bind的用法,及与call和apply的区别

    call和apply的使用和区别不再做阐述,可以参考我的另一篇随笔<JavaScript中call和apply方法的使用>(https://www.cnblogs.com/lcr-smg/ ...

  6. php优秀框架codeigniter学习系列——CI_Controller分析

    该类是一个超级大的父类,它将在 CodeIgniter.php 中实例化化过的类,通通加载成它的类成员变量,所以可以方便的进行各种操作.各种应用控制器类,都会继承 CI_Controller 类. _ ...

  7. .net 服务因为GC时遇到的问题和解决办法

    1.问题: .net单一服务中,大量的请求访问后台服务,多线程处理请求,但每个线程都可能出现超时的现象.记录超时日志显示,超时可能在序列化时,Socket异步发送AsyncSend数据时,普通业务处理 ...

  8. springboot +mybatis 搭建完整项目

    springboot + mybatis搭建完整项目 1.springboot整合mybatis注解版 转:https://blog.csdn.net/u013187139/article/detai ...

  9. Python 常见字符串常量和表达式

    常见字符串常量和表达式 操作 解释 s = '' 空字符串 s = "spam's" 双引号和单引号相同 S = 's\np\ta\x00m' 转义序列 s = "&qu ...

  10. C语言链表:逆序建立单链表

    #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<malloc.h> #define LEN sizeof( ...