[H8-ML(4505)] Fw: [H8-ML(4504)] Re: SRAM増設時のSUB ファイル等の設定について行き詰まりました
From: "Yuki WAKUDA" <wakuchin@xxxxxxxxxxxx>
Date: 2004年02月23日(月)02時56分56秒
有難う御座います.

大変為になります.

それです!
main{
}
内に宣言されていたので,mainの外に宣言し,与えられたCASE3のように

int X[5000];
main
{
・・・
}
という形をとることによって,usbtest.MAPファイル内下方に
X    H'00020002    DAT
というのが出現しました!

プログラミングはソフトウェア側から入ったので,このように変数がどこに配置されるといったことを気にする概念が無かったので,理解に時間が
かかりました..

これでなんとちゃんと変数を確保することができました!

今回間違っていた点をまとめると
1.

アセンブラで確保しているセクションはLOCATE命令を使うと、混乱の元になりそう。

#########usbtest.subファイル内このように変更######
START V(0),P,C,D(200),R,B(0FEF10)


#########start.asm#######
.CPU 300HA
.SECTION V,CODE,LOCATE=H'000000
      ↓変更
#########start.asmファイル内このように変更#######
  .CPU 300HA
  .SECTION V,CODE

2.
V(ベクタ用セクション内)に実行コードを置いており,これをSTART.asm内の別の場所に配置換え.

3.
#DATA_ENDはアセンブラファイルの中でしか有効ではない。
セクションの開始アドレスを取得するなら
#STARTOF Dとか#STARTOF R、
セクションのサイズを取得するなら
#SIZEOF Dが使えます。
  mov.l #(STARTOF D),er0   ; 転送元
  mov.l #(STARTOF R),er1   ; 転送先
  mov.l #(STARTOF R + SIZEOF D), er2   ; 転送終了

ですが,これに関しては,STARTOF R に対してなぜかエラーが発生したので,
  mov.l #(STARTOF D),er0   ; 転送元
  mov.l #20000,er1   ; 転送先
  mov.l #DATA_END, er2   ; 転送終了
として対応

4.
配列をmain内で宣言して自動変数になっていました.
これをmain{}の外に配置することで,Rセクションに配置できた

といったかんじです.
投稿しようか迷っていたのですが,結果として解決が非常に早くて大変ためになりました.
魔法のように謎が解けました....

