Download pdf - Microblaze loader

Transcript
Page 1: Microblaze loader

MicroBoardのSPI ROMからMicroBlazeのプログラムを読んで起動する話

イーツリーズ/わさらぼ三好 健文

Page 2: Microblaze loader

やること1) MicroBlaze大きなプログラムを実行したい

← BlockRAMにのらない/外部メモリで実行2) プログラムは自動的に実行を開始したい

← ROMからプログラムを読んで実行したい3) MicroBoardにはQSPI FlashROMが載ってる4) Xilinx AR#55026にSPIからのブートローダが5) MicroBoardでも試してみよう

Page 3: Microblaze loader

手順概要1) MicroBlazeシステムを構築2) QSPIをシステムに追加3) トップのHDLを作成.#HOLDの処置を追加4) UCFを記述5) ローダーとアプリケーションプログラムを用意6) ローダーをBlockRAMに埋め込む7) アプリケーションプログラムを分割8) MCSファイルを作る

Page 4: Microblaze loader

MicroBlazeシステムを構築/概要● ISEからプロジェクトを作る● BSBで基本システムを作成

– 入力クロック66.666667MHz– CPU動作周波数66MHz– 使用デバイスを追加

● DDR3(後でLPDDRに設定するけど)● LED(GPIO出力)● DIPスイッチ(GPIO入力)● UART(ボーレート115200に)

● 細かなパラメタ調整

Page 5: Microblaze loader

MicroBlazeシステムを構築(1)ISEプロジェクトを作成コンテクストメニューからNew Sourceを選択

New Sourceとして追加するのはEmbedded Processor名前はお好みで

XPS起動直後にBSB Wizardを使うか?と聞かれるので”YES”を選択

Page 6: Microblaze loader

MicroBlazeシステムを構築(2)PLBじゃなくてAXIを使う(デフォルトのままいじらない)

周波数は66.666667MHzリセットはActive HIGH

● CPUの動作周波数は66MHz● 周辺デバイスに下記を追加

● MCB_DDR3● LED(GPIO, 4bit)● DIPスイッチ(GPIO, 4bit)● UART(115200, Interruptあり)

Page 7: Microblaze loader

MicroBlazeシステムを構築(3)● 入出力ポートの設定

– LEDとDIPスイッチが8bitなので4bit([0:3])に修正– クロック入力は差動じゃないので削除して新規作成

BSBで4bitと指定したのに,[0:7]になっていたので[0:3]に修正

差動クロックは削除

新たにクロック入力ピンを生成clock_generator_0_CLKIN_pinになった

Page 8: Microblaze loader

MicroBlazeシステムを構築(4)● MIGでメモリの設定

– DDR3をLPDDRにする– メモリはMT46H32M16XXXX-5を選択– ほかはデフォルトでOK

MCB_DDR3をダブルクリックしてMIGを起動

LPDDRを選択MT46H32M16XXXX-5を選択

Page 9: Microblaze loader

MicroBlazeシステムを構築(5)● メモリ用のクロックを200MHzに設定する

clock_generator_0をダブルクリック

メモリの動作周波数が600MHzになっている

200MHzに設定する

Page 10: Microblaze loader

MicroBlazeシステムを構築(6)● ブロックRAMのサイズを32KBにする

microblaze_0_d_bram_ctrlとmicroblaze_0_i_bram_ctrlのそれぞれの設定ダイアログを開いて

LMB BRAM High Addressを0x00007fffに設定

設定の確認は”Addresses”タブで

Page 11: Microblaze loader

QSPI ROMをシステムに追加/概要● IP CatalogでAXI Quad SPI Interfaceを選択● FIFO Depthを16,SCK Ratioを2に設定● microblaze_0(作ったCPU)にぶら下げる● 外部クロックをCLKOUT2に設定● 必要なポートを外部ピンに設定する● ここまで完了したらNetlistを作る

Page 12: Microblaze loader

QSPI ROMをシステムに追加(1)

AXI Quad SPI InterfaceIPコアを選択

名前をQSPI_FLASHに決めた(何でもいい)

microblaze_0に接続(デフォルト) モジュール(QSPI_FLASH)が追加できた

