EmbeddedRelated.com
Forums

Linux serial port dropping bytes

Started by Derek Young March 31, 2008
Didi wrote:
> > > This means you have 1.388 mS to fill the FIFO - plenty of time to > > > process it. > ... > CBFalconer wrote: > > ... > > Oh? The unit fills up, with 1500 bytes, and interrupts. Bytes can > > be coming in at one per microsec (roughly) until you get at least > > some out. > > Oops, sorry, I have taken the 1500 for FIFO depth, not the 128, hence > the wrong result.
Replying hastily while being tired has such an effect. Of course my initial calculation had been correct, after all these years doing that stuff I do these things subconsciously. Thus 128/(921600/10)=0.0013888..., or 1388.9 mS. Meaning he has 1 mS for around 100 bytes. If linux would prevent him from doing _that_, well, he'll be looking for an OS which works. Now I am even more tired - just going to bed - but I hope I put 1 and 1 together correctly this time. And yes, they always specify serial speeds in bits per second, I have never seen them specified in bytes per second last 20+ years. The speed 921.6 kbpS suggests he may be using an NSC Bluetooth module, they top at that speed, but this is only a speculation of an almost asleep guy. Dimiter ------------------------------------------------------ Dimiter Popoff Transgalactic Instruments http://www.tgi-sci.com ------------------------------------------------------ http://www.flickr.com/photos/didi_tgi/sets/72157600228621276/ Didi wrote:
> CBFalconer wrote: > > >> I'm trying to receive bytes over the built-in RS-422 serial port > > >> at 921.6 kbps. The received packets are 1500 bytes long. The > > >> UART is a 16C2850 (dual port version of the 16C850 with 128 byte > > >> FIFO). > > > > > > This means you have 1.388 mS to fill the FIFO - plenty of time to > > > process it. > > > > Oh? The unit fills up, with 1500 bytes, and interrupts. Bytes can > > be coming in at one per microsec (roughly) until you get at least > > some out. > > Oops, sorry, I have taken the 1500 for FIFO depth, not the 128, hence > the wrong result. > This means he will have (1388/1500)*128 uS to fill the FIFO, or about > 118 uS. > Still plenty of time to empty a FIFO into memory on most if not all > todays > CPUs which would have a 128 byte deep FIFO on the UART. > But latency is bound to creep in as an issue in this context given > that under > linux other IRQ handlers will not unmask early (I am relying on Grants > word for > that), so there is probably no working linux option - which is I > believe what > you suggested initially. > > Dimiter > > ------------------------------------------------------ > Dimiter Popoff Transgalactic Instruments > > http://www.tgi-sci.com > ------------------------------------------------------ > http://www.flickr.com/photos/didi_tgi/sets/72157600228621276/ > > > > > CBFalconer wrote: > > Didi wrote: > > > Derek Young wrote: > > >>... > > >> I'm trying to receive bytes over the built-in RS-422 serial port > > >> at 921.6 kbps. The received packets are 1500 bytes long. The > > >> UART is a 16C2850 (dual port version of the 16C850 with 128 byte > > >> FIFO). > > > > > > This means you have 1.388 mS to fill the FIFO - plenty of time to > > > process it. > > > > Oh? The unit fills up, with 1500 bytes, and interrupts. Bytes can > > be coming in at one per microsec (roughly) until you get at least > > some out. That doesn't happen until the interrupt is serviced, and > > control is transferred to the unloading code, after doing all the > > checks (for error, etc.) So that must have all happened in about > > one microsec, to avoid rejecting further input. Now the discharge > > loop has to remove items in less that 1 microsec per byte, just to > > keep up with the input line. I have doubts that you can even talk > > to the UART that fast. > > > > -- > > [mail]: Chuck F (cbfalconer at maineline dot net) > > [page]: <http://cbfalconer.home.att.net> > > Try the download section. > > > > > > > > -- > > Posted via a free Usenet account from http://www.teranews.com
Grant Edwards wrote:
> CBFalconer <cbfalconer@yahoo.com> wrote: >> Grant Edwards wrote: >>> CBFalconer <cbfalconer@yahoo.com> wrote: >>>> Derek Young wrote: >>>>> >>>>> I'm using an Arcom Viper PXA255 single board computer running >>>>> Linux, and I'm trying to receive bytes over the built-in RS-422 >>>>> serial port at 921.6 kbps. The received packets are 1500 bytes >>>>> long. The UART is a 16C2850 (dual port version of the 16C850 >>>>> with 128 byte FIFO). >>>>> >>>>> Everything works fine at low speeds, but if the packet rate >>>>> increases, I start to lose bytes. >>>> >>>> Your numbers indicate that you would need an interrupt roughly >>>> every 1 microsec. Not a chance. >>> >>> Huh? >>> >>> If he sets the FIFO threshold to 64, then the interrupt >>> frequency is 921600.0/10/64 == 1440Hz. >>> >>> If he sets it FIFO threshold to 96, then the interrupt >>> frequency is 921600.0/10/96 == 960Hz. 960Hz should be no >>> problem at all unless some of the other ISRs are running too >>> long. >> >> I know of UARTs that can hold 64, or even 128, results. I gather >> that that one has a 128 byte storage. Okay, now consider how long >> it takes to empty that buffer, when full. That has to be done at >> least every 921600/128 (I don't know where you got /10/96) > > You divide by 10 bits/byte to convert from bits/sec to > bytes/sec. Then you divide by the interrupt threshold to > convert from bytes/sec to interrupts/sec. > >> or roughly 10 khz, for about 100 uS between interrupts. > > It's 921600 _bits_ per second (including start and stop). > That's 92160 bytes per second. If he configures the FIFO > threshold to be 96, then the _fastest_ he'll get interrupts is > one interrupt every 96 bytes. That means 92160/96 interrupts > per second. > >> Now you don't know how many items are stored, so that implies >> a one by one discharge loop. Nobody has mentioned the CPU >> speed, but I still have grave doubts. Don't forget that >> during the discharge the FIFO is still filling up, at roughly >> 1 item per microsec. > > You seem to be confusing bits and bytes. > >> I would guess you are assuming the speed mentioned is a bit >> speed, > > It is. > >> not a per byte port speed, and the '10' is the length of the >> character, in bits. Nobody computes serial port speeds that >> way. > > Yes they do. They always do.
I left the whole thing unsnipped. The time has come for me to crave forgiveness. I think I have been afflicted with age or something. The bits/persec crowd are absolutely correct, and I am wrong. So that leaves the real problem handling throughput of approximately 1 char each 10 microsec. -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section. -- Posted via a free Usenet account from http://www.teranews.com
CBFalconer <cbfalconer@yahoo.com> writes:

> Robert Adsett wrote: >> CBFalconer says... >> >>> I would guess you are assuming the speed mentioned is a bit speed, >>> not a per byte port speed, and the '10' is the length of the >>> character, in bits. Nobody computes serial port speeds that way. >> >> I don't remember ever seeing serial port speed specified as other >> than bits/sec. And geven a lack of other information 10 seems >> like a reasonable place to start for a character with start and >> stop bits included. > > Well, I habitually set my serial ports to 300, 600, 2400, 9600, > 56000 etc., all measured in bytes per second.
Sounds like you have been doing it wrong for 40 years :) Seriously, it's always bits per second. At *has* to be, since there is a variable amount of overhead depending on parity on/off, number of stop bits etc, optional address flags etc. Do you think the bit rate magically adjusts itself so as to always maintain 9600 *bytes* per second? -- John Devereux
CBFalconer wrote:
> Robert Adsett wrote: >> CBFalconer says... >> >>> I would guess you are assuming the speed mentioned is a bit speed, >>> not a per byte port speed, and the '10' is the length of the >>> character, in bits. Nobody computes serial port speeds that way. >> I don't remember ever seeing serial port speed specified as other >> than bits/sec. And geven a lack of other information 10 seems >> like a reasonable place to start for a character with start and >> stop bits included. > > Well, I habitually set my serial ports to 300, 600, 2400, 9600, > 56000 etc., all measured in bytes per second. >
The phrase "when you're in a hole, stop digging" springs to mind. You got this one wrong. Communication rates are normally specified as the "bit rate", although people often call it "baud rate" for UARTs. For UART signalling, the "bit rate" and the "baud rate" are the same, although some physical links (such as a modem link) will have different baud rates and bit rates (the "baud rate" is the "symbols" per second, so if each "symbol" codes several bits, the bit rate is higher than the baud rate). UART, CAN, USB, Ethernet, Firewire, WLAN - almost all serial protocols I can think of are specified in bits per second.
John Devereux wrote:

