精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于FPGA搭建ARM Cortex-M3 SoC軟核

我快閉嘴 ? 來源:電子電路開發學習 ? 作者:wcc149 ? 2022-08-30 11:14 ? 次閱讀

上一篇文章介紹了ARM DesignStart計劃,其中提到了Cortex-M1/M3 DesignStart FPGA版本,支持Xilinx和國產Gowin平臺,本篇文章將手把手教你如何基于ARM DesignStart計劃,在FPGA上搭建一個Cortex-M3軟核處理器,以Xilinx Artix-7系列FPGA為例,介紹如何定制一顆ARM Cortex-M3 SoC軟核,并添加GPIO和UART外設,使用Keil MDK環境開發應用程序,Jlink下載、調試ARM程序,最終的實現效果是LED閃爍,串口輸出Hello World信息。

c22dfbe2-2810-11ed-ba43-dac502259ad0.jpg

都有哪些內容?

  • 必要的基礎知識

  • Cortex-M3 FPGA IP核下載

  • 硬件準備

  • 軟件準備

  • Cortex-M3軟核搭建

      • 新建Vivado工程

      • 添加IP核搜索路徑

      • 創建BlockDesign設計

      • 添加IP核,GPIO和UART外設

      • SWD接口引出

      • 外設基地址分配

      • 管腳分配

      • Bit流文件生成下載

  • Cortex-M3軟核程序設計

      • 新建Keil工程

      • GPIO輸入輸出控制實現

      • 串口數據發送和接收實現

      • 延時函數實現

      • Flash編程算法生成

      • 下載運行

本篇文章內容比較長,我已經將本文整理成了PDF文件,文中創建的Vivado工程,ARM Cortex-M3 IP核,Keil-MDK工程,Flash編程算法文件等等資料,我都已經上傳到GitHub、Gitee,文末可以查看開源地址。

或者關注我的公眾號,后臺回復:220327,獲取資料的下載地址。

1.必要的基礎知識

為了更快的完成在FPGA上實現ARM Cortex-M3軟核,一些必要的基礎知識還是要有的!

  • FPGA開發基礎知識,如FPGA開發流程,設計、綜合、布局、布線、約束、下載

  • Xilinx Vivado開發環境使用基礎,如BlockDesign設計方式,管腳分配,Bit流文件生成與下載

  • ARM Cortex-M3內核的使用基礎,如STM32MM32、GD32、CH32等微控制器的開發。

  • Keil-MDK開發環境的使用基礎,基本的工程建立、編譯、下載流程。

如果以上知識都具備,那么,恭喜你!可以在2小時內完成ARM Cortex-M3軟核在FPGA上的實現。

2.Cortex-M3 FPGA IP核下載

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

下載地址如下:

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

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

文件大小:7.52MB

MD5SUM:cd67536c29023429cde47130d51b6f49

官網下載需要先注冊賬號,如果下載速度很慢,可以在公眾號后臺回復:220318,獲取下載鏈接,復制到瀏覽器下載。

c23eeb28-2810-11ed-ba43-dac502259ad0.jpgARM官網

壓縮包解壓之后,共有4個文件夾:

c24d8822-2810-11ed-ba43-dac502259ad0.jpg壓縮包內容

各個文件夾存放的內容:

  • docs

存放ARM Cortex-M3處理器參考手冊、DesignStart FPGA版本使用說明、基于Arty-A7開發板的頂層BlockDesign框圖等文件。

  • hardware

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

  • software

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

  • vivado

包括DesignStart Cortex-M3 Xilinx FPGA版本的IP核文件,其中Arm_ipi_repository文件夾就是內核源文件了,IP文件內容已經加密,沒有可讀性。

c25b020e-2810-11ed-ba43-dac502259ad0.jpgIP核源碼

3.硬件準備

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

  • 一塊Artix-7開發板,用于構建Cortex-M3軟核SoC,我使用的是正點原子達芬奇Pro開發板,FPGA型號為XC7A100T。

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

  • ARM Cortex-M3調試器,用于調試ARM核程序下載和調試,如JlinkV9,Jlink-OB等。

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

