Re: real-time process

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>
> Alternatively (and better),
>
> Have the driver allocate 2 buffers and mmap() them into the process.
> Have the driver create 2 semaphores (initially zero) and let the app
> post and wait on them with ioctls.
>


> void *buf[2];
>
> buf [0] = mmap (fd, ...);
> buf [1] = buf [0] + HALF_BUFFER_SIZE; /* GCC extension :) */
>
> no = 0;
> while (!done ())
> {
>         /* Let the driver know a buffer is available. DMA starts
>            if not started already.  */
>         ioctl (fd, POSTSEM_0);
>
>         /* Wait until DMA interrupts and the interrupt handler signals the
>            semaphore.  Driver continues filling the other buffer.  */
>         ioctl (fd, WAITSEM_1);
>
>         /* Data is in buffer, no copying needed.  */
>         do_stuff (buf [no]);
>
>         /* Switch buffers.  */
>         no = !no;
> }


This one's frm my prev mails:
{
1. implement mmap() for the driver and try to get as big kernel memory space
as possible.

( usually u'll need DMA capable, non swappable memory ). Then implement n
buffering in it.

2. use some ioctls to select the buffer u want to xfer.
}

Here i meant exactly that. What i did was mmap n number of buffers.
and treat it like one virtual buffer in appl.

So ur modified code would be:

void *buf[NUM*BUFF_SIZE];

 buf [0] = mmap (fd, ...);

for( i = 0; i < NUM; i++ ) {
    buf [1] = buf [0] +i* BUFF_SIZE; /* GCC extension :) */


read( iofd, buf, NUM*BUFF_SIZE );
/* Initially u fill in all buffers with data. */


configure_number_of_driver_buffers_and_kick_it_to_start_xfer_of_first_buffer
();
/* This one kicks off the xfer of FIRST buffer */

 no = 0;

for(   index = 0; !done(); index = (index+1)%NUM ) {

        /* WAIT till u get an intimation (irq_handler) */
        /* This could be done by sem, fasync+sleep, or poll, */
       /* I used fasync() here with sleep */

    sleep(1);
    /* The sleep time is depending on the design,
         This fills up the buffer even if its not used up by driver
        bcoz, here the data xfered is video data, delay
       is more costly than data loss. So i can do with data loss
      than delay  ( NOTE: this is true for MY application )
   */
    Here the driver itself switches to next buffer xfer in irq_handler.

    read( iofd, buff[index],  BUFF_SIZE );

   }

    Well, the n buffers are required here bcoz of bandwidth and the
limitation
   on size of DMA capable buffers available in linux  kernel.
   u get buffers through __get_dma_pages() which can give u
   max 128k most of the times.

   Now considering the speed of CPU (mine is 233Mhz) and speed of DMA ( 100
Mbps by the device ).
 The device can finish xfering the 1st buffer before u fill in the second
one.
 So till its finished,  u need to block ( Which is not prefered ).
To give for this spead diffs u either need a very large buffer
 or increase number of small buffers.
U can calculate the exact buff nos and size depending on calculations
done on disk_read_latency, driver-appl switching latency,
actual throughput of the device etc.

-nagaraj.
\(*_*)/






>
> One can add buffers to compensate for jitter. On a real-time OS two
> buffers ought to be enough.  Ok ?
>
> ~velco




--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux