前往: 導覽, 搜尋

RK3399 Linux Manual

目錄

編譯Linux+QT

安裝依賴包

使用如下命令安裝所需的軟體包:

sudo apt-get update
sudo apt-get install git-core gnupg flex bison gperf libsdl1.2-dev libwxgtk3.0-dev build-essential zip curl zlib1g-dev gcc-multilib g++-multilib genromfs libc6-dev-i386 libncurses5-dev x11proto-core-dev libx11-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip gperf lsb-core lib32z1-dev lib32ncurses5-dev lzop

編譯uboot

說明:QT系統使用的uboot與內核與安卓完全相同,如果編譯過android的uboot和內核,則本小節步驟可以省略。

在android源碼目錄下執行如下命令編譯uboot,編譯完成後映像文件RK3399MiniLoaderAll_V1.05.bin(因版本不同,名稱不一定相同)以及uboot.img會釋放到out/release目錄。

./mk.sh     -u

編譯android內核

說明:QT系統使用的uboot與內核與安卓完全相同,如果編譯過android的uboot和內核,則本小節步驟可以省略。

在android源碼目錄下執行如下命令編譯linux內核,編譯完成後映像文件kernel.img、resource.img會釋放到out/release目錄。

./mk.sh     -k

編譯文件系統

在android源碼目錄下執行如下命令編譯linux映像文件,編譯完成後linux映像文件linux-rootfs.img會釋放到out/release目錄。

./mk.sh     -b

在執行./mk.sh -b編譯buildroot時,默認編譯會少一些插件或庫,會彈出一些錯誤信息。

Rk3288-buildroot-git.png

該提示信息表明編譯需要git包,執行如下指令安裝:

sudo  apt-get  install  git

Rk3288-buildroot-libc++.png

該提示表明標準的C++庫沒有安裝,執行如下指令安裝:

sudo apt-get install lib32stdc++-4.9-dev

Rk3288-buildroot-libz.png

該提示表明缺少libz庫,執行如下指令安裝:

sudo apt-get install lib32z1

再執行./mk.sh -b指令即可正常編譯了。編譯完成後,最終打包好的文件系統linux-rootfs.img存放在out/release目錄下。它包含了QT5.6的標準庫,以及一些常用的QT示例。

生成update-linux.img文件系統

在android源碼目錄下執行如下命令生成單一android映像文件update-linux.img:

./mk.sh     -U

update-linux.img為整個QT系統升級文件的單一映像,包括了uboot,內核,文件系統等。注意,生成update-linux.img的先決條件是已經成功編譯了uboot,內核和linux文件系統,缺一不可。


燒寫linux QT映像

Windows下燒寫映像文件

驅動安裝

解壓光碟tools\x3399燒寫工具\windows目錄下的DriverAssitant_v4.5.zip文件,打開「DriverInstall.exe」,點擊「驅動安裝」,提示安裝驅動成功即可。

399 × 192px
533 × 257px

注意事項:

1.目前支持的作業系統包括:XP,Win7_32,Win7_64,Win8_32,Win8_64。

2.XP系統在驅動安裝完後,若還提示「發現新設備」, 安裝驅動時選擇「自動安裝」。

3.若之前已經安裝過老版本驅動,請先點擊「驅動卸載」後再進行「驅動安裝」。

生成統一固件update-linux.img

我們已經在mk腳本中集成了生成統一固件的方法,在編譯linux文件系統時(./mk.sh -b -U),會自動生成update-android.img,並釋放到out/release目錄。

燒錄固件update-linux.img

解壓光碟tools\x3399燒寫工具\windows目錄下的AndroidTool_Release_v2.38.zip文件,得到AndroidTool_Release_v2.38文件夾,打開AndroidTool.exe,選擇「升級固件」選項卡,點擊「固件」,在彈出窗口中選擇已經生成的update-linux.img文件,如下圖所示。

905 × 456px

工具配置好後,插上開發板的TypeC線、串口線以及5V DC電源線,按下RECOVERY(VOL+)鍵不放的同時,長按POWER鍵開機,在串口終端會有如下列印:

1,075 × 706px

當uboot檢測到RECOVERY鍵按下時,會有「rockusb key pressed」的列印提示,這時,在燒錄工具界面會提示發現一個LOADER設備,然後點擊升級,即可開始升級過程(註:如果提示發現一個ADB設備,點擊切換按鈕切換成LOADER設備即可)。

905 × 456px

點擊升級,稍等片刻,燒寫成功界面如下:

905 × 456px

多設備升級固件update-linux.img

該工具適合用戶批量刷機,可以同時給多台設備燒錄固件。

解壓光碟tools\x3399燒寫工具\windows目錄下的FactoryTool-v1.42e.rar文件,打開FactoryTool.exe,點擊「固件」選擇update-android.img,勾選「升級」,點擊「啟動」,如下圖所示:

步驟1 點擊固件,選擇需要使用的update-linux.img;

步驟2 點擊啟動(選擇升級按鈕);

步驟3 連接開發板USB、DC電源,按下recovery鍵(對應VOL+鍵),對應USB口發現設備,並實現自動升級;然後重複步驟3即可同時升級第二台、第三台設備,升級成功或者失敗的設備會在兩邊的列表中列出,移除成功或者失敗的設備後可以繼續連接需要升級的設備。

998 × 753px

