スパイス  組み込み制御装置の受注製作

ライブラリの導入
平成27年 5月 19日

 MPLAB Harmonyをライブラリ化する  USBドライバをライブラリ化
 当初は MPLAB Harmonyの仕様通りの使い方をしてきたのですが、幾つか使い難い面があり最終的にはMPLAB Harmonyの標準的な使い方とは異なる使い方を模索するようになりました。
しかし、MPLAB Harmony自体は非常に魅力的です。特に周辺機能の初期化やアクセス関数を提供してくれるのは、分厚いデータシートを読むだけでは理解できない細部の注意点を気にせず、幾つかの関数について学ぶだけでやりたい事を始められる。

 そこでMPLAB Harmonyの出力を元に、これをライブラリ化する方法を説明します。
ここでのライブラリ化の目的は ことが目的です。残念ながら汎用ライブラリに仕上げることはできません。ここでの汎用ライブラリとは、設定ファイルの変更のみで再コンパイルの必要がないライブラリを指します。

 今回は、先日まで試行錯誤していたUSBについてライブラリ化を行います。最初に使用するサンプルプロジェクト名はcdc_com_port_dualです。変更の前後でミスが入る危険が高いので、頻繁にバックアップをとりながら進めます。
 基本的な手順は下記のとおりです。5までの作業は以前に実施してあります。
  1. 使用する基板の仕様に合わせて、水晶発信やPLLの設定を変更する。
  2. 複数ある基板に対するコンフィグレーションから一つを残して後は削除する。
  3. 標準基板に対するプログラムであるBSP関連のプログラムを削除する。
  4. プログラムの動作を確認する。(2CHあるシリアルポートが互いに送受信がクロスして動作する)
  5. デバッグを簡単化するために、各CHでの動作を単純なループバック(オウム返し)に変更する。
  6. プログラムに外部からアクセスする関数を追加する。
  7. 最後にライブラリ用のコンフィグレーションを作成する。
 ここでは6以降について書いていきます。
まず最初に、これらUSB関連機能を外部からアクセスするためのインターフェース関数を定義します。これは、外部からUSBシリアルにアクセスするとき、出来るだけ内部処理に関して何も知らないで使えるようにしたいためです。プログラム的には多少の無駄が発生しますが、それよりも分かり易さを優先します。
 基本的な関数としては下記が必要です。
  1. USBの初期化を行う初期化関数。引数としては割り込みの優先度および副優先度を指定する。
  2. メイン関数内のループ処理でUSBの処理を行うUSBタスク関数
  3. 割り込み処理を行うUSB割り込み処理関数
  4. USBからの読み出し関数。
  5. USBへの書き出し関数
 初期化関数とUSBタスク関数はMPLAB Harmonyによって自動的に作られますが、部分的な変更が必要になります。
USB割り込み処理関数は変更の必要が無ければ、そのままでもかまいません。
 読み出し関数では、読み出すデータがあればその文字数とデータへのポインタを返します。読み出すデータが無ければ文字数は0、ポインタはNULLを返すようにします。
更に、読み出したデータの処理が終わった後で、次のデータを読み出すように読み出し再開を要求する関数が必要になります。
 書き出しも二つの関数に分かれます。最初は書き出し作業が可能かどうかを確認するための関数で書き出し可能ならデータバッファへのポインタと一度に書き出せる文字数を返し、不可ならNULLを返すようにします。
書き出し関数では、データへのポインタとその文字数を引数として渡します。
 なお、本プロジェクトでは複数のシリアルポートを扱うので、引数にシリアルポートのCH番号を含めます。

 以上で新規に追加する関数のインターフェース仕様が決まりました。
ヘッダーファイルを以下に示します。
lib_usb_cdc_dual.h

#ifndef LIB_USB_CDC_DUAL_H
#define  LIB_USB_CDC_DUAL_H

#include <stdint.h>
#include <stdbool.h>

#define MAX_CDC_CH      2

bool USBCDC_init(uint8_t ip, uint8_t is);
void USBCDC_task(void);

//正常ならtrueを返す。
//falseを返すときでも*cntには0を入れる
bool USBCDC_getData(uint8_t ch, uint8_t **buf, uint8_t *cnt);

//受信データの処理が終わったことを通信部に知らせる。
//以後、次の受信動作を開始
bool USBCDC_finishGetData(uint8_t ch);


//送信中・USBのconfig中などで送信不可の時には*bufにNULLを返す
bool USBCDC_getPutBuf(uint8_t ch, uint8_t **buf, uint8_t *bufSize);

//送信処理。cntは必ずUSBCDC_getPutBuf()のbufSize以下
//bufはUSBCDC_getPutBuf()の返り値で無くてもよい
bool USBCDC_putData(uint8_t ch, uint8_t *buf, uint8_t cnt);

//割り込み処理関数
void USBCDC_CB(void);

#endif  //LIB_USB_CDC_DUAL_H
 長くなるので、次回に各関数のプログラムを示します。


目次へ  前へ  次へ