2010年5月27日木曜日

付属SH-2A基板 開発メモ

一旦、これまでの付属SH-2A基板の開発手順および、注意点をまとめます。

履歴
 6/6変更                
 6/7変更、追記
 6/12、追記
6/23、追記
 8/1  追記


Ⅰプログラム開発
 1.HEW 新規プロジェクトワークスペースの作成
  1)「ようこそ」で「新規プロジェクトワークスペースの作成」を選択
   ・「ワークスペース名」を入力    "sh2a_wksp"
    (プロジェクト名はワークスペース名と同じ)
   ・「ディレクトリ」を入力(参照)
   ==> 参照で指定したディレクトリが "c:\sh2a_home" とすると "c:\sh2a_home\sh2a_wksp" となる。
   ・CPU種別 "SuperH RISC engine"  そのまま
   ・ツールチェイン "Renesas SuperH Standard"  そのまま
  2)CPU設定
   ・ツールチェインバージョン "9.3.2.0" そのまま
   ・CPUシリーズ "SH2A-FPU" を選択
   ・CPUタイプ "SH72620" を選択
  3)グローバルオプション設定
   ・浮動小数点演算モード "MIX" そのまま
   ・丸め方式 "Zero" そのまま     ・・・・ 要 検討
  4)自動生成 設定
   ・ヒープメモリ "使用" で サイズ H'400
   ・main()関数生成 "C source file"  そのまま  
   ・I/Oレジスタ定義ファイル "使用"
  5)ライブラリ設定
   ・ctype.h math.h を "使用"
   ・stdarg.h を 試しに 使用 ひょっとして printf() sprintf()で必要かも?
  6)スタック設定
   ・スタックポインタアドレス H'1C100000 に変更
   ・スタックサイズ H'FA00 に変更
  7)ベクタ設定
   ・ベクタテーブル定義 "使用"
    "PowerON_Reset_PC" "Manual_Reset_PC" のベクタハンドラがエントリされている。
  8)ターゲット設定
   ・ターゲット 
    "SH2A-FPU Cycle Base Simulator"
    "SH2A-FPU Functonal Simulator" 両方使わず。
   ・ターゲットタイプ/ターゲットCPU 1)CPU設定の通りの内容が表示 そのまま

    「完了」


 2.ユーザーライブラリ使用設定
  1)インクルードファイルディレクトリの指定
   「SuperH RISC engine Standard Toolchain」のコンパイラ/ソース/インクルードディレクトリで「追加」
   ・相対パスはCustom directoryを選択
   ・ブラウズでユーザーライブラリのインクルードディレクトリを選択
  2)ユーザーライブラリの設定
    「SuperH RISC engine Standard Toolchain」の最適化リンカ/入力/ライブラリファイルで「追加」
   ・相対パスはCustom directoryを選択
   ・ブラウズで ユーザーライブラリ.libを選択
         

 3.テストプログラムの作成
  1)main()の編集
   プロジェクト名.cのファイルにmain()がある。
   ・インクルードファイルの追加
    "iodefine.h","" に加え ユーザー定義インクルードファイルを追加。
   ・while(1)ループを追加
   ・プログラムコードを追加
  2)割り込み設定 intprg.c の編集
  インターバルタイマを MTU2 の TGInA で実現した 場合  
   ・179:MTU0_TGI0A (Timer0 で使用)
   ・186:MTU1_TGI1A (Timer1 で使用)
   ・190:MTU2_TGI2A (Timer2 で使用)
   ・194:MTU3_TGI3A (Timer3 で使用)
   ・199:MTU4_TGI4A (Timer4 で使用) で 割り込みでCallされるハンドラ関数を記述する。
    ※例
    // 179 MTU2 MTU0 TGI0A
    #pragma ifunc INT_MTU2_MTU0_TGI0A,int_mtu_tgi0a
    void INT_MTU2_MTU0_TGI0A(void){
      extern void int_mtu_tgi0a(void);
      int_mtu_tgi0a();
    }

  3)割り込みベクタの設定 vecttbl.cの編集
   HEWモニタプログラムでのプログラムの設定 
    #pragma section INTTBL
    void *INT_Vectors[] = {
    // 8 Reserved
     (void*) RESET_Vectors,// Dummy, Used by SPI-Flash boot

  4)割り込みベクタの設定 vecttbl.hの編集
    レジスタバンクの指定
    // 179 MTU2 MTU0 TGI0A
    #pragma interrupt INT_MTU2_MTU0_TGI0A
     を
    #pragma interrupt INT_MTU2_MTU0_TGI0A(resbank)
     に

 4.ROM化の設定
  1) resetprg.cの修正
    インクルードファイル "iodefine.h" を追加
    インクルードファイル "typedefine.h"の削除

    プログラムコード INTC.IBNR.WORD = 0x4000; を追加( _INITSCT();の前 )
  2)出力ファイル形式の設定
   「SuperH RISC engine Standard Toolchain」の最適化リンカ/出力
    の出力形式をバイナリへ変更

 5.セクションの設定
  ・DVECTTBL,DINTTBL: 0x1C000000
  ・PResetPRG,PinPRG: 0x1C000500
  ・P,C,C$BSCE,C$DSEC,D: 0x1C001000
  ・B,R: 0x1C061000
  ・S: 0x1C0F0600
 
 6.新規セッションの作成
  1)新規セッション
   ・セッション名 適宜
   ・ターゲット SH-2A Serial Monitor を選択
   ・使用するプロジェクトジェネレータ Renesas SH Project Generator そのまま
  2)CPU選択
   ・CPUシリーズ "SH2A-FPU" を選択
   ・CPUタイプ "SH72620" を選択
 