>> Well, I habitually set my serial ports to 300, 600, 2400, 9600, >> 56000 etc., all measured in bytes per second. > > Sounds like you have been doing it wrong for 40 years :)
I wonder how he communicated with anything... let's see, 9600 bytes/sec, 8N1... that's 96000 Baud (well, bits/sec anyway...) - a 20% mismatch with 115200 Baud (well....)
CBFalconer wrote:
<snip>
> I left the whole thing unsnipped. The time has come for me to > crave forgiveness. I think I have been afflicted with age or > something. The bits/persec crowd are absolutely correct, and I am > wrong. >
I don't think you need forgiveness - you just made a mistake.
> So that leaves the real problem handling throughput of > approximately 1 char each 10 microsec. >
You need to handle an *average* of 1 character per 10 us. But the cost of handling each character is peanuts - even if the UART is on a slow bus, you should be able to read out characters at something like 20 per us. The cost is in the handling of the interrupt itself - context switches, cache misses, etc. That's why you use a UART with a buffer - it takes virtually the same time to read 128 bytes out the buffer during one interrupt, as to read 1 byte from the buffer during the interrupt. So if you've set your UART to give an interrupt every 100 characters, you get an interrupt every ms and read out a block of 100 characters at a time.
sprocket <jas@spam.cop.uk> writes:

