H8/3048F (秋月 AKI-H8)
IMAGE11.GIF - 980BYTES  基礎情報
IMAGE11.GIF - 980BYTES  H8に関する雑感
IMAGE11.GIF - 980BYTES  Cコンパイラ/起動ルーチン
IMAGE11.GIF - 980BYTES  リンク例
IMAGE11.GIF - 980BYTES  リアルタイムモニタ(RTM)
IMAGE11.GIF - 980BYTES  モニタプログラム
IMAGE11.GIF - 980BYTES  ダウンロード
IMAGE12.GIF - 2,801BYTES

変更履歴
2006年7月23日修正   ---- 古い情報の整理
2004年1月1日修正   ---- 内容見直し
2002年1月13日修正   ---- ロボットプロジェクト追加(H8/3664F)
2001年3月19日修正   ---- リンク先修正(技術内容に変更無し)
2000年3月26日修正   ---- 誤記訂正のみ
1999年10月9,10日修正 ----  Cコンパイラ/起動ルーチン、RTM(リアルタイムモニタ)
1999年10月3日修正   ---- Cコンパイラ/起動ルーチン、RTM(リアルタイムモニタ)
1999年9月18日修正   ---- ソフトウェアのダウンロード



H8/3048F ----- 基礎情報
IMAGE12.GIF - 2,801BYTES
TOP02_001.PNG - 934BYTES

関連WEBサイト
日立H8/300Hシリーズ(2003年に日立と三菱両者合弁のルネサスが誕生。今後の古い文章はほとんどがルネサスと読み替えて理解願います)、 及び秋月製AKI-H8キットに関する情報は、下記のWEBサイトで情報を得る事が出来ます。ハードウェアとソフトウェアのドキュメントは、PDFファイルとしてダウンロードできますし、その他色々な情報が入ると思います。

Hitachi H8 related web sites
http://japan.renesas.com/
http://japan.renesas.com/fmwk.jsp?cnt=h83048_root.jsp&fp=/products/mpumcu/h8_family/h8300h_series/h83048_group/


Akizuki H8 board related web sites
http://akizukidenshi.com/


私の開発環境
私は、下記のような環境でプログラム作成しています。

Personal Computer
ThinkPad385D Window95(2004年1月時点で、Sony VAIO PCG-GRS55/BとWindow XPとなりました)
すでに購入から3年以上(1999年時点)経っており、決して恵まれた環境ではないですが、ThinkPadシリーズはキータッチが良く、気に入っています。
その他のPCとして、
Sotec e-note H3100TRX4
Desktop (made in Taiwan) Window95
ThinkPad230cs

下記のアッセンブラ、リンカ、コンバータ、FLASHライタのそれぞれのプログラムは、秋月電子通商で「AKI-H8マイコンボード」のキットを購入すると、ハードウェアとソフトウェアの組合わせとして入手出来ます。私も‘98年2月頃購入しています。現在発売されているバージョンが、私の持っているものと同じか否かはチェックしていません( 当然違うでしょうから確認願います)。尚、一度このキットを購入すれば、その後の製作は、ハードウェアだけ買えばよいのですから、安くて済みます。私もすでに5枚ほど基板を購入して、色々なプロジェクトで使用しています。

Assembler
A38H.EXE H8/300H ASSEMBLER (Evaluation software) Ver.1.0
Linker
L38H.EXE H8/300H LINKAGE EDITOR (Evaluation software) Ver.1.0
Object Converter
C38H.EXE H8/300H OBJECT CONVERTER (Evaluation software) Ver.1.0
FLASH WRITER
FLASH.EXE F-ZAT MICRO COMPUTER ON-BOARD PURGE/WRITE TOOL Ver. 1.0

Cコンパイラも別売りで、秋月から販売されています。私がこのキットを購入する事を決めた一番の理由は、このCコンパイラが提供されるとのアナウンスが出たからです。

C Compiler
CC38H.EXE H8/300H C COMPILER (Evaluation software) Ver.1.0




H8に関する雑感
IMAGE12.GIF - 2,801BYTES
TOP02_001.PNG - 934BYTES

H8/300H

私の記憶では、日立は68系マイコン(つまりモトローラ系)のライセンスを取得し、マイコン市場に進出しました。長い間、モトローラとの協調の中で商売をやっていたのですが、MC6801系バリエーションの展開辺りからモトローラとの関係に終止符をうち、独自路線を展開して来ました(この時代の傑作は、HD63C09でモトローラオリジナルの機能に大胆にも多くの追加命令を入れたものです。OS-9との組合わせで、一部のマニアが多くの時間を費やしたMPUです)。

