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;
   対処: 未

2010年5月23日日曜日

SH-2A基板 32KB超プログラムのROM化を試しました。



先日、Interface誌 付属SH-2A基板特設ページ でリリースされた 「シリアル・フラッシュROM用ブート・ローダのプロジェクト・ファイル一式をアップロードしました(SPIbootloader1)」を参考にし、ブートローダープログラムを改造し、また、以前使用した「ROM化ユーザ・プログラム書き込み用プログラム(SPIwreterUserDI)」再度改造して、32KBを超えるサイズのプログラムをシリアル・フラッシュROM(M25P40)に書き込み、その動作を確認しました。


概要

1.プログラムの改造
 1)ブートローダープログラム(SPIbootloader1)のシリアル・フラッシュROMからの読み出しサイズを
448KB に拡張した。
 2)ROM化ユーザ・プログラム書き込み用プログラム(SPIwreterUserDI)で
  ・ブートローダープログラム
  ・HEWモニタプログラム
  ・ユーザープログラム
    の3つのプログラムを個別に書き込むように改造した。
2.ROM化プログラムの動作確認
  ・プログラムサイズ 42,364バイト のプログラムを書き込む
  ・リセット、USBケーブル 抜き差し(電源) での 稼動を確認
  ・HEWモニタの動作を確認  NMIピン High (JPP2 Open)

以下に今回の作業を述べます。

1.ブートローダープログラム(SPIbootloader1)の改造
 1)入手したブートローダープロジェクトの解析
 以前 Renesas サイトから入手した「シリアルフラッシュ・シリアルフラッシュメモリからのブート例」サンプルコード を参考にしながら、ソースコードを解析しました。
 気付いた点
  ・ロードするプログラムのサイズが実質固定で32KBであった。
   本来、0x00002000にあるプログラム情報(APPINFO)を取得し、プログラム開始・終了アドレスの差分をプログラムのロードサイズとしているが、今まで作成したプログラムの開始アドレスが0x1C000000(0x1C000500)であることを考えると、32KB固定と考えられる。
  ・プログラム情報(APPINFO)のアドレスの扱いが、ユーザープログラムの場合、0x00008020、HEWもにたの場合 0x00002020 ・・・・この 0x20(32バイト)のズレが不明 (このズレを無視して、0x00008000、0x00002000 で ローダプログラムを組むと不調 )
      
      32バイトのズレは、RESET_Vector のポインタが格納されている位置、

      Renesasのサンプル(sh7264_sflash_loader_prog)は、ブート開始時に PowerON_Reset_PC [0x1C000500] に跳び、
      SPIbootloader1の場合、RESET_Vector [0x1C000000]に跳ぶ、この違いがよく解らない。
 
      RESET_Vectorの最初のエントリはPowerON_Reset_PC 
      直接PowerON_Reset_PCに跳ぶか、
      一旦RESET_Vectorに跳ぶが、実はPowerON_Reset_PCに跳んでいた、同じようで同じでない、、、、

      何か苦肉の策で リザーブ8に RESET_Vector のポインタをセットして、このようなスキームを実現したのか、、、、 よく解らない。  

 2)ソース main.c の修正
   個々の疑問には、目をつぶり、
     /* アプリケーションプログラムを内蔵RAMにロード */
     sf_byte_read_long(0x00002000, (unsigned long *)app_top, app_len);
   の直前に、app_len = 0x00070000; //(448KB)を置く

    (app_len の算出等で改造の余地あり。)
  
