简体   繁体   English

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

[英]How to implement a Linux Device Driver for Data Acquisition Hardware?

I am developing an acquisition device which requires DMA operation to transfer large data frames to the main memory. 我正在开发一种采集设备,该设备需要DMA操作才能将大数据帧传输到主存储器。 For now I am assuming the destination is a contiguous memory region so I am allocating it (say 1 MB) at boot time as described in section "Do-it-yourself allocation" from ldd2-ch13 . 现在,我假设目标是一个连续的内存区域,因此我正在引导时对其进行分配(例如1 MB),如ldd2-ch13的 “自己动手分配”部分所述。 The driver can then access that region by calling ioremap(). 然后,驱动程序可以通过调用ioremap()来访问该区域。

The current system works as follows: 当前系统的工作方式如下:

  1. A memory-mapped control register enables a user-space application to Start/Stop the device 内存映射控制寄存器使用户空间应用程序可以启动/停止设备

  2. Upon start, the device begins to transfer the acquired data to the assigned memory region continuously (and circularly) at ~8MB/s. 启动后,设备开始以约8MB / s的速度(连续)(连续)将获取的数据传输到分配的存储区域。

  3. The reserved memory region has the size of two frames in order to employ a double-buffering technique . 保留的存储器区域具有两个帧的大小,以便采用双缓冲技术
  4. Once a complete frame has been transferred, the device triggers an interrupt. 传输完完整帧后,设备将触发中断。

I have developed a simple char driver which provides a blocking read() function so that the user-space can read a new data frame every time an interrupt is received. 我已经开发了一个简单的char驱动程序,该驱动程序提供了阻塞的read()函数,以便每次接收到中断时用户空间都可以读取新的数据帧。

After running a few tests, I realized that the user-space application misses some frames when running the following code: 运行一些测试之后,我意识到运行以下代码时用户空间应用程序会丢失一些帧:

    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");
    }

I suspect that the application's process is being put to sleep between two subsequent reads, allowing the device to rewrite the memory location which should have already been read. 我怀疑应用程序的进程在两次后续读取之间进入休眠状态,从而使设备可以重写应该已经读取的内存位置。

Since I have no experience in kernel development I would like to know how is the correct way to implement a driver for such a device in order to ensure synchronization. 由于我没有内核开发经验,因此我想知道如何为此类设备实现驱动程序以确保同步的正确方法。 Basically I am trying to implement a simple shared memory communication for a real-time acquisition device and I need to guarantee that the OS is able to read all the acquired data frames. 基本上,我试图为实时采集设备实现简单的共享内存通信,并且我需要保证操作系统能够读取所有采集的数据帧。

You are reading a very very old book. 您正在读一本非常古老的书。 Here the link to the last version of the book (it is just very old): Linux Device Driver 3 - Memory Mapping . 这里是本书最新版本的链接(该版本很旧): Linux Device Driver 3-Memory Mapping You can also read the DMA-API from the kernel documentation. 您也可以从内核文档中阅读DMA-API

To make a kind of synchronization read Time, Delays and Deferred Work chapter. 要进行某种同步,请阅读“ 时间,延迟和延期工作”一章。 You can use the a waitqueue . 您可以使用等待队列 You wait on read() and you *wake_up* when new frames are available. 您需要等待 read()并在新帧可用时“唤醒” *。

About your code, it is not enough to understand your problem. 关于您的代码,仅仅了解您的问题还不够。 But, if you think that you need to sleep/wait, you can implement the poll file_operation in your driver and use select() in user-space to ask if there is something to read. 但是,如果您认为需要睡眠/等待,则可以在驱动程序中实现poll file_operation并在用户空间中使用select()询问是否有需要读取的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM