EK-RA4W1 で Arduinoスケッチ

がじぇるね岡宮です。

#2021/4/19 Wire, SPI, pinModeの修正をしました

ちょっと趣味も兼ねてRAを触り初めまして、EK-RA4W1用にArduinoスケッチができるプロジェクトを作ってみました。FSP上で実装していますが、ピンが競合するとコード生成できない部分もあり、まだ最小構成の実装です。ご興味あればお使いください。

本来はUSB一本でフラッシュ書き込みとシリアルモニタをできるようにしたいところですが、J-Linkの方はRTT Viewerなるもので入出力するで、ソフトの起動とか煩わしいので、もう一本のUSBでSerialが扱えるようになってます。なので、書き込みとシリアルモニタを行う場合はmicro USBが2本必要です。

スケッチは今のところe2studioでのみ行えます。以下はイメージです。

以下、簡単な手順です。

1. 以下のzipをダウンロードしてください。

ra4w1_sketch_20210419.zip

2. zipをアーカイブファイルとしてインポートしてください。

3. プロジェクトルートの "configuration.xml" を開きコード生成を行って下さい。

4. arduinoフォルダ内の"sketch.cpp"を開いてください。このファイル上でArduinoスケッチができます。デフォルトサンプルはLチカとHelloが出力されるものです。Tera Termなどを使ってシリアル出力が確認できます。

5. ビルド後、デバッガ接続してダウンロードし、RUNしてください。この辺は普通の操作なので詳細は省きます。

デフォルトサンプルでは以下のようにHelloが出力されます。Serialの受信にはDTCを使っているので、結構軽やかに動くとは思います。FSPが殊の外簡単だったのでやってみました。

 

今のところ以下を実装してます。

- digitalWrite

- digitalRead

- analogWrite (ピン3, 5だけ対応してます。その他はSPIと競合したり、諸々のFSPの仕様でその他のピンはやめました)

- analogRead (ピンA4, A5にはアナログ端子がデフォルトの回路でつながってないので実装してません)

- attachiInterrupt (ピン2だけ実装してます。ピンが競合すると出力できないので。ピン2はユーザスイッチとシェアされてます。割り込み番号0で両方のピンが活性化されます)

- Serialクラス (Serial はUSB、Serial1はピン0, 1です)

- SPI class

- Wire class

このArduinoライブラリと一緒にBLEスタックのサンプルが動くことは確認済みですが、BLEのサービスをどう実装しようか迷っており、実装していません。

[Updates]

-2021 April 19: IICを修正(タイムアウト)、SPIを修正(通信完了処理)、PORT(兼用端子の処理)

Top Replies

Parents
  • 岡宮さん、こんにちは。NoMaYです。

    > Serialの受信にはDTCを使っているので、結構軽やかに動くとは思います。
    > FSPが殊の外簡単だったのでやってみました。

    受信でDTCが使えるのですか?ひょっとして送信の間違いとか??

    > このArduinoライブラリと一緒にBLEスタックのサンプルが動くことは確認済みですが、BLEのサービスをどう実装しようか迷っており、実装していません。

    私は、RAマイコンではなくて、RXとRL78ですが、TB-RX23WとRL78/G1D BLE Module Expansion Boardを買い込んでいるものの、CC-RXとCC-RLのサイズ制限によりBLEに全く触れないのでした。(なので開封もしてなかったり、、、それは承知の上で、いつか自分で何とかしようかな、と思いつつ買ったものではあるのですが、積基板の仲間入り状態ですね、、、) それに対し、EK-RA4W1はGNUARMでBLEが触れるので、その点にはじゃんじゃんアプローチした方が良いのではないでしょうかと、思ったりとか思わなかったりとか、、、

  • NoMayさん、いつもお世話になっています。

    >受信でDTCが使えるのですか?ひょっとして送信の間違いとか??

    受信だけDTCを使って、リングバッファを構成してます。送信については、ArduinoのSerial.writeは同期処理で行われるのでDTCにしてもあまりうまみがないのでやめました。サンプルが動かないとかもありますので。

    >EK-RA4W1はGNUARMでBLEが触れるので、その点にはじゃんじゃんアプローチした方が良いのではないでしょうかと、思ったりとか思わなかったりとか、、、

    そうですよね。やっぱりそう思われますよね。。

  • チョコです。

    岡宮さん、お久しぶりです。

    >送信については、ArduinoのSerial.writeは同期処理で行われるのでDTCにしてもあまりうまみがないのでやめました。サンプルが動かないとかもありますので。

    DTCの起動条件は送信完了の割り込みでしょうから、そのときに次の送信データがない(バッファ・アンダー・ラン)とかの対応ができないからじゃないですかね。送信にDTCを使うなら、ブロック単位での送信だけじゃないと無理でしょうね。

    受信なら、受信データを取りこぼさないためのDTCは使えそうですが、受信データ数が前もって分からないので、バッファ・オーバー・ランの対策がどうなっているかが気になるところです。これは、スケッチの方の問題かもしれませんが、プロトコルでの対応ができないのは問題かも。