> John Devereux wrote: > >>> Well, I habitually set my serial ports to 300, 600, 2400, 9600, >>> 56000 etc., all measured in bytes per second. >> >> Sounds like you have been doing it wrong for 40 years :) > > I wonder how he communicated with anything... let's see, 9600 > bytes/sec, 8N1... that's 96000 Baud (well, bits/sec anyway...) - a 20% > mismatch with 115200 Baud (well....)
Not a problem when you write both ends... :) -- John Devereux
Derek Young escribi&#4294967295;:
> >> Changing ISR priority isn't going to make any difference. >> It only determines which of two pending interrupts get >> serviced. It doesn't allow "higher" priority interrupts to >> preempt lower priority ones. If a low-priority ISR runs for a >> long time, it's still going to block high-priority ISRs for the >> whole time it's running. >> > > Darn. I thought a high-priority ISR would preempt all lower priority > ones. Thanks for the heads-up.
No, that's typical of RTOS (like VxWorks), and only if the BSP (or equivalent) is correctly implemented.
On 2008-04-02, CBFalconer <cbfalconer@yahoo.com> wrote:
> Robert Adsett wrote: >> CBFalconer says... >> >>> I would guess you are assuming the speed mentioned is a bit speed, >>> not a per byte port speed, and the '10' is the length of the >>> character, in bits. Nobody computes serial port speeds that way. >> >> I don't remember ever seeing serial port speed specified as other >> than bits/sec. And geven a lack of other information 10 seems >> like a reasonable place to start for a character with start and >> stop bits included. > > Well, I habitually set my serial ports to 300, 600, 2400, 9600, > 56000 etc., all measured in bytes per second.
Those numbers are bits per second. -- Grant Edwards grante Yow! MERYL STREEP is my at obstetrician! visi.com
On 2008-04-02, CBFalconer <cbfalconer@yahoo.com> wrote:

> I left the whole thing unsnipped. The time has come for me to > crave forgiveness.
No worries. :)
> So that leaves the real problem handling throughput of > approximately 1 char each 10 microsec.
That's where a large FIFO becomes important. Using Linux on an XScale (which, IIRC, is is what the OP is using), I've done up to 460K baud without problems. But, that was using a UART with a 1K byte rx FIFO. That UART also allowed 32-bit wide accesses to the tx/rx FIFOs so that you could transfer 4 bytes per bus cycle. With a 128 byte FIFO and byte-wide access, the timing constraints are quite a bit tighter, but I think it should be doable if you carefully vet the other drivers that are running on the system. -- Grant Edwards grante Yow! PARDON me, am I at speaking ENGLISH? visi.com