Possible BUG in ARM usart driver or crt routines

View: New views
14 Messages — Rating Filter:   Alert me  

Possible BUG in ARM usart driver or crt routines

by Ole Reinhardt-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi all,

I just discovered a strange bug, which I suppose to live anywhere in the
usart code. Eventually it's arm specific, perhaps also in the main usart
device driver code.

I'm using NutOS 4.6.0 with some extra bugfixes on an ethernut3 board.

In my special case I set the TX buffer size to a specific value. Let's
say 8. When I then try to send out a larger data buffer with fwrite I
recognise that packages of always 8 Bytes (same size as the usart tx
buffer size) are repeated...

Example:

I'll send the following buffer:

"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

What is send out:

"abcdefgabcdefg..."

So the first 8 bytes are repeated twice, next followed by some more or
less randomly new startpoint in the buffer.

My code looks like this:

[...]
_ioctl(_fileno(uart0), UART_SETTXBUFSIZ, &txbuf_port0);
[...]

int pos = 0;
u_char buffer[100] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789äöüÄÖÜß?!
\"§$%&/()={[]}\\,.-_<>|#'~+*'....";

do {
    pos += fwrite(&buffer[pos], 1, 100 - pos, uart0);
} while (pos < 100);

Has anybode noticed this behaviour too? Or have I missed any more recent
bugfixes?

Regards,

Ole Reinhardt


--
 _____________________________________________________________
|                                                             |
| Embedded-IT                                                 |
|                                                             |
| Ole Reinhardt        Tel. / Fax:        +49 (0)271  7420433 |
| Luisenstraße 29      Mobil:             +49 (0)177  7420433 |
| 57076 Siegen         eMail:    ole.reinhardt@... |
| Germany              Web:         http://www.embedded-it.de |
|_____________________________________________________________|

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: Possible BUG in ARM usart driver or crt routines

by Coleman Brumley-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I've not noticed this specific bug, but when I tried UART_SETTXBUFSIZE and
UART_SETRXBUFSIZE, I didn't get the expected results.

At the time, I just abandoned it because I didn't have the time to
investigate it.  

- Coleman

> -----Original Message-----
> From: en-nut-discussion-bounces@... [mailto:en-nut-discussion-
> bounces@...] On Behalf Of Ole Reinhardt
> Sent: Tuesday, September 01, 2009 11:26 AM
> To: Ethernut User Chat (English)
> Subject: [En-Nut-Discussion] Possible BUG in ARM usart driver or crt
> routines
>
> Hi all,
>
> I just discovered a strange bug, which I suppose to live anywhere in
> the
> usart code. Eventually it's arm specific, perhaps also in the main
> usart
> device driver code.
>
> I'm using NutOS 4.6.0 with some extra bugfixes on an ethernut3 board.
>
> In my special case I set the TX buffer size to a specific value. Let's
> say 8. When I then try to send out a larger data buffer with fwrite I
> recognise that packages of always 8 Bytes (same size as the usart tx
> buffer size) are repeated...
>
> Example:
>
> I'll send the following buffer:
>
> "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
>
> What is send out:
>
> "abcdefgabcdefg..."
>
> So the first 8 bytes are repeated twice, next followed by some more or
> less randomly new startpoint in the buffer.
>
> My code looks like this:
>
> [...]
> _ioctl(_fileno(uart0), UART_SETTXBUFSIZ, &txbuf_port0);
> [...]
>
> int pos = 0;
> u_char buffer[100] =
> "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789äöüÄÖÜß?
> !
> \"§$%&/()={[]}\\,.-_<>|#'~+*'....";
>
> do {
>     pos += fwrite(&buffer[pos], 1, 100 - pos, uart0);
> } while (pos < 100);
>
> Has anybode noticed this behaviour too? Or have I missed any more
> recent
> bugfixes?
>
> Regards,
>
> Ole Reinhardt
>
>
> --
>  _____________________________________________________________
> |                                                             |
> | Embedded-IT                                                 |
> |                                                             |
> | Ole Reinhardt        Tel. / Fax:        +49 (0)271  7420433 |
> | Luisenstraße 29      Mobil:             +49 (0)177  7420433 |
> | 57076 Siegen         eMail:    ole.reinhardt@... |
> | Germany              Web:         http://www.embedded-it.de |
> |_____________________________________________________________|
>
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: Possible BUG in ARM usart driver or crt routines

