Re: 8ms Timer for serial port access
From: Byron A Jeff (byron_at_cc.gatech.edu)
Date: 10/31/03
- Next message: Byron A Jeff: "Re: 8ms Timer for serial port access"
- Previous message: Jens Schumacher: "Re: 8ms Timer for serial port access"
- In reply to: Grant Edwards: "Re: 8ms Timer for serial port access"
- Next in thread: David Schwartz: "Re: 8ms Timer for serial port access"
- Reply: David Schwartz: "Re: 8ms Timer for serial port access"
- Reply: Jens Schumacher: "Re: 8ms Timer for serial port access"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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
- Next message: Byron A Jeff: "Re: 8ms Timer for serial port access"
- Previous message: Jens Schumacher: "Re: 8ms Timer for serial port access"
- In reply to: Grant Edwards: "Re: 8ms Timer for serial port access"
- Next in thread: David Schwartz: "Re: 8ms Timer for serial port access"
- Reply: David Schwartz: "Re: 8ms Timer for serial port access"
- Reply: Jens Schumacher: "Re: 8ms Timer for serial port access"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|