[Armadillo:04704] [a500fx][ttymxc] 送っていない 0xff を連続受信するモードに陥る

URATAN Shigenobu email@hidden
2009年 10月 27日 (火) 17:01:17 JST


うらたんと申すものです。

以下の環境で、Armadillo-500 FX、Armadillo-500 のあたりをとっております。

  ・Armadillo-500 FX 液晶モデル開発セット
  ・Armadillo-500 + 開発ボード
  ・atmark-dist-20090318.tar.gz
  ・linux-2.6.26-at6.tar.gz
  ・atde2-20090403.zip


さて UART を使うプログラムを作成して動作を確認していたところ、
以下のような挙動に遭遇してしまいました。
取り急ぎ ご報告いたします。


 - * - * -


症状

    9600bps に設定された ttymxc4 に、115200bps の SPACE, '@', '`' などを
    送信すると、(何も送信していないのに) 0xff を連続受信し続けるモードに
    なることが たいへんよくある。


構成

        a500fx
     +-----------+          +----------+
     |   ttymxc0 | console  | TeraTerm |
     |    115200 |<-------->|  115200  |(マザーボードの COM ポート)
     |           |          +----------+
     |           |          +----------+
     |   ttymxc4 |    '@'   | TeraTerm |
     |     9600  |<---------|  115200  |(USB-Serail 変換 USB-RSAQ3 を使用)
     +-----------+          +----------+


再現手順 [1]

    (1) uart の受信状況が見える debug-kernel を用意する (patch は末尾に)
    (2) debug-kernel と標準の userland で起動
    (3) console より root で login
    (4) /etc/inittab を編集し、ttymxc4 を 9600bps に変更
    (5) killall getty; init -q して ttymxc4 を 9600bps に再設定
    (6) 9600bps にて 通常通り通信できることを確認
    (7) ttymxc4 に向け 115200bps にて SPACE, '@', '`' などを送信する…


再現手順 [2]  (a500で行ったので ttymxc1 だ)

    (1) (ほぼ) atmark-dist 標準環境で起動
    (2) /etc/inittab を編集し、ttymxc1 を 9600bps に変更
    (3) killall getty; init -q して ttymxc1 を 9600bps に再設定
    (4) 9600bps にて 通常通り通信できることを確認
    (5) /etc/inittab を編集し、ttymxc1 を コメントアウト
    (6) killall getty; init -q して ttymxc1 をフリーに
    (7) cat /dev/ttymxc1 | od -hv
    (8) 9600bps で 16文字送るごとにダンプされることを確認
    (9) ttymxc1 に向け 115200bps にて SPACE, '@', '`' などを送信する…


暴走状態のログ

    上記 再現手順 [1] において ttymxc0(115200bps) より採取したログを
    以下に示します。行ったアクションほかを、ログ中に補足してあります。

    アクションとログ
    +---------------------------------------------------
    |a500fx#
    |a500fx# sr2:0x4229 status:0x810d  <--- 9600bps で [RETURN] 送信 ... 正常
    |sr2:0x4229 status:0x810d         <--- 同上 ... 正常
    |sr2:0x4229 status:0x81ff   <--- 115200bps で SPACE 送信→
    |sr2:0x4229 status:0x81ff           →0xff を連続受信し始める
    |sr2:0x4229 status:0x81ff             (ログがだーっと流れ始めます)
    |sr2:0x4229 status:0x81ff
    |sr2:0x4229 status:0x81ff
    |sr2:0x4229 status:0x81ff
    |sr2:0x4229 status:0x81ff
    |sr2:0x4229 status:0x81ff
    |sr2:0x4229 status:0x81ff
    |sr2:0x4229 status:0x81ff
    |sr2:0x4229 status:0x81ff
    |sr2:0x4229 status:0x81ff
    |sr2:0x422b status:0x81ff   <--- ここで sr2 が変化
    |sr2:0x422b status:0x81ff
         29  sr2:0x422b status:0x81ff ... (同じ出力 29行分を 1行に省略)
    |sr2:0x422b status:0xe1ff   <--- ここで status が変化
    |sr2:0x422b status:0xe1ff
    |sr2:0x422b status:0xe1ff
    |...
    |..
    |.   途中を uniq -c したもの
    |    210    sr2:0x422b status:0xe1ff
    |      1    sr2:0x4229 status:0xe1ff
    |    255    sr2:0x422b status:0xe1ff
    |      1    sr2:0x4229 status:0xe1ff  <--- 256回に 1回は sr2 が違う?
    |    255    sr2:0x422b status:0xe1ff
    |      1    sr2:0x4229 status:0xe1ff
    |    255    sr2:0x422b status:0xe1ff
    |      1    sr2:0x4229 status:0xe1ff
    |    255    sr2:0x422b status:0xe1ff
    |      1    sr2:0x4229 status:0xe1ff
    |    118    sr2:0x422b status:0xe1ff
    +---------------------------------------------------