独自路線の最初が、H16(今は亡きシリーズ‐‐‐短命でした)やH8のシリーズでした。H8は先ず、H8/500シリーズが展開され、その後に下位機種(私の認識では)のH8/300シリーズが展開され、次にH8/300H(この他300Lシリーズなど)が展開されました。詳しい内容は分析していないのですが、H8/300Hとなり”H”が追加された時に、初期のH8/500シリーズより性能が向上し、500シリーズとの差別化がはっきりしなくなるほどでした。更に、H8Sシリーズが加わり、殆どのアップリケーション分野で300シリーズが中心になるでしょう(私は、日立の関係者ではありませんので、単に意見としてお聞きください)。

H8/3048Fは、このH8/300Hシリーズの中の一つで、FLASH ROM内蔵の為、アマチュアがICE等の装置を持たずに、ぶっつけ本番のデバックをやりなから何かを開発するには、格好のCPU(モトローラ系ではMPUと呼びますが)と言えます。FLASHは、何回でも(実は仕様書上はたった100回しか保証されていない!)簡単に書きかえられますし、紫外線による消去も不要です。パソコンとのシリアルコミュニケーションラインを確保して、うまくハード構成を考えれば、最終システムに何も手を加えずにソフトウェアのバージョンアップが出来ます。

H8用ソフトウェア

秋月で売られているソフトウェアは、Cコンパイラを含み、日立製のソフトウェアと非常に高い互換性を有しています。ですから、日立のWEBサイトからコンパイラ用のドキュメント情報を入手して比較してみると、一部機能が無い部分が有りますが、ほぼ同じ機能を有している事が判ります。つまり、秋月版は日立版のサブセットになっています。秋月製のソフトウェアに「日立」の文字は何処にも出てきませんが、Cコンパイラの生成コードを分析した感じでは、源は同じ所へ行き着くと思われます。

日立版に有って、秋月版で無い機能としては(私が認識した分。ここに掲載した意外にもまだあるはず)、
Assembler

Linker
(1)多くのファイルをリンクする際に、一度中間的にモジュール作成する機能が使えない。
(2)ライブライアン機能(これは別ソフトウェアだったかも知れない?)


C Compiler
(1)#pragma文の機能が使えない(但し、#pragma interruptはどういう訳か使える)
(2)リンカが名前別にセクションを指定出来るのに対して、コンパイラ上(実際にはCのソース内などで指定)でその機能がサポートされていない。

などが有ります。



H8/3048F ----- Cコンパイラ/起動ルーチン
IMAGE12.GIF - 2,801BYTES
TOP02_001.PNG - 934BYTES

C言語でプログラムを作成し、コンパイル後ROM内にそのコードを書込んでも、残念ながら動き出しません。最低限の準備として、そのCコンパイラ生成コードを呼び出す為の処理が必要です。Cコンパイラが、#pragma asmをサポートしていれば、Cソースの中にスタック制御命令などを記述して、Cのソースだけで書く事も出来ます(もう一つの必要条件として、コンパイラがセクション指定を解析し、制御できる事)が、秋月販売のCコンパイラでは、残念ながらC言語のみではROMから起動する事は無理です。

そこで、起動ルーチンが必要となります。
起動ルーチンには、
(1)VECTOR領域の設定
(2)リセット直後のスタック設定
(3)D領域(ROM内)のRAM内(DR)へのコピー
(4)Cソースへのサブルーチンコール(必ずしも _mainへコールする必要はない)
などの機能が必要ですが、これらはプログラムの作り方により違ってきます。

下記のソースコードは、私が使用している起動ルーチンで、ここでダウンロードできます
ポイントを赤字で説明します。

