0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

用FPGA搭建一個(gè)STM32內(nèi)核?

硬件攻城獅 ? 來(lái)源:硬件攻城獅 ? 2023-03-20 10:11 ? 次閱讀

1.必要的基礎(chǔ)知識(shí)

為了更快的完成在FPGA上實(shí)現(xiàn)ARM Cortex-M3軟核,一些必要的基礎(chǔ)知識(shí)還是要有的!

FPGA開(kāi)發(fā)基礎(chǔ)知識(shí),如FPGA開(kāi)發(fā)流程,設(shè)計(jì)、綜合、布局、布線、約束、下載

Xilinx Vivado開(kāi)發(fā)環(huán)境使用基礎(chǔ),如BlockDesign設(shè)計(jì)方式,管腳分配,Bit流文件生成與下載

ARM Cortex-M3內(nèi)核的使用基礎(chǔ),如STM32MM32、GD32、CH32等微控制器的開(kāi)發(fā)。

Keil-MDK開(kāi)發(fā)環(huán)境的使用基礎(chǔ),基本的工程建立、編譯、下載流程。

如果以上知識(shí)都具備,那么,恭喜你!可以在2小時(shí)內(nèi)完成ARM Cortex-M3軟核在FPGA上的實(shí)現(xiàn)。

2.Cortex-M3 FPGA IP核下載

首先,我們需要從ARM官網(wǎng)上獲取ARM Cortex-M3 FPGA軟核IP包。

下載地址如下:

https://silver.arm.com/browse/AT426

文件名稱(chēng):Cortex-M3 DesignStart FPGA-Xilinx edition(r0p1-00rel0)

文件大小:7.52MB

MD5SUM:cd67536c29023429cde47130d51b6f49

官網(wǎng)下載需要先注冊(cè)賬號(hào),如果下載速度很慢,可以在公眾號(hào)后臺(tái)回復(fù):220318,獲取下載鏈接,復(fù)制到瀏覽器下載。

f585d4ee-c4b7-11ed-bfe3-dac502259ad0.jpgARM官網(wǎng)

壓縮包解壓之后,共有4個(gè)文件夾:

f5b91c3c-c4b7-11ed-bfe3-dac502259ad0.jpg壓縮包內(nèi)容

各個(gè)文件夾存放的內(nèi)容:

docs

存放ARM Cortex-M3處理器參考手冊(cè)、DesignStart FPGA版本使用說(shuō)明、基于Arty-A7開(kāi)發(fā)板的頂層BlockDesign框圖等文件。

hardware

存放基于Digilent Arty-A7開(kāi)發(fā)板的Vivado工程,頂層BlockDesign文件,管腳約束文件,Testbench文件等。

software

存放Keil-MDK工程,SPI Flash的編程算法文件等。

vivado

包括DesignStart Cortex-M3 Xilinx FPGA版本的IP核文件,其中Arm_ipi_repository文件夾就是內(nèi)核源文件了,IP文件內(nèi)容已經(jīng)加密,沒(méi)有可讀性。

f5d72768-c4b7-11ed-bfe3-dac502259ad0.jpgIP核源碼

3.硬件準(zhǔn)備

為了完成DS CM3在FPGA上的搭建,我們至少需要以下硬件:

一塊Artix-7開(kāi)發(fā)板,用于構(gòu)建Cortex-M3軟核SoC,我使用的是正點(diǎn)原子達(dá)芬奇Pro開(kāi)發(fā)板,F(xiàn)PGA型號(hào)為XC7A100T

Xilinx FPGA下載器,用于下載軟核Bit流到FPGA,如Platform Usb Cable,JTAG-HS2/HS3等。

ARM Cortex-M?3調(diào)試器,用于調(diào)試ARM核程序下載和調(diào)試,如JlinkV9,Jlink-OB等。

官方的DS CM3 IP核是基于Digilent的Arty-A7開(kāi)發(fā)板,F(xiàn)PGA型號(hào)為XC7A35T/100T,Vivado版本為v2019.1,如果你手頭正好有這塊開(kāi)發(fā)板,那么可以直接使用官方提供的示例工程。

arty-a7開(kāi)發(fā)板

正點(diǎn)原子達(dá)芬奇Pro開(kāi)發(fā)板

4.軟件準(zhǔn)備

Xilinx Vivado開(kāi)發(fā)環(huán)境,官方建議版本為2018.2以上,我使用的是2018.3版本

Keil MDK開(kāi)發(fā)環(huán)境,如5.33版本

DS_CM3的Keil器件包

從Keil官網(wǎng)上下載DesignStart Cortex-M3所專(zhuān)用的器件支持包,下載鏈接如下:

https://keilpack.azureedge.net/pack/Keil.V2M-MPS2_DSx_BSP.1.1.0.pack

5.Cortex-M3軟核搭建

準(zhǔn)備好以上軟硬件,就可以開(kāi)始Cortex-M3軟核的搭建了。

首先,新建一個(gè)文件夾,命名為cortex_m3_on_xc7a100t,用于存放本次示例所有的工程文件,并新建以下幾個(gè)文件夾:

f6c391f2-c4b7-11ed-bfe3-dac502259ad0.jpg目錄結(jié)構(gòu)

每個(gè)文件夾的功能:

bd文件夾

用來(lái)存放BlockDesign設(shè)計(jì)

cm3_core文件夾

用來(lái)存放的是ARM Cortex-M3內(nèi)核IP核文件,

doc文件夾

