レジスタの宣言
Blackfin用のプログラムでは、例えば次のようにしてレジスタへのアクセスを提供するのが普通です。この方法はVisualDSP++で用いられている方法です。
#define pPLL_CTL ((volatile unsigned short *)PLL_CTL)
これで例えば *pPLL_CTLとすればC言語プログラム中で問題なくレジスタにアクセスできます。ところが、gdbではこの方法が使えません。
そこで、あれこれいじり回していたのですが、結局プログラム中で特定変数の配置アドレスを強制することで、レジスタの位置にかぶせて変数を宣言する方法におちつきつつあります。
やり方としては、まず次のように定義します。
volatile unsigned short regPLL_CTL __attribute__ ((aligned(4), section("PWRMGMT"))); volatile unsigned short regPLL_DIV __attribute__ ((aligned(4), section("PWRMGMT"))); volatile unsigned short regVR_CTL __attribute__ ((aligned(4), section("PWRMGMT"))); volatile unsigned short regPLL_STAT __attribute__ ((aligned(4), section("PWRMGMT"))); volatile unsigned short regPLL_LOCKCNT __attribute__ ((aligned(4), section("PWRMGMT"))); volatile unsigned short regSWRST __attribute__ ((aligned(4), section("SYSRST"))); volatile unsigned short regSYSCR __attribute__ ((aligned(4), section("SYSRST"))); volatile unsigned long regSIC_RVECT __attribute__ ((aligned(4), section("SYSRST"))); volatile unsigned long regSIC_IMASK __attribute__ ((aligned(4), section("SYSRST"))); volatile unsigned long regSIC_IAR0 __attribute__ ((aligned(4), section("SYSRST"))); volatile unsigned long regSIC_IAR1 __attribute__ ((aligned(4), section("SYSRST"))); volatile unsigned long regSIC_IAR2 __attribute__ ((aligned(4), section("SYSRST"))); volatile unsigned long regSIC_IARDUMMY __attribute__ ((aligned(4), section("SYSRST"))); volatile unsigned long regSIC_ISR __attribute__ ((aligned(4), section("SYSRST"))); volatile unsigned long regSIC_IWR __attribute__ ((aligned(4), section("SYSRST")));
そして、ldスクリプトの中で
.pwrmgmt : { jsp_bf533_pwrmgmt.o(PWRMGMT)} > MEM_SYSMMR .sysrst : { . = ALIGN(0x100); jsp_bf533_pwrmgmt.o(SYSRST)} > MEM_SYSMMR
としてビルドします。すると
suikan@suikan-laptop:~/workspace_demo/sample1$ readelf -s jsp | grep reg | sort -k 2 267: ffc00000 2 OBJECT GLOBAL DEFAULT 6 _regPLL_CTL 205: ffc00004 2 OBJECT GLOBAL DEFAULT 6 _regPLL_DIV 317: ffc00008 2 OBJECT GLOBAL DEFAULT 6 _regVR_CTL 349: ffc0000c 2 OBJECT GLOBAL DEFAULT 6 _regPLL_STAT 226: ffc00010 2 OBJECT GLOBAL DEFAULT 6 _regPLL_LOCKCNT 197: ffc00100 2 OBJECT GLOBAL DEFAULT 7 _regSWRST 158: ffc00104 2 OBJECT GLOBAL DEFAULT 7 _regSYSCR 210: ffc00108 4 OBJECT GLOBAL DEFAULT 7 _regSIC_RVECT 373: ffc0010c 4 OBJECT GLOBAL DEFAULT 7 _regSIC_IMASK 336: ffc00110 4 OBJECT GLOBAL DEFAULT 7 _regSIC_IAR0 240: ffc00114 4 OBJECT GLOBAL DEFAULT 7 _regSIC_IAR1 325: ffc00118 4 OBJECT GLOBAL DEFAULT 7 _regSIC_IAR2 333: ffc0011c 4 OBJECT GLOBAL DEFAULT 7 _regSIC_IARDUMMY 344: ffc00120 4 OBJECT GLOBAL DEFAULT 7 _regSIC_ISR 218: ffc00124 4 OBJECT GLOBAL DEFAULT 7 _regSIC_IWR
となり、正しいアドレスに配置されていることが分かります。
出張中で手元にターゲットがないためどの程度有効かまだ調べていませんが、そこそこうまくいきそうです。注意点としては
- 初期値がセットされないように気をつける
- アドレスが宣言順に必ずなるか気をつける
ことでしょうか。2番目はユーザーからはコントロールできない気もします。