; H8 Real Time Monitor (Adovance mode) System start-up and assembler routine
; Caution!!
; The code of both edtsk_dispatch() and edtsk_end() are stolongly related
; with caller structure of rtm_h8() that is generated by the C compiler that
; you are using. So you have to check the code both caller and those assembeler
; code if you change the C compiler version.
; This code is used with following version of rtm_h8.
; rtm_h8.obj 99/08/11 00:01
;
; May 25,1998    Kenji Arai Start modification for H8/3048F
; June 24,1998   Debug ED task dispatch routine
; August 11,1999 Create the release version
;
; (C)JH1PJL / Kenji Arai
; kenjia@sannet.ne.jp or jh1pjl@arrl.net
;
; From /* HERE(START) */ to /*HERE(END)*/ is written by Mr.Tanaka and modified by Kenji
;
; Copyright (C) 1998, Office SoftBone
; SoftBone Repesentative Tanaka, Toshihide
; ttanaka@cb3.so-net.ne.jp
; http://member.nifty.ne.jp/softbone/index.html
;
;***********************************************************************
* CPUの種類をアッセンブラに知らせます。
.cpu 300HA
* IMPORTは、このファイル外の変数、ラベル名称等を宣言します。
.IMPORT $STACK
.IMPORT _main
.IMPORT _rtm_h8
* EXPORTは、このファイル内で定義される変数、ラベル名称等を宣言します。
.EXPORT Cold_Start
.EXPORT _irq_enable
.EXPORT _irq_disable
.EXPORT _edtsk_dispatch
.EXPORT _edtsk_end
* _mainの様に名称にアンダースコア( _ )が先頭に付いているのは、Cで作成されたラベルです。Cの中では、アンダースコアは付いておらず、コンパイルされたオブジェクトファイル内では上記の様に変換されます。逆にアッセンブラソースの中で意図的にアンダースコア付きの名称を使うと、Cで書いたソースの中で関数名として、それを使う事が出来ます。例えば、Cのソース内で、関数として edtsk_end() を呼ぶ事が出来ます。
; Support for running on the ROM(Transfer initial data)
; Interrupt enable/disable
; Tick timer using interval timer mode(ITU0)
; Interrupt handler for serial communication
; /* HERE(START) */
;=========================================================================
;           Vector area
;=========================================================================
* ここは例外処理のスタートアドレスを設定します。セクションを分けて、ベクターを個別に設定していますが、直接アドレスを指定せず名称(VCT_0,1)を登録し、リンク時に指定します。
.SECTION VCT_0,DATA,ALIGN=2
.data.l Cold_Start
.SECTION VCT_1,DATA,ALIGN=2
.data.l _rtm_timer ;Tick Timer
;=========================================================================
;           Data Section
;=========================================================================
.section C,DATA
.section CR,DATA
.section D,DATA
.section DR,DATA
.section B,DATA
_ccr_save:
.res.w    1 ;Save area for CCR
;=========================================================================
; Code Section
;=========================================================================
.section P,CODE

;-----------------------
;Cold start(RESET)
;-----------------------
* ここからパワーオンリセット後のプログラムが走ります。
Cold_Start:
;Set stack pointer
mov.l    #$STACK,er7
;Clear RAM area
mov.l    #0,er0
mov.l    #h'fef00,er1
loop:
mov.l    er0,@er1
adds.l    #4,er1
cmp.l    er7,er1
blo       loop
;Data transfer from C(ROM) to D(RAM)
* ROMエリアからRAMエリアへのコピーを行います。D(ROM内)からDR(RAM内)へ。#(startof D)はリンク時に、Dのセクションの開始アドレスが確定した段階で、自動的に決まります。#(sizeof D)は同様に、確定情報としてのD領域のサイズが自動的に決定されます。リンク条件(一般には、リンカーが使用するコマンドファイル(私のプログラムをダウンロードした方は、ファイルHP_link.subの事)を参考にして下さい。大事な事は、自分で作成したプログラムの中で、追加や変更の際に、このDのサイズが変わってもこの起動ルーチンを変更しなくても良い事です。
MAPファイルを覗くと分かるのですが、DとDRのサイズは同じになっています。すなわち、コピーする事を前提に同じサイズが取られます。さて、誰がこの様に同じ大きさを設定しているのでしょうか?(正解は、リンカー用SUBファイルを見ると分かります)

