Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

reading on serial port slow...

263 views
Skip to first unread message

werasm

unread,
Dec 14, 2007, 11:09:18 AM12/14/07
to
Hi all,

I have an application where I need to use SCHED_FIFO as
result of some deadlines. On of the biggest reasons for
using SCHED_FIFO currently is that we have a diagnostic
thread that want to run using using default scheduling, that
this thread would run the the background (I come from a
VxWorks background).

I wrote an application that writes to the serial port using
a task that basically writes, then sleeps 10ms, the reads.
I would expect the data to be available, but is seems that
the work done by one of my SCHED_FIFO tasks prevents
the serial driver from reading the data by the time the sleep
ends. Do any of you have any advice concerning this? I
don't want to modify the serial driver (I've never fiddled with
Linux driver code before). Currently I'm not sure from
which context the driver picks up data from the port.

Any help would be appreciated.

Regards,

Werner

Joe Beanfish

unread,
Dec 14, 2007, 1:29:06 PM12/14/07
to

You should be using select() and/or a blocking read() rather than
assuming anything about timing.

werasm

unread,
Dec 14, 2007, 3:14:13 PM12/14/07
to

Well, yes. I know select, and I'm very aware of what a blocking
read is as I'm quite intimate with POSIX. The point is, when
the read times out, the data is not there yet (that is the
problem). I don't see why select should fix that, and
unfortunately I have to assume things about timing as I'm
communicating with many devices on a RS485 link, and each
device only have 20ms to respond. Select is too slow - period.

Now back to my question - If another task keeps my processor
busy and that task uses FIFO scheduling, why does the driver
not pick up the data (and read return without data), despite
data being available). The problem is fixed when I don't use
FIFO scheduling, but that causes other problems.

