MSP430 4線式 SPI マルチスレーブ・ライブラリ メッセージマネージャ編 version 1.0 2014/3/10 PIC 山内 一男 この資料は 「複数IOの管理方式v1.0」、 「4線式SPIマルチスレーブ・ライブラリとデモシステム」をベースにした続編に あたります。 本書は、マスターとマルチスレーブのSPI接続を利用した、「メッセージ交換による、マルチCPU連携処理システム」向けの、 メッセージマネージャライブラリを説明するものです。 具体的な処理を理解できるようにデモexampleを添付しました。 目 次 1 特徴 ..................................................................................................... 2 2 ソフトウェア階層構成 .................................................................................... 2 3 機能・仕様 .............................................................................................. 2 3-1 メッセージフォーマット.......................................................................................................2 3-2 受信エラーチェック ..........................................................................................................3 3-3 バッファ管理 ..................................................................................................................3 3-4 コマンド(_cmd/_ans)..............................................................................................3 3-5 SPI 通信の留意点 .......................................................................................................3 3-5-1 マスターの処理手順 ...................................................................................................3 3-5-2 スレーブの処理手順 ...................................................................................................4 4 API ...................................................................................................... 4 4-1 メッセージ管理の構造体 .................................................................................................4 4-1-1 コマンド構造体 ..........................................................................................................4 4-1-2 データ構造体 ............................................................................................................4 4-1-3 受信構造体 .............................................................................................................4 4-2 API 詳細 .....................................................................................................................5 4-2-1 SPI IO 構造体の登録 .............................................................................................5 4-2-2 送信バッファの登録 ....................................................................................................5 4-2-3 送信コマンドの書き込み..............................................................................................5 4-2-4 送信コマンド・データの書き込み ...................................................................................5 4-2-5 送信メッセージのピックアップ .........................................................................................5 4-2-6 受信コマンドの読み出し ..............................................................................................6 4-2-7 受信データの読み出し ................................................................................................6 4-2-8 コーリングシーケンス ....................................................................................................6 5 デモ example .......................................................................................... 6 5-1 テストプロジェクト test_message .............................................................................6 5-2 メッセージ交換のプロジェクト G2xx_meseg_MstSPI4、G2xx_meseg_SlvSPI4 ......6 1 1 特徴 ① マスターとスレーブの間で交換するメッセージを生成・分解するサービスを提供します。 AP(アプリケーション)が直接バッファ内容をアクセスする必要がありません。 SPIのみならず、UARTやWLANなどのペリフェラルにも応用できます。 ② メッセージは、SPIパケットに、ヘッダー(サイズ、スレーブ番号、コマンド)、データとendマークをパックしたものです。 ③ サイズとendマークを使い、バイトもれやビットズレなどの受信ミスを検出する機能があります。 ④ endマークのコードで、次のパケットの有無が解ります。 ⑤ 送信バッファとして最大4個までのバッファを管理できます。 これは、同時に複数イベントが発生したとき、すでに生 成して未送信のメッセージが上書きされないように、送信バッファを使い分けるためです。 ⑥ コマンド(_cmd/_ans)は、マスターとスレーブの間で、処理依頼や結果報告とイベントの通知などに使用します。 マスターとスレーブの間で処理内容を取り決めて定義するものです。 APのロジックに直結します、ユーザが定義して 使用します。 ⑦ 送信メッセージがない時に送信をすると、自動的にダミーメッセージ(_NOP)を送ります。 2 ソフトウェア階層構成 ソフトウェアの階層構成は、下記になります。 APは赤矢印の制御をAPIで実行します。 3 機能・仕様 3-1 メッセージフォーマット ① ② header:size(1byte)、s-ID(1byte)、コマンド(2byte) size : パケット長、sizeを含めたバイト長 s-ID : スレーブID コマンド : マスター:_cmd、 スレーブ:_ans endマーク(1byte) 終了記号 ]:次のパケットはない、 [:次のパケットがある 2 ③ フォーマット(uint8_t) size n, s-ID, cmd*2, data1, data2, ...., data(n-5), endマーク 3-2 受信エラーチェック sizeで指定された最後のbyteがendマークか判定されます。 これでbyte落ちやbitズレの有無をチェックします。 3-3 バッファ管理 使用する送信バッファを登録した順で優先度をつけて管理します。 最大4個まで登録できます。 最後の優先度が低いバッファは、ダミーメッセージ用にも使われますので、内容は書き換えられる場合があります。 3-4 コマンド(_cmd/_ans) マスタとスレーブのアプリケーションが、お互いの処理(要求とアンサーなど)を取り決めて定義します。 例えば、ADCデータの要求とADCデータの報告などです。 よってアプリケーションの処理・ロジックに直接ディペンドします。 マスタは_cmd_xxx:大文字、 スレーブは_ans_xxx:小文字 で識別できるようにしてあります。 デモexampleのMessage_manager.hでは下記の定義をしてあります。 /* SPI message table /* _cmd_xxx are master commands and _ans_xxx are slave replies // command: master -> slave #define _cmd_Start 0x5354 // "ST", restart //#define _cmd_Wake 0x574B // "WK", wake up //#define _cmd_Sleep 0x534C // "SL", request to sleep #define _cmd_Report 0x5250 // "RP", request reports about error #define _cmd_Test 0x5453 // "TT", send test data #define _cmd_Query 0x5155 // "QU", query a slave #define _cmd_ADC 0x4144 // "AD", request ADC data #define _mode_Request 0x4D52 // "MR", change to request mode #define _mode_Polling 0x4D50 // "MP", change to polling mode // reply: slave -> master #define _ans_Restart 0x7374 // "st", restart #define _ans_Nak 0x6E6B // "nk", NAK, command error #define _ans_Busy 0x6273 // "bs", Busy #define _ans_Report 0x7270 // "rp", reply about transfer error #define _ans_TestACK 0x7441 // "tA", reply ACK for test data #define _ans_TestNAK 0x744E // "tN", reply NAK for test data #define _ans_ADC 0x6164 // "ad", send ADC data #define _Nop */ */ 0xFFFF // No command or no answer 3-5 SPI 通信の留意点 SPIは送信と受信を同時に行います。 ですからマスターのコマンドに対し、スレーブからのアンサーは次以降の通信で 帰ってくることになります。 つまり、_cmd/_ansの識別をして処理をすることになります。 3-5-1 マスターの処理手順 スレーブにコマンドを送り、スレーブからのアンサー情報を受け取ります。 スレーブが「次のパケット有り」を送ってきたら、すぐにポーリング(_cmdQuery)をしてアンサーを早く入手できます。 マスターは、アンサー(_ans_xxxx)の内容を見て、受付の処理をすることになります。 イベントドリブンの処理になり、コマンド->レスポンスのシーケンス処理をすることはできません。 3 3-5-2 スレーブの処理手順 コマンドを受信したときは、それに対応する処理をしてメッセージを生成して、マスターにアンサーを返します。 マルチイベントを処理していると、複数の(未送信)メッセージが生成されます。 マスタからコマンドが来たときに、この 複数の未送信メッセージをアンサーとして返すことになります。 メッセージマネージャが優先度の高いメッセージから送信しますので、スレーブはメッセージ生成に注力できます。 マスターからのコマンドに対し、何もメッセージがない時は、メッセージマネージャがダミー(_NOP)のアンサーを返します。 4 API Message_manager.hに、使用する構造体とAPIの定義と説明があります。 4-1 メッセージ管理の構造体 4-1-1 コマンド構造体 パケットサイズ(size)と送信コマンド(_cmd/_ans:2byte)を定義します。 下記は通信のテストコマンドの定義例です。 ・マスター Mess_CMD Test_str const struct Mess_CMD TestACK_str = { size_Test + M_header, _ans_TestACK }; const struct Mess_CMD TestNAK_str = { size_Test + M_header, _ans_TestNAK }; const struct = { size_Test + M_header, _cmd_Test }; ・スレーブ 4-1-2 データ構造体 パケットに格納するワードデータを定義します。 ワードの変数か配列が対象です。 コマンド構造体に、データサイズ(byte)とデータpointer(uint16_t *)を付加したものです。 リトルエンディアンなので、low byte, High byte の順で送受信されます。 下記は、通信エラー回数を回答するコマンドの定義例です。 const struct Mess_DATA Report_str = {{ M_header+2, _ans_Report }, 2, &cnt_error }; 4-1-3 受信構造体 受信したコマンド、データサイズ(パケットsize - 5 byte)と「次のパケットの有無」がセットされます。 struct Mess_RECV { uint16_t M_cmd; uint8_t size; M_next 次のパケットなし:#define _single 0 次のパケットあり:#define _next 1 4 uint8_t M_next; }; 4-2 API 詳細 各APIの仕様を説明します。 具体的な利用法はデモexampleで確認お願いします。 4-2-1 SPI IO 構造体の登録 void Mess_config( struct IO_req2Buf *SPI_req ); 使用するSPIのIO構造体を登録します。 受信バッファは指定必須ですが、送信バッファは優先度の高いバッファがその都度セットされます。 4-2-2 送信バッファの登録 uint8_t Mess_set_BUF( uint8_t *buffer ); 使用する送信バッファを登録します。 登録順で優先度が決められます。 最後に登録したバッファは優先度が最下位となり、dummyコマンド(_NOP)の送信にも使われます。 実際の送信ではFIFOではなく、優先度の高いバッファから送信されます。 この理由は、FIFOはチェーン更新オーバヘッドが大きいためと、優先度高いメッセージを早く送ることを重視しています。 割り当てられた Buf_ID(ハンドル)が戻り値として返されます。 4-2-3 送信コマンドの書き込み void Mess_set_CMD( uint8_t Buf_ID, const struct Mess_CMD *P_CMD ); 指定Buf_IDのバッファにコマンドを書き込みます。 送信要求フラッグがonになります。 送信される前に、同じBuf_IDで2回書き込むと上書きされ、最初の内容は消失します。 byteデータは、この関数呼び出しの前にバッファに書き込んでおきます。 4-2-4 送信コマンド・データの書き込み void Mess_set_cmdDATA( uint8_t Buf_ID, const struct Mess_DATA *P_DATA ); 指定Buf_IDのバッファに、コマンドとワードデータを書き込みます。 ワードデータは、パケットのヘッダー直後、4byte目から指定バイト数をコピーして書き込みます。 4-2-5 送信メッセージのピックアップ uint8_t Mess_pickup_BUF(); SPIのIO要求の直前で呼び出します、必須です。 送信要求フラッグonかつ優先度の高いバッファを、SPI構造体の送信バッファにセットします。 そのバッファの送信要求フラッグはoffになります。 他に送信要求フラッグonのバッファがあれば、endマークを「次のパケット有り」にして送信します。 ・ 送信要求フラッグonのバッファがない時は、dummy(_NOP)を生成して送信バッファにセットします。 5 4-2-6 受信コマンドの読み出し uint8_t Mess_get_CMD( struct Mess_RECV *Pmess ); SPIのIO完了後に呼び出します、コマンドとデータsize、次のパケット有り/無しが、Pmessにセットされます。 戻り値は、SPIエラー、endマーク不適(Mess_noETX)、レスポンスなし(Mess_noReply)が返ります。 4-2-7 受信データの読み出し void Mess_get_DATA( uint8_t size_DT, uint16_t *Pdata ); 受信コマンドの読み出しが正常にできた場合で、データsize !=0かつワードデータ付きのコマンドの場合は、ワードデー タを変数か配列(*Pdata)にsize_DT(バイト)読み出します。 4-2-8 コーリングシーケンス API関数の呼び出し順は下記になります。 詳細は、デモexampleで確認できます。 /* calling sequence * * Msee_config(); * Mess_set_BUF(); * ... * Mess_set_CMD(); or Mess_set_cmdDATA(); * ... * Mess_pickup_BUF(); // <--- Calling this function is essential * SPIm4_IO_NoWait(); // SPI IO * Mess_get_CMD(); * if( size_DT !=0 ) Mess_get_Data(); */ 5 デモ example 添付zipのプロジェクトは、CCSv5.5で生成してあります。 新規のworkspaceにimportで移植します。 APIライブラリは、G2553_Driver_LIBにあります。 これを各プロジェクトは”link“とinclude pathで参照します。 5-1 テストプロジェクト test_message メッセージAPI関数のテストとパフォーマンス測定用です。 5-2 メッセージ交換のプロジェクト G2xx_meseg_MstSPI4、G2xx_meseg_SlvSPI4 マスターとスレーブの間でメッセージ通信をして、メッセージ動作テストと通信エラーの監視をするプロジェクトです。 1)マスターの動作 最初に_cmd_Startコマンドを送り、スレーブに初期化を要求します。 そのアンサーが来た(active)なslaveを見つ けて、それらactiveなスレーブのみをテスト対象にします。 activeなslaveは、terminalに16進数で表示されます。 バイトデータとして0x01~0xFFの数字(+1インクリメント)を_cmd_Testコマンドで送り、そのアンサーがエラーあり (_ans_testNAK)の場合は、terminalにエラー発生を表示します。 既定の回数が来ると通信レポートを要求(_cmd_Report)し、そのアンサー結果、エラー回数、を表示します。 さらに既定の回数が来ると、最初の処理から反復します。 6 下記が表示例です。 slave 1,2 がactiveで、何もエラーが出ていない状態です。 2) スレーブの動作 スレーブは、マスターからのコマンド種別に従って、処理をします。 _cmd_Startの時は、初期状態から再開します。 _cmd_Testの時は、受信バイトデータ(+1インクリメント)をチェックして、アンサー(_ans_TestACK/NAK)を 返します。 エラー回数を記録します。 _cmd_Reportの時は、エラー回数(1ワードデータ)をアンサー(_ans_Report)として返します。 ** SPIのclkラインに長いリード線をつけて、旧式のヘアードライヤーボディに巻きつけてon/offの試験してみましたが、エラ ーは起きていません。 高圧モータでも近くになければ、まず大丈夫かなと思います。 実際の装置環境で使用していただけ れば、通信障害のテストができると思います ** 以 上 今回のデモexampleは、ペリフェラルをSPIのみで動作させていますので、まだマルチIOイベントの確認ができていません。 次回は、マスター/スレーブともにマルチIOイベントのプロジェクトに書き換えて、確認試験をする予定です。 7
© Copyright 2024 Paperzz