2.ROM化ユーザ・プログラム書き込み用プログラム(SPIwreterUserDI)の再改造
 1)ブートローダープログラムのROM書き込み
  1.で作成したブートローダープログラムを 0x1C080000 に置いて、シリアルフラッシュROMのセクタ0の消しこみ後、先頭8KBに書き込む。

     /* SPI-ROMの書き込み処理 for HEW Loader Program */
     if( write_prog_data( (unsigned char *)0x1C080000, 0x00000000, 0x00002000) < 0 ){
        error();
     }

 2)HEWモニタプログラムのROM書き込み
   以前使用した「SPIシリアル接続フラッシュROM アップデート・ファイル」(SPIROM.BIN)のHEWモニタプログラムの部分をシリアルフラッシュROMの 8KB~32KB に書き込む。
   (HEWでは、SPIROM.BIN は 0x1C092000 に置く)   6/4追記

     /* SPI-ROMの書き込み処理 for HEW Monitor */
     if( write_prog_data_user( (unsigned char *)0x1C092000, 0x00002000, 0x00006000) < 0 ){
        error();
     }

 3)ユーザープログラムのROM書き込み
   作成した、ユーザープログラムをシリアルフラッシュROMの 32KB以降 に書き込む。書き込みが次セクタに及ぶ場合、先に、次セクタの消しこみを行う。
   (HEWでは、USERROM.BIN は 0x1C0A0000 に置く)   6/4追記
     app_prog_size = SECTOR_SIZE * SECTOR_NUM - 0x00008000;

     /* SPI-ROMの書き込み処理 for UserProgram */
     if( write_prog_data_user( (unsigned char *)0x1C0A0000, 0x00008000, app_prog_size) < 0 ){
        error();
     }

3.ROM化プログラムの動作確認
 今回の検証用に32KBを超えるプログラムを作成した、半ば強引に、動作が不十分なグラフィックモジュールを組み込んだ。現時点で動作確認できているモジュールについては、正常の動作が確認できました。
 後は、1MBを超えるプログラムサイズをどうするか、、まあ、不要なことかも知れません。


*write_prog_data_userのコード
  int write_prog_data_user(unsigned char *program_data, unsigned long sflash_addr, unsigned long size)
  {
    unsigned long sector_no;
    unsigned long saddr;
    unsigned long sz;
    unsigned char read_data;
    unsigned char *w_p;

    /* ==== 引数から値をローカル変数にコピー ==== */
    saddr = sflash_addr;
    sz = size;
    w_p = program_data;

    /* ==== シリアルフラッシュメモリへの書き込み ==== */
    while( sz > 0){
      sector_no = saddr / SECTOR_SIZE;

      /*セクタ消去を調整 No.0 セクタの消去除外 */
      if(sector_no > 0)
      {
        if( Is_erased_sector(sector_no) == 0 ){ /* 未消去であれば */
          sf_sector_erase(sector_no);  /* 消去する */
          set_erase_flag(sector_no);  /* 消去したら、消去済みフラグを立てる */
        }
      }
      sf_byte_program(saddr, w_p, 1 );  /* 1バイトずつ書き込む */
      w_p++;
      saddr++;
      sz--;
    }
    /* ==== ベリファイ処理(書き込みの検証)==== */
    saddr = sflash_addr;
    sz = size;
    w_p = program_data;

    while( sz > 0){
      sf_byte_read(saddr,&read_data, 1);  /* 書き込みしたデータを読み出し */

      if( *w_p != read_data ){
        return -1;    /* データが一致しない場合エラーとする */
      }
      w_p++;
      saddr++;
      sz--;
    }
    return 0;
  }
※5/24 訂正 0x1C090000 ==> 0x1C0A0000 ユーザープログラムROM書き込み

2010年5月22日土曜日

SH-2A基板 「GCC対応シリアル・ダウンローダ(TinyMON)」を試す。



CQ出版 Interface誌 付属SH-2A基板特設ページ から「GCC対応シリアル・ダウンローダ(TinyMON)」を入手し、その動作を検証しました。

「GCC対応シリアル・ダウンローダ(TinyMON)」の検証では、GNU GCC 開発環境の検証、この環境で作成したプログラムのROM化の検証が併せて行えたようです。

[概要]
・TinyMONのシリアル通信チャネルをSCIF2からSCIF3に変更
・GNU GCCによる開発環境の検証 (TinyMONのビルド)
・TinyMONの動作確認

