Re: 8ms Timer for serial port access

From: Byron A Jeff (byron_at_cc.gatech.edu)
Date: 10/31/03


Date: 30 Oct 2003 18:19:14 -0500

In article <slrnbq2ulb.sgd.grante@isis.visi.com>,
Grant Edwards <grante@visi.com> wrote:
-In article <bnro2r$t75@cleon.cc.gatech.edu>, Byron A Jeff wrote:
-
->> Moreover, if that is the case then the only sane way to write a
->> serial_check_buffer() function is to include a minimal sleep, which will
->> cause 10ms of that timing granularity to be given to other processes!
->
-> Correct again. sleep has a grainularity of 10ms.
-
-If you're talking about the libc call sleep(), it has a granularity of 1sec.

No. I meant the grainularity of being rescheduled after blocking in the
kernel. usleep, nanosleep, and select have fine enough grainularity to
expose this.

-
-> But my question is now does read and/or select have the same grainularity?
-
-No. The task can become runnable after a read/select call at any point.
-That's largely a moot point, since the task won't actually _run_ until the
-next time the scheduler runs, and that's at the next 10ms interrupt.

As you point out it is moot.

-
-OK, there _is_ (or at least was, the last time I looked) a way for a driver
-to wake up somebody blocked on a a read and then make sure that the
-scheduler runs as soon as the driver tasklett completes. That way the 10ms
-scheduler granularity can be bypassed. That's fine as long as only one
-driver does it once in a while. If all the drivers tried to do it, it could
-cause a lot of overhead.

And of course the other method I pointed out.

-
-> What about usleep or nanosleep?
-
-Same answer. It would be _possible_ to impliment them in such a way that a
-task becomes runnable with microsecond granularity, but under "normal"
-conditions, the state of a task doesn't matter until the next 10ms interrupt
-causes the scheduler to run.

Correct. So we need an abnormal circumstance.

-
-> If so then I can see why Jens is upset.
-
-He seems to be "upset" because Linux is not an RTOS. Nobody ever claimed it
-was. If you beat on it enough, you can get it closer than the usual
-"default" state of things.

Agreed. There's not apparent reason (note the word apparent here) why the
scheduler is only run at 10ms intervals. He frustrated because it doesn't
meet his expectation that if he asks to sleep for 800 uS that he doesn't
come back online for up to more than 10 times that required timeframe.

-
-> -> But the timer can't measure in microseconds, and the second data
-> -> _read_ happens literally microseconds (all within the same
-> -> time slice) after the first one. Hence the timer says there was
-> -> 0ms between them, because its smallest granularity is 10ms.
->
-> Not exactly correct. You sleep for 10ms if no data is there, and you
-> don't sleep at all on the read if data is there.
->
-> Note from the above run you don't want to use select. You want to keep running
-> track of the last time you did a read, sleep until 8333 uS after the last read
-> then read again. The difference with the real-time schedule is that as soon
-> as the 8333 uS elapses, the kernel will immediately preempt whatever is running
-> and restart your process.
-
-If you want to try that, you'd better do a couple other things as well:
-
- 1) Disable the FIFO on your UART so you get an interrupt for every byte.
- It'll increase overhead, but it'll play hell with your timings
- otherwise.
-
- 2) Set the low-latency flag on the device. By default, the serial driver
- buffers up rx bytes and only pushes them up to the tty line discipline
- layer once every (you guessed it!) 10ms. Setting the low-latency flag
- will send the bytes up on every interrupt.

Can you set the FIFO level? I think the driver generally sets it up to
interrupt when it fills with 14 bytes (I think).

Also is there an ioctl that forces a FIFO flush even though an interrupt hasn't
occured yes? I think that would be better than disabiling the FIFO and
generating an interrupt each and every received byte.

-
-> Correct. So make the process run on the real time scheduler, Make sure that
-> it usleeps when it's waiting, and it'll wake up right on time.
-
-But if you don't set up the serial driver correctly, there probably won't be
-any data there when you wake up: it'll be sitting int he UART Rx FIFO or in
-the serial driver's receive buffer.

Cool beans. I never looked at serial.c that closely.

BAJ



Relevant Pages

  • Re: Developing interrupt driven serial driver
    ... My next task is to make this driver codebase interrupt driven. ... deassert CTS so that the DTE would stop sending when the FIFO is full. ... interrupt handler for the receiver put the data into a larger buffer ...
    (comp.arch.embedded)
  • Re: [PATCH] Remove process freezer from suspend to RAM pathway
    ... hardware can put itself to sleep and atomically preserve memory as it ... Ensure that the other CPUs have finished any trailing interrupt ... Block driver bind or unbind calls. ... While holding a mutex needed to suspend ...
    (Linux-Kernel)
  • Re: Losing interrupts
    ... Does the AD converter board issue an interrupt with any value acquired ... Here a hardware FIFO or a DMA would be better. ... If you don't want to use RTAI, your best bet is to write a device driver ...
    (comp.os.linux.embedded)
  • Re: 2.6.19 and up to 2.6.20-rc2 Ethernet problems x86_64
    ... If the system fails in ACPI mode, but works in non-ACPI mode, ... Using ACPI for SMP configuration information ... Using IOAPIC for interrupt routing ... Non-volatile memory driver v1.2 ...
    (Linux-Kernel)
  • Re: [PATCH] uio: User IRQ Mode
    ... This patch adds a "User IRQ Mode" to UIO. ... In this mode the user space driver ... is responsible for acknowledging and re-enabling the interrupt. ...
    (Linux-Kernel)

Quantcast