FIFO Depth=16,SCK Ratio=2に設定

Page 13: Microblaze loader

QSPI ROMをシステムに追加(2)● SPIクロックのソースをCLKOUT2に設定● IOピンを外部に引き出す

“Ports”タブでポートの設定をする - EXT_SPI_CLKにclock_generator_0のCLKOUT2を接続 - SCK, SS, IO0, IO1, SPISELを外部ポートに指定

終わったら,確認がてらNetlistを作成しておく

Page 14: Microblaze loader

トップのHDLを作成/概要● ISEに戻ってトップモジュールのHDLを生成● SSELは常に'1'にする● #HOLD用の信号を追加.常に'1'を出力

作成したEmbedded Processorを選択して

Create top HDL Sourceをダブルクリック

トップモジュール(のVHDLコード)がプロジェクトに追加された

Page 15: Microblaze loader

トップのHDLを作成(1)● SSELは常に'1'にする

– 外部ポートのQSPI_FLASH_SPISEL_pinを削除– port map は QSPI_FLASH_SPISEL_pin => '1',

● #HOLD用の信号を追加.常に'1'を出力– QSPI_FLASH_HOLD : out std_logic を追加– QSPI_FLASH_HOLD <= '1'; とか

後述のbootloaderプログラムではSPIモードでROMにアクセスします#HOLD (D3)を'1'にしていないと,データが読めません!!

Page 16: Microblaze loader

UCFの記述● いつも通り.メモリは書かなくていいから楽

NET RS232_Uart_1_sout LOC = T7 | IOSTANDARD = LVCMOS33;NET RS232_Uart_1_sin LOC = R7 | IOSTANDARD = LVCMOS33;NET RESET LOC = V4 | IOSTANDARD = LVCMOS33 | TIG | PULLDOWN;NET LEDS_TRI_O<0> LOC = P4 | IOSTANDARD = LVCMOS18;NET LEDS_TRI_O<1> LOC = L6 | IOSTANDARD = LVCMOS18;NET LEDS_TRI_O<2> LOC = F5 | IOSTANDARD = LVCMOS18;NET LEDS_TRI_O<3> LOC = C2 | IOSTANDARD = LVCMOS18;NET DIP_Switches_TRI_I<0> LOC = B3 | IOSTANDARD = LVCMOS33;NET DIP_Switches_TRI_I<1> LOC = A3 | IOSTANDARD = LVCMOS33;NET DIP_Switches_TRI_I<2> LOC = B4 | IOSTANDARD = LVCMOS33;NET DIP_Switches_TRI_I<3> LOC = A4 | IOSTANDARD = LVCMOS33;NET clock_generator_0_CLKIN_pin LOC = K15 | IOSTANDARD = LVCMOS33;NET QSPI_FLASH_SCK_pin LOC = R15 | IOSTANDARD = LVCMOS33;NET QSPI_FLASH_SS_pin LOC = V3 | IOSTANDARD = LVCMOS33;NET QSPI_FLASH_IO0_pin LOC = T13 | IOSTANDARD = LVCMOS33;NET QSPI_FLASH_IO1_pin LOC = R13 | IOSTANDARD = LVCMOS33;

NET QSPI_FLASH_HOLD LOC = V14 | IOSTANDARD = LVCMOS33;

NET "clock_generator_0_CLKIN_pin" TNM_NET = clock_generator_0_CLKIN_pin;TIMESPEC TS_clock_generator_0_CLKIN_pin = PERIOD clock_generator_0_CLKIN_pin 66666 kHz;

### Set Vccaux for S6LX9 MicroBoard to 3.3V ###CONFIG VCCAUX = "3.3" ;

Page 17: Microblaze loader

ローダーとアプリケーションを用意● Xilinx #AR55026からいただいてくる● このローダーはアプリケーションプログラムの

サイズを埋め込む必要があるので注意– REST_SECTION_BYTE_NUM

● DDRメモリの名前が違うので修正– xparameters.hを参照– XPAR_DDR3_SDRAM_S_AXI_BASEADDR を

XPAR_MCB_DDR3_S0_AXI_BASEADDRに変更● ローダーは全セクションをBRAMに割り当てる

