遅ればせながら。

AEのESP-WROOM-02モジュールを動かしています。

 

開発環境はいろいろあるらしいのだけれど、厳しくレスポンスを要求されるような使い方はしないだろう、ということでlua(NodeMCU)を書き込んでみました。書き込んでインタープリタを起動する迄の扱い勝手は数年前に遊んだH8/Tiny(こちらは自作BASICだが)と変わらない印象です。

 

しかしまあ、あれだ。

 

身の回りでIP網に組み込みたいモノ、というのがすぐに思いつかないのが辛い。

 

 

取り敢えずブレボに載せた。タクトスイッチは飾りです、偉くなくてもそのくらい解ってください。

LinuxMint (amd64)に移行してから、gcc(h8300-hms)をうまくビルドできず、別途32ビット環境を用意してクロス環境を構築したりしていたのですが、今ひとつ使いにくくてそのままにしていました。

 

で、懲りずにもう一度64ビット環境下での構築を試みていたのですが、やはり途中で発生するエラーを解決できませんでした。

仕方ないのでh8300用にPCを1台用意しようかと思ったのですが(何せ現在中古PCは激安なので)、ソースファイル等の管理の煩わしさを考えると完全に物理的に切り離してしまうのもイマイチだなあ、と。

 

そこで、LAN内のサーバー上に構築してみることにしました。サーバー、と言っても普通のPCからディスプレイとキーボードを取り外しただけで、日頃はファイル置き場とネットラジオを聴くくらいにしか使っていません。

サーバーのCPUはAtom、OSはSlitaz(32bit)です。SlitazはリポジトリにH8のツールも用意されているのですが、h8300hn(H8/300Hノーマルモード、ターゲットにしているH8/300H Tinyの動作モード)のコードがなかったりすると嫌なので(ubuntuのパッケージがそうでした)自前で構築しました。

 

卓上で常用しているPC(Thinkpad R500、以下R500)にnfsで繋いでシンボリックリンクでパス名を調整して、プロジェクトをR500から調整してもサーバー側(VNC経由)から編集しても齟齬のないようにしました。厳密にはパーミッションの問題が残っていますが...

 

nfsで卓上に引っ張ってきているのはターゲットへの書き込みにUSB-RS232C変換ケーブルを使うからで、流石にこんなのをサーバーに繋ぎっぱなしにするのは如何なものかと。ftpでいちいち持ってくるのも一手ではありますが。

 

IDEにはGeanyを使っています。軽いだけが取り柄ですが。コマンドラインオプションで、設定の参照先を切り替えることが可能ですので、Xfceのデスクトップ上にランチャーを出しておけば使い勝手が良くなります。

サーバーへのアクセスをVNCではなくリモートシェルにして、手元の開発環境(軽いだけが取り柄のGeanyです)に組み込んでしまえば、リモート環境であることを意識せずに開発できるのですが、それは今後の課題ということで。


 

FORTH の話の続き

fig にアクセスして、参考になりそうな処理系をダウンロードしました。Gforth(GNU forth)とgraspforth という、両方共既存のOS上で実行可能なものです。例によって実行環境はPuppyLinux571JP、ソースを展開して適当に./configure なり make なりします。

Gforth を起動したところ


組み込みワードを表示してみる。(VLIST)

既に1画面に収まっていません。うーむ、これを全て覚えて使いこなす人がいるのだろうか?

続いて graspforthを試す。

俺の知っている forth と違う、かも知れない。


作ったほうが早いな。
 

H8/300H(3694)で浮動小数点計算する話の続き。

