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

All Replies

  • 岡宮さん、こんにちは。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は使えそうですが、受信データ数が前もって分からないので、バッファ・オーバー・ランの対策がどうなっているかが気になるところです。これは、スケッチの方の問題かもしれませんが、プロトコルでの対応ができないのは問題かも。

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

    基本的には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を使っても、格納したデータの管理(受信データ数の管理やデータの読出しポインタの管理)は改善できないのでは。

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

  • 岡宮さん、こんにちは。チョコさんも、こんにちは。NoMaYです。

    もし、RAマイコン+FSP+115Kbps UARTで素朴な割り込み処理によるリングバッファ受信が出来ないとしたら、原因はどこにあるのだろうか?というのも興味をそそられるトピックスですね、、、

    (1) RAマイコンのUSB機能が動作しているとしたら、その処理に長時間の割り込み禁止区間が存在しないか?
    (2) RAマイコンのセキュリティ機能であるTrusZone-Mが動作していて、それが割り込み応答時間を著しく劣化させている?
    (3) RAマイコン上でFreeRTOSが動作していて、それとTrustZone-Mの組み合わせだと、割り込み応答時間が著しく悪化してしまう?
    (4) FSPのリングバッファの排他処理にRTOSと相性の悪い箇所があって、USBタスクとの優先度の兼ね合いで、割り込み禁止時間が長期化することがある?

    あと、ベステクさんの話の件で思ったのですが、Arduino APIフォーマットを堅持するのもひとつの考えですが、もし、シリアルサーボで要求される仕様が以下のものであるなら、リングバッファを使わない実装も考えられるかもと思いました、、、

    要求仕様

    (A) パケットは、GR-ROSEから送信、サーボから返信、で一塊である
    (B) サーボからの返信の長さは、GR-ROSEから送信するコマンドに応じて、一意である
    (C) なので、1線式UARTとしてみても、((GR-ROSEから送信するコマンド)+(サーボからの返信))、の長さは固定長である

    もしそうであれば

    (a) Nバイト送信&(N+M)バイト受信の専用APIを用意すれば、素朴に簡単に固定長UART受信のDTCで対処可能かも

    チョコさん
    > >受信でDTCが使えるのか? 使えると思いますよ。単にリングバッファ処理と考えてしまえば、受信するデータ数は気にしなくていいはずです。
    > >「DTCで軽やかに」 データの転送にはDTCを使っても、格納したデータの管理(受信データ数の管理やデータの読出しポインタの管理)は改善できないのでは。

    RL78のDTCやDMAでUART受信リングバッファを実装出来るだろうか?みたいなスレッドをそのうち書こうと思います。今までもリングバッファ受信だけなら出来ると思っていたのですけど、単に受信しただけでは当然意味がなくて、受信したデータの読み出し処理(格納したデータの管理)が正しく出来るのかずっと気になっていて、今回の件が、きっと何かの縁なのだろう、という気がしたので、本格的に考えてみようと思い始めました。

  • NoMaYさん、こんにちは。

    すみません、ちょっと誤解が生じているかもしれませんが、RA+FSPで、割り込みによるリングバッファ送受信はできています。

    EK-RA4W1にはUSB Functionも出てなくて(出ていると思ったら普通のUART+FTDIで)、デバイス的にTrust Zoneもないです。ただ、今後RA6あたりでRoboticsも検討したいと思っていますが、通信で問題が生じたときに(1)~(4)の可能性は高くなるだろうと思います。そのときにDTC/DMAによる措置が活きてくると思い、今回半ば無理やりにDTCを使った(幸いFSPでの追加が楽だった)、ということになります。

    (a)に関しては、シリアルサーボは各社でプロトコルも違うため、各社ごとにAPI化しなくてはいけなくなるかもしれません。その辺がちょっと面倒ですね。ちなみにベステク様のドライバはレジスタ直でかなり最適化されたものを使用されていますので、Arduinoの話はGRだけです(それでもROSなんかはArduino向けのプラットフォームやサンプルも多いので、Arduinoライブラリは今後も起点にしたいと思ってます)