linux下燒寫映像文件

生成固件update-linux.img

我們已經在mk腳本中集成了生成統一固件的方法,在編譯android文件系統時(./mk.sh -s),會自動生成update-linux.img,並釋放到out/release目錄。

燒錄固件update-linux.img

工具路徑:tools\x3399燒寫工具\linux\ Linux_Upgrade_Tool_v1.24.zip

在升級之前將update-linux.img拷貝到upgrade_tool相同目錄下,運行upgrade_tool(需要sudo)

work@ubuntu:~/3288/Linux_Upgrade_Tool_v1.2/cp rockdev/update.img .
work@ubuntu:~/3288/Linux_Upgrade_Tool_v1.2$ sudo ./upgrade_tool 

執行結果如下圖,發現設備列表,輸入要升級的DevNo(設備號)選擇設備: DevNo.png

選擇設備後彈出工具使用菜單如下圖,左側是功能描述,右側是命令語法,升級相關操作都在upgrade command列表下,忘記命令語法可以輸入H進行查看,清屏輸入CS,退出按Q。

DevNo1.png

  • CD 命令: 選擇設備, 當執行的命令有包含設備重啟操作時, 需重新選擇設備,當改變操作設備時需重新選擇
  • SD 命令:msc 切換到 rockusb 升級模式。 當切換執行成功後, 需要重新選擇設備
  • UF 命令:升級完整 update.img 固件,當執行成功後需要重新選擇設備
  • UL 命令:升級 loader 功能,當執行成功後需要重新選擇設備
  • DI 命令:下載單獨 image 鏡像到指定扇區,例如升級 kernel.img 或者 system.img 都可以

直接使用此功能.例如下載 kernel.img: DI -k kernel.img parameter //如果之前通過 DI 下 載過 parameter,則再下載 kernel.img 時就可以不用指定最後的 parameter 參數

  • DB 命令:下載 boot,在 maskrom狀態下,可以通過此功能, 讓 maskrom設備進行 Rockusb協議通訊
  • EF 命令:擦除整個 nandflash
  • LF 命令:低格保留塊後面區域,只有在 loader 模式下使用

執行uf update-linux.img開始更新固件,下圖為更新過程截圖:

Rockusb>uf update-linux.img

DevNo2.png


備註:也可通過配置config.ini文件配置升級映像文件,只需輸入UF即可升級,請用戶自行嘗試。

使用upgrade_tool指令燒寫映像

上一節我們介紹了通過upgrade_tool燒寫統一固件update-linux.img的方法,熟悉三星平台的開發者會發現,這種方法並不是很高效,真正操作起來,它遠沒有fastboot工具來的迅速。其實,upgrade_tool工具同樣支持類似於fastboot的燒寫方式。

為了燒寫方便,可以在mk腳本中,默認在編譯系統時,將燒寫工具upgrade_tool拷貝到out/release目錄。

第一步:打開串口終端,並打開minicom,用於適時監控串口調試信息;

第二步:按住RECOVERY鍵,連接USB OTG線和電源線,這時uboot列印信息將會提示已經進入USB下載模式。如果接通電源後沒來得及按住RECOVERY鍵,在按住RECOVERY鍵的同時,再按下復位鍵即可。

第二步:打開第二個串口終端,進入out/release目錄;

第三步:在out/release目錄下敲擊如下指令,燒寫相應的映像。

 sudo upgrade_tool  di  –k  <nowiki>kernel.img(烧写内核)

 sudo upgrade_tool  di  –s  system.img(烧写文件系统)

 sudo upgrade_tool  di  resource  resource.img(烧写资源文件)

 sudo upgrade_tool  di  –r recovery.img(烧写急救文件)

 sudo upgrade_tool  ul  RK3399MiniLoaderAll_V1.05.bin (烧写bootloader)

 sudo upgrade_tool  di  uboot  uboot.img  parameter.txt(烧写uboot,必须指定parameter.txt)

 sudo upgrade_tool  di  trust   trust.img   parameter.txt(烧写trust,必须指定parameter.txt)

 sudo upgrade_tool  uf  update-linux.img(烧写统一固件)
 

Rkflashkit

rkflashkit 有圖形界面,後加了命令行支持,更是好用。

work@ubuntu~/rktool$ sudo apt-get install build-essential fakeroot

work@ubuntu~/rktool$ git clone <nowiki>https//github.com/linuxerwang/rkflashkit

work@ubuntu~/rktool$ cd rkflashkit

work@ubuntu~/rktool$ ./waf debian

work@ubuntu~/rktool$ sudo apt-get install python-gtk2

work@ubuntu~/rktool$ sudo dpkg -i rkflashkit_0.1.4_all.deb
 

注意:rkflashkit_0.1.4_all.deb會因版本更新,版本數字可能會有所變化,如果執行失敗,執行ls命令查看下即可。

work@ubuntu~/rktool/$ sudo rkflashkit

如下是圖形界面,在Devices下選擇設備,選擇要燒寫的分區和對應的映像文件,點擊Flash image即可。

947 × 684px

