レジスタの宣言

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番目はユーザーからはコントロールできない気もします。