Can I do anything (apart from modifying the driver which I
don't consider an option) to solve this.

Regards,

Werner

werasm

unread,
Dec 14, 2007, 3:27:11 PM12/14/07
to
On Dec 14, 7:29 pm, Joe Beanfish <j...@nospam.duh> wrote:


> You should be using select() and/or a blocking read() rather than
> assuming anything about timing.

My requirements require me to do it the way I do it. I'm very familiar
with select (and non-blocking read) or blocking read. But you still
have not answered my question (but perhaps you don't know the answer).

Regards,

Werner

Floyd L. Davidson

unread,
Dec 14, 2007, 8:53:37 PM12/14/07
to

Your question was "What's wrong with my code?"

I can see the problem, right *there*...

--
Floyd L. Davidson <http://www.apaflo.com/floyd_davidson>
Ukpeagvik (Barrow, Alaska) fl...@apaflo.com

werasm

unread,
Dec 15, 2007, 3:31:36 AM12/15/07
to

You don't need to see my code. Actually my code works fine.
Initially I used a blocking read - no magic there - go look
it up in the Unix Spec. We used to Termios driver to set
up the port and the smallest timeout specifiable is 1 DeciSec
or the first character, whichever happens first. The problem
was that even after a DeciSec for certain tests there was
no data to read (under certain circumstances), even though
the data should have been received after approx. 7ms (and
this was verified by oscilloscope). The reason I found
to be the fact that the task sending a 1000 messages
(in a loop) was holding the processor. The more messages
were sent, the longer the processor was held (because
of the fact that it used SCHED_FIFO). My question is:

Can I change the "lack of reading behaviour" by forcing
the Linux Kernel (or the termios driver) to service its I/Os,
thereby making the data available to read. It was also seen
that as soon as the thread that sends messages stops, data
suddenly becomes available to read (after a couple of
messages has been lost). I'm not in the mood for posting
my code. The behavior I describe is quite clear. Therefore
please just answer if you can, else go irritate someone
else.

Regards,

Werner

werasm

unread,
Dec 15, 2007, 3:38:01 AM12/15/07
to

I could add to this that once the sending thread stopped
messages suddenly started being received within 15ms
intervals, which is more the behavior that I expected. I
received about 1995 out of 2000 - the first five got lost
due to timeout (Whether by select (non-blocking) OR blocking
read).

phil-new...@ipal.net

unread,
Dec 15, 2007, 9:35:42 AM12/15/07
to
On Sat, 15 Dec 2007 00:31:36 -0800 (PST) werasm <wer...@gmail.com> wrote:
| On Dec 15, 2:53 am, fl...@apaflo.com (Floyd L. Davidson) wrote:
|> werasm <wer...@gmail.com> wrote:
|> >On Dec 14, 7:29 pm, Joe Beanfish <j...@nospam.duh> wrote:
|>
|> >> You should be using select() and/or a blocking read() rather than
|> >> assuming anything about timing.
|>
|> >My requirements require me to do it the way I do it. I'm very familiar
|> >with select (and non-blocking read) or blocking read. But you still
|> >have not answered my question (but perhaps you don't know the answer).
|>
|> >Regards,
|>
|> >Werner
|>
|> Your question was "What's wrong with my code?"
|>
|> I can see the problem, right *there*...
|>
|> --
|> Floyd L. Davidson <http://www.apaflo.com/floyd_davidson>
|> Ukpeagvik (Barrow, Alaska) fl...@apaflo.com
|
| You don't need to see my code. Actually my code works fine.

And since Linux also works fine (though you are quite welcome to read
the code, and even change its behaviour if you like), then I guess all
is well?


| Initially I used a blocking read - no magic there - go look
| it up in the Unix Spec. We used to Termios driver to set
| up the port and the smallest timeout specifiable is 1 DeciSec
| or the first character, whichever happens first. The problem
| was that even after a DeciSec for certain tests there was
| no data to read (under certain circumstances), even though
| the data should have been received after approx. 7ms (and
| this was verified by oscilloscope). The reason I found
| to be the fact that the task sending a 1000 messages
| (in a loop) was holding the processor. The more messages
| were sent, the longer the processor was held (because
| of the fact that it used SCHED_FIFO). My question is:

So why not persist in the reading as a test to see how long it is for
the process to actually get the data? Or see if it ever gets the data.
If there is a problem somewhere, this information might help.

So why are you wanting this other task to hold the processor?


| Can I change the "lack of reading behaviour" by forcing
| the Linux Kernel (or the termios driver) to service its I/Os,
| thereby making the data available to read. It was also seen
| that as soon as the thread that sends messages stops, data
| suddenly becomes available to read (after a couple of
| messages has been lost). I'm not in the mood for posting
| my code. The behavior I describe is quite clear. Therefore
| please just answer if you can, else go irritate someone
| else.

If the data is unavailable _and_ persists to be unavailable, there could
be many causes. If the other process being running can cause the data
to become unavailable, that, too, could be one or more of many issues.
There could be scheduling issues with the process trying to read the data
or even the driver reading it from the hardware, depending on how much
the busy process is hogging resources. It could be a memory issue. This
is where diagnostic analysis is needed. And we cannot do that for you
(because we need far more information than is available to us to do it).

If you are confident that the driver is somehow refusing to read the
device for extended periods of time for some reason, then what I suggest
is to add some code to that driver to have it do printk's to describe
what it is doing at any given instant of time, at critical logic points
in its code (such as reading from the device, handling interrupts, etc).
And watch the console for this.

--
|---------------------------------------/----------------------------------|
| Phil Howard KA9WGN (ka9wgn.ham.org) / Do not send to the address below |
| first name lower case at ipal.net / spamtrap-200...@ipal.net |
|------------------------------------/-------------------------------------|

phil-new...@ipal.net

unread,
Dec 15, 2007, 9:37:05 AM12/15/07
to
On Sat, 15 Dec 2007 00:38:01 -0800 (PST) werasm <wer...@gmail.com> wrote:

| I could add to this that once the sending thread stopped
| messages suddenly started being received within 15ms
| intervals, which is more the behavior that I expected. I
| received about 1995 out of 2000 - the first five got lost
| due to timeout (Whether by select (non-blocking) OR blocking
| read).

So which thread do you want to control the CPU?

werasm

unread,
Dec 15, 2007, 11:57:09 AM12/15/07
to
On Dec 15, 3:35 pm, phil-news-nos...@ipal.net wrote:

> | You don't need to see my code. Actually my code works fine.
>
> And since Linux also works fine (though you are quite welcome to read
> the code, and even change its behaviour if you like), then I guess all
> is well?

I had no doubt Linux works fine, but under the particular
circumstance It did not. The code doing the read works fine
no doubt, because if I'm willing to wait and no other process
with priority SCHED_FIFO is hogging the processor, I do get my
data. I have no experience in Linux device drivers apart from
using them (in that part have quite some experience as VxWorks
have a similar interface (POSIX) to drivers). The only
difference is in VxWorks I know the priority of all tasks
(including the Kernel). Here I'm blind. I expected the serial
driver to pick up data regardless of whether or not SCHED_FIFO
threads exists (I only have one process, BTW).

> So why not persist in the reading as a test to see how long it is for
> the process to actually get the data? Or see if it ever gets the data.
> If there is a problem somewhere, this information might help.

I have done this - it takes until the SCHED_FIFO thread completes.
This shows me (I think, and I've read somewhere) that the Kernel
does not schedule the driver to pick up data from the port into
the RxBuffers.

> So why are you wanting this other task to hold the processor?

I don't want it to, but there is a chance of this happening. I did
not need to do much for the waiting time to become greater than 30ms,
and this is unacceptable. Furthermore, I would prefer using
SCHED_FIFO because I have a logging task that I run under normal
scheduling that may only run during idle time. But if SCHED_FIFO
causes this behavior, then I would be forced to use SCHED_DEFAULT.

> | Can I change the "lack of reading behaviour" by forcing
> | the Linux Kernel (or the termios driver) to service its I/Os,
> | thereby making the data available to read. It was also seen
> | that as soon as the thread that sends messages stops, data
> | suddenly becomes available to read (after a couple of
> | messages has been lost). I'm not in the mood for posting
> | my code. The behavior I describe is quite clear. Therefore
> | please just answer if you can, else go irritate someone
> | else.
>
> If the data is unavailable _and_ persists to be unavailable, there could
> be many causes. If the other process being running can cause the data
> to become unavailable, that, too, could be one or more of many issues.

There are no other processes. We only have on application running on
and embedded processor( AT91RM9200 using ucLibC).

> There could be scheduling issues with the process trying to read the data
> or even the driver reading it from the hardware, depending on how much
> the busy process is hogging resources.

It looks like there are scheduling issues yes, and that is why I asked
the question. Is there anything that I can do to force the Kernel to
force the driver - basically.

> It could be a memory issue.

Certainly not a lack of memory issue. The behavior is even prevalent
when
I send one message (only not that obvious). Things only start getting
better when the receiving thread is the only thread doing something.

> This
> is where diagnostic analysis is needed. And we cannot do that for you
> (because we need far more information than is available to us to do it).

The reason seems simple - a thread is hogging the processor. One thing
I cannot afford to do, is make that thread wait on a blocking read.
The
reason was established by diagnostic analysis - if the loop is longer,
the
time that the data remains unavailable is longer.

> If you are confident that the driver is somehow refusing to read the
> device for extended periods of time for some reason, then what I suggest
> is to add some code to that driver to have it do printk's to describe
> what it is doing at any given instant of time, at critical logic points
> in its code (such as reading from the device, handling interrupts, etc).
> And watch the console for this.

As I said, I've little experience concerning drivers, and precariously
little
time. Changing the scheduling fixed the problem, but I'm wary that
this may
cause other problems in future. Basically the test consisted of the
following
(Psuedo code only - I have a well tested lib that handles passing of
callbacks
over threads, and I'll ommit this):

ThreadA - SCHED_FIFO - priority X
...
for( int i = 0; i < 1000; i++ )
{
threadBQ.push( callback( msgToSend ) );
}

ThreadB - SCHED_FIFO - priority X+1.
...
msgToSend = threadBQ.pop( waitForever );
port.tx( msgToSend )

if( port.rx( data ) )
{
dispatch( data );
}

The implementation of rx can have various flavors. Currently I
use nanosleep to sleep for 10ms (as this is when I expect the
data to be available). I know that using select is an option, but
currently it is not an option as I'm using code that encapsulates
the termios driver, and I'm not using POSIX directly. I've looked
at this encapsulation and don't find fault with it (apart from
a read wait resolution of minimum 100ms - a function of the termios
driver - see man termios). Therefore I use nanosleep:
//...
bool dataWasReceived = false;
for( int i = 0; i < 3; ++i )
{
Utils::SleepMilliseconds( 10 );
if( port.rx( data ) )
{
dispatch( data );
dataWasReceived = true;
}
}
if( ! dataWasReceived )
{
std::cout << "Missed message!" << std::endl;
//or printf...
}

Regards,

Werner

werasm

unread,
Dec 15, 2007, 1:01:02 PM12/15/07
to
On Dec 15, 3:37 pm, phil-news-nos...@ipal.net wrote:
> On Sat, 15 Dec 2007 00:38:01 -0800 (PST) werasm <wer...@gmail.com> wrote:
>
> | I could add to this that once the sending thread stopped
> | messages suddenly started being received within 15ms
> | intervals, which is more the behavior that I expected. I
> | received about 1995 out of 2000 - the first five got lost
> | due to timeout (Whether by select (non-blocking) OR blocking
> | read).
>
> So which thread do you want to control the CPU?

I was hoping that things that happen in Kernel space can at
least complete despite what scheduling is used by threads, or
that there is some mechanism (API call) to force this (like
for instance when Thread B in my other example begins the read,
it could call "sync" perhaps, that would force the buffers to
be filled by data on the port. I've not tried sync, but
sync seems to be unrelated to reading.

Regards,

Werner

werasm

unread,
Dec 15, 2007, 1:02:27 PM12/15/07
to
On Dec 15, 3:35 pm, phil-news-nos...@ipal.net wrote:
[snip]

BTW, thanks. I appreciate your response and time.

Regards,

Werner

phil-new...@ipal.net

unread,
Dec 15, 2007, 5:31:11 PM12/15/07
to

Things running in the kernel are scheduled, too.

phil-new...@ipal.net

unread,
Dec 15, 2007, 5:41:35 PM12/15/07
to
On Sat, 15 Dec 2007 08:57:09 -0800 (PST) werasm <wer...@gmail.com> wrote:

| I had no doubt Linux works fine, but under the particular
| circumstance It did not. The code doing the read works fine
| no doubt, because if I'm willing to wait and no other process
| with priority SCHED_FIFO is hogging the processor, I do get my
| data. I have no experience in Linux device drivers apart from
| using them (in that part have quite some experience as VxWorks
| have a similar interface (POSIX) to drivers). The only
| difference is in VxWorks I know the priority of all tasks
| (including the Kernel). Here I'm blind. I expected the serial
| driver to pick up data regardless of whether or not SCHED_FIFO
| threads exists (I only have one process, BTW).

SCHED_FIFO and runaway processes are not really very compatible.


|> So why not persist in the reading as a test to see how long it is for
|> the process to actually get the data? Or see if it ever gets the data.
|> If there is a problem somewhere, this information might help.
|
| I have done this - it takes until the SCHED_FIFO thread completes.
| This shows me (I think, and I've read somewhere) that the Kernel
| does not schedule the driver to pick up data from the port into
| the RxBuffers.

SCHED_FIFO and runaway processes are not really very compatible.


|> So why are you wanting this other task to hold the processor?
|
| I don't want it to, but there is a chance of this happening. I did
| not need to do much for the waiting time to become greater than 30ms,
| and this is unacceptable. Furthermore, I would prefer using
| SCHED_FIFO because I have a logging task that I run under normal
| scheduling that may only run during idle time. But if SCHED_FIFO
| causes this behavior, then I would be forced to use SCHED_DEFAULT.

One thread needs to absolutely run for sure, while the other thread
must never be interfered with. Hmmm. Sounds like a deadock or the
unstoppable force meeting the immovable object.


|> | Can I change the "lack of reading behaviour" by forcing
|> | the Linux Kernel (or the termios driver) to service its I/Os,
|> | thereby making the data available to read. It was also seen
|> | that as soon as the thread that sends messages stops, data
|> | suddenly becomes available to read (after a couple of
|> | messages has been lost). I'm not in the mood for posting
|> | my code. The behavior I describe is quite clear. Therefore
|> | please just answer if you can, else go irritate someone
|> | else.
|>
|> If the data is unavailable _and_ persists to be unavailable, there could
|> be many causes. If the other process being running can cause the data
|> to become unavailable, that, too, could be one or more of many issues.
|
| There are no other processes. We only have on application running on
| and embedded processor( AT91RM9200 using ucLibC).


|
|> There could be scheduling issues with the process trying to read the data
|> or even the driver reading it from the hardware, depending on how much
|> the busy process is hogging resources.
|
| It looks like there are scheduling issues yes, and that is why I asked
| the question. Is there anything that I can do to force the Kernel to
| force the driver - basically.

Not use SCHED_FIFO or not have a runaway process/thread.

Maybe the right priority settings for the right processes can do the job.


|> It could be a memory issue.
|
| Certainly not a lack of memory issue. The behavior is even prevalent
| when
| I send one message (only not that obvious). Things only start getting
| better when the receiving thread is the only thread doing something.
|
|> This
|> is where diagnostic analysis is needed. And we cannot do that for you
|> (because we need far more information than is available to us to do it).
|
| The reason seems simple - a thread is hogging the processor. One thing
| I cannot afford to do, is make that thread wait on a blocking read.

Then you need a different scheduling paradigm.


| The
| reason was established by diagnostic analysis - if the loop is longer,
| the
| time that the data remains unavailable is longer.

And a blocking read affects this how?


|> If you are confident that the driver is somehow refusing to read the
|> device for extended periods of time for some reason, then what I suggest
|> is to add some code to that driver to have it do printk's to describe
|> what it is doing at any given instant of time, at critical logic points
|> in its code (such as reading from the device, handling interrupts, etc).
|> And watch the console for this.
|
| As I said, I've little experience concerning drivers, and precariously
| little
| time. Changing the scheduling fixed the problem, but I'm wary that
| this may
| cause other problems in future. Basically the test consisted of the

It may. Things need to be tuned well and thoroughly tested, of course.

Sorry, I really am not following that code. It's a little too abstract
for me.

werasm

unread,
Dec 15, 2007, 5:47:02 PM12/15/07
to
On Dec 15, 11:31 pm, phil-news-nos...@ipal.net wrote:
> On Sat, 15 Dec 2007 10:01:02 -0800 (PST) werasm <wer...@gmail.com> wrote:
> | On Dec 15, 3:37 pm, phil-news-nos...@ipal.net wrote:
> |> On Sat, 15 Dec 2007 00:38:01 -0800 (PST) werasm <wer...@gmail.com> wrote:
> |>
> |> | I could add to this that once the sending thread stopped
> |> | messages suddenly started being received within 15ms
> |> | intervals, which is more the behavior that I expected. I
> |> | received about 1995 out of 2000 - the first five got lost
> |> | due to timeout (Whether by select (non-blocking) OR blocking
> |> | read).
> |>
> |> So which thread do you want to control the CPU?
> |
> | I was hoping that things that happen in Kernel space can at
> | least complete despite what scheduling is used by threads, or
> | that there is some mechanism (API call) to force this (like
> | for instance when Thread B in my other example begins the read,
> | it could call "sync" perhaps, that would force the buffers to
> | be filled by data on the port. I've not tried sync, but
> | sync seems to be unrelated to reading.
>
> Things running in the kernel are scheduled, too.

When you call sync(), that is? I have not but perhaps I'd give
sync a try prior to reading. Think it might do the trick? I'll
only start testing again on Monday.

Regards,

Werner

werasm

unread,
Dec 15, 2007, 6:19:29 PM12/15/07
to
On Dec 15, 11:41 pm, phil-news-nos...@ipal.net wrote:


> One thread needs to absolutely run for sure, while the other thread
> must never be interfered with. Hmmm. Sounds like a deadock or the
> unstoppable force meeting the immovable object.

That is not what I stated. One thread must run when it needs to,
period, but it should yield to the reading of data from the
serial port, and to nothing else (especially not logging). I
have no control (I haven't tried sync() yet) over the priority
of the data reading thread (because that sits in the Kernel, or
happens in Kernel space).

Therefore, in general I'm forced to have control over priorities,
and I require only the highest prior task to run until it has
completed (if no data needs to be plucked from the serial port),
and the only way I can get this is by using SCHED_FIFO.

> And a blocking read affects this how?

Even a blocking read has a timeout. When the timeout arrives,
nothing exist on the port - similar to using nanosleep with
non-blocking read.

> It may. Things need to be tuned well and thoroughly tested, of course.

I mainly need SCHED_FIFO as there are cases when things absolutely
has to happen. The problem is that the reading of data from the port
is one of those things, and SCHED_FIFO threads impose on that, which
makes it useless (I still have to try sync()!...)

> Sorry, I really am not following that code. It's a little too abstract
> for me.

Never mind. If I understand your reply concerning sync, it may cause
the port to be serviced. I'll look into that. Unfortunately
unabstracting
the code could become long. Posting member function callbacks over
threads
is no small feat, and our application lives on that architecture.

Regards,

Werner

phil-new...@ipal.net

unread,
Dec 15, 2007, 7:29:09 PM12/15/07
to
On Sat, 15 Dec 2007 15:19:29 -0800 (PST) werasm <wer...@gmail.com> wrote:

| I mainly need SCHED_FIFO as there are cases when things absolutely
| has to happen. The problem is that the reading of data from the port
| is one of those things, and SCHED_FIFO threads impose on that, which
| makes it useless (I still have to try sync()!...)

Apparently SCHED_FIFO is not what you need. I'm not sure what is.
But under SCHED_FIFO, your goals appear to be in conflict with each
other.


| Never mind. If I understand your reply concerning sync, it may cause
| the port to be serviced. I'll look into that. Unfortunately
| unabstracting
| the code could become long. Posting member function callbacks over
| threads
| is no small feat, and our application lives on that architecture.

At this point I would not look at your code even if you made it available.
The only thing I might pursue is the original design requirements that were
the basis of the application development, to see if that would lead to the
design approach you took.

Bob Hauck

unread,
Dec 15, 2007, 7:45:33 PM12/15/07
to
On Sat, 15 Dec 2007 08:57:09 -0800 (PST), werasm <wer...@gmail.com> wrote:

> ThreadA - SCHED_FIFO - priority X
> ...
> for( int i = 0; i < 1000; i++ )
> {
> threadBQ.push( callback( msgToSend ) );
> }
>
> ThreadB - SCHED_FIFO - priority X+1.
> ...
> msgToSend = threadBQ.pop( waitForever );
> port.tx( msgToSend )
>
> if( port.rx( data ) )
> {
> dispatch( data );
> }
>
> The implementation of rx can have various flavors. Currently I
> use nanosleep to sleep for 10ms (as this is when I expect the
> data to be available).

From the symptoms you describe it sounds like you really have B at a
lower priority than A rather than higher as you have written here. I
think you said you're coming from VxWorks, where lower number is higher
priority, the opposite of POSIX, where is higher number is higher.

Just thought I'd mention that before moving on.

SCHED_FIFO means that scheduling is strictly in order of priority with
no fairness rules. The regular scheduling dynamically adjusts
priorities to avoid cpu starvation. SCHED_FIFO simply doesn't do that.
What's more, the whole SCHED_FIFO class has absolute priority over any
regular process.

Therefore, if thread A has priority and takes more than 10 ms to perform
the loop then thread B will wait more than 10 ms to wake up. Period.
Has nothing to do with drivers or anything else. A is ready to run and
it has higher priority. B's timeout having expired makes no difference,
as nanosleep only guarantees a minimum sleep time.

If you want thread B to run at some particular interval, then you have
to design things that way. You need to redesign thread A to block on a
timeout or event once in a while, or else make thread B equal or higher
in priority than A.


--
-| Bob Hauck
-| "Reality has a well-known liberal bias." -- Stephen Colbert
-| http://www.haucks.org/

werasm

unread,
Dec 15, 2007, 8:49:23 PM12/15/07
to
On Dec 16, 1:45 am, Bob Hauck <postmas...@localhost.localdomain>
wrote:

> On Sat, 15 Dec 2007 08:57:09 -0800 (PST), werasm <wer...@gmail.com> wrote:
> > ThreadA - SCHED_FIFO - priority X
> > ...
> > for( int i = 0; i < 1000; i++ )
> > {
> > threadBQ.push( callback( msgToSend ) );
> > }
>
> > ThreadB - SCHED_FIFO - priority X+1.
> > ...
> > msgToSend = threadBQ.pop( waitForever );
> > port.tx( msgToSend )
>
> > if( port.rx( data ) )
> > {
> > dispatch( data );
> > }
>
> > The implementation of rx can have various flavors. Currently I
> > use nanosleep to sleep for 10ms (as this is when I expect the
> > data to be available).
>
> From the symptoms you describe it sounds like you really have B at a
> lower priority than A rather than higher as you have written here. I
> think you said you're coming from VxWorks, where lower number is higher
> priority, the opposite of POSIX, where is higher number is higher.

Nope, B is most definitely higher. It is while it sleeps that A gets
busy. nanosleep actually does exactly what it should - I timed it.
The only problem is then thread B reads, in which case no data
exists to be read.

> Just thought I'd mention that before moving on.

Good point to mention as it could cause confusion, but know Linux
does not use inverse prior.

> SCHED_FIFO means that scheduling is strictly in order of priority with
> no fairness rules.

Yes, that was what I wanted.

> The regular scheduling dynamically adjusts
> priorities to avoid cpu starvation. SCHED_FIFO simply doesn't do that.
> What's more, the whole SCHED_FIFO class has absolute priority over any
> regular process.

Yes.

>
> Therefore, if thread A has priority and takes more than 10 ms to perform
> the loop then thread B will wait more than 10 ms to wake up.

Not if thread B has a higher priority - thread B waked up just fine,
but
the read failed.

> If you want thread B to run at some particular interval, then you have
> to design things that way.

Thread B runs when it must, but the data is not available (on the I/O
port).

> You need to redesign thread A to block on a
> timeout or event once in a while, or else make thread B equal or higher
> in priority than A.

I can't do that. Thread A has to give the command and move one in this
case as
there are other things that don't depend on data being received (on
the
serial port) that has to happen in the meantime (actually this
involves
other I/O). Thread A should move on while Thread B is waiting for data
(B
after all does nothing but wait nanosleep, and the reads data, so A
can
rightly continue. It would stop naturally when B starts executing, and
it
does, but then the data is not available (as seemingly another thread
-
lets call this one Thread C, living in Kernel space - was starved.).

Thank you for your response,

Werner

werasm

unread,
Dec 15, 2007, 9:09:50 PM12/15/07
to
On Dec 16, 1:29 am, phil-news-nos...@ipal.net wrote:

> At this point I would not look at your code even if you made it available.
> The only thing I might pursue is the original design requirements that were
> the basis of the application development, to see if that would lead to the
> design approach you took.

I cannot say Linux was my choice, but the requirements leading to what
I deem
my design would be is like this:

The system is a realtime dispenser controller(chaff and flare, to be
precise).
Various types of dispensers could exist. The interfaces are also
abstracted,
but currently I communicate with half of them over a CAN bus and with
the
other half over RS485. This depends on what the dispensers require. I
have
the following threads (NB: priority order not inversed):

Supervision : highest.

CAN i/o : highest - 2.
Serial i/o : highest - 2.
Discrete i/o : highest - 2.

State administration : highest - 5.
Dispense control : highest - 6
Status monitoring : highest - 7
Diagnostics (logging) : default (0), queue allowed to toss messages.

The thread doing most of the work is the Dispense Ctrl thread. It
schedules dispensers to dispense. I especially don't want it to yield
to status monitoring and logging. I suppose I can achieve this
programatically but typically SCHED_FIFO would do the job well
if it did not impose on the servicing of the I/O by the Kernel.
This would not have been the case for VxWorks, sadly. Could calling
sync from the I/O threads (that have higher priority) perhaps do
the trick. I have not tried this yet but I'm hoping it may work.

Regards,

Werner

Grant Edwards

unread,
Dec 15, 2007, 9:46:02 PM12/15/07
to
On 2007-12-14, werasm <wer...@gmail.com> wrote:

> I wrote an application that writes to the serial port using
> a task that basically writes, then sleeps 10ms, the reads.
> I would expect the data to be available, but is seems that
> the work done by one of my SCHED_FIFO tasks prevents
> the serial driver from reading the data by the time the sleep
> ends.

I don't see how what you describe is possible. The serial
driver is interrupt driven. There is no task involved in the
serial driver reading the data, so it matters not what other
tasks are doing or what priority they have.

> Do any of you have any advice concerning this?

You problem is probably that other tasks are keeping the
reading task from waking up, but one thing you can do is to
make sure you have the low-latency flag set on the serial
driver. That will insure that the driver passes received data
up to the line-discipline layer on every receive interrupt
(regardless of how many/few bytes have been received).

> I don't want to modify the serial driver (I've never fiddled
> with Linux driver code before).

Whoa, there. What makes you think there's something wrong with
the serial driver? The problem is most certanily in your
application design.

> Currently I'm not sure from which context the driver picks up
> data from the port.

It's done by what used to be called a an ISR "lower half". Now
it's called a software interrupt or something like that.

Set the low-latency flag on the device in question and make
sure the reading task has a higher priority than anything else
that's running.

--
Grant Edwards grante Yow! Are we THERE yet?
at
visi.com

werasm

unread,
Dec 16, 2007, 8:53:22 AM12/16/07
to
On Dec 16, 3:46 am, Grant Edwards <gra...@visi.com> wrote:

> You problem is probably that other tasks are keeping the
> reading task from waking up, but one thing you can do is to
> make sure you have the low-latency flag set on the serial
> driver. That will insure that the driver passes received data
> up to the line-discipline layer on every receive interrupt
> (regardless of how many/few bytes have been received).

I will check into the low latency flag advice. Could that have
any adverse effects?

> Whoa, there. What makes you think there's something wrong with

> the serial driver? The problem is most certainly in your
> application design.

I probably sound obstinate, but my thread priorities are as
described here above, with the reading thread having the
highest priority without a doubt. The reading thread wakes
up fine just to find no data is waiting. I could do a
blocking read from the outset (as suggested by someone
else), but this has problems of its own nature Basically
we are using the termios driver that only allows to specify
timeouts with resolutions of 100ms, which is to slow. I
need to be aware of a system not responding withing 20ms.

I'm considering doing a blocking read just to see whether
there is a difference (based on the fact that I've read
somewhere that the servicing of the ISR may be delayed). On
VxWorks I've used select and read in combination. I
did not want to scratch in the port abstraction (which simply
performs either a blocking or non-blocking read, the blocking
read returning to slow when nothing is available).

I think the fact that I don't attempt to read prior to sleeping
implies there is no I/O request which may delay the servicing
of the particular interrupt (I think or reason out of naivety).

> It's done by what used to be called a an ISR "lower half". Now
> it's called a software interrupt or something like that.
>
> Set the low-latency flag on the device in question and make
> sure the reading task has a higher priority than anything else
> that's running.

Oh, the thread calling read most certainly is at the highest
priority - have you not seen that in my replies to others. I
will also give the low-latency flag a try.

Regards,

Werner

Rainer Weikusat

unread,
Dec 16, 2007, 9:07:19 AM12/16/07
to

Taking your other posts into account, what you describe cannot be
caused by a process hogging the CPU directly, only as a side effect of
something this process does (probably, while running in the kernel).

Basically, something which would be supposed to happen as part of then
serial interrupt processing apparently doesn't happen. And that would
be the place where I would start to look: What happens (or doesn't
happen) in the serial driver when the data arrives 'electrically'?

Grant Edwards

unread,
Dec 16, 2007, 11:25:52 AM12/16/07
to
On 2007-12-16, werasm <wer...@gmail.com> wrote:
> On Dec 16, 3:46 am, Grant Edwards <gra...@visi.com> wrote:
>
>> You problem is probably that other tasks are keeping the
>> reading task from waking up, but one thing you can do is to
>> make sure you have the low-latency flag set on the serial
>> driver. That will insure that the driver passes received data
>> up to the line-discipline layer on every receive interrupt
>> (regardless of how many/few bytes have been received).
>
> I will check into the low latency flag advice. Could that have
> any adverse effects?

IIRC, it increases overhead because data is transferred from
the driver to the line-discipline layer with a finer granularity.

> I'm considering doing a blocking read just to see whether
> there is a difference (based on the fact that I've read
> somewhere that the servicing of the ISR may be delayed).

I don't think it's going to make any difference, but it won't
hurt either.

> On VxWorks I've used select and read in combination. I did not
> want to scratch in the port abstraction (which simply performs
> either a blocking or non-blocking read, the blocking read
> returning to slow when nothing is available).
>
> I think the fact that I don't attempt to read prior to sleeping
> implies there is no I/O request which may delay the servicing
> of the particular interrupt (I think or reason out of naivety).

I/O requests don't delay the servicing of interrupts.

>> It's done by what used to be called a an ISR "lower half". Now
>> it's called a software interrupt or something like that.
>>
>> Set the low-latency flag on the device in question and make
>> sure the reading task has a higher priority than anything else
>> that's running.
>
> Oh, the thread calling read most certainly is at the highest
> priority - have you not seen that in my replies to others.

I've not really been able to follow your responses to others.

> I will also give the low-latency flag a try.

--
Grant Edwards grante Yow! KARL MALDEN'S NOSE
at just won an ACADEMY AWARD!!
visi.com

Pierre Asselin

unread,
Dec 16, 2007, 8:52:45 PM12/16/07
to
werasm <wer...@gmail.com> wrote:

> Therefore, in general I'm forced to have control over priorities,
> and I require only the highest prior task to run until it has
> completed (if no data needs to be plucked from the serial port),
> and the only way I can get this is by using SCHED_FIFO.

> On Dec 15, 11:41 pm, phil-news-nos...@ipal.net wrote:

> > And a blocking read affects this how?

> Even a blocking read has a timeout.

I've been trying to make sense of the thread, without much success.
I second phil's question: what's wrong with a blocking read ? From
the read(2) manpage, if you read() on a descriptor that doesn't
have O_NONBLOCK set (see open(2) or fcntl(2)), then you block until
some data arrives or for eternity, whichever happens first. In
other words, a blocking read has no timeout.

If you want a timeout, you precede the read() by a select().


> When the timeout arrives,
> nothing exist on the port - similar to using nanosleep with
> non-blocking read.

Then why is the thread waking up ? If the data hasn't yet
arrived it should keep waiting.

Are you trying to read byte by byte in a tight loop ?
Don't do that. The better idiom is to wait for some
data to arrive, then read as much of it as there is.

/* not tested */
char buf[ENOUGH];
int got= 0;
int nready;
while(got < NEED) {
nready= select(1, &rfd, &none, &none, &timeout); /* blocks */
if(0==nready) break; /* timeout before data arrived */
got+= read(fd, buf+got, ENOUGH-got);
}

/* when you get here, one of two conditions holds: either
* got >= NEED
* in which case you have your data and you should
* process it,
* or
* got < NEED
* in which case you hit the timeout and you should
* assume the data isn't forthcoming.
*/

I suspect the SCHED_FIFO is a red herring or maybe that it worsens
the symptoms. If you want to read your data promptly, then *the
reader thread has to be waiting for it when the data arrives*.
The arrival of the data is what will wake it up.


--
pa at panix dot com

David Schwartz

unread,
Dec 17, 2007, 3:06:04 AM12/17/07
to
On Dec 15, 4:29 pm, phil-news-nos...@ipal.net wrote:

> Apparently SCHED_FIFO is not what you need. I'm not sure what is.
> But under SCHED_FIFO, your goals appear to be in conflict with each
> other.

Exactly. SCHED_FIFO is when you want nothing to interrupt the thread
until it says it's done. If that's not what you want, then that's not
what you want.

DS

David Schwartz

unread,
Dec 17, 2007, 3:09:46 AM12/17/07
to
On Dec 15, 5:49 pm, werasm <wer...@gmail.com> wrote:

> Nope, B is most definitely higher. It is while it sleeps that A gets
> busy. nanosleep actually does exactly what it should - I timed it.
> The only problem is then thread B reads, in which case no data
> exists to be read.

Since you should be using a blocking read, how could you know this?

> Not if thread B has a higher priority - thread B waked up just fine,
> but
> the read failed.

It sounds like you are still using a non-blocking read, despite the
fact that it's been explained that this is not what you want. There's
no point in giving you advice if you ignore it.

DS

werasm

unread,
Dec 17, 2007, 6:25:10 AM12/17/07
to
On Dec 17, 9:09 am, David Schwartz <dav...@webmaster.com> wrote:
> On Dec 15, 5:49 pm, werasm <wer...@gmail.com> wrote:
>
> > Nope, B is most definitely higher. It is while it sleeps that A gets
> > busy. nanosleep actually does exactly what it should - I timed it.
> > The only problem is then thread B reads, in which case no data
> > exists to be read.
>
> Since you should be using a blocking read, how could you know this?

No, I'm using nanosleep currently, and then a non-blocking read. The
reason for this is quite simple - the termios driver only allows you
to set up a minimum time of 100ms (too much). I'm using a port
abstraction
that could be set up to use a blocking read, but I chose to use a
non-blocking read because of the 100ms. If I'm to use select, I must
fiddle with the port abstraction, but I don't see why this should make
a difference (perhaps I'm surprised when I do in the course of the
next to days).

Therefore - to re-iterate:

I'm currently using a non-blocking read after I slept for 10ms (A
behavior for me in principle similar to select). When the thread
wakes up the data is not available using a non-blocking read.

> It sounds like you are still using a non-blocking read, despite the
> fact that it's been explained that this is not what you want. There's
> no point in giving you advice if you ignore it.

Yes, and I'll take the advice and change the port abstraction (to use
select) and let you know whether it improves things (in due course).

Nevertheless, I still wonder at the difference in behavior between

a) nanosleep - nonblocking read and..

b) select, non-blocking read.

Blocking read itself is simple out of the question because of the
granularity of the termios driver (in DeciSeconds).

Regards,

Werner

werasm

unread,
Dec 17, 2007, 6:27:07 AM12/17/07
to

Nothing except a higher priority thread, of course (and I/Os).

W

David Schwartz

unread,
Dec 17, 2007, 6:58:10 AM12/17/07
to
On Dec 17, 3:25 am, werasm <wer...@gmail.com> wrote:

> > Since you should be using a blocking read, how could you know this?

> No, I'm using nanosleep currently, and then a non-blocking read.

This is dumb. If the nanosleep is for too long, you'll process the
data later than you could have. If the nanosleep isn't for long
enough, your read will fail. So why are you doing things this way?

> The
> reason for this is quite simple - the termios driver only allows you
> to set up a minimum time of 100ms (too much).

Who cares? How does this prevent you from using a blocking read or
select?

> I'm using a port
> abstraction
> that could be set up to use a blocking read, but I chose to use a
> non-blocking read because of the 100ms. If I'm to use select, I must
> fiddle with the port abstraction, but I don't see why this should make
> a difference (perhaps I'm surprised when I do in the course of the
> next to days).

No idea what this means, other than that you're totally ignoring the
advice everyone is giving you. Use a blocking read. If for some reason
you can't do that, use select. Otherwise, there is no reason to expect
your code to work.

> Therefore - to re-iterate:
>
> I'm currently using a non-blocking read after I slept for 10ms (A
> behavior for me in principle similar to select). When the thread
> wakes up the data is not available using a non-blocking read.

Right, and this is what everyone is telling you not to do. You are
trying to fake a blocking read with a block followed by a read. That
just doesn't work. You either need to use a proper blocking read or
proper non-blocking I/O, depending upon whether or not you really want
to block.

> > It sounds like you are still using a non-blocking read, despite the
> > fact that it's been explained that this is not what you want. There's
> > no point in giving you advice if you ignore it.

> Yes, and I'll take the advice and change the port abstraction (to use
> select) and let you know whether it improves things (in due course).

That's a good idea, since it sounds like you actually don't want to
block.

> Nevertheless, I still wonder at the difference in behavior between
>
> a) nanosleep - nonblocking read and..
>
> b) select, non-blocking read.
>
> Blocking read itself is simple out of the question because of the
> granularity of the termios driver (in DeciSeconds).