その他の条件

    ●a500fx において (A5027Z-C, S/N 080503-003132, ChipRev: M91EN)

    ・ttymxc0 でも ttymxc4 でも出た。
    ・マザーボードの COM ポートでも USB-Serial 変換(USB-RSAQ3)でも出た。
    ・暴走中にシリアルのコネクタを抜いても連続受信状態は継続する。
    ・受信 4800bps 設定でも 57600bps で送信することにより出る。
      他の組み合わせでは、下の表のとおり合理的(?)な受信エラー状態となる。

           ** ttymxc4(9600bps 設定)に PC から異なったボーレートで
           ** 文字を送ったときの URXD レジスタの値と反応

            ttymxc4 (9600)    +---------------+---------------+
              URXD reg status |  ' ' (0x20)   |  '@' (0x40)   |
            +-----------------+---------------+---------------+
            |    300bps(1/32) | 0xd900,0xd900 | 0xd900,0xd900 | <== (2)
            |    600bps(1/16) | 0xd900,0xd900 | 0xd900,0xd900 |
            |   1200bps (1/8) | 0xd900,0xd900 | 0xd900,0x8180 |
            |   2400bps (1/4) | 0xd900,0x8180 | 0xd900,0x81f8 |
            |   4800bps (1/2) | 0xd900,0x81f8 | 0xd900,0x81fe |
            +-----------------+---------------+---------------+
            |   9600bps (1/1) |   0x8120      |   0x8140      | <== (1)
            +-----------------+---------------+---------------+
            |  14400bps(x1.5) |   0x81e8      |   0x81d0      | <== (3)
            |  19200bps (x2)  |   0x81f8      |   0x81fc      |
            |  38400bps (x4)  |   0x81ff      |   0x81fe      |
            |  57600bps (x6)  |   0x81ff      |   0x81ff      |
            | 115200bps (x12) |   0x81ff (!)  |   0x81ff      | <== (4)
            | 230400bps (x24) |  (no-sense)   |  (no-sense)   | <== (5)
            +-----------------+---------------+---------------+
                (1) 0xNNCC の下2桁:CC が文字コードです。あってます。
                (2) しゃべるほうが遅いので 2文字到着したと扱われてます。
                (3) しゃべるほうが速いので start-bit は(誤)検出しても
                    データは拾いきれません。
                (4) この (!) のとき、問題のモードに入るときがあります。
                (5) しゃべるのが速すぎて start-bit (誤)検出もせず、
                    なにも来ない扱いです。

           ** ttymxc4(4800bps 設定)に PC から異なったボーレートで
           ** 文字を送ったときの URXD レジスタの値と反応

            ttymxc4 (4800)    +---------------+---------------+
              URXD reg status |  ' ' (0x20)   |  '@' (0x40)   |
            +-----------------+---------------+---------------+
            |  38400bps (x8)  |   0x81ff      |   0x81ff      |
            |  57600bps (x12) |   0x81ff (!)  |   0x81ff      | <== (4)
            | 115200bps (x24) |  (no-sense)   |  (no-sense)   | <== (5)
            +-----------------+---------------+---------------+

    ●a500 において (A5001Z-B, S/N 070201-003125, ChipRev: M45G)

    ・a500 でも ttymxc1(9600bps) で出た、他は未確認。


考察

    ・再現手順 [2] であればユーザープロセスにも CPU が回ることから、
      ハードウェアの「受信*中*ステートに中途半端に入って抜けない」問題か?
        (再現手順 [1] だと debug 出力で CPU/uart を食い尽くすようで)


余談
    ・kernel から見たレジスタアドレスが、iMX31 仕様書のアドレス値に対して
      オフセットされているのはなぜ?
    ・今回の問題とは(たぶん)まったく関係ないが、
      mxc_uart.c の この(patch参照) if() 文の記述、ボクはまずいと思います。
    ・cp /dev/xxx ... すると device file そのものがコピーされちゃうんですね !?



以上ですが、よろしくお願いいたします。
-- 
  email@hidden



==================== patch ここから ====================
diff -c orig/linux-2.6.26-at6/drivers/serial/mxc_uart.c linux-2.6.26-at6/drivers/serial/mxc_uart.c
*** orig/linux-2.6.26-at6/drivers/serial/mxc_uart.c	Fri Jun 19 15:49:16 2009
--- linux-2.6.26-at6/drivers/serial/mxc_uart.c	Tue Oct 27 11:05:37 2009
***************
*** 339,344 ****
--- 339,345 ----
  
  	sr2 = readl(umxc->port.membase + MXC_UARTUSR2);
  	while (((sr2 & MXC_UARTUSR2_RDR) == 1) && (max_count-- > 0)) {
+ 	//     ~~~~is this truly correct ?~~~~
  		ch = readl(umxc->port.membase + MXC_UARTURXD);
  
  		flag = TTY_NORMAL;
***************
*** 351,356 ****
--- 352,361 ----
  		 * character. Perform the appropriate actions based on the
  		 * error bit that was set.
  		 */
+ // if(umxc->port.membase == (char *)0xfc090000/*mxc0*/) ...
+ if((int)umxc->port.membase == 0xfc0b4000/*mxc4*/) {
+ printk(KERN_INFO "sr2:0x%04x status:0x%04x\n", sr2, status);
+ }
  		if (status & MXC_UARTURXD_ERR) {
  			if (status & MXC_UARTURXD_BRK) {
  				/*
==================== patch ここまで ====================



armadillo メーリングリストの案内