Comedi的学习过程

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的论坛上寻找维护者的帮助,因为有时差之类的因素,需要等待较长时间才能得到维护者的回信。




posted @ 2019-02-14 11:06  空水  阅读(997)  评论(0编辑  收藏  举报