Reply
  • チョコです。

    岡宮さん、お久しぶりです。

    >送信については、ArduinoのSerial.writeは同期処理で行われるのでDTCにしてもあまりうまみがないのでやめました。サンプルが動かないとかもありますので。

    DTCの起動条件は送信完了の割り込みでしょうから、そのときに次の送信データがない(バッファ・アンダー・ラン)とかの対応ができないからじゃないですかね。送信にDTCを使うなら、ブロック単位での送信だけじゃないと無理でしょうね。

    受信なら、受信データを取りこぼさないためのDTCは使えそうですが、受信データ数が前もって分からないので、バッファ・オーバー・ランの対策がどうなっているかが気になるところです。これは、スケッチの方の問題かもしれませんが、プロトコルでの対応ができないのは問題かも。

Children
  • チョコさん、ご無沙汰しております。コメントいただきありがとうございます。

    基本的にはArduinoのソースに合わせているのですが、UART送信は1バイトずつで、送信→送信完了割り込み→次のバッファ送信を繰り返し行い、リングバッファのtailがheadに達したらお終いという実装です。この一連の処理がwhile内で行われるため、ブロッキング処理になってます。この実装だとアンダーランは生じません。Arduinoは他の処理が並行して実行しているという前提になっていないので、世の中のサンプルも基本はブロッキング処理前提になってます。ちょっとチョコさんのご指摘の答えになっているか分からないのですがそんな感じです。なのでDTC使いませんでした。

    オーバーランはどうでしょうね。まだ私もDTCの場合のエラー処理は把握してませんが、1Mbps程度までではオーバーランが発生するケースはそれほどない印象です。むしろArduinoの受信リングバッファは64バイトと小さめで、処理しきれない場合は無効になる仕様ですが、こちらの方が問題になるケースが多い印象です。不定期で不確定なサイズの受信といえば、ESP8266とかのWi-FiでHTTPのGETをしたときなど、サーバーの応答によるのですが、バッファ処理してる間にバッファが溜まっていってしまう方が問題になる気はしてます。Arduino UNOは8ビット 16MHzですから、その点RXとかRAではそこまで問題が顕在化するわけではないのですが。(逆に言えば、そのぐらいのCPU性能でも色々チャレンジする熱狂的な人が多いのはすごいと思ってます)

    色々長々書いてしまいました。UDPみたくエラーが起きても受信してから考えるみたいな感じがArduinoの実装ですね。

  • チョコです。

    早速のレスありがとうございます。

    ベアメタル型の処理ばかりやってきたので、Arduinoのシングル・タスク型プログラミングは不安でしょうがないですね。慣れのせいでしょうが、いろんな割り込みに処理を分割して、メインでは大きな流れしか処理しなくてもいいようなことが多かったからでしょうかね。

    元が(今も)ハード屋なので、Serial(調歩同期通信)では、ハードウェアのハンドシェイクか最低でもソフトウェアでのハンドシェイクを組み込むことを考えてしまいます。

    >むしろArduinoの受信リングバッファは64バイトと小さめで、処理しきれない場合は無効になる仕様ですが、

    これをバッファ・オーバー・ランと表現したのですが。Arduinoでのエラー処理が甘いのは気になってはいるところです。もっとも、エラー処理を増やすとプログラムが複雑になります。結局何を主な目的にするかでしょうね。

    以上

  • チョコさん、なるほど、まさにおっしゃる通りと思います。ELC、SnoozeなどRL78の細かい配慮がそこに凝縮されていると思いますし、コスパでシェアを獲得してきた所以と思っています。

    >結局何を主な目的にするかでしょうね。

    そうですね。

    Arduinoはデザイナとかプログラムに無縁な人をターゲットに電子工作の幅を広げてくれた印象があります。そこから高性能、省電力、周辺などの多様性が増し、標準のArduinoライブラリから色々な派生が出てきました。GR-KURUMIなんかもdelayでsnoozeやstandbyに入るなど工夫しましたが、ニーズを知る上でまずは使ってもらうという点ではArduinoはよい入口になっていると感じてます。反面、データシートを読まないでソフトのAPIだけで使いたい人も増えている訳なんですが・・・(私もその1人なのですが)

  • ちなみに、Serialの軽やかさという点では、以下のようなブリッジコードを書いて、

    void setup(){
    Serial.begin(115200);
    Serial1.begin(115200);
    }

    void loop(){
    if(Serial.available()){
    Serial1.write(Serial.read());
    }
    if(Serial1.available()){
    Serial.write(Serial1.read());
    }
    }

    以下のような300バイト(+α)をテキストコピーしてTera Termに貼り付けたき、ズバッと正確にオウム返しされたら結構な軽やかさと考えてます。これは当然ボーレートが早くなるほど条件が厳しくなるのですが、通信相手方のボーレートに合わせてこのテストをすればほぼ大体問題なく送受信ができます。DTCの場合、リピート転送が終わったときだけ、完了割り込みが発生し、ソフトで再スタートしないといけませんが、そのオーバーヘッドさえ乗り越えられればOKって感じです。

    0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
    0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
    0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789

  • チョコです。

    確かにこの程度のloop処理だと、速いでしょうね。

    ところで、Serial1も通信速度は115200ボーですよね。違っていたらバッファの制御がめんどくさいし、そのうちには、遅い方のバッファがあふれます。

    個人的には、割り込み処理をアセンブラで記述し、SFRを直接いじって的なプログラムでバックグラウンド処理を行うかもしれません。

    >DTCの場合、リピート転送が終わったときだけ、完了割り込みが発生し、ソフトで再スタートしないといけませんが、

    RL78G14のDTCしか使ったことはありませんが、リピートモードはソフトでの再スタートは必要なかったのでは?リピートモードの説明に「• リピートモード割り込みは禁止」と書かれています。

    そもそも、115200程度だと、ソフト処理でも(DTCなしでも)十分に間に合うはずですが。

  • チョコさん、失礼しました。Serial1.begin(115200)の一行足りてなかったので、修正しました。

    私はRL78のDTCを使ったことがないのでリスタートが必要かどうか分かりませんが、RAのFSPを使った感じではリスタートが必要でした。もしかしたら割り込みなしでリスタートをする方法が他にあるかもしれません。

    >個人的には、割り込み処理をアセンブラで記述し、SFRを直接いじって的なプログラムでバックグラウンド処理を行うかもしれません。

    ・・・私は真似できないです

  • 岡宮さん、こんにちは。NoMaYです。

    受信でDTCが使えるのか?(もっと正確に書くと、固定長受信でDTCを使うのは困難は無いけれど、リングバッファ受信での実装にDTCが使えるか?(割り込み応答に要求される時間は緩和されるか?リングバッファへの書き込みと読み出しが錯綜するような状況でも安全に処理出来るのか?))という気になる点の他に、実はもうひとつ気になる点もあったのでした、、、

    GR-SAKURAやGR-KURUMIでは、DTCを使わずとも、素朴な割り込み処理によるリングバッファ受信で軽やかに動いていたのではなかったでしたっけ、、、(最初の投稿以後のものを読むと、RAマイコン+FSPでは無理だったからDTCを使い始めたのだろうか?、という印象を強く持つようになったのですが、、、)

    [追記]

    すみません、GR-SAKURAは100MHz動作なので、その分、余裕があった、とも考えることは出来ますけれどね、、、

  • チョコです。

    >受信でDTCが使えるのか?

    使えると思いますよ。単にリングバッファ処理と考えてしまえば、受信するデータ数は気にしなくていいはずです。

    115200ボーだと、87μs/1キャラクタ程度なので、殆どの処理方法でできるはずです。

    GR-KURUMIはRL78/G13だったので、DTCはありません。その代わり、もっと高速(機能は限られる)のDMAがありますが。

  • NoMayさん、するどいですねぇ。これまでGRはDTC/DMAを使ってこなかったのですが、GR-ROSEでベストテクノロジー様が派製品を作ってくださったときに色々と教えていただきました(検証もしていただきました)。私はそこまで詳しくないので詳細には説明できませんが、ちょっと書きます。

    ヒューマノイドとか20軸ぐらいのシリアルサーボを制御するとき、1ms内で数パケットこなすぐらいのイメージで、2Mbps~3Mbpsがデフォルトのようです。そういった中でFreeRTOSのようなタスクスイッチの割り込みが絡むと、タスクを増やすにもシリアルの割り込みの影響が大きくなってくるため、DMAやDTCでFIFO処理をする、ということになります。このときUARTにFIFOがあれば緩和されるのですが、RXもFIFOを積んだUARTが少なく、実際GR-ROSEはFIFO付きUARTをシリアルサーボライン(4ライン+RS485 1ライン)にはアサインしてませんでした(もうちょっと言いますとシリアルサーボ専用でなく、通常の全二重と切り替えられるよう、オープンドレイン出力になっているため、それほどボーレートを上げられない事情もありました)。少し話が逸れましたが、GR-ROSEは次のアップデートでDTCかDMAでのシリアル処理を入れようと考えていましたが、まだ実施していません。DMAのチャンネル数はマイコンに依存するため、他への展開を考えるとDTCの方がよいのですが、DMAの方が設定が簡単なため(DTCはテーブルをどこに置くかちょっと考えるのが面倒なだけですが)、GR-ROSEではDMA 5チャンネルを使おうと考えていたところでした。

    色々とコメントいただきありがたいです。「DTCで軽やかに」で盛り上がるとは思いませんでした。。

  • チョコです。

    >2Mbps~3Mbpsがデフォルトのようです。

    Mbpsですか、120MHzのRX65nならできそうですね。

    32MHzのRL78で考えると、UARTの電気的特性には5.3M(MAX)とありますが、それは単にハードとしてのUARTの動作速度で、スタートビットの検出と動作マージンを考えると6倍程度のサンプリングでは不安があります。16倍程度で考えるとせいぜい2Mbpsが限度です。

    >「DTCで軽やかに」

    データの転送にはDTCを使っても、格納したデータの管理(受信データ数の管理やデータの読出しポインタの管理)は改善できないのでは。

    ハードが絡むと、ついつい...