Digilent Arty-A7開發板:

c27dbcea-2810-11ed-ba43-dac502259ad0.jpgarty-a7開發板

正點原子達芬奇Pro開發板:

c292a7b8-2810-11ed-ba43-dac502259ad0.jpg正點原子達芬奇Pro開發板

4.軟件準備

  • Xilinx Vivado開發環境,官方建議版本為2018.2以上,我使用的是2018.3版本

  • Keil MDK開發環境,如5.33版本

  • DS_CM3的Keil器件包

    從Keil官網上下載DesignStart Cortex-M3所專用的器件支持包,下載鏈接如下:

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

5.Cortex-M3軟核搭建

準備好以上軟硬件,就可以開始Cortex-M3軟核的搭建了。

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

c2a225ee-2810-11ed-ba43-dac502259ad0.jpg目錄結構

每個文件夾的功能:

  • bd文件夾

    用來存放BlockDesign設計

  • cm3_core文件夾

    用來存放的是ARM Cortex-M3內核IP核文件,

  • doc文件夾

    用來存放設計文檔

  • flash文件夾

    用來存放生成的bit和mcs文件

  • rtl文件夾

    用來存放用戶設計的verilog源文件

  • xdc文件夾

    用來存放管腳、時序約束文件

其中cm3_core文件夾,需要將官方壓縮文件文件中的Arm_ipi_repository文件夾復制過來,路徑為AT426-BU-98000-r0p1-00rel0vivadoArm_ipi_repository

以上文件夾準備好之后,就可以開始新建工程了。

5.1 新建Vivado工程

打開Vivado 2018.3,打開工程創建向導,輸入工程名稱,工程的存放路徑為之前我們新建的文件夾。

c2b5674e-2810-11ed-ba43-dac502259ad0.jpg新建工程

選擇FPGA芯片的完整型號:XC7A100TFGG484。

c2c49fd4-2810-11ed-ba43-dac502259ad0.jpg選擇芯片型號

最終創建完成之后的工程目錄

c2e1cd52-2810-11ed-ba43-dac502259ad0.jpgVivado工程目錄

5.2 添加IP核搜索路徑

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

c2eee5f0-2810-11ed-ba43-dac502259ad0.jpg添加到搜索路徑

5.3 創建BlockDesign設計

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

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

在畫布中添加Cortex-M3處理器核:

c2fe8d0c-2810-11ed-ba43-dac502259ad0.jpg添加ARM核

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

c3125684-2810-11ed-ba43-dac502259ad0.jpg配置ARM核

指令空間和數據空間大小,這里設置成64KB,都不進行初始化。

c32af7ac-2810-11ed-ba43-dac502259ad0.jpgITCM核DTCM配置

5.4 添加一些必要的IP核

  • 時鐘PLL

    用于提供給內核、總線、外設時鐘,這里我們配置成50MHz單端輸入,PLL輸出配置成50MHz,如果時鐘頻率設置更高,綜合后會提示WNS,TNS時序不滿足,可能會影響系統的正常運行。

  • 處理器復位IP

    用于提供內核、外設、互聯組件所需要的復位信號,不需要進行定制,保持默認設置。

  • 總線互聯IP

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

  • 基本邏輯門IP

    Cortex-M3內核需要低電平復位,而復位IP輸出為高電平復位,需要在中間插入一個非門來進行轉換。

  • 常量IP

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

將以上IP添加到BlockDesign畫布中,并按照下圖進行連接:

c33a4dec-2810-11ed-ba43-dac502259ad0.jpg原理圖連接

從官方手冊中可以知道,ARM提供的軟核IP中已經包括了ITCM和DTCM存儲器,所以我們無需添加外部的BRAM來作為程序和數據的存儲區。

c34ae9e0-2810-11ed-ba43-dac502259ad0.jpgCortex-M3內核結構

