wordpress網(wǎng)站go.php跳轉(zhuǎn)濰坊網(wǎng)站建設(shè)優(yōu)化
第七篇 系統(tǒng)BSP開發(fā)
文章目錄
- 第七篇 系統(tǒng)BSP開發(fā)
- 1. 嵌入式Linux系統(tǒng)介紹
- 嵌入式Linux系統(tǒng)組成
- 產(chǎn)品形態(tài)
- 嵌入式芯片
- 啟動流程
- Linux系統(tǒng)
- Linux系統(tǒng)框架
- 嵌入式編譯環(huán)境
- 2.嵌入式Linux開發(fā)準(zhǔn)備
- 手冊文檔
- 開發(fā)工具
- 配套硬件
- 工程源碼
- 3.嵌入式Linux開發(fā)組成概述
- 編譯工具鏈
- 什么是工具鏈
- 什么是交叉編譯工具鏈
- 獲得合適的交叉編譯工具鏈
- sysroot
- 自由軟件許可
- 常見開源組件
- 自由軟件與更改分開
- 編譯工具
- GUN組織
- Makefile
- Autotools
- Cmake
- Meson
- 編譯系統(tǒng)
- buildroot
- Yocto
- Openwrt
- 構(gòu)建系統(tǒng)對比
- 其他構(gòu)建工具
- 發(fā)行版rootfs
- 4.使用Buildroot BSP構(gòu)建系統(tǒng)
- 配置開發(fā)環(huán)境
- 下載vmware虛擬機(jī)工具
- 獲取Ubuntu系統(tǒng)鏡像
- 運(yùn)行虛擬機(jī)系統(tǒng)
- 安裝編譯所需依賴
- 獲取配套源碼
- Git下載
- 下載其他
- Buildroot簡介
- 構(gòu)建原理
- skeleton
- 構(gòu)建流程
- 編譯構(gòu)建系統(tǒng)
- 執(zhí)行配置命令
- Q:編譯nncase錯(cuò)誤
- A: 解決方式
- Q:編譯AI示例報(bào)錯(cuò)
- A: 解決方式
- 構(gòu)建成功鏡像介紹
- 更新系統(tǒng)鏡像
- 1.5.1 硬件操作
- 1.5.2 燒錄鏡像
- 1.5.3 安裝WinUSB燒錄驅(qū)動
- 1.5.4 完整燒錄鏡像
- 1.5.5 啟動EMMC系統(tǒng)
- 5. 使用SDK配套工具鏈開發(fā)應(yīng)用
- 交叉編譯工具鏈所在位置
- gcc編譯器
- 系統(tǒng)組件lib庫
- 系統(tǒng)組件頭文件
- 支持Makefile
- 配置工具鏈環(huán)境
- 支持Cmake示例
- 6.使用工具鏈進(jìn)行驅(qū)動開發(fā)-簡單
- 開發(fā)helloword驅(qū)動
- 開發(fā)gpio點(diǎn)燈驅(qū)動+應(yīng)用
- 7.針對系統(tǒng)進(jìn)行定制化開發(fā)操作
- 支持需要的組件庫
- 定義自己的系統(tǒng)啟動程序
1. 嵌入式Linux系統(tǒng)介紹
嵌入式Linux系統(tǒng)組成
產(chǎn)品形態(tài)
上面的產(chǎn)品都運(yùn)行的Linux系統(tǒng),產(chǎn)品的種類外觀 場景 非常多,上至飛機(jī),下至 車機(jī) 手機(jī)。
嵌入式芯片
接下來介紹軟件層面的區(qū)別
啟動流程
Linux系統(tǒng)
-
發(fā)行版 系統(tǒng)
-
嵌入式系統(tǒng)
一般稱 Linux發(fā)行版系統(tǒng)為 大系統(tǒng),嵌入式自定義系統(tǒng) 為 小系統(tǒng)
Linux系統(tǒng)框架
嵌入式編譯環(huán)境
2.嵌入式Linux開發(fā)準(zhǔn)備
資料 資料 資料 !!!
開發(fā)板公司做的資料
- 全志T113-S3原廠資料
總結(jié)來看只需要:**原廠主芯片資料+BSP源碼+ 開發(fā)板廠家原理圖 位圖規(guī)格書等。**就可以開始嵌入式開發(fā)工作。
手冊文檔
-
原廠支持的手冊 https://github.com/kendryte/k510_docs/
-
K510 主芯片手冊
- K510 BSP開發(fā)手冊
-
DongshanPI-Vision開發(fā)板位號圖與原理圖
開發(fā)工具
- 系統(tǒng)燒寫工具 KendryteBurningTool: https://github.com/kendryte/BurningTool
配套硬件
- 核心板
- DongshanPI-Vision底板
- MIPI CSI IMX219 攝像頭 x2
- 5.5寸 1080P MIPIx4LINE 顯示屏
工程源碼
- 原廠K510 BSP源碼 https://github.com/kendryte/k510_buildroot
-
百問網(wǎng)DongshanPI-Vision BSP源碼
-
https://e.coding.net/weidongshan/dongshanpi-vision/buildroot-2020.02.11.git
-
https://e.coding.net/weidongshan/dongshanpi-vision/br2-canaan-k510.git
-
?
3.嵌入式Linux開發(fā)組成概述
編譯工具鏈
什么是工具鏈
工具鏈是一組編程工具,用于開發(fā)軟件、創(chuàng)建軟件產(chǎn)品。工具鏈通常是另一個(gè)計(jì)算機(jī)程序或一組相關(guān)程序。通常,工具鏈里有多個(gè)工具,前一個(gè)工具的輸出結(jié)果,是下一個(gè)工具的輸入,也就是說前一個(gè)工具處理完,再交給下一個(gè)工具處理。
一個(gè)簡單工具鏈可能由三部分組成:編譯器和鏈接器(將源代碼轉(zhuǎn)換為可執(zhí)行程序)、庫(為操作系統(tǒng)提供接口)和調(diào)試器(用于測試和調(diào)試創(chuàng)建的程序)。一個(gè)復(fù)雜的軟件產(chǎn)品,如視頻游戲,需要準(zhǔn)備音效、音樂、紋理、3 維模型和動畫的工具,以及將這些資源組合成成品的附加工具。
**GNU ** 工具鏈 是一個(gè)廣泛收集的、遵守GNU協(xié)議的、眾多編程工具。這些工具形成一個(gè)工具鏈,用于開發(fā)應(yīng)用程序和操作系統(tǒng)。
GNU 工具鏈在Linux、一些BSD系統(tǒng)和嵌入式系統(tǒng)軟件的開發(fā)中起著至關(guān)重要的作用。
什么是交叉編譯工具鏈
**交叉編譯器:**在平臺A上使用它能夠生成程序,這個(gè)程序時(shí)運(yùn)行在平臺B上的。例如,在PC上運(yùn)行程序,但這個(gè)程序是在Android 智能手機(jī)上運(yùn)行的,這個(gè)編譯器就是交叉編譯器。
在PC上為其他平臺(目標(biāo)平臺)編譯代碼時(shí),需要交叉編譯器。能否直接在目標(biāo)平臺上編譯程序?比如在ARM板上編譯程序?大多時(shí)候不可行,因?yàn)锳RM板資源很可能受限。
交叉編譯器的基本用途是將構(gòu)建環(huán)境與目標(biāo)環(huán)境分開。這在幾種情況下很有用:
-
設(shè)備資源極其有限的嵌入式計(jì)算機(jī)。例如,微波爐將有一個(gè)非常小的計(jì)算機(jī)來讀取它的鍵盤和門傳感器,向數(shù)字顯示器和揚(yáng)聲器提供輸出,并控制烹飪食物的機(jī)器。這臺計(jì)算機(jī)通常不夠強(qiáng)大,無法運(yùn)行編譯器、文件系統(tǒng)或開發(fā)環(huán)境。
-
為多目標(biāo)編譯。例如,公司可能希望用同一套代碼,支持多個(gè)不同的操作系統(tǒng)。通過使用交叉編譯器,可以設(shè)置單個(gè)構(gòu)建環(huán)境,為每個(gè)目標(biāo)系統(tǒng)單獨(dú)編譯程序。
-
在服務(wù)器上編譯。服務(wù)器性能強(qiáng)大,很多公司都是在服務(wù)器上為其他平臺編譯程序。
-
引導(dǎo)到新平臺。在為新平臺開發(fā)軟件時(shí),人們使用交叉編譯器來編譯必要的工具,例如操作系統(tǒng)和本地編譯器。
獲得合適的交叉編譯工具鏈
-
獲取現(xiàn)成的
- 來自發(fā)行版系統(tǒng)內(nèi): Ubuntu 和 Debian 有許多現(xiàn)成的交叉編譯器。
-
來自不同組織:
-
芯片原廠提供的交叉編譯工具鏈(一般包含在配套的BSP內(nèi))。
-
Bootlin社區(qū)提供的各種架構(gòu)工具鏈 。
-
ARM 官方提供的aarch32 aarch64工具鏈。
-
Linaro 提供 ARM 和 AArch64 工具鏈,以及一些早期版本工具鏈。
-
gnutoolchains 提供可以在windows上運(yùn)行的交叉編譯工具鏈。
-
riscv-collab 提供的riscv GNU 工具鏈。
-
-
自己編譯構(gòu)建
-
Crosstool-NG,專門構(gòu)建交叉編譯工具鏈的工具。 迄今為止擁有最可配置選項(xiàng)/并支持多種功能的。
-
嵌入式Linux構(gòu)建系統(tǒng)一般都知道如何構(gòu)建交叉編譯工具鏈:Yocto/OpenEmbedded、Buildroot、OpenWRT等。
-
-
參考文檔
-
Crosstool-NG 文檔,https://github.com/crosstool-ng/crosstool-ng/blob/master/docs/
-
GCC 文檔,https://gcc.gnu.org/onlinedocs/
-
Binutils 文檔,https://sourceware.org/binutils/docs/
-
sysroot
參考PPT 03-BUILDROOT課程第一部分之Linux工具鏈.pptx P18
-
sysroot 是頭文件和庫 的 邏輯根目錄。
-
gcc 尋找頭文件,ld 尋找?guī)斓牡胤?/p>
-
gcc 和 binutils 都是使用 --with-sysroot= 參數(shù)構(gòu)建的。
-
內(nèi)核頭文件和 C 庫安裝在 。
-
如果工具鏈已經(jīng)移動到不同的位置,如果它在 --prefix 的子目錄中,gcc 仍然會找到它的 sysroot ,但是需要在編譯時(shí)指定如下參數(shù)。
? --prefix=
? --with-sysroot=
-
可以在運(yùn)行時(shí)使用 gcc 的 --sysroot 選項(xiàng)覆蓋。
-
可以使用 -print-sysroot 選項(xiàng)打印當(dāng)前的 sysroot。
可以理解為 sysroot 就是提前幫你約束好了一個(gè)統(tǒng)一存放非標(biāo)準(zhǔn)GCC庫以外的其他組件/應(yīng)用 lib庫 頭文件的位置,方便其他程序 調(diào)用,去使用它! 而不用頻繁去
增加 -I -L參數(shù)進(jìn)行指定位置。
參考:https://ryan0988.pixnet.net/blog/post/207806602-gcc-sysroot-&-spec-files
參考:https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html
參考: https://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Spec-Files.html#Spec-Files
自由軟件許可
常見開源組件
Target設(shè)備工具: 系統(tǒng)工具
-
dbus, 一種應(yīng)用程序間面向?qū)ο蟮耐ㄐ趴偩€。
-
gpsd,一個(gè)解析和共享 GPS 數(shù)據(jù)的守護(hù)進(jìn)程
-
libusb,一個(gè)無需編寫內(nèi)核驅(qū)動程序即可訪問 USB 設(shè)備的用戶空間庫。
-
內(nèi)核子系統(tǒng)的實(shí)用程序:用于 I2C 的 i2c-tools、用于輸入的 input-tools、用于 MTD 設(shè)備的 mtd-utils、用于 USB 設(shè)備的 usbutils。
Target設(shè)備工具:編程語言
-
提供最常見腳本語言的解釋器,常用于:
-
應(yīng)用開發(fā)
-
網(wǎng)絡(luò)服務(wù)開發(fā)
-
腳本
-
-
支持的編程語言
-
shell(bash、sh…)
-
Lua,簡單的嵌入式C應(yīng)用。
-
python
-
Perl
-
Ruby
-
TCL
-
PHP
-
Target設(shè)備工具: 音頻 視頻 多媒體
- GStreamer,一個(gè)多媒體框架
允許對各種編解碼器進(jìn)行解碼/編碼(FFmpeg)。
通過插件支持硬件編碼器和解碼器,專有/特定插件通常由 SoC 供應(yīng)商提供。 - alsa-lib,與 ALSA 內(nèi)核聲音子系統(tǒng)關(guān)聯(lián)的用戶空間庫
直接使用編解碼庫, - 如果決定不使用GStreamer:
- libavcodec:來自 ffmpeg 項(xiàng)目,用于 vlc 和 mplayer 等播放器,支持大多數(shù)音視頻編解碼器(mpeg4、h264、vp8、vp9…)
- libvpx:vp8 和 vp9 視頻編碼
- libflac:FLAC:免費(fèi)無損音頻編解碼器
- libopus:最新最大的有損音頻編解碼器
- libmad:解碼mp3音頻
Target設(shè)備工具: 圖形套件(Low-Level)
- Gtk: 著名的工具包,提供基于widget 的高級API 來開發(fā)圖形應(yīng)用程序
C 語言中的標(biāo)準(zhǔn) API,但存在針對各種語言的綁定:C++、Python 等。
在 X.org 和 Wayland 之上工作。
沒有窗口系統(tǒng),運(yùn)行多個(gè)應(yīng)用程序需要一個(gè)輕量級的窗口管理器。 可能的解決方案:Matchbox.。
License:LGPL
多平臺:Linux、MacOS、Windows。
官網(wǎng) https://www.gtk.org
- Wayland: 更簡單的 X 替代品
Wayland 是一種供合成器與其客戶對話的協(xié)議,以及該協(xié)議的 C 庫實(shí)現(xiàn)。
Weston:Wayland 合成器的最小且快速的參考實(shí)現(xiàn),適用于許多嵌入式和移動用例。
大多數(shù)圖形工具包(Gtk、Qt、EFL…)現(xiàn)在都支持 Wayland。
大多數(shù)桌面發(fā)行版都支持它:Fedora、Debian、Ubuntu(從 21.04 開始)
https://en.wikipedia.org/wiki/Wayland_(display_server_protocol)
- Qt : 一個(gè)著名的工具包,提供基于小部件的高級 API 來開發(fā)圖形應(yīng)用程序
C++語言實(shí)現(xiàn)
Target(目標(biāo))系統(tǒng)需要 C++ 庫
C++ 使用的標(biāo)準(zhǔn) API,但有其他語言的綁定
可以工作在
Framebuffer
X11
wayland
支持多平臺:Linux、MacOS、Windows。
擁有非常豐富的文檔教程
官網(wǎng):https://www.qt.io/
License:LGPLv3 和 GPLv3 混合(某些部分是 LGPLv2 和 GPLv2),使得非 GPL 應(yīng)用程序難以實(shí)現(xiàn)。 根據(jù)客戶的說法,商業(yè)許可非常昂貴。
Target設(shè)備工具: 數(shù)據(jù)庫
-
SQLite
官網(wǎng):https://www.sqlite.org
SQLite 是一個(gè)小型的 C 庫,它實(shí)現(xiàn)了一個(gè)自包含的、可嵌入的、輕量級的、零配置的 SQL 數(shù)據(jù)庫引擎
嵌入式 Linux 系統(tǒng)的首選數(shù)據(jù)庫引擎
可以作為普通庫使用
可以直接嵌入到應(yīng)用程序中,甚至是專有應(yīng)用程序,因?yàn)?SQLite 是在公共領(lǐng)域發(fā)布的
Target設(shè)備工具: 網(wǎng)絡(luò)瀏覽器
-
WebKit https://webkit.org/ 網(wǎng)絡(luò)瀏覽器引擎。 可用于開發(fā) Web 瀏覽器或向應(yīng)用程序添加 HTML 渲染功能的應(yīng)用程序框架。 您還可以用全屏瀏覽器(更容易實(shí)現(xiàn))替換您的應(yīng)用程序。
License:LGPL 中的部分和 BSD 中的其他部分允許專有應(yīng)用。
被許多網(wǎng)絡(luò)瀏覽器使用:Safari、iPhone 和 Android 默認(rèn)瀏覽器…谷歌瀏覽器現(xiàn)在使用其 WebCore 組件的一個(gè)分支)。 電子郵件客戶端也使用它來呈現(xiàn) HTML。
多個(gè)圖形后端:Qt、GTK、EFL…
自由軟件與更改分開
編譯工具
-
每個(gè)開源組件都有配置、編譯和安裝的機(jī)制
-
一個(gè)基本的 Makefile 需要閱讀 Makefile 以了解它是如何工作的以及如何調(diào)整它以進(jìn)行交叉編譯
-
基于 Autotools 的構(gòu)建系統(tǒng) 這是最常見的構(gòu)建系統(tǒng)。
-
CMake,https://cmake.org/ 比 autotools 更新更簡單。 (有時(shí)是大型)項(xiàng)目使用。例如 KDE、KiCad、LLVM/Clang、Scribus、OpenCV、Qt。
-
Meson,https://mesonbuild.com/ 使用起來更快更簡單。 現(xiàn)在被 GNOME(partially)、GTK+、Gstreamer、Mesa、Systemd、Wayland (Weston) 等項(xiàng)目使用。
-
還有更多…
GUN組織
Makefile
Autotools
一系列工具,它們關(guān)聯(lián)在一起形成了一個(gè)完整且可擴(kuò)展的構(gòu)建系統(tǒng)
-
autoconf 用于處理軟件包的配置
-
automake 用于生成構(gòu)建軟件包所需的 Makefile
-
pkgconfig 用于簡化針對已安裝共享庫的編譯
-
llibtool 用于以系統(tǒng)無關(guān)的方式處理共享庫的生成
這些工具中的大多數(shù)都比較陳舊且使用起來相對復(fù)雜,但如今大多數(shù)免費(fèi)軟件包都在使用它們。 人們必須對他們做什么以及他們?nèi)绾喂ぷ饔幸粋€(gè)基本的了解。
Cmake
CMake 是一個(gè)開源的跨平臺工具系列,旨在構(gòu)建、測試和打包軟件。 CMake 用于使用簡單的平臺和編譯器獨(dú)立配置文件來控制軟件編譯過程,并生成可在您選擇的編譯器環(huán)境中使用的本機(jī) makefile 和工作區(qū)。 CMake 工具套件是由 Kitware 創(chuàng)建的,旨在響應(yīng) ITK 和 VTK 等開源項(xiàng)目對強(qiáng)大的跨平臺構(gòu)建環(huán)境的需求。
CMake 是 Kitware 的商業(yè)支持開源軟件開發(fā)平臺集合的一部分。
Meson
概述:Meson 是一個(gè)開源構(gòu)建系統(tǒng),其速度非???#xff0c;重要的是,它對于用戶盡可能友好。
Meson 主要特點(diǎn)是:開發(fā)人員花在編寫或調(diào)試構(gòu)建定義上的每一刻都是浪費(fèi)一秒鐘。
等待構(gòu)建系統(tǒng)從開始編譯代碼的每一秒也是如此。
特征:對 Linux、macOS、Windows、GCC、Clang、Visual Studio 和
其他受支持語言的多平臺支持,包括 C、C++、D、Fortran、Java、Rust 構(gòu)建定義,
采用非常易讀且用戶友好的非圖靈完備 DSL 交叉編譯,適用于許多操作系統(tǒng)以及裸機(jī)系統(tǒng)。
在保證準(zhǔn)確性的情況下最大程度優(yōu)化了速度和增量構(gòu)建,
與發(fā)行包一起工作的內(nèi)置多平臺依賴提供程序。
編譯系統(tǒng)
- Buildroot,由社區(qū)開發(fā) https://buildroot.org
- OpenWRT,最初是無線路由器Buildroot的一個(gè)分支,現(xiàn)在是一個(gè)更通用的項(xiàng)目 https://openwrt.org
- OpenEmbedded,更靈活但也更復(fù)雜 http://www.openembedded.org 及其工業(yè)化版本 Yocto 項(xiàng)目。
- lPTXdist,由 Pengutronix 開發(fā) https://www.ptxdist.org 類似的配置界面(menuconfig),但剛開始有點(diǎn)難掌握。
buildroot
Yocto
Openwrt
構(gòu)建系統(tǒng)對比
其他構(gòu)建工具
發(fā)行版rootfs
4.使用Buildroot BSP構(gòu)建系統(tǒng)
配置開發(fā)環(huán)境
HOST主機(jī)配置建議:
- i5 8代以上處理器,至少 4核心 主頻在 3Ghz以上
- DDR3 1660Mhz 12GB以上內(nèi)存
- 300G以上存儲可用空間
- 電腦預(yù)留至少兩個(gè) USB 2.0 TYpeA接口
- 電腦支持 WiFi 2.4Ghz 頻率無線上網(wǎng)
- 電腦支持 Windows10+ 以上系統(tǒng) (不支持Mac 不支持裸跑ubuntu/其他版本Linux)
下載vmware虛擬機(jī)工具
使用瀏覽器打開網(wǎng)址 https://www.vmware.com/products/workstation-pro/workstation-pro-evaluation.html 參考下圖箭頭所示,點(diǎn)擊下載安裝 Windows版本的VMware Workstation ,點(diǎn)擊 DOWNLOAD NOW 即可開始下載。
下載完成后全部使用默認(rèn)配置一步步安裝即可。
獲取Ubuntu系統(tǒng)鏡像
- 使用瀏覽器打開 https://www.linuxvmimages.com/images/ubuntu-2004/ 找到如下箭頭所示位置,點(diǎn)擊 VMware Image 下載。
- 或者使用資料光盤內(nèi):
1_DongshanPI-Vision資料\3_DongshanPI-Vision_配套工具\(yùn)【VMware】Ubuntu-20.04虛擬機(jī)系統(tǒng)鏡像
目錄下Ubuntu_20.04.4_VM.7z
下載過程可能會持續(xù) 10 到 30 分鐘,具體要依據(jù)網(wǎng)速而定。
運(yùn)行虛擬機(jī)系統(tǒng)
- 解壓縮 虛擬機(jī)系統(tǒng)鏡像壓縮包,解壓縮完成后,可以看到里面有如下兩個(gè)文件,接下來,我們會使用 后綴名為 .vmx 這個(gè) 配置文件。
- 打開已經(jīng)安裝好的 vmware workstation 軟件 點(diǎn)擊左上角的 文件 → 打開 找到上面的 Ubuntu_18.04.6_VM_LinuxVMImages.COM.vmx 文件,之后會彈出新的虛擬機(jī)對話框頁面。
- 如下圖所示為 為我們已經(jīng)虛擬機(jī)的配置界面,那面我們可以 點(diǎn)擊 紅框 1 編輯虛擬機(jī)設(shè)置 里面 去調(diào)正 我們虛擬機(jī)的 內(nèi)存 大小 和處理器個(gè)數(shù),建議 最好 內(nèi)存為 8GB 及以上,處理器至少4 個(gè),網(wǎng)絡(luò)適配器最好使用 橋接模式。 調(diào)整好以后,就可以 點(diǎn)擊 開啟此虛擬機(jī) 來運(yùn)行此虛擬機(jī)了
第一次打開會提示 一個(gè) 虛擬機(jī)已經(jīng)復(fù)制的 對話框,我們這時(shí),只需要 點(diǎn)擊 我已復(fù)制虛擬機(jī) 就可以繼續(xù)啟動虛擬機(jī)系統(tǒng)了。
等待數(shù)秒,系統(tǒng)就會自動啟動了,啟動以后 鼠標(biāo)點(diǎn)擊 Ubuntu 字樣,就可以進(jìn)入登錄對話框,輸入 密碼 ubuntu 即可登錄進(jìn)入ubuntu系統(tǒng)內(nèi)。
注意:
Ubuntu默認(rèn)的用戶名密碼分別為 ubuntu ubuntu
Ubuntu默認(rèn)的用戶名密碼分別為 ubuntu ubuntu
Ubuntu默認(rèn)的用戶名密碼分別為 ubuntu ubuntu
ubuntu默認(rèn)需要聯(lián)網(wǎng),如果你的 Windows電腦已經(jīng)可以訪問Internet 互聯(lián)網(wǎng),ubuntu系統(tǒng)后就會自動共享 Windows電腦的網(wǎng)絡(luò) 進(jìn)行連接internet 網(wǎng)絡(luò)。
安裝編譯所需依賴
- 安裝必要軟件包, 鼠標(biāo)點(diǎn)擊進(jìn)入 ubuntu界面內(nèi),鍵盤同時(shí) 按下 ctrl + alt + t 三個(gè)按鍵會快速喚起,終端界面,喚起成功后,在終端里面執(zhí)行如下命令進(jìn)行安裝必要依賴包。
? 你的ubuntu虛擬機(jī) 第一次啟動是 無法 通過 windows下復(fù)制 命令 粘貼到 ubuntu內(nèi)的,則需要先手敲 執(zhí)行如下命令 安裝一個(gè) 用于 虛擬機(jī)和 windows共享剪切板的工具包,安裝完成后,點(diǎn)擊右上角的 電源按鈕,重啟ubuntu系統(tǒng),或者 直接輸入 sudo reboot 命令進(jìn)行重啟。重啟系統(tǒng)后 才可以執(zhí)行 Windows復(fù)制 粘貼至 ubuntu的拖拽操作。
sudo apt install open-vm-tools-desktop
重啟系統(tǒng)后,重新打開終端 復(fù)制如下 命令 來安裝 編譯 DongshanPI-Vision系統(tǒng)所需的必要依賴包,鍵盤同時(shí) 按下 ctrl + alt + t 三個(gè)按鍵會快速喚起,終端界面,喚起成功后,在終端里面執(zhí)行如下命令進(jìn)行安裝必要依賴包。
sudo apt-get install -y g++ vim libssl-dev android-tools-fastboot python3-pip mtd-utils libncurses5-dev libgdbm-dev libnss3-dev libreadline-dev libgdbm-dev libffi-dev wget sed make binutils build-essential gcc bash patch gzip bzip2 perl tar cpio unzip rsync file bc python cvs git mercurial subversion android-tools-mkbootimg zlib1g-dev libgdbm-dev libc6:i386 libstdc++6:i386 libncurses5:i386 zlib1g:i386
這時(shí)就可以 通過windows端向ubuntu內(nèi)粘貼文件,或者拷貝拷出文件了。
做完這一步以后,就可以繼續(xù)往下,獲取源碼。
如果下載安裝速度非常慢,可以修改 軟件源地址為 國內(nèi) 阿里云源 或者 清華源
獲取配套源碼
Git下載
打開VMware虛擬機(jī)工具啟動Ubuntu20.04系統(tǒng),啟動完成后在用戶目錄中打開終端,創(chuàng)建DongshanPI-Vision
文件夾,用于存放系統(tǒng)源碼。
進(jìn)入DongshanPI-Vision
目錄下,拉取系統(tǒng)源碼:https://e.coding.net/weidongshan/dongshanpi-vision/br2-canaan-k510.git。
進(jìn)入br2-canaan-k510
目錄下,拉取buildroot源碼:https://e.coding.net/weidongshan/dongshanpi-vision/buildroot-2020.02.11.git。
ubuntu@ubuntu2004:~$ mkdir DongshanPI-Vision && cd DongshanPI-Vision
ubuntu@ubuntu2004:~/DongshanPI-Vision$ git clone https://e.coding.net/weidongshan/dongshanpi-vision/br2-canaan-k510.git
ubuntu@ubuntu2004:~/DongshanPI-Vision$ cd br2-canaan-k510/
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510$ git clone https://e.coding.net/weidongshan/dongshanpi-vision/buildroot-2020.02.11.git
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510$ ls
board Config.in docs external.mk Makefile package pkg-download release_notes.md tools
buildroot-2020.02.11 configs external.desc LICENSE mkdtb-local.sh patches README.md toolchain
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510$
下載其他
? 為了加速整個(gè)編譯的時(shí)間和避免出現(xiàn)因?yàn)槟承┌鼰o法下載導(dǎo)致的問題,我們需要單獨(dú)講 我們提前準(zhǔn)備好的 dl.tar.gz nds64le-elf-mculib-v5d.txz 壓縮包單獨(dú)下載下來 然后拷貝至 bsp工程目錄內(nèi)進(jìn)行解壓縮。
- dl.tar.gz 壓縮包:
- 下載方式一:瀏覽器 訪問 鏈接 點(diǎn)擊下載 https://dongshanpi.cowtransfer.com/s/4d7394cfad3640
- 下載方式二:資料光盤內(nèi)
1_DongshanPI-Vision資料/2_DongshanPI-Vision_BSP源碼
dl.tar.gz
- nds64le-elf-mculib-v5d.txz 壓縮包
- 下載方式一:瀏覽器 訪問 鏈接 點(diǎn)擊下載 https://dongshanpi.cowtransfer.com/s/bc101fb198e746
- 下載方式二:資料光盤內(nèi)
1_DongshanPI-Vision資料/2_DongshanPI-Vision_BSP源碼
nds64le-elf-mculib-v5d.txz
提前下載準(zhǔn)備好 dl.tar.gz nds64le-elf-mculib-v5d.txz 兩個(gè)壓縮包以后,可以直接通過 Filezila tftp傳輸工具上傳至 BSP工程目錄,也可以通過拖拽方式 直接拉至 ubuntu文件管理器內(nèi)。
切換到 終端命令行界面,可以看到 多出來的兩個(gè)壓縮包
解壓壓縮包dl.tar.gz文件
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510$ tar -xzvf dl.tar.gz
解壓完成后可以在當(dāng)前文件夾看到多出了一個(gè)名為dl
文件夾
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510$ ls
board dongshanpi-vision_defconfig patches
buildroot-2020.02.11 external.desc pkg-download
Config.in external.mk README.md
configs LICENSE release_notes.md
dl Makefile toolchain
dl.tar.gz mkdtb-local.sh tools
docs package
之后解壓縮 nds64le-elf-mculib-v5d.txz 因?yàn)檫@個(gè)壓縮包 最終要解壓到 DongshanPI-Vision/br2-canaan-k510/toolchain 目錄,所以我們需要使用 -C 指定解壓路徑來進(jìn)行解壓操作。
解壓交叉編譯工具鏈壓縮包 nds64le-elf-mculib-v5d.txz
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510/toolchain$ tar -xvf nds64le-elf-mculib-v5d.txz -C toolchain
解壓完成后,我們就可以開始進(jìn)行 編譯操作了!
Buildroot簡介
參考課程嵌入式Linux Buildroot系列開發(fā)第一部分之基礎(chǔ)知識課件 《BUILDROOT課程第一部分之Buildroot介紹.pptx》《BUILDROOT課程第一部分之配置Buildroot支持boards.pptx》
構(gòu)建原理
skeleton
根文件系統(tǒng) skeleton(骨架)
構(gòu)建流程
一個(gè)ROOTFS 的完整構(gòu)建流程
make 實(shí)現(xiàn)(帶有一些輔助 shell 腳本) 所有交互通過在 Buildroot 源目錄中調(diào)用 make 運(yùn)行。
$ make help
無需以 root 身份運(yùn)行,Buildroot 旨在以普通用戶權(quán)限執(zhí)行。甚至強(qiáng)烈建議不要以 root 身份運(yùn)行!
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig$ make help
Cleaning:clean - delete all files created by builddistclean - delete all non-source files (including .config)Build:all - make worldtoolchain - build toolchainsdk - build relocatable SDKConfiguration:menuconfig - interactive curses-based configuratornconfig - interactive ncurses-based configuratorxconfig - interactive Qt-based configuratorgconfig - interactive GTK-based configuratoroldconfig - resolve any unresolved symbols in .configsyncconfig - Same as oldconfig, but quietly, additionally update depsolddefconfig - Same as syncconfig but sets new symbols to their default valuerandconfig - New config with random answer to all optionsdefconfig - New config with default answer to all options;BR2_DEFCONFIG, if set on the command line, is used as inputsavedefconfig - Save current config to BR2_DEFCONFIG (minimal config)update-defconfig - Same as savedefconfigallyesconfig - New config where all options are accepted with yesallnoconfig - New config where all options are answered with noalldefconfig - New config where all options are set to defaultrandpackageconfig - New config with random answer to package optionsallyespackageconfig - New config where pkg options are accepted with yesallnopackageconfig - New config where package options are answered with noPackage-specific:<pkg> - Build and install <pkg> and all its dependencies<pkg>-source - Only download the source files for <pkg><pkg>-extract - Extract <pkg> sources<pkg>-patch - Apply patches to <pkg><pkg>-depends - Build <pkg>'s dependencies<pkg>-configure - Build <pkg> up to the configure step<pkg>-build - Build <pkg> up to the build step<pkg>-show-info - generate info about <pkg>, as a JSON blurb<pkg>-show-depends - List packages on which <pkg> depends<pkg>-show-rdepends - List packages which have <pkg> as a dependency<pkg>-show-recursive-depends- Recursively list packages on which <pkg> depends<pkg>-show-recursive-rdepends- Recursively list packages which have <pkg> as a dependency<pkg>-graph-depends - Generate a graph of <pkg>'s dependencies<pkg>-graph-rdepends - Generate a graph of <pkg>'s reverse dependencies<pkg>-dirclean - Remove <pkg> build directory<pkg>-reconfigure - Restart the build from the configure step<pkg>-rebuild - Restart the build from the build stepbusybox:busybox-menuconfig - Run BusyBox menuconfiglinux:linux-menuconfig - Run Linux kernel menuconfiglinux-savedefconfig - Run Linux kernel savedefconfiglinux-update-defconfig - Save the Linux configuration to the path specifiedby BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILEDocumentation:manual - build manual in all formatsmanual-html - build manual in HTMLmanual-split-html - build manual in split HTMLmanual-pdf - build manual in PDFmanual-text - build manual in textmanual-epub - build manual in ePubgraph-build - generate graphs of the build timesgraph-depends - generate graph of the dependency treegraph-size - generate stats of the filesystem sizelist-defconfigs - list all defconfigs (pre-configured minimal systems)Miscellaneous:source - download all sources needed for offline-buildexternal-deps - list external packages usedlegal-info - generate info about license complianceshow-info - generate info about packages, as a JSON blurbprintvars - dump internal variables selected with VARS=...make V=0|1 - 0 => quiet build (default), 1 => verbose buildmake O=dir - Locate all output files in "dir", including .configFor further details, see README, generate the Buildroot manual, or consult
it on-line at http://buildroot.org/docs.html
make defconfig
make menuconfig
make -dirclean
make -rebuild
make savedefconfig
make sdk
make V=1
編譯構(gòu)建系統(tǒng)
執(zhí)行配置命令
在DongshanPI-Vision/br2-canaan-k510
目錄下,執(zhí)行make CONF=dongshanpi-vision_defconfig
,在SDK源碼內(nèi)指定DongshanPI-Vision開發(fā)板系統(tǒng)配置文件。
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510$ make CONF=dongshanpi-vision_defconfig
配置完成后會自動開始編譯系統(tǒng)。編譯時(shí)間可能會比較長,大概需要 2 - 3個(gè)小時(shí)!
? 為了加速編譯過程,我們直接使用我們提前準(zhǔn)備好的 輸出工程,放在 BSP 工程目錄來加速編譯,確保 你的Ubuntu 環(huán)境沒有問題,如果你希望 可以重頭編譯,查看編譯詳細(xì)過程,就不需要操作這一步。我們直接將資料光盤內(nèi) 1_DongshanPI-Vision資料/2_DongshanPI-Vision_BSP源碼
dongshanpi-vision_defconfig.tar.gz 通過拖拽方式/tftp方式上傳至 **~/DongshanPI-Vision/br2-canaan-k510 **目錄,然后 使用 rm -r dongshanpi-vision_defconfig/ 命令 刪除剛才的緩存數(shù)據(jù),之后解壓縮 dongshanpi-vision_defconfig.tar.gz 壓縮包,解壓成功后繼續(xù)執(zhí)行 make CONF=dongshanpi-vision_defconfig 命令。
Q:編譯nncase錯(cuò)誤
驗(yàn)證命令
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig$ make nncase_linux_runtime-rebuild
A: 解決方式
配置ubuntu默認(rèn) python 版本一定要為 3.8 ,否則無法安裝 nncase-k510
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510$ sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510$ sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.8 2
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510$ update-alternatives --list python
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510$ sudo update-alternatives --config python
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510$ python -m pip install --upgrade pip
配置完成后 需要 重啟Ubuntu系統(tǒng)生效 才能繼續(xù)執(zhí)行后續(xù)的命令
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510$ pip install nncase-k510 -i https://pypi.tuna.tsinghua.edu.cn/simple
Q:編譯AI示例報(bào)錯(cuò)
驗(yàn)證命令
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig$ make ai-rebuild
A: 解決方式
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig$ pip install onnx -i https://pypi.tuna.tsinghua.edu.cn/simple
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig$ pip install onnxsim -i https://pypi.tuna.tsinghua.edu.cn/simple
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig$ pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510$ make ai-rebuild
方法二: 使用資料光盤內(nèi)的 pip 包集合1_DongshanPI-Vision資料/2_DongshanPI-Vision_BSP源碼
requirements.txt 執(zhí)行如下命令進(jìn)行統(tǒng)一安裝!
構(gòu)建成功鏡像介紹
編譯完成后,會生成dongshanpi-vision_defconfig
文件夾
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510$ cd dongshanpi-vision_defconfig/
ubuntu@ubuntu2004:~/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig$ ls
build host images Makefile nand_target staging target
其中各文件描述如下:
文件 | 內(nèi)容描述 |
---|---|
Makefile | 編譯鏡像使用的Makefile。 |
build | 所有源碼包的編譯目錄。例如linux kernel,u-boot,BBL,busybox等,源碼都會解壓到build目錄下并編譯。 |
host | 所有host package的安裝路徑,toolchain也會拷貝至此目錄下,用于構(gòu)建交叉編譯環(huán)境。 |
images | 編譯生成的目標(biāo)文件目錄(詳見下面的說明) |
nand_target | 根文件系統(tǒng)原始目錄(生成NandFlash鏡像使用) |
target | 根文件系統(tǒng)原始目錄(生成eMMC和SD卡鏡像使用) |
- dongshanpi-vision_defconfig/images目錄下是燒錄鏡像,其中各個(gè)文件的說明如下。
文件 | 內(nèi)容描述 |
---|---|
bootm-bbl.img | Linux+bbl內(nèi)核鏡像(打包過內(nèi)核的bbl目標(biāo)文件,用于uboot引導(dǎo)bbl) |
k510.dtb | 設(shè)備樹 |
sysimage-emmc.img | emmc燒錄文件:已整個(gè)打包uboot_burn、kernel和bbl |
sysImage-sdcard.img | sdcard燒錄文件:已整個(gè)打包uboot_burn、kernel和bbl |
sysImage-nand.img | nand燒錄文件:已整個(gè)打包uboot_burn、kernel和bbl |
u-boot.bin | uboot 二進(jìn)制文件 |
u-boot_burn.bin | uboot 燒錄文件 |
uboot-emmc.env | uboot環(huán)境變量:用于emmc啟動 |
uboot-sd.env | uboot環(huán)境變量:用于sdcard啟動 |
uboot-nand.env | uboot環(huán)境變量:用于nand啟動 |
vmlinux | Linux內(nèi)核鏡像文件(帶elf調(diào)試信息) |
rootfs.ext2 | buildroot格式rootfs ext2鏡像文件 |
sysimage-sdcard-debian.img | sdcard燒錄文件:卡鏡像(debian格式rootfs) |
- dongshanpi-vision_defconfig/build 目錄下是所有被編譯對象的源碼,其中幾個(gè)重要的文件說明如下。
文件 | 內(nèi)容描述 |
---|---|
linux-xxx | 被編譯的 Linux kernel源碼目錄 |
uboot-xxx | 被編譯的 Uboot 源碼目錄 |
riscv-pk-k510-xxx | 被編譯的 bbl 源碼目錄 |
… |
注: xxx是版本號。后面章節(jié)引用kernle,bbl和uboot的路徑時(shí),xxx均表示版本號。
需要特別注意:當(dāng)make clean 的時(shí)候,dongshanpi-vision_defconfig文件夾下所有內(nèi)容將被刪除。所以,如果需要修改kernel、bbl或者uboot代碼,不要直接在build目錄下修改,可以進(jìn)行 單獨(dú) 編譯 uboot kernel 操作。
單獨(dú)清理 緩存,重新生成系統(tǒng)鏡像 rm output/target; find output/build/ -name .stamp_target_installed | xargs rm; make
更新系統(tǒng)鏡像
硬件要求:
- DongshanPI-Vision開發(fā)板
- Type-c數(shù)據(jù)線 x2
軟件要求:
- 拷貝前面編譯打包好的emmc系統(tǒng)鏡像 sysimage-emmc.img 至 Windows 目錄內(nèi),并記住它在計(jì)算機(jī)中保存的位置。
- 解壓資料光盤內(nèi)
1_DongshanPI-Vision資料\3_DongshanPI-Vision_配套工具\(yùn)【W(wǎng)indows】DongshanPI-Vision EMMC燒錄工具
KendryteBurningTool 燒錄工具。
1.5.1 硬件操作
將下圖中的撥碼開關(guān)的boot0和boot1都向上撥,使開發(fā)板進(jìn)入下載模式。使用兩條Type-C線連接開發(fā)板端和電腦端,用于給開發(fā)板進(jìn)行供電和使用串口進(jìn)行燒錄EMMC系統(tǒng)。
1.5.2 燒錄鏡像
下載EMMC鏡像并記住它在計(jì)算機(jī)中的位置。打開KendryteBurningTool 燒錄工具,進(jìn)入KendryteBurningTool\bin
目錄下,雙擊打開BurningTool.exe
,如下所示的文件。
注意:在使用KendryteBurningTool 燒錄工具時(shí)需要關(guān)閉串口軟件和虛擬機(jī),防止串口被占用。
打開BurningTool.exe
程序后會進(jìn)入如下界面:
點(diǎn)擊選擇文件,選擇下載好的EMMC鏡像。選擇完成后點(diǎn)擊保存,操作步驟如下所示:
保存后需要在串口選擇中選擇開發(fā)板的串口號,當(dāng)我們將開發(fā)板和PC電腦端通過Type-C連接起來后,可以在BurningTool軟件中點(diǎn)擊紅色箭頭處查看我開發(fā)板的端口號,選擇開發(fā)板的串口端口號。(我們也可以在設(shè)備管理器中確認(rèn)開發(fā)的端口號)
選擇完成后,點(diǎn)擊開始燒錄燒錄。如果您不是第一次進(jìn)行燒錄,此時(shí)等待成功燒錄完成即可。如果您是第一次進(jìn)行燒錄請繼續(xù)閱讀下面的內(nèi)容。第一次燒錄步驟如下所示:
當(dāng)PC電腦首次進(jìn)行燒錄時(shí),第一個(gè)進(jìn)度條結(jié)束后,會顯示下圖中的錯(cuò)誤信息。此時(shí)需要安裝驅(qū)動。
1.5.3 安裝WinUSB燒錄驅(qū)動
- 找到資料光盤內(nèi)
1_DongshanPI-Vision資料\3_DongshanPI-Vision_配套工具\(yùn)【W(wǎng)indows】DongshanPI-Vision EMMC燒錄工具
zadig-2.4.exe 雙擊并運(yùn)行。
打開zadig-2.4
軟件,進(jìn)入如下界面
點(diǎn)擊Option
中的選擇List All Devices
(列出所有設(shè)備),具體操作如下所示:
上述操作完成后,可以看到在虛線框內(nèi)出現(xiàn)了設(shè)備名,我們需要切換設(shè)備為 Mass storage devices
,具體操作如下所示:
點(diǎn)擊Replace Driver
替換驅(qū)動程序,此時(shí)會彈出一個(gè)確認(rèn)窗口,點(diǎn)擊是
。
安裝完成后會彈出以下窗口點(diǎn)擊close
到此燒錄驅(qū)動成功安裝。
1.5.4 完整燒錄鏡像
安裝完成燒錄鏡像后,再次打開BurningTool.exe
燒錄工具軟件,按一下開發(fā)板 RESET按鍵,按照1.5.3章節(jié)中的操作進(jìn)行燒錄即可。完整燒錄步驟如下所示:
1.5.5 啟動EMMC系統(tǒng)
將下圖中的撥碼開關(guān)的boot0和boot1都向下?lián)?#xff0c;使開發(fā)板進(jìn)入EMMC啟動模式。使用兩條Type-C線連接開發(fā)板端和電腦端,用于給開發(fā)板進(jìn)行供電和使用串口登錄開發(fā)板控制臺。
使用串口軟件查看串口控制臺,成功啟動后會進(jìn)入開發(fā)板控制臺。
之后 我們需要參考 文章開頭 開發(fā)板使用章節(jié) 使開發(fā)板可以連接WiFi網(wǎng)絡(luò),進(jìn)行后續(xù)的 程序開發(fā)上傳操作
5. 使用SDK配套工具鏈開發(fā)應(yīng)用
交叉編譯工具鏈所在位置
gcc編譯器
所在路徑:~/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig/host/bin
系統(tǒng)組件lib庫
所在路徑:~/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig/host/riscv64-buildroot-linux-gnu/sysroot/usr/lib
系統(tǒng)組件頭文件
所在路徑:~/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig/host/riscv64-buildroot-linux-gnu/sysroot/usr/include
支持Makefile
配置工具鏈環(huán)境
如果需要在任意位置或者終端都可以使用交叉編譯工具鏈,則需要單獨(dú) 增加 工具鏈bin的路徑至 ubuntu PATH環(huán)境變量里,可以添加至 ~/.bashrc
也可以在每一個(gè)終端單獨(dú)配置。export PATH=$PATH:/home/ubuntu/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig/host/bin
配置完成后,執(zhí)行 riscv64-linux-gcc -v
驗(yàn)證是否配置成功。
ubuntu@ubuntu2004:~$ export PATH=$PATH:/home/ubuntu/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig/host/bin
ubuntu@ubuntu2004:~$ riscv64-linux-gcc -v
"/home/ubuntu/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig/host/opt/ext-toolchain/bin/riscv64-linux-gcc.gnu" "--sysroot" "/home/ubuntu/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig/host/riscv64-buildroot-linux-gnu/sysroot" "-mabi=lp64d" "-march=rv64imafd" "-v"
Using built-in specs.
COLLECT_GCC=/home/ubuntu/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig/host/opt/ext-toolchain/bin/riscv64-linux-gcc.gnu
COLLECT_LTO_WRAPPER=/home/ubuntu/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig/host/opt/ext-toolchain/bin/../libexec/gcc/riscv64-linux/7.3.0/lto-wrapper
Target: riscv64-linux
Configured with: /local/sqa/Jenkins/workspace/build-system-3/source-packages/gcc-7.4.0-riscv-ast-v3_2_0-branch-official/configure --target=riscv64-linux --prefix=/local/sqa/Jenkins/workspace/build-system-3/toolchain/nds64le-linux-glibc-v5d --with-pkgversion=2019-11-20_nds64le-linux-glibc-v5d-6c120106e03 --disable-nls --enable-languages=c,c++ --enable-lto --with-gmp=/local/sqa/Jenkins/workspace/build-system-3/host-tools --with-mpfr=/local/sqa/Jenkins/workspace/build-system-3/host-tools --with-mpc=/local/sqa/Jenkins/workspace/build-system-3/host-tools --with-isl=/local/sqa/Jenkins/workspace/build-system-3/host-tools --with-cloog=/local/sqa/Jenkins/workspace/build-system-3/host-tools --with-arch=rv64imafdcxv5 --with-tune=nx25 --enable-gp-insn-relax-default=yes --with-abi=lp64d --disable-werror --disable-multilib --enable-shared --enable-tls --with-sysroot=/local/sqa/Jenkins/workspace/build-system-3/toolchain/nds64le-linux-glibc-v5d/riscv64-linux/sysroot CFLAGS='-O2 -g -Wno-implicit-fallthrough -Wno-int-in-bool-context -Wno-cast-function-type -Wno-tautological-compare ' CXXFLAGS='-O2 -g -Wno-implicit-fallthrough -Wno-int-in-bool-context -Wno-cast-function-type -Wno-tautological-compare ' CC=/local/sqa/Jenkins/workspace/build-system-3/host-tools/bin/gcc CXX=/local/sqa/Jenkins/workspace/build-system-3/host-tools/bin/g++ LD=/local/sqa/Jenkins/workspace/build-system-3/host-tools/bin/ld AR=/local/sqa/Jenkins/workspace/build-system-3/host-tools/bin/gcc-ar RANLIB=/local/sqa/Jenkins/workspace/build-system-3/host-tools/bin/gcc-ranlib NM=/local/sqa/Jenkins/workspace/build-system-3/host-tools/bin/nm --enable-checking=release LDFLAGS=--static 'CFLAGS_FOR_TARGET=-O2 -g -mstrict-align -msoft-fp16' 'CXXFLAGS_FOR_TARGET=-O2 -g -mstrict-align -msoft-fp16' LDFLAGS_FOR_TARGET=
Thread model: posix
gcc version 7.3.0 (2019-11-20_nds64le-linux-glibc-v5d-6c120106e03)
ubuntu@ubuntu2004:~$
講工具鏈路徑增加至環(huán)境變量以后,可以使用Makefile 指定我們的交叉編譯工具鏈,編譯一個(gè) hello.c 通過 scp 方式,傳輸至開發(fā)板內(nèi),進(jìn)行運(yùn)行。
如下所示,為Makefile 示例,以及 hello.c 程序示例。
ubuntu@ubuntu2004:~/DongshanPI-Vision-Example/makefile-hello$ cat Makefile
CC := riscv64-linux-gcc
hello: hello.c${CC} -o hello hello.c
clean:rm hello
ubuntu@ubuntu2004:~/DongshanPI-Vision-Example/makefile-hello$ cat hello.c
#include <stdio.h>
int main(void)
{printf ("Hello 100ASK DongshanPI-Vision K510 AI Board !!! \r\n");return 0;
}
寫完程序后,執(zhí)行make命令來編譯,編譯完成后可以通過 網(wǎng)絡(luò)方式講 文件傳輸至開發(fā)板內(nèi)。
ubuntu@ubuntu2004:~/DongshanPI-Vision-Example/makefile-hello$ make
riscv64-linux-gcc -o hello hello.c
ubuntu@ubuntu2004:~/DongshanPI-Vision-Example/makefile-hello$ file hello
hello: ELF 64-bit LSB executable, UCB RISC-V, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv64-lp64d.so.1, for GNU/Linux 4.15.0, with debug_info, not stripped
ubuntu@ubuntu2004:~/DongshanPI-Vision-Example/makefile-hello$
? 如下為傳輸命令,先確保開發(fā)板 可以連接網(wǎng)絡(luò),之后 我們 講 ubuntu下編譯好的程序,拖拽到 windows下,使用 ssh 登陸開發(fā)板,然后 通過 tftp等命令上傳編譯后的 hello 可執(zhí)行程序。
[root@canaan /usr ]$ wpa_passphrase Programmers 100asktech > /etc/wpa_supplican
t.conf
[root@canaan /usr ]$ cat /etc/wpa_supplicant.conf
network={ssid="Programmers"#psk="100asktech"psk=934634dfcb4c3d40869ffb1ad66fd7857d80b2751d576e31e05bc587f20c9985
}
[root@canaan /usr ]$
[root@canaan /usr ]$ wpa_supplicant -D nl80211 -i wlan0 -c /etc/wpa_supplicant.conf &
Successfully initialized wpa_supplicant
[ 2199.972897] [dhd] P2P interface registered
[ 2200.006809] [dhd] WLC_E_IF: NO_IF set, event Ignored
[ 2200.014276] [dhd] P2P interface started
[ 2200.051980] [dhd] [wlan0] wl_run_escan : LEGACY_SCAN sync ID: 0, bssidx: 0
wlan0: Trying to associate with SSID 'Programmers'
[ 2201.178392] [dhd] CFG80211-ERROR) wl_set_set_cipher : set wsec_info error (0)
[ 2201.191461] [dhd] [wlan0] wl_conn_debug_info : Connecting with 94:d9:b3:b7:c9:0a ssid "Programmers", len (11), channel=2g-7(chan_cnt=1), sec=wpa2/psk/mfpn/tkip/aes, rssi=-39
[ 2201.272947] [dhd] [wlan0] wl_ext_iapsta_link : [S] Link UP with 94:d9:b3:b7:c9:0a
[ 2201.284568] [dhd] [wlan0] wl_bss_connect_done : Report connect result - connection succeeded
wlan0: Associated with 94:d9:b3:b7:c9:0a
wlan0: CTRL-EVENT-SUBNET-STATUS-UPDATE status=0
[ 2201.327785] [dhd] [wlan0] wl_add_keyext : key index (0) for 94:d9:b3:b7:c9:0a
wlan0: WPA: Key negotiation completed with 94:d9:b3:b7:c9:0a [PTK=CCMP GTK=TKIP]
wlan0: CTRL-EVENT-CONNECTED - Connection to 94:d9:b3:b7:c9:0a completed [id=0 id_str=][root@canaan /usr ]$ udhcpc -i wlan0
udhcpc: started, v1.31.1
udhcpc: sending discover
udhcpc: sending select for 192.168.0.174
udhcpc: lease of 192.168.0.174 obtained, lease time 122
deleting routers
adding dns 192.168.0.1
adding dns 192.168.0.1
[root@canaan /usr ]$
最后執(zhí)行程序,即可看到通過 Makefile 交叉編譯生成的hello 可執(zhí)行程序在開發(fā)板上運(yùn)行了起來。
支持Cmake示例
使用CMake構(gòu)建語言就和Makefile存在了一定的區(qū)別,如下演示示例,提供同樣的 hello.c 程序,通過CMake構(gòu)建語言去指定交叉編譯工具鏈頭文件lib庫等位置,編寫出 CMakeLists.txt
編譯規(guī)則文件,最后使用 cmake
進(jìn)行編譯生成
ubuntu@ubuntu2004:~/DongshanPI-Vision-Example/cmake-hello$ cat CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(helloword)
SET(CROSS_COMPILE 1)
set(CMAKE_SYSTEM_NAME Linux)
#CROSS_COMPILE Path
set(CMAKE_C_COMPILER "/home/ubuntu/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig/host/bin/riscv64-linux-gcc")
#Link LibsPath
link_directories(/home/ubuntu/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig/host/riscv64-buildroot-linux-gnu/sysroot/usr/lib
)
#Include Path
include_directories(/home/ubuntu/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig/host/riscv64-buildroot-linux-gnu/sysroot/usr/include/)
add_executable(hello_word hello.c)ubuntu@ubuntu2004:~/DongshanPI-Vision-Example/cmake-hello$ cat hello.c
#include <stdio.h>
int main(void)
{printf ("Hello Cmake 100ASK DongshanPI-Vision K510 AI Board !!! \r\n");return 0;
}
如下圖所示為編譯演示步驟,需要先在工程目錄下 創(chuàng)建一個(gè) build 目錄,之后進(jìn)入到這個(gè) build 目錄內(nèi),執(zhí)行 cmake … 命令,進(jìn)行編譯前的檢查配置,檢查通過后,執(zhí)行make命令來開始編譯,最終生成hello_word 可執(zhí)行程序,通過adb 命令上傳至開發(fā)板,最后在開發(fā)板內(nèi)執(zhí)行。
這里只列舉了兩個(gè)簡單的示例,大家可以自行根據(jù)《第三節(jié)課嵌入式Linux開發(fā)簡述》課程里面 Autotools 舉例的helloword示例,以及 meson 舉例的 helloword示例,如何進(jìn)行交叉編譯在開發(fā)板上運(yùn)行。
6.使用工具鏈進(jìn)行驅(qū)動開發(fā)-簡單
開發(fā)helloword驅(qū)動
ubuntu@ubuntu2004:~/DongshanPI-Vision-Example/hello_drv$ cat hello_drv.c
#include <linux/module.h>#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>/* 1. 確定主設(shè)備號 */
static int major = 0;
static char kernel_buf[1024];
static struct class *hello_class;#define MIN(a, b) (a < b ? a : b)/* 3. 實(shí)現(xiàn)對應(yīng)的open/read/write等函數(shù),填入file_operations結(jié)構(gòu)體 */
static ssize_t hello_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{int err;printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);err = copy_to_user(buf, kernel_buf, MIN(1024, size));return MIN(1024, size);
}static ssize_t hello_drv_write (struct file *file, const char __user *buf, size_t size, loff_t *offset)
{int err;printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);err = copy_from_user(kernel_buf, buf, MIN(1024, size));return MIN(1024, size);
}static int hello_drv_open (struct inode *node, struct file *file)
{printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);return 0;
}static int hello_drv_close (struct inode *node, struct file *file)
{printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);return 0;
}/* 2. 定義自己的file_operations結(jié)構(gòu)體 */
static struct file_operations hello_drv = {.owner = THIS_MODULE,.open = hello_drv_open,.read = hello_drv_read,.write = hello_drv_write,.release = hello_drv_close,
};/* 4. 把file_operations結(jié)構(gòu)體告訴內(nèi)核:注冊驅(qū)動程序 */
/* 5. 誰來注冊驅(qū)動程序啊?得有一個(gè)入口函數(shù):安裝驅(qū)動程序時(shí),就會去調(diào)用這個(gè)入口函數(shù) */
static int __init hello_init(void)
{int err;printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);major = register_chrdev(0, "hello", &hello_drv); /* /dev/hello */hello_class = class_create(THIS_MODULE, "hello_class");err = PTR_ERR(hello_class);if (IS_ERR(hello_class)) {printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);unregister_chrdev(major, "hello");return -1;}device_create(hello_class, NULL, MKDEV(major, 0), NULL, "hello"); /* /dev/hello */return 0;
}/* 6. 有入口函數(shù)就應(yīng)該有出口函數(shù):卸載驅(qū)動程序時(shí),就會去調(diào)用這個(gè)出口函數(shù) */
static void __exit hello_exit(void)
{printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);device_destroy(hello_class, MKDEV(major, 0));class_destroy(hello_class);unregister_chrdev(major, "hello");
}/* 7. 其他完善:提供設(shè)備信息,自動創(chuàng)建設(shè)備節(jié)點(diǎn) */module_init(hello_init);
module_exit(hello_exit);MODULE_LICENSE("GPL");ubuntu@ubuntu2004:~/DongshanPI-Vision-Example/hello_drv$ cat hello_drv_test.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>/** ./hello_drv_test -w abc* ./hello_drv_test -r*/
int main(int argc, char **argv)
{int fd;char buf[1024];int len;/* 1. 判斷參數(shù) */if (argc < 2) {printf("Usage: %s -w <string>\n", argv[0]);printf(" %s -r\n", argv[0]);return -1;}/* 2. 打開文件 */fd = open("/dev/hello", O_RDWR);if (fd == -1){printf("can not open file /dev/hello\n");return -1;}/* 3. 寫文件或讀文件 */if ((0 == strcmp(argv[1], "-w")) && (argc == 3)){len = strlen(argv[2]) + 1;len = len < 1024 ? len : 1024;write(fd, argv[2], len);}else{len = read(fd, buf, 1024); buf[1023] = '\0';printf("APP read : %s\n", buf);}close(fd);return 0;
}ubuntu@ubuntu2004:~/DongshanPI-Vision-Example/hello_drv$ cat Makefile
# 1. 使用不同的開發(fā)板內(nèi)核時(shí), 一定要修改KERN_DIR
# 2. KERN_DIR中的內(nèi)核要事先配置、編譯, 為了能編譯內(nèi)核, 要先設(shè)置下列環(huán)境變量:
# 2.1 ARCH, 比如: export ARCH=arm64
# 2.2 CROSS_COMPILE, 比如: export CROSS_COMPILE=aarch64-linux-gnu-
# 2.3 PATH, 比如: export PATH=$PATH:/home/book/100ask_roc-rk3399-pc/ToolChain-6.3.1/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin
# 注意: 不同的開發(fā)板不同的編譯器上述3個(gè)環(huán)境變量不一定相同,
# 請參考各開發(fā)板的高級用戶使用手冊KERN_DIR = /home/ubuntu/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig/build/linux-origin_master/all:make -C $(KERN_DIR) M=`pwd` modules $(CROSS_COMPILE)gcc -o hello_drv_test hello_drv_test.c clean:make -C $(KERN_DIR) M=`pwd` modules cleanrm -rf modules.orderrm -f hello_drv_testobj-m += hello_drv.o
ubuntu@ubuntu2004:~/DongshanPI-Vision-Example/hello_drv$
export PATH=$PATH:/home/ubuntu/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig/host/bin/
export ARCH=riscv
export CROSS_COMPILE=riscv64-linux-
開發(fā)gpio點(diǎn)燈驅(qū)動+應(yīng)用
ubuntu@ubuntu2004:~/DongshanPI-Vision-Example/led_drv$ cat leddrv.c
#include <linux/module.h>
#include <linux/platform_device.h>#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <linux/gpio/consumer.h>
#include <linux/of.h>/* 1. 確定主設(shè)備號 */
static int major = 0;
static struct class *led_class;
static struct gpio_desc *led_gpio;/* 3. 實(shí)現(xiàn)對應(yīng)的open/read/write等函數(shù),填入file_operations結(jié)構(gòu)�? */
static ssize_t led_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);return 0;
}/* write(fd, &val, 1); */
static ssize_t led_drv_write (struct file *file, const char __user *buf, size_t size, loff_t *offset)
{int err;char status;//struct inode *inode = file_inode(file);//int minor = iminor(inode);printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);err = copy_from_user(&status, buf, 1);/* 根據(jù)次設(shè)備號和status控制LED */gpiod_set_value(led_gpio, status);return 1;
}static int led_drv_open (struct inode *node, struct file *file)
{//int minor = iminor(node);printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);/* 根據(jù)次設(shè)備號初始化LED */gpiod_direction_output(led_gpio, 0);return 0;
}static int led_drv_close (struct inode *node, struct file *file)
{printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);return 0;
}/* 定義自己的file_operations結(jié)構(gòu)�? */
static struct file_operations led_drv = {.owner = THIS_MODULE,.open = led_drv_open,.read = led_drv_read,.write = led_drv_write,.release = led_drv_close,
};/* 4. 從platform_device獲得GPIO* 把file_operations結(jié)構(gòu)體告訴內(nèi)核:注冊驅(qū)動程序*/
static int chip_demo_gpio_probe(struct platform_device *pdev)
{//int err;printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);/* 4.1 設(shè)備樹中定義�? led-gpios=<...>; */led_gpio = gpiod_get(&pdev->dev, "led", 0);if (IS_ERR(led_gpio)) {dev_err(&pdev->dev, "Failed to get GPIO for led\n");return PTR_ERR(led_gpio);}/* 4.2 注冊file_operations */major = register_chrdev(0, "100ask_led", &led_drv); /* /dev/led */led_class = class_create(THIS_MODULE, "100ask_led_class");if (IS_ERR(led_class)) {printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);unregister_chrdev(major, "led");gpiod_put(led_gpio);return PTR_ERR(led_class);}device_create(led_class, NULL, MKDEV(major, 0), NULL, "100ask_led%d", 0); /* /dev/100ask_led0 */return 0;}static int chip_demo_gpio_remove(struct platform_device *pdev)
{device_destroy(led_class, MKDEV(major, 0));class_destroy(led_class);unregister_chrdev(major, "100ask_led");gpiod_put(led_gpio);return 0;
}static const struct of_device_id ask100_leds[] = {{ .compatible = "100ask,leddrv" },{ },
};/* 1. 定義platform_driver */
static struct platform_driver chip_demo_gpio_driver = {.probe = chip_demo_gpio_probe,.remove = chip_demo_gpio_remove,.driver = {.name = "100ask_led",.of_match_table = ask100_leds,},
};/* 2. 在入口函數(shù)注冊platform_driver */
static int __init led_init(void)
{int err;printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);err = platform_driver_register(&chip_demo_gpio_driver); return err;
}/* 3. 有入口函數(shù)就應(yīng)該有出口函數(shù):卸載驅(qū)動程序時(shí),就會去調(diào)用這個(gè)出口函�? * 卸載platform_driver*/
static void __exit led_exit(void)
{printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);platform_driver_unregister(&chip_demo_gpio_driver);
}/* 7. 其他完善:提供設(shè)備信息,自動創(chuàng)建設(shè)備節(jié)點(diǎn) */module_init(led_init);
module_exit(led_exit);MODULE_LICENSE("GPL");ubuntu@ubuntu2004:~/DongshanPI-Vision-Example/led_drv$ cat ledtest.c #include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>/** ./ledtest /dev/100ask_led0 on* ./ledtest /dev/100ask_led0 off*/
int main(int argc, char **argv)
{int fd;char status;/* 1. 判斷參數(shù) */if (argc != 3) {printf("Usage: %s <dev> <on | off>\n", argv[0]);return -1;}/* 2. 打開文件 */fd = open(argv[1], O_RDWR);if (fd == -1){printf("can not open file %s\n", argv[1]);return -1;}/* 3. 寫文件 */if (0 == strcmp(argv[2], "on")){status = 1;write(fd, &status, 1);}else{status = 0;write(fd, &status, 1);}close(fd);return 0;
}ubuntu@ubuntu2004:~/DongshanPI-Vision-Example/led_drv$ cat Makefile # 1. 使用不同的開發(fā)板內(nèi)核時(shí), 一定要修改KERN_DIR
# 2. KERN_DIR中的內(nèi)核要事先配置、編譯, 為了能編譯內(nèi)核, 要先設(shè)置下列環(huán)境變量:
# 2.1 ARCH, 比如: export ARCH=arm64
# 2.2 CROSS_COMPILE, 比如: export CROSS_COMPILE=aarch64-linux-gnu-
# 2.3 PATH, 比如: export PATH=$PATH:/home/book/100ask_roc-rk3399-pc/ToolChain-6.3.1/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin
# 注意: 不同的開發(fā)板不同的編譯器上述3個(gè)環(huán)境變量不一定相同,
# 請參考各開發(fā)板的高級用戶使用手冊KERN_DIR = /home/ubuntu/DongshanPI-Vision/br2-canaan-k510/dongshanpi-vision_defconfig/build/linux-origin_master/all:make -C $(KERN_DIR) M=`pwd` modules $(CROSS_COMPILE)gcc -o ledtest ledtest.c clean:make -C $(KERN_DIR) M=`pwd` modules cleanrm -rf modules.orderrm -f ledtest# 參考內(nèi)核源碼drivers/char/ipmi/Makefile
# 要想把a(bǔ).c, b.c編譯成ab.ko, 可以這樣指定:
# ab-y := a.o b.o
# obj-m += ab.oobj-m += leddrv.oubuntu@ubuntu2004:~/DongshanPI-Vision-Example/led_drv$