Ⅱ工夫
 1.割り込みハンドラ設定  例)MTU2 Ch0-a
   割り込みハンドラ関数の設定を関数ポインタで行うことで、割り込み時にCallされる関数をプログラムで切り替えるように修正(割り込み発生時に分岐(if文、 switch文)させるのではなく、割り込み発生前にすでに、割り込みハンドラ関数を切り替えられるように修正)

  1)割り込みプログラム"intprg.c"での割り込みハンドラ関数の設定を変更
    #pragma ifunc INT_MTU2_MTU0_TGI0A,int_mtu_tgi0a
    void INT_MTU2_MTU0_TGI0A(void){
      extern void (*int_mtu_tgi0a)(void);
      (*int_mtu_tgi0a)();
    }
  2)割り込みハンドラ関数の宣言 main.c
    void (*int_mtu_tgi0a)(void);
  3)割り込みハンドラ関数の宣言 その他のソース
    extern void (*int_mtu_tgi0a)(void);
  4)割り込みハンドラ関数の実装 ユーザーソース
   ①割り込みハンドラー関数 設定関数  ユーザーソース1
    void TIMER_Set_Intrrupt(TIMER_TypeDef* TIMERx,void *pfunc,int intpri)
    {
        switch(TIMERx->Timer_ID)
        {
        case TIMER_ID_0:
            INTC.IPR11.BIT._MTU00 = (u8)intpri;
            INTC.IPR11.BIT._MTU01 = (u8)intpri;
            int_mtu_tgi0a = pfunc;
           break;
        case TIMER_ID_1:
   ②割り込みハンドラー関数 設定 ユーザーソース2
    #define APP_INTRPT_PRIORITY 6
    extern void (*int_mtu_tgi0a)(void);

    void APP_TM2_IRQInterrupt(void) ・・この関数を割り込み時にCallされるように設定。
    {
      ・・・・・・・・・・
      TIMER_InterruptReset(&TIMER_2); ・タイマスタートレジスタ(TMSTSR)で割り込みフラグクリア、タイマインタラプトイネーブルレジスタ(TMIER)で割り込み許可を行う。
    }  

    void App_examplefunc()
    {
      ・・・・・・・・・・
      TIMER_Set_Intrrupt(&TIMER_2,APP_TM2_IRQInterrupt,APP_INTRPT_PRIORITY);
      ・・・・・・・・・・
      return;
    }

 2.大きな初期化データの扱い。 6/12追記
  画像データの表示に、ヘッダーファイルで定義された配列の初期化データを使った場合、プログラムファイルは、その分大きくなる。HEWのライセンス制限を考えると、画像データをバイナリファイルにし、HEWのダウンロードファイルとして扱う、プログラムでは、ダウンロード先のアドレス指定でデータを扱う。

 3.セクションの利用 (大きな初期化データの扱い。)6/23追記
  データ領域に設定したデータが、原因不明(たぶん私のバグが原因と思う)で潰れていた、その分析、対処で、そのデータ領域を任意のアドレスに配置するために セクションを利用しました。
  1)コーディング ソースファイル(*.c)
   ユーザー関数の前に #pragma section SECTION_NAME を記述    
  2)コーディング ヘッダーファイル(*.h)
   ヘッダー定義の先頭に #pragma section SECTION_NAME を記述    
   ヘッダー定義の末尾に #pragma section を記述・・・セクション指定を解除
  3)セクションの設定(作成)
   ①セクションアドレスの設定
    シンボル表示で空きアドレスを確認する。

   以降 [SuperH RISC engine Standard Toolchain] の作業
   ②セクション PSECTION_NAMEを設定 プログラム領域 
   ③セクション CSECTION_NAMEを設定 定数領域 
     const unsigned char CnstXxT[128] =
       {0,3,1,4,1,5,9,2,6,5,3,5,,,,,,,};
   ④セクション DSECTION_NAMEを設定 初期化データ領域 
     unsigned char XxT[128] =
       {0,3,1,4,1,5,9,2,6,5,3,5,,,,,,,};
   ⑤セクション BSECTION_NAMEを設定 未初期化データ領域 
     unsigned char WkXxT[128];
   ※設定(作成)したセクションに、メンバーとなる関数、定数、変数の定義が無い場合、ビルドでワーニングが出る。ワーニング表示されたセクションは削除します。

