I am developing an acquisition device which requires DMA operation to transfer large data frames to the main memory. 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 . The driver can then access that region by calling ioremap().
The current system works as follows:
A memory-mapped control register enables a user-space application to Start/Stop the device
Upon start, the device begins to transfer the acquired data to the assigned memory region continuously (and circularly) at ~8MB/s.
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.
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 . You can also read the DMA-API from the kernel documentation.
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.
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.