用來(lái)存放設(shè)計(jì)文檔

flash文件夾

用來(lái)存放生成的bit和mcs文件

rtl文件夾

用來(lái)存放用戶(hù)設(shè)計(jì)的verilog源文件

xdc文件夾

用來(lái)存放管腳、時(shí)序約束文件

其中cm3_core文件夾,需要將官方壓縮文件文件中的Arm_ipi_repository文件夾復(fù)制過(guò)來(lái),路徑為AT426-BU-98000-r0p1-00rel0vivadoArm_ipi_repository

以上文件夾準(zhǔn)備好之后,就可以開(kāi)始新建工程了。

5.1 新建Vivado工程

打開(kāi)Vivado 2018.3,打開(kāi)工程創(chuàng)建向?qū)?,輸入工程名稱(chēng),工程的存放路徑為之前我們新建的文件夾。

f7017760-c4b7-11ed-bfe3-dac502259ad0.jpg新建工程

選擇FPGA芯片的完整型號(hào):XC7A100TFGG484

f71d5bd8-c4b7-11ed-bfe3-dac502259ad0.jpg選擇芯片型號(hào)

最終創(chuàng)建完成之后的工程目錄

f743a1da-c4b7-11ed-bfe3-dac502259ad0.jpgVivado工程目錄

5.2 添加IP核搜索路徑

為了能在BlockDesign中搜索到ARM Cortex-M3處理器IP核,我們需要把ARM 軟核IP所在的路徑添加到搜索路徑。

f766901e-c4b7-11ed-bfe3-dac502259ad0.jpg添加到搜索路徑

5.3 創(chuàng)建BlockDesign設(shè)計(jì)

為了方便后續(xù)使用圖形化的方式連接各IP核,我們采用BlockDesign圖形化的設(shè)計(jì)方式,這樣可以快速的搭建出一顆定制化的軟核處理器。

新建BlockDesign,命名為cm3_core,保存到最初創(chuàng)建的bd文件夾中。

在畫(huà)布中添加Cortex-M3處理器核:

f7a8277c-c4b7-11ed-bfe3-dac502259ad0.jpg添加ARM核

雙擊Cortex-M3 IP核進(jìn)行一些基本配置,我們不需要Trace功能,選擇No Trace,使用SWD接口調(diào)試,禁用JTAG端口

f7cc7a1e-c4b7-11ed-bfe3-dac502259ad0.jpg配置ARM核

指令空間和數(shù)據(jù)空間大小,這里設(shè)置成64KB,都不進(jìn)行初始化。

f808b02e-c4b7-11ed-bfe3-dac502259ad0.jpgITCM核DTCM配置

5.4 添加一些必要的IP核

時(shí)鐘PLL

用于提供給內(nèi)核、總線、外設(shè)時(shí)鐘,這里我們配置成50MHz單端輸入,PLL輸出配置成50MHz,如果時(shí)鐘頻率設(shè)置更高,綜合后會(huì)提示WNS,TNS時(shí)序不滿(mǎn)足,可能會(huì)影響系統(tǒng)的正常運(yùn)行。

處理器復(fù)位IP

用于提供內(nèi)核、外設(shè)、互聯(lián)組件所需要的復(fù)位信號(hào),不需要進(jìn)行定制,保持默認(rèn)設(shè)置。

總線互聯(lián)IP

Cortex-M3內(nèi)核為AHB總線,而且內(nèi)部已經(jīng)轉(zhuǎn)換成了AXI3總線,而Xilinx官方提供的GPIO/UART等外設(shè)IP核是AXI4-Lite總線,所以需要添加一個(gè)總線互聯(lián)矩陣,用于將不同協(xié)議進(jìn)行轉(zhuǎn)換,從機(jī)數(shù)量配置為1,主機(jī)數(shù)量配置為2,連接到處理器的SYS總線。

基本邏輯門(mén)IP

Cortex-M3內(nèi)核需要低電平復(fù)位,而復(fù)位IP輸出為高電平復(fù)位,需要在中間插入一個(gè)非門(mén)來(lái)進(jìn)行轉(zhuǎn)換。

常量IP

本次軟核搭建不涉及中斷部分,所以IRQ和NMI都給定常量0即可,如果需要將中斷接入處理器,可以通過(guò)Concat核將多個(gè)中斷源合并成一個(gè)連接到IRQ。

將以上IP添加到BlockDesign畫(huà)布中,并按照下圖進(jìn)行連接:

f82df668-c4b7-11ed-bfe3-dac502259ad0.jpg原理圖連接

從官方手冊(cè)中可以知道,ARM提供的軟核IP中已經(jīng)包括了ITCM和DTCM存儲(chǔ)器,所以我們無(wú)需添加外部的BRAM來(lái)作為程序和數(shù)據(jù)的存儲(chǔ)區(qū)。

f8674404-c4b7-11ed-bfe3-dac502259ad0.jpgCortex-M3內(nèi)核結(jié)構(gòu)

內(nèi)核中提供ITCM和DTCM都是基于RAM實(shí)現(xiàn),這也就意味著后續(xù)我們使用Keil下載程序只是下載到RAM中,掉電數(shù)據(jù)會(huì)丟失。

至此,ARM Cortex-M3處理器內(nèi)核就搭建完成了,下面來(lái)添加GPIO和UART外設(shè)。

5.5 添加GPIO和UART外設(shè)