注意)最初のソースファイル(ファイルのダウンロードが出来るようになってから1999年10月9日まで)には、下記(ピンク部分)の部分が書かれていますが、ここは間違いです。元々、Cが生成するコードは、プログラム領域(P)、定数領域(C)と初期化の必要なデータ領域(この他、未初期化データ領域(B)が有りますが、ここはRAM内をクリアするだけです)がありますが、初期化が必要なデータ領域は、初めからRAMに入れたまま起動できないので、初期化データをROMの中に入れておき、ユーザープログラムを起動する前にその値をRAMにコピーしてからスタートします。そこでROM内D領域をDRにコピーします。
では、間違いがあったC領域はどのように使うのでしょうか?
下記のコードは、C領域に入ります。
const unsigned char cyclic_period[2] = { 1,2 };
下記は、D領域に入ります。
unsigned char cyclic_period[2] = { 1,2 };
つまり、起動後に変数でなく定数として使用される(const宣言)なら、ROM(C領域)の中に置いても問題ないわけです。
mov.l  #(startof C),er5    /* Mistake */
mov.l #(startof CR),er6   /* Mistake */
mov.w #(sizeof C),r4       /* Mistake */
eepmov.w
* 下記の3行のプログラムは、ブロック転送を意味します。
mov.l    #(startof D),er5
mov.l    #(startof DR),er6
mov.w   #(sizeof D),r4
eepmov.w
* ここから-- Call main() --までは、RTMの基本的な時間単位(Tick)を決定する部分で、RTMを使わない場合は不要な部分です。Tickタイムは、500uSです。
;ITU Initialization
TSTR    .EQU     H'FFFF60
TCR0    .EQU     H'FFFF64
TIER0   .EQU     H'FFFF66
TSR0    .EQU     H'FFFF67
GRA0   .EQU     H'FFFF6A

mov.b   #b'00100011,r0l  ;compare match -> clear TCNT, clock/8
mov.b   r0l,@TCR0
bclr      #0,@TSR0                    ;clear imfa
bset     #0,@TIER0                    ;
mov.w   #1000,r0                      ;load counter 500uSec
mov.w   r0,@GRA0                    ;
bset     #0,@TSTR                    ;start itu ch0
* main()をコールします。基本的には二度と戻らない事を前提にしています。戻っても下の様に無限ループに入り何もしません。
;           -- Call main() --
jsr                   @_main
;           -- Never come here --
orc.b #b'10000000,ccr    ;Disable interrupt
bra       $
; /* HERE(END) */
;--------------------------
;500uSec interval Interrupt
;--------------------------
* Tick(500us毎)の処理です。RTMの一番大事な処理ルーチンrtm_h8()を呼出します。
; -- Timer Interrupt Handler --
_rtm_timer:
push.l    er0
push.l    er1
bclr      #0,@TSR0                    ; stop interrupt ( clear imfa )
mov.b   @(8,SP),r0l                   ; Get CCR
mov.b   r0l,@_ccr_save    ; Save CCR to RAM
jsr                   @_rtm_h8                     ; Real Time Monitor Core routine
pop.l     er1
pop.l     er0
rte
* 割り込み処理の許可と禁止をコントロールする為の関数irq_enable()とirq_disable()を定義しています。
; -- Interrupt reqest Enable --
_irq_enable:
andc.b   #b'01111111,ccr ; Clear interrupt Mask
rts
; -- Interrupt reqest Disable --
_irq_disable:
orc.b     #b'10000000,ccr ; Set interrupt Mask
rts
* 下記の処理は、RTM内から呼出される関数で、ユーザーは呼出し禁止です。気にしないで下さい。気にしなければいけないのは、Cコンパイラが秋月製でないか、秋月でも私が使ったものでない場合(Version違い)は、RTMがうまく動作しない可能性がある事です。
The code of both edtsk_dispatch() and edtsk_end() are stolongly related with caller structure of rtm_h8() that is generated by the C compiler that you are using. So you have to check the code both caller and those assembler code if you change the C compiler version.
私の使っている秋月製Cコンパイラのバージョンは、下記のものです。
This code is used with following version of rtm_h8. rtm_h8.obj 99/08/11 00:01
; -- EVENT DRIVEN TASK dispatch --
;           Calling sequence of edtsk_dispatch()
;
_edtsk_dispatch:
* ER1には戻り番地が、ER0には飛び先番地が入っています。そしてインターラプトの状態を許可しながらサブルーチンコールします。RTE命令を使っていますが、あくまでもサブルーチンコールをしているのと同じです。
push.l    er1                                        ; Save return address(_edtsk_end)
push.l    er0                                        ; Set task start address
mov.b   @_ccr_save,r0l    ; Get CCR from RAM
mov.b   r0l,@sp                        ; Save to stack
rte                                                               ; Goto Event Driven Task
; -- EVENT DRIVEN TASK exit process --
* ユーザーのタスクが終了した時点で、ここに戻ってきます。さてその後は何処に行って何をするのでしょうか?
_edtsk_end:
orc.b     #b'10000000,ccr ; Mask interrupts
rts                                                               ; return to _rtm_h8
.END