by Thiago A. Corrêa :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

On Tue, Sep 1, 2009 at 12:25 PM, Ole
Reinhardt<ole.reinhardt@...> wrote:

>
> Has anybode noticed this behaviour too? Or have I missed any more recent
> bugfixes?
>

   I'm using the atmega128 for production currently, with the UC3 I
didn't have the time yet to do this kind of testings. But since it's
based on the arm code, it probably has the same bug.

   With the atmega128 the default buffer size seems fine, but I don't
think I ever filled it completely.

Kind Regards,
   Thiago A. Correa
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: Possible BUG in ARM usart driver or crt routines

by Ole Reinhardt-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi!

>    With the atmega128 the default buffer size seems fine, but I don't
> think I ever filled it completely.

With the default buffer size it seems to work quite well, but now I need
to send out data without any buffer.

Detailed problem:

I need to wait for at least 50ms after sending the buffer before sending
more data. If I have a large buffer I can not say how much data is still
in the buffer, so a nutsleep directly after fwrite() I don't know the
exactly when the last byte was send out (by interrupt driven UART).

Bye,

Ole

--
 _____________________________________________________________
|                                                             |
| Embedded-IT                                                 |
|                                                             |
| Ole Reinhardt        Tel. / Fax:        +49 (0)271  7420433 |
| Luisenstraße 29      Mobil:             +49 (0)177  7420433 |
| 57076 Siegen         eMail:    ole.reinhardt@... |
| Germany              Web:         http://www.embedded-it.de |
|_____________________________________________________________|

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: Possible BUG in ARM usart driver or crt routines

by Ethernut :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Ole,

Ole Reinhardt wrote:
> In my special case I set the TX buffer size to a specific value. Let's
> say 8. When I then try to send out a larger data buffer with fwrite I
> recognise that packages of always 8 Bytes (same size as the usart tx
> buffer size) are repeated...

Just tried that on Ethernut 3. Not exactly the behaviour you described,
but definitely broken. I'll look into it.

Harald
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: Possible BUG in ARM usart driver or crt routines

by Ole Reinhardt-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Harald,

> Just tried that on Ethernut 3. Not exactly the behaviour you described,
> but definitely broken. I'll look into it.

Thanks!

Ole

--
 _____________________________________________________________
|                                                             |
| Embedded-IT                                                 |
|                                                             |
| Ole Reinhardt        Tel. / Fax:        +49 (0)271  7420433 |
| Luisenstraße 29      Mobil:             +49 (0)177  7420433 |
| 57076 Siegen         eMail:    ole.reinhardt@... |
| Germany              Web:         http://www.embedded-it.de |
|_____________________________________________________________|

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: Possible BUG in ARM usart driver or crt routines

by Ethernut :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Ole,

Ole Reinhardt wrote:
> Hi Harald,
>
>> Just tried that on Ethernut 3. Not exactly the behaviour you described,
>> but definitely broken. I'll look into it.
>
> Thanks!

Not completely solved, but I found the reason.

Setting a different buffer size will not automatically adjust the low
and high watermarks. Using

    parm = 8;
    _ioctl(_fileno(uart1), UART_SETTXBUFSIZ, &parm);
    parm = 2;
    _ioctl(_fileno(uart1), UART_SETTXBUFLWMARK, &parm);
    parm = 6;
    _ioctl(_fileno(uart1), UART_SETTXBUFHWMARK, &parm);

should fix your current problem.

Harald
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: Possible BUG in ARM usart driver or crt routines

by Ethernut :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Ole Reinhardt wrote:

> I need to wait for at least 50ms after sending the buffer before sending
> more data. If I have a large buffer I can not say how much data is still
> in the buffer, so a nutsleep directly after fwrite() I don't know the
> exactly when the last byte was send out (by interrupt driven UART).