マイコンにはまりつつあるので,今後とも勉強ですヽ(´▽`)/


ご回答くださいましたはまやんさん,小坂さん.有難う御座いました.

最後に成功したファイルを添付しておきます..(要領が大きくなりますが,自分のような初心者にはこのような実例が助かるので,,すみませ
ん.)

#####usbtest.sub######
OUTPUT usbtest
PRINT usbtest
INPUT start,main,sci,lcd
LIB D:\H8\akic\c38hab
START V(0),P,C,D(200),R,B(20000)
ROM (D,R)
EXIT
####################
ほんとは,
#####start.asm########
 .CPU 300HA
 .SECTION V,CODE

 .IMPORT _main

 .DATA.L  _start  ;リセットベクトル
 .DATA.L  int_error
 .DATA.L  int_error
 .DATA.L  int_error

 .DATA.L  int_error
 .DATA.L  int_error
 .DATA.L  int_error
 .DATA.L  int_error

 .DATA.L  int_error
 .DATA.L  int_error
 .DATA.L  int_error
 .DATA.L  int_error

IRQ0: .DATA.L  int_error
IRQ1: .DATA.L  int_error
IRQ2: .DATA.L  int_error
IRQ3: .DATA.L  int_error
IRQ4: .DATA.L  int_error

;----------------------------------------------------------
 .SECTION P,CODE,ALIGN=2
_start:
 mov.l #H'0FFF10,er7

 ABWCR:  .EQU H'FFFEC
 ASTCR:  .EQU H'FFFED
 WCR:  .EQU H'FFFEE
 WCER:  .EQU H'FFFEF
 P1_DDR:  .EQU H'FFFC0
 P2_DDR:  .EQU H'FFFC1
 P5_DDR:  .EQU H'FFFC8
 P8_DDR:  .EQU H'FFFCD

;_INITIALIZE:
 MOV.B #H'FF,R0L
 MOV.B R0L, @ABWCR  ; CS1領域バス幅8ビット(P4:D0-D7)*/
 MOV.B #H'FF,R0L
 MOV.B R0L,@ASTCR  ; CS1領域3ステートアクセス*/
 MOV.B #H'F0,R0L
 MOV.B R0L,@WCR  ; 0wait*/
 MOV.B #H'FF,R0L
 MOV.B R0L,@P1_DDR  ; P1をアドレスバス(A0-A7)*/
 MOV.B R0L,@P2_DDR  ; P2をアドレスバス(A8-A15)*/
 MOV.B R0L,@P5_DDR  ; P5をアドレスバス(A16-A19)*/
 MOV.B #H'E8,R0L
 MOV.B R0L,@P8_DDR  ; P8-3 CS1出力*/


;初期化付きデータを使用する場合、RAMに転送する
 mov.l #(STARTOF D), er0   ; 転送元(8000)
 mov.l #H'20000, er1   ; 転送先
 mov.l #DATA_END, er2   ; 転送終了
init_loop:
 cmp.l er1, er2
 beq init_end
  mov.b @er0+, r3l
 mov.b r3l, @er1
 inc.l #1, er1
 bra init_loop
init_end:
 jsr @_main

; 割り込み未使用
int_error:
 rte

;----------------------------------------------------------
; 割り込み許可、禁止ルーチン

 .EXPORT _EnableInterrupt,_DisableInterrupt
_EnableInterrupt:
 andc.b #H'3f,ccr
 rts
_DisableInterrupt:
 orc.b #H'c0,ccr
 rts

;----------------------------------------------------------
 .SECTION D,DATA


 .SECTION B,DATA
DATA_END: .RES.W  1

 .END
######################


> >これによると,例えば,X[500]は今,main内で
> >#######
> >int    X[500];
> >for(i=0;i<500;i++){
> >X[i] = ○○;
> >}
> >#######
> >というような使い方をしていますが,これはRセクションとBセクシ
> ョンのどちらなのでしょうか.
>
> main()
> {
>     int x[500];
>     :
> }
> この記述で,配列xは自動変数なのでスタック領域に実行時に作られ
> ます。
>
> >  mov.l #H'0FFF10,er7
> でしたので,スタック領域は0FFF10からアドレスの若い方に向かっ
> て確保されます。xはリンク時に作られる変数ではないので,Rとか
> Bセクションにはなりません。それでmapファイルにはなにも表示さ
> れないのです。
> この例ではスタック領域が内部RAM(4kbyteだったかな)におかれる
> 設定になっているので,大きな配列はとれません。
>
> CASE1 外部RAM領域にスタックを置きたいならer7に外部RAMの最終
> アドレス+1以下で最大の2の倍数を設定します。こうすると大きな
> 配列をスタックに取ることができます。(このようなスタイルは好
> まれないと思いますが)
>
> CASE2 スタックの置き場を変更せずに,大きな配列をBセクション
> に置きたいなら
> main()
> {
>     static int x[2000];
>     :
> }
> のように記述します。(この方法が自然だと思います)
> static変数は隠蔽された変数なのでmapファイルには現れませんが,
> Bセクションのサイズが大きくなってそれとわかると思います。
>
> CASE3 他の関数からこの配列をアクセスすることがあるのなら関数
> の外部に
>
> int x[2000];
>
> main()
> {
>     :
> }
>
> と記述します。
> この記述では変数xがmapファイルに現れます。
>
>
> 蛇足ですが,500個の定数を記述するなら
> 関数の内部外部を問わず
> const int x[500]={
>     123,345,654,23,123,...........500個の定数
> }
> のように記述するとCセクション(ROM領域)に配置され,貴重なRAM
> 資源を無駄にしません。
> 外部RAMが1Mもある場合には関係ないかもしれませんが。
> 東京高専 情報工学科 小坂敏文
>

スレッド概略
[表示中](起点)


投稿順に移動
[←前の記事へ(P)]
[→次の記事へ(N)]


リスト表示へ
[このスレッド(T)]
[本記事の前後(L)]