李鑫志 戈志華 劉向明
1(武漢工程大學機電工程學院 湖北 武漢 430073)2(深圳市深視智能科技有限公司 廣東 深圳 518102)
基于ARM平臺AMP架構下從核重復加載設計與實現
李鑫志1,2戈志華2劉向明1
1(武漢工程大學機電工程學院 湖北 武漢 430073)2(深圳市深視智能科技有限公司 廣東 深圳 518102)
針對工業智能相機在不同工作場景的需求以及在二次開發方面的諸多不便,通過重點研究和分析基于多核ARM平臺的AMP架構下主從核的啟動機制,提出一種用戶態從核重復加載方案,豐富了開發者解決實際工程問題的手段。以Zynq-7000為硬件平臺,在雙核Cortex-A9處理器上分別配置嵌入式Linux系統和Bare-Metal環境,實現了主核對從核的復位和重新喚醒控制和不同從核任務程序的自由切換,對工程應用有積極的參考價值。
ARM AMP架構 從核重復加載 嵌入式Linux系統 Bare-Metal環境
隨著嵌入式技術應用領域的日益廣泛和復雜,其對處理器性能、功耗等提出了更高的要求,越來越多的嵌入式應用采用多核處理器作為其硬件開發平臺。多核并行計算技術[1]作為當前計算機系統提高處理能力、減小體積、降低功耗的主要方式,是未來嵌入式計算技術發展的主要方向。在多核并行計算環境中,主要有 SMP、AMP和BMP 三種架構[2-4]。對稱多處理SMP(Symmetric Multi-Processing)架構所有的資源由多核操作系統負責,所有的資源都是共享的,可由操作系統統一管理,在編程的時候要考慮到并行編程的技術,不利于應用程序的移植。混合多處理BMP(Bound multiprocessing)架構,資源由操作系統統一管理,但是上層應用可以指定運行在某一個特定的核上。非對稱多處理AMP(Asymmetric Multi-Processing)架構的特點是每個核都可以擁有自己專有的操作系統,通過共享內存和中斷實現核間通信。其中有一個主核,其余為從核,核間有序啟動且互不干擾。主從核之間的關系如圖1所示。這樣可根據不同系統的性能分配不同任務,具有更優秀的能量效率。

圖1 主從核關系
Zynq-7000系列是Xilinx公司攜手ARM公司,于2012年推出的全可編程片上系統AP SoC(All Programmable System on Chip)[5]可擴展的處理平臺,采用微處理器加可編程邏輯(ARM+FPGA)的結構,并搭載雙核Cortex-A9處理器。本文采用Zynq-7000系列可擴展的處理平臺EPP(Extensible Processing Platform)[6]為硬件平臺,在主核中搭建Linux操作系統(CPU0),從核(CPU1)設計為以Bare-Metal方式運行。CPU1的作用是高速計算,計算數據和結果通過共享內存與CPU0交流。CPU0的主要作用是提供人機交互界面,并控制CPU1的運行。
1.1 主核(CPU0)啟動
Zynq支持兩種啟動模式[7]:安全模式和非安全模式。在安全模式模式下,可以根據PS端配置不同選擇從Quad-SPI Flash、Nand Flash、NOR Flash或SD卡啟動;在非安全模式模式下,可以使用JTAG啟動作為主要啟動方式。CPU0的啟動可以概要地描述為三個階段,分別是:
階段0:BootROM
階段1:First Stage Boot Loader (FSBL)
階段2:Second Stage Boot Loader (SSBL)
BootROM階段控制著Zynq 7000芯片的整個初始化過程。BootROM中的代碼主要對片上系統SoC(System on Chip)中的NOR, Quad-SPI, NAND, SD與基本外設控制器進行初始化,使得ARM核可以訪問并使用這些外圍設備,它還負責加載階段1中的FSBL程序,將系統的控制權移交給FSBL繼續執行。本文設計是從主頻200 MHz 32 MB Quad-SPI Flash中啟動。
第一階段的初始啟動引導程序FSBL(First Stage Boot Loader),是在BootROM之后啟動引導過程,由Boot ROM將其加載到片上存儲器OCM(On-Chip Memory)或直接在NOR Flash上運行。FSBL主要完成以下幾項工作:1) 根據XPS中的配置,完成PS端的初始化;2) 使用比特流文件對PL進行配置;3) 加載CPU1程序;4) 加載階段2段引導程序到內存中,并跳轉到SSBL上進行執行程序。
第二階段是SSBL階段。對于運行在Zynq平臺的Linux 系統而言,SSBL階段就是U-Boot過程。它的作用是完成Linux內核啟動之前所需的全部初始化工作,例如DDR控制器、NAND Flash控制器、SPI控制器等,并且支持從本地或網絡中加載Linux內核、Device Tree文件以及根文件系統到內存中。
啟動流程如圖2所示。

