AsyncSerial ‐ リングバッファ付きシリアル通信
Import libraryAsyncSerial
Asynchronous (Non-blocking) Serial Communication library with variable length software ring buffer (FIFO). You can use primary method of the RawSerial Library. Operability confirmed on mbed 2.0. (Rev.146)
AsyncSerialとは?
ソフトウェアFIFO(リングバッファ、First-in, First-outの略)を用いてノンブロッキング(非同期)のシリアル(UART)通信を行うためのライブラリです。
mbed標準のSerialライブラリやRawSerialライブラリはソフトウェアバッファを備えておらず、基本的にブロッキング通信となってしまいます(ハードウェアFIFOを備えるCPUなら、限られた長さでのノンブロッキング通信は可能です)。これらのライブラリにはwriteメソッドがあり、任意の長さの配列をノンブロッキングで送信する事ができるものとなっていますが、対応ボードが限られており、まともに使える代物ではありません。
そこで標準のRawSerialライブラリを拡張して実装したものがAsyncSerialです。RawSerialライブラリを拡張したことによって、Serial / RawSerialライブラリと同じメソッド名を用いて操作をすることが可能です。加えて、ArduinoのSerialライブラリに実装されているような peekc()、 flush()、 そして wait() メソッドを実装してあります。(詳しい説明は後述)
動作環境
mbed 2.0での動作のみ確認しております。 mbed OS 5での動作確認はしておりません。
追記: 現在、mbed標準ライブラリ Revision 147以降で正しく動作しない現象が確認されております。 対策方法は以下の通りです。
- mbed Compilerにて左側のプログラムワークスペースにある歯車マークの”mbed”を選択し、上側のツールバーにある”リビジョンを選択
- 中央に表示されるリスト上の、"Release 146 of the mbed library."を選択
- 中央のツールバーにある、”切り替え”をクリック
- 上側のツールバーにある”リビジョン”を再度クリック
mbed標準ライブラリに含まれるバグの可能性が高いと思われますが、今後のアップデートで改善される可能性もあります。
使用方法
基本的にはSerial / RawSerialライブラリと全く同じ使い方ができるので、そちらも参照してください。
- RawSerial APIリファレンス(英語) /users/mbed_official/code/mbed/docs/25aea2a3f4e3/classmbed_1_1RawSerial.html
また、AsyncSerialのAPIについては以下のページにも記載してあります。
- AsyncSerial APIリファレンス(英語) /users/babylonica/code/AsyncSerial/docs/tip/classAsyncSerial.html
シリアルポートの初期化
シリアルポートの初期化は、Serial / RawSerialと同じようにAsyncSerial クラスのオブジェクトを生成することで行います。
プロトタイプ
AsyncSerial(PinName txpin, PinName rxpin, uint32_t baudrate=9600, uint32_t buffer_size=256);
引数
型 | 引数 | 説明 |
---|---|---|
PinName | txpin | 送信するピン(PinNames.hで定義されたもの) |
PinName | rxpin | 受信するピン(PinNames.hで定義されたもの) |
uint32_t | baudrate | ボーレート(デフォルト引数のため指定しない場合はデフォルト値になります。デフォルト値: 9600bps) |
uint32_t | buffer_size | 送信・受信バッファのサイズ(デフォルト引数のため指定しない場合はデフォルト値になります。デフォルト値: 256byte) |
戻り値
コンストラクタのため、戻り値はありません。
記述例
AsyncSerial hoge(USBTX, USBRX); // 送受信をmicroUSB経由で行う AsyncSerial hoge(USBTX, USBRX, 115200, 128); // 送受信をmicroUSB経由で行い、ボーレートを115200bpsに、バッファサイズを128byteに設定する
baud - ボーレート設定
ボーレートの設定はシリアルポートの初期化時だけでなく、以下のように設定することが可能です。
プロトタイプ
void baud(int baudrate);
引数
型 | 引数 | 説明 |
---|---|---|
int | baudrate | ボーレート(bps) |
戻り値
戻り値はありません。
記述例
hoge.baud(115200); // ボーレートを115200bpsに設定
format - 通信方式設定
ビット数、パリティ、ストップビットを設定します。 このメソッドを呼び出さなかった場合、デフォルトの8N1でシリアル通信が行われます。
プロトタイプ
void format(int bits=8, Parity parity=SerialBase::None, int stop_bits=1);
引数
型 | 引数 | 説明 | |
---|---|---|---|
int | bits | ビット数(5 - 8) | |
Parity | parity | AsyncSerial::None | パリティなし |
AsyncSerial::Odd | 奇数パリティ | ||
AsyncSerial::Even | 偶数パリティ | ||
AsyncSerial::Forced1 | 強制的に1 | ||
AsyncSerial::Forced0 | 強制的に0 | ||
int | stop_bits | ストップビット(1 - 2) |
戻り値
戻り値はありません。
記述例
hoge.format(8, AsyncSerial::Even, 2); // シリアルポートを8E2に設定
getc - 1byte受信する
受信バッファからデータを1byte取り出します。
プロトタイプ
virtual int getc(void);
引数
引数はありません。
戻り値
型 | 説明 |
---|---|
int | 受信したデータ |
記述例
uint8_t data; data = (uint8_t)hoge.getc();
peekc - 1byte受信する(読み取り位置変更なし)
受信バッファからデータを1byte取り出します。
なお、getc メソッドと違いバッファの読み取り位置を変更しません。すなわち、peekc メソッドは同じデータを繰り返し読み取ります。
プロトタイプ
virtual int peekc(void);
引数
引数はありません。
戻り値
型 | 説明 |
---|---|
int | 受信したデータ |
記述例
if( hoge.peekc() == '@' ){ // Code }
readable - 受信したデータのサイズを取得する
受信バッファにデータが何byte届いているかを取得します。 ArduinoにおけるSerial.available メソッドのようなものです。
プロトタイプ
virtual int readable(void);
引数
引数はありません。
戻り値
型 | 説明 |
---|---|
int | 受信バッファに届いているデータのサイズ(byte) |
記述例
if( hoge.readable() > 0 ){ hoge.putc( 0x0A ); }
flush - 受信バッファをクリア
受信バッファのデータを強制的にクリアします。
プロトタイプ
virtual void flush(void);
引数
引数はありません。
戻り値
戻り値はありません。
記述例
hoge.flush();
putc - 1byte送信する
送信バッファに1byteのデータを追加することによって、データを1byte送信します。
プロトタイプ
virtual void putc(int c);
引数
型 | 引数 | 説明 |
---|---|---|
int | c | 送信するデータ |
戻り値
戻り値はありません。
記述例
hoge.putc( 0x0A );
puts - 1行の文字列を送信する
文字列に改行文字(CR+LF)を付けて送信します。
プロトタイプ
virtual void puts(const char *str);
引数
型 | 引数 | 説明 |
---|---|---|
const char* | str | 送信する文字列 |
戻り値
戻り値はありません。
記述例
hoge.puts("Hello, World!");
printf - 書式付き文字列を送信する
書式付きの文字列を送信します。おなじみのprintfと同じような動作をします。
プロトタイプ
virtual int printf(const char *format, ...);
引数
型 | 引数 | 説明 |
---|---|---|
const char* | format | 送信する書式付き文字列 |
可変個引数 |
戻り値
型 | 値 | 説明 |
---|---|---|
int | 0 | エラー |
1以上 | 送信した文字列の長さ(byte) |
記述例
int num = 4; hoge.printf("Hi, I'm Cortex-M%d.\n", num);
write - バイト列を送信する
1byteの配列をまるごと送信します。
プロトタイプ
virtual int write(const uint8_t *buffer, int length);
引数
型 | 引数 | 説明 |
---|---|---|
const uint8_t* | buffer | 送信するバイト列 |
int | length | 送信するバイト数(byte) |
戻り値
型 | 値 | 説明 |
---|---|---|
int | 0 | エラー |
1以上 | 正常終了 |
記述例
uint8_t array[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; hoge.write(array, 11);
wait - すべての送信が完了するまで待機する
すべての送信が完了するまで、すなわち送信バッファが空になるまで待機します。
プロトタイプ
virtual void wait(void);
引数
引数はありません。
戻り値
戻り値はありません。
記述例
hoge.wait();
サンプルコード
- シリアルポートを2ポート用意し、片方に届いたデータをもう片方のポートから送信するプログラム
// -*- coding: utf-8 -*- // Board: NUCLEO_F303_K8 #include "mbed.h" #include "AsyncSerial.hpp" AsyncSerial ser(D5, D4); AsyncSerial pc(USBTX, USBRX); int main(){ while(1){ while( pc.readable() > 0 ){ ser.putc( pc.getc() ); } } }
6 comments on AsyncSerial ‐ リングバッファ付きシリアル通信:
Please log in to post comments.
wait出来ていませんでした。
void AsyncSerial::wait(void){ while( fifo_rx.available() > 0 ){} return; }
void AsyncSerial::wait(void){ while( fifo_tx.available() > 0 ){} return; } に変更したら出来ました。