The difference is that with nanosleep, you have to guess how long to
wait. If you don't wait long enough, the read fails. If you wait too
long, you waste time. The 'select' function waits until either the
data arrives or the timeout occurs, which is what you actually want.
Make sure to set the descriptor non-blocking. (Since you don't want to
block.)

DS

Bob Hauck

unread,
Dec 17, 2007, 8:17:47 AM12/17/07
to
On Mon, 17 Dec 2007 03:25:10 -0800 (PST), werasm <wer...@gmail.com> wrote:
> On Dec 17, 9:09 am, David Schwartz <dav...@webmaster.com> wrote:
>> On Dec 15, 5:49 pm, werasm <wer...@gmail.com> wrote:
>>
>> > Nope, B is most definitely higher. It is while it sleeps that A gets
>> > busy. nanosleep actually does exactly what it should - I timed it.
>> > The only problem is then thread B reads, in which case no data
>> > exists to be read.
>>
>> Since you should be using a blocking read, how could you know this?
>
> No, I'm using nanosleep currently, and then a non-blocking read. The
> reason for this is quite simple - the termios driver only allows you
> to set up a minimum time of 100ms (too much).

That timer only applies if there is not enough data. The read will
return after 100 ms if there is less data than you asked for. If you
set the flags right it will return right away if there is data.