1.TinyMONの改造
 シリアル通信チャネルをSCIF2からSCIF3に変更するにあたり、以下の修正をTinyMONに行いました。
 1)cpu_uart.cの修正
  ・UARTコントローラの設定変更
    #define USE_UART_CH 2  => #define USE_UART_CH 3
  ・ポート設定
   付属SH-2A基板のCN3のNo.18(RxD3)No.24(TxD3)を使用するための設定。
    /* ポートコントローラ制御レジスタ */
    #define PGCR3 ((volatile unsigned short int *)(0xFFFE38C8))
    #define PGCR4 ((volatile unsigned short int *)(0xFFFE38C6))
     を追加

    /* ポート設定(RXD3(PG15))*/
    *PGCR3 = (*PGCR3&0x0FFF)|0x3000;
    /* ポート設定(TXD3(PG16))*/
    *PGCR4 = (*PGCR4&0xFFF0)|0x0003;
     を追加

    ※2010.7.18追加
    シリアル通信チャネル3 BaseAddress の設定
    /* FIFO付きシリアルコントローラSCIF(SCIF3) */
    #define BaseAddr (0xFFFE9800)
     を追加
 

    シリアル通信チャネル3 スタンバイ解除
    /* SCIF3スタンバイ解除 */
    *STBCR4 = (*STBCR4 & 0xEF); /* SCIF3動作 */
     を追加

2.TinyMONのビルド
 GNU GCCの開発環境は KPITカミンズ・インフォシステムズ・リミテッド より入手した環境で行いました。
 1)Makefileの修正
  ・各ツールの指定
    GCC = /usr/local/sh-tools/bin/sh-elf-gcc
    LD = /usr/local/sh-tools/bin/sh-elf-ld
    AS = /usr/local/sh-tools/bin/sh-elf-as
    OBJCOPY = /usr/local/sh-tools/bin/sh-elf-objcopy
    =>
    GCC = sh-elf-gcc
    LD = sh-elf-ld
    AS = sh-elf-as
    OBJCOPY = sh-elf-objcopy
    (/cygdrive/c/KPIT_Cummins/GNUSHv10.01-ELF/sh-elf/bin/sh-elf-gcc.exe ..)
    (環境設定で既にPATHが通っているので)
  ・ライブラリの参照指定を変更
    GCCLIB = /usr/local/sh-tools/lib/gcc/sh-elf/3.4.5/m2
    $(LD) -Map $(TARGET).map -T $(LDSCRIPT) $(OBJS) -L$(GCCLIB) -lgcc -o $(TARGET).elf
    =>
    LIBRARY_DIRS = -L ../../../../KPIT_Cummins/GNUSHv10.01-ELF/sh-elf/lib/gcc/sh-elf/4.4-GNUSH_v10.01/m2a -L ../../../../KPIT_Cummins/GNUSHv10.01-ELF/sh-elf/sh-elf/lib/m2a
     $(LD) -Map $(TARGET).map -T $(LDSCRIPT) $(OBJS) $(LIBRARY_DIRS) -lgcc -o $(TARGET).elf
    ※修正前のライブラリディレクトリ指定が m2 で 気休めに m2a に変更しました。

 2)ビルドの実行
   色々、試行錯誤(後述)の結果、無事成功。
 3)シリアルフラッシュROMへの書き込み。
   SPIwreterUserDI(改)により TinyMON を シリアルフラッシュROMに書き込みました。

3.TinyMONの動作検証
 幸か不幸か、HEWをインストールしたPCにシリアル(RS232c)のポートが残っていたので、付属SH-2A基板にRS232CドライバIC(ADM3202)を繋ぐだけでPCとのシリアル通信が実現できました。
 とりあえず、ハイバーターミナルでTinyMONの動作が検証できました。
 ・SH7262リセットで ハイバーターミナルに”Tiny Dump Monitor” が 表示
 ・ヘルプ表示
 ・メモリダンプ
   ためしに、SH7262レジスタ 周波数制御レジスタ(FRQCR)を確認しようと 
   DB FFFE0010 を 実行したが、0x1104 の設定は確認出来なかった。????
   (00 00 であった)
   ・・・課題点

※開発メモ
1.GNU GCCの開発環境(KPIT版)/(付属SH-2A基板特設ページ版)
 今回GNU GCCの開発環境はKPITでリリースされている環境を使用しました、付属SH-2A基板特設ページ(Interface誌)で提供される sh-tools20100424.tar.bz2 で GNU GCCの開発環境を整えた場合、上記のようなMakefileの修正の必要は無く容易にGNU GCCによる開発が出来るようです。