一些常用的單片機(jī),如STM32,芯片內(nèi)部的TIM、UART、SPI、CAN等外設(shè)一般是固定數(shù)量的,而我們使用FPGA來(lái)搭建ARM軟核SoC就比較靈活了,如果你不需要SPI,那就不用添加SPI外設(shè),需要10個(gè)UART就添加10個(gè)UART,外設(shè)配置比較靈活,當(dāng)然這些外設(shè)都是基于FPGA邏輯資源實(shí)現(xiàn)的,實(shí)際添加的數(shù)量會(huì)受限于FPGA芯片的邏輯資源大小。

下面以添加一組AXI GPIO和一組AXI UART為例,介紹如何使用ARM軟核來(lái)控制這兩個(gè)外設(shè)。

Xilinx官方提供的AXI GPIO外設(shè)具有以下特性:

內(nèi)部有兩個(gè)通道,通道1和通道2,每個(gè)通道最多支持32個(gè)管腳

每個(gè)管腳可以配置成輸入或輸出模式

每個(gè)管腳可以設(shè)置復(fù)位初值

支持中斷輸出

提供的AXI UART外設(shè)有以下特性:

全雙工

支持5-8位數(shù)據(jù)位

支持奇偶校驗(yàn)

可配置波特率110-230400

這里我們將GPIO配置成雙通道,通道1為輸出模式,低4位用于連接LED,通道2為輸入模式,低4位用于連接按鍵。

f896cb70-c4b7-11ed-bfe3-dac502259ad0.jpgGPIO配置

UART配置成115200波特率,8位數(shù)據(jù)位,無(wú)奇偶校驗(yàn)。

f8af466e-c4b7-11ed-bfe3-dac502259ad0.jpgUART配置

配置完成之后,將它們連接的到互聯(lián)IP的主機(jī)接口上:

f8d3d60a-c4b7-11ed-bfe3-dac502259ad0.jpg原理圖連接

這兩組IP的時(shí)鐘可以和處理器使用同樣的時(shí)鐘,復(fù)位可以使用復(fù)位IP輸出的外設(shè)復(fù)位信號(hào)。

關(guān)于AXI GPIO和AXI UART的詳細(xì)使用,可以查看官方文檔:

pg144-axi-gpio.pdf

https://www.xilinx.com/support/documentation/ip_documentation/axi_gpio/v2_0/pg144-axi-gpio.pdf

pg142-axi-uartlite.pdf

https://www.xilinx.com/support/documentation/ip_documentation/axi_uartlite/v2_0/pg142-axi-uartlite.pdf

5.6 SWD接口的引出

官方的DesignStart IP核資料中,除了Cortex-M3處理器,還有一個(gè)DAP-Link調(diào)試核,如果使用DAP-Link調(diào)試器需要添加這個(gè)IP核。

f8f4845e-c4b7-11ed-bfe3-dac502259ad0.jpgDAP-Link

這里我們不使用DAP-Link調(diào)試器,而是使用Jlink SWD模式。SWD模式一共需要兩根線,一個(gè)是SWCLK時(shí)鐘信號(hào),一個(gè)是SWDIO雙向數(shù)據(jù)信號(hào),處理器提供了3個(gè)管腳:SWDI,SWDO和SWDOEN,我們還需要實(shí)現(xiàn)一個(gè)雙向端口模塊。

基于IOBUF原語(yǔ)實(shí)現(xiàn)的雙向端口模塊,內(nèi)容如下:

moduleswdio_tri_buffer(
//Inputs
inputswd_o,
inputswd_oe,

//Outputs
outputswd_i,

//Inouts
inoutswd_io
);

IOBUFswd_iobuf_inst(
.O(swd_i),
.I(swd_o),
.IO(swd_io),

.T(!swd_oe)
);

endmodule

將它添加到我們的設(shè)計(jì)中。

f923c822-c4b7-11ed-bfe3-dac502259ad0.jpgSWD接口連接

最終的BlockDesign設(shè)計(jì)如下圖所示:

f934723a-c4b7-11ed-bfe3-dac502259ad0.jpg原理圖連接

5.7 分配外設(shè)基地址

添加完外設(shè)IP之后,我們還需要對(duì)外設(shè)進(jìn)行基地址和空間分配,在地址編輯框,右鍵選擇自動(dòng)分配。

f996e384-c4b7-11ed-bfe3-dac502259ad0.jpg基地址分配

分配完成之后,使用設(shè)計(jì)驗(yàn)證(Validate Design)功能,可以檢查當(dāng)前BlockDesign設(shè)計(jì)連接的合法性。

f9cf2834-c4b7-11ed-bfe3-dac502259ad0.jpg驗(yàn)證設(shè)計(jì)

5.8 生成Wrapper并例化到頂層

為了方便后續(xù)添加自定義的FPGA邏輯模塊,我們將Cortex-M3軟核處理器作為一個(gè)處理器例化到頂層設(shè)計(jì)中。

在BlockDesign源文件上右鍵,先選擇Generate Output Products,耐心等待生成完成之后,選擇Create HDL Wrapper。

f9ef3e6c-c4b7-11ed-bfe3-dac502259ad0.jpg生成Wrapper

之后就會(huì)生成一個(gè)_wrapper的verilog文件。

新建頂層文件top_hdl.v并保存到rtl文件夾,將_wrapper例化到頂層。

moduletop_hdl(
//Inputs
inputclk,
inputrst_n,
inputswclk,
inputuart_rxd,
input[3:0]sw,

//Outputs
output[3:0]led,
outputuart_txd,

//Inouts
inoutswdio
);