Ⅲビルドエラー対応
 1.HEW
  1)コンパイルエラー 8/1追記
   現象
    #pragma inline_asm set_sp
    static void set_sp(int a){MOV R4, R15} で
    Illegal Option for #pragma inline_asm エラー
   対処
    「ビルド」/「SuperH RISC engine standerd tool chain」の コンパイラ/カテゴリ:オブジェクトで出力ファイル形式 「アセンブリプログラム(*.src)」に変更

  2)コンパイルエラー 8/1追記
   現象
    #indef HEW でエラー発生
   対処
    「ビルド」/「SuperH RISC engine Standard Toolchain」の コンパイラ/カテゴリ:ソース/マクロ定義でHEW(値なし)を追加



Ⅳ不具合(問題点)対処
 1.HEW関連
  1)関数 sprintf() でハングする。    6/6追記
   現象:プログラムがsprintf()で止まる。
   原因:標準ヘッダー 指定忘れ #include 
   対処:このヘッダーを指定 で 正常に

  2)関数 pow() を使った演算結果不具合   6/6追記
   現象:pow()を使った計算結果が 4、8、16、で扱われるはずが、、3、7、15で扱われた計算結果になっている。
   原因: 例 pow(2.0,2.0)の演算結果は4.0となっているが、どうも 3.9999....で扱われているようで、整数値との計算で3への切り捨てが行われているようです。
   対処:「SuperH RISC engine Standard Toolchain」のCPU設定、標準ライブラリ設定 等のオプション設定などで対処すべきとは思いますが、自作のpow()関数で逃げました。
 自作pow()関数 ループで乗算を繰り返す簡単なものですが、昔、MSCの初期バージョンを使っていた頃にも同じようなことをしていたと思い出しました。

 2.付属SH-2A基板およびSH72620関連
  1)内蔵ADC               6/6追記
   現象:AN0入力の出力値がAN1入力の影響を受ける。
    AN0の出力値のノイズ値を調べると、AN1の入力のタイミングであることがわかりました。
   対処;未定

  2)内蔵ADC               6/7追記
   現象:AN0入力、シングルモード、でループでデータ収集すると、ハングする。
      ループ回数は不定で、数万回のADCのデータ変換でハングするようです。
   原因:ADCの終了フラグ待ちでハング、。。。終了フラグが立たないようです。
   対処:ADCをスキャンモード、マルチモードで使う。なんとか所定の動作が達成できました。

  3)ルネサスシリアルペリフェラルインターフェース(SPI) 6/23追記
   現象:コマンドレジスタ(SPCMD0-3)設定内容がメモリ表示で確認出来ない。SPCMD0の場合、アドレス0xFFFF8810に設定した値が表示されると思うが、00 00の表示、(インスタントウォッチでは設定値が確認できるのですが)、これが原因かどうかしれませんがSPCMD0-3の設定がコーディングの手法により上手くいかないことがあるようです。
 成功したコーディング RSPIn.SPCMDm.WORD = 0xXXXX;
   対処: 未

0 件のコメント:

コメントを投稿