実数をサポートしたBASICインタープリタとかをGCC(※)で書くのはどうもメモリ不足(RAMだけでなくROMも)を引き起こしそうな気がしてきました。16ビットCPUがこれほどまでに効率が悪いなんて、パソコンとして使っている時には全く意識しませんでしたね。
とはいえ多少なりとも実用的な計算機に仕上げようとすると、何らかの処理系を載せたいところではあります。
BASICがダメならFORTHはどうよ?となりますが、一口にFORTHといってもFIGにANSI,それとGNUにも仕様があるらしい。きちんとした、即ち単体で対話操作及びコンパイルが可能でOSとしての機能も併せ持つものを書こうとすればそれなりに大変ではあります。
まあ、今回は計算ができればいいので、適当に仕様をでっちあげて「俺FORTH」を書いても問題ないのですが。
どうせGCCで書くんだし(お


※ルネサス(というか日立)のコンパイラを試したことがないのでGCC明記してます。

『だぼぅ!』よりも『えっさほい』(RAM容量的な意味で)を優先するのが定石、そして動かしているうちに『すぴーだっ!』(MPUクロック的な意味で)したくなる、だろう多分。


H8/300H(3694)に関する何かの続き。

LCDを接続しましたので、キーボードも繋いでポケットコンピュータでも作るか?と思ったのですが、その前に浮動小数点計算を解決しなくてなりません。16ビットMPUなのに電卓未満の実用性、とか言われたくないし。

ということで、早速やろうとしたのですが。

私が使っているh8300用gccはdebian/ubuntu に用意されているものではなく、自分でビルドしたものです。このためh8/300系のライブラリは全て揃っており、3694が使う 300H ノーマルモード でも浮動小数点計算が可能です。またnewlib2.0も同時にビルドしましたのでmath等のCライブラリが使えるはずです。試したことはありませんが。

注意しなくてはならないのは、既成のスタートアップルーチンはそのまま使えない(と思う)ので自分で用意しなくてはなりません。

試しに以下のコードをコンパイルしてみます。

#include <stdio.h>
#include "iodefine.h"
#include "monitor.h"

int main(int argc, char **argv)
{
    volatile float a,b,c;
    a = 123.4;
    b = 456.7;
    c = a * b;
    return (int)c;
}


Makefile

PKG = main
OBJ = mystartupram.o main.o sub.o

SCRIPT_PREFIX = ./
TOOLS_PREFIX = /usr/local/h8300-hms/bin/
LIBPATH= /usr/local/h8300-hms/lib/gcc/h8300-hms/4.4.6/h8300h/normal/
LIBPATH2= /usr/local/h8300-hms/h8300-hms/lib/h8300h/normal/

CC = $(TOOLS_PREFIX)h8300-hms-gcc
AS = $(TOOLS_PREFIX)h8300-hms-as
OBJCOPY = $(TOOLS_PREFIX)h8300-hms-objcopy
OBJDUMP = $(TOOLS_PREFIX)h8300-hms-objdump

all: $(PKG).mot Makefile

$(PKG).mot: $(PKG)
    $(OBJCOPY) -O srec $< $@
    sed -e "2,5d" $@  > $<.mot2
    rm $@
    mv $<.mot2 $@
    $(OBJDUMP) -D -S -s -mh8300hn $< > $<.ref


$(PKG): $(OBJ)
    $(CC)  -L$(LIBPATH) -L$(LIBPATH2) -o $@  -T $(SCRIPT_PREFIX)3694f.x  -nostartfiles  $(OBJ) $(LIBPATH)libgcc.a $(LIBPATH2)libc.a

.s.o:
    $(AS) -o $@ $<

# -mh H8/300H, -mn H8 Tiny normal mode, -relax 分岐最適化
.c.o:
    $(CC) -O2 -w -mrelax -g -o $@ -c -mh -mn $<

clean:
    rm -f $(OBJ) $(PKG)

write:
    h8write -3664 $(PKG).mot /dev/ttyUSB0

.PHONY: clean all


結果(main.ref)を稿末に示します。
とにかく、やることの割にバイナリサイズがデカすぎる。floatでこうならdoubleとかどうなるのか。newlib内の初等関数を使うならdouble必須なのだが。
今までやってきたように、RAM上でデバッグしながら開発を進める訳にはいかないでしょう。

というより、動くのかこれ?

 



秋月電子の 3694マイコン(ルネサス Tiny H8/300H)に、同じく秋月電子が扱っているキャラクタ液晶表示器(以下LCD)を接続してみました。
昔からあるパラレルタイプのものは、只でさえ少ない3694のポートを占有してうまくないので、I2Cタイプのものを試しました。なお、3694の前身である3664はI2Cインターフェースがバグ持ちのようです。I2Cで遊ぶなら3694がお勧めですね。

I2Cを使うのは初めてだったので、3694のマニュアルと首っ引きでコーディングしました。コーディング、等というのも憚られるような短いものですが、何せ初期化が完了しないとLCDには何の気配もなく(黒豆腐は勿論、影すら浮かばない)、文字通り暗中模索でまる1日費やしてしまいました。
LCDのマニュアルによれば、初期化の際は1コマンド送るごとに27μS程度の時間待ちをすれば良いように書かれています。しかしよく見ると、Follower Control (0x6C) (内部電源回路の設定)送出後は200mS以上となっています。この通りにすべきなのでしょうが、少しでもメモリを節約したかった(RAMへプログラムを送って動かしている)ので全て同じ待ち時間とし、試行錯誤で表示可能な最短時間を探しました。この辺は製品によってばらつきがあると思われるので調整が必要になります。

一応、(自分用のメモとして)コードも載せますが、I2Cバス上に何か問題が発生すると帰ってこないので、LCDを表示して遊ぶ以外には使えません。


 



H8/300H(3694)を使った工作、というのをしつこく続けていました。

これまで温度センサーやらロータリーエンコーダやらドットマトリクスLEDやら、いろいろ繋いで遊んだのですが結局オーソドックスなLED時計をひとつこさえてみました。
当初予定していた温度計機能は、センサー直結だと精度が足りないので取りやめ。ロータリーエンコーダも時計だけに使うにはもったいないので、これも普通に押しボタン2個で代用。アラーム用に圧電サウンダを繋いでおしまい。

アラームも、最初はメロディでも流そう、と意気込んでいたのですがLED点灯用にタイマVを使ってしまったので、これも単なるビープ音の断続へとスペックダウンしました。タイマVを使うと周波数の制御にCPUを使うことなく音が出せて好都合だったのですが、次回への宿題となりました。ビープ音のほうはタイマAを1kHzにして使っています。

肝心の時計のほうは時刻表示、アラーム設定1、ダウンカウンタ(ストップウォッチ)1としました。わずかこれだけの機能を実現するのにプログラムサイズはCで書いたとはいえ1318バイトもあります。タイマAによる割り込み部分はROM化(モニタルーチン)してあるにも関わらず、です。これにモニタ側の作業領域やスタックが加わってきますから内蔵RAMだけでの開発はここら辺が限界だと思います。機能を追加するにはバグ出しの終わった部分からROM化してRAM領域を解放しなければなりません。

しかし、まあ、久しぶりにCとアセンブラをチャンポンで使ってプログラミングしたのですが、(メモリが不足して)途中でリファクトしたらコンパイラの最適化にひっかかって挙動がおかしくなるは、アセンブラで書いた割り込みルーチンがバグって、ひょっとしたらステート溢れしてるのかしらん、とプリントアウトして紙の上でバグだしするハメになる(手計算でステート数を拾いました)は、で大変でした。モトローラライクなニモニックは読みやすいと思いますが、それでも勘違いや見間違いはあるものです(特にブランチ命令)。

とりあえず練習問題代わりの製作はこれで一旦締めて、次の何かを考えようと思います。I2Cとか、まだ使っていない機能もあるので。

作ったもの
モニタプログラム(ブレークポイント、レジスタ読みだし、Sフォーマット読み込み機能あり)
TINYBASIC(整数のみ、エディタ内蔵)
時計プログラム

 

モニタ(及びBASICインタープリタ)の初期化部分で、サブクロックを1/32してTMOWへ出力するように設定している。
このため、P10/TMOWの切り替えを行うだけで、BEEP音(周波数約1kHz)の入り切りができる。
 
20 LET A=PMR1():B=PMR1(A|1): RETURN : REM BEEP ON
30 LET A=PMR1():B=PMR1(A&0x00FE): RETURN : REM BEEP OFF

ポートは直接圧電スピーカ等をドライブできないので、必ずトランジスタ等を経由すること。
 

承前。

4桁の時計表示の様子


プログラムを以下に示す。(閲覧環境による折り返しに留意してください)
 
10 REM A-J -> @(N)
20 FOR Z=0 TO 9: READ @(Z): NEXT
30 DATA 0x00FC,0x0060,0x00DA,0x00F2,0x0066,0x00B6,0x00BE,0x00E0,0x00FE,0x00F6
40 LET Z=PCR1(0x00C0):Z=PCR8(0x00FF)
50 LET T=TIME():X=0: FOR K=0 TO 3:Y=PDR8(0):Y=PDR1(X):Y=PDR8(@(T&0x000F))
55 IF K==0 AND SECOND()&1 THEN Y=PDR8(@(T&0x000F)|1)
60 LET T=T>>>4:X=X+0x0040: NEXT : GOTO 50

55行にて1秒毎に最下位桁(右端)のピリオドを点滅させている。
写真からも伺えるが、最上位桁の輝度が高い。これは最上位桁の表示が終わってから最下位桁に遷移する処理(60行終わりから50行のFOR文迄)が、他の桁より時間がかかっている為、点灯時間が長くなっていることが原因である。

同様に、ピリオド点灯時は55行の処理が時間稼ぎとなって最下位桁の輝度が少し高くなる。

これらを回避するには定刻割り込みにて点灯ルーチンを組めばよい。但し、既にタイマAを時計カウンタに使っているので別途タイマを割り当てなくてはならない(以前、ドットマトリクスLEDを使ったとき試している)。
 

自分宛メモ
久しぶりにH8/300H tinyで遊ぼうとしたら、以前作った回路図やプログラムを紛失していて慌てたので。


回路図

 
10 REM A-J -> @(N)
20 FOR Z=0 TO 9: READ @(Z): NEXT
30 DATA 0x00FC,0x0060,0x00DA,0x00F2,0x0066,0x00B6,0x00BE,0x00E0,0x00FE,0x00F6
40 LET Z=PCR1(0x00C0):Z=PCR8(0x00FF)
50 LET Z=SECOND():Y=Z&0x000F:X=PDR8(0):X=PDR1(0):X=PDR8(@(Y))
60 LET Y=(Z>>>4)&0x000F:X=PDR8(0):X=PDR1(0x0040): IF Y!=0 THEN X=PDR8(@(Y))
70 GOTO 50

テストプログラム 60進2桁の秒カウンタ

以前作ったモニタ/BASICインタープリタを使っている。まだ1年も経っていないはずだが、ポート回りの関数を追加していたことが記憶から抜け落ちていて我ながら驚く。
モニタがタイマAを使って1秒刻みのカウントアップカウンタを持っているので、それを読み出して使っている。表示パターンはROM化していなかったので、BASICの配列変数を使っている。

 


Search

Calendar

S M T W T F S
    123
45678910
11121314151617
18192021222324
252627282930 
<< June 2017 >>

Archive

Mobile

qrcode

Selected Entry

Link

Profile

Search

Other

Powered

無料ブログ作成サービス JUGEM