內核中提供ITCM和DTCM都是基于RAM實現,這也就意味著后續我們使用Keil下載程序只是下載到RAM中,掉電數據會丟失。

至此,ARM Cortex-M3處理器內核就搭建完成了,下面來添加GPIO和UART外設。

5.5 添加GPIO和UART外設

一些常用的單片機,如STM32,芯片內部的TIM、UART、SPI、CAN等外設一般是固定數量的,而我們使用FPGA來搭建ARM軟核SoC就比較靈活了,如果你不需要SPI,那就不用添加SPI外設,需要10個UART就添加10個UART,外設配置比較靈活,當然這些外設都是基于FPGA邏輯資源實現的,實際添加的數量會受限于FPGA芯片的邏輯資源大小。

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

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

  • 內部有兩個通道,通道1和通道2,每個通道最多支持32個管腳

  • 每個管腳可以配置成輸入或輸出模式

  • 每個管腳可以設置復位初值

  • 支持中斷輸出

提供的AXI UART外設有以下特性:

  • 全雙工

  • 支持5-8位數據位

  • 支持奇偶校驗

  • 可配置波特率110-230400

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

c35d1048-2810-11ed-ba43-dac502259ad0.jpgGPIO配置

UART配置成115200波特率,8位數據位,無奇偶校驗。

c45b0edc-2810-11ed-ba43-dac502259ad0.jpgUART配置

配置完成之后,將它們連接的到互聯IP的主機接口上:

c46700de-2810-11ed-ba43-dac502259ad0.jpg原理圖連接

這兩組IP的時鐘可以和處理器使用同樣的時鐘,復位可以使用復位IP輸出的外設復位信號。

關于AXI GPIO和AXI UART的詳細使用,可以查看官方文檔:

  • 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處理器,還有一個DAP-Link調試核,如果使用DAP-Link調試器需要添加這個IP核。

c47b38f6-2810-11ed-ba43-dac502259ad0.jpgDAP-Link

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

基于IOBUF原語實現的雙向端口模塊,內容如下:

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

將它添加到我們的設計中。

c48afc50-2810-11ed-ba43-dac502259ad0.jpgSWD接口連接

最終的BlockDesign設計如下圖所示:

c49c59b4-2810-11ed-ba43-dac502259ad0.jpg原理圖連接

5.7 分配外設基地址

添加完外設IP之后,我們還需要對外設進行基地址和空間分配,在地址編輯框,右鍵選擇自動分配。

c4ae97aa-2810-11ed-ba43-dac502259ad0.jpg基地址分配

分配完成之后,使用設計驗證(Validate Design)功能,可以檢查當前BlockDesign設計連接的合法性。

c4bcf502-2810-11ed-ba43-dac502259ad0.jpg驗證設計

5.8 生成Wrapper并例化到頂層

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

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

c4c88b92-2810-11ed-ba43-dac502259ad0.jpg生成Wrapper

之后就會生成一個_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的圖形化工具進行管腳分配,尤其注意要將SWDIO和SWDCLK引出到排針管腳上,方便后續使用外接的Jlink調試器進行ARM程序下載。

c4d7911e-2810-11ed-ba43-dac502259ad0.jpg分配管腳

或者直接新建XDC文件,使用約束語句進行管腳分配。

部分約束語句:

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]}]

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

如果你分配的時鐘管腳不是FPGA的全局時鐘管腳,需要添加BUFG原語進行緩沖。

5.10 Bit流文件生成和下載

我的板子使用的是QSPI Flash,為了提高下載和啟動速度,在生成Bit流時,配置生成選項:數據壓縮、50M讀取速度,4位數據線。

c4e6be3c-2810-11ed-ba43-dac502259ad0.jpg生成Bit流配置

或者直接使用XDC語句進行約束:

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流文件,綜合的速度和處理器主頻、核心數有關。

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