Another issue is the hardware FIFO in the serial port. If you use the
default port settings the hardware will only signal an interrupt once
the FIFO has reached a certain fullness or the FIFO has some characters
waiting but no new ones have arrived for a while. IIRC "a while" is a
few character times.

The "low latency" IOCTL flag that someone told you about sets the port
to signal an interrupt after each character. If you are sending short
messages this will minimize the waiting time caused by the FIFO at the
cost of higher interrupt overhead.


> Nevertheless, I still wonder at the difference in behavior between
>
> a) nanosleep - nonblocking read and..
>
> b) select, non-blocking read.

With select() you know that there is actually data ready. With
nanosleep() you are just assuming that there is data ready, which
assumption seems to be wrong.

If you want to do some processing if there is no data ready for some
period of time, just use select with a timeout.

werasm

unread,
Dec 17, 2007, 9:32:30 AM12/17/07
to
On Dec 17, 12:58 pm, David Schwartz <dav...@webmaster.com> wrote:
> On Dec 17, 3:25 am, werasm <wer...@gmail.com> wrote:
>
> > > Since you should be using a blocking read, how could you know this?
> > No, I'm using nanosleep currently, and then a non-blocking read.
>
> This is dumb. If the nanosleep is for too long, you'll process the
> data later than you could have. If the nanosleep isn't for long
> enough, your read will fail. So why are you doing things this way?
>
> > The
> > reason for this is quite simple - the termios driver only allows you
> > to set up a minimum time of 100ms (too much).
>
> Who cares? How does this prevent you from using a blocking read or
> select?

