EtherCATマスターSOEMを.NETで使う

この記事は EtherCATについて語る Advent Calendar 2019 の11日目です。

昨日は@nonNoiseさんの EtherCAT開発方法 フレーム編(ライトまで) でした。

今日はオープンソースのEtherCATマスターであるSOEMをWindows上の.NETアプリで使う方法を解説します。

SOEMとは?

SOEMはオープンソースのEtherCATマスターである。WindowsMacOSLinuxなどに対応している。ビルドシステムとしてCMakeを用いる。

github.com

方針

  1. SOEMをDLL化するためAPIC言語で定義する
  2. CMakeを使ってDLLをビルドする
  3. DLLをラップするクラスをC#で作成する
  4. C#アプリで使う

f:id:licheng:20191210124119p:plain:w640

(1) SOEMをDLL化するためAPIC言語で定義する

まず、SOEMをDLL化して外部から呼ぶ出せるようにするため、APIC言語で定義する。soemlib.c という名前でソースファイルを作成し、必要なAPI関数を定義する。DLLのAPI関数の定義には、__declspec(dllexport) と __stdcall というキーワードを付ける。一例を以下に示す。

#include "ethercat.h"

__declspec(dllexport) int __stdcall soem_open(char* nif)
{
    int ret = ec_init(nif);
    return ret;
}

(2) CMakeを使ってSOEMのDLLをビルドする

Windows環境でのCMakeによるSOEMのビルド方法についてはまず以前の記事を参照。

SOEM/CMakeLists.txt の最後のほうに1行追加する。DLLのソースを置くサブディレクトリの追加である。親ディレクトリ名がlinuxになっているが気にしない。

if(BUILD_TESTS) 
  add_subdirectory(test/linux/slaveinfo)
  add_subdirectory(test/linux/eepromtool)
  add_subdirectory(test/linux/simple_test)
  add_subdirectory(test/linux/soemlib)     # ←この行を追加
endif()

SOEM/test/linux/soemlib/CMakeLists.txt を下記の内容で作成する。これがDLLをビルドするレシピである。add_library()で SHARED を指定することで共有ライブラリがビルドされる。Windowsでは共有ライブラリとはすなわちDLLである。

set(SOURCES soemlib.c)
add_library(soemlib SHARED ${SOURCES})
target_link_libraries(soemlib soem)
install(TARGETS soemlib DESTINATION lib)

(1)で作成したsoemlib.cを SOEM/test/linux/soemlib/ に置く。そしてCMakeによるビルドを実行する。ビルドが成功すると、SOEM/build/test/linux/soemlib/soemlib.dll が生成される。

(3) DLLをラップするクラスをC#で作成する

作成したDLLを.NETアプリから使うため、C#でラッパーを作成する。EtherCAT.cs という名前でソースファイルを作成しクラスを定義する。DLLが提供するAPI関数をC#で使うには、DllImport属性を使い、DLLファイル名とAPI関数名を指定する。一例を下記に示す。

using System.Runtime.InteropServices; // DllImport