該工具也支持命令行,使用help命令查看使用方法

 work@ubuntu~/rktool/rkflashkit$ rkflashkit --help

 Usage<cmd<nowiki>> [args] [<cmd> [args]...]



 part                              List partition

 flash @<PARTITION> <IMAGE FILE>   Flash partition with image file

 cmp @<PARTITION> <IMAGE FILE>     Compare partition with image file

 backup @<PARTITION> <IMAGE FILE>  Backup partition to image file

 erase  @<PARTITION>               Erase partition

 reboot                            Reboot device



 For example, flash device with boot.img and kernel.img, then reboot



  sudo rkflashkit flash @boot boot.img @kernel.img kernel.img reboot

 work@ubuntu~/rktool/rkflashkit$ 

QT文件系統的搭建

前面章節的介紹,都是九鼎創展工程師已經移植的文件系統包,如果換一個平台,一切從零開始,我們如何構建linux QT文件系統呢?本章節將會帶您一步步搭建linux文件系統。

下載buildroot

在buildroot官網下載最新的buildroot包,下載地址如下:

[http//buildroot.uclibc.org/download.html http//buildroot.uclibc.org/download.html]

本文使用的是buildroot 2016.02,用戶下載最新版本與本文介紹版本配置可能略有不同,根據下文配置適當修改即可。

配置buildroot

將下載的buildroot包拷貝到ubuntu系統用戶目錄並解壓,得到buildroot目錄,通過命令終端進入buildroot目錄,執行make menuconfig,進入配置界面:

1,456 × 938px

進入Target options菜單,

1,456 × 938px

在Target Architecture中選擇ARM(little endian),在Target Binary Format中選擇ELF,退回上一級,進入Toolchain目錄,按下圖配置:

1,456 × 938px

退回上一級,進入System configuration目錄,作如下配置:

1,456 × 938px

退回上一級,進入Target packages目錄,再進入Graphic libraries and applications (graphic/text)目錄,選擇Qt5,如下圖所示:

1,456 × 938px

注意不要選Qt,它對應QT4.8版本。進入Qt5菜單,按下圖配置:

1,456 × 938px

1,456 × 938px

退回menuconfig的開始界面,進入Filesystem images菜單,作如下配置:

1,456 × 938px

到此,buildroot配置完成。默認配置保存在buildroot根目錄的.config中,我們可以備份該配置文件,以防後續配置出錯。執行如下指令備份配置文件:

   cp  .config  x3399_defconfig

編譯buildroot

配置完成後,執行make指令即可編譯buildroot了。編譯buildroot會會依賴一些第三方插件和庫,在第一章的編譯文件系統小節中,已經給出了需要安裝的包,在編譯之前需要提前安裝,否則會報錯。 編譯完成後,文件系統映像rootfs.ext2會生成到output/images目錄。

測試QT5.1默認示例

將uboot,內核,文件系統燒寫進開發板,進入linux文件系統後,可以進入/usr/lib/qt/examples目錄測試QT示例。

進入gui/analogclock目錄,執行analogclock文件,指令如下:

./analogclock &

這時,在開發板上可以看到有一個時鐘圖案被繪製出來(會覆蓋默認的QTTEST程序),如下圖所示:

QT5.1-default.png

進入gui/rasterwindow目錄,執行rasterwindow文件,指令如下:

./ rasterwindow &

這時,在開發板上可以看到一個標註有QWindow的圖案被繪製出來,如下圖所示:

QT5.1-default1.png

進入qpa/windows目錄,執行windows文件,指令如下:

./windows &

這時,在開發板上可以看到有三幅圖案被繪製出來,如下圖所示:

QT5.1-default2.png

進入sql/drilldown目錄,執行如下指令:

./drilldown &

這時,在開發板上可以看到有四個QT畫面被繪製出來,如下圖所示:

QT5.1-default3.png

進入sql/books目錄,執行如下指令:

./books &

這時,在開發板上可以看到有一個對話框被繪製出來,如下圖所示:

QT5.1-default4.png

進入sql/masterdetail目錄,執行如下指令:

./masterdetail &

這時,在開發板上可以看到有一個對話框繪製出來,如下圖所示:

QT5.1-default5.png

默認buildroot編譯出了很多示例,這裡不帶一一列舉,有興趣的讀者可以自行嘗試。

安裝QT Creator

通常我們使用QT Creator創建基於QT的工程。在QT官網下載最新的QT安裝包,下載地址如下:

http://download.qt.io/official_releases/qt/

打開連結頁面如下:

QT-Creator-install.png

點擊5.1,下載最新的安裝包,得到名為qt-linux-opensource-5.1.1-x86-offline.run的文件,將它拷貝到ubuntu的用戶目錄,使用如下指令安裝:

./ qt-linux-opensource-5.1.1-x86-offline.run

安裝完成後,QT Creator也就安裝完成了。

編譯QT Creator默認示例

點擊ubuntu圖標,輸入qt,將會查找含有qt的文件,同時,安裝好的QT Creator也會被列出來,如下圖所示:

Build-QT-Creator-default.png

點擊QT圖標,QT Creator將會運行,如下圖所示:

Build-QT-Creator-default1.png

默認QT的配置是針對X86架構的,這時編譯出來的示例只能在PC機上運行。我們打開Image Composition Example示例,它是一個圖片疊加顯示的示例,找到該示例,單擊即可。打開後的界面如下:

Build-QT-Creator-default2.png

點擊左下腳綠色的三腳箭頭,開始編譯工程。在Compile Output欄會顯示編譯的整個過程。編譯完成後,提示如下:

Build-QT-Creator-default3.png

編譯完成後,編譯出來的映像會自動運行,一個疊加的蝴蝶圖像界面顯示出來了,界面如下:


Build-QT-Creator-default4.png

下面我們將該示例編譯到開發板上運行。使用QT Creator打開上面的示例工程,如下圖所示:

Build-QT-Creator-default5.png

選擇Projects一欄,可以看到最頂端的框圖1,顯示Desktop Qt 5.1.1 GCC 64bit,表明它通過64位的GCC編譯,框圖2表明在debug模式下編譯,相對release模式,debug模式下含有大量調試信息,編譯出來的映像會比較大。通常發布映像時,我們選擇release模式。框圖3指定了編譯的路徑。框圖4指定了qmake和交叉編譯工具。框圖5為調試按鍵,第一個用於選擇編譯模式為debug或release,第二個為運行按鈕,第三個為單步調試按鈕,第四個為編譯按鈕。框圖6為一些輸出信息,如Compile Output,會給出整個編譯的信息。

在框圖1中,點擊Tools->Options,如下圖:

Build-QT-Creator-default6.png

在左測對話框中選擇Build & Run,在後邊選擇Qt Versions,默認Manual為空,Auto-detected選擇的QT5.1默認的qmake,它將運行在X86平台的linux系統上,因此我們要手動添加在ARM平台上運行的qmake。

在buildroot編譯文件系統時,我們選中QT5後,將會在buildroot的output/host/usr/bin目錄生成支持ARM平台的qmake,點擊Add,指向該路徑的qmake:

Build-QT-Creator-default7.png

點擊Open,即在Manual中添加了支持ARM平台的qmake。再選擇Compilers一欄,如下圖所示:

Build-QT-Creator-default8.png

默認Manual為空,Auto-detected為支持X86 32位和64位的GCC,這將直接導致編譯出來只能在PC機上運行。點擊Add,選擇GCC,如下圖所示:

Build-QT-Creator-default9.png

在Name中重命名,以區別ARM和PC平台,如我們命名為GCC-ARM-LINUX,它將會直接顯示在前面QT工程界面的框圖1中,到時我們編譯QT工程時,能夠一目了然,編譯出來的到底是PC平台還是ARM平台。在Compiler path中指定交叉編譯工具,在buildroot中默認已經自動下載並安裝了交叉編譯工具,我們指定到如下路徑即可:

buildroot/output/host/opt/ext-toolchain/bin/arm-linux-gnueabihf-g++

設置完成後,點擊OK,完成設置。

再回到QT的工程界面,我們發現框圖1中的配置仍然針對PC機,點擊框圖1中的Manage Kits,如下圖所示:

Build-QT-Creator-default10.png

注意,這時默認Manual仍然為空,點擊Add,會彈出一個有很多選項的對話框,我們按如下方式配置:

Build-QT-Creator-default11.png

這裡的Name,我們可以點擊Qt Versions,選擇Manual中的qmake,下面就會有名稱出來,將它拷貝過來即可,如下圖所示:

Build-QT-Creator-default12.png

在框圖一中,點擊設置編譯環境的下拉箭頭,如下圖所示:

Build-QT-Creator-default13.png

選擇Change Kit->Qt5.1.1(System),更改後的界面如下:

Build-QT-Creator-default14.png

在框圖2中選擇release,更改後的界面如下:

Build-QT-Creator-default15.png

到此,配置完畢,點擊框圖5中的編譯按鈕,在Compile Output中可以看到編譯信息如下:

Build-QT-Creator-default16.png

這時,在框圖2中指定的目錄中已經生成了能夠在ARM平台運行的映像了,如下圖所示:

Build-QT-Creator-default17.png

將該文件拷貝到x3399開發板上運行,可以看到美麗的蝴蝶圖案顯示出來了。

Build-QT-Creator-default18.png

qttest測試程序

使用QT_demo測試LED燈

led

點擊上面的四盞燈可以看到開發板led的燈的亮和滅。

使用QT_demo測試蜂鳴器

進入QT5.6.1系統後,默認會運行我們自主編寫的測試demo,測試界面如下:

1,024 × 600px 按住Beep鍵時,蜂鳴器鳴叫,鬆開時,蜂鳴器停止鳴叫。

使用QT_demo調節背光

測試界面如下:

1,024 × 600px

滑動圓形滑輪,可對開發板背光進行亮暗調節。

使用QT_demo測試按鍵

測試界面如下:

1,024 × 600px

按下開發板任一獨立按鍵,圖中界面即會顯示相應鍵值,同時,按下時提示[keydown],抬起時提示[keyup]。

使用QT_demo測試音頻

將喇叭或耳機接到開發板的對應接口,點擊下圖中的Play Sound按鈕,會播放測試歌曲:

QTtest-demo5-audio.png

使用QT_demo測試觸控螢幕

進入如下界面:

ts

單擊黃色矩形框,界面會進入全屏模式,這時我們可以任意書寫來測試觸控螢幕了,測試示例圖片如下:

ts1

使用QT_demo測試網絡

將網線連接開發板的有線乙太網接口,點擊界面中的Network Test按鈕,如果網絡已經連通,則會添加DNS,如果沒有連通,則會提示相應錯誤,如下圖所示:

1,024 × 600px

連接網線後測試時,會有如下提示:

1,024 × 600px

使用QT_demo測試TF卡

tf

tf 將SD卡插入開發板的SD卡槽,點擊Tfcard Test,界面上會列出SD卡中的內容。

tf1

使用QT_demo測試重啟

點擊Reboot按鈕,開發板將重啟。

reboot

使用QT_demo測試關機

點擊Poweroff按鈕,開發板將會關機。

poweroff



linux底層開發示例

播放mp3

註:linux系統預設登錄帳戶為root,密碼:123456

將存放有mp3文件的TF卡插到開發板的任意卡槽,使用如下命令掛載TF卡:

<nowiki>
 cd  /

 mkdir  sdcard

 mount  /dev/mmcblk1p1  /sdcard

 cd  sdcard

使用如下命令播放:

./mplayer  *.avi
./mplayer  *.mp3

連接串口後,可以通過PC鍵盤的0或9調節音量。也可以使用madplayer播放音樂。

在後台運行程序

在上一節中給出了播放音樂的示例,但是這時候mplayer已經占據了終端控制台,在音樂播放完之前,我們無法再使用終端控制台了。又比如我們開發一款產品時,就需要在啟動文件系統後運行一個應用程式,如果運行了一個程序,終端控制台就被占用了,那將極大的限制我們的功能。為止,我們可以將程序放在後台運行。使用方法很簡單,我們只需在執行的指令後面添加一個」&」即可。如播放音樂時使用如下命令:

./mplayer  *.mp3  &

中止程序的運行

中止程序的運行有多種方式,最直接的方式就是直接按ctrl+c。如前面我們正在播放一段音頻文件,我們可以按ctrl+c退出程序。但是如果程序在後台運行,那麼我們按ctrl+c就不管用了。這時我們可以使用kill命令。

kill+===PID===
kill+===文件名===

螢幕抓圖

本文檔中的各個圖片,都是採用gsnap這個工具進行抓圖的。進入QT圖形界面後,我們能在LCD上看到豐富多彩的人機互動界面。通過gsnap可以抓取到圖形界面精彩的瞬間。在控制台終端輸入如下命令:

gsnap  test_pic.jpg  /dev/fb0

這時在當前目錄將會保存test_pic.jpg圖像文件。詳細的gsnap移植步驟在後面會有詳細描述。

掛載TF卡

進入QT圖形界面後,在命令終端會有控制台出現,這時可以通過控制台查看文件系統的內容。將TF卡插到開發板的任意卡槽,串口終端會有如下提示:

1,899 × 299px

這時在文件系統的/dev目錄將會自動生成一個名叫mmcblk1p1的塊設備文件。它就是對應的TF卡的設備文件,使用如下命令掛載TF卡到/sdcard目錄:

mkdir  /sdcard
mount  /dev/mmcblk1p1  /sdcard

查看/scard目錄下的內容,即是我們TF卡中的內容,如下圖所示:

1,905 × 378px

掛載U盤

進入QT圖形界面後,在命令終端會有控制台出現,這時可以通過控制台查看文件系統的內容。插入U盤後,串口終端會有如下提示:

1,882 × 304px

這時在文件系統的/dev目錄將會自動生成一個名叫sda4的塊設備文件。它就是對應的U盤設備文件,使用如下命令掛載U盤到/udisk目錄:

mkdir  /udisk
mount  /dev/sda4  /udisk

查看/udisk目錄下的內容,即是我們U盤中的內容,如下圖所示:

1,873 × 241px

保存系統時鐘

Linux可以使用date指令更改時間日期。例如:

date  -s  201607211433  设置为2016年7月21日14:33分
hwclock  -w  把刚设置的时间存入RTC寄存器
hwclock  -s   恢复linux系统时钟为RTC寄存器值,一般将该指令放在rcS中开机自动执行。

1,123 × 139px

掉電保存數據到flash

由於本系統採用了ext4文件系統,因此可以很方便的保存數據,確保掉電後數據不丟失。如我們從U盤中拷備一首歌曲到/root目錄:

cp /udisk/muyangqu.mp3 /

重啟開發板,我們發現在root目錄仍然存在剛才拷備的這首歌曲,說明掉電後數據並沒有丟失。

設置開機自動運行程序

藉助啟動腳本可以設置各種程序開機後自動運行,這點很類似於WINDOWS的Autobat自動批處理文件。啟動腳本位於/etc/init.d/rcS中,我們可以將自己想要開機運行的程序或是開機執行的指令放在rcS裡面。比如我們想製作一個簡單的開機音樂,我們就完全可以在rcS中添加如下語句:

./mplayer  start.mp3  &

這時,開機後就會播放名叫start.mp3的音樂了。注意start.mp3需要在當前執行指令所在目錄。

查看開發板內存信息

X3399開發板默認配置2GB LPDDR3 SDRAM,在uboot啟動時,列印信息上會給出RAM大小信息:

1,096 × 570px

在進入文件系統後,可以通過cat命令查詢Linux系統分配到的SDRAM大小。執行如下命令:

cat  /proc/meminfo
1,106 × 525px

linux應用開發示例

本手冊給出的所有應用程式全部在九鼎創展x3399開發板上運行,這裡僅給出了一些比較基礎,常用的應用程式,旨在為用戶打開Linux世界奇妙的大門,用戶定能舉一反三,編寫出屬於自己的更加豐富完美的程序。

聲明:以下所有應用程式全部為九鼎創展科技有限公司原創作品,所有內容全經我們嚴格測試,建議用戶按照下面步驟動手編譯一遍,以增強自己的理解,不推薦直接使用我們提供好的文件。另外,敬請商業人士勿侵犯版權。

Hello World

第一步:生成可執行文件

在x3399_marshmallow目錄新建app-ex目錄,在app-ex目錄新建hello目錄,然後在hello目錄下新建hello.c和makefile兩個文件:

vim  hello.c
307 × 109px

這是一個最基礎的應用程式,如果我們聲明了交叉編譯工具(export PATH=/home/lixu/projects/3399/x3399_marshmallow/buildroot/output/host/opt/ext-toolchain/bin$PATH)(這裡我們用到buildroot中的交叉編譯工具),可以直接敲入命令進行編譯(由於開發板環境缺少c庫,編譯時需要加上-static靜態編譯):

arm-linux-gcc-4.4.3 -o hello hello.c -static

說明:由於開發板文件系統缺少標準函數庫,編譯時加上-static選項;使用的編譯器為aarch64-linux-gnu-gcc。

編譯完成後,在當前目錄會生成hello可執行文件,我們可以使用file命令查詢執行文件是否為ARM體系文件:

1,123 × 74px

第二步:將可執行文件下載到開發板運行

比較常用的方式有以下四種:

  • 通過串口和sz/rz工具
  • 複製到存儲媒介,如SD卡,U盤等
  • 通過NFS掛載文件系統,這時不用將可執行文件拷備到開發板了,推薦調試使用這種方式!
  • 通過ftp傳輸

這裡介紹第二種方法,以TF卡為例,其他方法請讀者自行嘗試。

將生成的hello文件拷備到TF卡,再將TF卡插入開發板的TF卡接口,將TF卡mount到/mnt目錄:

cd  /
mount  /dev/mmcblk1p1  /mnt

進入mnt目錄,可以看到剛才拷貝的hello文件了:

948 × 85px

運行hello:

./hello

列印信息如下:

967 × 135px

表明,程序已經成功運行。

前面編譯文件我們需要通過手敲命令執行,我們可以通過編寫makefile來代替手敲的動作。

在hello目錄下新建makefile文件:vim makefile

hello
   aarch64-linux-gnu-gcc –o hello hello.c –static
clean
   rm –f hello *.o

直接在hello目錄下敲make就可以生成hello文件。運行的效果和前面的完全相同。

數學函數庫調用

建立程序編譯路徑:

<nowiki>
 mkdir  math

 cd  math

 vim  math.c

編輯如下內容:

 <nowiki>include <stdio.h>

 include <stdlib.h>

 include <math.h>


int main(void)

{

    double a=9.0;

    printf("sqrt(%f)=%f\n",a,sqrt(a));



    return 0;

}

編輯makefile文件,內容如下:

<nowiki>
OBJS=math.o

LDFLAGS = -lm -static

CC = yourtoolchainpath/bin/aarch64-linux-gnu-gcc



math${OBJS}

    ${CC} -o $@ $^ $(LDFLAGS) 



clean

    rm -f math *.o

執行make,將生成的可執行文件math下載到開發板上運行,如下圖所示:

958 × 99px

多線程編程示例

建立程序編譯路徑:

<nowiki>
 mkdir  thread

 cd  thread

 vim  thread.c

編輯如下內容:

<nowiki>include<stddef.h>

include<stdio.h>

include<unistd.h>

include"pthread.h"

void function1(void);

void function2(void);

int func_flag=0;

pthread_mutex_t mutex;



main()

{

    pthread_t reader;

    pthread_mutex_init(&mutex,NULL);

    pthread_create(&reader,NULL,(void*)&function1,NULL);

    function2();

}



void function2(void)

{

    while(1)

    {

        pthread_mutex_lock(&mutex);

        if(func_flag==0)

        {

            printf("excute function2.\n");

            func_flag=1;

        }

        pthread_mutex_unlock(&mutex);

    }

}



void function1(void)

{

    while(1)

    {

        pthread_mutex_lock(&mutex);

        if(func_flag==1)

        {

            printf("excute function1.\n");

            func_flag=0;

        }

        pthread_mutex_unlock(&mutex);

    }

}

編輯makefile文件,內容如下:

<nowiki>
OBJS=thread.o

LDFLAGS = -lpthread -static

CC = yourtoolchainpath/bin/aarch64-linux-gnu-gcc



thread${OBJS}

    ${CC} -o $@ $^ $(LDFLAGS) 



clean

    rm -f thread *.o

執行make,將生成的可執行文件thread下載到開發板上運行,如下圖所示:

821 × 125px

多進程編程示例

在Linux下通用調用fork函數創建新的進程。調用fork時,系統將產生一個與當前進程相同的進程。它與原有的進程具有相同的數據,連接關係和在程序同一處執行時的連續性。通常將原有的進程叫父進程,新創建的進程叫子進程。

fork調用將分兩次返回,從父子進程返回。進程創建語法如下:

 <nowiki>include <unistd.h>

 pid_t  pid;

 pid = fork();

如果pid返回0,表示說明從子進程返回,否則從父進程返回,此時返回的是進程的ID號。我們可以通過getpid()函數來獲得進程的ID號。

首先建立程序編譯目錄:

<nowiki>
 mkdir  process

 cd  process

 vim  process.c

編輯如下內容:

<nowiki>include<stdio.h>

include<unistd.h>

include<sys/types.h>



main()

{

    pid_t pid;

    pid=fork();

    if (pid<0)

    {

        printf("fork is error!\n");

        return 1;

    }

    else if (pid == 0)

    {

        while (1)

        {

            printf("the child process is running now.pid=%d\n",getpid());

            sleep(1);//linux延时函数,延时1秒

        }

    }

    else

    {

        while (1)

        {

            printf("the perent process is running now.pid=%d\n",getpid());

            sleep(1);

        }

    }

    return 0;

}

編輯makefile文件,內容如下:

<nowiki>
OBJS=process.o

LDFLAGS = -lpthread -static

CC = yourtoolchainpath/bin/aarch64-linux-gnu-gcc



process${OBJS}

    ${CC} -o $@ $^ $(LDFLAGS)



clean

    rm -f process *.o

執行make編譯,將生成的可執行文件下載到開發板運行,仔細觀察串口監控信息:

967 × 210px

makefile編程示例

在上面的很多測試程序實例中,我們都編寫了一些簡單的makefile文件。下面我們介紹makefile的基本的語法。

makefile就好比批處理文件,裡面寫了一系列集合,當運行make編譯時,便會按makefile提供的命令及順序完成編譯。

這裡我們給出三個文件:main.c,func.c,func.h。主程序在main.c中,在main.c中程序會調用func.c中的函數,func.c中的函數又會用到func.h中定義的變量。

main.c文件內容如下:

<nowiki>include "func.h"



extern int fd;



int main(int argc,char **argv)

{    

    fd = open(DEVICE_NAME,0);//打开设备

    if(fd == -1)

    {

        printf("open device %s error \n",DEVICE_NAME);

        return 0;

    }

    else

    {

        printf("open device %s ok! \n",DEVICE_NAME);

    }

    

    while(1)

    {

        glint_led();

    }

    close(fd);

    return 0;

}

該文件會調用glint_led ()函數,這個函數在func.c中。func.c的內容如下:

<nowiki>include "func.h"



void glint_led(void)

{

    ioctl(fd,LED_ON);

    sleep(1);

    ioctl(fd,LED_OFF);

    sleep(1);

}

這裡僅僅是一個讀取按鍵的函數,供main函數調用。該函數需要用到了一些變量,另外還需要一些頭文件支持,這些都存放在func.h中,其內容如下:

<nowiki>include <stdio.h>

include <stdlib.h>

include <unistd.h>

include <sys/ioctl.h>



define DEVICE_NAME    "/dev/vib"

define LED_ON 0x11

define LED_OFF 0x22



int fd;

很明顯,這是基於LED測試程序,人為的分成的三個文件。我們的目的不在於分離代碼,而在於學習makefile的編寫方法。

當不使用makefile時,我們使用如下指令編譯:

aarch64-linux-gnu-gcc-gcc -o mkfile main.c func.c

編譯完成後,將會生成可執行文件mkfile。將它下載到開發板上運行,和前面的按鍵測試完全相同。現在我們嘗試編寫第一個屬於自己的makefile

<nowiki>
mkfilemain.o func.o

    aarch64-linux-gnu-gcc -o mkfilemain.o func.o

main.omain.c

    aarch64-linux-gnu-gcc -c main.c -o main.o

func.ofunc.c func.h

    aarch64-linux-gnu-gcc -c func.c -o func.o

    

clean

    rm -f mkfile *.o

執行make後,編譯器會依次編譯main.c和func.c文件,生成main.o和func.o文件,最後將這兩個.o文件打包到可執行文件mkfile中。這時將mkfile文件下載到開發板運行,效果和前面的是一樣的。我們可以執行make clean指令清除生成的.o文件和可執行文件。

makefile具有很強大的推理功能,我們完全可以簡化上面的代碼。優化後的代碼如下:

<nowiki>
OBJS=main.o func.o

CC= aarch64-linux-gnu-gcc



mkfile${OBJS}

    ${CC} -o $@ $^

main.o

func.ofunc.h



clean

    rm -f mkfile *.o

可見,這次比上面的完整版要簡化多了。前面通過變量OBJS定義了要編譯的源文件,變量CC給出了交叉編譯工具。$@ 表示目標文件的全稱,即mkfile,$^表示所有被依賴的文件,並以空格分開,即main.o func.o。後面的clean為清除指令,執行make clean後會執行 clean後面的指令。需要注意的是,rm指令後面千萬不要使用$@符號來表征我們要刪除的目標文件,因為這時候$@已經不再表示mkfile了,而表示clean。同樣,使用make指令編譯,一樣能夠生成我們需要的目錄文件mkfile。

上面的makefile使用了變量以及預定義變量。第一句即定義了變量OBJS,將它賦值為main.o func.o,第二句定義了變量CC,將它賦值為一個交叉編譯工具定義。引用變量時,通過${*}表示,這裡*表示前面定義的變量。

上面使用了$@和$^兩個預定義變量,GNU make主要有以下七種預定義變量:

$*

不包含擴展名的目標文件名稱

$+

所有的依賴文件,以空格分開,以出現的先後為序,可能包含重複的依賴文件

$<

第一個依賴文件的名稱

$?

所有的依賴文件,以空格分開,這些依賴文件的修改日期比目標的創建日期晚

$@

目標的完整名稱

$^

所有的依賴文件,以空格分開,不包含重複的依賴文件

$%

如果目標是歸檔成員,則該變量表示目標的歸檔成員名稱。例如,如果目標名稱為mytarget.so(image.o),則$@ 為mytarget.so,而$% 為image.o。

對比以上幾種編譯方式,我們不然發現,其實最簡的還是第一種,因為它就一句話就搞定了。那麼在makefile中,我們是否也可以精簡到只有一句話呢?答案是肯定的。我們繼續利用makefile強大的推理功能進行簡化,得到如下makefile代碼:

<nowiki>
OBJS=main.o func.o

CC= aarch64-linux-gnu-gcc



mkfile${OBJS}

    ===${CC} -o $@ $^===



clean

    rm -f mkfile *.o

這次,makefile真正編譯的代碼,就只有上面紅色部分一條指令了。和前面比較,不難發現,單獨對main.c和func.c兩個文件編譯的指令已經去掉了。前面我們提到,makefile具有強大的推理功能,我們在生成目標文件mkfile時,makefile會推理出它需要main.c和func.c兩個文件,因此它首先就會去編譯這兩個文件,最後再執行目標文件的生成。因此我們完全可以將它們省去。

這裡只是makefile的一點基礎,讀者可以藉助於其他書籍對makefile作更深一層的了解。

mplayer移植

有兩種移植mplayer,第一種方法就是直接下載mplayer源碼包,手動配置編譯環境,再通過交叉編譯環境編譯。該方法比較傳統,我們有更方便的方法,直接在buildroot中選中mplayer,再make即可,buildroot會自動下載mplayer源碼包,自動配置編譯環境並編譯。

在buildroot的menuconfig配置選項中,進入Target packages-> Audio and video applications選項,選中mplayer,如下圖所示:

1,366 × 768px

保存退出,在buildroot下直接make,生成文件系統後更新到開發板,mplayer就打包進文件系統了。

madplayer移植

madplayer的移植方法和mplayer的移植方法完全雷同,直接在buildroot中選中madplayer的選項,再make即可。

螢幕抓圖工具gsnap移植

螢幕抓圖的方法有多種,有不少愛好者自己動手寫抓圖小程序。這裡我們使用JPEG庫來處理。具體用到了jpegsrc.v6b.tar.gz和gsnap.tar.gz兩個源碼包(這2個壓縮包請讀者自己到網絡上面下載)。

一:安裝libjpeg

解壓jpeg庫源碼包,進入根目錄:

tar     zxf     jpegsrc.v6b.tar.gz
cd  jpeg-6b

二:配置編譯環境:

<nowiki>
./configure --prefix=/home/lixu/projects/3399/x3399_marshmallow/buildroot/output/host/opt/ext-toolchain --exec-prefix=/home/lixu/projects/3399/x3399_marshmallow/buildroot/output/host/opt/ext-toolchain --target=arm-linux --enable-shared --enable-static



CC=/home/lixu/projects/3399/x3399_marshmallow/buildroot/output/host/opt/ext-toolchain/bin/aarch64-linux-gnu-gcc

AR=/home/lixu/projects/3399/x3399_marshmallow/buildroot/output/host/opt/ext-toolchain/bin/aarch64-linux-gnu-ar rc

AR2=/home/lixu/projects/3399/x3399_marshmallow/buildroot/output/host/opt/ext-toolchain/bin/aarch64-linux-gnu-ranlib

三:配置好之後,make編譯,如果提示缺少libtool文件:

1,292 × 76px

下載libtool-2.2.6a.tar.gz,解壓編譯獲得libtool工具。

1,122 × 47px

再make clean,重複之前的第二步:配置編譯環境。

四:在x3399_marshmallow/buildroot/output/host/opt/ext-toolchain下建立man/man1目錄:

cd  x3399_marshmallow/buildroot/output/host/opt/ext-toolchain
mkdir  -p  man/man1

五:編譯,安裝

make
make  install

這時,在x3399_marshmallow/buildroot/output/host/opt/ext-toolchain/man/man1目錄下將會生成以下文件:

cjpeg.1  djpeg.1  jpegtran.1  rdjpgcom.1  wrjpgcom.1

在x3399_marshmallow/buildroot/output/host/opt/ext-toolchain/lib目錄下生成以下文件:

libjpeg.a  libjpeg.la  libjpeg.so  libjpeg.so.62  libjpeg.so.62.0.0

六:解壓gsnap

tar  zxf  gsnap.tar.gz
cd  gsnap

七:修改makefile

<nowiki>
all

    /home/lixu/projects/3399/x3399_marshmallow/buildroot/output/host/opt/ext-toolchain/bin/aarch64-linux-gnu-gcc -g gsnap.c -ljpeg -o gsnap –static

clean

    rm -f gsnap

八:編譯,得到可執行文件gsnap

make

九:將jpeg庫文件複製到文件系統的lib目錄,注意保持文件的連結屬性

cp  -a  libjpeg.s*  “文件系统路径”/lib

十:將可執行文件gsnap複製到文件系統的sbin目錄

cp  gsnap  “文件系统路径”/sbin

十一:重新製作文件系統,下載到開發板上,使用如下命令即可截獲圖形界面:

gsnap  1.jpg  /dev/fb0

同樣可以將圖片保持為bmp,png等其他格式。