As far as the blocking read is concerned - 100ms granularity is
too much - I cannot wait longer than 10ms (15 at the absolute
most - period). As far as select goes - I'll test and see how
it goes. I used nanosleep initially because my deadline was
10ms and the abstraction (not my code) did not give me a
granularity or minimum wait time of less than 100ms.

The reason why I cannot wait is because I use RS485 and if
there is any sniff that something is down, I need to use
something else (cmd/reply protocol).

>
> > I'm using a port
> > abstraction
> > that could be set up to use a blocking read, but I chose to use a
> > non-blocking read because of the 100ms. If I'm to use select, I must
> > fiddle with the port abstraction, but I don't see why this should make
> > a difference (perhaps I'm surprised when I do in the course of the
> > next to days).
>
> No idea what this means, other than that you're totally ignoring the
> advice everyone is giving you.

What this means is that I am using someone else's class (this class
abstracts the port, and the abstraction does not use select). I
will have to modify this which I did not want to do (as this
defeats the purpose of abstraction).

> The difference is that with nanosleep, you have to guess how long to
> wait.

Or perhaps stipulate how long you can afford to wait - no different,
therefore.

> If you don't wait long enough, the read fails.

If you don't select long enough, the read fails as well - no
difference.

> If you wait too long, you waste time.

