y.nakamura
2016年7月8日 14時04分
中村です。
カーネルlinux-3.14-atXを使っている400シリーズと
IoT-G1/G2とBoxWS1のシリアルドライバの
overrunのカウントについてです。
ある方から質問を受けてドライバソースのoverrunまわりを
見ていて気づいたのですが、overrunのカウントに間違いが
あるような気がします。
linux-3.14-at4/drivers/tty/serial/imx.cでoverrunのカウンタを
カウントアップしている部分が2か所あります。
static irqreturn_t imx_rxint(int irq, void *dev_id) { ... rx = readl(sport->port.membase + URXD0); ... if (rx & URXD_OVRRUN) sport->port.icount.overrun++; ... } static irqreturn_t imx_int(int irq, void *dev_id) { ... sts2 = readl(sport->port.membase + USR2); ... if (sts2 & USR2_ORE) { dev_err(sport->port.dev, "Rx FIFO overrun\n"); sport->port.icount.overrun++; writel(USR2_ORE, sport->port.membase + USR2); } ... }
この2つのうち、データ受信割り込みのirqreturn_t imx_rxint()での
overrun++は不要(やってはいけない)のではないかと思います。
URXDレジスタのOVRRUNフラグの説明は次のようになっていて、
FIFOの32番目にデータが入ったときにその受信データのフラグとして
セットされますが、この時点ではまだオーバランしていません。
URXD:OVRRUN
Receiver Overrun. This read-only bit, when HIGH,
indicates that the corresponding character was
stored in the last position (32nd) of the Rx FIFO.
Even if a 33rd character has not been detected,
this bit will be set to ‘1’ for the 32nd character.
実際にオーバランが発生したことの検知はUSR2レジスタの
OREフラグで、この説明は次のようになっています。
USR2:ORE
Overrun Error. When set to 1, ORE indicates that
the receive buffer (RxFIFO) was full (32 chars inside),
and a 33rd character has been fully received.
This 33rd character has been discarded.
ioctlでoverrunエラーの発生回数を取り出して何かを
しようとするアプリケーションはほとんどないとは思いますが、
この部分が気になりました。
--
なかむら
コメント
y.nakamura
中村です。
> mainlineのソースを参照してみましたが、該当カ所に変更はありませんでした。
mainlineまで確認していただき、
どうもありがとうございます。
> 受信割り込みが、Half fullで入るため、よっぽど行儀の悪い(長時間割り込み
> コンテキストから抜けない)ドライバが無い限りは気にならないからだろうと
> 想像しています。
実は、元の投稿で書いた
>>>ある方から質問を受けてドライバソースのoverrunまわりを
>>>見ていて気づいたのですが、overrunのカウントに間違いが
というのは、USR2:OREでのoverrunが発生して、
>>> dev_err(sport->port.dev, "Rx FIFO overrun\n");
によるメッセージが出たのがきっかけでした。
行儀の悪いコードがあるんでしょうね。
私が自分で確認をしたものではないのですが、
Wi-SUNアドオンモジュールWS00での通信時に発生したそうです。
WS00でのoverrunとなると、本投稿の元ネタとは違ってきますので
(元の投稿は、URXDのOVRRUNでのカウントは不要なのでは?と
いう話ですので)、このWS00でのoverrunが解決しないときには、
別スレッドで投稿しようと思います。
--
なかむら
at_mizo
溝渕です。
> 行儀の悪いコードがあるんでしょうね。
>
> 私が自分で確認をしたものではないのですが、
> Wi-SUNアドオンモジュールWS00での通信時に発生したそうです。
恐らくたまたま再現したのがWS00(通信はUART)であるだけで、行儀の悪いコー
ドはUARTでは無いのではないかと推測しています。
というのも、UARTドライバ内では長期間割り込みコンテキスト(および割り込
み禁止でのロック取得含)から抜けないような処理が見当らないためです。
WS00のbaud rateは115kbpsなので、half full(16)からのoverrunだと16 char
分で約1.4msなので、抜けにくいループ等をしている可能性が高いかなと思い
ます。
overrun発生時の状況(ハードウェア構成および動作していたソフトウェア)を
教えていただけるともう少し目処が付けられそうです。
> このWS00でのoverrunが解決しないときには、別スレッドで投稿しようと思い
> ます。
ご進展ありましたら、投稿お願いいたします。
以上です。
y.nakamura
中村です。
すみません。書き方が悪かったようです。
> 恐らくたまたま再現したのがWS00(通信はUART)であるだけで、行儀の悪いコー
> ドはUARTでは無いのではないかと推測しています。
はい。私もUARTのドライバ以外と思ってます。
UART以外のどこかで
> WS00のbaud rateは115kbpsなので、half full(16)からのoverrunだと16 char
> 分で約1.4msなので、抜けにくいループ等をしている可能性が高いかなと思い
> ます。
のようなちょっと長い割り込み禁止状態に
なっているのではないかと・・・です。
> ご進展ありましたら、投稿お願いいたします。
overrunのことを聞いたのはだいぶ前で、
その後この話の続きを聞いてませんので、
今はどうなのか私も把握できていないのですが、
何かありましたら、また、よろしくお願いいたします。
--
なかむら
at_mizo
2016年8月10日 15時28分
溝渕です。
ご報告ありがとうございます。
ご指摘の通り、sport->port.icount.overrunが少なくとも文字を取りこぼした
文字数(または取りこぼした回数)を示すのであれば、imx_rxint()は不要に思
います。
「少くとも」と表現したのは、取りこぼした文字数を正確に把握することがで
きまない(34文字目を受信ししても2文字こぼしたことを検出不可)ためです。
> URXDレジスタのOVRRUNフラグの説明は次のようになっていて、
> FIFOの32番目にデータが入ったときにその受信データのフラグとして
> セットされますが、この時点ではまだオーバランしていません。
上記、オーバーランしている場合としていない場合があると思います。これは、
33番目のデータを受信してもしなくても、32番目のデータを受信したタイミン
グでセットされるためです。
いずれにしても、USR2:OREはW1Cレジスタなので、ここでのみ
sport->port.icount.overrunをインクリメントしても良さそうな気がします。
mainlineのソースを参照してみましたが、該当カ所に変更はありませんでした。
受信割り込みが、Half fullで入るため、よっぽど行儀の悪い(長時間割り込み
コンテキストから抜けない)ドライバが無い限りは気にならないからだろうと
想像しています。
以上です。