圖2 啟動流程圖
1.2 從核(CPU1)啟動
在主核啟動的FSBL階段,會完成CPU1程序的加載。加載過程中拷貝cpu1_bootvec.bin文件到boot.bif文件中所指向([load = 0xFFFFFFF0]D:lxz ftpcpu1_bootvec.bin)的地址。cpu1_bootvec.bin文件中的內容是一段循環執行代碼的入口地址(0xFFFFFF2C)。可以在XMD中通過命令①:
① XMD% connect arm hw -debugdevice cpunr 2
② XMD% mrd 0xffffff2c 0x10
③ XMD% rrd
連接到CPU1,通過命令②查看從0xFFFFFF2C位置開始的循環執行代碼的內容,如下:
FFFFFF2C: F57FF04F
FFFFFF30: E320F002
FFFFFF34: E3E0000F
FFFFFF38: E590E000
FFFFFF3C: E37E00D4
FFFFFF40: 0AFFFFF9
FFFFFF44: EE070F15
FFFFFF48: EE070FD5
FFFFFF4C: EE080F17
FFFFFF50: E3A04000
FFFFFF54: EE014F18
FFFFFF58: E12FFF1E
循環執行的匯編代碼在這里已經被編譯成16個4字節的十六進制指令。當CPU1上電后會運行這段循環代碼,代碼的功能是自動檢查地址0xFFFFFFF0處的值。也可以通過命令③查看此時PC的值為0x00000000。
在AMP架構的情況下,Linux可以通過remotproc模塊動態加載從核CPU1。這種方案需要先將remotproc模塊安裝到Linux內核,或者動態加載到內核,這樣不利于開發者對CPU1的控制。而且remotproc模塊本身也存在著諸多不穩定的因素。對比該方案,本文提出一種用戶態從核加載方案。
該方案的原理是,當CPU0中Linux系統運行時,向系統級控制寄存器SLCR(System Level Control Registers)中的復位控制寄存器CPU_RCC(CPU Reset and Clock Control)發送命令復位CPU1,然后CPU0將CPU1要運行的新程序加載到DDR中相應位置,這一步在CPU0的代碼中實現。然后重新喚醒CPU1。
由于CPU1在復位后會對CPU1復位時所有通用寄存器都將被清零,所以此時PC是指向0地址的。提前將CPU1的循環執行代碼拷貝到0地址處,當CPU1重新運行起來后就開始執行循環代碼,并檢查地址0xFFFFFFF0的值是否為0,不為0即說明該處被寫入了一個地址,此時CPU1就會跳轉到被寫入的地址處執行。基于這種CPU0喚醒CPU1的機制,可以實現在用戶態下從核的加載。方案的具體步驟如下:
1) 在CPU1運行時,CPU0對其復位;
2) CPU0將CPU1要運行的新程序加載到DDR中;
3) CPU0重新啟動CPU1。
重復以上三個步驟就可以完成在用戶態從核重復加載的目的。方案的流程如圖3所示。

圖3 從核重復加載
從圖3中不難看出,在CPU0與CPU1間完成幾次簡單的通信可以就實現從核重復加載,這使得開發者可以更加簡便、靈活地解決實際工程中的相關問題。
實驗的目的是通過主核(CPU0)控制從核(CPU1)完成重復加載,并先后執行Binarization.elf和RotatingCalipersal.elf兩個圖像處理的CPU1程序。Binarization.elf的功能是對圖像進行二值化處理,RotatingCalipersal.elf的功能是利用旋轉卡殼算法提取圖像中的圓。
3.1 CPU1復位
首先,在CPU1運行時,CPU0是通過調用CPU1控制函數對其進行復位。控制函數實現如下:
#include
#define SYSTEM _REG_SIZE 0x1000
#define SYSTEM _REG_BASSADRESS 0xF8000000
#define SYSTEM _RELATIVE_OFFSET 0x00000244
/*CPU1控制函數實現*/
void Function_Ctrl_Cpu1 (unsigned int reg_value){
int rwmem_fd = -1;
unsigned int *gp_CPU_reset_vaddr = NULL;
rwmem_fd = open("/dev/rwmem", O_RDWR | O_SYNC);
gp_CPU_reset_vaddr = (unsigned int *)mmap(0, SYSTEM
_REG_SIZE,
//映射虛擬地址
PROT_READ|PROT_WRITE, MAP_SHARED,
rwmem_fd, SYSTEM _REG_BASSADRESS);
unsigned int base_addr = (unsigned nt)(gp_CPU_reset_vaddr);
(*(volatile unsigned int*)(base_addr+SYSTEM_RELATIVE
_OFFSET)) = reg_value;
}
參考Zynq-7000 All Programmable SoC Technical Reference Manual中系統級控制寄存器的CPU1復位控制寄存器,如表1所示。向寄存器A9_CPU_RST_CTRL(絕對地址:0xF8000244)寫入值0x22。

