[Suzaku:02025] Re: XPS-SIV00 の Base&High Address の変更について

mizo email@hidden
2010年 12月 1日 (水) 10:43:32 JST


溝渕です。

email@hidden wrote:
> 九州工業大学の吉武と申します.
> 
> 今回,IPコアのBase,High Addressの変更について質問させていただきました.
> 
> 現在,研究でSUZAKU(SZ410)+AV BoardとそのサンプルプログラムXPS-SIV00を
> 使い,カメラからの画像取得→二値化→ラベリング→重心計算を行うプログラム
> を作成しています.
> 
> これら一連の流れはすべてHDL側で行って,その各データをレジスタ
> (v_register.vhd)に書き込み,それらの値をLinux側のdemo-av中で読み取り,
> PCのブラウザに表示させています.
> 
> 多くのデータをやり取りするので,EDKにおいてXPS-SIV00のBase,High Address
> を現状の0xF0FF4200~0xF0FF43FF(size=512)から
> 0xF0FF4000~0xF0FF43FF(size=1K)に変更して
> 
> Clean Hardware → Clean Software → Generate Netlist → Generate 
> Bitstream →Build All User Applications → Update Bitstream → binに
> 変更 → hermitで書き込み
> 
> という順でやってみたのですが,新しく追加したアドレスに書き込んだ部分は
> 表示されず,元々表示できていた値まで表示されないという状態になってしまい
> ました.
> 
> HDL側のuser_logic.vhdとxps_siv00.vhdのBase,High Address部分に変更を加え
> たのですが,linux側には変更を加えていません.
> Linux側にも変更が必要なのでしょうか?ならば変更するファイルの場所などを教
> えていただきたいのですが・・・

xparameters.hの置き換えが必要ですが行なっていますか?置き換えるべきファ
イルは、
arch/ppc/platforms/4xx/xparameters/xparameters_sz410-siv.h
です。

これを行なわなければ、sivのHigh Addressの変更が有効になりません。

ここで定義している値は、
arch/ppc/platforms/4xx/suzaku-v.c
のsiv_resources[]に代入されます。

siv_resources[]は、platform_deviceのresourceで、
drivers/video/siv.c内の
platform_get_resource()
で取得しています。

> 以下に値を習得できていたときのサンプルへの追加ソースを示します.
> 
> HDL側xps_siv00
> 
> ・v_register.vhd
> 
>    CNT_H_IN			  : in  std_logic_vector(0 to 31);
>    CNT_V_IN			  : in  std_logic_vector(0 to 31);
>    CNT_W_IN			  : in  std_logic_vector(0 to 31)
> 
>       if Bus2IP_Addr(0 to 31) = C_BASEADDR + x"130" then	--Add Reg 1
>           IP2Bus_Data <= CNT_H_IN; ←送りたい値
>       end if;
>       if Bus2IP_Addr(0 to 31) = C_BASEADDR + x"160" then	--Add Reg 2
>           IP2Bus_Data <= CNT_V_IN;
>       end if;
>       if Bus2IP_Addr(0 to 31) = C_BASEADDR + x"190" then	--Add Reg 3
>           IP2Bus_Data <= CNT_W_IN;
>       end if;
> 
> Linux側atmark-dist

以下atmark-distではなく、linux-kernelへの修正ですよね?

> ・suzaku_siv.h
> 
> struct cog_param{		   // use IOCTL
> 	unsigned long cog_h;	   // Center of gravity -> horizontal
> 	unsigned long cog_v;	   // Center of gravity -> vertical
> 	unsigned long cog_w;	   // white
> };
> 
> #define FBIO_COG_H				_IOWR('V', 0x14, struct cog_param *)
> #define FBIO_COG_V				_IOWR('V', 0x15, struct cog_param *)
> #define FBIO_COG_W				_IOWR('V', 0x16, struct cog_param *)
> 
> ・siv.c 
> 
> #define REG_SIV_COG_H			(siv_addr + 0x130)
> #define REG_SIV_COG_V			(siv_addr + 0x160)
> #define REG_SIV_COG_W			(siv_addr + 0x190)    ←ここら辺が設定して値が返
> ってくるMAXの値です.
> + 0x200 などにすると値が返ってきません.

siv_addr + 0x200はFPGAで定義していますか?定義していないのであれば値が
返ってこないのは正しい挙動のように感じます。

> siv_ctlrのbase~high Addressまでの値が0x1FFだったの
> で増やせば使えるのかなと思い現在変更を試みて
> いるところです.関係ないのでしょうか?

これを増やすのが、xparameters.hですね。

以下は問題無さそうです。

以上です。

> 関数siv_ioctl内
> 
> struct cog_param cog_param;
> 
>     case FBIO_COG_H:
> 		copy_from_user(&cog_param, (void *)arg, sizeof(cog_param));
> 		cog_param.cog_h =in_be32(REG_SIV_COG_H);
> 		copy_to_user((void *)arg, &cog_param, sizeof(cog_param));
> 		return 0;
>     case FBIO_COG_V:
> 		copy_from_user(&cog_param, (void *)arg, sizeof(cog_param));
> 		cog_param.cog_v = in_be32(REG_SIV_COG_V);
> 		copy_to_user((void *)arg, &cog_param, sizeof(cog_param));
> 		return 0;
>     case FBIO_COG_W:
> 		copy_from_user(&cog_param, (void *)arg, sizeof(cog_param));
> 		cog_param.cog_w = in_be32(REG_SIV_COG_W);
> 		copy_to_user((void *)arg, &cog_param, sizeof(cog_param));
> 		return 0;
> 
> ・demo-av.c
> 
>               if (fd >= 0) {
> 			ioctl(fd, FBIO_COG_H, &cog_param);
> 			ioctl(fd, FBIO_COG_V, &cog_param);
> 			ioctl(fd, FBIO_COG_W, &cog_param);
>                }
> 
> sprintf(buf, "H:%ld  V:%ld  W:%ld", cog_param.cog_h, cog_param.cog_v,
> cog_param.cog_w);
> printf("<center>%s</center>\n", buf);
> 
> COGとはCenter Of Gravity(重心)のことで,H,V,Wが表示したい値です.
> 大雑把に書いてしまってすいません.
> 
> FPGAについてはスターターキットなどをかじりましたが,完全に理解したとはい
> いがたく,
> 初心者並の知識です.長々と書いてしまいましたが,解決案があればご教授お願
> いします.




suzaku メーリングリストの案内