cm3_core_wrappercm3_core_wrapper_ut0(
//Inputs
.cm3_clk(clk),
.cm3_resetn(rst_n),
.cm3_gpio_in_tri_i(sw[3:0]),
.cm3_swclk(swclk),
.cm3_uart_rxd(uart_rxd),

//Outputs
.cm3_gpio_out_tri_o(led[3:0]),
.cm3_uart_txd(uart_txd),

//Inouts
.cm3_swdio(swdio)
);

endmodule//top_hdlend

5.9 管腳分配

綜合(Synthesis)完成之后,使用Vivado的圖形化工具進(jìn)行管腳分配,尤其注意要將SWDIO和SWDCLK引出到排針管腳上,方便后續(xù)使用外接的Jlink調(diào)試器進(jìn)行ARM程序下載。

fa159620-c4b7-11ed-bfe3-dac502259ad0.jpg分配管腳

或者直接新建XDC文件,使用約束語(yǔ)句進(jìn)行管腳分配。

部分約束語(yǔ)句:

set_propertyPACKAGE_PINR4[get_portsclk]
set_propertyPACKAGE_PINV13[get_portsswclk]
set_propertyPACKAGE_PINV14[get_portsswdio]
set_propertyPACKAGE_PINE14[get_portsuart_rxd]
set_propertyPACKAGE_PIND17[get_portsuart_txd]
set_propertyPACKAGE_PINU7[get_portsrst_n]
set_propertyPACKAGE_PINV9[get_ports{led[3]}]
set_propertyPACKAGE_PINY8[get_ports{led[2]}]
set_propertyPACKAGE_PINY7[get_ports{led[1]}]
set_propertyPACKAGE_PINW7[get_ports{led[0]}]
set_propertyPACKAGE_PINT4[get_ports{key[3]}]
set_propertyPACKAGE_PINT3[get_ports{key[2]}]
set_propertyPACKAGE_PINR6[get_ports{key[1]}]
set_propertyPACKAGE_PINT6[get_ports{key[0]}]

如果你的板子和我的(正點(diǎn)原子達(dá)芬奇Pro)一樣,那么可以直接使用以上管腳約束。

如果你分配的時(shí)鐘管腳不是FPGA的全局時(shí)鐘管腳,需要添加BUFG原語(yǔ)進(jìn)行緩沖。

5.10 Bit流文件生成和下載

我的板子使用的是QSPI Flash,為了提高下載和啟動(dòng)速度,在生成Bit流時(shí),配置生成選項(xiàng):數(shù)據(jù)壓縮、50M讀取速度,4位數(shù)據(jù)線

fb0a1af6-c4b7-11ed-bfe3-dac502259ad0.jpg生成Bit流配置

或者直接使用XDC語(yǔ)句進(jìn)行約束:

set_propertyBITSTREAM.GENERAL.COMPRESSTRUE[current_design]
set_propertyBITSTREAM.CONFIG.CONFIGRATE50[current_design]
set_propertyCONFIG_VOLTAGE3.3[current_design]
set_propertyCFGBVSVCCO[current_design]
set_propertyBITSTREAM.CONFIG.SPI_BUSWIDTH4[current_design]

以上約束不是必須的,只是為了提高下載和配置速度。

耐心等待工程綜合完成,生成Bit流文件,綜合的速度和處理器主頻、核心數(shù)有關(guān)。

和常規(guī)的FPGA下載方式一樣,將生成的軟核Bit文件通過(guò)Xilinx下載器下載到FPGA內(nèi)部,先不要固化到外部SPI Flash 。

手頭沒(méi)有Xilinx下載器的,可以參考之前的文章,自己做一個(gè)JTAG-HS2下載器

開(kāi)源、低成本的Xilinx FPGA下載器

5.11 Jlink連接測(cè)試

下載完成之后,現(xiàn)在FPGA內(nèi)部運(yùn)行的就是一顆基于ARM Cortex-M3的軟核處理器了,使用Jlink等調(diào)試工具可以連接到芯片。

將Jlink調(diào)試器的SWCLK和SWDIO連接到我們分配的管腳V13和V14上。

手頭沒(méi)有Jlink的,也可以參考之前的文章,自己做一個(gè)Jlink-OB

手把手教你制作Jlink-OB調(diào)試器

使用Keil開(kāi)發(fā)DesignStart Cortex-M3軟核的程序,需要先安裝一個(gè)DesignStart專(zhuān)用的器件包。

打開(kāi)一個(gè)STM32 Keil工程,器件修改為剛剛安裝的ARM DS_CM3,在Option->Debug-Setting界面中選擇SWD方式,第一次連接會(huì)提示需要選擇一個(gè)器件,這里選擇Cortex-M3:

fb58cce6-c4b7-11ed-bfe3-dac502259ad0.jpg選擇器件型號(hào)

如果以上配置均正確,就能看到已經(jīng)連接到的ARM Cortex-M3核心。如果沒(méi)有,說(shuō)明FPGA工程配置有錯(cuò)誤,需要確認(rèn)是否和以上配置流程一致。

fb7e002e-c4b7-11ed-bfe3-dac502259ad0.jpg連接到ARM核心

至此,ARM Cortex-M3軟核基本搭建完成,接下來(lái)我們使用Keil來(lái)編寫(xiě)ARM核的程序,實(shí)現(xiàn)GPIO和UART的控制。

6.Cortex-M3軟核程序設(shè)計(jì)