表1 Register A9_CPU_RST_CTRL(部分)[7]
于是調用CPU1控制函數如下:
Function_Ctrl_Cpu1 (0x22);
//關閉CPU1時鐘,復位CPU1
3.2 加載bin文件
方案是先將elf文件轉編譯成一個bin文件然后再加載到DDR中。在bin文件中沒有任何段表信息,只需在編譯bin文件時配置文件入口地址。這樣就將原本只能在內核中完成的從核加載轉化成bin可執行文件的用戶態從核加載。
通過編譯工具鏈中的objcopy工具將Binarization.elf文件和RotatingCalipersal.elf文件編譯成bin文件,執行如下命令:
④ [root@localhost]#arm-none-linux-gnueabi-objcopy -O
binary Binarization.elf Binarization .bin
⑤ [root@localhost]#arm-none-linux-gnueabi-objcopy-O
binary RotatingCalipersal.elf RotatingCalipersal.bin
在Xilinx SDK[8]里面通過修改lscript.ld中text段的內存區域屬性修改程序入口地址,此處配置Binarization.bin文件的入口地址為0x10200000。
3.3 重新啟動CPU1
加載Binarization.bin文件成功后,通過兩次調用上述CPU1控制函數,分別將CPU1的時鐘開啟以及重新喚醒CPU1:
Function_Ctrl_Cpu1 (0x20);
//時鐘恢復
Function_Ctrl_Cpu1 (0x0);
//重新喚醒CPU1
在CPU1復位后,所有通用寄存器都被清零,PC指向0地址。將CPU1的循環執行代碼提前拷貝到0地址處, CPU1復位后就開始執行這段代碼,循環檢查地址0xFFFFFFF0處的值。經過上述第二步操作,此時地址0xFFFFFFF0處值已經是0x10200000,即Binarization.bin文件的入口地址。于是CPU1跳轉到Binarization.bin文件入口地址開始運行該可執行文件。同理,重復步驟1)-步驟3),并將可執行文件RotatingCalipersal.bin的入口地址寫到地址0xFFFFFFF0。如此便實現了在用戶態下對從核的重復加載。實驗結果如圖4所示。其中圖4(a)為處理前圖像,圖4(b)為二值化處理后圖像,圖4(c)為原提取圖像。

圖4 實驗結果
本文在Zynq-7000為平臺上,詳細分析了CPU0和CPU1的啟動過程,并利用這種啟動機制,提出了一種在用戶態下從核重復加載方案。方案的特點是開發者可以靈活地在用戶態下復位和喚醒CPU1。將CPU1的任務程序以bin文件的形式提前加載到DDR中,當需要切換時只需加載相應bin文件的入口地址到指定地址即可。通過實驗證明此方案是行之有效且穩定可靠的。
[1] 張林波, 遲學斌, 莫則堯, 等. 并行計算導論[M]. 北京:清華大學出版社, 2006.
[2] Freescale Semiconductor Inc. Running AMP, SMP or BMP Mode for Multicore Embedded Systems[M].USA: Freescale Semiconductor Inc, 2014.
[3] 蔣建軍, 劉彤. 一種AMP架構下的處理器負載均衡改進方法[J]. 山東農業大學學報(自然科學版), 2015 ,46(1):96-100.
[4] 肖學甲. 基于AMP架構的多核間任務同步與通信的設計與實現[D]. 西安:西安電子科技大學, 2011.
[5] 何賓. Xilinx All Programmable Zynq-7000 SoC設計指南[M]. 北京:清華大學出版社, 2013.
[6] Xilinx Inc. Zynq-7000 Extensible Processing Platform Summary[OL]. http://www.xilinx.com/support.html.
[7] Xilinx Inc. Zynq-7000 All Programmable SoC Technical Reference Manual[OL]. https://www.xilinx.com/support/documentation/user_guides/ug585-Zynq-7000-TRM.pdf.
[8] Xilinx Inc. Xilinx Design Tools: Installation and Licensing Guide[OL]. http://www.xilinx.com/support.html.
DESIGN AND IMPLEMENTATION OF SALVE PROCESSOR RELOAD UNDER AMP ARCHITECTURE BASED ON ARM PLATFORM
Li Xinzhi1,2Ge Zhihua2Liu Xiangming1
1(SchoolofMechanicalandElectricalEngineering,WuhanInstituteofTechnology,Wuhan430073,Hubei,China)2(ShenzhenSincevisionTechnologyCo.,Ltd.,Shenzhen518102,Guangdong,China)
Aiming at the need of industrial smart cameras under different working scenes and the inconvenience during secondary development, a user-mode scheme of slave processor reload is proposed through studying and analyzing the booting mechanism of host-slave processor under AMP architecture based on multi-core ARM platform, enriching the approaches for developers to solve practical engineering problems. Choosing Zynq-7000 as hardware platform, then the embedded Linux system and Bare-Metal environment are deployed separately on the part of dual-core processor Cortex-A9. The host processor is able to control the slave processor to reset and re-wakeup, and switch different bare-metal program freely, which has high reference value in engineering applications.
ARM AMP architecture Slave processor reload Embedded Linux system Bare-Metal environment
2015-12-03。李鑫志,碩士生,主研領域:機器視覺在工程中的應用。戈志華,碩士。劉向明,教授。
TP3
A
10.3969/j.issn.1000-386x.2017.01.040