– lscript.ldでタブから選べばいい

Page 18: Microblaze loader

ブートローダーの中身● SPIメモリにアクセスするための初期化● SPIメモリからプログラムを読んでDDRメモリ

に書く● 書き終わったら,DDRメモリの先頭(プログラ

ム開始アドレス)にジャンプする

Page 19: Microblaze loader

ブートローダーの中身(抜粋).../* * Read the rest_section data from flash. */for(i=0; i<(REST_SECTION_BYTE_NUM/16)+1; i++){ Status = SpiFlashRead(&Spi, (REST_SECTION_START_ADDR+16*i), 16, COMMAND_RANDOM_READ); if(Status != XST_SUCCESS) { return XST_FAILURE; } for(k=0; k<16; k++) *destination_location++ = ReadBuffer[k+4];}/* * Read the vector_section data from flash. */for(i=0; i<(VECTOR_SECTION_BYTE_NUM/16)+1; i++){ Status = SpiFlashRead(&Spi, (VECTOR_SECTION_START_ADDR+16*i), 16, COMMAND_RANDOM_READ); if(Status != XST_SUCCESS) { return XST_FAILURE; } for(k=0; k<16; k++) *reset_location++ = ReadBuffer[k+4];}xil_printf("user application load succeed!\r\n");boot_app = (int (*) (void)) XPAR_DDR3_SDRAM_S_AXI_BASEADDR;boot_app();...

Page 20: Microblaze loader

ローダーをBlockRAMに埋め込む● data2memを実行すればよい● SDKで作ったelfファイルをプロジェクトに登録してGenerate Programming FileでOK

elfをプロジェクトに登録

Generate Programming Fileを実行なお,初回登録時は”?”状態になるがelfを変更しても状態は変更ず生成済状態のままなので注意!!

内部ではdata2memが実行されるbitファイルは上書きではなく別に生成される.注意!!

Page 21: Microblaze loader

アプリケーションを分割/概要● アプリケーションプログラムの空間はでかい

– ベクタ関連のセクション(0x00000000-0x0000004f)

– プログラムデータ(DDRのアドレス)● そのままだと大量の無駄な領域が必要● 分割して個別にバイナリイメージ化する

Page 22: Microblaze loader

アプリケーションを分割(1)

C:\WORK\images>mb-objcopy -O binary -j .vectors.reset ^ -j .vectors.sw_exception -j .vectors.interrupt -j .vectors.hw_exception ^ user_application.elf vector_section.bin

● ISEなコマンドプロンプトシェルで作業– ベクタセクションだけをとりだす

– ベクタセクション以外を取り出す

– ここで作成したrest_section.binのサイズをbootloader.cのREST_SECTION_BYTE_NUMに設定

C:\WORK\images> mb-objcopy -O binary -R .vectors.reset ^ -R .vectors.sw_exception -R .vectors.interrupt -R .vectors.hw_exception ^ user_application.elf rest_section.bin

Page 23: Microblaze loader

アプリケーションを分割(2)● 実行例

Page 24: Microblaze loader

MCSファイルを作成/概要● FPGAのbitファイルとアプリケーションを

MCSにまとめる– FPGAのbitファイルは0番地から– アプリケーションプログラムは0xb00000から– ベクタ領域は0xc0000から– 開始位置を変更したければbootloader.cを修正

● iMPACTでもコマンドラインでもOK

Page 25: Microblaze loader

MCSファイルを作成(1)

C:\WORK\images>promgen -spi ^ -w -p mcs -u 0 download.bit ^ -data_file up b00000 rest_section.bin^ -data_file up c00000 vector_section.bin

● 次のコマンドを実行すればよい

作ったらROMに書く

Page 26: Microblaze loader

起動● 動いた.● 読み出しデータを表示してみたところ

Page 27: Microblaze loader

まとめ● AR#55026をMicroBlazeで試してみた● 動いた,やったね!!● 今更ISE?

– まあSpartan6使わなきゃなこともあるし● 次は,

– 自己書き換え,かな– SDKのサンプルの様にS形式を解釈する?


Recommended