和常規(guī)的ARM Cortex-M3內(nèi)核單片機(jī)開(kāi)發(fā)流程類(lèi)似,使用Keil新建工程,源文件,根據(jù)外設(shè)使用手冊(cè),讀寫(xiě)指定的寄存器實(shí)現(xiàn)GPIO的控制,UART數(shù)據(jù)寫(xiě)入,編譯下載,調(diào)試。

在之前創(chuàng)建的cortex_m3_on_xc7a100t文件夾下,新建mdk_prj文件夾,用于保存Keil-MDK的工程,并新建以下3個(gè)文件夾:

application//用戶(hù)源文件
object//編譯生成的文件
project//Keil的工程文件

6.1 新建Keil工程

打開(kāi)Keil-MDK,選擇Project->New Project,新建一個(gè)工程,命名為ds_cm3_prj,保存到project目錄下。

fbb793e8-c4b7-11ed-bfe3-dac502259ad0.jpgKeil工程目錄

器件型號(hào)選擇我們新安裝的ARM Cortex-M3 DS_CM3內(nèi)核。

fbe97d68-c4b7-11ed-bfe3-dac502259ad0.jpg選擇器件型號(hào)

組件管理界面中,添加CMSIS內(nèi)核文件和Startup啟動(dòng)文件:

fc113f06-c4b7-11ed-bfe3-dac502259ad0.jpg添加內(nèi)核文件

并按照如下結(jié)構(gòu)組織文件:

fc4e076a-c4b7-11ed-bfe3-dac502259ad0.jpg文件結(jié)構(gòu)

6.2 設(shè)置RAM和ROM地址

在工程選項(xiàng)中設(shè)置片上ITCM的起始地址0x0、大小64K,片上DTCM起始地址0x20000000、大小64K:

fc7bb200-c4b7-11ed-bfe3-dac502259ad0.jpgRAM地址配置

起始地址來(lái)源于使用手冊(cè)中圖4-1系統(tǒng)內(nèi)存地址映射,可以看到其中ITCM和DTCM的起始地址:

fc8f8e92-c4b7-11ed-bfe3-dac502259ad0.jpgITCM和DTCM起始地址

大小是我們?cè)贑ortex-M3內(nèi)核配置中設(shè)置的大?。?/p>

fcbd22ee-c4b7-11ed-bfe3-dac502259ad0.jpgITCM和DTCM大小

設(shè)置完成之后,新建main.c文件,輸入以下內(nèi)容,編譯工程,應(yīng)該無(wú)錯(cuò)誤輸出。

#include"DS_CM3.h"
#include"system_DS_CM3.h"

intmain(void)
{
while(1)
{

}
}

6.3 GPIO輸入輸出控制

通過(guò)查看AXI GPIO的使用手冊(cè),通道1的數(shù)據(jù)寄存器偏移地址為0,通道2的數(shù)據(jù)寄存器偏移地址為0x08,根據(jù)Vivado中的連接,LED連接到通道1,按鍵連接到通道2上,所以只需要對(duì)這兩個(gè)寄存器地址進(jìn)行讀寫(xiě),就可以實(shí)現(xiàn)LED的控制和撥碼開(kāi)關(guān)狀態(tài)的讀取。

fcdd689c-c4b7-11ed-bfe3-dac502259ad0.jpgAXI GPIO寄存器定義

在Vivado地址分配界面,可以看到GPIO和UART的基地址分別為:0x4000_0000和0x4060_0000。

fd180f88-c4b7-11ed-bfe3-dac502259ad0.jpg外設(shè)基地址

LEL控制和撥碼開(kāi)關(guān)讀?。?/p>

*(volatileuint32_t*)(0x40000000+0x0)=0x0f;//GPIO通道1低4位寫(xiě)1
*(volatileuint32_t*)(0x40000000+0x0)=0x00;//GPIO通道1低4位寫(xiě)0

uint32_tsw=0;
sw=*(uint32_t*)(0x40000000+0x08);//獲取GPIO通道2的32位輸入狀態(tài)

6.4 串口數(shù)據(jù)發(fā)送和接收

向串口發(fā)送FIFO寫(xiě)入一字節(jié)數(shù)據(jù):

while((*(volatileuint32_t*)(0x40600000+0x08))&0x08!=0x08);//等待發(fā)送FIFO不滿(mǎn)
*(volatileuint32_t*)(0x40600000+0x04)=0x41;//向串口發(fā)送FIFO寫(xiě)入字符'A'=0x41

從串口接收一字節(jié)數(shù)據(jù):

uint8_tdat=0;
if((*(volatileuint32_t*)(0x40600000+0x08))&0x01==1)//串口接收FIFO中有數(shù)據(jù)
dat=(*(volatileuint32_t*)(0x40600000+0x00));//從接收FIFO中讀取1字節(jié)數(shù)據(jù)。

關(guān)于AXI GPIO和AXI UART寄存器的詳細(xì)說(shuō)明,可以查看官方文檔:

pg144-axi-gpio.pdf

https://www.xilinx.com/support/documentation/ip_documentation/axi_gpio/v2_0/pg144-axi-gpio.pdf

pg142-axi-uartlite.pdf

https://www.xilinx.com/support/documentation/ip_documentation/axi_uartlite/v2_0/pg142-axi-uartlite.pdf

6.5 延時(shí)函數(shù)實(shí)現(xiàn)

為了讓LED的變化,可以被人眼所看到,需要使用延時(shí)函數(shù)對(duì)亮滅進(jìn)行延時(shí)。

