View previous topic :: View next topic |
Author |
Message |
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
Redirect STD IO to external fifo UART - Streams - How ? |
Posted: Tue Nov 20, 2007 8:24 pm |
|
|
My problem is with understanding how to implement a user defined Stream that intercepts stdin and stdout
calls , such that the whole family of std i/o serial related functions ( putc, getc, printf, kbhit etc ) are directed to MY routines for use with an external polled 16550 family UART -
i have plenty of experience with hardware coding for the 16c550 - thru the 16c1054 (my current favorite).
This is for an application using the ADS-8371 750KS 16 bit A/D - w parallel alternating byte access - 16f887 control on the E port - Data reception on the D port and D port shared with a LOT of 74HC574 aux expansion latches- and other stuff , and ideally real soon - the 16c1054 too. The UART has its own clock source.
the A port has address select lines for the 82c54, ADS8371 and 16c1054 ( think of it as a 16550 FIFO UART on steroids )
Even running at the full 20 mhz, the timing overhead of the internal rs232 UART in the 887 is a huge time sucker compared to how fast samples are available from the A/D - (i've been using 57.6kbaud after some jerking around - but thats another story) My zippy a/d is just grossly wasted as the characters dribble out by comparison-
the answer for me is an EXTERNAL hi performance UART with nice deep fifos and parallel transfer into it - with no wait states - and a simple check if new data can be dumped into the internal circular transmit fifo
( all the data volume is on the sending side w 4 hex chars per sample )
using the EXTERNAL UART at a steady 115K or 230Kbaud output - which is received and converted using a DIGI Edgport serial to USB adapter and then transferred to the PC host as a USB stream - via the windows com device API - stunningly fast ( parallel access to dump that data HAS to beat the pants off ANY baud rate on the internal UART)
I want to be sampling data instead of waiting of the on board UART
pinch out the bits.
Because the D port parallel bus is shared in common with latches,the A/D and an 82c54 ( as well as soon - the 16cxxxx uart) -AND other devices - that all have multiple byte access states possible, interrupts are totally not feasible. a deep fifo external UART that is polled - solves that nicely IF if can figure out how to cleanly make MY handlers for it - connect to std io functions
is there any guidance i can read on that ?
i looked at examples like modbus ( using the intrernal RS232 ) and the rs483 422 examples - but again - its the internal #use RS232 statement directed to an alternate stream modifier but mapped to the internal UART. I'm sorry to admit it - but those examples are so clouded by macro pre processor statements ( and UN commented in line with the code) that it is all as clear as mud to me.
if anyone can point me in the general direction that would let me get a grasp of how to redirect those STDIO streams - and the internal mechanisms for "#USE " of my virtual polled serial device for STD io -
// i would be forever ( or at least for
delay_ms(100000000) );
// grateful
IF this has been answered well before- please excuse my ignorance for not digging deep enough to find it. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Nov 20, 2007 11:50 pm |
|
|
The CCS printf() function has a feature that allows re-directing the
output to another function. The printf output is sent to the specified
function, one character at a time. For putc(), getc(), etc., you'll have
to write your own functions.
See the sample code in the link below. It shows how to write your own
serial i/o functions for a PIC and a version of the compiler in which the
built-in functions don't work. You'll have to do something similar to this,
except make it work with your external UART.
http://www.ccsinfo.com/forum/viewtopic.php?t=26631&start=7 |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
much clearer now |
Posted: Wed Nov 21, 2007 4:54 pm |
|
|
so if i am getting this right - the 'stream' is basically a reference to my replacement function for the actual I/O operation.
very helpful to get that concept from you T H A N K S.
of course the method described has a remaining, glaring performance weakness for REALLY hi thru put I/O in that it is character based.
You see - there is some small overhead in using the external UART in that
(without dedicating precious PIC pins to a HARDWARE FIFO status poll on the UART chip ) some register setup is still required to know if more characters can FIT before the transfer begins to the UART FIFO .
it adds up to about 30 instructs - just getting ready
but once done - transfers across the D bus of MULTIPLE chars can go VERY fast =- as in with fast IO it is 7 PIC instructs per byte moved to the UART
( mov data to D port - toggle Not_WRT on UART basically )
- by only getting single chars at a time from the print formatter - while it should still be be MUCH better than the using the internal UART rates -there are many more kind-of wasted cycles associated with the formatting beforehand - as each character still carries my handler overhead but only getting ONE byte moved at a time for the setup .
--------------------------------
the IDEAL formatter would pass a PTR to a string already done and ready to transmit - that would be an awesome solution - but is not in the cards right ? after scouring the V4 ref manual no printf variant that does anything caught my attention. ( BTW: i would pay EXTRA $$ for a well doen INDEX to that manual )
i have no problem sharing the finished code once i'm certain to have wrung out all the waste i can - so any ideas that would break thru that last item would be great to incorporate
do you think the port choices i have made are generically useful to others ? |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Nov 21, 2007 7:52 pm |
|
|
Just wondering...
If you want to transmit the data over USB, why use the serial UART as an intermediate? Directly sending the data to a parallel USB tranceiver like the FTDI FT245BL will reduce component count and increase throughput by at least a factor 6 (230kbit serial v.s. 1.5Mbit for slow USB 1.0 device).
In the PIC18 series there are processors with an inbuilt USB tranceiver reducing component count even more. Additional advantages of the PIC18 over the PIC16 are a more efficient instruction set, higher clock frequency (48MHz vs. 20MHz) and larger memory. The 16c1054 has a FIFO of 256 bytes, the PIC chips have 1k (configurable for Tx and Rx)... |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
why serial service at all? customer $$ call the shots - |
Posted: Wed Nov 21, 2007 9:22 pm |
|
|
if only it was so simple as me saying - we will use this interface and do it like so . but there are
serveral reasons for staying serial -
the gizmo in question is a very specialized data acq head end
product used in Bio /drug research and it comes
with a big legacy ball and chain - and mostly, computer non-savy user base to match
1- one legacy aspect is keeping compatibility with an older - slower sampling version of roughly the same product -- which has according to MY customer - always been well handled by serial services and an existing user base, some of whom still use old WinDoze versions of the application.
2 - i'm using both channels of a MAX 223 for TWO serial ports - ONE is a local monitor where the received data lines from RS-232 come out of the MAX 222 and are ANDED together for a data tap - monitor - before connecting to the UART RECV pins - and UART Transmit drive is paralleled to BOTH send sides of the 222.
this feature is easy to maintain with the Edgeport for Newer PCs with ONLY USB on board. The second serial port is a free standing data recorder that can grab and store the specific serial data format the gizmo makes
3- i'm not in control of the PC apps that this works with and the spec i am meeting is driven by the porting of my customer's $$$ to my bank account.
All this is more or less spec'd by a chief scientist who is (a) a Nobel prize winner in the field (b) 71 years old - still with the company and cranky as a bat at noon hour.
in the world of commerce - the one who writes the checks gets to tell the
one who bangs the bits how they want them served.
|
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
about the SPAM line above NOT MY TYPING!! |
Posted: Wed Nov 21, 2007 9:24 pm |
|
|
the cool BBS system translated the word i typed B-I-O / D-R-U-G into the word S-P-A-M
above - never saw anything so bizarre before on a board ??????????????? |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Nov 22, 2007 8:46 am |
|
|
Backwards compatibility says it all...
Be careful though, high speed RS232 can cause lots of problems especially with longer or bad quality cables. Not to mention the difficult timing problems we had using external RS232 to USB converters.
I'm sure you can make it work but the architecture you describe sounds sub-optimal. You are using one of the smaller PIC processors to which you have added an external timer module, port extenders and now an external UART. Isn't it possible to use a more advanced (PIC) processor with more timers, enhanced UART higher clock frequency and higher pin count so you could get rid of all those external components? It would simplify your design a lot and removes interfacing overhead.
For example the PIC18 has two hardware interrupt levels so you can separate the timing critical data acquisition from the rs232 transmission. |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
what can be done ? |
Posted: Thu Nov 22, 2007 9:25 am |
|
|
all clear and understood - but the external latches and timer are essential to a safety aspect of the system that has been carefully evaluated and approved by the customer - and i have the long standing rule of not breaking what is already working pretty well. and i only get paid ONCE for the project so digging up the foundation is not in the budget. |
|
|
SET
Joined: 15 Nov 2005 Posts: 161 Location: Glasgow, UK
|
|
Posted: Thu Nov 22, 2007 9:30 am |
|
|
Quote: | all clear and understood - but the external latches and timer are essential to a safety aspect of the system that has been carefully evaluated and approved by the customer - and i have the long standing rule of not breaking what is already working pretty well. and i only get paid ONCE for the project so digging up the foundation is not in the budget. |
Totally sympathise with your dilemma . We often get involved in projects, that all things being equal, could be done bettter if redesign was an option. Especially applies to medical, once a design is done it's very hard to move it by much. |
|
|
SET
Joined: 15 Nov 2005 Posts: 161 Location: Glasgow, UK
|
|
Posted: Thu Nov 22, 2007 9:38 am |
|
|
Quote: | You see - there is some small overhead in using the external UART in that
(without dedicating precious PIC pins to a HARDWARE FIFO status poll on the UART chip ) some register setup is still required to know if more characters can FIT before the transfer begins to the UART FIFO .
it adds up to about 30 instructs - just getting ready
but once done - transfers across the D bus of MULTIPLE chars can go VERY fast =- as in with fast IO it is 7 PIC instructs per byte moved to the UART
( mov data to D port - toggle Not_WRT on UART basically )
- by only getting single chars at a time from the print formatter - while it should still be be MUCH better than the using the internal UART rates -there are many more kind-of wasted cycles associated with the formatting beforehand - as each character still carries my handler overhead but only getting ONE byte moved at a time for the setup . |
Just thinking aloud here - the user routine passed to 'printf' could maintain an internal state, and buffer chars too (static variables), so could perhaps give you the best of both worlds? ('transparent' usage of printf, and the external UART performance) |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Nov 22, 2007 10:43 am |
|
|
SET wrote: | Just thinking aloud here - the user routine passed to 'printf' could maintain an internal state, and buffer chars too (static variables), so could perhaps give you the best of both worlds? ('transparent' usage of printf, and the external UART performance) | Continuing to think in the same line:
Maybe it is possible to add a special terminating character to the strings? The customized putc() function buffers all data until it detects the 'flush' character.
An alternative approach is to have the customized putc() function buffer the data until either one of the following occurs:
1) a defined number of characters is in the temporary buffer, let's say 10 characters.
or
2) a time out has passed since the last character was added to the internal temporary buffer, let's say 100ms. (requires a low priority interrupt).
This same algorithm is being used in several TCP/IP stacks but I can't remember the name for it. |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
excellent suggestion |
Posted: Thu Nov 22, 2007 11:05 am |
|
|
i think that using a reserved character is a superb suggestion and very do-able in my case. and of course there is a natural free one here too.
i feel so d-u-m for not thinking of it myself.
all i really have to do then is format the string handed to printf with a \r and wait for the carriage return to be handed to my_putc() in the stream before moving the whole thing to the fifo. not as perfect has having a printf that shares a buffer - or hands a ptr to the finished string - but as close as we are gonna come i think. excellent suggestion.
it is really humbling to find so many sharp people here. i spend too many frustrating ( but paid ) hours with my customer's two alleged V.B. programmers, who i personally wouldn't trust to code Hello World for me.
i admit i had some grave doubts after reading topics like "how do i declare a global variable" and so on - but the moderator and folks who have replied are terrificly clever and generous with smart suggestions. I am indebted to you all. and THANKS to all too. |
|
|
|