H8/3048F ----- リンク例
IMAGE12.GIF - 2,801BYTES
TOP02_001.PNG - 934BYTES

下記はリンクのコマンド例です。

H8/300H LINKAGE EDITOR (Evaluation software) Ver.1.0
LINK COMMAND LINE
LNK /SUB=HP_link.SUB
LINK SUBCOMMANDS

INPUT rtm_h8,sci,tasks_asm
INPUT rtm_h8_hw, tasks
*リンクするOBJファイルを入力として指定します。
LIBRARY \h8c\c38hab.lib
*リンクするライブラリーファイルの指定
ROM (D,DR)
*初期値を持つRAMのコピー元とコピー先
DEFINE $STACK(0FFDFE)
*スタックのアドレス指定
PRINT h8sys.MAP
*下記のようなリンク結果の情報出力先の指定
OUTPUT h8sys.ABS
*実行ファイルの出力ファイル先
START VCT_0(0),VCT_1(60),VCT_2(94),VCT_3(0d0),VCT_4(0e0)
START P,C,D(100)
START CR,DR,B(0FEF10)
*OBJ配置アドレスを指定しています。
EXIT

下記がリンクコマンド実行で生成されるリストです。


H8/300H LINKAGE EDITOR (Evaluation software) Ver.1.0
*** LINKAGE EDITOR LINK MAP LIST ***
SECTION NAME START - END LENGTH UNIT NAME MODULE NAME

ATTRIBUTE : DATA NOSHR
VCT_0 H'00000000 - H'00000003 H'00000004 rtm_h8_hw rtm_h8_hw
VCT_1 H'00000060 - H'00000063 H'00000004 rtm_h8_hw rtm_h8_hw
VCT_2 H'00000094 - H'00000097 H'00000004 tasks_asm tasks_asm
VCT_3 H'000000D0 - H'000000D7 H'00000008 tasks_asm tasks_asm
VCT_4 H'000000E0 - H'000000E7 H'00000008 tasks_asm tasks_asm
*VECTOR情報の設定結果です。VCT_0とVCT1は、ここで指定しているように、コールドスタート(パワーオンリセット)とRTM用のタイマー割込み設定です。ROM内に置かれます。

P H'00000100 - H'00000521 H'00000422 rtm_H8 rtm_H8
H'00000522 - H'000007F5 H'000002D4 sci sci
H'000007F6 - H'0000089B H'000000A6 rtm_h8_hw rtm_h8_hw
H'0000089C - H'000009B7 H'0000011C tasks tasks
H'000009B8 - H'000009D9 H'00000022 spregld3 spregld3
H'000009DA - H'00000A01 H'00000028 spregsv3 spregsv3
* TOTAL ADDRESS *
H'00000100 - H'00000A01 H'00000902
*プログラム領域で、ROM内におかれます。配置順番はINPUTで指定された順となっています。H'100番地から配置されているのは、START P,C,D(100)の指定によるものです。

ATTRIBUTE : DATA NOSHR
C H'00000A02 - H'00000A67 H'00000066 rtm_H8 rtm_H8
H'00000A68 - H'00000A68 H'00000000 rtm_h8_hw rtm_h8_hw
H'00000A68 - H'00000AC9 H'00000062 tasks tasks
* TOTAL ADDRESS *
H'00000A02 - H'00000AC9 H'000000C8
*CはROMに置かれるデータ領域です。今回の例では、RTMでのタスク起動周期データ等が、この領域に入っています。 

ATTRIBUTE : DATA NOSHR ROM
D H'00000ACA - H'00000ACA H'00000000 rtm_h8_hw rtm_h8_hw
* TOTAL ADDRESS *
H'00000ACA - H'00000ACA H'00000000
*起動時に、このプログラム部分で、ROM領域からRAM領域にコピーしてからユーザープログラムが実行されます。

ATTRIBUTE : DATA NOSHR
CR H'000FEF10 - H'000FEF10 H'00000000 rtm_h8_hw rtm_h8_hw
* TOTAL ADDRESS *
H'000FEF10 - H'000FEF10 H'00000000

ATTRIBUTE : DATA NOSHR RAM
DR H'000FEF10 - H'000FEF10 H'00000000 rtm_h8_hw rtm_h8_hw
* TOTAL ADDRESS *
H'000FEF10 - H'000FEF10 H'00000000

