ようこそ.あなたは 2983 人目のお客様です.キリ番踏んだら連絡してね.
このサイトはniiimがオープンな情報を元に適当なまとめた情報を掲載しています.間違いがあればご指摘頂けると助かります.
本稿ではAutosar CPのCanIfとCANのバッファ機能について紹介します.
CAN Diverは通常Canと表記されますが,混乱防止のためCanDrvと表記します.CanIfの上位モジュールは,Upper Layerとして表記します.
Hardware Object (HWO) | CAN Controller内にある1つのPDUに対応するRAM領域. 主に以下の4つの設定項目が存在する: - ID - データ長 - Handle Type (FullCAN or BasicCAN) - Object Type (Transmission or Reception) |
FullCAN | HWOの種類の1つ.1つのHWOに対して1つのPDUを割当てる. |
BasicCAN | HWOの種類の1つ.1つのHWOに対して複数のPDUを割当てる. |
Hardware Transmission Handle (HTH) | 送信に用いるHWOを指すポインタ.1つのPDUに対して複数のHWOを割当てることもできる(SWS_Can_00403). |
Hardware Reception Handle (HRH) | 受信に用いるHWOを指すポインタ. |
Autosarより引用して参考図を示します.次の図では8個のHWOが存在し,4つのHWOが4つのHRHと,2つのHWOが1つのHTHと割当たっています.この構成はOuter Priority Inversionを回避するために用いられます.
受信の際も同様です.
なお割当てる数はHTH, HRHにおいて,割当てるHWOの数はCanHwObjectCountと呼ばれます.
基本的な送信フロー次の通りです.
CanDrvnの処理は割込み(Interrupt)でもタスク処理(Polling)でも処理できます.割込みの時のシーケンス図を,Autosar仕様から引用して示します.
送信が完了すると,CanDrvは送信完了通知(TxConfirmation)を受取り,CanIfに通知します.CanDrvの送信完了通知の受取りは,割込み(Interrupt)かタスク処理(Polling)かを選択することができます.割込みの時のシーケンス図を,Autosar仕様から引用して示します.
送信完了通知を利用すれば,CanBusのレベルで正しく送信されたかを知ることができます.
このため,CanIfのコンフィグでは各フレームに対して,どのUpper Layerに対して送信完了通知を行うかや,その呼出し関数を指定することができるようになっています.
補足. CANの物理層のプロトコルでは,送信者がAckSlotをRecessiveにしておいて送信しておき,その部分を受信者がDominantに書換えることによって,受信者のうち少なくとも誰か一人が正しく受信したことが分かる仕組みとなっていました.送信完了通知はこれを利用します.従ってここでの「送信完了」とはAckSlotがDominantとなった,即ち受信者のうち誰か一人に正しく受信されたことことを意味します.
CanDrvのMailboxの書込みはCAN_BUSYで失敗するケースがあります.その原因は,例えば当該Mailboxに書込む瞬間において,より優先度の低いIDが多数あるケースです.この時,あるフレームに対する1回目のCan_Writeでは,該当するMailboxに書込まれるが,そのフレームはチャネルがBusyのため送信されず,同じフレームに対する2回目のCan_Writeでは,1つ目のフレームがまだ送信中の状態のためCAN_BUSYとなります.但しCAN Controllerによっては,Mailboxが上書きができ,CAN_BUSYとならないケースもあるので注意が必要です.
Can_Writeの返り値がCAN_BUSYであった時,CanIfは当該フレームがBasicCANに割当てられていれば,CanIfのバッファ(CanIfTxBuffer)にバッファリングを行います.なおバッファに既に前のフレームが存在する場合,最新のものに上書きされます.
バッファリングされたフレームの送信は送信完了通知の時に行います.「送信完了通知」の節で述べたように,送信完了通知は割込み(Interrupt)かタスク処理(Polling)が選べますが,Interruptの時の例をAutosar仕様書から引用して示します.
1つの同一のBasicCANに割当てられたフレームA, Bが存在し,Upper Layerがシグナルの内容を変えてA1, B1, B2と送信要求を行うとします.この時,他の優先度の高いフレームによってバスが占有されているとします.
バスの占有が解除されると,ECUはA1, B2の順にバス上に送信する.
FullCANに割当てられたフレームは,CanIfTxBufferが存在しません.このため,Can_Writeの戻り値がCAN_BUSYとなった場合は,バッファリング処理は存在せず破棄します.
但しMailboxには保存されるため,他のフレームによるバスの占有が起きた場合,その解除後にはMailboxのフレームのみ送信される形となります.この例を次に示します.
FullCANに割当てられたフレームCが存在し,Upper Layerがシグナルの内容を変えてC1, C2, C3と送信要求を行うとします.この時,他の優先度の高いフレームによってバスが占有されているとします.
バスの占有が解除されると,ECUはC1のみバス上に送信します.
CanDrvの処理は割込み(Interrupt)でもタスク処理(Polling)でも処理でき,フレームによって切替えることもできます(Mixed).Pollingでの処理フローは次の通りです.
Pollingでのシーケンス図を示します.