Polling the status for each 50ms may help. I've prepared a wiki page to
explain some advanced UART functions:

http://www.ethernut.de/nutwiki/Advanced_UART_Functions


Harald
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: Possible BUG in ARM usart driver or crt routines

by Coleman Brumley-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Harald,

There are some issues with the AT91 USART error handling in that he error
flag doesn't get cleared correctly.  

I documented this, and a potential fix some time ago at
http://coleman.jandasoft.biz/?p=8


- Coleman


> -----Original Message-----
> From: en-nut-discussion-bounces@... [mailto:en-nut-discussion-
> bounces@...] On Behalf Of Harald Kipp
> Sent: Wednesday, September 02, 2009 2:27 PM
> To: Ethernut User Chat (English)
> Subject: Re: [En-Nut-Discussion] Possible BUG in ARM usart driver or
> crt routines
>
> Ole Reinhardt wrote:
>
> > I need to wait for at least 50ms after sending the buffer before
> sending
> > more data. If I have a large buffer I can not say how much data is
> still
> > in the buffer, so a nutsleep directly after fwrite() I don't know the
> > exactly when the last byte was send out (by interrupt driven UART).
>
> Polling the status for each 50ms may help. I've prepared a wiki page to
> explain some advanced UART functions:
>
> http://www.ethernut.de/nutwiki/Advanced_UART_Functions
>
>
> Harald
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: Possible BUG in ARM usart driver or crt routines

by Bernd Walter-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, Sep 01, 2009 at 06:58:58PM +0200, Ole Reinhardt wrote:

> Hi!
>
> >    With the atmega128 the default buffer size seems fine, but I don't
> > think I ever filled it completely.
>
> With the default buffer size it seems to work quite well, but now I need
> to send out data without any buffer.
>
> Detailed problem:
>
> I need to wait for at least 50ms after sending the buffer before sending
> more data. If I have a large buffer I can not say how much data is still
> in the buffer, so a nutsleep directly after fwrite() I don't know the
> exactly when the last byte was send out (by interrupt driven UART).

I needed something similar, but used direct hardware access on SAM7X256.
Setup DMA to send the data block and interrupt on txdone.
Interrupt routine sets rx-idle interrupt - you also could use a general
purpose timer for that case.
I use it for Modbus/RTU, which also uses rx-idle support for RX,
which is very fine, because I setup RX DMA with max packet size and get
an interrupt once the packet is available.
The interrupt sets an event for the worker thread ans resisssues a
new timer for TX, because there is a defined safety gap to enshure
that everyone sees the packet end.
The rx idle are differently setup, because the packet end rx-idle
is triggered by the first received character and the tx safety
directly starts counting.
SAM7's USART timeout features are quite nice.

--
B.Walter <bernd@...> http://www.bwct.de
Modbus/TCP Ethernet I/O Baugruppen, ARM basierte FreeBSD Rechner uvm.
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: Possible BUG in ARM usart driver or crt routines

by samkelo tyatyantsi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Hi Harald,
 
>  I've prepared a wiki page to explain some advanced UART functions:
 > http://www.ethernut.de/nutwiki/Advanced_UART_Functions
 

Thanks for the explanation on the nutwiki page, I did have an
experience slightly similar to that of Ole, but I finally found a way
around it.  



kind regards.
 Samkelo.

_________________________________________________________________
More than messages–check out the rest of the Windows Live™.
http://www.microsoft.com/windows/windowslive/
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: Possible BUG in ARM usart driver or crt routines

by Ethernut :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Coleman Brumley wrote:

> There are some issues with the AT91 USART error handling in that he error
> flag doesn't get cleared correctly.  
>
> I documented this, and a potential fix some time ago at
> http://coleman.jandasoft.biz/?p=8

Many thanks, Coleman.

Indeed the flags never get cleared, neither in the hardware register nor
in the global shadow variable.