(中略)
    // EtherCATラッパークラス
    class EtherCAT
    {
(中略)
        // 開く
        [DllImport("soemlib.dll", EntryPoint = "soem_open")]
        extern public static int open(string nif);

(4) C#アプリで使う

あとは作成したクラスを使った.NETアプリをC#で作成する。例として2個のEtherCATスレーブを接続してラジコンサーボの角度の指令とポテンショメータの角度の取得をおこなうアプリを作成した。


WindowsとArduinoでEtherCAT

ソース

この記事で作成したソースを下記に公開する。

github.com

EtherCATマスターSOEMをマイコンに移植する

この記事は EtherCATについて語る Advent Calendar 2019 の8日目です。

昨日は@nonNoiseさんの EtherCAT開発方法 概要編 でした。

今日はオープンソースのEtherCATマスターであるSOEMをOS無しのマイコンに移植する上でのポイントをまとめます。(本件の位置づけは上記の記事を読むと分かりやすいです。)

SOEMとは?

SOEMはオープンソースのEtherCATマスターである。WindowsMacOSLinuxに対応するほか、いくつかのRTOSにも対応しているっぽい。ビルドシステムとしてCMakeを用いる。

github.com

移植対象のマイコン

f:id:licheng:20191207215436p:plain:w640

今回は、Arduino Due + Ethernet Shield2を移植対象とする。SOEMはビルドシステムにCMakeを用いているが、マイコン用のクロスビルド環境の構築が面倒なので今回はCMakeは使わないことにする。すでに移植したソースを以下に示す。(注意:あくまで実験目的のものである。)

github.com

SOEMのソースのディレクトリ構造

  • soem: SOEM本体のソース
  • osal: OS抽象化層のソース。タイマやスレッドなどOSが提供する機能の抽象化。
  • oshw: ハードウェア抽象化層のソース。エンディアン変換やNICバイスの抽象化。
  • test: アプリケーションのサンプルコード。

各々について移植のポイントを以下にまとめる。

(1) soemの移植

(1.1) メモリリソースの節約

オリジナルのSOEMはワンチップマイコンで動作させるにはRAM使用量が大きすぎる。そのためターゲットのメモリ容量に合わせて以下の定数を小さくしてRAM使用量を減らす。

  • EC_MAXODLIST: CoEのオブジェクトディクショナリの数の上限 (※)
  • EC_MAXOELIST: CoEのオブジェクトエントリーの数の上限 (※)
  • EC_MAXSLAVE: スレーブの最大接続数
  • EC_MAXBUF: イーサネットフレームバッファの数

※ CoE = CANopen over EtherCAT プロトコル

(1.2) 時計

オリジナルのSOEMは時刻を使用する。ただし、ワンチップマイコンのシステムではリアルタイムクロックを持たないことや持っていても十分な精度を持たないこともある。今回はマイコン起動時からの経過時間をタイマでカウントして代用することにした。(たぶんこれによって何か不都合があると思われるが未調査。)

具体的には、ecx_configdc関数の処理を適宜修正する。

(1.3) LANポートの冗長構成の省略

オリジナルのSOEMは冗長構成のために2個のLANポートに対応している。しかし1個のLANポートしかないシステムの場合、無駄にRAMを占有されてしまう。そこでLANポートの冗長構成に関係する以下の変数と関数を削除する。

  • ecx_redportt構造体
  • ecx_init_redundant関数
  • ec_init_redundant関数

(2) osalの移植

(2.1) タイマと時計

タイマを抽象化する下記の関数をマイコンに合わせて実装する。

  • osal_usleep関数: usec単位で指定した時間だけ処理を止める。
  • osal_timer_start関数: usec単位でタイムアウト時間を指定してタイマを開始する。
  • osal_timer_is_expired関数: タイマがタイムアウトしたかどうかを返す。

また、時計を抽象化する下記の関数も実装する。ただし(1.2)で述べたように、今回はマイコン起動時からの経過時間で代用することにする。

  • osal_current_time関数: 現在の時刻を取得する。
  • osal_time_diff関数: 二つの時刻の差を返す。
(2.2) スレッド

タイマを抽象化する下記の関数をマイコンに合わせて実装する。ただし、SOEM自身はスレッド機能を使用していない。アプリケーション側でスレッドを使用しないなら未実装でも問題ない。

  • osal_thread_create関数: スレッドを生成する
  • osal_thread_create_rt関数: 優先度の高いスレッドを生成する
(2.3) デバッグ出力

デバッグ出力のための EC_PRINT関数を実装する。マイコンシステムの場合、デバッグ用のUART(シリアルポート)に出力するのが一般的である。
EC_PRINT関数はマクロで定義されており、EC_DEBUGマクロが定義されているときのみ有効となる。EC_PRINT関数の実体はprintf関数と同等の可変長引数を取る関数として実装する。printf関数が使える環境であれば #define EC_PRINT printf とすればよい。

(3) oshwの移植

(3.1) エンディアン (バイトオーダ)

Ethernetプロトコルはビッグエンディアンだが、CPUはビッグエンディアンのものもあればリトルエンディアンのものもある。そこでバイトオーダの違いを吸収するため以下の関数を実装する。

  • oshw_htons関数: 16ビット整数をCPUのバイトオーダからビッグエンディアンに変換する。
  • oshw_ntohs関数: 16ビット整数をビッグエンディアンからCPUのバイトオーダに変換する。
(3.2) ネットワークインターフェースの検索

利用可能なネットワークインターフェースを検索する下記の関数を実装する。ただし、マイコンシステムではネットワークインターフェースは既知のものに固定されることがほとんどであり、アプリケーション側でこの機能が不要なら未実装でも問題ない。

  • oshw_find_adapters関数: 利用可能なネットワークインターフェースを列挙する。
  • oshw_free_adapters関数: ネットワークインターフェースの列挙に使用したメモリを解放する。
(3.3) NICデバイスドライバ (ここが一番の難所!)

NICバイスを抽象化する以下の関数を実装する。

単一のNICバイスに対応 複数のNICバイスに対応 機能
ec_setupnic ecx_setupnic NICバイスを初期化する
ec_closenic ecx_closenic NICバイスを閉じる
ec_setbufstat ecx_setbufstat 受信バッファの状態を設定する
ec_getindex ecx_getindex 新しいフレームバッファを取得する
ec_outframe
ec_outframe_red
ecx_outframe
ecx_outframe_red
フレームを送信する
(ノンブロッキング)
ec_waitinframe ecx_waitinframe フレームを受信する
(ブロッキング)
ec_srconfirm ecx_srconfirm フレームを送受信する
(ブロッキング)
ec_setupheader 同左 Ethernetヘッダを生成する

ここが一番の難所であるが、以下に要点をまとめる。

(3.3.1) クリティカルセクション

クリティカルセクションを保護するため、OS環境であればミューテックス等を用いる。OS無しのマイコンシステムでも割り込みを使用するなら割り込み禁止/許可の処理が必要である。

(3.3.2) 冗長構成の省略

(1.3)で述べたように、LANポートの冗長構成を省略するのであれば、2個目のLANポートに関係する変数redportとredstateを削除し、これらの変数が使われている冗長構成の処理も削除する。

(3.3.3) ソケットのハンドル

WindowsMacLinuxなどのOS環境ではネットワーク通信はソケットを基本としており、生のイーサネットフレームの送受信にも「RAWソケット」を使用する。これをハンドルする変数がsockhandleである。しかし、マイコンシステムでとくにソケットをハンドルする必要がなければこの変数は使わなくてよい。

(3.3.4) Ethernetコントローラの制御処理の実装

ここが最も重要な部分である。Ethernetコントローラの初期化処理、終了処理、フレーム送信処理、フレーム受信処理を移植対象のハードウェアに応じて実装し、必要な箇所から呼び出す。

処理の内容 呼び出し箇所(nicdrv.c) 今回の実装例(SOEM.cpp)
初期化処理 ecx_setupnic関数 hal_ethernet_open関数
終了処理 ecx_closenic関数 hal_ethernet_close関数
フレーム送信処理 ecx_outframe関数 hal_ethernet_send関数
フレーム受信処理 ecx_recvpkt関数 hal_ethernet_recv関数

例えば、今回の例ではEthernetコントローラはEthernet Shield2基板上のW5500を用いるので、初期化処理は下記のようになる。

#include <Ethernet2.h>
#include <utility/w5500.h>

int hal_ethernet_open(void)
{
    w5500.init();
    w5500.writeSnMR(sock, SnMR::MACRAW); 
    w5500.execCmdSn(sock, Sock_OPEN);
    return 0;
}

(4) testの移植

アプリケーションのサンプルコードなので、適宜マイコンシステムの環境に合わせて移植して動作を確認する。特にslaveinfoとsimple_testで基本的な動作が確認できる。

デモ

最後に、今回取り上げたArduino Due版SOEMをマスターとするロボットのデモを下記に示す。

github.com

IoTつくるよ!でのEtherCATに関するFAQ

この記事は EtherCATについて語る Advent Calendar 2019 の4日目です。

昨日は@nonNoiseさんの EtherCATスレーブに使える半導体 (1) でした。

さて、11月30日(土)に開催されたIoTつくるよ!2に出展し、「ArduinoでEtherCATのデモ」を展示してきました。すこし場違いかと懸念してましたが、思いのほか反響をいただきました。

f:id:licheng:20191230111811j:plain:w480

よくいただいた質問と回答をここにまとめます。その場では正確にお答えできなかったものが多いです。スミマセン。帰ってから調べました。間違いがあったらご指摘ください。

Q1. 接続できるスレーブは何台まで?

EtherCATの規格では最大65535台までです。これは16ビットのアドレスでスレーブを識別するためです。

ちなみに、SOEMの実装ではデフォルトで最大200台までとなっています。これはスレーブを静的な配列変数で管理するというわりと残念な実装になっているためです。私がArduinoに移植したSOEMではRAM容量の都合で最大64台までに制約しています。

Q2. 通信周期は最速でどれくらい?

サイクルタイム(データ更新周期)は最小125usecとされます。EtherCATは100Base-TXEthernetにもとづいており、最大1518バイトのEthernetフレームを100Mbpsで伝送するには121.44usecを要するのでこれは理論限界に近い値です。

ただし1518バイトものフレームを使うことは実際には稀であり、扱うデータ量が少なければさらに短いサイクルタイム(最速で12.5usec)も実証されているそうです。 (こちらの記事を参照)

ちなみに今回の私のデモでは通信周期は実測で約1.3msecでした。かなり遅いですが、どこがボトルネックかは未調査です。

Q3. IPアドレスが無いってどういうこと?

私たちがふだんパソコン等でEthernetを使うときはたいていIPプロトコルを用いており、Ethernetフレームの上にIPパケットが載っています。IPアドレスというのはIPプロトコルにおける概念です。それに対してEtherCATではIPプロトコルとは異なるプロトコルを用いているので、IPアドレスという概念は存在しません。

ちなみにIPプロトコルではEthernetフレームのタイプ番号が0800hですが、EtherCATプロトコルではタイプ番号が88A4hです。

Q4. IPアドレスが無いならスレーブの識別はどうするの?

EtherCATはスレーブを数珠つなぎ(デイジーチェーン)に接続するので、マスターに近い方から順に1,2,3,…と番号を割り振ることができます。これをオートインクリメントアドレスと言います。物理的な位置にもとづくアドレスです。

マスターは起動時にオートインクリメントアドレスを用いて各スレーブと通信し、各スレーブに固定のアドレスを割り振ります。このアドレスをコンフィギュアドアドレスと言います。

ちなみに今回の私のデモはごく簡単なシステムのため、オートインクリメントアドレスだけを使って処理しており、コンフィギュアドアドレスは使いませんでした。「1台目のスレーブからポテンショメータの値を取得して、2台目のスレーブにサーボの角度を設定する」と言った具合です。

Q5. 距離はどれくらい届くの?

ノード間の距離は100m以内です。これはEtherCATの規格というより、100Base-TXの規格で規定されるものです。

ちなみに、今回のデモ展示用に長さ約10cmの短いLANケーブルを自作しましたが、LANケーブルは短すぎると良くないという噂を聞きました。理由が不明で、根拠となる規定も見つけられませんでした。真相はいかに?

Q6. PoE (Power over Ethernet) には対応するの?

EtherCATでは、従来からあるPoEとは異なる電力供給技術として、EtherCAT Pという規格を定めています。PoEは一般的なCAT5eのLANケーブルを用いて、48V, 15.4Wの電源を供給します。それに対してEtherCAT Pでは、独自仕様のケーブルを用いて、2系統の24V, 3Aの電源を供給し、これにEtherCATの信号を重畳します。

また、電力ケーブルと通信ケーブルを複合したこれまた独自仕様のケーブルにより、最大で630 V AC / 850 V DC, 64Aの電源供給とEtherCAT通信を「1本のケーブル」でおこなうことができます。

(見たことないから知らんけど。)

Q7. EtherCATはオープン規格なの?

オープン規格と言いつつ、仕様書をダウンロードするにはETG (EtherCAT Technology Group)に入会する必要があります。ETGへは無料で入会することができますが、法人でないと入会できないようです。

ちなみに私の所属する組織はETGメンバーではありません。つまり私はモグリです。

EasyCATのコンフィグ方法

EasyCATとは?

AB&T社が開発・販売しているEtherCATスレーブ基板の製品群。この記事ではおもに EasyCAT Shield for Arduino について述べる。その名の通り、Aruino用のシールドである。

EasyCATのコンフィグとは?

EasyCATは、出荷時には入力32バイト+出力32バイトのPDO構成にコンフィグされている。ソフトウェアからは各々32バイトのバイト列として参照できる。買ってきてすぐに使えるのでこれはこれでお手軽だが、ユーザーが自由にPDO構成を設計してEasyCATをコンフィグすることもできる。その場合、ソフトウェアからはPDOを構造体として参照できる。コンフィグ情報はEasyCATのEEPROMに保存される。

コンフィグのためのツール

EasyCATのコンフィグには、Easy Configuratorというソフトウェアを使用する。このソフトウェアはメーカーの製品ページで配布されている。ユーザーマニュアルも同ページで配布されているので、詳細はそちらを参照のこと。

  • Windows用アプリである。(Mac版やLinux版は存在しない。)
  • Ethernetインターフェース(LANポート)が必要。(EEPROM書き込みに用いる。)
  • Npcapライブラリが必要。 (こちらの記事を参照。)

標準モードとカスタムモード

EasyCATのコンフィグには、入出力が定義ずみの標準モードと、ユーザーが自由に設計できるカスタムモードがある。標準モードには入出力のバイト数が16+16、32+32(出荷時)、64+64、128+128の4種類がある。この記事ではカスタムモードのコンフィグ方法について説明する。

Easy Configuratorの起動

Easy Configuratorはインストール不要のアプリである。zipを適当なフォルダに解凍して使う。Exe/EasyCAT_Config_GUI.exeから起動する。

スレーブ識別情報

「SLAVE IDENTIFICATION」の欄に、スレーブの識別情報を記入する。

f:id:licheng:20191126160339p:plain

  • Vendor Id: ETGが割り当てた32ビットのベンダID。(※)
  • Vendor Name: ベンダIDを保有する会社名
  • Product Code: 32ビットの製品コード
  • Revision: 32ビットのリビジョン番号
  • Name: 製品名

※ 教育および実験の目的以外で使用する場合には必ず取得すること!

入出力PDOの定義

「INPUT PDO ENTRIES」および「OUTPUT PDO ENTRIES」の欄に入出力のPDOの名前と型を記入する。言ってはなんだが非常に編集しづらい。どうしてこんなク●UIになったのだろうか?

f:id:licheng:20191126160406p:plain:w600

プロジェクトの保存とファイル生成

メニューの[Project] > [Save as]でプロジェクトを保存する。そして「Create files」のボタンを押すと、プロジェクトのフォルダに以下の3つのファイルが生成される。

(1) .xmlファイル (ESIファイル)

EtherCAT Slave Information(ESI)仕様書で定義された、XML形式のテキストファイル。EtherCATスレーブの識別情報や入出力PDO構成など種々の情報を記述する。

(2) .binファイル (SIIファイル)

EtherCAT Slave Information Interface(SII)仕様書で定義された、バイナリ形式のファイル。EtherCATスレーブの識別情報や入出力PDO構成など特に重要な情報が格納される。EtherCATスレーブのEEPROMに保存され、デバイスのコンフィグに用いられる。

(3) .hファイル (C言語ヘッダファイル)

Arduinoなどマイコンファームウェアを開発するために必要なヘッダファイル。入出力PDOが構造体として定義される。

EasyCATのEEPROMへ書き込む

EasyCATに電源を入れて、EasyCATとPCをLANケーブルで接続する。EasyCATの「IN」のポートに接続し、「OUT」のポートには何も接続しないこと。ハブなどは使わず必ずケーブル1本で直結すること。

「Write EEPROM」ボタンを押すとファイル選択画面が開くので、生成した.binファイルを選択する。すると.binファイルがEasyCATのEEPROMに書き込まれる。書き込みには30秒くらいかかる。

Arduinoで使う

CUSTOM という名のマクロを定義してから、生成した.hファイルをインクルードし、その後に EasyCAT.h をインクルードする。

#define CUSTOM         // カスタムモード
#include "HogeSlave.h" // 生成したヘッダファイル
#include "EasyCAT.h"   // Arduino用ライブラリ
#include <SPI.h>

EasyCAT EASYCAT;

上記の例のPDO構成の場合、下記のようにしてアクセスできる。ちなみに、ユーザーマニュアルは入力と出力を取り違えていると思われる。PDOの入力/出力というのはマスターから見た表現である。

  // 出力(マスター→スレーブ)
  uint16_t a = EASYCAT.BufferOut.Cust.piyoOutput1;
  int64_t  b = EASYCAT.BufferOut.Cust.piyoOutput2;
  double   c = EASYCAT.BufferOut.Cust.piyoOutput3;
  
  // 入力(スレーブ→マスター)
  EASYCAT.BufferIn.Cust.piyoInput1 = (uint8_t)x;
  EASYCAT.BufferIn.Cust.piyoInput2 = (int32_t)y;
  EASYCAT.BufferIn.Cust.piyoInput3 = (float)  z;

日圧(JST)の圧着コネクタいろいろ

日本圧着端子(JST)の基板対電線用圧着コネクタのうちよく使うものを以下にまとめる。JSTのコネクタはやたらと種類が多くてメーカーのサイトを見てもよく分からないが、入手しやすく現場でよく使われるものをチョイスしたつもりである。(※わりと独断と偏見が混ざってます)

サイズの大きいものから順に挙げる。

シリーズ ピッチ 定格電流 定格電圧 適用電線
VH 3.96mm 10A 250V AWG#22~#16
NH 2.5mm 3A 250V AWG#30~#22
XH 2.5mm 3A 250V AWG#30~#22
EH 2.5mm 3A 250V AWG#32~#22
PH 2.0mm 2A 100V AWG#32~#24
ZH 1.5mm 1A 50V AWG#32~#26
SH 1.0mm 1A 50V AWG#32~#28

VH (3.96mmピッチ)

すごく大きい。電源など大電流が流れる箇所に使う。ピッチが広く足が太いためユニバーサル基板では使いにくいが、基板の穴を広げたり足を曲げたりして無理矢理挿し込んだりする。ケーブルを挿抜しやすくカチっとささる。すごく信頼感がある。

f:id:licheng:20191107204249j:plain

NH (2.5mmピッチ)

2.54mmピッチのユニバーサル基板に挿せる。(正確にはピッチが異なるが8ピンくらいまでならふつうに挿せる。)これは後述するXH、EHも同様である。昔はよく使ったが、今となってはかなり大型で邪魔になるのであまり使わない。挿抜はしやすい。

他のコネクタと異なり、お腹側(コンタクトが見える側)から見て右が1番ピンなのが紛らわしい。

f:id:licheng:20191107204534j:plain

XH (2.5mmピッチ)

小ピン数なら2.54mmピッチのユニバーサル基板に挿せる。たぶん2.5mmピッチのコネクタの中ではいちばんよく使われている。個人的には次に挙げるEHのほうが小さくて好みなのであまり使わない。特に厚み方向がかさばる。

f:id:licheng:20191107204554j:plain

EH (2.5mmピッチ)

小ピン数なら2.54mmピッチのユニバーサル基板に挿せる。2.5mmピッチでありながらかなり小型なので個人的には好みだが、やや抜きにくいのが欠点。XHやPHと比べてハウジングを掴みにくいので、ケーブルにテンションをかけずに抜くことが難しい。

他のコネクタと異なり、サイド型ポストに挿したときにお腹側が上向きになるのでピン番号に注意。

f:id:licheng:20191107204635j:plain

PH (2mmピッチ)

手ごろなサイズなのでいちばん汎用的によく使う。そこそこ小型で、かつエンジニアのPA-09とかの汎用工具でも圧着が難しくない。JSTの純正工具は数万円する。2mmピッチなので2.54mmピッチのユニバーサル基板では使えない。

f:id:licheng:20191107204653j:plain

ZH (1.5mmピッチ)

このあたりのピッチから汎用工具での圧着が難しくなる。とはいえ、JSTの純正工具は何万円もする。RSコンポーネンツで圧着ずみのワイヤーが売られている。近藤科学のサーボに採用されているが、ZHの定格電流は1Aなので明らかに定格を超えている。やれやれ。

f:id:licheng:20191107204710j:plain

SH (1mmピッチ)

基板を小型化したいときはこれを使う。汎用工具での圧着は困難。できたとしても信頼性に難あり。JSTの純正工具は十何万円もする。RSコンポーネンツで圧着ずみのワイヤーが売られている。ただしなぜか赤色のワイヤーしかない。圧着ずみワイヤーは高価なのでついピンセットで抜いて再利用しがちだが、著しく信頼性が落ちるのでやめて。ベース(ポスト)は表面実装タイプのみである。

f:id:licheng:20191107204759j:plain

Visual Studio Codeで がじぇるね の開発 (C++)

Visual Studio CodeGADGET RENESAS(がじぇるね)の開発をする裏技です。

  • GR-SAKURAとGR-CITRUSで確認ずみ。
  • Windowsで確認ずみ。Macでもたぶんできるはず。Linuxは未対応。
  • Arduinoベース(C++言語)での開発です。Rubic / mrubyではありません。
  • Visual Studio CodeArduino拡張機能Arduino IDEIDE for GRを使用します。
  • GR-KURUMI、GR-ROSE、GR-PEACHなどではエラーが出ます。これについては調査中です。
  • これはあくまで裏技です。うまくいかなくても自己責任でお願いします。

方針

がじぇるねにはIDE for GRというArduino IDEから派生したローカル開発環境があり、Arduinoベース(C++言語)での開発ができます。

まずこのIDE for GRに含まれるツールチェーン、プラットフォーム設定ファイル、ボード設定ファイルなどを本家のArduino IDEから利用できるようにします。これにより本家Arduino IDEで がじぇるね の開発ができるようになります。

あとは、VSCodeArduino拡張機能を利用すれば、VSCodeで がじぇるね の開発ができます。

手順

ツールのインストール

まずVSCodeArduino拡張機能、および本家Arduino IDEをインストールします。Arduino拡張機能については下記の記事を参考にしてください。

lipoyang.hatenablog.com

また、IDE for GRのzipを下記サイトからダウンロードして適当な場所に解凍しておいてください。

gadget.renesas.com

ファイルのコピー

解凍したIDE for GRのフォルダから、ドキュメントのArduinoフォルダにファイルをコピーします。ドキュメントのArduinoフォルダとは、Windows10では通常 C:/Users/ユーザ名/Documents/Arduino です。

まず、ide4gr-x.xx/hardware/arduinoフォルダを、名前を renesas に変更したうえで Arduino/hardware/ へコピーしてください。次に、ide4gr-x.xx/hardware/toolsフォルダを Arduino/hardware/ へコピーしてください。同名のフォルダが既にある場合、Windowsでは勝手に結合してくれますが、Macだとうっかりすると置き換えになるので必ず「結合」を選択してください。

ディレクトリ構造は下図のようになります。

f:id:licheng:20191026233650p:plain

platform.txt の編集

さきほどコピーした Arduino/hardware/renesasフォルダの下の各サブフォルダの中にある platform.txt を編集します。サブフォルダはプラットフォーム(マイコン種別)ごとに分けられており、下記のように各ボードと対応しています。

  • rl78g13 : GR-KURUMI, GR-COTTON, GR-ADZUKI
  • rx63 : GR-SAKURA, GR-CITRUS
  • rx64m : GR-KAEDE
  • rx65n : GR-ROSE
  • rza1h : GR-PEACH
  • rza1lu : GR-LYCHEE

ここでは GR-SAKURA, GR-CITRUS に対応する rx63/platform.txt の場合を説明します。他のプラットフォームの場合も同様なはずですが、前述のとおりいろいろエラーが出てうまくいきません。いっそ使わないプラットフォームはフォルダごと削除してもよいでしょう。

rx63/platform.txt を開くとツールチェーンのパスやオプションなどの指定が記述されています。この中で下記の3種類の文字列を書き換えます。テキストエディタの置換機能などを利用すればよいでしょう。

  • {runtime.ide.path}/hardware/tools
    {runtime.hardware.path}/../tools
  • {runtime.ide.path}/hardware/arduino/rx63
    {runtime.hardware.path}/rx63
  • -Ihardware/arduino/rx63
    -I{runtime.hardware.path}/rx63

実行

VSCodeで適当なスケッチのフォルダを開き、ボード選択で がじぇるね のボードが選択できることを確認します。(undefined)という表示はとりあえず無視します。

f:id:licheng:20191026234834p:plain

ボードを接続し、Ctrl+Alt+Uでスケッチをビルド/書き込みできることを確認します。

f:id:licheng:20191027105434p:plain

LPC111xマイコンのピン機能設定の注意点

LPC111xマイコンのピン機能は基本的にはGPIOがデフォであり、IOCONFIGレジスタのFUNC=0がGPIOとなっているが、一部そうでないピンがある。特に下記(2)の場合が要注意である。

(1) RESET, SWCLK, SWDIO

RESET, SWCLK, SWDIOのピン(PIO0_0, PIO0_10, PIO1_3)は、こちらの機能がデフォ(FUNC=0)となっており、FUNC=1でGPIOになる。これはまあ当然のことである。

(2) FUNC=0が予約となっているピン

PIO0_11, PIO1_0, PIO1_1, PIO1_2はなぜかFUNC=0が「予約」となっており、FUNC=1でGPIOになる。

LPCXpressoでのコード例

    // PIO0_1 は FUNC=0 が GPIO
    Chip_IOCON_PinMuxSet(LPC_IOCON, IOCON_PIO0_1, (IOCON_FUNC0 | IOCON_MODE_INACT));
    
    // PIO1_0 は FUNC=1 が GPIO
    Chip_IOCON_PinMuxSet(LPC_IOCON, IOCON_PIO1_0, (IOCON_FUNC1 | IOCON_MODE_INACT));