Applilet EZ PL for RL78 V1.0J, V2.00J を試してみました。
デジタル回路版電子ブロックという感じで興味深いツールと思いましたが、少々使いづらい点もあったので改善要望として挙げておきます。
> 本ツールは評価版です。本ツールに関するテクニカルサポートは受け付けておりません。
と明記されていることは理解しており、返答等を求めているものではありません。
・作例 Lチカ
1185.knight2000.zip
10ピンの RL78/G10 をターゲットとして作成。Applilet EZ PL for RL78 V2.00 + CC-RL V1.04.00 の組み合わせで生成を行った結果、.map ファイルに出力される各セクションは
*** Mapping List *** SECTION START END SIZE ALIGN .vect 00000000 0000007f 80 0 .const 00000080 0000008f 10 2 .constf 00000080 00000080 0 2 .sdata 00000080 00000080 0 2 .option_byte 000000c0 000000c3 4 1 .security_id 000000c4 000000cd a 1 .textf 000000c4 000000c4 0 1 .data 000000ce 00000142 75 2 .text 00000143 00000a24 8e2 1 .RLIB 00000a25 00000a8a 66 1 .bss 000ffce0 000ffceb c 2 .dataR 000ffcec 000ffd60 75 2 .stack_bss 000ffd62 000ffda1 40 2 .sbss 000ffe20 000ffe28 9 2 .sdataR 000ffe2a 000ffe2a 0 2 *** Total Section Size *** RAMDATA SECTION: 000000ca Byte(s) ROMDATA SECTION: 00000113 Byte(s) PROGRAM SECTION: 00000948 Byte(s)
という結果となった。ROM の容量が 2kB を超えたため、R5F10Y16ASP では動作させることができない。内容的には単純なものであるためこの程度のものは R5F10Y16ASP で動作させたいところであり、省メモリ化でそれが実際に可能かを検証する。
検証その 1
1856.knight2000lite1.zip
makeprj.bat を以下の通り変更
.c をコンパイルする際に使用する *.pcc を以下の通り変更
リンクの際に使用する *.plk を以下の通り変更
以上の変更を行い makeprj.bat を実行してビルド行った結果、.map ファイルに出力された各セクションは以下の通りであり
*** Mapping List *** SECTION START END SIZE ALIGN .vect 00000000 0000007f 80 0 .const 00000080 0000008f 10 2 .constf 00000080 00000080 0 2 .sdata 00000080 00000080 0 2 .option_byte 000000c0 000000c3 4 1 .security_id 000000c4 000000cd a 1 .textf 000000c4 000000c4 0 1 .SLIB 000000c4 000000c4 0 1 .data 000000ce 0000013c 6f 2 .text 00000143 00000961 81f 1 .RLIB 00000a25 00000a8a 66 1 .bss 000ffce0 000ffceb c 2 .dataR 000ffcec 000ffd5a 6f 2 .sbss 000ffe20 000ffe26 7 2 .sdataR 000ffe28 000ffe28 0 2 *** Total Section Size *** RAMDATA SECTION: 00000082 Byte(s) ROMDATA SECTION: 0000010d Byte(s) PROGRAM SECTION: 00000885 Byte(s)
ROM の使用量が 201バイト、RAM の使用量が 72バイトそれぞれ削減された。
検証その2
6131.knight2000lite2.zip
検証その1 の内容に加えソースプログラムの冗長な部分に手を入れた。手法としては先に述べている部分も多いがその他、
以上の変更を行った。
結果、ビルド時に生成される .map ファイルに出力された各セクションは以下の通りであり
*** Mapping List *** SECTION START END SIZE ALIGN .vect 00000000 0000007f 80 0 .callt0 00000080 000000bf 40 2 .const 00000080 00000080 0 2 .constf 00000080 00000080 0 2 .data 00000080 00000080 0 2 .sdata 00000080 00000080 0 2 .option_byte 000000c0 000000c3 4 1 .textf 000000c0 000000c0 0 1 .RLIB 000000c0 000000c0 0 1 .SLIB 000000c0 000000c0 0 1 .security_id 000000c4 000000cd a 1 .text 000000ce 00000533 466 1 .bss 000ffce0 000ffce0 0 2 .dataR 000ffce0 000ffce0 0 2 .sbss 000ffe20 000ffea7 88 2 .sdataR 000ffea8 000ffea8 0 2 *** Total Section Size *** RAMDATA SECTION: 00000088 Byte(s) ROMDATA SECTION: 000000ce Byte(s) PROGRAM SECTION: 00000466 Byte(s)
最初のものと比べ ROM の使用量が約半分と、大幅なメモリ使用量の削減が達成できたと言える。R5F10Y16ASP でも十分動作させられるサイズに収まった。
Applilet EZ PL for RL78 のテンプレートとして提供されているソースファイルがメモリ使用量を重視して書かれていればこの程度のメモリ使用量の削減は可能な筈であり今後に期待したい。
※ 2017/05/29 cstart.asm に不具合があったので添付ファイルを更新
「検証その 1」の .map ファイルの出力を見てみると、NoMay さんの報告されてる「(3) 機能しないパターンその2」と同様の「謎の空隙(くうげき)」が出来ていることに気付いた。
リンクの際に使用している rlink.exe へのサブコマンド・ファイル knight2000.plk に
-STARt=.text,.textf,.RLIB,.SLIB,.sdata,.data/000ce,.dataR,.bss/FFCE0,.sdataR,.sbss/FFE20
を追加してビルドした結果、
*** Mapping List *** SECTION START END SIZE ALIGN .vect 00000000 0000007f 80 0 .const 00000080 0000008f 10 2 .constf 00000080 00000080 0 2 .option_byte 000000c0 000000c3 4 1 .security_id 000000c4 000000cd a 1 .text 000000ce 000008ec 81f 1 .textf 000008ed 000008ed 0 1 .RLIB 000008ed 00000952 66 1 .SLIB 00000953 00000953 0 1 .sdata 00000954 00000954 0 2 .data 00000954 000009c2 6f 2 .dataR 000ffce0 000ffd4e 6f 2 .bss 000ffd50 000ffd5b c 2 .sdataR 000ffe20 000ffe20 0 2 .sbss 000ffe20 000ffe26 7 2 *** Total Section Size *** RAMDATA SECTION: 00000082 Byte(s) ROMDATA SECTION: 0000010d Byte(s) PROGRAM SECTION: 00000885 Byte(s)
謎の空隙は解消した。
cstart.asm を小変更して 5バイト縮小。
6403.cstart.asm.zip
fujitaさん、こんにちは。NoMaYです。
;-------------------------------------------------- ; call main function ;-------------------------------------------------- CALL !_main ; main(); ;-------------------------------------------------- ; call exit function ;-------------------------------------------------- CLRW AX ; exit(0);_exit: BR $_exit
ここ↑を、こう↓しませんか?
;-------------------------------------------------- ; call main function ;--------------------------------------------------$IF (1) BR !_main ; main();$ELSE CALL !_main ; main();$ENDIF$IF (1)$ELSE ;-------------------------------------------------- ; call exit function ;-------------------------------------------------- CLRW AX ; exit(0);_exit: BR $_exit$ENDIF
オリジナルの cstart.asm から機能を変更しない方針で手を加えてましたが Applilet EZ PL for RL78 専用になら main() から終了しないのでその変更もありですね。
でもどうせなら mian.c から main() を削除して
$IF (1) ;-------------------------------------------------- ; Panel Initiate ;-------------------------------------------------- CALL !_panel_init0 ;-------------------------------------------------- ; Main Loop ;-------------------------------------------------- BR !_main_loop $ELSE ;-------------------------------------------------- ; call main function ;-------------------------------------------------- CALL !_main ; main(); ;-------------------------------------------------- ; call exit function ;-------------------------------------------------- CLRW AX ; exit(0); _exit: BR $_exit $ENDIF
としたいです。
思ったのですが、main()とmain_loop()に関しては、以下のような書き換え(main_loop()をmain()に埋め込んでしまう)も選択肢としてありそうだ、と思いました。(なお、それ以外の関数を埋め込まずにいるのは、main()とmain_loop()は共にmain.cに書かれた関数だが、それ以外は他のソースに書かれた関数だから、と言うところからです。)この選択肢だと、cstart.asmの終わりでCALL !_mainとする代わりにBR !_mainとするやり方でも同じ感覚のコードになるのではと思います。(あと、mainからリターンして来た時の為のCLRW AX / _exit: / BR $_exitも削れるということに変わりは無いです。)
void main( void ){ /* Panel Initiate */ panel_init0(); /* Main Loop */ while(1) { /* Panel proccessing */ panel(); /* Watchdog timer reset start */ WDT_Reset();#if !defined PWM_USED /* Processing at 10ms cycle */ if(TM_10ms()){ }#endif /* end of defined PWM_USED */ }}
よくよく考えてみると、自分的には、BR !_mainとするか更に手を打ってBR !_main_loopとするかはケースバイケースで良いかなという気がして来ていて、cstart.asmの終わりでCALL !○○○とする以外にBR !○○○とする手もあって、そうすれば、○○○からリターンした時の為のCLRW AX / _exit: / BR $_exitも削れるということを言えたから、それで良しかな、と思い始めました。ちなみに、もう1つ思ったのですが、CALLT命令が使えなくなった時点で、(確かに、機能は変更していない、とは言え、) オリジナルのcstart.asmとの比較では、「Applilet EZ PL for RL78専用」と言えるような様相を既に呈し始めている、ような気がしました。他方、マイコンのプログラムの実際のコードなら、大抵、上のソースのようにmain()の中(もしくはその下層)で処理を繰り返しているか、main()の最後(もしくはその下層の最後)でwhile(1){}やfor(;;){}によりリターンせずにいるか、の何れかでしょうし、exit()も、マイコンのプログラムの実際のコードでは使われることは無いでしょうから、「Applilet EZ PL for RL78専用」と表現するほど特殊なことでも無い、ような気はしています。
CALLT 命令は同一のサブルーチンを 3回以上それで呼び出さないとコードサイズを縮小させるには意味がないものであり、ROM のサイズが 1~4kB の RL78/G10 に CALLT のベクタが 32個予約されているのは無駄な気がしますが、何個使えれば十分かというのはプロジェクトに拠るものなので、CALLT テーブル領域をそれ以外の目的でどの程度使って良いかは判断が難しいです。
理想的には CC-RL のリンカに、CALLT テーブル領域やベクタ・テーブル領域の CALLT や割り込みのベクタで使用されない領域に、.data や .sdata セクションの全体や .text や .const セクションを部分的にでも配置して「可能な限り詰める」機能があれば良いですね。そうすればこういった悩みからも解放されます。
アセンブラで
MOVW HL,#MIRLW(STARTOF(.data))
と書けないのも残念なところです。これができないために cstart.asm がもう 2バイト縮小できません。
.VECTOR 疑似命令でジャンプ先に指定するラベルは .text セクションのものに限られるらしく、そのためにリセットベクタから一旦 .text セクションに飛んで更に BR !addr16 命令で .callt0 セクションに飛ぶという無駄なことをしていますが、これにより .text セクションを 3バイト無駄にしています。もうちょっとここいら辺りの制限がなくなると嬉しいのですが。
「可能な限り詰める」話(細やかな“セクションの全体"と“セクションを部分的に”の書き分けも重要な点だと気付きました)に関しては、別件のチョコさんのスレッドのマップファイルを見れば、きっとCC-RL開発部門の人もイメージが掴み易くなると思います。また、このスレッドの以前の投稿(私と藤田さん)でのCC-RLのリンカの SYmbol_delete が機能しないことがある件についても、もしCC-RL開発部門の人に見て頂けるなら幸いと思います。さらに、今回のcstart.asmでのBSSクリアコードやROMからRAMへのDATAコピーコードは将来のCC-RLのS1用cstart.asmに取り込まれると良いと思いますよね。また、(記述位置はCC-RL開発部門の人には賛否ありそうな気もしますが、) S1用cstart.asmを作成した時の修正漏れと思われる CALL !!_hdwinit の !! は ! にした方が良いですよね。(修正漏れだと感じたのは CALL !!_main の !! は ! になっていたからです、、、) (ちなみに、CS+のインストールフォルダを見ていて気付いたのですが、CS+\CC\Device\RL78\PG\Generate\RESETPRG\ がcstart.asmのテンプレートフォルダっぽい感じです、、、)