On 2008-06-11, Chris Carlen <crcarleREMOVETHIS@BOGUSsbcglobal.net> wrote:
>
> Yes. In discussions with our main programmer here (I am mainly an
> electronics and laser/optics guy, but also like to do low-level
> programming) he mentions that most programmers tend to agree that serial
> IO doesn't fit the C stream model well, mainly since the serial port may
> have nothing available at times, which doesn't mean that it is the end
> of file.
>
> We also got into a discussion of different models for the operation of a
> SCI_getc() like function. I was designing my function to not block, but
> just return EOF as a "nothing available" indicator. It would be up to
> higher level code (the protocol level) to determine the significance of
> this.
>
> He tends to think the SCI_getc() call *should* block until something is
> available to return, or timeout and then return an EOF, in which case
> EOF has a somewhat different significance than in the non-blocking case.
>
> I like the non-blocking timeout model since my usage might be listening
> to human types commands at a terminal, for which it is impossible to
> define a timeout. What if the guy/gal takes their lunch break in the
> middle of typing a command?
I'd suggest taking a look at how Unix non-blocking I/O works - the
ideas there have been well tested with real world experience.
There you have two functions for dealing with reading data. read()
functions as you would expect, however if there is no data available
it returns -1 - not EOF (even though these are the same thing,
conceptually there is a difference). errno is set to indicate why
-1 was returned, so you have different codes for EOF, no data,
hardware error etc.
Applying these concepts to your situation that suggests two distinct
functions - your SCI_getc() function like you have now, probably
in 'non-blocking' trim, and an SCI_poll() function that tells you
how many characters are available to be read. Alternatively,
SCI_poll() could simply have a boolean sense, telling you if there
is any input waiting to be read. This approach has the merit that
you can test for the presence of input in a completely different
area of code to where you actually read it, so for example you can
have such a test in your program main loop and only call your
'process input' stuff when it is actually needed.
--
Andrew Smallshaw
andrews@sdf.lonestar.org
Reply by Chris Carlen●June 11, 20082008-06-11
Jack Klein wrote:
> On Tue, 10 Jun 2008 15:59:32 -0700, Chris Carlen
> <crcarleREMOVETHIS@BOGUSsbcglobal.net> wrote in comp.arch.embedded:
>>int SCI_getc(void);
>>returns the next character received or EOF if nothing is available.
>
> You may have to decide if EOF is optimum. You are using in a way that
> is different than in C FILE * operations. Your caller could receive
> EOF now, and without doing anything he can receive a valid data value
> if a character has been received since then. That doesn't happen in C
> streams.
Yes. In discussions with our main programmer here (I am mainly an
electronics and laser/optics guy, but also like to do low-level
programming) he mentions that most programmers tend to agree that serial
IO doesn't fit the C stream model well, mainly since the serial port may
have nothing available at times, which doesn't mean that it is the end
of file.
We also got into a discussion of different models for the operation of a
SCI_getc() like function. I was designing my function to not block, but
just return EOF as a "nothing available" indicator. It would be up to
higher level code (the protocol level) to determine the significance of
this.
He tends to think the SCI_getc() call *should* block until something is
available to return, or timeout and then return an EOF, in which case
EOF has a somewhat different significance than in the non-blocking case.
I like the non-blocking timeout model since my usage might be listening
to human types commands at a terminal, for which it is impossible to
define a timeout. What if the guy/gal takes their lunch break in the
middle of typing a command?
>>However, if there is an error in the receiver, there appear to be two
>>ways to inform the user space:
>>
>>
>>1. On the call to SCI_getc() after all valid chars have been removed
>>from the buffer, return a special code other than EOF, such as a:
>>
>>#define SCI_RXERR -2 /* or something like that */
>>
>>Now if detailed info on the nature of the error were needed in this
>>case, a call such as SCI_status() could provide this. In this case, the
>>user mustn't always call SCI_status() after an EOF to find out if it was
>>really no char available, or an error.
>>
>>Since serial reception fundamentally differs from file IO, I find this
>>option attractive.
>>
>>
>>2. The second option is to return EOF always if there is no char
>>available or there is an error, similar to fgetc(). Then the user would
>>have to call another function SCI_status() or the like to get a code
>>which can be parsed to determine the specific nature of the error.
>>
>>Since the SCIx_getc() call will frequently return EOF while waiting for
>>data, it seems cumbersome to always have to call SCI_status() to see if
>>it was due to an error.
>
> You do realize that the SCI is an 8-bit peripheral on an architecture
> with 16-bit registers, don't you?
Yes, though actually it has 32 bit registers; but at most 16 bit IO
registers, granted. The char type is defined identical to int, so one
can't really work with 8 bit bytes, and reads from 8 bit registers
automatically "cast" to ints. That is why my first option shown above
is to use the upper byte range for an error code. This isn't really
afforded by the architecture though. It is simply a choice of how to
define the return value of the function.
The gist of my question was mainly to determine if the mood among
programmers was such that deviations from some standard model are looked
down upon, and also to see if there is any sense of standardization of
APIs to talk to UARTs at all, at the embedded device level. This
doesn't appear to be the case, which encourages me to do something
exactly like I mentioned and you detail below...
>No data value read from the UART
> will ever be outside the range of 0 to 255. That leaves you an
> enormous number of values to define as various status indicators,
> rather than data.
>
> Consider something like:
>
> enum {
> SCI_NO_DATA = 0x100,
> SCI_PARITY_ERROR = 0x101,
> SCI_OVERFLOW_ERROR = 0x102,
> SCI_FRAMING_ERROR = 0x103,
> SCI_BREAK_RECEIVED = 0x104
> /* continue as needed */
> };
>
> This enumeration is defined in a header that includes the prototypes
> of API functions.
>
> Then your user merely has to do:
>
> int val = SCI_Get();
> if (val < SCI_NO_DATA)
> {
> /* do something with data */
> }
> else
> {
> /* handle errors, perhaps with a switch on the enum value */
> }
>
Yes, exactly.
--
Good day!
____________________________________
CRC
crobcREMOVETHIS@BOGUSsbcglobal.net
NOTE, delete texts: "REMOVETHIS" and
"BOGUS" from email address to reply.
Reply by Robert Adsett●June 11, 20082008-06-11
In article <2udu44pu3c5bs1n7a0ccr60anbo9jk4m5o@4ax.com>, Jack Klein
says...
> On Tue, 10 Jun 2008 19:50:34 -0400, Robert Adsett
> <sub2@aeolusdevelopment.com> wrote in comp.arch.embedded:
> > Note this also requires that your returned value be larger than a char,
> > a failing shared by the C character level input fuctions.
>
> Well, yes and no. The 2812 does not have 8-bit bytes, CHAR_BIT is 16.
> sizeof(int) == sizeof(char) == 1.
On Tue, 10 Jun 2008 15:59:32 -0700, Chris Carlen
<crcarleREMOVETHIS@BOGUSsbcglobal.net> wrote in comp.arch.embedded:
> Hi:
>
> Once again, I am writing a buffered, interrupt-driven driver for the
> serial comm UART (SCI) in the TI TMS320F2812. The lowest level
> interface to the user will be a function
>
> int SCI_getc(void);
>
> returns the next character received or EOF if nothing is available.
You may have to decide if EOF is optimum. You are using in a way that
is different than in C FILE * operations. Your caller could receive
EOF now, and without doing anything he can receive a valid data value
if a character has been received since then. That doesn't happen in C
streams.
> However, if there is an error in the receiver, there appear to be two
> ways to inform the user space:
>
>
> 1. On the call to SCI_getc() after all valid chars have been removed
> from the buffer, return a special code other than EOF, such as a:
>
> #define SCI_RXERR -2 /* or something like that */
>
> Now if detailed info on the nature of the error were needed in this
> case, a call such as SCI_status() could provide this. In this case, the
> user mustn't always call SCI_status() after an EOF to find out if it was
> really no char available, or an error.
>
> Since serial reception fundamentally differs from file IO, I find this
> option attractive.
>
>
> 2. The second option is to return EOF always if there is no char
> available or there is an error, similar to fgetc(). Then the user would
> have to call another function SCI_status() or the like to get a code
> which can be parsed to determine the specific nature of the error.
>
> Since the SCIx_getc() call will frequently return EOF while waiting for
> data, it seems cumbersome to always have to call SCI_status() to see if
> it was due to an error.
You do realize that the SCI is an 8-bit peripheral on an architecture
with 16-bit registers, don't you? No data value read from the UART
will ever be outside the range of 0 to 255. That leaves you an
enormous number of values to define as various status indicators,
rather than data.
Consider something like:
enum {
SCI_NO_DATA = 0x100,
SCI_PARITY_ERROR = 0x101,
SCI_OVERFLOW_ERROR = 0x102,
SCI_FRAMING_ERROR = 0x103,
SCI_BREAK_RECEIVED = 0x104
/* continue as needed */
};
This enumeration is defined in a header that includes the prototypes
of API functions.
Then your user merely has to do:
int val = SCI_Get();
if (val < SCI_NO_DATA)
{
/* do something with data */
}
else
{
/* handle errors, perhaps with a switch on the enum value */
}
On Tue, 10 Jun 2008 19:50:34 -0400, Robert Adsett
<sub2@aeolusdevelopment.com> wrote in comp.arch.embedded:
> In article <g2n10q0ee4@news4.newsguy.com>, Chris Carlen says...
> > Hi:
> >
> > Once again, I am writing a buffered, interrupt-driven driver for the
> > serial comm UART (SCI) in the TI TMS320F2812. The lowest level
> > interface to the user will be a function
> >
> > int SCI_getc(void);
> >
> > returns the next character received or EOF if nothing is available.
> >
> > However, if there is an error in the receiver, there appear to be two
> > ways to inform the user space:
> >
> >
> > 1. On the call to SCI_getc() after all valid chars have been removed
> > from the buffer, return a special code other than EOF, such as a:
> >
> > #define SCI_RXERR -2 /* or something like that */
> >
> > Now if detailed info on the nature of the error were needed in this
> > case, a call such as SCI_status() could provide this. In this case, the
> > user mustn't always call SCI_status() after an EOF to find out if it was
> > really no char available, or an error.
> >
> > Since serial reception fundamentally differs from file IO, I find this
> > option attractive.
>
> Note this also requires that your returned value be larger than a char,
> a failing shared by the C character level input fuctions.
Well, yes and no. The 2812 does not have 8-bit bytes, CHAR_BIT is 16.
sizeof(int) == sizeof(char) == 1.
But the SCI is an 8-bit peripheral. All reads from the SCI Rx data
register return some value in the low 8 bits, and zeros in the high 8
bits.
So one can easily pick patterns above 255 to use for any special
purpose indicators.
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
Reply by Robert Adsett●June 10, 20082008-06-10
In article <g2n10q0ee4@news4.newsguy.com>, Chris Carlen says...
> Hi:
>
> Once again, I am writing a buffered, interrupt-driven driver for the
> serial comm UART (SCI) in the TI TMS320F2812. The lowest level
> interface to the user will be a function
>
> int SCI_getc(void);
>
> returns the next character received or EOF if nothing is available.
>
> However, if there is an error in the receiver, there appear to be two
> ways to inform the user space:
>
>
> 1. On the call to SCI_getc() after all valid chars have been removed
> from the buffer, return a special code other than EOF, such as a:
>
> #define SCI_RXERR -2 /* or something like that */
>
> Now if detailed info on the nature of the error were needed in this
> case, a call such as SCI_status() could provide this. In this case, the
> user mustn't always call SCI_status() after an EOF to find out if it was
> really no char available, or an error.
>
> Since serial reception fundamentally differs from file IO, I find this
> option attractive.
Note this also requires that your returned value be larger than a char,
a failing shared by the C character level input fuctions.
> 2. The second option is to return EOF always if there is no char
> available or there is an error, similar to fgetc(). Then the user would
> have to call another function SCI_status() or the like to get a code
> which can be parsed to determine the specific nature of the error.
>
> Since the SCIx_getc() call will frequently return EOF while waiting for
> data, it seems cumbersome to always have to call SCI_status() to see if
> it was due to an error.
>
>
> What is typically done?
Option 3. Ignore them except as needed to clear them from the hardware
(and maybe collect stats). Leaving error check up to higher level
protocols.
Option 3 is certainly common, I won't call it typical. There's often
little to be gained by error checking at the individual byte level.
Robert
** Posted from http://www.teranews.com **
Reply by Chris Carlen●June 10, 20082008-06-10
Hi:
Once again, I am writing a buffered, interrupt-driven driver for the
serial comm UART (SCI) in the TI TMS320F2812. The lowest level
interface to the user will be a function
int SCI_getc(void);
returns the next character received or EOF if nothing is available.
However, if there is an error in the receiver, there appear to be two
ways to inform the user space:
1. On the call to SCI_getc() after all valid chars have been removed
from the buffer, return a special code other than EOF, such as a:
#define SCI_RXERR -2 /* or something like that */
Now if detailed info on the nature of the error were needed in this
case, a call such as SCI_status() could provide this. In this case, the
user mustn't always call SCI_status() after an EOF to find out if it was
really no char available, or an error.
Since serial reception fundamentally differs from file IO, I find this
option attractive.
2. The second option is to return EOF always if there is no char
available or there is an error, similar to fgetc(). Then the user would
have to call another function SCI_status() or the like to get a code
which can be parsed to determine the specific nature of the error.
Since the SCIx_getc() call will frequently return EOF while waiting for
data, it seems cumbersome to always have to call SCI_status() to see if
it was due to an error.
What is typically done?
Thanks for input.
--
Good day!
____________________________________
CRC
crobcREMOVETHIS@BOGUSsbcglobal.net
NOTE, delete texts: "REMOVETHIS" and
"BOGUS" from email address to reply.