ATTRIBUTE : DATA NOSHR
B H'000FEF10 - H'000FEF23 H'00000014 rtm_H8 rtm_H8
H'000FEF24 - H'000FEF3F H'0000001C sci sci
H'000FEF40 - H'000FEF41 H'00000002 rtm_h8_hw rtm_h8_hw
H'000FEF42 - H'000FEF97 H'00000056 tasks tasks
* TOTAL ADDRESS *
H'000FEF10 - H'000FEF97 H'00000088



H8/3048F ----- RTM(Real Time Monitor)
IMAGE12.GIF - 2,801BYTES
TOP02_001.PNG - 934BYTES
 
注意
プログラムは、
ここでダウンロード出来ますが 、このRTMと日立モニタープログラムとの組合わせやRTMの内容に関して、(株)日立製作所およびその関連会社へ問合わせする事はしないで下さい。
内容に関する質問は、私(新井健司)にEメールにてお願いします。

世の中には色々なリアルタイムモニタが存在しますが、このモニタは一番原始的なモニタです。

--------------------------- 仕様概要 ---------------------------------
TICK周期:
----------500uS
起動可能タスク数:
----------サイクリック・タスク(Cyclic Task) 最大8個
----------イベントドリブン・タスク(Event Driven Task) 最大4個
----------ベース・タスク(Base Task)固定1個のみ(現在は日立製モニターを実行可能)
サイクリック・タスクの起動周期設定:
----------2mS単位で任意の値を設定可能。最大500mS周期。
サイクリック・タスクの優先度:
----------優先度は、固定であり変更出来ません。
----------優先順位は、cy7_main()(最高) cy0_main()(最低)となります。
イベントドリブン・タスクの優先度:
----------優先度は、固定であり変更出来ません。
----------優先順位は、ed3_main()(最高) ed0_main()(最低)となります。
例外処理の制限:
----------Tickタイマーとして、ITUのChannel0を使用しています。それ以外の例外処理は、使用していませんので、ユーザーが自由に使用できます。
タイマー機能:
----------ユーザーが使用出来るタイマーが4個有ります。2mSを最小値とし、最大131,070mS(約2分11秒)までの時間をカウントダウンする事が出来ます。零になると、その後は何もしません。
RTM提供関数:
----------RTM初期設定void rtm_init( void )
----------RTMの起動void rtm_core( void )
----------イベントドリブン・タスク(Event Driven Task)起動要求
void reqed0( void ), void reqed1( void ), void reqed2( void ), void reqed3( void )
----------割込み処理制御 void irq_enable( void ), void irq_disable( void )

---------------------- タスク記述の仕方(原則)------------------------------
----------タスクは、Cの関数として記述します。例えば、

void ed3_main(void)
{
/* 必要な処理を記述 */
}
の形を取ります。

----------タスクは、必ずシステム全体の制御が成立する許容範囲時間内に終了する必要があります。
従って、無限ループの形や、ある事象を待つようなプログラムは作成不可能です。

----------タスクの起動周期の設定
下記Dを参照して下さい。

----------最初の起動順序
下記Eを参照して下さい。

----------使用しないタスクの処理
/* CY1 Task */
void cy1_main(void)
{
          ;
}
の様に、関数としては定義した上で、空にしておきます。


/********************************************************************
Event and Cyclic Task's for any project using RTM_H8/3048F( Adovance mode )
August 11,1999  proto-type for any project /Kenji Arai
(C)JH1PJL / Kenji Arai kenjia@sannet.ne.jp or jh1pjl@arrl.net
*********************************************************************/
@この#pragma文でインターラプトの処理ルーチンをCだけで記述できます。但し、処理ベクターは(アッセンブラにて)、別に設定する必要があります。また#pragmaは、ヘッダーファイル等に先立って記述する必要があります。(一般情報)
#pragma interrupt ed0_ISR /* You can control the interrupt handler without assembler routine */
#include <3048f.h>
A下記のヘッダーファイルは、RTMを使用する場合は必ず入れて下さい。(RTM関連情報)
#include "rtm_h8.h"       /* I/O definition */
#include "sci.h"  /* Serial communication */
/*****  Function Prototype *****/
B起動ルーチンから呼ばれます。(一般情報)
void main( void );
void general_init( void );
void IdleNop( void );
C各タスクの型宣言です。各タスクの初期設定は、不要であれば省略できます。(RTM関連情報)
void ed0_main( void );
static    void ed0_init( void );
void ed1_main( void );
void ed2_main( void );
void ed3_main( void );
static    void cy0_init( void );
void cy0_main( void );
static    void cy1_init( void );
void cy1_main( void );
static    void cy2_init( void );
void cy2_main( void );
void cy3_main( void );
void cy4_main( void );
void cy5_main( void );
void cy6_main( void );
void cy7_main( void );
/***** Function Prototype ( Extern ) *****/
void irq_enable( void );
void irq_disable( void );
/***************************************************************/
/* I/O define for sample */
省略
/* General define */
省略
/* You need follows definition and you can modify the contents */
/* from here */