使用系統(tǒng)滴答定時(shí)器實(shí)現(xiàn)一個(gè)延時(shí)函數(shù):

volatileuint32_tcnt=0;//volatile類(lèi)型

voidSysTick_Handler(void)
{
cnt++;
}

voiddelay_ms(uint32_tt)
{
cnt=0;
while(cnt-t>0);
}

為了讓延時(shí)函數(shù)準(zhǔn)確延時(shí),我們還需要更改工程中的系統(tǒng)時(shí)鐘頻率,和FPGA中配置的內(nèi)核時(shí)鐘保持一致。

fd4f0060-c4b7-11ed-bfe3-dac502259ad0.jpg

系統(tǒng)時(shí)鐘

完成的main.c文件內(nèi)容:

#include"DS_CM3.h"
#include"system_DS_CM3.h"
//C庫(kù)
#include
#include
#include

#defineBASEADDR_LED0x40000000
#defineBASEADDR_UART0x40600000
#defineCHANNEL_LED1
#defineCHANNEL_SW2

#defineXGPIO_CHAN_OFFSET8
#defineXGpio_WriteReg(BaseAddress,RegOffset,Data)Xil_Out32((BaseAddress)+(RegOffset),(uint32_t)(Data))
#defineXGpio_ReadReg(BaseAddress,RegOffset)XGpio_In32((BaseAddress)+(RegOffset))

#defineXUL_TX_FIFO_OFFSET4/*transmitFIFO,writeonly*/
#defineXUL_STATUS_REG_OFFSET8/*statusregister,readonly*/
#defineXUL_SR_TX_FIFO_FULL0x08/*transmitFIFOfull*/

#defineXUartLite_GetStatusReg(BaseAddress)XUartLite_ReadReg((BaseAddress),XUL_STATUS_REG_OFFSET)
#defineXUartLite_ReadReg(BaseAddress,RegOffset)XGpio_In32((BaseAddress)+(RegOffset))

#defineXUartLite_IsTransmitFull(BaseAddress)
((XUartLite_GetStatusReg((BaseAddress))&XUL_SR_TX_FIFO_FULL)==
XUL_SR_TX_FIFO_FULL)

#defineXUartLite_WriteReg(BaseAddress,RegOffset,Data)Xil_Out32((BaseAddress)+(RegOffset),(uint32_t)(Data))

volatileuint32_tcnt=0;

voidSysTick_Handler(void)
{
cnt++;
}

voiddelay_ms(uint32_tt)
{
cnt=0;
while(cnt-t>0);
}

uint32_tXGpio_In32(uint32_tAddr)
{
return*(volatileuint32_t*)Addr;
}

voidXil_Out32(uint32_tAddr,uint32_tValue)
{
volatileuint32_t*LocalAddr=(volatileuint32_t*)Addr;
*LocalAddr=Value;
}

uint32_tXGpio_DiscreteRead(uint32_tAddr,uint8_tChannel)
{
returnXGpio_ReadReg(Addr,(Channel-1)*XGPIO_CHAN_OFFSET);
}

voidXGpio_DiscreteWrite(uint32_tAddr,uint8_tChannel,uint32_tData)
{
XGpio_WriteReg(Addr,(Channel-1)*XGPIO_CHAN_OFFSET,Data);
}

voidXUartLite_SendByte(uint32_tBaseAddress,uint8_tData)
{
while(XUartLite_IsTransmitFull(BaseAddress));
XUartLite_WriteReg(BaseAddress,XUL_TX_FIFO_OFFSET,Data);
}

voidcm3_print(constchar*ptr)
{
while(*ptr!=(char)0){
XUartLite_SendByte(BASEADDR_UART,*ptr);
ptr++;
}
}

voidMyUartPrintf(char*fmt,...)
{
unsignedcharUsartPrintfBuf[296];
va_listap;
unsignedchar*pStr=UsartPrintfBuf;

va_start(ap,fmt);
vsnprintf((char*)UsartPrintfBuf,sizeof(UsartPrintfBuf),(constchar*)fmt,ap);
va_end(ap);

while(*pStr!=0)
{
XUartLite_SendByte(BASEADDR_UART,*pStr);
pStr++;
}
}

voidled_blink(void)
{
XGpio_DiscreteWrite(BASEADDR_LED,CHANNEL_LED,0);
delay_ms(500);
XGpio_DiscreteWrite(BASEADDR_LED,CHANNEL_LED,0xf);
delay_ms(500);
}

