私たちのグループは、組み込みプロセッサ(Phytec LPC3180、ARM9)を使用しています。LPC3180のI2Cバスの1つに4つのMAX3107UARTチップを含むボードを設計しました。重要な場合は、このプロセッサで利用可能な最新バージョンであるカーネル2.6.10を実行しています(この製品のサポートはあまり良くありません。PhytecおよびPhytecが提供する多数のドライバを開発または修正する必要がありました。この製品のLinuxコード(特にカーネルバージョン)のアップグレードには関心がないようです。これは、LPC3180が優れたデバイスであるという点で、特にイーサネットを必要とせず、実際には必要としない低電力の組み込み製品のコンテキストでは、あまりにも悪いです。エーテルネットは必要ありません(イーサネットコントローラーチップの関連する電力消費のため)。
I2Cバス上の4つのデバイス(MAX3107 UARTチップ)の1つが文字を受信すると、割り込みを生成します。4つのMAX3107チップすべての割り込みラインは共有され(オープンドレインプルダウン)、ラインはレベル割り込み用に構成された3180のGPIOピンに接続されます。3017の1つが割り込みを生成すると、次の処理を(大まかに)実行するハンドラーが実行されます。
spin_lock_irqsave();
disable_irq_nosync(irqno);
irq_enabled = 0;
irq_received = 1;
spin_unlock_irqrestore()
set_queued_work(); // Queue up work for all four devices for every interrupt
// because at this point we don't know which of the four
// 3107's generated the interrupt
return IRQ_HANDLED;
上記のコードを終了する前に割り込みが再度有効にされないことに注意してください。これは私がやや厄介だと思うことです。むしろ、ドライバーは、(「enable_irq(LPC_IRQ_LINE)関数呼び出し」を使用して)下半分のワークキュータスクによって割り込みが再度有効になるように記述されています。ワークキュータスクは割り込みコンテキストで実行されないため、スリープする可能性があると思います。割り込みハンドラにとっては悪い考えだと私は信じています。
上記のアプローチの理論的根拠は次のとおりです。1。4つのMAX3107UARTチップの1つが文字を受信し、割り込みを生成する場合(たとえば)、割り込みハンドラは4つのI2Cデバイスのどれが実際に割り込みを引き起こしたかを把握する必要があります。ただし、明らかに、I2C読み取りはスリープする可能性があるため、上半分の割り込みハンドラーのコンテキスト内からI2Cデバイスを読み取ることはできません。これは、割り込みハンドラーの上半分には不適切と見なされます。2.上記の問題(つまり、どのデバイスが割り込みを引き起こしたか)に対処するために採用されたアプローチは、割り込みを無効のままにして上半分のハンドラーを終了することです。その後、非割り込みコンテキストコードはI2Cバス上の4つのデバイスのそれぞれにクエリを実行できます。どちらが文字を受信したか(したがって、割り込みを生成したか)を把握します。3.3。下半分のハンドラーが割り込みを生成したデバイスを特定すると、下半分のコードはそのチップの割り込みを無効にして、LPC3180への割り込みラインを再トリガーしないようにします。その後、シリアルデータを読み取って終了します。
ここでの主な問題は、割り込みハンドラの上半分から4つのMAX3107UARTチップをクエリする方法がないことです。上半分が戻る前に単に割り込みを再度有効にすると、同じチップが再び割り込みを生成し、上半分が割り込みを無効にし、下半分の作業キューをスケジュールして無効にする状況につながると思います割り込みは、下半分のコードがチップに到達して割り込みを発生させる前に、別の割り込みが発生したなどの理由で、同じ場所に戻るだけです。
このドライバーに対処するためのアドバイスをいただければ幸いです。ドライバーの上半分で割り込みを無効にして、上半分のドライブコードが存在する前に再度有効にしないという考えは本当に好きではありません。これは安全ではないようです。
ありがとう、
ジム
PS:私の読書では、上記の要件に対処する手段としてスレッド化された割り込みを発見しました(少なくとも、http://lwn.net/Articles/302043/などのWebサイトの記事の私の解釈です)。Phytecが提供する2.6.10カーネルにスレッド割り込み関数が含まれているかどうかはわかりません。今後数日でこれを調査するつもりです。