2.GNU GCCの開発環境(KPIT版)での注意点
 1)インストール先について。
 私の場合 WindowsVISTA 64bit版にインストールしました。すると、インストール先が Program Files(x86) になりました。これが Cygwin で結構、厄介なことになります。しかたなく、別ディレクトリ(C:\KPIT_Cummins)にインストールし直しました。

 2)Makeファイルのライブラリ設定。
 ・ビルドエラー ”cannot find -lgcc make: *** [all] Error 1 ”が発生。 最初、libgcc.a の所在を確認し、Makefileでのライブラリ設定に反映させました。しかし、エラーは解消されず、sh-elf-ld が libgcc.a を見つけられないのか不明でした。
 試しに、-lc や -lm 等でも ビルドを行うと、これも同様のエラー libc.a、libm.c が 有るのに見つけられないと言うエラーが起きました。いろいろもがくうちに、ライブラリフォルダの位置が問題と考えるようになりました。
 Windows上で C:\KPIT_Cummins\GNUSHv10.01-ELF配下のライブラリファイルは、Cygwinでは、/cygdrive/c/KPIT Cummins/GNUSHv10.01-ELF配下と表現します。
 Windows上で C:\Cygwin\usr\local\sh-tools等の配下のライブラリファイルは、Cygwinでは/usr/local/sh-tools等の配下と表現します。
 どうも、sh-elf-ld が /cygdrive/c/....の 表記を受け付けないようです。この推測を実証するために、次の対処を行ったところ、ようやくビルドが成功しました。

 (対処) 
  ライブラリ指定を
    LIBRARY_DIRS = -L /cygdrive/c/KPIT_Cummins/GNUSHv10.01-ELF/sh-elf/....
  から
    LIBRARY_DIRS = -L ../../../../KPIT_Cummins/GNUSHv10.01-ELF/sh-elf/....
  に修正

2010年5月16日日曜日

SH-2A基板 「ROM化ユーザ・プログラム書き込み用プログラム」を試しました。 (その2)

「ROM化ユーザ・プログラム書き込み用プログラム(以降 SPIwreterUserDI)」により、いままで作成した、付属SH-2A基板 自作テストプログラムの書き込みを行いました。

◎自作テストプログラムのROM化対応について。
 ○ SPIwreterUserDIのドキュメント(README.TXT)で指示されているROM化作業
  (「付属SH-2A基板特設ページ」
   /「付属SH-2A基板関連のダウンロード・データ」
    /「ROM化ユーザ・プログラム書き込み用プログラムをアップロードしました」
   から入手した SPIwriteUser.zip >> CQ Connect) 

  ・出力ファイルをバイナリに変更
   [ビルド]/[SuperH RISC engine Standard toolchain]
    [最適化リンカ]/[出力]で  「バイナリ」を選択
  ・vecttbl.cの修正
   割り込みベクタテーブル(INT_Vectors[])
    // 8 Reserved
   (void*) Dummy, を (void*) RESET_Vectors, に修正

 ○ Interface_Sample2のドキュメント(README.TXT)で指示されているROM化作業
  (「付属SH-2A基板特設ページ」
   /「付属SH-2A基板関連のダウンロード・データ」
    /「タイマ割り込みLED点滅制御サンプル・プログラムの改定版を用意しました」
   から入手した Interface_Sample2.zip) 

  ・resetprg.c で レジスタバンクの初期化処理を追加
    #include  "typedefine.h" を #include  "iodefine.h" に置き換える。

   INTC.IBNR.WORD = 0x4000; を set_fpscr(FPSCR_Init); と  _INITSCT();の間に追加する。


◎自作テストプログラムのROM化 結果
 ・GPIOテストプログラム(ほぼサンプルプログラム)
   動作:  4つのLEDを交互に点滅
   サイズ: 6912バイト
   ==> 成功
 ・モノクロLCDテストプログラム
   動作: LCD SG12864 の 表示 (自作フォント表示)
   サイズ: 33260バイト
   ==> 成功/失敗 (単純にROM書き込みを繰り返すのですが。成功したり、失敗したり。稼動までに異常に時間がかかったり。。。。)
 ・キー入力+モノクロLCD テストプログラム
   動作: LCD SG12864 の 表示 (自作フォント表示)
       キー入力により、表示文字を変化させる。
   サイズ: 33988バイト
   ==> ほとんど失敗 10回の試行中 成功2回、成功の場合も一旦USBケーブルを外すと動作せ
ず。


