(シミュレータ編第5回)タイマを実装する

2010/09/29

あなたは 人目のお客様です.

書きたいことがたまっているので,今日はもうひとテーマ. シミュレータにタイマを実装してみよう.

タイマについてはH8移植編その2第1回で実機で動作 させている.が,ここで利用しているのは8ビットタイマというやつだ.

もともとH8/3069Fは8ビットタイマと16ビットタイマという2種類のタイマを 持っている.まあこのときは8ビットタイマのほうが便利そうでそっちを利用 したのだけど,しかしH8のラインナップを見てみると,16ビットタイマを実装 している機種のほうが多いみたいで,そっちのほうがスタンダードなようなのだな. なので,16ビットタイマを実装することにする.

タイマの実装はそれほど難しくはなくて,1命令実行ごとにカウンタレジスタを カウントして,一定値になったら割り込みを上げればいいだけだ. まあ実際にはシステムクロックを使ったりするので1命令で1カウントという わけではないし,当然ながら実機とシミュレータでは実時間での動作速度が 異なるから,シミュレータでは1秒と設定して1秒でタイマがかかるわけではない. だけどまあこのへんはあんまり考えず,1クロック1カウントで単純に実装して しまえばいいだろう.

あと動作テストをどうするかなのだけど,「H8移植編その2」のコードは 8ビットタイマを利用しているので,そのままでは動作テストには使えない. 実は自分でも忘れていたのだけど,昔のH8移植編第6回の ときにタイマを利用していて,ここでは16ビットタイマを使っているのだな. で,移植編その2のときはこのことをすっかり忘れていて,まあ8ビットタイマの ほうが便利そうということで8ビットタイマを利用した. なので今まではOS自作本のコードをベースにしてテストしていたのだけど, ここでは例外的に,H8移植編第6回の古いコードを 動作テストに利用することにする.もちろんこのコードはそのままではシミュレータで 動作しないので, シミュレータ編第2回シミュレータ編第4回で行ったような修正を入れて 動作テストに用いる.

で,作成したのが以下.

まず,シミュレータ側の対応だ. これはシミュレータ編第2回で作成した device.c というファイル(sim/h8300/device.c)に,タイマの対応を入れている. 具体的な修正内容は上記ソースコードを参照してほしいのだが, まあ単に16ビットタイマ関連のレジスタを毎回見てカウンタをインクリメントし, カウンタが満了したら割り込みを上げているだけだ.上記ソースコードでは device.cの本体と,前回(シミュレータ編第2回) に対する差分のパッチ(device.c.patch)を添付してある.

GDBは上記のdevice.cの修正をsim/h8300/device.cに対して入れて,ビルドしなおす. これはgdbのトップディレクトリで make を実行すればよい. FreeBSDの場合はgmakeを利用すること.

さらに,H8移植編第6回の古いコードをシミュレータ対応 する.とはいっても方法はここまでで説明してきたことと同様なのだが,古いコード で最近のコードとはちょっと違う部分があるので,何点か注意が必要.

まず,intr.Sとvector.cをH8移植編第6回の ブートローダーからそのままコピーする.さらにこれらをコンパイル対象に 加えるように Makefile を修正.

diff -ruN h8_06/os/Makefile h8_sim_05/os/Makefile
--- h8_06/os/Makefile	Wed Sep 29 20:50:10 2010
+++ h8_sim_05/os/Makefile	Wed Sep 29 20:54:01 2010
@@ -1,5 +1,6 @@
 OBJS += startup.o main.o interrupt.o
 OBJS += lib.o serial.o timer.o
+OBJS += vector.o intr.o
 #LIBOBJS += 
 #LIB = libxxx.a
 TARGET ?= hello
次に割り込みベクタをROM先頭に配置するようにリンカスクリプト修正. これもH8移植編第6回のブートローダーの リンカスクリプトの記述をそのまま持ってきている.
diff -ruN h8_06/os/ld.scr h8_sim_05/os/ld.scr
--- h8_06/os/ld.scr	Wed Sep 29 20:50:10 2010
+++ h8_sim_05/os/ld.scr	Wed Sep 29 20:53:27 2010
@@ -4,6 +4,7 @@
 
 MEMORY
 {
+	vectors(r)	: o = 0x000000, l = 0x000100 /* top of ROM */
 	/*
 	 * reserve 256bytes space for software interrupt vector
 	 * and 256bytes space for ELF header.
@@ -14,6 +15,10 @@
 
 SECTIONS
 {
+	.vectors : {
+		vector.o(.data)
+	} > vectors
+
 	.text :	{
 		_text_start = . ;
 		*(.text)
次にOSの先頭で各種初期化を行うように追加.
diff -ruN h8_06/os/main.c h8_sim_05/os/main.c
--- h8_06/os/main.c	Wed Sep 29 20:50:10 2010
+++ h8_sim_05/os/main.c	Thu Sep 30 02:07:11 2010
@@ -5,6 +5,13 @@
 
 static int init()
 {
+  extern int bss_start, ebss;
+
+  memset(&bss_start, 0, (char *)&ebss - (char *)&bss_start);
+
+  /* ソフトウエア・割り込みベクタをゼロクリアする */
+  interrupt_init();
+
   serial_init();
   timer_init();
 
以上で修正は終了.

実際に試してみよう.今回はブートローダーを用いずにOSをシミュレータで直接起動 できるように修正してあるので,直接起動する.

注意点として,H8移植編第6回の頃は make.sh という スクリプトを用いてビルドしていたので,OSのビルドは

% make
でなく,
% ./make.sh
のようにして行う.make clean とかも同様. またビルドして作成されるモジュールは kozos でなく hello という名前なので注意. なにせ随分以前のコードなので,このへんはだいぶ最近と違ってしまっている.

実際に動作させてみる.まずビルドしなおしたGDBを起動する. 起動モジュールは hello を指定する.

hiroaki@teapot:~/h8>% ./gcc/gdb-7.2/gdb/gdb sim/h8_sim_05/os/hello
GNU gdb (GDB) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i386-unknown-freebsd6.2 --target=h8300-elf".
For bug reporting instructions, please see:
...
Reading symbols from /home/hiroaki/h8/sim/h8_sim_05/os/hello...(no debugging symbols found)...done.
(gdb) target sim
Connected to the simulator.
(gdb) load
connect to /dev/ttyp9
Loading section .vectors, size 0x100 vma 0x0
Loading section .text, size 0x1922 vma 0xffc120
Loading section .rodata, size 0x16 vma 0xffda42
Start address 0xffc120
Transfer rate: 53696 bits in <1 sec.
(gdb) 
cu を接続する.
teapot# cu -l /dev/ttyp9
Connected
GDBで実行開始.
(gdb) run
Starting program: /home/hiroaki/h8/sim/h8_sim_05/os/hello 
cu側にはブートメッセージが出力される.
teapot# cu -l /dev/ttyp9
Connected
boot succeed!
os> test
test
os> II
定期的にタイマ割り込みが入り,「I」の文字が出力されている. どうやらそれっぽく動いているようだ.よしよし.

もともとは1秒おきに「I」が表示されていたが,シミュレータ動作ではだいぶ インターバルが開いて「I」が表示されている.まあPCの性能によってもだいぶ 変わってくるとは思うが,実時間のとおりには動かないのでこのへんは使う側で 注意が必要だ.


メールは kozos(アットマーク)kozos.jp まで