/*********** Constant data in ROM *********************************************/
Dサイクリック・タスク(Cyclic Task)の周期起動時間を設定します。No4からNo7の各タスクは何も仕事をしていないので起動周期は一番長くしています。(RTM関連情報)
/* Cyclic Task Period */
const unsigned char cyclic_period[8] = {
          T_50MS,/* cyclic task no.0 */
          T_50MS,/* cyclic task no.1 */
          T_250MS,/* cyclic task no.2 */
          T_100MS,/* cyclic task no.3 */
          T_500MS,/* cyclic task no.4 */
          T_500MS,/* cyclic task no.5 */
          T_500MS,/* cyclic task no.6 */
          T_500MS/* cyclic task no.7 */
};
Eサイクリック・タスク(Cyclic Task)の初期起動の時間を設定します。ポワーオンリセット後に、初めて起動する時に一度だけ設定される値で、タスクの起動順番が決定できます。(RTM関連情報)
const unsigned char cyclic_init_period[8] = {
          T_50MS,/* cyclic task no.0 */
          T_100MS,/* cyclic task no.1 */
          T_200MS,/* cyclic task no.2 */
          T_250MS,/* cyclic task no.3 */
          T_500MS,/* cyclic task no.4 */
          T_500MS,/* cyclic task no.5 */
          T_500MS,/* cyclic task no.6 */
          T_500MS/* cyclic task no.7 */
};
F上記の2つの配列は、const宣言していますので、C領域(ROM内)に置かれます。もしconst宣言しなければ、D領域(ROM内)に置かれ、起動ルーチンによってDR領域にコピーして使われます。この使い分けは、この値がプログラムによって動的に書換える必要があるか否かによります。書換えなければ、D領域に置いて少ないRAM領域を有効に使いましょう。(一般情報)
/* to here */
/*********** Data in RAM ********************************************************/
省略
/*********** Extern data *********************************************************/
extern unsigned tim_usr0, tim_usr1, tim_usr2, tim_usr3;                  /* timer for user */
/*********************************************************************************
          Main routine and General initialization for each task
**********************************************************************************/
void main( void )
{
          irq_disable();
          rtm_h8_init();
          general_init();
          irq_enable();

          SciPutS( 1, "Start the real time monitor for H8/3048F \r\n" );
          SciPutS( 1, " (C) Kenji Arai JH1PJL August,1999 \r\n" );
          while( 1 ){
F下記関数が、リアルタイムモニタのメインルーチンです。この関数は電源が切られるまで繰返し実行されます。(RTM関連情報)
                     rtm_core();
          }
}
void general_init( void )
{
          irq_disable();
          /* If you do not need to call the monitor, you use following call. */
          SciInit( 1, rxBuf, sizeof( rxBuf ), IdleNop );
          /* Port initialize if need */
          P4.DDR = 0xff;              /* set P4 port for output */
F各タスクの初期設定ルーチンです。初期化が必要か否かは、ユーザーの判断で行います。(RTM関連情報)
          /* Initialize each task */
          ed0_init();
          cy0_init();
          cy1_init();
          cy2_init();
          /* interrupt enable */
          irq_enable();
}
void IdleNop( void )
{
          ;           /* no operation */
}
/*********************************************************************************
          Event Driven Tasks
*********************************************************************************/
/*                   ED0 Task */
F下記関数は、イベントドリブン・タスクの一例です。この関数は、Gの割込み処理によって実行されます。この例では、タイマーで起動されていますので、サイクリックタスクと同じ様な動きになりますが、不定期に発生する事象に同期して実行する場合に使います。(RTM関連情報)
void ed0_main(void)
{
          LED_RD = 1;
          /* any program you can write */
          LED_RD = 0;
}
void ed0_ISR( void )
{
          /* This is a example to control the interval timer */
          ITU3.TSR.BIT.IMFB = 0;  /* Clear compare mach flag */
          ITU.TSTR.BIT.STR3 = 0;  /* Stop clock */
          ITU3.GRB = time_period; /* Set next interval timer */
          ITU.TSTR.BIT.STR3 = 1;  /* Start again */
Gここで、イベントドリブン・タスクを呼んでいます。(RTM関連情報)
          reqed0();                      /* Start request for ED0 */
}