まだ、Interface誌の付属SH-2A基板関連の公開情報(本誌、およびダウンロードファイル)の読み落としがあるのでしょう。あとは、暇をみて、ぼちぼちと。。。。。


******************

最後に jujurouさんのコメントに感謝します。

2010年5月15日土曜日

SH-2A基板 「ROM化ユーザ・プログラム書き込み用プログラム」を試しました。



 先日、Interface誌 付属SH-2A基板特設ページ でリリースされた 「ROM化ユーザ・プログラム書き込み用プログラム(以降 SPIwreterUserDI)」を試しました。



 早速、”だめもと”で、外付けシリアルフラッシュROM(M25P40)搭載の付属SH-2A基板で試しました。結果は、当然のことですが失敗しました。SPIwreterUserDI実行後は、HEWモニタプログラム等が消去されたようで、リセット後、SH-2A基板は沈黙。。。



 以下に、SPIwreterUserDI の改造および、その際の顛末について述べます。


※改造後のプログラム概要
  ・M25P40 セクタ0 のクリア後、以前使った。「SPIシリアル接続フラッシュROM アップデート・ファイル」(SPIROM.BIN)の前半 32KB分 を書き込む。
  ・M25P40 セクタ0 の後半32KBから、ユーザープログラムを書き込む。
   (セクタの消去は、セクタ1以降に行う。)


1.SPIwreterUserDIを外付けシリアルフラッシュROM(M25P40)に使う上での問題点。
 ・付属基板上のM25P05-Aの場合、ユーザープログラムはセクタ1に書き込まれるが、M25P40では、HEWモニタプログラムと同じ、セクタ0に書き込まれる。この時、セクタ0の消去が行われ、HEWモニタプログラム等が消去されてしまいます。


2.SPIwreterUserDIの改造
 ①SPIwreterUserDIの改造 その1
   serial_flash.hのセクタサイズ、セクタ数を書き換える。(M25P40用に) 
   ※プログラム書き込みサイズはまだそのまま。
 ②ビルド
 ③書き込み実行 ==>失敗
   書き込み実行し、LEDの点滅までたどりつくが、付属基板リセットすると、HEWモニタ、およびLED点滅プログラムは作動しなくった。
 ④M25P40の復旧
   モニタプログラムを書き込み、MP25P40を復旧させる。
 ⑤SPIwreterUserDIの改造 その2
   a.SH-2Aマイコン基板実装SPIシリアル接続フラッシュROM アップデート・ファイル(2010年4月24日版)の 「SPIROM.BIN」をSPIwreterUserDIのフォルダに組み込み、Download modulesに追加する。
     USERROM.BINのオフセットを 1C090000に変更
     SPIROM.BINのオフセットを 1C080000で追加する。
   b.main.cを修正
    ・SPIROM.BINを シリアルフラッシュROMのアドレス0x00000000 サイズ0x00008000で write_prog_dataを使って書き込む。
    ・write_prog_data_userをwrite_prog_dataを元に作成する。(セクタNo.0の場合 セクタの消去は行わないように改造)
    ・USERROM.BINを シリアルフラッシュROMのアドレス0x00008000 サイズ0x00008000で write_prog_data_userを使って書き込む。
   c.ビルド/ダウンロード SPIwriterUser.abs、SPIROM.BIN、USERROM.BIN
   d.実行
   ==>成功
 ⑥SPIwreterUserDIの改造 その3
   ・write_prog_data_userでの書き込みプログラムサイズを セクタサイズ(SECTOR_SIZE)× セクタ数(SECTOR_NUM) - 0x00008000 に変更

3.今後、
 現時点で、SPIwreterUserDIでROM化するユーザープログラムの作成に失敗しています。付属SH-2A基板特設ページでダウンロードした、LED点滅プログラム(Interface_Sample/SH7262_LED)でも試すのですが、上手くいきません。SPIwreterUserDIに付随した LED点滅プログラム(USERROM.BIN)だけROM可できている状況です。

 その辺の所は、Intarface次号を期待して、。。。。

2010年5月9日日曜日

SH-2A基板でモノクロLCDを使う。