Yes, for this reason I have in the past also used select, but now I'm
using a port abstraction that does additional things like break signal
generation on Tx, etc (WHICH IS NOT MINE). I did not mind wasting a
millisecond or two, but I had a deadline (hence I opted for
nanosleep). If you still can't comprehend why, I rest my case.

> The 'select' function waits until either the
> data arrives or the timeout occurs, which is what you actually want.

Yes, I know what select does. This time I had good reason (as
explained
above) not to use is. Without twiddling with the class given to me
I don't even have access to descriptors. For that reason I used
the interface provided to me of which select was not part.

Regards,

Werner

Grant Edwards

unread,
Dec 17, 2007, 11:08:16 AM12/17/07
to
On 2007-12-17, Bob Hauck <postm...@localhost.localdomain> wrote:

> Another issue is the hardware FIFO in the serial port. If you
> use the default port settings the hardware will only signal an
> interrupt once the FIFO has reached a certain fullness or the
> FIFO has some characters waiting but no new ones have arrived
> for a while. IIRC "a while" is a few character times.

In the "standard" 16550 implimenation from National, it's 4
character times. Most of the PC chipsets do the same.

> The "low latency" IOCTL flag that someone told you about sets
> the port to signal an interrupt after each character.

No, it sets up the driver so that it transfers data to the line
discipline layer on every receive interrupt (rather than doing
it once every 10ms).

