本文是昨天發(fā)的文章《龍芯杯CPU設(shè)計(jì)競(jìng)賽與ZYNQ設(shè)計(jì)流程介紹》接續(xù)部分。重點(diǎn)介紹傳統(tǒng)方式的Linux移植和Xilinx的Petalinux的快速移植開(kāi)發(fā)兩種。
部分硬件設(shè)計(jì)中需要CPU完成對(duì)電路寄存器的配置,為了完成Zedboard對(duì)FPGA上部分寄存器的配置功能,可以在PS單元(處理器系統(tǒng))上運(yùn)行裸機(jī)程序(無(wú)操作系統(tǒng)支持)完成和PL單元(FPGA部分)的數(shù)據(jù)交互功能,此時(shí)PS單元更像單片機(jī)開(kāi)發(fā);另一種方法是PS單元運(yùn)行Linux操作系統(tǒng),通過(guò)驅(qū)動(dòng)程序和應(yīng)用程序完成對(duì)硬件寄存器的讀寫(xiě)操作,并且Linux有著完整的網(wǎng)絡(luò)協(xié)議棧支持,后續(xù)可拓展性更強(qiáng),可以更好的發(fā)揮ZYNQ這種異構(gòu)架構(gòu)芯片的性能。主要分為兩部分,分別闡述Zedboard中FPGA和處理器互聯(lián)總線與硬件設(shè)計(jì)和Zedboard處理器系統(tǒng)上嵌入式Linux的移植與通過(guò)驅(qū)動(dòng)和應(yīng)用程序簡(jiǎn)單配置FPGA寄存器的實(shí)現(xiàn)。上次介紹了沒(méi)有操作系統(tǒng)下的驅(qū)動(dòng)和應(yīng)用程序開(kāi)發(fā),本文介紹帶操作系統(tǒng)的驅(qū)動(dòng)和應(yīng)用程序開(kāi)發(fā)。
1、傳統(tǒng)方式移植Linux
Zedboard上電后會(huì)首先啟動(dòng)BootRom,bootrom中固化了最初啟動(dòng)需要的初始代碼,并根據(jù)板卡上的跳線決定從flash或者sd卡或者jtag啟動(dòng)。這里選擇從SD卡啟動(dòng),bootrom中的代碼會(huì)將SD卡中的啟動(dòng)文件拷貝到RAM或者片上共享緩存中去,為下一步啟動(dòng)做準(zhǔn)備。
下一階段的啟動(dòng)文件負(fù)責(zé)初始化FPGA的比特流文件和初始化ARM處理器的FSBL文件(VIVADO生成),在PL和PS單元完成最基本的初始化操作后,就需要啟動(dòng)BootLoader來(lái)引導(dǎo)后面發(fā)linux內(nèi)核,XIlixn的解決方案中可以將二進(jìn)制比特流文件和fsbl以及uboot打包成BOOT.bin文件,BOOT.bin中的uboot可以加載內(nèi)核到內(nèi)存,并從0x00080000位置啟動(dòng)內(nèi)核。另外,內(nèi)核啟動(dòng)還需要設(shè)備樹(shù)和根文件系統(tǒng)。
(1)交叉編譯鏈和開(kāi)發(fā)環(huán)境搭建
為了得到能夠在嵌入式平臺(tái)上運(yùn)行的代碼,需要在linux主機(jī)上交叉編譯需要運(yùn)行的代碼,交叉編譯工具鏈就是提供交叉編譯的一套工具集。開(kāi)發(fā)主機(jī)選擇Ubuntu1604LTS系統(tǒng),安裝VIVADO17.4版本,安裝完成后 VIVADO SDK
用時(shí)已經(jīng)自動(dòng)安裝了交叉編譯鏈arm-linux-gnueabihf- ,使用命令
source/opt/Xilinx/SDK/2017.4/setting64.sh
添加引用1后即可使用交叉編譯鏈。Xilinx在較早的VIVADO SDK版本中提供了arm-xilinx-linux-gnueabi-編譯鏈,區(qū)別在于arm-linux-gnueabihf-使用硬件加速浮點(diǎn)數(shù)運(yùn)算,而arm-xilinx-linux-gnueabi-使用軟件計(jì)算。通過(guò)查詢資料,發(fā)現(xiàn)17.4版本的SDK中包含arm-xilinx-linux-gnueabi-編譯鏈的引用,但是軟件安裝時(shí)沒(méi)有成功安裝,這應(yīng)該是17.4版本的一個(gè)BUG,我們?cè)诹硪慌_(tái)安裝15.4版本VIVADO SDK的Ubuntu主機(jī)下,找到/opt/Xilinx/SDK/2015/gnu/arm文件夾,將其拷貝到17.4版本對(duì)應(yīng)的目錄,發(fā)現(xiàn)可以成功引用,輸入(交叉編譯鏈)gcc-v查看:
gcc版本為4.9.2。需要注意的是,使用兩條編譯鏈中的任意一條都可以用于交叉編譯,但是兩者之前不兼容,因此使用其中一條交叉編譯鏈即可。17.4自帶的gcc編譯器版本更高,是6.2.1版本。
為了支持32 位工具,需要預(yù)先安裝 32 位支持工具包。使用sudo命令獲取root權(quán)限,apt-get install lib32z1 lib32ncurses5lib32bz2-1.0 lib32stdc++6安裝上述工具包。(PS,可以修改Ubuntu鏡像源為西電開(kāi)源社區(qū)鏡像,實(shí)測(cè)速度在5MB左右)。安裝上述包后還需要安裝Openssl庫(kù)來(lái)實(shí)現(xiàn)網(wǎng)絡(luò)保密性,在編譯u-boot時(shí)會(huì)用到,使用命令apt-get install libssl-dev安裝。
為了提高工作效率,嵌入式開(kāi)發(fā)通常可以在Windows下使用SourceInsight等內(nèi)核源碼閱讀工具來(lái)開(kāi)發(fā)驅(qū)動(dòng)和應(yīng)用程序,而交叉編譯環(huán)境則往往在linux主機(jī)上,因此我們可以使用ssh登陸linux服務(wù)器,完成命令控制和編譯文件,使用ftp文件傳輸服務(wù)在Windows和linux主機(jī)之間傳遞文件,編譯完成的驅(qū)動(dòng)可以以NFS掛載的方式直接在嵌入式開(kāi)發(fā)板運(yùn)行。搭建工作環(huán)境不是本文的重點(diǎn),因此不再這里詳細(xì)說(shuō)明。
(2)U-boot編譯
Xilinx官方提供了u-boot的源碼,位于https://github.com/Xilinx/u-boot-xlnx/releases,我們按照自己需要的版本進(jìn)行下載和使用。
將下載好的u-boot-xlnx-xilinx-v2017.1.zip文件上傳到Ubuntu服務(wù)器,使用命令unzip解壓縮后進(jìn)入u-boot-xlnx-xilinx-v2017.1目錄,在 u-boot 的文件夾下有很多子文件夾構(gòu)成,其中每個(gè)文件夾都實(shí)現(xiàn)一個(gè)對(duì)應(yīng)的功能。
1) api:相關(guān)的api函數(shù),如輸出字符函數(shù)。
2) arch: 與特定的 CPU 構(gòu)架相關(guān)。在該目錄下,有u-boot 所支持的各種架構(gòu)的cpu,并且有一個(gè)單獨(dú)的子目錄對(duì)應(yīng)。典型的,arch 文件夾下名字為 arm 的子目錄就是 Zynq-7000 SOC所對(duì)應(yīng)使用的 CPU 構(gòu)架目錄。
3)board: 和一些已有開(kāi)發(fā)板有關(guān)的文件。每一個(gè)開(kāi)發(fā)板都有一個(gè)子目錄出現(xiàn)在當(dāng)前目錄下
4)common: 實(shí)現(xiàn)u-boot 命令行下所支持的命令。在該目錄下,每條命令對(duì)應(yīng)一個(gè)獨(dú)立的文件夾。
5)disk: 提供對(duì)磁盤的支持。
6)doc:文檔說(shuō)明
7)drivers: 在該目錄下保存著 u-boot 所支持的設(shè)備驅(qū)勱程序。典型的如各種網(wǎng)卡、支持的CFI 癿 Flash 存儲(chǔ)器、串口和 USB 等。
8)fs:支持的文件系統(tǒng)
9)include:該目錄下保存著 u-boot 所使用的頭文件,對(duì)各種硬件平臺(tái)支持的匯編文件、系統(tǒng)的配置文件以及對(duì)文件系統(tǒng)支持的文件。該目錄下configs 目錄有開(kāi)發(fā)板相關(guān)的配置頭文件,如 zynq_common.h 是與 zynq 開(kāi)發(fā)板相關(guān)的配置文件。
10)lib: 該目錄下保存著體系結(jié)構(gòu)相關(guān)的庫(kù)文件。
11)net: 該目錄下保存著網(wǎng)絡(luò)協(xié)議相關(guān)的代碼。比如BOOTP 協(xié)議、 TFTP 協(xié)議、RARP 協(xié)議和 NFS 文件系統(tǒng)的實(shí)現(xiàn)
12)tools: 該目錄下保存著用于生成 u-boot 癿工具,包括 mkimage、 crc、 Makefile 和boards.cfg配置文件。
下面開(kāi)始進(jìn)行u-boot的編譯,編譯u-boot需要扁平化設(shè)備樹(shù)的支持,首先輸入命令apt-get installdevice-tree-compiler安裝設(shè)備樹(shù)編譯工具。安裝完成dtc工具后就可以進(jìn)行u-boot的編譯了。
在configs文件下保存有各個(gè)開(kāi)發(fā)板的默認(rèn)配置,我們搜索zynq有關(guān)的配置文件,發(fā)現(xiàn)zynq_zed_defconfig文件,這個(gè)就是Zedboard默認(rèn)的配置選項(xiàng)。而ax70**系列的則是黑金開(kāi)發(fā)板的默認(rèn)配置文件。
在編譯u-boot之前,需要先將配置選項(xiàng)寫(xiě)入.config配置文件中,輸入命令make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zynq_zed_defconfig進(jìn)行配置。注意,你需要先source /opt/Xilinx/SDK/2017/setting64.sh添加相關(guān)引用才能使用,當(dāng)然也可以把上述命令寫(xiě)入/etc/profile這樣就可以開(kāi)機(jī)使用。
當(dāng)出現(xiàn)written to .configs時(shí),表明配置選項(xiàng)寫(xiě)入成功,接下來(lái)我們就可以進(jìn)行編譯u-boot了。
使用命令make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-編譯u-boot,經(jīng)過(guò)一段時(shí)間的編譯后,在u-boot根目錄下會(huì)出現(xiàn)u-boot文件,我們將其下載到Windows下并重命名為u-boot.elf,等待下一步使用。
(3)生成BOOT.bin啟動(dòng)文件
BOOT.bin需要VIVADO SDK生成fsbl,然后將u-boot和VIVADO生成的比特流打包。
啟動(dòng)VIVADO SDK,選擇File ->New -> Application Project創(chuàng)建一個(gè)新的SDK工程,工程命名為fsbl,其余保持默認(rèn)不變。
點(diǎn)擊next,選擇ZYNQ FSBL模板,點(diǎn)擊Finish完成工程的創(chuàng)建,SDK會(huì)自動(dòng)創(chuàng)建一個(gè)名為fsbl的工程和fsbl_bsp板級(jí)支持包。選中fsbl工程,右鍵選項(xiàng)選擇Create Boot Image,在彈出的選項(xiàng)卡中可以發(fā)現(xiàn)SDK已經(jīng)問(wèn)我們添加了剛才生成的fsbl和有VIVADO導(dǎo)入SDK中的比特流文件,我們只需要再添加編譯好的u-boot即可。
點(diǎn)擊右側(cè)的Add可以添加新的文件,Delete可以刪除選中的文件,Edit可以編輯文件的類型。我們選擇Add添加u-boot.elf文件。
在新的選項(xiàng)卡中填入uboot.elf的路徑,這里一定要注意類型為Datafile類型,否則無(wú)法正常啟動(dòng)。
點(diǎn)擊OK確認(rèn)后退回到上次層選項(xiàng)卡,選擇Create Image選項(xiàng),在SDK目錄下就會(huì)生成對(duì)應(yīng)的BOOT.bin文件。
將BOOT.bin拷貝到Zedboard的SD卡,連接串口,開(kāi)機(jī)觀察串口提示,發(fā)現(xiàn)u-boot已經(jīng)可以正常啟動(dòng)了,并且此時(shí)FPGA也已經(jīng)按照VIVADO的網(wǎng)表文件初始化完成,但是u-boot提示無(wú)法讀取內(nèi)核鏡像,我們將在下一步中生成。
(4)內(nèi)核編譯
Xilinx官方提供了linux的源碼,供開(kāi)發(fā)者下載和使用,我們打開(kāi)Xilinx官網(wǎng)鏈接:https://github.com/Xilinx/linux-xlnx/releases;選擇17.4版本下載并解壓。Linux解壓命令為 :
tar zxvf linux-xlnx-xilinx-v2017.4.tar.gz
解壓后進(jìn)入該目錄,這里對(duì)關(guān)鍵目錄進(jìn)行說(shuō)明:
1)include/---- 內(nèi)核頭文件,需要提供給外部模塊使用
2) kernel/---- Linux 內(nèi)核癿核心代碼,包擴(kuò)進(jìn)程調(diào)度子系統(tǒng),以及進(jìn)程調(diào)度相關(guān)的模塊。
3)arch/---- 體系結(jié)構(gòu)相關(guān)的代碼,例如 arm, x86 等等,我們使用的ARM A9處理器就在arch/arm/目錄下。
arch/mach包含了具體開(kāi)發(fā)板有關(guān)的代碼
arch/boot/dts 包含了設(shè)備樹(shù)文件
arch/arm/configs目錄下包含了arm架構(gòu)處理器和開(kāi)發(fā)板的一些內(nèi)核默認(rèn)配置文件,Zedboard的默認(rèn)配置文件也在此目錄下。
4)driver目錄則存放了可用的驅(qū)動(dòng)程序,你可以將自己的驅(qū)動(dòng)放入此目錄,在后面選擇編譯進(jìn)內(nèi)核。
5)scripts目錄下包含了設(shè)備樹(shù)編譯器dtc和解釋內(nèi)核配置選項(xiàng)相關(guān)的文件和目錄。
其余目錄則不是本文介紹的重點(diǎn),當(dāng)開(kāi)發(fā)平臺(tái)啟動(dòng)BootLoader后,需要讀取內(nèi)核鏡像,并依賴設(shè)備樹(shù)文件傳入的一些啟動(dòng)參數(shù)才能啟動(dòng)。當(dāng)然還需要文件系統(tǒng)的支持。Linux內(nèi)核有Imange、zImage和uImage等格式,Image就是正常編譯出的linux內(nèi)核,但是鑒于嵌入式資源有限,我們可以將內(nèi)核和一段自解壓程序進(jìn)行壓縮,這樣啟動(dòng)時(shí)BootLoader先調(diào)用zImage的解壓接口進(jìn)行解壓縮,而后在調(diào)用內(nèi)核接口啟動(dòng)內(nèi)核,相比于Image,zImage啟動(dòng)更慢一些。uImage就是在頭部加入了一些u-boot相關(guān)代碼的壓縮Linux內(nèi)核鏡像,便于u-boot啟動(dòng)內(nèi)核鏡像。因此,我們最終要生成的就是uImage內(nèi)核鏡像。
上面說(shuō)過(guò)在arch/arm中存放了我們需要的arm A9處理器的代碼和文件,進(jìn)入arch/arm/configs,搜索zynq相關(guān)的配置,發(fā)現(xiàn)xilinxz_zynq_defconfig配置文件,這就是Zedboard可用的默認(rèn)配置文件。和u-boot類似,我們也需要先寫(xiě)入默認(rèn)配置到.config文件才能編譯內(nèi)核。
使用命令make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- xilixn_zynq_defconfig進(jìn)行內(nèi)核配置文件的寫(xiě)入。寫(xiě)入完成后提示written to .config。可用使用make menuconfig配置內(nèi)核選項(xiàng):
這里保持默認(rèn),無(wú)需修改,如果需要將自己的驅(qū)動(dòng)編譯進(jìn)內(nèi)核,可以在這里選中,但是這樣不利于調(diào)試驅(qū)動(dòng)。
使用命令make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- 編譯內(nèi)核,內(nèi)核編譯需要較長(zhǎng)的時(shí)間。如果配置過(guò)程中需要重新修改或者發(fā)生錯(cuò)誤,可以使用make distclean命令使內(nèi)核恢復(fù)最初的狀態(tài),然后重新編譯。
我們使用make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- uImageLOADADDR=0x00008000重新生成內(nèi)核,指定內(nèi)核鏡像為uImage,內(nèi)核入口地址為0x00008000。由于內(nèi)核已經(jīng)編譯過(guò)一次,這次可以很快生成。
生成的內(nèi)核位于arch/arm/boot目錄下。拷貝uImage到Zedboard的SD卡準(zhǔn)備啟動(dòng)時(shí)使用。
(5)生成設(shè)備樹(shù)文件
設(shè)備樹(shù)是一種設(shè)備節(jié)點(diǎn)的描述,它告訴內(nèi)核板卡上有哪些外設(shè)以及外設(shè)占用的資源,比如寄存器映射空間和中斷號(hào)等信息。另外設(shè)備樹(shù)還可以修改內(nèi)核啟動(dòng)參數(shù),如串口選擇、波特率設(shè)置和根文件系統(tǒng)的選擇。
通過(guò)VIVADO SDK可以生成設(shè)備樹(shù)描述文件,這樣便于我們開(kāi)發(fā),而不需要完全手動(dòng)創(chuàng)建。VIVIADO安裝時(shí)并沒(méi)有安裝設(shè)備樹(shù)生成器,所以需要我們手動(dòng)安裝。我們首先下載xilinx提供的device tree generator,并安裝到SDK。訪問(wèn)https://github.com/Xilinx/device-tree-xlnx/releases獲取對(duì)應(yīng)版本的設(shè)備樹(shù)生成器。下載并放到VIVADO安裝目錄下的SDK17.4\data\embeddedsw\devicetree\bsp\目錄下,重命名為device-tree-xlnx_v2017_4(我的VIVADO版本為17.4)。打開(kāi)SDK,在SDK中操作點(diǎn)擊菜單: Xilinx Tools -> Repositories,然后在LocalRepositories中添加我們剛才下載的SDK17.4\data\embeddedsw\devicetree\bsp\device-tree-xlnx_v2017_4路徑并點(diǎn)擊OK。
添加成功后如上圖。點(diǎn)擊菜單File -> New -> Board Support Package。彈出選項(xiàng)卡New Board Support Packet Project,選擇device_tree,如果你上一步配置不成功,則不會(huì)出現(xiàn)device_tree選項(xiàng),此時(shí)需要檢查上一個(gè)步驟的問(wèn)題。添加成功后點(diǎn)擊Finish選項(xiàng),VIVADO SDK會(huì)自動(dòng)生成設(shè)備樹(shù)描述文件dts。
稍后,VIVADO彈出BoardSupport Packet Setting選項(xiàng)卡,在bootargs中填入console=ttyPS0,115200 root=/dev/ram rw initrd=0x800000,8Mearlyprintk rootfstype=ext4 rootwait devtmpfs.mount=0。“bootargs”參數(shù)用于指定啟動(dòng)時(shí)傳遞給內(nèi)核的參數(shù)。“console device”參數(shù)用于指定所使用的串口輸出設(shè)備。
在SDK目錄下的device_tree目錄下可以看到很多dts文件,system-top.dts就是我們需要編譯的設(shè)備樹(shù)描述文件。它引用了zynq-7000.dtsi等對(duì)于zynq芯片通用的部分文件。將SDK目錄下的整個(gè)device_tree目錄上傳到Ubuntu服務(wù)器,使用dtc編譯器編譯。編譯命令如下:
./scripts/dtc/dtc-I dts -O dtb -o device.dtb ./device_tree/system-top.dts
6)文件系統(tǒng)
根文件系統(tǒng)使用uramdisk.image.gz根文件系統(tǒng),ramdisk.image.gz根文件系統(tǒng)其格式與uboot不同,啟動(dòng)時(shí)uboot會(huì)提示ramdisk格式錯(cuò)誤,若要讓uboot能夠識(shí)別ramdisk.image.gz根文件系統(tǒng),需要利用mkimage給ramdisk.image.gz添加一些頭部信息,生成uramdisk.image.gz。可以直接使用網(wǎng)絡(luò)上的uramdisk.image.gz來(lái)作為根文件系統(tǒng),一般來(lái)講,根文件系統(tǒng)不需要做出修改。
另一種廣泛應(yīng)用的根文件系統(tǒng)是LINARO_FS,Linaro文件系統(tǒng)也可從網(wǎng)絡(luò)上獲取,因?yàn)槲覀兊脑O(shè)備樹(shù)中指定了從uramdisk.image.gz文件系統(tǒng)啟動(dòng),因此這里不再介紹從Linaro文件系統(tǒng)啟動(dòng)。
現(xiàn)在,我們已經(jīng)得到BOOT.bin文件,設(shè)備樹(shù)device_tree.dtb文件和根文件系統(tǒng)uramdisk.image.gz根文件系統(tǒng)。將這三個(gè)文件放入Zedboard的SD卡,上電啟動(dòng)就可以使用Linux操作系統(tǒng)了。
7)驅(qū)動(dòng)程序和應(yīng)用程序測(cè)試
Linux驅(qū)動(dòng)程序有靜態(tài)編譯進(jìn)內(nèi)核和動(dòng)態(tài)模塊加載兩種,這里選擇動(dòng)態(tài)模塊加載的方式,便于進(jìn)行調(diào)試。在前面的硬件設(shè)計(jì)中,我們將AXI-Lite Slave的四個(gè)寄存器掛載到基地址為0x43c00000的位置,而Zedboard板卡上的8位LED燈連接到了寄存器0的低8位,因此我們寫(xiě)寄存器0的低八位就能很容易的通過(guò)LED的狀態(tài)來(lái)判斷寫(xiě)入是否成功。
驅(qū)動(dòng)程序的入口和出口分別是init和exit,需要使用宏進(jìn)行修飾如下:
// 注冊(cè)初始化Linux驅(qū)動(dòng)的函數(shù) module_init( leds_drv_init); // 注冊(cè)卸載Linux驅(qū)動(dòng)的函數(shù) module_exit( leds_drv_exit);
linux操作系統(tǒng)中無(wú)法直接讀寫(xiě)物理地址,因此入口函數(shù)中,我們需要映射物理地址,使用ioremup函數(shù)映射物理地址。注意這里物理地址和硬件設(shè)計(jì)中保持一致。
leds= ioremap(0x43c00000, sizeof(LEDS_T))
Led燈只是一個(gè)簡(jiǎn)單的字符設(shè)備,但是這里我們使用該設(shè)備來(lái)注冊(cè)設(shè)備驅(qū)動(dòng)。
ret= misc_register(&misc);
雜項(xiàng)設(shè)備也是在嵌入式系統(tǒng)中用得比較多的一種設(shè)備驅(qū)動(dòng)。在 Linux 內(nèi)核的include/linux目錄下有Miscdevice.h文件,要把自己定義的misc device從設(shè)備定義在這里。其實(shí)是因?yàn)檫@些字符設(shè)備不符合預(yù)先確定的字符設(shè)備范疇,所有這些設(shè)備采用主編號(hào)10,一起歸于misc device,其實(shí)misc_register就是用主標(biāo)號(hào)10調(diào)用register_chrdev()的。也就是說(shuō),misc設(shè)備其實(shí)也就是特殊的字符設(shè)備,可自動(dòng)生成設(shè)備節(jié)點(diǎn)。LDD3中l(wèi)ed設(shè)備也是用misc_register函數(shù)注冊(cè)為雜設(shè)備,這說(shuō)明led設(shè)備是作為雜項(xiàng)設(shè)備出現(xiàn)在內(nèi)核中的,在內(nèi)核中,misc雜項(xiàng)設(shè)備驅(qū)動(dòng)接口是對(duì)一些字符設(shè)備的簡(jiǎn)單封裝,他們共享一個(gè)主設(shè)備號(hào),有不同的次設(shè)備號(hào),共享一個(gè)open調(diào)用,其他的操作函數(shù)在打開(kāi)后運(yùn)用linux驅(qū)動(dòng)程序的方法重載進(jìn)行裝載。
驅(qū)動(dòng)代碼:
#define DEVICE_NAME "leds" #define LEDS_BASE_ADDR (0x43c00000) typedef struct{ volatile unsigned int ADDR0; volatile unsigned int ADDR1; volatile unsigned int ADDR2; volatile unsigned int ADDR3; }LEDS_ADDR; LEDS_ADDR* leds; static int leds_drv_open(struct inode *Inode, struct file *File) { leds->ADDR0 = 0xffffffff; leds->ADDR1 = 0xffffffff; leds->ADDR2 = 0xffffffff; leds->ADDR3 = 0xffffffff; return 0; } static ssize_t leds_drv_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { return 0; } static ssize_t leds_drv_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { unsigned int ret = 0; unsigned int tmp_val; u32 pos = *offset; ret = copy_from_user(&tmp_val, buf, count); leds->ADDR0 = tmp_val; //默認(rèn)寫(xiě)入寄存器0 return ret; } // 描述與設(shè)備文件觸發(fā)的事件對(duì)應(yīng)的回調(diào)函數(shù)指針 static struct file_operations dev_fops = { .owner = THIS_MODULE, .open = leds_drv_open, .read = leds_drv_read, .write = leds_drv_write, }; // 描述設(shè)備文件的信息 static struct miscdevice misc = { .minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &dev_fops }; // 初始化Linux驅(qū)動(dòng) static int __init leds_drv_init(void) { int ret; leds = ioremap(LEDS_BASE_ADDR, sizeof(LEDS_T)); // 建立設(shè)備文件 ret = misc_register(&misc); // 輸出日志信息 if(ret) { printk("leds_drv_init faiitrt!\n"); } else { printk("leds_drv_init success!\n"); } return ret; } // 卸載Linux驅(qū)動(dòng) static void __exit leds_drv_exit(void) { iounmap(leds); // 刪除設(shè)備文件 misc_deregister(&misc); // 輸出日志信息 printk("leds_drv_exit success!\n"); } // 注冊(cè)初始化Linux驅(qū)動(dòng)的函數(shù) module_init( leds_drv_init); // 注冊(cè)卸載Linux驅(qū)動(dòng)的函數(shù) module_exit( leds_drv_exit); MODULE_LICENSE("Dual BSD/GPL");
應(yīng)用程序調(diào)用驅(qū)動(dòng)程序接口,從控制臺(tái)讀取一個(gè)數(shù)字,寫(xiě)入到寄存器0,寄存器0的低八位就可以在led燈上顯示出來(lái)。
應(yīng)用程序源碼:
#include <stdio.h> #include <stdlib.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main(int argc, char** argv) { int fd; fd = open("/dev/leds", O_RDWR); if(fd < 0) { printf("fd = %d open fialed!\n", fd); } //unsigned int leds = 0; int leds = 0; char ch[4]; printf("input your strings:\n"); int i = 0; while( 1 ) { ch[i] = getchar(); if (ch[i] == '\n') break; else i++; } if (i == 3) { leds = (ch[0]-48)*100 + (ch[1]-48)*10 + ch[2]-48; } if (i == 2) { leds = (ch[0]-48)*10 + ch[1]-48; } if (i == 1) { leds = ch[0]-48; } printf("leds = %d,i = %d\n",leds,i); write(fd, &leds, 8); printf("end\n"); close(fd); return 0; }
將驅(qū)動(dòng)和應(yīng)用程序上傳到Ubuntu,使用arm-linux-gnueabihf-交叉編譯鏈編譯。驅(qū)動(dòng)程序需要編寫(xiě)makefile,Makefile中需要指定一個(gè)已編譯的內(nèi)核源碼樹(shù)。編譯完成后再Zedboard板測(cè)試如下:
1> 掛載Ubuntu的NFS服務(wù),(需要Ubuntu開(kāi)啟NFS服務(wù)并指定路徑)首先查詢Ubuntu IP地址為192.168.1.103,在Zedboard控制臺(tái)輸入:
mount-t nfs -o nolock 192.168.1.103:/home/zed/work /mnt
將Ubuntu上的work目錄掛載到Zedboard板
掛載成功后使用ssh登陸Ubuntu并轉(zhuǎn)到Ubuntu的驅(qū)動(dòng)目錄,執(zhí)行make,得到驅(qū)動(dòng).ko文件。
Make命令執(zhí)行成功,目錄下生成最終使用的ko文件部分中間文件。使用
arm-linux-gnueabihf-gcc -o ledstest.o ledstest.c生成測(cè)試程序。
回到串口工具連接Zedboard板卡,使用insmod掛載驅(qū)動(dòng),并執(zhí)行測(cè)試程序。
掛載成功后,運(yùn)行APP成功,APP從控制臺(tái)讀入一個(gè)字符串65,將其ASCII碼轉(zhuǎn)換為數(shù)值寫(xiě)入寄存器0,Zedboard板卡上led如圖:
2、Petalinux快速開(kāi)發(fā)
Petalinux是xilinx為zynq7000系列移植linux程序設(shè)計(jì)的一套開(kāi)發(fā)程序。它可以加快嵌入式開(kāi)發(fā)人員的工作速度。
安裝petalinux首先需要安裝需要的庫(kù),本次實(shí)驗(yàn)在Ubuntu1604LTS上安裝petalinux17.4.注意,petalinux版本和VIVADO版本需要對(duì)應(yīng)。
Petalinux無(wú)法以root用戶安裝,因此如果想安裝petalinux到非用戶目錄下有兩種辦法:將opt目錄下的文件夾所有屬性改為當(dāng)前用戶或者安裝到當(dāng)前用戶目錄下再以root權(quán)限復(fù)制整個(gè)文件夾到opt目錄。這里選用第一種方法,首先創(chuàng)建安裝目錄:
運(yùn)行petalinux的安裝文件,并指定目錄為/opt/pkg/petalinux,檢查依賴環(huán)境無(wú)誤后就會(huì)進(jìn)行安裝,安裝前需要根據(jù)提示同意用戶協(xié)議。
安裝完成后就可以使用petalinux定制linux操作系統(tǒng)。Petalinux可以識(shí)別VIVADO工程,并根據(jù)VIVADO工程來(lái)智能設(shè)置外設(shè)信息。VIVADO工程目錄下的.sdk目錄就包含了petalinux所需的硬件信息。Ubuntu新建文件夾作為petalinux的工程目錄,并將.sdk拷貝到petalinux工程目錄的上一級(jí)目錄下,即和petalinux工程目錄為同級(jí)目錄。定位petalinux
source/opt/pkg/petalinux/settings.sh
檢查安裝環(huán)境和庫(kù)依賴,無(wú)問(wèn)題后可以建立工程。使用命令:
petalinux-create--type project --template zynq –name leds
建立名為leds的工程,cd到leds目錄下,讀取硬件信息:
petalinux-config--get-hw-description ./led.sdk
在彈出的窗口中可以配置petalinux工程,默認(rèn)源碼從GitHub下載,也可以從本地讀取,這里保持默認(rèn)。在 Advanced bootable images storage Settings選項(xiàng)中配置啟動(dòng)方式,默認(rèn)從SD卡啟動(dòng),這里依舊保持默認(rèn)。
將配置保存,退出,petalinux會(huì)下載源碼并配置工程。成功后使用如下命令配置linux內(nèi)核:
petalinux-config-c kernel
配置成功后保存并退出
編譯完成后使用petalinux-config-c rootfs配置根文件系統(tǒng),同樣保存后退出。使用命令petalinux-build編譯整個(gè)系統(tǒng)工程。經(jīng)過(guò)一段漫長(zhǎng)的等待,編譯完成。
運(yùn)行下面命令生成BOOT文件:
將工程目錄 images -> linux目錄中的BOOT.bin和image.ub復(fù)制到SD卡,啟動(dòng)Zedboard,完成Linux操作系統(tǒng)的移植。
注意使用petalinux移植linux使用的是arm-linux-gnueabihf-交叉編譯鏈,因此后續(xù)驅(qū)動(dòng)開(kāi)發(fā)時(shí)也需要指定交叉編譯鏈為arm-linux-gnueabihf-,后續(xù)驅(qū)動(dòng)的開(kāi)發(fā)與傳統(tǒng)方式移植linux部分一致,因此不再闡述。
全文完。
敢問(wèn)工廠和醫(yī)院,在今天這樣一個(gè)萬(wàn)物互聯(lián)的物聯(lián)網(wǎng)時(shí)代,在人工智能幾乎無(wú)處不在的時(shí)代, 你準(zhǔn)備好升級(jí)了嗎?今天 ,我們就來(lái)聽(tīng)聽(tīng)賽靈思工業(yè)、視覺(jué)、科學(xué)與醫(yī)療市場(chǎng)總監(jiān) Chetan Khona 如何看待人工智能在工業(yè)和醫(yī)療領(lǐng)域的發(fā)展,在產(chǎn)業(yè)升級(jí)和變革的關(guān)鍵時(shí)刻如何做正確的選擇,而且未雨綢繆,讓今天的選擇同樣能夠適應(yīng)未來(lái)的再升級(jí)、再發(fā)展。
賽靈思公司工業(yè),視覺(jué),科學(xué)與醫(yī)療市場(chǎng)總監(jiān), Chetan Khona
數(shù)據(jù)的爆炸性增長(zhǎng)已經(jīng)是一個(gè)老調(diào)且不爭(zhēng)的事實(shí), 可是你真的知道每天產(chǎn)生的數(shù)據(jù)有多少嗎?福布斯網(wǎng)站的一篇文章顯示, 我們每天產(chǎn)生的數(shù)據(jù)超過(guò) 2.5艾字節(jié) ( 1艾字節(jié)即1 Exabyte, 等于100億億字節(jié))!而且90%的數(shù)據(jù)產(chǎn)生于過(guò)去的兩年時(shí)間,2019年用于人工智能的數(shù)據(jù)是60 堯字節(jié), 1 堯字節(jié)即 1 Yottabyte, 等于1億億億字節(jié)! 驚不驚喜?意不意外?
Chetan表示,大概5-10年以前,其實(shí)數(shù)據(jù)僅僅是用于一些本地的應(yīng)用,但當(dāng)今時(shí)代,隨著物聯(lián)網(wǎng)時(shí)代的到來(lái),越來(lái)越多的設(shè)備都已經(jīng)連接到了網(wǎng)絡(luò),因此如何使用這些數(shù)據(jù)至關(guān)重要。
毋庸質(zhì)疑,數(shù)據(jù)無(wú)論對(duì)于工業(yè)物聯(lián)網(wǎng)(IIoT)還是醫(yī)療物聯(lián)網(wǎng) (HcIoT)來(lái)說(shuō),優(yōu)勢(shì)都非常明確:對(duì)于工業(yè),數(shù)據(jù)可以做預(yù)測(cè)性的維護(hù),這就能夠盡可能降低工廠停工時(shí)間,從而保障盈利和利潤(rùn);二來(lái),數(shù)據(jù)可以通過(guò)資產(chǎn)分析,來(lái)更好的了解客戶的購(gòu)買習(xí)慣,從而創(chuàng)造新的收入流。其次是連接性,連接性是物聯(lián)網(wǎng),這也是工業(yè)互聯(lián)網(wǎng)的基礎(chǔ)。通過(guò)賽靈思方案更新軟件和硬件,能夠延長(zhǎng)產(chǎn)品的使用壽命,從而降低了更新?lián)Q代的成本。對(duì)于醫(yī)療物聯(lián)網(wǎng)來(lái)講,通過(guò)數(shù)據(jù)可以更好的改善醫(yī)院和診所的工作效率,并以此提高時(shí)間的利用率,提高對(duì)患者的服務(wù),最終改善的是人們的生活質(zhì)量。
但同時(shí),數(shù)據(jù)的應(yīng)用也帶來(lái)了諸多挑戰(zhàn)。首當(dāng)其沖的就是由數(shù)據(jù)帶來(lái)的隱私問(wèn)題,尤其是伴隨著時(shí)間的變化、計(jì)算能力的增長(zhǎng),安全性就會(huì)面臨更大的挑戰(zhàn)。另外,影響安全性的時(shí)延和響應(yīng)能力問(wèn)題;包括傳輸、存儲(chǔ)和處理在內(nèi)的數(shù)據(jù)問(wèn)題。
以醫(yī)療物聯(lián)網(wǎng)為例,目前,全球已安裝超過(guò)1億臺(tái)醫(yī)療物聯(lián)網(wǎng)設(shè)備,到2020年將增長(zhǎng)到1.61億臺(tái)。但同時(shí)也有醫(yī)療高管表示,當(dāng)前阻礙醫(yī)療組織采用物聯(lián)網(wǎng)的三大障礙:隱私問(wèn)題占59%,原有系統(tǒng)集問(wèn)題成占55%,安全問(wèn)題占54%。
Chetan 介紹說(shuō), 賽靈思通過(guò)三種策略幫助客戶高效、有效的來(lái)利用數(shù)據(jù)。這也是賽靈思ISM部分的核心戰(zhàn)略。其中包括:
Chetan Khona表示,在業(yè)界,賽靈思一直被冠以“FPGA發(fā)明者”的稱號(hào),然而在工業(yè)領(lǐng)域和醫(yī)療領(lǐng)域,賽靈思的Zynq SoC和Zynq UltraScale+ MSoC 產(chǎn)品系列才是工業(yè)和醫(yī)療以及機(jī)器視覺(jué)領(lǐng)域的最愛(ài)。原因何在?
傳統(tǒng)上,一個(gè)公司內(nèi)部就有多個(gè)工程師團(tuán)隊(duì),而且在設(shè)計(jì)上可以獨(dú)立決策,比如一個(gè)團(tuán)隊(duì)選擇PPC、VxWorks、CAN,還有選arm、Linux、MQTT,還有一個(gè)選x86、Windows、OPC UA,他們之所以能夠自主的選擇這些系統(tǒng),是因?yàn)楫?dāng)時(shí)這些系統(tǒng)非常的簡(jiǎn)單。但是工業(yè)物聯(lián)網(wǎng)、醫(yī)療物聯(lián)網(wǎng)就不同了,雖然非常強(qiáng)大,但是越來(lái)越復(fù)雜,這也使得工程師團(tuán)隊(duì)越來(lái)越多的選擇公共平臺(tái), 實(shí)現(xiàn)產(chǎn)品線內(nèi)部甚至夸產(chǎn)品線可擴(kuò)展的設(shè)計(jì)平臺(tái)。這是現(xiàn)在工業(yè)界發(fā)展的趨勢(shì),也就是IT、OT的融合,信息技術(shù)和運(yùn)營(yíng)技術(shù)的融合。
可擴(kuò)展,靈活多變, 這正是賽靈思Zynq SoC 處理器平臺(tái)的優(yōu)勢(shì)。Zynq SoC 中的arm系統(tǒng)就能夠?yàn)樵崎_(kāi)發(fā)提供服務(wù),同時(shí)還能提供IT和OT的支持,以及提供FPGA的定制化,所以工業(yè)性能加定制功能使得我們的產(chǎn)品非常有吸引力,這也是大家選擇賽靈思的第一大原因,所以這也是兩年之前根據(jù)Aspencore做的調(diào)查,現(xiàn)在開(kāi)發(fā)者已經(jīng)把賽靈思視作未來(lái)開(kāi)發(fā)使用的SoC產(chǎn)品當(dāng)中的排名前三的工具之一。
從賽靈思ISM 領(lǐng)域增長(zhǎng)趨勢(shì)圖就可以看出上述兩款產(chǎn)品的受歡迎程度, 自從其上市并量產(chǎn)后賽靈思在ISM領(lǐng)域的收入增速高達(dá)25%。
賽靈思Zynq的用戶中不乏中國(guó)工業(yè)和醫(yī)療用戶, 他們對(duì)賽靈思的工業(yè)物聯(lián)網(wǎng)平臺(tái)給予了很高的評(píng)價(jià)。如下圖的典型應(yīng)用和客戶評(píng)價(jià)。
“南瑞繼保廣泛采用賽靈思 Zynq SoC 作為控制、保護(hù)、合并和切換產(chǎn)品的通用平臺(tái)。該解決方案符合 IEC61850 的要求,并經(jīng)過(guò)國(guó)家電網(wǎng)公司的認(rèn)證。”
—— Xiang Li ,南瑞繼電保護(hù)研發(fā)經(jīng)理
“我們正在使用賽靈思 Zynq SoC,使前端設(shè)備能夠以業(yè)界最低功耗提供一流的識(shí)別效率”。
—— 曠視公司
“一個(gè) Zynq SoC 取代了 20 多個(gè)芯片和工業(yè)網(wǎng)絡(luò)連接,以 1/6 的尺寸和 1/5 的成本提供了驚人的同步性能。”
—— 顧強(qiáng),武漢精鋒微控 CEO
“邁瑞(Mindray)的使命是制造高質(zhì)量的產(chǎn)品,并將昂貴的醫(yī)療技術(shù)轉(zhuǎn)變?yōu)槿澜缛藗兌伎梢韵硎艿降母哔|(zhì)量醫(yī)療服務(wù)。我們已經(jīng)選擇賽靈思技術(shù)來(lái)滿足客戶的臨床需求。”
—— 邁瑞醫(yī)療
“作為視頻監(jiān)控領(lǐng)域的全球領(lǐng)導(dǎo)者,海康威視(Hikvision )致力于不斷創(chuàng)新。我們的設(shè)備已經(jīng)廣泛應(yīng)用于 100 多個(gè)國(guó)家,以提高從銀行、地鐵、體育場(chǎng)館到游樂(lè)園和賭場(chǎng)等場(chǎng)所的安全。事實(shí)證明,賽靈思平臺(tái)非常適合。”
—— 海康威視,選自賽靈思年度質(zhì)量報(bào)告
“賽靈思并不是現(xiàn)在開(kāi)始進(jìn)入到工業(yè)和醫(yī)療的物聯(lián)網(wǎng)領(lǐng)域, 只是從我們引入了相關(guān)的 SoC 之后,我們的增長(zhǎng)就在加速。”Chetan Khona 強(qiáng)調(diào)說(shuō)。
此外,和消費(fèi)領(lǐng)域求新求變的特點(diǎn)相比,工業(yè)和和醫(yī)療領(lǐng)域的發(fā)展相對(duì)緩慢和穩(wěn)定,對(duì)產(chǎn)品的耐用性更加重視。“耐用性,也就是產(chǎn)品生命周期的長(zhǎng)壽性更加重要。”Chetan Khona說(shuō)。
據(jù)了解,產(chǎn)品最低生命周期是各大廠商競(jìng)爭(zhēng)的重點(diǎn),很多半導(dǎo)體公司難以做到15年的生命周期,這將難以滿足工業(yè)領(lǐng)域的最低要求。相比之下,賽靈思的優(yōu)勢(shì)得以顯現(xiàn)。
賽靈思的品質(zhì)和強(qiáng)大的產(chǎn)品生命周期在客戶中擁有良好的質(zhì)量聲譽(yù) – 根據(jù)賽靈思最新的工程質(zhì)量報(bào)告顯示,賽靈思產(chǎn)品在行業(yè)中擁有0 召回的歷史記錄。賽靈思據(jù)Chetan Khona介紹,目前賽靈思可以為產(chǎn)品提供最低15年的生命周期保障,而且通常可以達(dá)到20年甚至更久。
賽靈思工業(yè)物聯(lián)網(wǎng)平臺(tái)既有傳統(tǒng)的工業(yè)領(lǐng)域優(yōu)勢(shì),包括工業(yè)實(shí)時(shí)和確定性控制與接口、工業(yè)生命周期、質(zhì)量、可靠性、安全性、溫度與功耗,但并不是僅僅賽靈思能夠支持這些功能,還有很多其他的企業(yè)也可以。賽靈思所做的就是加入業(yè)界領(lǐng)先的AI時(shí)延與性能優(yōu)勢(shì),并和傳統(tǒng)的優(yōu)勢(shì)進(jìn)行結(jié)合,這點(diǎn)是非常重要的。因?yàn)橛械钠髽I(yè)可能可以做AI,但是沒(méi)有傳統(tǒng)的優(yōu)勢(shì),但賽靈思是兩者兼具,有一些GPU可以做AI但是它不具備傳統(tǒng)的優(yōu)勢(shì),還有一些企業(yè)像TI, 瑞薩、恩智浦可以做SoC,但是它又不具備AI方面的能力,所以對(duì)很多客戶不可能去使用多個(gè)器件的方案,因?yàn)椴捎觅愳`思的單芯片解決方案就能夠確保高度的集成,達(dá)到最高的成本有效性。
面向未來(lái),賽靈思 2019年將發(fā)貨另一款顛覆性的新產(chǎn)品ACAP(自適應(yīng)計(jì)算計(jì)算平臺(tái))。Chentan 表示,就像當(dāng)年 FPGA、SoC 和 GPU 的發(fā)明一樣,這是一款全新物種的產(chǎn)品品類。2019年下半年,ACAP 首個(gè)品牌系列Versal 將正式面世。Versal 擁有6個(gè)子系列,今年率先推出的將是 Versal AI Core 系列和 Versal Prime( 基礎(chǔ)版)。
對(duì)于工業(yè)領(lǐng)域最重要的是 Edge AI,目前已經(jīng)在Zynq和Zynq UltraScale 中部署,2020 年它會(huì)成為 Versal 的一個(gè)子系列,主要是在每瓦的性能上能夠達(dá)到行業(yè)領(lǐng)先,可以用的系統(tǒng)有機(jī)器視覺(jué)、超聲設(shè)備和超聲手持等。目前,Zynq UltraScale+ 是賽靈思系列產(chǎn)品當(dāng)中在工業(yè)物聯(lián)網(wǎng)和醫(yī)療物聯(lián)網(wǎng)當(dāng)中最成功的產(chǎn)品,未來(lái), Versal AI Edge 也將會(huì)是一款無(wú)與倫比的產(chǎn)品。
堆棧,Alveo加速器卡,邊緣和云協(xié)作,加上行業(yè)公認(rèn)的品質(zhì)信譽(yù)和強(qiáng)大的產(chǎn)品路線圖,賽靈思將助力工業(yè)、醫(yī)療領(lǐng)域的客戶實(shí)現(xiàn)更加智能和靈活應(yīng)變的資產(chǎn)優(yōu)勢(shì),奔向理想中的未來(lái)工廠、未來(lái)醫(yī)院和未來(lái)城市。