今年のGWも、CQ出版 Interface誌の付録基板と格闘していました。なんだか、年中行事化しているようです。3日も有れば出来ると思っていたモノクログラフィカルLCD(SG12864)の表示に、連休いっぱいかかってしまいました。
特に今年は、気持ちよい晴天が続き。部屋にこもりっきりで付属SH-2A基板をいじるのはどうかと思いながら....







付属SH-2A基板でLCDの表示に辿り着くまでにHEWで起きたエラーと対処を記します。

1.数値演算用関数(math.h)log10、pow等が使えない。
エラー: L2310 (E) Undefined external symbol "_log10" referenced in "C:\....
対処 : <HEW> [ビルド]/[SuperH RISC engine Standard Toolchain...]
          [標準ライブラリ]
            カテゴリで標準ライブラリを選択
              math.hにチェック
              string.hもついでに
ドキュメントを見ると、標準ライブラリ関数として、これらの数値演算関数は使えると書かれています。当然デフォルトの環境で使えると思っていたので最初は、開発環境が壊れたと思いました。しかし、調べていくうちに、”SuperH RISC engine Standard Toolchain...”での設定が必要と知りました。

2.セクションの設定エラー
エラー: L2321 (E) Section "B" overlaps section "P"
     L2321 (E) Seciton "R" overlaps section "P"
対処 : <HEW> [ビルド]/[SuperH RISC engine Standard Toolchain...]
          [最適化リンカ]
            カテゴリでセクションを選択

   セッションP~Dに384KB(0x60000)を確保することにして、セッションB,Rの設定 1C005000~ => 1C061000~に変更

(セッション情報 ビルド時に作成されたマップファイル(*.map)で確認した内容 )
セッション P~Dまでが 1C001000~1C008437 で サイズ 7436(29750)
セッション B,Rが   1C005000~1C005D33 で サイズ d34(3380) ※確かにかぶっている。
セッション Sが    1C0F0600~1C0FFFFF で サイズ fa00(64000)

I誌(2010.6)の第3章の記事(P107)で、セクションの設定例(表6)があり、その設定を鵜呑みにして、セクション設定を行ったことが原因、設定例では、プログラムサイズが16KB未満に限定されてしまいます。
HEWの無償版の制限サイズ256KBに合わせた設定であってほしかった。


次に、今年の基板で手こずった点を以下に述べます。

○マルチファンクションタイマパルスユニット2(MTU2)
 I誌の記事には、コンペアマッチタイマ(CMT)の使い方があったのですが、2Chしかないので、MTU2を使いたいと考え、MTU2を試すのですが、なかなか思うように使えません。特にタイマカウンタが16ビットで、他のマイコンの32ビットのタイマカウンタに慣れいた自分にとって結構不便を感じました。
また、CMTとMTU2の使い勝手が大きく異なることも....

○レジスタのサイズがまちまち。
 レジスタのサイズは、8,16,32ビットがあり、同じようなタイプのレジスタで異なるサイズがある場合があり、ケアレスミスで、サイズを誤ってアクセスし、それに気付くまで結構時間がかかったりしました。
また、レジストリ等のネーミングルールがいまいち整備されていないようで、これも意外と手こずる原因になりました。
 SH系のソースのヘッダーファイル”iodefine.h”を工夫すれば、ほとんどのレジストリを32ビットで扱えるのではないと思うのですが、なにせこのヘッダーファイル、9000行を超える巨大ファイル、手が出せずにいます。

○割り込み
intprg.c、vecttbl.c、vect.h等を編集する必要あり、
・vect.hのエントリに(resbank)を付加、
  割り込み時にレジスタバンクを使うと言う意味か?
・vectbl.cはそのまま
・intprg.cに#pragma文と、割り込みでCallする関数を記述する。
いまいち、しっくりこない。


○汎用入出力ポート(GPIO)
・ポートEはオープンドレイン出力
 Vcc+抵抗で電圧を印加する。”1”出力はハイインピーダンスで電圧を保持し(High電圧)、”0”出力でこのポートを通しGNDに電荷を流し、Low電圧となる。
・ポートHは入力専用
GPIOの各ポートは、GPIOとしての機能と端子数を揃えてもらいたいものです。ポートHにLCDの端子を繋げてしまい、ハンダをやり直すはめになりました。I誌(2010.6)のP76-77を見ながら拡張ボードを作成したので、ビルドエラーで初めて、ポートの選択を誤ったことに気付きました。