H下記関数は、イベントドリブン・タスクの初期化ルーチンです。(RTM関連情報)
void ed0_init( void )
{
          /* Initialize input(example) */
          P5.PCR.BYTE = 0xff;      /* Set pull up resistor on */
          /* Initialize output(example) */
          PA.DDR = 0x10;             /* PA4 set to output port */
          /* LED output */
          LED_GR = 1;
          LED_RD = 0;
          /* Initialize Audio output ( Use ITU CH1 ) */
          ITU1.TCR.BIT.CCLR = 2; /* Counter is cleared by GRB */
          ITU1.TCR.BIT.TPSC = 3; /* Internal,CLK/8 */
          ITU1.TIOR.BIT.IOB = 3;   /* Output toggles at GRB */
          ITU1.GRB = F_600HZ;     /* Osc frequency */
          /* Initialize Key interval counter ( Use ITU CH3 ) */
          ITU3.TCR.BIT.CCLR = 2; /* Counter is cleared by GRB */
          ITU3.TCR.BIT.TPSC = 3; /* Internal,CLK/8 */
          ITU3.GRB = 0xffff;         /* Max timer length */
          ITU.TSTR.BIT.STR3 = 1;  /* Start timer3 */
          ITU3.TIER.BIT.IMIEB = 1;/* Compare mach interrupt enable with GRB */
}

/* ED1 Task */
void ed1_main(void)
{
          ;
}
/* ED2 Task */
void ed2_main(void)

{
          ;
}

/* ED3 Task */
void ed3_main(void)
{
          ;
}
/* Cyclic Tasks */
/* CY0 Task */
void cy0_init( void )
{
          /* Initializefor Two phase type Rotary Encoder ( Use ITU CH2 )*/
          ITU.TMDR.BIT.MDF = 1;  /* Activate the phase count mode */
          ITU.TSTR.BIT.STR2 = 1;  /* Start timer2 */
}
void cy0_main( void )
{
          int                   d;
          /* Read counter data and set a frequency */
          d = ITU2.TCNT;             /* Read counter value */
}

/* CY1 Task */
void cy1_init( void )
{
          ;
}
void cy1_main(void)
{
          ;
}

/* CY2 Task */
void cy2_init( void )
{
          ;
}
void cy2_main(void)
{
          ;
}

省略
/* CY7 Task */
void cy7_init( void )
{
          ;
}
void cy7_main(void)
{
          ;
}

/* End of all source */

/*************************************************************/



H8/3048F ----- モニタープログラム
IMAGE12.GIF - 2,801BYTES
TOP02_001.PNG - 934BYTES

日立は、マイクロコンピュータ関連の講習会を古くから手がけています。無料の物から有料の物まで、下記WEBサイトで確認出来ます。
http://www.renesas.com/jpn/support/seminar/sample/index.html(モニタープログラム)
(http://www.hitachi.co.jp/Sicd/Japanese/Seminar/down.htm)
その場所で、色々なソースコードをダウンロード出来るのですが、その一つに、無料で使えるモニタプログラムがあり、勉強するには良い題材です。私も、RTM(リアルタイムモニタ)と組合わせて使えるように、改造して使わせてもらっています。私のホームページからは、私の改変した部分のみを発表します。

注意
この日立製モニタープログラムとRTMとの組合わせを、
ここでダウンロード出来ますが、組合わせやRTMの内容に関して、日立およびその関連会社へ問合わせする事はしないで下さい。
内容に関する質問は、私(新井健司)に
Eメールにてお願いします。



H8/3048F ----- ソフトウェアのダウンロード
IMAGE12.GIF - 2,801BYTES
TOP02_001.PNG - 934BYTES

Real Time Monitor
rtmH8_JH1PJL.exe(46kB)

Monitor Program
H8_Monitor_Modify.exe(51kB)


注意
この日立製モニタープログラムとRTMとの組合わせやRTMの内容に関して、(株)日立製作所およびその関連会社へ問合わせする事はしないで下さい。
内容に関する質問は、私(新井健司)に
Eメールにてお願いします。