この記事について
LapisさんのLazuriteを、ちょっとイレギュラーな方法で遊んでみようと思います。
実用性はあまり考えてません。
筆者のところではLazurite 920J で試していますが、オリジナルのLazurite SubGHzの方もだいたいうまくいくかと思います。
記事は気長に段階的に更新していこうと思います。
まずは、LazuriteIDEの動きを観察してみる
そもそも、LazuriteIDEを そのまま使うつもりはない のですが、
どんな具合でコンパイラ等々を叩いてるのか、とか、焼き込みはどのコマンド使ってるのか、とかを見てみます。
IDEのフォルダ構成を眺める
デフォルトのインストール先は C:/LazuriteIDE/
になっています。
とりあえず、ここにインストールされている前提で話を進めていきます。
コマンドラインからビルドすることを前提に考えると、興味あるのは
bin/
hardware/
の2つのフォルダだけです。
bin/
文字通り実行のバイナリが入っています。
bin/直下には、
- bin_hex_converter.exe
- hexとバイナリの変換を行う
- lazurite_ft232_ctrl.exe
- FT232のGPIOピンを操作して、Lazuriteを書き込みモードに遷移させる
- XYM.exe
- XMODEM方式(懐)でバイナリをLazuriteに送信する
みたいな、主に書き込み関連のツールが入っています。
bin/U8Dev/
ツールチェーン一式が入っています。古めかしいIDEやICEのツールとかも入っているみたいですが、
使うことはないでしょう、
bin/U8Dev/Doc/
地味に大事なドキュメントフォルダです。
コンパイラとCPUの命令セットは入ってますが、何故かペリフェラル類のドキュメントが抜けてるので、
ML620Q503/Q504 ユーザーズマニュアル も一緒に
入れておくと良いかと思います。
hardware/lazurite_subghz/
主にソースが入っています。
hardware/lazurite_subghz/ml620q504/
ペリフェラル類のドライバです。微妙に下記のlazuriteのフォルダの中身と相互依存しています。
hardware/lazurite_subghz/lazurite/
Arduinoとだいたい互換のAPIの実装が入っています。オリジナルのArduinoのC++と違って
Cで実装しているので、使用感の似たAPIといった方が良いのかもしれません。
hardware/lazurite_subghz/sub_ghz/
Lazuriteの無線モジュール(bp3596)のドライバが入っています。
コンパイルするとワーニングがいっぱい出ます。
ビルドの動き
この辺りはわりあい素直で、LazuriteIDEのウィンドウに
実行しているコマンドラインが表示されるので、それを追っていくとだいたい理解できます。
- コンパイラ(ccu8),アセンブラ(rasu8)でcファイルからobjファイルを生成 (.c -> .asm -> .obj)
- objファイルをライブラリアン(libu8)まとめて、libファイルを生成 (.obj -> .lib)
- libファイルとobj(startup部分) をリンカ(rlu8)くっつけて、HEXファイルを生成
- HEXファイルをバイナリに変換
ここで実行しているような感じでコマンドを叩いてあげれば、
実行ファイルが出来そうな感じです。
書き込みの動き
書き込みもわりかしシンプルな動きです。ウィンドウにコマンドが表示されないので、
子プロセスの起動が見えるようなツールみたいなのを
使って、起動しているコマンドを追っかけて行きます。
- lazurite_ft232_ctrl.exe で TEST0,1端子を上げ下げして書き込みモードに。
- XYM.exeでファイルを転送
- lazurite_ft232_ctrl.exe で TEST0,1端子を上げ下げしてリセット
XMODEMを使ったファイル転送がレガシィな感じで素敵です。
この辺も、あまり特殊なことはやってなくて、素直にコマンド叩いているという感じです。
ビルドの方と合わせて、この辺のコマンドを実行すれば、
イメージの作成から、Flashへの焼き込み、実行ができそうです。
AWESOME toolchain
このLapis Semiconductorのu8向けコンパイラ、かなり癖あるというか、
とってもイカれたしたコンパイラです。
- C89対応、規格が古いのでgccでコンパイル通るコードで通らないものがいっぱい。
- 変数名やマクロ名に最大31文字の制限がある。
- LFNにちゃんと対応していない。DOS時代の8.3形式でないと受け付けないところがある。
ちょっと色々試してみると…
int test() {
return 1;
}
C:\Users\user>ccu8 /TML620504F test.c <--- これはOK
C:\Users\user>copy test.c test-function.c
C:\Users\user>ccu8 /TML620504F test-function.c <--- NG. ファイル名にハイフンが入ってると駄目
C:\Users\user>copy test.c testfunction.c
C:\Users\user>ccu8 /TML620504F testfunction.c <--- OK. ファイル名にハイフンが入ってなければ通る
C:\Users\user>copy test.c te-st.c
C:\Users\user>ccu8 /TML620504F te-st.c <--- NG. LFNでなくてもハイフンはNG
ファイル名のハイフンは駄目、だけど...
extern int test2();
#include "test-2.h"
int test2() {
return 2;
}
C:\Users\user>ccu8 /TML620504F test2.c <--- OK. includeで見るヘッダファイルでのハイフンはなぜか許される
なかなか奇怪な挙動です。
extern int test3();
#include "test3.h"
int test3() {
return 3;
}
C:\Users\user>ccu8 /TML620504F /Iincludedirectory test3.c <--- NG. /IはLFNを受け付けない
C:\Users\user>ccu8 /TML620504F /IINCLUD~1 test3.c <--- OK. 8.3形式のディレクトリ名ならいける。
/IにLFNは駄目。だけど、
C:\Users\user>copy test3.c longfilenametest3.c
C:\Users\user>ccu8 /TML620504F /IINCLUD~1 longfilenametest3.c <--- OK. ファイル名はLFNで通る。
/Iが駄目なら#includeはどうか?
#include "includedirectory/test3.h"
int test3() {
return 3;
}
C:\Users\user>ccu8 /TML620504F /I. test3x.c <--- OK. プリプロセッサのinclude文はLFNで通る。
文法で影響あるのは、シンボルの31文字制限.
char* lazurite_is_awesome_iot_platform() {
return "Lazurite is awesome iot platform.";
}
C:\Users\user>ccu8 /TML620504F test_longfunc.c
CCU8 C Compiler, Ver.3.41
Copyright (C) 2008-2013 LAPIS Semiconductor Co., Ltd.
test_longfunc.c
test_longfunc.c(1) : Warning : W3000 : Identifier truncated to 'lazurite_is_awesome_iot_platfor'
Error(s) : 0
Warning(s) : 1
途中で切られるので、
char* lazurite_is_awesome_iot_platform() {
return "Lazurite is awesome iot platform.";
}
char* lazurite_is_awesome_iot_platform_for_newbie() {
return "Lazurite is awesome iot platform.";
}
のような場合、
C:\Users\user>ccu8 /TML620504F test_longfunc2.c
CCU8 C Compiler, Ver.3.41
Copyright (C) 2008-2013 LAPIS Semiconductor Co., Ltd.
test_longfunc2.c
test_longfunc2.c(1) : Warning : W3000 : Identifier truncated to 'lazurite_is_awesome_iot_platfor'
test_longfunc2.c(5) : Warning : W3000 : Identifier truncated to 'lazurite_is_awesome_iot_platfor'
test_longfunc2.c(5) : Error : E4030 : 'lazurite_is_awesome_iot_platfor' already has a body
Error(s) : 1
Warning(s) : 2
重複定義で死にます。
シンボル名の制限は引っかかると手が打ちづらいです。
もっとも、これがOKでも他のところで色々ひっかかるところがあるので、
githubからコロッとソース持ってきてコンパイルして使う、というのはちょっと無理がありそうです。
LLVMのCBackendを使ってアレコレする
以下、後日更新。