手頭沒有Xilinx下載器的,可以參考之前的文章,自己做一個JTAG-HS2下載器!

開源、低成本的Xilinx FPGA下載器

c4fa0bc2-2810-11ed-ba43-dac502259ad0.jpg

5.11 Jlink連接測試

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

Jlink調試器的SWCLK和SWDIO連接到我們分配的管腳V13和V14上。

手頭沒有Jlink的,也可以參考之前的文章,自己做一個Jlink-OB

手把手教你制作Jlink-OB調試器

c50a45b4-2810-11ed-ba43-dac502259ad0.jpg

使用Keil開發DesignStart Cortex-M3軟核的程序,需要先安裝一個DesignStart專用的器件包。

下載地址如下:

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

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

c518bbda-2810-11ed-ba43-dac502259ad0.jpg選擇器件型號

如果以上配置均正確,就能看到已經連接到的ARM Cortex-M3核心。如果沒有,說明FPGA工程配置有錯誤,需要確認是否和以上配置流程一致。

c530829c-2810-11ed-ba43-dac502259ad0.jpg連接到ARM核心

至此,ARM Cortex-M3軟核基本搭建完成,接下來我們使用Keil來編寫ARM核的程序,實現GPIO和UART的控制。

6.Cortex-M3軟核程序設計

和常規的ARM Cortex-M3內核單片機開發流程類似,使用Keil新建工程,源文件,根據外設使用手冊,讀寫指定的寄存器實現GPIO的控制,UART數據寫入,編譯下載,調試。

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

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

6.1 新建Keil工程

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

c543af3e-2810-11ed-ba43-dac502259ad0.jpgKeil工程目錄

器件型號選擇我們新安裝的ARM Cortex-M3 DS_CM3內核。

c551a18e-2810-11ed-ba43-dac502259ad0.jpg選擇器件型號

組件管理界面中,添加CMSIS內核文件和Startup啟動文件:

c560d97e-2810-11ed-ba43-dac502259ad0.jpg添加內核文件

并按照如下結構組織文件:

c574ad8c-2810-11ed-ba43-dac502259ad0.jpg文件結構

6.2 設置RAM和ROM地址

在工程選項中設置片上ITCM的起始地址0x0、大小64K,片上DTCM起始地址0x20000000、大小64K:

c585566e-2810-11ed-ba43-dac502259ad0.jpgRAM地址配置

起始地址來源于使用手冊中圖4-1系統內存地址映射,可以看到其中ITCM和DTCM的起始地址:

c5956f36-2810-11ed-ba43-dac502259ad0.jpgITCM和DTCM起始地址

大小是我們在Cortex-M3內核配置中設置的大?。?/p> c5b5df14-2810-11ed-ba43-dac502259ad0.jpgITCM和DTCM大小

設置完成之后,新建main.c文件,輸入以下內容,編譯工程,應該無錯誤輸出。

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

intmain(void)
{
while(1)
{

}
}

6.3 GPIO輸入輸出控制

通過查看AXI GPIO的使用手冊,通道1的數據寄存器偏移地址為0,通道2的數據寄存器偏移地址為0x08,根據Vivado中的連接,LED連接到通道1,按鍵連接到通道2上,所以只需要對這兩個寄存器地址進行讀寫,就可以實現LED的控制和撥碼開關狀態的讀取。

c5c7ce22-2810-11ed-ba43-dac502259ad0.jpgAXI GPIO寄存器定義

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

c5d7f9c8-2810-11ed-ba43-dac502259ad0.jpg外設基地址

LEL控制和撥碼開關讀?。?/p>

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

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

6.4 串口數據發送和接收

向串口發送FIFO寫入一字節數據:

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

從串口接收一字節數據:

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

關于AXI GPIO和AXI UART寄存器的詳細說明,可以查看官方文檔:

  • 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 延時函數實現

為了讓LED的變化,可以被人眼所看到,需要使用延時函數對亮滅進行延時。

使用系統滴答定時器實現一個延時函數:

volatileuint32_tcnt=0;//volatile類型

voidSysTick_Handler(void)
{
cnt++;
}

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

為了讓延時函數準確延時,我們還需要更改工程中的系統時鐘頻率,和FPGA中配置的內核時鐘保持一致。

c5e53480-2810-11ed-ba43-dac502259ad0.jpg

系統時鐘

完成的main.c文件內容:

#include"DS_CM3.h"
#include"system_DS_CM3.h"
//C庫
#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);
}
}

實現的功能是,4顆LED每100ms閃爍一次,同時串口輸出此時撥碼開關的實時狀態。

編譯無誤后,就可以進行程序下載了。

6.6 Flash編程算法生成

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

c5f5eea6-2810-11ed-ba43-dac502259ad0.jpg下載算法

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

c6034452-2810-11ed-ba43-dac502259ad0.jpg復制模板

打開其中的Keil工程:

c60e1486-2810-11ed-ba43-dac502259ad0.jpg下載算法

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

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

#include"..FlashOS.H"//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,//只有一個扇區,起始地址為0
SECTOR_END
};

FlashPrg.c文件,實現一些存儲區擦除的函數:


	
#include"..FlashOS.H"//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
}

	
編譯無誤后,會在工程目錄下生成一個FLM文件。
c62025ae-2810-11ed-ba43-dac502259ad0.jpg新生成的下載算法

將它復制到上一級目錄:

c62d2934-2810-11ed-ba43-dac502259ad0.jpg新生成的下載算法

6.7 編譯下載運行

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

c6414590-2810-11ed-ba43-dac502259ad0.jpg添加Flash編程算法

點擊下載按鈕,把ARM程序下載到ARM核:

c64dd210-2810-11ed-ba43-dac502259ad0.jpg43

可以看到LED每500ms閃爍一次,串口數據每1s輸出一次,同時按下按鍵,串口輸出按鍵的狀態。

c22dfbe2-2810-11ed-ba43-dac502259ad0.jpg43

和其他ARM內核芯片一樣,也是支持在線調試的:

c668115c-2810-11ed-ba43-dac502259ad0.jpg43

由于ARM程序是下載到Cortex-M3軟核內的RAM存儲區,所以掉電后程序會丟失。如何將程序下載到片外的SPI Flash中,我還沒有成功實現。

7.開源地址

本篇文章的pdf文件,Vivado工程,Keil工程,Keil器件支持 包,Flash編程算法文件,外設IP的參考文檔,ARM M3軟核IP資料包等資料我已經開源到Github和Gitee,地址如下:

  • Gitee

gitclonehttps://gitee.com/whik/cortex_m3_on_xc7a100t.git
  • Github

gitclonehttps://github.com/whik/cortex_m3_on_xc7a100t.git

審核編輯:湯梓紅


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • FPGA
    +關注

    關注

    1626

    文章

    21678

    瀏覽量

    602004
  • ARM
    ARM
    +關注

    關注

    134

    文章

    9057

    瀏覽量

    366873
  • soc
    soc
    +關注

    關注

    38

    文章

    4124

    瀏覽量

    217964
  • Cortex-M3
    +關注

    關注

    9

    文章

    269

    瀏覽量

    59437

原文標題:好文推薦| 手把手教你在FPGA上搭建一個ARM Cortex-M3軟核