> If you are sending short messages this will minimize the
> waiting time caused by the FIFO at the cost of higher
> interrupt overhead.

If you want to receive single characters right away, you'll
need to disable the receive FIFO as well as set the low-latency
flag. IIRC, you can disable the rx FIFO either by setting the
rx_trigger value to 1 or by forcing the UART type to 16450.

Doing this at very high baud rates will eat up some CPU time...

>> Nevertheless, I still wonder at the difference in behavior between
>>
>> a) nanosleep - nonblocking read and..
>>
>> b) select, non-blocking read.
>
> With select() you know that there is actually data ready.
> With nanosleep() you are just assuming that there is data
> ready, which assumption seems to be wrong.

With select, you wake up immediately upon receipt of data. With
sleep, you wait for a fixed period of time no matter how soon
the data arrives.

> If you want to do some processing if there is no data ready
> for some period of time, just use select with a timeout.

Using select() is definitely the correct solution (regardless
of what the author of some broken "port abstraction" class
seems to think.)

Wouldn't it be easier to just fix the broken port class than to
spend days and days arguing with everybody who tries to help?

--
Grant Edwards grante Yow! On the road, ZIPPY
at is a pinhead without a
visi.com purpose, but never without
a POINT.

werasm

unread,
Dec 17, 2007, 12:29:56 PM12/17/07
to
On Dec 17, 5:08 pm, Grant Edwards <gra...@visi.com> wrote:


