がじぇるね岡宮です。
#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(兼用端子の処理)
チョコです。
>2Mbps~3Mbpsがデフォルトのようです。
Mbpsですか、120MHzのRX65nならできそうですね。
32MHzのRL78で考えると、UARTの電気的特性には5.3M(MAX)とありますが、それは単にハードとしてのUARTの動作速度で、スタートビットの検出と動作マージンを考えると6倍程度のサンプリングでは不安があります。16倍程度で考えるとせいぜい2Mbpsが限度です…
岡宮さん、こんにちは。NoMaYです。あと、トラディショナルなやり方としては、以下のようなやり方ですね。(1) 多重割り込みを許可する(2) UART受信割り込みの割り込み優先度を上げるその上で、以下でしょうかね。(3) DTC+ここまでの話のリングバッファ+上記、の組み合わせでCPUサイクルの消費も抑えるなお、FreeRTOSに、Cortex-M、RX、PIC32、などではconfigMAX_SYSCALL_INTERRUPT_PRIORITY割り込み優先度という概念があって…
岡宮さん、こんにちは。NoMaYです。FTDIは専用のWindowsデバイスドライバですので、吸い上げ能力がWindows標準のCDCドライバより増強されている可能性もありますね、、、(ただ、そもそもESP8266からバーストで例えば256バイトとか送信されてくるものなら、受信リングバッファは256バイトは確保しておくのが安全/必要だと思います、、、WindowsはマルチタスクOSですので、タイムスライスが割り当てられていないタイミングでは書き込みツールはデータを吸い上げられないですので…
岡宮さん、こんにちは。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が触れるので、その点にはじゃんじゃんアプローチした方が良いのではないでしょうかと、思ったりとか思わなかったりとか、、、
そうですよね。やっぱりそう思われますよね。。
>受信で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で軽やかに」で盛り上がるとは思いませんでした。。
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ライブラリは今後も起点にしたいと思ってます)
>RL78のDTCやDMAでUART受信リングバッファを実装出来るだろうか?みたいなスレッドをそのうち書こうと思います。
バッファがオーバー・フローしない保証(受信より読出しが速い)があれば、簡単にできると思いますよ。オーバー・フローする可能性があるときは、DTC等の使用の有無によらずハンド・シェイクが必要でしょうね。
DTC等を使うと、受信によるバッファへの書き込みがハードになるだけです。バッファからの読出しは全てソフト処理なので、問題はデータ数の計算だけでしょう。これも、ソフト上のポインタとハードの格納用ポインタの比較だけで済むと考えられるので、それ程違いはないと思われます。
オーバー・フロー対策を考えると、DTCのリピートモードは使用しないで、そこで、割り込みを受けて、バッファの読出しポインタをチェックしてそのまま継続するか、オーバー・フロー対策を行うことになるかと思います。
DTCを使うと、受信のスループットが少し良くなるとは思います。
岡宮さん、こんにちは。NoMaYです。> RA+FSPで、割り込みによるリングバッファ送受信はできています。あぁっ、そういうことでしたか。素朴な割り込みによるリングバッファ実装で実際に発生していた問題があって、その問題がDTCによるリングバッファ実装により実際に解決された、ということでは無かったのですね。そうだとすると、私の予感としては、五分五分の確度で、懸念される問題の解決にはならないかも知れないかなぁ、という気がしました。(1) 例えば、2Mbpsですと約5μsに1つデータが到着しますので、FIFO無しUARTではその頻度で割り込み処理する必要があります(2) これが、4段FIFO付きUARTになると余裕が4倍になり、最悪約20μsに1度だけ割り込み処理出来れば取りこぼしは発生しません(3) 他の割り込み処理やデータ処理の排他制御の事情で(RTOSカーネル内のクリティカルセクションもこの範疇)、少なからずプログラムにはこういったUART受信割り込みを受け付けられない時間がありますが、そのデッドラインの余裕が4倍になるのです。(4) 他方、岡宮さんのプログラムでは、ひょっとして、以下の処理に許容される時間は5μsのままではないでしょうか?> DTCの場合、リピート転送が終わったときだけ、完了割り込みが発生し、ソフトで再スタートしないといけません(5) 5μsのままでも、64バイトのリングバッファとしたとき、上記の関門の発生頻度は1/64になりますが、逆にいうと、1/64までにしか減らないということになります。もちろん、取りこぼしがあったら再送要求するようなプロトコルを考えれば1/64は大きなメリットがありますけど、ASCIIテストデータなら容易に取りこぼしを認識出来るとしても、本番稼動時のバイナリデータとなると、取りこぼしの検出はそんなに容易では無いと思います。(6) 他方、デッドラインの時間の話の他に、割り込みの発生頻度が1/64になることで、割り込み処理に食われてしまうCPUサイクルが1/64になる、というメリットもあります。それで、ベステクさんが仰ったことの可能性としては、私は以下の2つのどちらかではないかと受け取りました。(A) タスクが多くなると総通信量が増え、素朴な受信割り込み処理の頻度も増え、受信割り込み処理にCPUサイクルが食われることが問題?(B) タスクが多くなるとクリティカルセクションでの割り込み禁止時間もそこそこ長くなり、例えば5μsのデッドラインを超えることが問題?そして、仰ったことの実際が(A)であればDTCはひとつの策になりそうですが、(B)であれば有効な策といえない(発生頻度が1/64に減るといったレベルでは心もとない)ような気がするのです、、、[追記]あぁっ、そうだ、受信オーバーランで簡単に検出出来ますね、、、(ちょっと、恥をかいてしまいました、、、)
チョコさん、こんにちは。NoMaYです。岡宮さんへのリプライとも被るのですが、以下の処理に許容される時間は、例えば2Mbpsだったとすれば、通常の受信割り込みでのデッドラインの5μsと同じですよね?実は、私は、このデッドラインを緩和することを唯一の目的(というか作業の成果というか)と考えていたので、受信でDTCが使えるのか?(≒受信でDTCを使っても成果は得られないのでは?)という私の発言になっていますね、、、> オーバー・フロー対策を考えると、DTCのリピートモードは使用しないで、そこで、割り込みを受けて、バッファの読出しポインタをチェックしてそのまま継続するか、オーバー・フロー対策を行うことになるかと思います。> DTCを使うと、受信のスループットが少し良くなるとは思います。
>私は、このデッドラインを緩和することを唯一の目的(というか作業の成果というか)と考えていたので、
そうですか。
マニュアルの説明を眺めていると、「D/Aコンバータを使ったサイン波出力」なんてあるので、プログラムの介入は必要ないならば、DTCのリピートモードでは割り込み禁止にしておくと、DTCはバッファの最後まで行くと自動的に先頭に戻り、転送を継続します。割り込みは禁止なので、CPUが介在することはないので、オーバーランしない限りはデッドラインはなくなるのではないかと思われます。
リピートモードでは割り込み禁止にしておくと、バッファの最後まで行ったときに割り込みが出ないので、必要なら、チェイン転送で別のチャネルの転送データで対応することも考えられます。そうすると、無駄な転送が増えて、スループットは下がりそうですが。
岡宮さん、こんにちは。NoMaYです。なお、なんというか、GR-ROSEにはRAMが640K載っていますので、バッファを10K確保してしまうなんていうことも可能ですので、頻度というかリスクというか、それを1万分の1に減らせるということでもあるので、そのレベルになると、GR-ROSEを使ったプロトタイピングという段階では、それもありかもなぁ、と今しがた思いました、、、
岡宮さん、こんにちは。NoMaYです。あと、トラディショナルなやり方としては、以下のようなやり方ですね。(1) 多重割り込みを許可する(2) UART受信割り込みの割り込み優先度を上げるその上で、以下でしょうかね。(3) DTC+ここまでの話のリングバッファ+上記、の組み合わせでCPUサイクルの消費も抑えるなお、FreeRTOSに、Cortex-M、RX、PIC32、などではconfigMAX_SYSCALL_INTERRUPT_PRIORITY割り込み優先度という概念があって、その割り込み処理内でFreeRTOS APIを呼ばないならば上記のトラディショナルなやり方がそのままやれるような機構が用意されています。手前ミソな話ですが、実は、私は今、FreeRTOSの公式ソースでは残念ながらRL78ではサポートされていない上記のconfigMAX_SYSCALL_INTERRUPT_PRIORITY割り込み優先度を多少なりとも扱えるようにFreeRTOSのRL78依存部を改造して、その改造結果を利用したサンプルプログラムを作成しているところなのでした。チョコさんのアドバイスのチェイン転送を活用してはどうかという可能性も追ってみますが、上に書いたやり方をまずサンプルプログラムにしてみようと思い始めたところです。(昨日、今日、のこのスレッドでイメージが沸いて来ました、、、)
NoMaYさん、こんにちは。GR-ROSEでは実は1024にしています。1024ぐらいにしないと、確かESP8266のフラッシュ書き込みができないことがありました。ただ、最新のESPの書き込みツールだとUSB側の処理が追い付いてない可能性があり、ちょっと課題のひとつなのですよね。。
#else /*__RX600__*/ #define SERIAL_BUFFER_SIZE 1024#endif/*__RX600__*/
追記:USBの可能性を疑ったのは、下段の構成に返るとフラッシュ書き込みがOKになるからです。
PC-(USBーSerial)ーESP ※NG
PCーFTDIー(SerialーSerial)ーESP ※OK
岡宮さん、こんにちは。NoMaYです。> GR-ROSEでは実は1024にしています。1024ぐらいにしないと、確かESP8266のフラッシュ書き込みができないことがありました。ESP8266への書き込みで受信リングバッファサイズを大きくしないといけないのは何か不思議ですね、、、書き込みツール側で書き込まれたデータが正しいか検証出来るように書き込まれたデータがリードバックされて来るとか?FTDIのFT232はUART側の受信データバッファサイズが384か512ではなかったでしたっけ、、、[追記]ちょっと不思議なところはありますが、デバッグの第一歩は、受信リングバッファオーバーフローか受信オーバーランか、はたまたどちらも起きていないのか、確認することでしょうか、、、
NoMaYさん、こんにちは
そうですね。GR-ROSEのRAMが大きいのでデバッグせずに増やしてしまったわけですが、やりたい優先度としては以下ですかね。結局GR-ROSE内部のバケツリレーが間に合っていないことが原因と思います(バッファを増やすとOKなため)。FTDI内のバケツリレーに負けているということなのですよね。。
①リングバッファのDMA/DTC化による割り込み占有率の低減
②USBの処理軽減(できるか自信ありません)
③シリアル送受信エラーのデバッグ
まぁでもESPのファーム書き換えだけのためにバケツリレーを早くするのは、全体としての優先はちょっと低く、どちらかというとROS2の次の世代のライブラリや、AWS IoTの最新版やAzure OSへの対応などの方が高いかなと思ってます。でもRAが楽しくなってきたのでどうしようかなぁとか。
岡宮さん、こんにちは。NoMaYです。FTDIは専用のWindowsデバイスドライバですので、吸い上げ能力がWindows標準のCDCドライバより増強されている可能性もありますね、、、(ただ、そもそもESP8266からバーストで例えば256バイトとか送信されてくるものなら、受信リングバッファは256バイトは確保しておくのが安全/必要だと思います、、、WindowsはマルチタスクOSですので、タイムスライスが割り当てられていないタイミングでは書き込みツールはデータを吸い上げられないですので、、、)あと、女房と畳は新しい方が良い、という辺りでしょうか?私は、あまたのCPUアーキテクチャが存在したことを知っている世代なので、あまりARMコアだから/Cortexコアだから、というので興奮しないのですよね、、、
はは、私もコアへのモチベーションはそんなにないのですが、これまでGR系でBluetoothの企画をやると純正コンパイラのリンクサイズ制限に悩まされてきたので、標準がGNUのRAはその辺を気にしなくてよい解放感に満ちているといった感じです。