As the AT91 channel status register keeps the errors until explicitly
cleared by RSTSTA, we may be able to remove the register read from the
interrupt routine to decrease the system's interrupt latency. We simply
need to keep track of the ring buffer overflow.

My first attempt was to remove the shadow variable and skip reading the
character from the receiver holding register, if the ring buffer is
full. The next incoming character would automatically set the OVRE flag
in the channel status register. Unfortunately this conflicts with
XON/XOFF handshake. Thus, we still need the global variable to flag
buffer overruns. :-(

Harald

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: Possible BUG in ARM usart driver or crt routines

by Coleman Brumley-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Harald,

> Many thanks, Coleman.

My pleasure.

I took the "16 pound sledge" approach of ignoring the errors because I had
to implement a protocol at the USART level.  

Unfortunately, I think I'm getting burned by this because it's now being
reported that the device is missing RS485 data which is likely due to buffer
overruns.  I don't have a moment to investigate this thoroughly, but hope to
get to it in the future.  

- Coleman


> -----Original Message-----
> From: en-nut-discussion-bounces@... [mailto:en-nut-discussion-
> bounces@...] On Behalf Of Harald Kipp
> Sent: Friday, September 04, 2009 5:11 AM
> To: Ethernut User Chat (English)
> Subject: Re: [En-Nut-Discussion] Possible BUG in ARM usart driver or
> crt routines
>
> Coleman Brumley wrote:
>
> > There are some issues with the AT91 USART error handling in that he
> error
> > flag doesn't get cleared correctly.
> >
> > I documented this, and a potential fix some time ago at
> > http://coleman.jandasoft.biz/?p=8
>
> Many thanks, Coleman.
>
> Indeed the flags never get cleared, neither in the hardware register
> nor
> in the global shadow variable.
>
> As the AT91 channel status register keeps the errors until explicitly
> cleared by RSTSTA, we may be able to remove the register read from the
> interrupt routine to decrease the system's interrupt latency. We simply
> need to keep track of the ring buffer overflow.
>
> My first attempt was to remove the shadow variable and skip reading the
> character from the receiver holding register, if the ring buffer is
> full. The next incoming character would automatically set the OVRE flag
> in the channel status register. Unfortunately this conflicts with
> XON/XOFF handshake. Thus, we still need the global variable to flag
> buffer overruns. :-(
>
> Harald
>
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: Possible BUG in ARM usart driver or crt routines

by Coleman Brumley-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> -----Original Message-----
> From: en-nut-discussion-bounces@... [mailto:en-nut-discussion-
> bounces@...] On Behalf Of Harald Kipp
> Sent: Friday, September 04, 2009 5:11 AM
> To: Ethernut User Chat (English)
> Subject: Re: [En-Nut-Discussion] Possible BUG in ARM usart driver or
> crt routines
>
> Coleman Brumley wrote:
>
> > There are some issues with the AT91 USART error handling in that he
> error
> > flag doesn't get cleared correctly.
> >
> > I documented this, and a potential fix some time ago at
> > http://coleman.jandasoft.biz/?p=8
>
> Many thanks, Coleman.
>
> Indeed the flags never get cleared, neither in the hardware register
> nor
> in the global shadow variable.
>
> As the AT91 channel status register keeps the errors until explicitly
> cleared by RSTSTA, we may be able to remove the register read from the
> interrupt routine to decrease the system's interrupt latency. We simply
> need to keep track of the ring buffer overflow.
>
> My first attempt was to remove the shadow variable and skip reading the
> character from the receiver holding register, if the ring buffer is
> full. The next incoming character would automatically set the OVRE flag
> in the channel status register. Unfortunately this conflicts with
> XON/XOFF handshake. Thus, we still need the global variable to flag
> buffer overruns. :-(

In my investigation of this, I noticed that it seems that the OVRE flag in
the channel status register is always set, especially when dealing with a
lot of RS485 traffic at higher (38.4 and 76.8) baudrates.  

For what it's worth, the Linux AT91 serial driver ignores the channel status
register entirely by reading it and clearing it by RSTSTA.  So, the channel
status register is never propagated to the "upper layers".  

Coleman


_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion