SSブログ

ルネサスSH7216ワークショップ [RX&SH&H8]

行きます。当選しました(笑)。400MIPSとか体験して来ます。
https://update.renesas.com/registration/CampSem.do?CampaignID=WS_SH7216&language=jp®ion=jp&TOPIC=seminar

事前に予習して行かなければいけませんね。

SuperHプロセッサのアーキテクチャ

SuperHプロセッサのアーキテクチャ

  • 作者: 藤澤 幸穂
  • 出版社/メーカー: オーム社
  • 発売日: 2006/06
  • メディア: 単行本



SuperHファミリのCプログラミング

SuperHファミリのCプログラミング

  • 作者: 鹿取 祐二
  • 出版社/メーカー: オーム社
  • 発売日: 2008/09
  • メディア: 単行本



H8マイコンプログラミング ルネサス統合環境標準IO定義ファイルの使い方 [RX&SH&H8]

hew_image_58.png今まで解説をサボっていましたが、HEWのウイザードの途中で(勿論選択すれば)自動的に生成されるCPU内蔵周辺IOの定義ファイルに付いて解説します。

プロジェクトウイザードで生成されたCソースファイルが有る同じディレクトリに「iodefine.h」と言うヘッダーファイルが作成されています。このファイルをHEWのエディターウインドウに開いてみて下さい。
例えばIOポート5のレジスタであるPDR5レジスタは以下の様に定義されています。


struct st_io {                                          /* struct IO    */

             途中を省略している。

             union {                                    /* PDR5         */
                   unsigned char BYTE;                  /*  Byte Access */
                   struct {                             /*  Bit  Access */
                          unsigned char B7:1;           /*    Bit 7     */
                          unsigned char B6:1;           /*    Bit 6     */
                          unsigned char B5:1;           /*    Bit 5     */
                          unsigned char B4:1;           /*    Bit 4     */
                          unsigned char B3:1;           /*    Bit 3     */
                          unsigned char B2:1;           /*    Bit 2     */
                          unsigned char B1:1;           /*    Bit 1     */
                          unsigned char B0:1;           /*    Bit 0     */
                          }      BIT;                   /*              */
                   }            PDR5;                   /*              */

             途中を省略している。

#define IO      (*(volatile struct st_io    *)0xFFD0)   /* IO    Address*/

H8マイコンの周辺IOはMemory mapped IOであり、プログラムメモリやワークメモリ等と同じメモリ空間に存在しています。
一番下の行の記述が、0xFFD0を構造体st_ioのアドレスとして定義しています。
構造体st_ioの定義自体がその上にある記述で、特にPDR5レジスタは符号無し8bitデータとビットフィールドで共用体を構成しています。つまりこのレジスタへのアクセス方法としてbyte単位とビット単位の2つの方法を提示しており、まあ御好きな方をお使いくださいと言ったところでしょうか。

H8/3694Fのハードウエアマニュアルを見るとPDR5レジスタは以下の様になっています。


hew_image_59.pngまず肝心な事はPCR5レジスタとPDR5レジスタは対になっていると言う事です。

PDR5の0~7までのビットはそれぞれのポートに対応しており、PCR5の対応するビットが入力に設定されていた場合、PDR5レジスタを読む事で端子の状態を知る事ができます。

また、PCR5の対応するビットが出力に設定されている場合はPDR5レジスタに書き込む事で端子の状態を変化させる事ができ、読み出しを行うと、現在PDR5に書き込まれている値を読み出す事ができます。

ルネサスのH8用Cコンパイラのビットフィールドのbitオーダーは標準ではMSBから順に割り付けが行われます。他の周辺IOのレジスタもそうですが、ハードウエアマニュアルのビット名の記述となるべく一致させ、ビット毎の意味をイメージし易くしています。
※LSBから割り付けを行う事も可能です。詳しくはコンパイラーマニュアルのコンパイルオプションの項目を見てください。

ところでビットフィールドを利用するには条件があります。該当するメモリやレジスタが、必ず読み出した時に書き込んだ内容を反映する事です。
例えば「iodefine.h」の中のPCR5レジスタの記述はどうなっているか、下記に書き出してみました。
             unsigned char      PCR5;                   /* PCR5         */

これは構造体st_ioのunsigned char型のメンバーとして登録されているだけで、PDR5の様にビットフィールドとしては記述されていません。
もう一度ハードウエアマニュアルのPCR5レジスタの表を見ると、R/Wの項目はWだけになっています。つまりこのレジスタに対しては書き込み(W)のみ保証され、読み込み(R)してもその値は書いた値を反映していないと言う事です。

組み込みマイコンで頻繁に利用されるビット操作は、Read modify Write動作、つまり読み出して、変更して、また書き込む動作なので、読み出した値が書き込んだ値を反映していない場合、書き戻しの動作時に間違った値を書き込んでしまいます。
この事からHEWが生成するiodefine.hの中では、上記の様に間違ったビット操作を行わない様に配慮されています。

さて、C言語の記述の上ではPDR5レジスタへのアクセス方法はbyte単位、ビット単位で可能です。この2つの違いは実際にはどうなのでしょうか?。
ここからは実際にコードを書いてみて確かめてみます。
ちょこっといじって確かめるにはこの辺りのプロジェクトが良さそうですね。
http://hamayan.blog.so-net.ne.jp/2009-06-07-1


hew_image_60.png記述したコードを左の図に示します。

この基板上にはP80にLEDが接続され、P80にLOWを出力するとLEDが点灯します。
更にP50にスイッチを接続し、スイッチの状態をLEDに反映する様にコードを書きました。
図の中ではビットフィールドを使用して記述しています。

もしこれをビットフィールドを使わずに記述するなら、以下の様になるでしょうか。


  /*LEDが接続されているポートを出力に切り替える*/
  IO.PCR8 = 0x01;	/*0000 0001 ポート8入出力*/
  /*スイッチが接続されているポートを入力に切り替える*/
  IO.PCR5 = 0x00;	/*0000 0000 ポート5入出力 但しリセット直後は入力となっている*/
  /*スイッチが接続されているポートのプルアップを有効にする*/
  IO.PUCR5.BYTE |= 0x01;	/**/

  while( 1 )
  {
    if(IO.PDR5.BYTE & 0x01)
	  IO.PDR8.BYTE |= 0x01;
    else
	  IO.PDR8.BYTE &= ~0x01;
  }



Img_1436.jpg
共にデバックモニタ上にロードして実行させ、スイッチを押したり離したりすると、それに合わせてLEDが点滅します。機能的には同じですが、コードは違うでしょう!。と言うわけでどの様なコードが書かれているか調べてみます。
この様な場合、デバックモニタ上にロードしたプログラムの逆アセンブル表示を見て比較する方法がありますが、もっと簡単にコンパイル時のオプションとしてリスト出力を設定します。


hew_image_61.pngツールチェインのコンパイラータブのカテゴリ=リストで、「コンパイルリスト出力」にチェックを入れて、「オブジェクトプログラムのリスト出力」もチェックします。
これで再ビルドを行うと、現在実行中のセッションのディレクトリの中になんとか.lstと言うファイルが作成されていますので、それを開きます。


下がビットフィールドを使った時のリスト出力です。※オリジナルはCソースと混在で比較し難いので、アセンブル出力のみ抽出。
     000C  F801                   MOV.B       #1,R0L
     000E  38EB                   MOV.B       R0L,@65515:8
     0010  1800                   SUB.B       R0H,R0H
     0012  30E8                   MOV.B       R0H,@65512:8
     0014  7FD17000               BSET.B      #0,@65489:8
     0018                     L6:                                   
     0018  7ED87700               BLD.B       #0,@65496:8
     001C  7FDB6700               BST.B       #0,@65499:8
     0020  4000                   BRA         L6:8

以下はbyte単位
     000C  F801                   MOV.B       #1,R0L
     000E  38EB                   MOV.B       R0L,@65515:8
     0010  1800                   SUB.B       R0H,R0H
     0012  30E8                   MOV.B       R0H,@65512:8
     0014  7FD17000               BSET.B      #0,@65489:8
     0016                     L6:                                   
     0016  7ED87300               BTST.B      #0,@65496:8
     001A  4700                   BEQ         L8:8
     001C  7FDB7000               BSET.B      #0,@65499:8
     0020  4000                   BRA         L6:8
     0022                     L8:                                   
     0022  7FDB7200               BCLR.B      #0,@65499:8
     0026  4000                   BRA         L6:8

byte単位の場合、特定のビットのみ代入する記述ができないので、条件式により動作を変える方法を取っていますが、それがこの様な結果になっていますね。

命題として「P50の状態をP80に反映する」となっているので、ビットフィールドを使った場合の方がより直接的に理解し易く記述できている点も見逃せません。
しばしばビットフィールドは移植性が無いと敬遠され勝ちですが、組み込みマイコンのポートを操作している時点で移植性なんてまるっきり期待できませんし、コンパイラによってビットオーダーが変わるとバグになり易いとか言う話も、その辺はコンパイラメーカーも良く判っていて、先に述べた様にコンパイルオプションで対応可能なのです。基本的に新しいコンパイラを使用する時は、まずはマニュアルに目を通しましょう。
そんな訳でまあ今更ビットフィールドを否定する理由は特に無いんじゃないかと思います。

但し、HEWで生成するiodefine.hや、ルネサスの半導体セミナーのページで配付しているCPU別ヘッダーファイルは、当然その動作保証はルネサスのコンパイラに限られるので、それ以外のコンパイラで使う方は良く自分で使うコンパイラのマニュアルを調べてから使った方が良いです。

※実はこのビット同士の代入の例題はずるです。H8マイコンではこのビットフィールドの直接代入を行う記述をした方が効率が良い事は知っていましたからね。

SuperHファミリのCプログラミング

SuperHファミリのCプログラミング

  • 作者: 鹿取 祐二
  • 出版社/メーカー: オーム社
  • 発売日: 2008/09
  • メディア: 単行本



C言語でH8マイコンを使いこなす

C言語でH8マイコンを使いこなす

  • 作者: 鹿取 祐二
  • 出版社/メーカー: オーム社
  • 発売日: 2003/10
  • メディア: 単行本



H8マイコン+C言語効率アップテクニック

H8マイコン+C言語効率アップテクニック

  • 作者: 鹿取 祐二
  • 出版社/メーカー: オーム社
  • 発売日: 2004/11
  • メディア: 単行本



緊急デバック! H8マイコンとパスワールドさんカラーLCDをE8でデバックする。 [RX&SH&H8]

Img_1435.jpg
Img_1434.jpg
パスワールドさんhttp://passworld.co.jp/からのいただき物ですが、横128ピクセル、縦160ピクセルのカラーCSTN LCDをH8で動かしました。
サンプルコードを貰っていたのですが、MSP430用のコードであり、H8用のコードに置き換えるのちょっと手間取ってしまったので(つまり一発では動かなかった)、急遽E8の出動です。

ステップ実行で配線も含めて確認しながらデバックを行い、サンプルの表示が出るまで進みました。

やっぱりデバッカーが有ると楽ですね、精神的にも「上手く行かなきゃ最後はこれを持ち出せばいい!」って思えるので楽です。

で!、やっぱりLCDもカラーが良いね!。

※カラーLCDに付いては、もう少しいじってからネタにするかもしれません。

C言語でH8マイコンを使いこなす

C言語でH8マイコンを使いこなす

  • 作者: 鹿取 祐二
  • 出版社/メーカー: オーム社
  • 発売日: 2003/10
  • メディア: 単行本



H8マイコン完全マニュアル

H8マイコン完全マニュアル

