カジバ技研

ドローンとか飛行機とか

Mbed OS 5,6でシリアル通信

はじめに

 Mbed OS 5(OS5), Mbed OS 6(OS6)に手を出し沼りました。 今回紹介する沼はシリアル通信です。 そのままではコンパイルを通りませんでした。

 今まで使ってたものはMbed OS 2でした。 よくサンプルがあるのはMbed OS 2を使ったものが多いため、 躓いた備忘録も兼ねて公開します。

試す際は自己責任で試してください。

シリアル通信

 Mbed OS 2のシリアル通信のサンプルコードは ライブラリをmbedos5,6にするとコンパイルが通らなくなります。 それぞれの原因を述べた後、サンプルコードを載せています。

OS5

問題点

 Serialクラスを使った従来のサンプルコードそのままで試すと実行中にエラーで止まりました。 シリアル通信の受信に使う関数getcあたりで止まっているのはほぼ確実そうです。 原因不明のためこのエラーは無視ししてアプローチを変えることにしました。

 そのため使えそうなクラスを探したところ、 RawSerialを使うとほぼそのまま移行できそうだったので試して成功しました。

 変更点は最初の宣言をSerialからRawSerialに変えただけです。 https://os.mbed.com/docs/mbed-os/v5.15/apis/rawserial.html

ソースコード

//リビジョンmbed-os-5.15.7
#include "mbed.h"
// Blinking rate in milliseconds
#define BLINKING_RATE_MS        
//シリアル通信の初期設定
RawSerial pc(USBTX, USBRX);//Serial->RawSerial
// Initialise the digital pin LED1 as an output
DigitalOut myled1(LED1);
DigitalOut myled2(LED2);
void pc_rx();
int main()
{
    //Start
    pc.printf("Start\r\n");  
    //シリアル通信の割り込み処理
    pc.attach(pc_rx, SerialBase::RxIrq);
    //Lチカ
    while (true) {
        myled1=1-myled1;
        myled1 = !myled1;
        ThisThread::sleep_for(100);
    }
}
void pc_rx(){
    myled2=1-myled2;
    //char getc=pc.getc();
    char getter;
    //読み取り
    getter=pc.getc();
    //頭文字に"re,読み取ったエコー"
    pc.printf("re:%c\r\n",getter);  
    return;
}

mbedos6

問題点

 OS5ではRawSerialクラスを使うことで解決しましたが、 OS6ではRawSerialクラスはなさそうなので別のクラスを使用しました。

 OS6は調べた限りシリアル通信のクラスが2つありましたが、 特に受信割り込みを使う必要があったためUnbufferedSerialクラスを使いました。

https://os.mbed.com/docs/mbed-os/v6.13/apis/unbufferedserial.html

 BufferedSerialクラスは割り込み処理に必要な関数attachがprivateで面倒だったので不採用です。

ソースコード

//リビジョンmbed-os-6.13.0
#include "mbed.h"
// Blinking rate in milliseconds
#define BLINKING_RATE_MS                                                    500
#define BUFFERDSIZE 5

static UnbufferedSerial *pc;

// Initialise the digital pin LED1 as an output
DigitalOut myled1(LED1);
DigitalOut myled2(LED2);
void pc_rx();
int main()
{
    char send[7]={'S','t','a','r','t','\r','\n'};
    //シリアル通信の初期設定
    pc= new UnbufferedSerial(USBTX, USBRX,9600);
    //Start
    pc->write(send,7);  
    //シリアル通信の割り込み処理
    pc->attach(pc_rx, SerialBase::RxIrq);
    //Lチカ
    while (true) {
        myled1=1-myled1;
        myled1 = !myled1;
        thread_sleep_for(BLINKING_RATE_MS);
    }
}
void pc_rx(){
    myled2=1-myled2;
    int err;
    char getter2[2]={'\r','\n'};
    //char getc=pc.getc();
    char send[3]={'r','e',','};
    char getter[10]={0,0,0,0,0,0,0,0,0,0};
    //読み取り
    pc->read(getter, BUFFERDSIZE);
    //頭文字に"re,"
    pc->write(send,3);  
    //読み取ったエコー
    pc->write(getter,BUFFERDSIZE);    
    pc->write(getter2,2);//改行
    return;
}

更新履歴

R30817 初稿公開