[#5063] serial uart bfin_5xx.c stops receiving when RX buf wraps (patch included)

Document created by Aaronwu Employee on Sep 3, 2013
Version 1Show Document
  • View in full screen mode

[#5063] serial uart bfin_5xx.c stops receiving when RX buf wraps (patch included)

Submitted By: Tomasz Motylewski

Open Date

2009-04-09 04:26:14     Close Date

2010-06-11 04:43:21

Priority:

Medium High     Assignee:

Sonic Zhang

Status:

Closed     Fixed In Release:

N/A

Found In Release:

2008R1.5-RC3     Release:

head, branch-2008R1

Category:

Drivers     Board:

STAMP

Processor:

ALL     Silicon Revision:

0.2

Is this bug repeatable?:

Yes     Resolution:

Fixed

Uboot version or rev.:

    Toolchain version or rev.:

08r1.5-14 gcc 4.1.2

App binary format:

N/A     

Summary: serial uart bfin_5xx.c stops receiving when RX buf wraps (patch included)

Details:

 

The patch   blackfin.uclinux.org/git/?p=readonly-mirrors/linux-kernel.git;a=commitdiff;h=03869d610feefa6f531c24dc1e4c076d31151f25 fixes bugs [#4455] and [#4436] but a new bug appears:

 

when receiving small packets of characters sometimes data is not read until next character comes. This happens when the most recent character is exactly at the beginning of the RX buffer. In my case this stops the whole communication - application does not respond, so client does not send anymore till timeout.

 

What follows is the output of /sys/kernel/debug/blackfin/DMA Controller/DMA8_ ...

 

CURR_ADDR    CURR_X_COUNT    CURR_Y_COUNT

 

0x03f00200   0x0000          0x0000        system start, no chars received

0x03f00001   0x01ff          0x0008        1 character received

0x03f00202   0x01fe          0x0008        next character

0x03f001ff   0x0001          0x0008        next 509 chars

0x03f00200   0x0200          0x0007        next char

0x03f003ff   0x0001          0x0007        next 511 chars

0x03f00400   0x0200          0x0006        next char

0x03f00c00   0x0200          0x0002        next 2048 chars

0x03f00e00   0x0200          0x0001        next 512 chars

0x03f00e01   0x01ff          0x0001        next char

0x03f00fff   0x0001          0x0001        next 510 chars

0x03f01000   0x0000          0x0001        next char SUPRISE, SUPRISE, driver will not receive, expected 0x0200  0x0008

0x03f00001   0x01ff          0x0008        next char, back to normal

 

This behaviour is documented in BF537_HRM_whole_book_3.0.pdf page 5-15 and others.

To get above data I have enabled debugfs and set 115200 baud. I have sent data from by PC by:

dd if=big-file.txt of=/dev/ttyUSB0 bs=1 count=1 (here comes count in decimal)

I guess DMA8 is just my setup, you will have to find out which is used on your blackfin CPU.

 

My guess is that cause of [#4455] and [#4436] was not only race condition but also "0x03f01000 0x0000  0x0001" condition which is 100% reproducible when sending characters 1 by 1.

 

I have fixed and tested it using CURR_X, CURR_Y (see attached patch).

But I would like to suggest considering

 

if(CURR_Y_COUNT == 0)

    return; // ... skip processing, no bytes till now

USE (CURR_ADDR-buffer_start)%buffer_size and delete whole CURR_*_COUNT insanity.

 

Best regards

 

Tomasz Motylewski

 

Wolf & Woelfel GmbH

  www.wolf-woelfel.de/

 

 

 

Follow-ups

 

--- Tomasz Motylewski                                        2009-04-09 06:15:31

I would like to use this opportunity to request shortening poll time in the

driver. Current 20 ms latency is too long. See attached bfin_5xx.c-lowlat.diff

I have tested 2 patches I have attached together.

 

All was tested in 2008R1.5-RC3 with bfin_5xx.c (2008R1 + patch) and

linux-2.6.x/include/asm-blackfin/mach-bf*/bfin_serial_5xx.h copied from 2008R1

head. I am also attaching the whole patched bfin_5xx.c as is.

 

Release 0.3 BF537 works the same way.

 

--- Mike Frysinger                                           2009-04-09 06:37:01

doesnt the timeout occur only in the error case ?  if that's true, you dont want

the timeout function firing when it shouldnt be and so it should stay at 50ms.

 

--- Tomasz Motylewski                                        2009-04-09 11:47:29

My understanding is that DMA interrupt only occurs when switching DMA

"lines". You may do test I have describen above checking

/proc/interrupts.

 

After receiving over 4 KB (often single characters) I have:

 

# cat /proc/interrupts

  6:   24524759   BFIN Timer Tick

18:          8   BFIN_UART_RX

19:        291   BFIN_UART_TX

24:       3135   EMAC_RX

Err:          0

 

That means without "timeout" IRQ happens only every 512 bytes. Good

for throuput but not latency. Even at 115200 baud full load IRQs will only

happen about every 44 ms, while other function polls every 20 ms.

 

P.S. And please consider removing uart->rx_dma_nrows

 

--- Tomasz Motylewski                                        2009-04-09 11:57:26

clarification: in case "0x03f01000 0x0000  0x0001" the characters in

the buffer are NEVER received. "timeout" function simply ignores them

every time it is called. Only when (and if) next character comes, driver copies

the waiting + fresh character.

 

--- Sonic Zhang                                              2009-04-23 05:47:31

As Tomasz Motylewski mentioned, this bug is caused by irregular behavior of DMA

register CURR_X_COUNT and CURR_Y_COUNT when an auto restart uart rx DMA run to

last byte in DMA buffer, trigger the interrupt and stay at this possiton. The

status of current x and y is 0:7 instead of 512:8 or 0:8. The driver doesn't

take care of this case when calculating the position.

 

Fixed.

 

In addition, the poll interval is set based on normal keyboard input response

time. If you think it is too slow, you need to give a reasonable explanation.

 

 

--- Robin Getz                                               2009-04-23 09:48:02

Can you better define what you mean by "irregular behavior":

- not expected, but described properly in the HRM

- not expected, and not documented in the HRM

 

From what I can tell - this is the expected behavior per the HRM, and should

not be described as irregular.

 

-Robin

 

--- Sonic Zhang                                              2009-04-23 23:07:58

Yes, it is described in the DMA part of the HRM. Irregular here means the x and

y status at the last line is different from that of lines in the middle of a 2D

dma.

 

 

 

    Files

    Changes

    Commits

    Dependencies

    Duplicates

    Associations

    Tags

 

File Name     File Type     File Size     Posted By

bfin_5xx.c-dmafix.diff    text/plain    4721    Tomasz Motylewski

bfin_5xx.c    text/x-csrc    34897    Tomasz Motylewski

bfin_5xx.c-lowlat.diff    text/plain    712    Tomasz Motylewski

Outcomes