  • 作者: 藤沢 幸穂
  • 出版社/メーカー: オーム社
  • 発売日: 2000/12
  • メディア: 単行本



H8マイコンで割り込みしよう2 デバックモニタ上で割り込みの実現をしてみる 後編 [RX&SH&H8]

Img_1425.jpgええっと、前回は何をしたんだっけ。ああそうか、デバックモニタ上でプログラムを実行する時のメモリイメージを描いたのですね。

では、実際にプロジェクトを作成してみます。

今回も新たにプロジェクトを生成します。ここでやった手順でプロジェクトを作成してください。
http://hamayan.blog.so-net.ne.jp/2009-06-07-1


hew_image_52.png最終的にはこの様にHEWが起動しています。
左のペインの中で表示されている幾つかのファイルの内、「mon_int_sample.c」はこのプロジェクトを生成した時のプロジェクト名がそのまま関数mainを含むファイルとしてウイザードが生成したものですが、更に自分で「vector.c」と「startup.c」と言うファイルを追加しています。

それではこれら2つのファイルの内容を以下に掲載します。


vector.c
#include <machine.h>
#include "iodefine.h"

void startup( void ); /*BOOT処理*/

#pragma interrupt(abort) /*NMI*/
void abort( void ){}

#pragma interrupt(TRAP0) /*トラップ命令#0*/
void TRAP0( void ){}

#pragma interrupt(TRAP1) /*トラップ命令#1*/
void TRAP1( void ){}

#pragma interrupt(TRAP2) /*トラップ命令#2*/
void TRAP2( void ){}

#pragma interrupt(TRAP3) /*トラップ命令#3*/
void TRAP3( void ){}

#pragma interrupt(ADRBRK) /*アドレスブレーク*/
void ADRBRK( void ){}

#pragma interrupt(CPUSLEEP) /*スリープ命令実行による直接遷移*/
void CPUSLEEP( void ){}

#pragma interrupt(IRQ0) /*外部割込み端子0*/
void IRQ0( void ){}

#pragma interrupt(IRQ1) /*外部割込み端子1*/
void IRQ1( void ){}

#pragma interrupt(IRQ2) /*外部割込み端子2*/
void IRQ2( void ){}

#pragma interrupt(IRQ3) /*外部割込み端子3*/
void IRQ3( void ){}

#pragma interrupt(WKP) /*外部割込み端子WKP*/
void WKP( void ){}

#pragma interrupt(TAOVI) /*タイマーAオーバーフロー*/
void TAOVI( void )
{
  IRR1.BIT.IRRTA = 0;  /*割込み条件のクリア*/
  IO.PDR8.BIT.B0 ^= 1;  /*LEDチカチカ*/
}

#pragma interrupt(TIMERW) /*タイマーW*/
void TIMERW( void ){}

#pragma interrupt(TIMERV) /*タイマーV*/
void TIMERV( void ){}

#pragma interrupt(SCI_3) /*シリアル*/
void SCI_3( void ){}

#pragma interrupt(IIC_2) /*I2C*/
void IIC_2( void ){}

#pragma interrupt(ADI) /*A/D*/
void ADI( void ){}



#pragma section VECT
/* 仮想ベクタテーブル */
void (*const VEC_TBL[])(void) =
{
  startup,    /*Vector 0 Reset Vector*/
  (void *)0,  /*Vector 1*/
  (void *)0,  /*Vector 2*/
  (void *)0,  /*Vector 3*/
  (void *)0,  /*Vector 4*/
  (void *)0,  /*Vector 5*/
  (void *)0,  /*Vector 6*/
  abort,      /*Vector 7*/
  TRAP0,      /*Vector 8*/
  TRAP1,      /*Vector 9*/
  TRAP2,      /*Vector 10*/
  TRAP3,      /*Vector 11*/
  ADRBRK,     /*Vector 12*/
  CPUSLEEP,   /*Vector 13*/
  IRQ0,       /*Vector 14*/
  IRQ1,       /*Vector 15*/
  IRQ2,       /*Vector 16*/
  IRQ3,       /*Vector 17*/
  WKP,        /*Vector 18*/
  TAOVI,      /*Vector 19*/
  (void *)0,  /*Vector 20*/
  TIMERW,     /*Vector 21*/
  TIMERV,     /*Vector 22*/
  SCI_3,      /*Vector 23*/
  IIC_2,      /*Vector 24*/
  ADI,        /*Vector 25*/
};


startup.c
#include <machine.h>

void main( void );

void startup( void )
{
#pragma asm
  MOV.W #(STARTOF BSTK) + (SIZEOF BSTK),R7
#pragma endasm
//  set_imask_ccr(1);  /*全体の割り込み禁止*/
  _INITSCT();
 
  main();

  while(1) ;
}

/***********************************************************/
/* スタック領域として領域の確保を行う。                      */
/***********************************************************/
#pragma section STK
static char stack_area[256];

「vector.c」の中身はhttp://hamayan.blog.so-net.ne.jp/2009-06-12-1で紹介した「intprg.c」の中身に似ていますが、若干の違いが有ります。
例えば「intprg.c」の中でTimer A オーバーフロー割り込みは以下の様に記載されていました。
__interrupt(vect=19) void INT_TimerA(void)
{
  IRR1.BIT.IRRTA = 0;  /*割込み条件のクリア*/
  IO.PDR8.BIT.B0 ^= 1;  /*LEDチカチカ*/
}

しかしこの「vector.c」では以下の様に記述しています。
#pragma interrupt(TAOVI) /*タイマーAオーバーフロー*/
void TAOVI( void )
{
  IRR1.BIT.IRRTA = 0;  /*割込み条件のクリア*/
  IO.PDR8.BIT.B0 ^= 1;  /*LEDチカチカ*/
}

__interruptと#pragma interruptは同じ意味で、後ろに続く関数を割り込み関数として認識させるものです。

ここでの大きな違いは(vect=19)の有り/無しです。これは前にも解説したように割り込みベクター番号19の位置に関数の先頭アドレスを埋め込む様に指示している宣言です。

なのでhttp://hamayan.blog.so-net.ne.jp/2009-06-12-1では特に割り込みベクターテーブルの記述を行っていません。

ではデバックモニタで割り込みを使用する時もHEWのウイザードが生成した「intprg.c」を使えばよいじゃないか!と思われるでしょうけれど、そうは行かないのです。

(vect=?)を使う方法はデバックモニタ上にプログラムをロードする上で問題が発生します。つまり埋め込み先はFLASH ROM領域であり、幾らデバックモニタ上にロードしてもFLASH ROMの内容までは書き換える事ができません。このプログラムを無理やり実行するとおそらくデバックモニタは不正な割り込みが発生した!とメッセージを出力し、そこで実行を停止するでしょう。

そこで今回の「vector.c」なのですが、この場合は関数が割り込み処理である事は宣言していますが、メモリ上のどの位置に割付すると言った情報は一切記載されていません。この割付に関してはビルド時にコンパイラの後の処理で実行されるリンカーに一任しています。コンパイラはいわゆるリロケータブルなオブジェクトファイルを生成します。

※これは、随分前に戻ってしまいますが、http://hamayan.blog.so-net.ne.jp/2009-06-03で紹介したワークフローの中でコンパイラからリロケータブルオブジェクトファイルを生成して、それが最適化リンケージエディタに読み込まれるまでの流れですね。

もう一つ、「startup.c」ですが、こちらは「resetprg.c」に相当するファイルです。「resetprg.c」を開いてみて下さい。あちこちコメントアウトしてあって実に読み難いファイルですが、ポイントは以下の宣言です。
__entry(vect=0) void PowerON_Reset(void);

__interruptの記述に似ていますが、__entry(または#pragma entry)はリセット時専用の宣言です。
この宣言で修飾された関数はリセット直後に実行される関数として認識され、関数の先頭に自動的にスタックポインタの初期化が挿入されます。

試しに「resetprg.c」のコンパイル時にアセンブラリスト出力を行うコンパイルオプションを設定して内容を見てみます。※実際の出力から無関係な記述は省略されています。
        22:    __entry(vect=0) void PowerON_Reset(void);
        54:    #pragma section ResetPRG
        55:    
        56:    __entry(vect=0) void PowerON_Reset(void)
     0000                     _PowerON_Reset:                      ; function: PowerON_Reset
     0000  79070000               MOV.W       #STARTOF S+SIZEOF S,R7
        57:    { 

MOV.W #STARTOF S+SIZEOF S,R7
は、スタック領域として使用されるSセクションの先頭アドレスにスタックサイズを加算した値を、スタックポインタとして使用されるR7レジスタに代入しています。

もちろん「startup.c」でも関数「startup」で初っ端にスタックポインタの設定を行っています。この場合はBSTKと言うセクションを使用しており、BSTKの実体はこの「startup」の下に続く領域の宣言としてSTKセクションを宣言しています。
※H8のコンパイラではC言語でセクションを宣言した場合、自動的に頭に
P:プログラムコードの意味。
C:定数の意味。
D:初期化付き変数の意味。
B:0クリアのみの変数の意味。
が付加されます。

そして、
__entry(vect=0)
と記述されているところから判る様に、この宣言もまた絶対アドレスで0x0000を示しており、デバックモニタ上ではこの情報を正常にロードする事ができません。やはりスタートアッププログラムもリロケータブルである必要があります。

ちなみに、実はデバックモニタ上でユーザープログラムを実行する時は特にプログラムの初っ端でスタックポインタの設定をする必要がありません。実はです(笑)。

デバックモニタからユーザプログラムへCPUの実行が移る時、デバックモニタが適当なスタックポインタを設定してくれています。
だからスタックポインタの設定を一切行っていない”Hello World”プログラムが何の問題も無く動いたのです。


話が長くなって書いている本人が疲れたので、ここからは飛ばします。
ツールチェインのダイアログを開いて以下のポイントを変更します。
hew_image_56.png インラインアセンブル(#pragma asm)を使用する時は、Cソースの出力ファイル形式をアセンブル出力にして置く。
hew_image_53.png エントリーポイントにチェックを入れて「_startup」と入力します。

アンダースコアが付くのは、C言語で宣言されたラベルには自動的にラベルの先頭にアンダースコアが付加されるからです。お忘れ無く。
hew_image_54.png セクションの内容を変更します。0x0000F880を選択して編集モードに切り替えたのが次の画面です。

言うまでも無いですが0x0000F880はデバックモニタの”?”コマンドで出力されたUser Vectorのアドレスに合わせてあります。

※勿論配置アドレスを0番地に設定してROMイメージ(MOTファイル)を作成し、それをH8マイコンに書き込めば、そのまま動かす事ができます。
hew_image_55.png 通常はROMにはこのセクション、RAMにはあのセクションって振り分けて設定するのですが、今回は全部RAM上で展開する関係上、一緒くたにして記述しています(笑)。いい加減ですね。



hew_image_57.pngHTERMを起動し、デバックモニタが書かれているH8マイコンと接続し、今回作成したプログラムのロードを行うと画面の様になります。
黄色くハイライトされている行がPCの位置を表し、ステップ実行等を行えばこの黄色い帯も移動します。

※このプログラムは、ポートにLEDを接続しておくと、実行した時にLEDがチカチカします。

※実際のところ「vector.c」や「startup.c」は決まりきった記述、決まりきった処理なので、デバックモニタ上で動くプログラムを作成したくなったら、今回の手順でプロジェクトを生成し、上の「vector.c」と「startup.c」をコピーし、適当に編集して使うとよいと思います。

ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発

ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発

  • 作者: 濱原 和明
  • 出版社/メーカー: オーム社
  • 発売日: 2005/04/25
  • メディア: 単行本



H8マイコンで割り込みしよう2 デバックモニタ上で割り込みの実現をしてみる [RX&SH&H8]

Img_1425.jpg前回はHEWのウイザードに従って作成したプロジェクトに、自動的に生成された割り込み関数を使って割り込みを実現しましたが、今回は自力で割り込み処理に関する記述を追加して、それをデバックモニタで利用します。

H8/3694FのRAM上にユーザープログラムをダウンロードしてデバックを行うので、デバックできるプログラムサイズは相当に小さくなってしまい、実用的なプログラムのデバックは困難です。「ならやってみる意味無いじゃん」と思われるかもしれませんが、以外と面白い話も有りますので、宜しければ読んでみてください。

まずその前にデバックモニタで割り込みを実現する概念についての解説を行います。


hew_image_50.pngデバックモニターが稼動しているH8/3694F上に割り込み付きユーザープログラムをダウンロードしたイメージは図の様になります。

これはMAP出力及びデバックモニタの”?”コマンドの出力から描き起こしました。


MAP出力の一部
*** Mapping List ***

SECTION START   END        SIZE   ALIGN

CVECT
      0000f880  0000f8b3      34   2
P
      0000f8b4  0000f949      96   2
D
      0000f94a  0000f94a       0   2
C$BSEC
      0000f94a  0000f94d       4   2
C$DSEC
      0000f94e  0000f953       6   2
R
      0000f954  0000f954       0   2
B
      0000f954  0000f954       0   2
BSTK
      0000f954  0000fa53     100   2

デバックモニタの”?”コマンド出力の一部
?
 Monitor Vector 0000 - 003F
 Monitor ROM    0100 - 6B09
 Monitor RAM    F780 - F87F
 User    Vector F880 - F8BF

文字の背景色が青のところはFLASH ROM上に置かれ、ピンクのところはRAM上に置かれます。黄色はIOレジスタで、今回の話には関係しません。

さて、H8/300Hマイコンの割り込みベクターの開始アドレスは必ず0番地から開始する必要があります。しかしこのアドレスから始まる領域はFLASH ROM空間でもあり、ユーザープログラムの全てをRAM上に転送する事を前提としているデバックモニタではそのままでは割り込みが使用出来ない事となります。※FLASH ROM上にユーザープログラムやユーザーベクターを”書く”事は一応出来ない事としている。

そこでデバックモニターでは仮想ベクターと言う概念を使う事でユーザー割り込みの実現をしています。



hew_image_51.png割り込み発生時には、まずデバックモニタ上の割り込み処理が応答します。この割り込みの中では自分自身の割り込みベクター番号が判っているので、その番号に該当するユーザーベクター領域の該当アドレスから実際に行うべき関数の先頭アドレスを読み取り、そのアドレスの先にジャンプします。

例えば割り込み番号が19のタイマーAのオーバーフロー割り込みが発生したとします。
タイマーAのオーバーフロー割り込みの絶対アドレスは0x0026なので、デバックモニタの割り込み処理の中ではUser Vector領域のアドレス+0x0026番地(0xF880+0x0026=0xF8A6)を加算したところから関数の先頭アドレスを取得します。
FILE=C:\WorkSpace\sample\mon_int_sample\Debug\vector.obj
                0000f8d0  0000f8fb        2c
  _abort
                0000f8d0         2   func ,g         * 
  _TRAP0
                0000f8d2         2   func ,g         * 
  _TRAP1
                0000f8d4         2   func ,g         * 
  _TRAP2
                0000f8d6         2   func ,g         * 
  _TRAP3
                0000f8d8         2   func ,g         * 
  _ADRBRK
                0000f8da         2   func ,g         * 
  _CPUSLEEP
                0000f8dc         2   func ,g         * 
  _IRQ0
                0000f8de         2   func ,g         * 
  _IRQ1
                0000f8e0         2   func ,g         * 
  _IRQ2
                0000f8e2         2   func ,g         * 
  _IRQ3
                0000f8e4         2   func ,g         * 
  _WKP
                0000f8e6         2   func ,g         * 
  _TAOVI
                0000f8e8         a   func ,g         * 
  _TIMERW
                0000f8f2         2   func ,g         * 
  _TIMERV
                0000f8f4         2   func ,g         * 
  _SCI_3
                0000f8f6         2   func ,g         * 
  _IIC_2
                0000f8f8         2   func ,g         * 
  _ADI
                0000f8fa         2   func ,g         * 

通常の割り込み処理に比較すれば一手間多い訳ですが、それ以外のところではユーザーがあまり意識しないで割り込みを利用できます。
ユーザーが気にしなければならない点は、ユーザーベクターが必ずデバックモニタのUser Vector領域に一致すると言う点です。

その為にはユーザーがリンカーに対してユーザーベクターを所望のアドレスから配置するように設定してやる必要があります。
次回はその辺りの解説をするつもりです。

ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発

ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発

  • 作者: 濱原 和明
  • 出版社/メーカー: オーム社
  • 発売日: 2005/04/25
  • メディア: 単行本



H8マイコンで割り込みしよう [RX&SH&H8]

Img_1425.jpgちょっと間が空いてしまいましたが、割り込み処理をやってみます。割り込みの無いマイコンなんて、、、フッ!。

割り込みの実現の仕方について、通常の記述と(今回)、デバックモニタでの割り込みの実現方法(次回)の両方を解説します。


それでは今まで作業をしてきたsampleワークスペースを開きます。
もしHEWの画面が図の様に前回のプロジェクト名が太字になっていた場合は、始めに作成したプロジェクトを選択し、右クリックで「アクティブプロジェクトに設定」を行います。
hew_image_47.png


左のペインの中の「intprg.c」をダブルクリックしてエディットWindowに「intprg.c」を開きます。
まずファイルの先頭付近、machine.hをインクルードしている直後にiodefine.hもインクルードしておきます。
#include "iodefine.h"

次に55行目付近の修正を行います。
// vector 19 Timer A Overflow
とコメントされている行の下に関数があります。今回はこのTimer Aを使って定周期で割り込みを発生させ、やっぱりLEDをチカチカさせます。
__interrupt(vect=19) void INT_TimerA(void)
{
  IRR1.BIT.IRRTA = 0;  /*割込み条件のクリア*/
  IO.PDR8.BIT.B0 ^= 1;  /*LEDチカチカ*/
}

これだけです。
関数の中身の最初の行は、割り込みコントローラのフラグbitをクリアしています。これを行わないと次の割り込みが発生しなくなります割り込み処理から抜けてもまた割り込みが発生してしまい、それが永久に続くのでお忘れ無く。

次の行が実際にLEDをチカチカさせている処理です。最初にmain関数の中に記述した物をここに持って来ただけです。

次にmain関数にはどういった記述を行っているのか紹介します。
void main(void)
{
  /*LEDが接続されているポートを出力に切り替える*/
  IO.PCR8 = 0x01;	/*0000 0001 ポート8入出力*/
  /*TAの初期化 インターバルタイマーとして使用する*/
  TA.TMA.BIT.CKSI = 0;  /*CPUクロックを1/8192する*/
  IENR1.BIT.IENTA = 1;  /*TA割り込みを許可*/

  while( 1 ) ;
}

これまた簡単な内容ですが、IOポートやTimer Aの初期化を行って、割り込みをイネーブルし、最後は無限ループに入っているだけです。
このボードのCPUクロックは20MHzとなっています。TimerAをインターバルタイマーとして使用すると、TA.TMA.BIT.CKSIで選ばれた分周比でCPUクロックが分周され、次に続くカウンターで分周されたクロックを256個数えられます。
実際には0~255まで数えるのですが、TimerAは255から0に戻る時(8bitカウンターがオーバーフローする時)、割り込みがイネーブルされていた場合、割り込みを発生します。
結局20000000÷8192÷256≒9.5Hzで割り込みが発生する事となり、LEDの点滅周期は≒210msとなります。

ビルドを行い、FDTを使ってターゲットに書き込みを行います。
書き込みモードを解除して通常の動作モードに切り替えてみると、LEDがチカチカ点滅しているのを見る事が出来ると思います。

これでダサい?ソフトウエアループを使ったLEDチカチカから、割り込みを使ったスマートなLEDチカチカ(笑)にステップアップできました。

おっと、肝心な事を書き忘れていました。
__interrupt(vect=19) void INT_TimerA(void)
と記述されていますが、最初の__interruptはこの関数が割り込み処理である事を示し、続くvect=19はベクター番号を指定しています。

割り込みベクターはROMの0番地から始まる領域に書く事が決まっており、0番地がベクター番号0となっています。ベクター番号19と書く事でコンパイラは自動的にROMの書き込みアドレス(H8/Tinyの場合は19×2)を計算する事が可能となり、実際にそのアドレスの位置に割り込み関数のアドレスを埋め込みます。

後ろの型の宣言は通常のC言語の関数そのものの宣言です。


H8マイコン完全マニュアル

H8マイコン完全マニュアル

  • 作者: 藤沢 幸穂
  • 出版社/メーカー: オーム社
  • 発売日: 2000/12
  • メディア: 単行本



C言語でH8マイコンを使いこなす

C言語でH8マイコンを使いこなす

  • 作者: 鹿取 祐二
  • 出版社/メーカー: オーム社
  • 発売日: 2003/10
  • メディア: 単行本



ごめんよぅルネサス、ごめんよぅ [RX&SH&H8]

hew_image_46.png設計が古いなんて書いてごめんよぅ。

最近のラインナップ知らなかったけど、今日どんな物が有るのか見てみたら、SSU(SPI)付きの物も、高速オンチップオシレーター付きの物も有るのね。
最近ではFLASH ROMの耐久性がmin1000回、typ10000回になったのね。
今まではH8/3687F最強と思っていたけれど、、、。

H8/36077が良いよね。3687Fの後継っぽい。
でも、デジキーでは0.8mmピッチのでっかい方のパッケージしか売っていなかったのよ。

と言うか、お願いだから全部入りのやつ出してー。
と言うか、早くRXマイコン触らしてくれー。

※高速オンチップオシレータとかSSUとか、なんとなく三菱の風を感じる。霧が峰か!。

H8マイコン完全マニュアル

H8マイコン完全マニュアル

  • 作者: 藤沢 幸穂
  • 出版社/メーカー: オーム社
  • 発売日: 2000/12
  • メディア: 単行本



C言語でH8マイコンを使いこなす

C言語でH8マイコンを使いこなす

  • 作者: 鹿取 祐二
  • 出版社/メーカー: オーム社
  • 発売日: 2003/10
  • メディア: 単行本



あれ、今更だけれど [RX&SH&H8]

今更だけれど、H8/Tinyには多重割り込みの機能が無いじゃん。


と言う事は、HOS-V4でH8/Tinyに対応しているけれど、pacintn.src内で行っている多重割込みの処理は要らないという事になるじゃん、、、。
何故今まで気付かなかったのか。

T-SH2MBへTCP/IPプロトコルスタックを実装中 [RX&SH&H8]

11528824.jpg次の事に進む前に、どうしてもこれが気になるので、ある程度動かせる事を確認してしまおう!と言う話。
TCPやUDPを完成させる前に、ネットワークコントローラや下位ドライバーの足腰を確認しておきます。つまり、うんと負荷を掛けた状態で、なるべくロストを小さくするとか、ハングしないとか、エラー処理がきちんと行われるとか、応答が早いか等ですね。
t-sh2mb_001.pngで、確認にはnmapが取り敢えずお手軽に負荷を掛ける事ができるので、ネットからnmapを落してきて、試してみました。
当然始めは駄目駄目で、ちまちま改良してようやくここまで来ました。
左の図はRAM上(デバックモニタ上)で動かした時の結果で、平均して1.9秒程度で完了します。
ROM上で動かすと、これが結構バスにWAITを入れねば安定しませんでしたが、平均して1.3秒程度で完了します。
まあここまで来れば十分実用になるでしょう。あまりnmap向けチューニングとかやっても実情と合わなかったりもしますので。

SuperHで学ぶμITRON仕様OS―リアルタイムOSの動作原理と実装法がわかる!

SuperHで学ぶμITRON仕様OS―リアルタイムOSの動作原理と実装法がわかる!

  • 作者: 鹿取 祐二
  • 出版社/メーカー: 電波新聞社
  • 発売日: 2005/12
  • メディア: 単行本



SuperHプロセッサのアーキテクチャ

SuperHプロセッサのアーキテクチャ

  • 作者: 藤澤 幸穂
  • 出版社/メーカー: オーム社
  • 発売日: 2006/06
  • メディア: 単行本



SH2ボード(T-SH2MB)、H8ボード(T104-H8A、B)の価格 [RX&SH&H8]


T-SH2MBが基本構成で17800円、T104-H8A、Bが基本構成で19800円だそうです。
写真は基本構成と一致しない可能性がありますので、購入前にTAC様に連絡を取って確認してくださいね。
いよいよ、あの付録基板を持っているからと言って、あのベースボードを買う理由が、、、。

若松が何故あの価格で出しているのか?不明らしいです。


この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。