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

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

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

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

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

  2. 启动后,设备开始以约 8MB/s 的速度连续(并循环)将获取的数据传输到分配的内存区域。

  3. 保留的内存区域有两个帧的大小,以便使用 double-buffering technique .
  4. 传输完整帧后,设备会触发中断。

我开发了一个简单的 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");
    }

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

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

最佳答案

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

做一种同步读取Time, Delays and Deferred Work章节。您可以使用等待队列。您等待 read() 并在新帧可用时*唤醒*。

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

关于c - 如何为数据采集硬件实现 Linux 设备驱动程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15792144/

相关文章:

linux - 无法使用 awk 提取 fastboot 命令

linux - 启动 LXC 容器时主机系统键盘布局发生变化

c - 用于 Linux 内核模块和设备驱动程序的静态分析工具

c - 当 fgets 危险时(大小小于缓冲区大小)?

c - 如何使用 gcc 和 make 为每个优化级别编译成二进制文件?

c - gcc 链接器找不到 .so 库文件

linux - printk 消息未显示在 dmesg 日志中

c - 如何使用 MPI_Scatterv 将矩阵的行发送到所有进程?

c - 从用户区读取 32k i2c eeprom

C++ - 找不到共享库 liblog4cpp.so.4