如何为数据采集硬件实现Linux设备驱动程序?

时间:2013-04-03 15:55:09

标签: c linux linux-kernel operating-system linux-device-driver

我正在开发一种采集器件,需要DMA操作才能将大数据帧传输到主存储器。现在我假设目的地是一个连续的内存区域,所以我在启动时分配它(比如1 MB),如ldd2-ch13中的“自己动手分配”部分所述。然后,驱动程序可以通过调用ioremap()来访问该区域。

当前系统的工作原理如下:

  1. 内存映射控制寄存器允许用户空间应用程序启动/停止设备

  2. 启动后,设备开始以~8MB / s的速度连续(和循环)将获取的数据传输到指定的存储区域。

  3. 保留的内存区域大小为两帧,以便使用double-buffering technique
  4. 传输完整帧后,设备会触发中断。
  5. 我开发了一个简单的char驱动程序,它提供了一个阻塞的read()函数,这样每次收到一个中断时,用户空间就可以读取一个新的数据帧。

    运行一些测试后,我意识到用户空间应用程序在运行以下代码时错过了一些帧:

        for(i=0;i<NUM_FRAMES;i++) {
    
           read(dev_d,buf,FRAME_SIZE);/*Read frame*/
    
           for(j=0;j<FRAME_SIZE;j++) /*File dump*/
              fprintf(fp,"%d",buf[j]);
    
            fprintf(fp,"\n");
        }
    

    我怀疑应用程序的进程在两次后续读取之间进入休眠状态,允许设备重写应该已经读取的内存位置。

    由于我没有内核开发经验,我想知道为这种设备实现驱动程序的正确方法是什么,以确保同步。基本上我正在尝试为实时采集设备实现简单的共享内存通信,我需要保证操作系统能够读取所有采集的数据帧。

1 个答案:

答案 0 :(得分:2)

你正在读一本非常古老的书。这里是本书最后一个版本的链接(它很老):Linux Device Driver 3 - Memory Mapping。您还可以从内核文档中阅读DMA-API

进行一种同步读取Time, Delays and Deferred Work章节。您可以使用a waitqueue 。你可以在read()上等待,并在新帧可用时你* wake_up *。

关于您的代码,仅仅了解您的问题是不够的。但是,如果您认为需要休眠/等待,可以在驱动程序中实现轮询file_operation,并在用户空间中使用select()来询问是否有要阅读的内容。