intmain(void)
{
uint32_tsw=0;

SystemCoreClockUpdate();
SysTick_Config(SystemCoreClock/1000);

cm3_print("HelloDesignStartARMCortex-M3onFPGAXilnxArtix-7XC7A100T
");
MyUartPrintf("SystemCoreClock=%ld
",SystemCoreClock);

while(1)
{
led_blink();
sw=XGpio_DiscreteRead(BASEADDR_LED,CHANNEL_SW);
MyUartPrintf("keystate=%d-%d-%d-%d
",sw>>3,sw>>2&1,sw>>1&1,sw&1);
}
}

實(shí)現(xiàn)的功能是,4顆LED每100ms閃爍一次,同時(shí)串口輸出此時(shí)撥碼開(kāi)關(guān)的實(shí)時(shí)狀態(tài)。

編譯無(wú)誤后,就可以進(jìn)行程序下載了。

6.6 Flash編程算法生成

使用Jlink下載程序需要指定Flash編程算法,但是Keil自帶的算法中并沒(méi)有我們所需要的:

fdb87374-c4b7-11ed-bfe3-dac502259ad0.jpg下載算法

所以我們需要定制一份Flash編程算法,打開(kāi)Keil安裝目錄下的ARMFlash文件夾,將_Template文件夾復(fù)制出一份,并命名為DS_CM3,

fdeeba2e-c4b7-11ed-bfe3-dac502259ad0.jpg復(fù)制模板

打開(kāi)其中的Keil工程:

fe4b0a54-c4b7-11ed-bfe3-dac502259ad0.jpg下載算法

這個(gè)工程可以自己設(shè)置要編程的Flash起始地址、大小,擦除大小等。

FlashDev.c文件填入以下內(nèi)容,和我們之前ITCM的配置保持一致,起始地址0x0,大小64K:

#include"..FlashOS.H"http://FlashOSStructures

structFlashDeviceconstFlashDevice={
FLASH_DRV_VERS,//DriverVersion,donotmodify!
"MyCM3onFPGA",//DeviceName
ONCHIP,//DeviceType
0x00000000,//DeviceStartAddress
0x00010000,//修改為64KB
1024,//ProgrammingPageSize
0,//Reserved,mustbe0
0xFF,//InitialContentofErasedMemory
100,//ProgramPageTimeout100mSec
3000,//EraseSectorTimeout3000mSec

//SpecifySizeandAddressofSectors
0x010000,0x000000,//只有一個(gè)扇區(qū),起始地址為0
SECTOR_END
};

FlashPrg.c文件,實(shí)現(xiàn)一些存儲(chǔ)區(qū)擦除的函數(shù):


#include"..FlashOS.H"http://FlashOSStructures
#include"string.h"

intInit(unsignedlongadr,unsignedlongclk,unsignedlongfnc){
return(0);//FinishedwithoutErrors
}

intUnInit(unsignedlongfnc){
return(0);//FinishedwithoutErrors
}

intEraseChip(void){
memset((unsignedchar*)0,0,0x10000);
return(0);//FinishedwithoutErrors
}

intEraseSector(unsignedlongadr){
memset((unsignedchar*)adr,0,1024);
return(0);//FinishedwithoutErrors
}

intProgramPage(unsignedlongadr,unsignedlongsz,unsignedchar*buf){
memcpy((unsignedchar*)adr,buf,sz);
return(0);//FinishedwithoutErrors
}

編譯無(wú)誤后,會(huì)在工程目錄下生成一個(gè)FLM文件。
fe812792-c4b7-11ed-bfe3-dac502259ad0.jpg新生成的下載算法

將它復(fù)制到上一級(jí)目錄:

fe971dfe-c4b7-11ed-bfe3-dac502259ad0.jpg新生成的下載算法

6.7 編譯下載運(yùn)行

再打開(kāi)我們的ARM核Keil工程,添加DS_CM3 Flash編程算法:

fece7074-c4b7-11ed-bfe3-dac502259ad0.jpg添加Flash編程算法

點(diǎn)擊下載按鈕,把ARM程序下載到ARM核:

fee74bc6-c4b7-11ed-bfe3-dac502259ad0.jpg

可以看到LED每500ms閃爍一次,串口數(shù)據(jù)每1s輸出一次,同時(shí)按下按鍵,串口輸出按鍵的狀態(tài)。

ff1b0eb6-c4b7-11ed-bfe3-dac502259ad0.jpg

和其他ARM內(nèi)核芯片一樣,也是支持在線調(diào)試的:

ff3a661c-c4b7-11ed-bfe3-dac502259ad0.jpg43

由于ARM程序是下載到Cortex-M3軟核內(nèi)的RAM存儲(chǔ)區(qū),所以掉電后程序會(huì)丟失。如何將程序下載到片外的SPI Flash中,我還沒(méi)有成功實(shí)現(xiàn)。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 微控制器
    +關(guān)注

    關(guān)注

    48

    文章

    7399

    瀏覽量

    150664
  • FPGA
    +關(guān)注

    關(guān)注

    1624

    文章

    21573

    瀏覽量

    600706
  • ARM
    ARM
    +關(guān)注

    關(guān)注

    134

    文章

    9009

    瀏覽量

    366136
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    3

    文章

    1351

    瀏覽量

    40159
  • STM32
    +關(guān)注

    關(guān)注

    2263

    文章

    10849

    瀏覽量

    353865

原文標(biāo)題:用FPGA搭建一個(gè)STM32內(nèi)核?

文章出處:【微信號(hào):mcu168,微信公眾號(hào):硬件攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    基于STM32U5 的 STM32CubeMX環(huán)境搭建

    基于STM32U5 的 STM32CubeMX環(huán)境搭建
    的頭像 發(fā)表于 09-21 17:35 ?1386次閱讀
    基于<b class='flag-5'>STM32</b>U5 的 <b class='flag-5'>STM32</b>CubeMX環(huán)境<b class='flag-5'>搭建</b>

    請(qǐng)問(wèn)FPGAstm32串口通信位數(shù)比較大的數(shù)據(jù)如何用串口去傳輸

    就是在之前stm32作串口的時(shí)候直沒(méi)有仔細(xì)去思考串口通信的過(guò)程,直到自己fpga試著去搭建
    發(fā)表于 05-10 02:40

    在Altera系列fpga搭建cortex m3內(nèi)核,添加攝像頭外設(shè)的問(wèn)題

    描述:在塊Altera cyclone iv系列的fpga芯片上(友晶的DE2-115開(kāi)發(fā)板),搭建個(gè)cortex-M3軟核,并把ov7
    發(fā)表于 04-19 23:17

    如何自己搭建個(gè)STM32編程IDE?

    編譯器組成與編譯流程是怎樣的?如何自己搭建個(gè)STM32編程IDE?
    發(fā)表于 11-29 06:20

    Xilinx_FPGA系列入門(mén)教程()—如何搭建Xilinx

    Xilinx FPGA系列入門(mén)教程()——如何搭建Xilinx FPGA開(kāi)發(fā)環(huán)境
    發(fā)表于 01-18 15:30 ?45次下載

    編寫(xiě)個(gè)可以GRUB來(lái)引導(dǎo)的簡(jiǎn)單x86內(nèi)核

    我們將從零開(kāi)始,動(dòng)手編寫(xiě)個(gè)可以GRUB來(lái)引導(dǎo)的簡(jiǎn)單x86內(nèi)核,該內(nèi)核會(huì)在屏幕上打印條信息,
    的頭像 發(fā)表于 01-21 09:12 ?7467次閱讀

    Linux內(nèi)核學(xué)習(xí)的環(huán)境搭建內(nèi)核編譯

    基礎(chǔ)知識(shí)及基本shell命令;現(xiàn)代操作系統(tǒng)的基本概念;C語(yǔ)言和gcc基本使用。 在開(kāi)始我們的linux內(nèi)核學(xué)習(xí)之前。首先需要搭建我們的工作學(xué)習(xí)環(huán)境,即安裝linux系統(tǒng)。關(guān)于linux系統(tǒng)構(gòu)建本身的學(xué)問(wèn)已經(jīng)復(fù)雜到可以成為
    的頭像 發(fā)表于 01-02 18:01 ?2072次閱讀

    STM32MP1系列Cortex-M4內(nèi)核開(kāi)發(fā)和調(diào)試

    STM32MP1系列Cortex-M4內(nèi)核開(kāi)發(fā)STM32CubeIDE開(kāi)發(fā)環(huán)境搭建從官網(wǎng)下載最新的STM32CubeIDE開(kāi)發(fā)環(huán)境安裝MP1
    發(fā)表于 12-01 12:21 ?1次下載
    <b class='flag-5'>STM32</b>MP1系列Cortex-M4<b class='flag-5'>內(nèi)核</b>開(kāi)發(fā)和調(diào)試

    STM32CubeMX——搭建環(huán)境、編譯燒寫(xiě)

    文章內(nèi)容:本文主要介紹STM32CubeMX的安裝方法,以及怎么這個(gè)軟件來(lái)生成個(gè)流水燈工程文件。目錄、
    發(fā)表于 12-07 10:21 ?22次下載
    <b class='flag-5'>STM32</b>CubeMX——<b class='flag-5'>搭建</b>環(huán)境、編譯燒寫(xiě)

    STM32(CM3內(nèi)核) 內(nèi)存映射

    這里寫(xiě)目錄標(biāo)題STM32(CM3內(nèi)核) 內(nèi)存映射.CM3內(nèi)核簡(jiǎn)介二.CM3內(nèi)核地址映射三.搭建
    發(fā)表于 12-07 19:21 ?9次下載
    <b class='flag-5'>STM32</b>(CM3<b class='flag-5'>內(nèi)核</b>) 內(nèi)存映射

    STM32 搭建開(kāi)發(fā)環(huán)境

    STM32 搭建開(kāi)發(fā)環(huán)境
    發(fā)表于 12-08 14:36 ?20次下載
    <b class='flag-5'>STM32</b> <b class='flag-5'>搭建</b>開(kāi)發(fā)環(huán)境

    [STM32]STM32F407系列教程之,搭建簡(jiǎn)潔template模板

    [STM32]STM32F407系列教程之,搭建簡(jiǎn)潔template模板
    發(fā)表于 12-08 20:21 ?16次下載
    [<b class='flag-5'>STM32</b>]<b class='flag-5'>STM32</b>F407系列教程之<b class='flag-5'>一</b>,<b class='flag-5'>搭建</b>簡(jiǎn)潔template模板

    STM32來(lái)DIY個(gè)示波器

    下周開(kāi)始,套硬禾學(xué)堂精心制作的大課就要正式上線播出了 - STM32來(lái)DIY個(gè)示波器,總
    的頭像 發(fā)表于 07-12 09:53 ?6592次閱讀

    如何搭建個(gè)私有云平臺(tái)

    智能硬件開(kāi)發(fā)是個(gè)交叉學(xué)科,通常在入門(mén)的時(shí)候,是以單片機(jī)STM32為主,搭建云平臺(tái)或接入云平臺(tái),以此實(shí)現(xiàn)智能產(chǎn)品開(kāi)發(fā)和設(shè)計(jì)。
    發(fā)表于 08-04 10:21 ?6688次閱讀

    基于FPGA搭建個(gè)通用的圖像處理平臺(tái)

    本文介紹如何搭建個(gè)通用的圖像處理平臺(tái),采用HDMI接口進(jìn)行輸入、輸出,可用于測(cè)試基于HLS的FPGA圖像處理項(xiàng)目。
    的頭像 發(fā)表于 09-04 18:20 ?2090次閱讀
    基于<b class='flag-5'>FPGA</b><b class='flag-5'>搭建</b><b class='flag-5'>一</b><b class='flag-5'>個(gè)</b>通用的圖像處理平臺(tái)