文章出處:【微信號:麥克泰技術,微信公眾號:麥克泰技術】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    采用Cortex-M原型系統建立Cortex-M3 DesignStart原型

    ARM最近剛剛宣布了對DesignStart項目的升級,加入了ARM Cortex-M3處理器?,F在,可以通過DesignStart Eval即時、免費地獲取相關IP,對基于Cortex-M
    發表于 07-04 15:28 ?2269次閱讀

    制造一種基于Cortex-M0和Cortex-M3處理器的SoC

    FPGA搭建一顆私人定制的ARM Cortex-M0或Cortex-M3內核的SoC,
    發表于 07-27 16:58

    分享幾個基于ARM的復雜項目

    的實時人臉檢測 SOC介紹項目基于FPGA(Xilinx Spartan7 XC7S50)構建的ARM Cortex-M3
    發表于 08-25 16:31

    ARM Cortex-M3 DesignStart? Eval RTL和FPGA快速入門指南

    Corest-M3 DesignStart Eval允許開發人員基于ARM Cortex-M3處理器輕松開發和模擬SoC設計,然后使用ARM
    發表于 08-12 07:38

    ARM7和Cortex-M3比較

    比較項目 ARM7 Cortex-M3
    發表于 06-07 18:03 ?2789次閱讀

    ARM Cortex-M3權威指南

    ARM Cortex-M3權威指南》重點介紹了新的ARM架構、指令集的總結、硬件特性以及調試系統的概覽。《ARM Cortex-M3權威指
    發表于 12-14 15:08 ?48次下載

    Cortex-M3的新助手-- CoreLink SDK-100

    ARM Cortex-M3 DesignStart項目,幫助設計團隊快速地創建基于Cortex-M3的IoT和嵌入式產品。全新的CoreLink SDK-100對Cortex-M3
    發表于 06-20 15:21 ?2013次閱讀

    深入學習ARM Cortex-M3的權威級

    深入學習ARM Cortex-M3的權威級
    發表于 10-15 10:02 ?9次下載
    深入學習<b class='flag-5'>ARM</b> <b class='flag-5'>Cortex-M3</b>的權威級

    基于ARM Cortex-M3的過采樣技術

    基于ARM Cortex-M3的過采樣技術
    發表于 10-30 16:39 ?8次下載
    基于<b class='flag-5'>ARM</b> <b class='flag-5'>Cortex-M3</b>的過采樣技術

    米爾科技ARM Cortex-M3教程指南

    ARM Cortex-M3權威指南》重點介紹了新的ARM架構、指令集的總結、硬件特性以及調試系統的概覽。
    的頭像 發表于 11-25 09:07 ?2785次閱讀
    米爾科技<b class='flag-5'>ARM</b> <b class='flag-5'>Cortex-M3</b>教程指南

    ARM Cortex-M3系統設計與實現

    ARM Cortex-M3系統設計與實現——STM32基礎篇目錄0. 嵌入式入門學習路線1. STM32 MCU簡介 1.1 stm32 mcu結構 1.2 STM32 MCU存儲器映像 1.3
    發表于 11-05 19:50 ?22次下載
    <b class='flag-5'>ARM</b> <b class='flag-5'>Cortex-M3</b>系統設計與實現

    Ubuntu下Eclipse+GDB+OpenOCD搭建ARM Cortex-M3開發環境

    Ubuntu下Eclipse+GDB+OpenOCD搭建ARM Cortex-M3開發環境??2013-07-04 20:12:12|??分類:Embedded System |??標簽:eclipse??gdb??openoc
    發表于 12-06 19:36 ?11次下載
    Ubuntu下Eclipse+GDB+OpenOCD<b class='flag-5'>搭建</b><b class='flag-5'>ARM</b> <b class='flag-5'>Cortex-M3</b>開發環境

    如何定制一顆ARM Cortex-M3 SoC

    本文將手把手教你如何基于ARM DesignStart計劃,在FPGA搭建一個Cortex-M3
    的頭像 發表于 08-22 09:00 ?2175次閱讀

    如何基于ARMFPGA搭建一個Cortex-M3處理器

    由于ARM程序是下載到Cortex-M3內的RAM存儲區,所以掉電后程序會丟失。如何將程序下載到片外的SPI Flash中,我還沒有成功實現。
    發表于 08-22 08:57 ?2992次閱讀

    FPGA搭建一個STM32內核?

    為了更快的完成在FPGA上實現ARM Cortex-M3,一些必要的基礎知識還是要有的!
    的頭像 發表于 03-20 10:11 ?1460次閱讀