這篇文章介紹這學期我在嵌入式作業系統課程,使用Creator XScale PXA270板子的一些學習筆記與製作final project的一些過程,歡迎各位多多指教~
錯誤訊息:
{standard input}: Assembler messages:
{standard input}:311: Error: register or shift expression expected -- `orr r2,r1,lsl#16'
{standard input}:321: Error: register or shift expression expected -- `orr r3,r1,lsl#16'
{standard input}:329: Error: register or shift expression expected -- `orr r2,ip,lsl#16'
{standard input}:467: Error: register or shift expression expected -- `orr r2,r1,lsl#16'
{standard input}:475: Error: register or shift expression expected -- `orr r3,r0,lsl#16'
make[1]: *** [.obj/release-shared-emb-arm/ftbbox.o] Error 1
解決方式: 開啟ftconfig.h,修改第330行的內容
gedit src/3rdparty/freetype/include/freetype/config/ftconfig.h
修改內容:
錯誤訊息: ../3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h: In function 'int QTWTF::atomicIncrement(volatile int*)':
../3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h:253: error: '__sync_add_and_fetch' was not declared in this scope
../3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h: In function 'int QTWTF::atomicDecrement(volatile int*)':
../3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h:254: error: '__sync_sub_and_fetch' was not declared in this scope
解決方式: 開啟Threading.h,將第251、253、254行變成註解
gedit src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h
修改後內容:
錯誤訊息: ./wtf/Atomics.h: In function 'int WTF::atomicIncrement(volatile int*)':
./wtf/Atomics.h:112: error: '__sync_add_and_fetch' was not declared in this scope
./wtf/Atomics.h: In function 'int WTF::atomicDecrement(volatile int*)':
./wtf/Atomics.h:113: error: '__sync_sub_and_fetch' was not declared in this scope
解決方式: 開啟Atomics.h,將第110、112、113行變成註解
gedit src/3rdparty/webkit/Source/JavaScriptCore/wtf/Atomics.h
修改後內容:
此時的Qt還無法支援觸控輸入,僅能顯示並且透過Linux的支援可以插上鍵盤滑鼠操作
(PS1:在Linux的kernel driver那邊必須開啟TFT LCD的support)
(PS2:在PXA270執行時,一樣要記得設定LD_LIBRARY_PATH,而在執行時若沒特別啟動過Qt server,必須在執行檔名稱後加上-qws的option,忘記時Qt也會提醒你^.<)
背景介紹
Creator XScale PXA270開發版是一塊由新華電腦(microtime)公司出品的模組化XScale/ARM/SoC/FPGA/DSP嵌入式行動通訊發展平台,在此課程與final project主要使用的是"Create XScale‐PXA270 子板"與"MTLCD‐0708048 LCD Module",在Create XScale‐PXA270子板上的為Intel(現在已出售給Marvell)的Xscale系列PXA270處理器,基於ARMv5TE架構指令集,在旁附有SDRAM Memory 64MB、Flash Memory 32MB、SD Card Connectors、RJ45 10/100 Base‐T Ethernet Interface、USB 1.1 Device/Host Port各一、AC97 Audio Codec(Line_in、Mic_in、Headphone)、ADC Interface*4、PWM Interface、CMOS Camera Interface、TFT-LCD Interface、GPIO Interface...等;在軟體功能部分,由新華科技提供了GNU GCC cross compiler toolchain(arm-unknown-linux-gnu-gcc 4.0.2)、Uboot 1.1.5、Linux Kernel 2.6.15.3與patch(提供支援子板上的Ethernet、USB Host、TFT‐LCD(Frame buffer、Touch Screen)、AC97‐Codec...等與母板LED、7‐Seg LED、Key Pad...等的device driver)、rootfs,相關的實驗環境設定可以參考User Guide。
看到以上這麼多的軟硬體介面,別以為這板子有多強,其實這是2006年ASUS P535手機使用的規格了,不禁讓人感嘆科技進步之快阿~
看到以上這麼多的軟硬體介面,別以為這板子有多強,其實這是2006年ASUS P535手機使用的規格了,不禁讓人感嘆科技進步之快阿~
在此附上開發版本尊 |
Qt是自由且開放原始碼的跨平台C++應用程式開發框架。廣泛用於開發GUI程式,也可用於開發非GUI程式,比如控制台工具和伺服器。Qt使用於OPIE、Skype、VLC media player、Adobe Photoshop Elements、VirtualBox 與 Mathematica以及被Autodesk、歐洲太空總署、夢工廠、Google、HP、KDE、盧卡斯影業、西門子公司、富豪集團、華特迪士尼動畫製作公司、三星集團、飛利浦、Panasonic所使用。
*為什麼這篇選用Qt 4.8.6,而不使用最新的Qt 5.5?
原因很簡單,因為我在cross compile Qt 5.5時,一直遇到編譯error問題,且網路上大部分還是Qt 4的code且我也比較熟Qt 4的code,所以就使用Qt 4.8.6啦~
基本上與參考一的步驟一樣
第一步,加入cross-compiler toolchain的執行檔位置到PATH(可以直接改在~/.bashrc再source比較方便)
若遇到非以下問題請嘗試將錯誤訊息複製去google有許多大陸的論壇都會教你如何修改,修改後在繼續make、make install動作 。(ps: gedit跳到某行數的short-cut是ctrl+i)
問題1
錯誤訊息:
thread/qthread_unix.cpp:125: error: thread-local storage not supported for this target
解決方式: 開啟qthread_unix.cpp,在122行後undefine HAVE_TLS,使原本124行的#ifdef HAVE_TLS不成立 gedit src/corelib/thread/qthread_unix.cpp
加入內容:
*為什麼這篇選用Qt 4.8.6,而不使用最新的Qt 5.5?
原因很簡單,因為我在cross compile Qt 5.5時,一直遇到編譯error問題,且網路上大部分還是Qt 4的code且我也比較熟Qt 4的code,所以就使用Qt 4.8.6啦~
環境準備
以下開發環境在VirtualBox上執行Ubuntu 14.04LTS作業系統進行(ubuntu-14.04.2-desktop-amd64.iso),灌好系統後插入Guest Additions CD映像與安裝,使虛擬機畫面可以全螢幕並支援與Host OS交換檔案、剪貼簿等功能,設定vboxsf群組加入使用者權限、更新系統到最新、一些基本環境設定(安裝gcc, g++)、執行32bit GCC cross compiler toolchain的zlib等支援(lib32z1...等)指令如下:
附上網址: http://download.qt.io/archive/qt/4.8/4.8.6/,下載完成後解壓縮:
sudo usermod -aG vboxsf $(whoami) sudo apt-get update sudo apt-get upgrade sudo apt-get install build-essential g++ lib32z1 lib32ncurses5 lib32bz2-1.0 sudo apt-get install首先到Qt官網下載Qt 4.8.6 source code(qt-everywhere-opensource-src-4.8.6.tar.gz)
附上網址: http://download.qt.io/archive/qt/4.8/4.8.6/,下載完成後解壓縮:
wget http://download.qt.io/archive/qt/4.8/4.8.6/ tar zxvf qt-everywhere-opensource-src-4.8.6.tar.gz由於我們會先在桌面開發完成Qt應用程式後再porting到板子上,所以首先我們先build出桌面版本的Qt,經測試發現Qt內部的Makefile可能沒寫好,因此我們必須把桌面版本的Qt source與porting版的分開來(或是使用git來還原),故桌面版這次先重命名為 qt-desktop-opensource-src-4.8.6,根據Qt for X11 Requirements安裝相關套件,然後開始build~(-j8是開八條thread歐,請自行斟酌CPU能力與memory大小)
mv qt-everywhere-opensource-src-4.8.6 qt-desktop-opensource-src-4.8.6 cd qt-desktop-opensource-src-4.8.6 sudo apt-get install libfontconfig1-dev libfreetype6-dev libx11-dev libxcursor-dev libxext-dev libxfixes-dev libxft-dev libxi-dev libxrandr-dev libxrender-dev ./configure -release -opensource -confirm-license -prefix build-ubuntu64 make -j8 make install在完成漫長的編譯後,即可在build-ubuntu64下看到編譯完成的Qt framework,將Qt framework動態函式庫加到LD_LIBRARY_PATH,可執行example內的範例測試:
export LD_LIBRARY_PATH=$(pwd)/build-ubuntu64/lib:$LD_LIBRARY_PATH ./build-ubuntu64/examples/mainwindows/application/application
成功執行application的範例 |
開始Porting
在以上步驟我們完成了於Desktop上的Qt編譯,沒有任何修改code的行為就可在ubuntu上編譯成功,但是到了embedded上就不一樣了,另外在以上編譯桌面板的source下make distclean,仍會殘留大量Makefile、pri修改與config.tests...等檔案,因此必須再重tar開另一份source(或是使用git還原回去),故以下步驟開始:tar zxvf qt-everywhere-opensource-src-4.8.6.tar.gz cd qt-everywhere-opensource-src-4.8.6接著要開始創建Embedded Linux Target組態,官方提供了詳細的文件說明如:
- Cross-Compiling Qt for Embedded Linux Applications
- Qt for Embedded Linux
- Installing Qt for Embedded Linux
基本上與參考一的步驟一樣
第一步,加入cross-compiler toolchain的執行檔位置到PATH(可以直接改在~/.bashrc再source比較方便)
export PATH=path/to/cross/compiler:$LD_LIBRARY_PATH第二步,建立target的QMake規格檔案,以下是我的作法
export QT_ROOT=$(pwd) mkdir mkspecs/qws/linux-arm-pxa270-g++ cd mkspecs/qws/linux-arm-pxa270-g++ touch qmake.conf cp ../linux-arm-gnueabi-g++/qplatformdefs.h . gedit qmake.conf在qmake.conf輸入以下內容指定使用的toolchain並存檔,在這裡是使由新華提供的toolchain其prefix為arm-unknown-linux-gnu-,在flag部分針對armv5te架構、xscale系列來tune:
# # qmake configuration for building with arm-none-linux-gnueabi-g++ # include(../../common/linux.conf) include(../../common/gcc-base-unix.conf) include(../../common/g++-unix.conf) include(../../common/qws.conf) # modifications to g++.conf QMAKE_CC = arm-unknown-linux-gnu-gcc QMAKE_CXX = arm-unknown-linux-gnu-g++ QMAKE_LINK = arm-unknown-linux-gnu-g++ QMAKE_LINK_SHLIB = arm-unknown-linux-gnu-g++ # modifications to linux.conf QMAKE_AR = arm-unknown-linux-gnu-ar cqs QMAKE_OBJCOPY = arm-unknown-linux-gnu-objcopy QMAKE_STRIP = arm-unknown-linux-gnu-strip QMAKE_CFLAGS += -O3 -march=armv5te -mtune=xscale -Wa,-mcpu=xscale -Uarm -mapcs -mno-sched-prolog -mabi=apcs-gnu -mno-thumb-interwork -fno-omit-frame-pointer QMAKE_CXXFLAGS += $$QMAKE_CFLAGS load(qt_config)接著就可以開始編譯了,指定使用arm架構、platform使用剛剛定義的pxa270規格檔案並且關閉x window support:
cd $QT_ROOT ./configure -embedded arm -xplatform qws/linux-arm-pxa270-g++ -prefix build-pxa270 -release -no-opengl -opensource -verbose -no-glib -no-xrender -no-xrandr -no-xfixes -no-xcursor -no-xinerama -no-xsync -no-xvideo -no-xshape -little-endian -confirm-license -no-rpath make -j8 make install在以上的編譯過程你一定會遇到error而停下來,畢竟是cross compile有些是組合語言的關係、有些是define的問題,這邊列出我編譯時遇到的問題:
若遇到非以下問題請嘗試將錯誤訊息複製去google有許多大陸的論壇都會教你如何修改,修改後在繼續make、make install動作 。(ps: gedit跳到某行數的short-cut是ctrl+i)
問題1
錯誤訊息:
thread/qthread_unix.cpp:125: error: thread-local storage not supported for this target
解決方式: 開啟qthread_unix.cpp,在122行後undefine HAVE_TLS,使原本124行的#ifdef HAVE_TLS不成立 gedit src/corelib/thread/qthread_unix.cpp
加入內容:
#ifdef HAVE_TLS #undef HAVE_TLS #endif問題2
{standard input}:311: Error: register or shift expression expected -- `orr r2,r1,lsl#16'
{standard input}:321: Error: register or shift expression expected -- `orr r3,r1,lsl#16'
{standard input}:329: Error: register or shift expression expected -- `orr r2,ip,lsl#16'
{standard input}:467: Error: register or shift expression expected -- `orr r2,r1,lsl#16'
{standard input}:475: Error: register or shift expression expected -- `orr r3,r0,lsl#16'
make[1]: *** [.obj/release-shared-emb-arm/ftbbox.o] Error 1
解決方式: 開啟ftconfig.h,修改第330行的內容
gedit src/3rdparty/freetype/include/freetype/config/ftconfig.h
修改內容:
(原本的為) "orr %0, %2, lsl #16\n\t" /* %0 = %2 << 16 */ (修改後為) "orr %0, %0, %2, lsl #16\n\t" /* %0 = %2 << 16 */問題3
錯誤訊息: ../3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h: In function 'int QTWTF::atomicIncrement(volatile int*)':
../3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h:253: error: '__sync_add_and_fetch' was not declared in this scope
../3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h: In function 'int QTWTF::atomicDecrement(volatile int*)':
../3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h:254: error: '__sync_sub_and_fetch' was not declared in this scope
解決方式: 開啟Threading.h,將第251、253、254行變成註解
gedit src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h
修改後內容:
//#define WTF_USE_LOCKFREE_THREADSAFESHARED 1 // //inline int atomicIncrement(int volatile* addend) { return __sync_add_and_fetch(addend, 1); } //inline int atomicDecrement(int volatile* addend) { return __sync_sub_and_fetch(addend, 1); }問題4
錯誤訊息: ./wtf/Atomics.h: In function 'int WTF::atomicIncrement(volatile int*)':
./wtf/Atomics.h:112: error: '__sync_add_and_fetch' was not declared in this scope
./wtf/Atomics.h: In function 'int WTF::atomicDecrement(volatile int*)':
./wtf/Atomics.h:113: error: '__sync_sub_and_fetch' was not declared in this scope
解決方式: 開啟Atomics.h,將第110、112、113行變成註解
gedit src/3rdparty/webkit/Source/JavaScriptCore/wtf/Atomics.h
修改後內容:
//#define WTF_USE_LOCKFREE_THREADSAFESHARED 1 //#define WTF_USE_LOCKFREE_THREADSAFEREFCOUNTED 1 // //inline int atomicIncrement(int volatile* addend) { return __sync_add_and_fetch(addend, 1); } //inline int atomicDecrement(int volatile* addend) { return __sync_sub_and_fetch(addend, 1); }終於在完成以上編譯與修改動作後,建出了可以於PXA270執行的Qt framework
此時的Qt還無法支援觸控輸入,僅能顯示並且透過Linux的支援可以插上鍵盤滑鼠操作
(PS1:在Linux的kernel driver那邊必須開啟TFT LCD的support)
(PS2:在PXA270執行時,一樣要記得設定LD_LIBRARY_PATH,而在執行時若沒特別啟動過Qt server,必須在執行檔名稱後加上-qws的option,忘記時Qt也會提醒你^.<)
Linux kernel的設定
在Linux kernel部分,必須開啟LCD的支援,在PXA270上的詳細步驟如下:
make mrproper
make menuconfig
1.在"Load an Alternate Configuration File"
arch/arm/configs/creator_pxa270_defconfig
2.在"Device Drivers"->"Character devices"選擇include
Creator-pxa270 LCD、Creator-pxa270 Codec
3.在"Device Drivers"->"Graphics support"選擇include"PXA LCD framebuffer support"後才會出現LCD type選項,選擇"MTLCD-0708048 7.0 inches"
make clean
make -j4
make mrproper
make menuconfig
1.在"Load an Alternate Configuration File"
arch/arm/configs/creator_pxa270_defconfig
2.在"Device Drivers"->"Character devices"選擇include
Creator-pxa270 LCD、Creator-pxa270 Codec
3.在"Device Drivers"->"Graphics support"選擇include"PXA LCD framebuffer support"後才會出現LCD type選項,選擇"MTLCD-0708048 7.0 inches"
make clean
make -j4
您好,謝謝您的教學,請問將我將Qt framework動態函式庫加到LD_LIBRARY_PATH後,build-ubuntu64底下並沒有examples,examples和build-ubuntu64是屬於同一個資料夾,而examples/mainwindows/application/application application/目錄底下並沒有可執行的application,請問我是哪裡出錯了呢? 謝謝您,謝謝。
回覆刪除嗨你好,你的configure是否有build example?
刪除您好,我的qt-desktop-oprnsource底下並沒有configure這個資料夾,只有/config.profiles,/config.tests 這兩個資料夾,和一個名叫configure的shell script,/build-ubuntu64底下也沒有configure。我是用VMware Workstation 12 player,和Ubuntu 64-bit,其他都是照您的步驟進行。
刪除非常謝謝您的幫忙,我也正在做交大的期末project。
刪除我上一個回覆的意思是你下./configure的時候,要確定是否有設定成要編譯example
刪除./configure --help可以看有哪些option可以下
作者已經移除這則留言。
刪除您好,請問 ./configure -release -opensource -confirm-license -prefix build-ubuntu64 是把qt-desktop底下有關/build-ubuntu64的file 都編譯產生makefile,您是指說 和build-ubuntu64同一層的examples並沒有被configure到嗎?怎麼會這樣呢,請問我該如何調整。非常謝謝您,謝謝。
刪除作者已經移除這則留言。
回覆刪除作者已經移除這則留言。
回覆刪除