要は、mruby/c もわからんのに、IDEをつかうのがまずい?
ってのがあるので、本筋に従って、きちんとすすめてみるのが吉なのだね。
そもそも、ほかのマイコンと違って、ペリフェラルが可変のPSoCでは
PSoC Createrから切り離して、どうやってIDEするつもりだったのか
よくわからないって段階で、踏み込む必要がなかったわけだ。
先日の Embedded Technology 2019 で、某きむしゅさんから
rubyへの『愛がたらない』と言われたしなぁ(笑
てわけで、環境を構築してみる。
mruby/c チュートリアル
https://www.s-itoc.jp/activity/research/mrubyc/mrubyc_tutorial/
田中せんせのQiita
https://qiita.com/kazuaki_tanaka/items/daff64b84c4108a6dfc3
という二つのコースがあるけれど、田中せんせのやつは、
あとからみればしっくりくるけれど、最初にやると???となりそうなので
チュートリアルの1と2を、取り纏めながら進める。
PSoC Createrで PSoC5LPを選んで作り始める。
後々のために
-----
Project > Build Settings にて
ARM GCC -> Compiler -> General Use newlib-nano Float Formatting = True
にして実数利用を許容dwrのSystemタブで HeapSizeを0x400に拡張
-----
しておきます。
回路図入力で、Clockを1kHz で interrupt として取り出しておきます。
システムのTickとして利用するので、isr_mrbcTickと命名しました。
SouceFiles のところに
src
フォルダを追加しておく。
ファイルマネージャでソースファイルのフォルダに
mrubyc-release2.0 の srcフォルダをそのままコピーする。
フォルダ構成はこんなかんじですね。
-----
├─src
│ ├─hal_org
│ └─hal
└─TopDesign
-----
src フォルダ内の hal フォルダを hal_org にリネームして
hal_psoc5lp を hal にリネームする
PSoC Creator に追加作成した srcフォルダを選択したうえで
右クリックで、Add > Existing Item を選びます。
さきほど、コピーした srcフォルダ内のファイルをすべて追加します。
これで、準備完了ですね。
https://www.s-itoc.jp/activity/research/mrubyc/mrubyc_tutorial/735
に記載されている、mrubyc のサンプル をそのままつかいます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
led = 0 | |
while true | |
if led == 1 | |
led = 0 | |
else | |
led = 1 | |
end | |
if sw1_read() == 0 | |
led = 1 | |
end | |
led1_write( led ) | |
sleep 1 | |
end |
このコードを sample1.rb という名前で、
main.cのあるフォルダにコピーしておきます。
ついでに、mrbc.exe も ここにコピーしておきましょうか。
(ここでmruby IDEのなかのmrbc.exeをつかって悲劇を呼ぶのだが。。。)
cmdプロンプトから
mrbc.exe -E -Bsample1 sample1.rb
とすれば、 main.c とおなじフォルダに
sample1.c
が生成されます。
試しに sample1.c をエディタで開いてみると
こんなかんじになります。
どうやら、mrbc は mrubyのソースコードを バイナリの配列に入れてくれる
プログラムってわけですね。
試しに
mrbc.exe -E -Barry sample1.rb
とすると、 sample1.rb の中の配列名が
arry[] =
となることから
mrbcでの 引数 -Bの後の文字列が配列名であることはわかりますね。
で、PSoCのサンプルソースコードはこんなかんじになります。
躓き処が満載ではあるんだけど、いまはこれが全容かな。
mrbc_create_task( sample1, 0 );
の行で、タスクとなるmrubyコードが呼ばれるのはわかりますねぇ。
--------
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "project.h" | |
#include "./src/mrubyc.h" | |
#include "sample1.c" // mruby/c サンプルバイナリ | |
#define MEMORY_SIZE (1024*30) | |
static uint8_t memory_pool[MEMORY_SIZE]; | |
//================================================================ | |
// オンボードSW 現在状態の読み込み | |
static void c_sw1_read(mrb_vm *vm, mrb_value *v, int argc) | |
{ | |
int sw1 = SW1_Read(); | |
SET_INT_RETURN(sw1); | |
} | |
//================================================================ | |
// オンボードLED ON/OFF | |
static void c_led1_write(mrb_vm *vm, mrb_value *v, int argc) | |
{ | |
LED1_Write(GET_INT_ARG(1)); | |
} | |
//================================================================ | |
int hal_write(int fd, const void *buf, int nbytes) | |
{ | |
return 0; | |
} | |
int hal_flush(int fd) | |
{ | |
return 0; | |
} | |
CY_ISR(mrbcTick) | |
{ | |
mrbc_tick(); | |
} | |
int main(void) | |
{ | |
CyGlobalIntEnable; /* Enable global interrupts. */ | |
/* Place your initialization/startup code here (e.g. MyInst_Start()) */ | |
mrbc_init(memory_pool, MEMORY_SIZE); | |
isr_mrbcTick_StartEx(mrbcTick); // SYSTICKを実装 | |
mrbc_define_method(0, mrbc_class_object, "sw1_read", c_sw1_read); | |
mrbc_define_method(0, mrbc_class_object, "led1_write", c_led1_write); | |
mrbc_create_task( sample1, 0 ); | |
mrbc_run(); | |
return 0; | |
} |
--------
なんとなく、全容がみえてきた(≧▽≦)
さて、ここから、いろいろやってみましょうか。
mruby自体のデバッグってどうやるのか、とおもったら
PSoC Createrのデバッグ機能がつかえるから、
mrubyはタスクスイッチャとしてつかうのなら
おおむねデバッグはできそう。
さて、で、実際デバッグ実行してみると、うごかない。。。
はぁ?
ブレイクかけながら追いかけてみると、関数がよばれず、
そもそも mruby コードがうごいていない?疑惑浮上。。。
適当にブレイクかけながら試していると
class.c の mrbc_load_mrb関数内で mrubyのバイナリチェックを行う
static int load_header(struct VM *vm, const uint8_t **pos)
という関数がエラーを返している。
if( memcmp(p, "RITE0006", 8) != 0 ) {
となっていて、mrubyのバイナリバージョンが 0006 であることを
想定しているけれど、
今回得られてる、sample1[] の内容は
0x52,0x49,0x54,0x45,0x30,0x30,0x30,0x34 = RITE0004
だから、はねられてる、ってとこかな。
は! そうか! mrbc コンパイラが生成するバイナリ自体もちがうのか。
そんなんしらんがな。
なるほど、サイトをよくみると、
mruby Stable版v2.0.1 Windows版(コンパイル済バイナリ)
「mrubyコンパイラ2.0」(ZIP:1.5MB)
が必要なのね。
これで、再度mrbcかけて、再コンパイルしたら、うごいた!
Lチカ! 完了。
ううむ。そういうことなら、気色わるいので
mrbcフォルダをつくって、そのなかに、mruby Stable版v2.0.1一式を解凍して
mrbc.bat だけを、ソースフォルダのなかに置いた。
フォルダが変わったので、このbatファイルの中で
set MRBC=.\mrbc\mrbc.exe
に変更したけれど。
これで、コマンドプロンプトから
mrbc
ってやるだけで、rbファイルが一括コンパイルできるようになったよ。
しかし!。
まぁ、もうちょっと、わかりやすく手順を説明してほしいなぁ。サイトも統一感なさすぎる。
なるほど、こりゃ流行らんよねぇ。。。
<つづく>