> Wouldn't it be easier to just fix the broken port class than to
> spend days and days arguing with everybody who tries to help?

Thank you, valuable reply. Yes, I will whereafter I will test
again. Thank you for everybody that contributed. Especially your
last reply was insightful.

I will come back with my results - possibly during the course
of the week (but I have other more important things pressing),
else after a long holiday.

Werner

David Schwartz

unread,
Dec 17, 2007, 8:18:17 PM12/17/07
to
On Dec 17, 6:32 am, werasm <wer...@gmail.com> wrote:

> As far as the blocking read is concerned - 100ms granularity is
> too much - I cannot wait longer than 10ms (15 at the absolute
> most - period).

You are confusing two very different concepts.

Concept 1: If I do not get any data, I must do something else within
15 milliseconds.

Concept 2: I only wish to wait for the data for 15 milliseconds.

You claiming these two are identical, and they are not. For example,
suppose I need some work done within two weeks. If I don't get it
within 12 days, I want to call the person who is supposed to give it
to me and remind him that it's due in two days. One thread can wait
two weeks for the work while another sends him a memo in 12 days.

You can let one thread wait as long as it takes for data to arrive.
You can still have another thread do something special if the first
thread does not receive the data within the required interval.

> As far as select goes - I'll test and see how
> it goes.

It sounds like this is probably the ideal approach. The 'select'
function allows you to wait for something to happen with a flexible
timeout.

> I used nanosleep initially because my deadline was
> 10ms and the abstraction (not my code) did not give me a
> granularity or minimum wait time of less than 100ms.

You do not need to teach the operating system your protocol. You can
do whatever you want if data is not received within 10 milliseconds
without having to have some thread return from a function in that
time. You can set a 10 millisecond timer, cancel the timer yourself if
the data is received, and have the timer do whatever you want.

It sounds like you are using threads as straightjackets rather than
facilitators.

> The reason why I cannot wait is because I use RS485 and if
> there is any sniff that something is down, I need to use
> something else (cmd/reply protocol).

That doesn't mean you don't still want a thread blocked in 'recv'. If
any data arrives, whenever that happens, you want to process it,
right? You are trying to teach the kernel your protocol rather than
coding it.


> > The difference is that with nanosleep, you have to guess how long to
> > wait.

> Or perhaps stipulate how long you can afford to wait - no different,
> therefore.

Huge difference, because waiting too long may trigger bad behavior in
other parts of the system. It is your program's responsibility to
drain the buffer.

> > If you don't wait long enough, the read fails.

> If you don't select long enough, the read fails as well - no
> difference.

No, because you don't call 'read' in that case.

> > The 'select' function waits until either the
> > data arrives or the timeout occurs, which is what you actually want.

> Yes, I know what select does. This time I had good reason (as
> explained
> above) not to use is. Without twiddling with the class given to me
> I don't even have access to descriptors. For that reason I used
> the interface provided to me of which select was not part.

It sounds like your problem is simply a broken interface and has
little to nothing to do with the kernel or the serial driver.

DS

Luis Colorado

unread,
Dec 23, 2007, 5:11:47 PM12/23/07
to

"werasm" <wer...@gmail.com> escribió en el mensaje news:aaa39314-87f0-4c74...@o42g2000hsc.googlegroups.com...
> On Dec 15, 2:53 am, fl...@apaflo.com (Floyd L. Davidson) wrote:
>> werasm <wer...@gmail.com> wrote:
[....]
> You don't need to see my code. Actually my code works fine.

Oops ;)

> Initially I used a blocking read - no magic there - go look
> it up in the Unix Spec. We used to Termios driver to set
> up the port and the smallest timeout specifiable is 1 DeciSec
> or the first character, whichever happens first. The problem
> was that even after a DeciSec for certain tests there was
> no data to read (under certain circumstances), even though
> the data should have been received after approx. 7ms (and
> this was verified by oscilloscope). The reason I found
> to be the fact that the task sending a 1000 messages
> (in a loop) was holding the processor. The more messages
> were sent, the longer the processor was held (because
> of the fact that it used SCHED_FIFO). My question is:

The termios VTIME parameter is for intercharacter timeouts, it needs at least for a full character read to be in action.

Can at least we have a look at the values you used for VMIN and VTIME in your code, as the serial driver depends on both of them. If you think your code is so perfect than there is no need to show it to anyone, just you would be able to answer why it is not working and no need to ask it here.

>
> Can I change the "lack of reading behaviour" by forcing
> the Linux Kernel (or the termios driver) to service its I/Os,
> thereby making the data available to read. It was also seen
> that as soon as the thread that sends messages stops, data
> suddenly becomes available to read (after a couple of
> messages has been lost). I'm not in the mood for posting
> my code. The behavior I describe is quite clear. Therefore
> please just answer if you can, else go irritate someone
> else.
>

> Regards,
>
> Werner
>
>
>

Luis Colorado

unread,
Dec 23, 2007, 5:13:48 PM12/23/07
to
sync(2) just flush the block devices buffers to disk. It's not related to serial or char devices.

"werasm" <wer...@gmail.com> escribió en el mensaje news:287f5ce9-9088-4d64...@e6g2000prf.googlegroups.com...

Luis Colorado

unread,
Dec 23, 2007, 5:25:05 PM12/23/07
to

"Bob Hauck" <postm...@localhost.localdomain> escribió en el mensaje news:slrnfmctnr.4...@bigbird.haucks.org...

> On Mon, 17 Dec 2007 03:25:10 -0800 (PST), werasm <wer...@gmail.com> wrote:
>> On Dec 17, 9:09 am, David Schwartz <dav...@webmaster.com> wrote:
>>> On Dec 15, 5:49 pm, werasm <wer...@gmail.com> wrote:
>>>
[...]

> Another issue is the hardware FIFO in the serial port. If you use the
> default port settings the hardware will only signal an interrupt once
> the FIFO has reached a certain fullness or the FIFO has some characters
> waiting but no new ones have arrived for a while. IIRC "a while" is a
> few character times.

Not, if you use the default port settings you'll get your characters only once a new line has come in. You first have to get raw mode (in termios jerk) and then to decide if you want VMIN==0&&VTIME==0, VMIN!==0&&VTIME=0, VMIN==0&&VTIME!=0 or both !=0 (the driver behaves differently in these four different scenarios)

I think you all must read termios manual page.

0 new messages