Qt到Cortex-A8的移植
作者:凤竹郎2012-07-31
一、 前言
准备工作:交叉编译好的qt4.7.3的库,交叉编译好的tslib库,交叉编译好的mobility库。以及交叉编译好的Qt APP程序。
Qt4.7标准键盘可以正常使用,不需要配置键盘选项,之前版本可能需要配置-qt-kbd-usb选项。Qt4.7支持触摸屏需要配置-qt-mouse-tslib选项,默认支持-qt-mouse-linuxtp/pc选项,既支持鼠标。
二、 内核配置和编译
修改配置文件
#vim ~/arm/arch/configs/omap3_stalker_defconfig
1、 支持sonix的摄像头
[*] USB support --->
--- USB support
<*> Support for Host-side USB
<*> Multimedia support --->
--- Multimedia support
*** Multimedia core support *** <*> Video For Linux
[*] Enable Video For Linux API 1 (DEPRECATED)
[*] Video capture adapters --->
[*] V4L USB devices --->
[*] UVC input events device support
CONFIG_USB_SN9C102=y #
CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y #
CONFIG_USB_GSPCA_SONIXB=y #
CONFIG_USB_GSPCA_SONIXJ=y #
2、 支持USB标准键盘
Device Drivers --->
Input device support --->
<*> Mouse interface
[*] Mice --->
CONFIG_INPUT_MOUSE=y # is not set
CONFIG_INPUT_MOUSEDEV=y # is not set
#cd /home/ema/dvsdk/ti-dvsdk_dm3730-evm_4_02_00_06/psp/linux-2.6.32-psp03.00.01.06.sdk
#sudo make CROSS_COMPILE=arm-none-linux-gnueabi- ARCH=arm omap3_stalker_defconfig
#make CROSS_COMPILE=arm-none-linux-gnueabi- ARCH=arm
#make CROSS_COMPILE=arm-none-linux-gnueabi- ARCH=arm uImage
三、 移植Qt库,tslib库,mobility库,设置环境变量
1、 PC机设置
1.1编译Qt4.7前设置
vim ~/.bashrc
export LD_LIBRARY_PATH=/home/ema/dvsdk/ti-dvsdk_dm3730-evm_4_02_00_06/omap35x_graphics_sdk_4.00.00.01/gfx_dbg_es2.x/freedesktop/kdrive/usr/X11R6_SGX/lib:$LD_LIBRARY_PATH
export PATH=/usr/local/arm/arm-2009q1/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/arm/arm-2009q1/lib:$LD_LIBRARY_PATH
#export PKG_CONFIG_PATH=/usr/local/arm/arm-2009q1/lib/lib-arm/lib/pkgconfig:$PKG_CONFIG_PATH
export LD_LIBRARY_PATH=/home/ema/dvsdk/ti-dvsdk_dm3730-evm_4_02_00_06/linux-devkit/arm-none-linux-gnueabi/usr/lib:$LD_LIBRARY_PATH
export PKG_CONFIG_PATH=/home/ema/dvsdk/ti-dvsdk_dm3730-evm_4_02_00_06/linux-devkit/arm-none-linux-gnueabi/usr/lib/pkgconfig:$PKG_CONFIG_PATH
export LD_LIBRARY_PATH=/home/ema/dvsdk/ti-dvsdk_dm3730-evm_4_02_00_06/omap35x_graphics_sdk_4.00.00.01/gfx_dbg_es2.x:$LD_LIBRARY_PATH
1.2编译Qt4.7后设置
#ARM embedded enviroment Code build and compile
export PATH=/usr/local/qt-emembeded-4.7.3-arm-linux/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/qt-emembeded-4.7.3-arm-linux/lib:$LD_LIBRARY_PATH
export QMAKESPEC=/usr/local/qt-emembeded-4.7.3-arm-linux/mkspecs/qws/linux-omap3-g++
#Mobility libs
export LD_LIBRARY_PATH=/usr/local/qt-mobility-1.2.0-lib/lib:$LD_LIBRARY_PATH
2、开发板设置
#vim etc/profile
export LD_LIBRARY_PATH=/usr/local/qt-emembeded-4.7.3-arm-linux/lib:LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/usr/local/qt-mobility-1.2.0-lib/lib:$LD_LIBRARY_PATH
export TSLIB_ROOT=/usr/local/tslib
export LD_LIBRARY_PATH=$TSLIB_ROOT/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/usr/local/SDL-ARM-linux-gcc4.3.3/lib:$LD_LIBRARY_PATH
export PATH=/usr/local/qt-emembeded-4.7.3-arm-linux/bin:$PATH
export QT_QWS_FONTDIR=/usr/local/qt-emembeded-4.7.3-arm-linux/lib/fonts
export QT_PLUGIN_PATH=/usr/local/qt-emembeded-4.7.3-arm-linux/plugins
export QWS_MOUSE_PROTO="LinuxTP:/dev/input/event6 tslib:/dev/input/touchscreen0"
export QWS_USB_KEYBOARD=/dev/input/envent4
export QWS_SIZE=800X600
export QWS_DISPLAY="LinuxFb:mmWidth100:mmHeight130:0"
export TSLIB_CONSOLEDEVICE=none
export TSLIB_TSDEVICE=/dev/input/touchscreen0
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_PLUGINDIR=$TSLIB_ROOT/lib/ts
export TSLIB_CONFFILE=$TSLIB_ROOT/etc/ts.conf
#export SDL_NOMOUSE=1
以上配置可以去除Qt花屏现象,不要设置QWS_MOUSE_PROTO变量,否则可能出现Qt触摸屏显示触摸正常,Qt鼠标不可用现象。SDL可正常使用。
四、 交叉编译或拷贝交叉编译库(Gstreamer plugin,alsa,jpeg,png,freetype,phonon,dbus···)
$./qt –qws
此时会报一些错误,差GStreamer的一些相关库,需要从DVSDK上拷贝过来,可能还有png等相关库还需拷贝:
DVSDK库路径:/home/ema/dvsdk/ti-*/linux-devit/arm-*/usr/lib
$cd /usr/lib
$cp ~/libgthread-2.0 .* ./
$cp ~/libgtreamer-1.10.* ./
$cp ~/libgobject-2.0.* ./
$cp ~/libgmoudle-2.0.* ./
$cp ~/libglib-2.0.* ./
$cp ~/libgstinsterfaces-0.10.* ./
$cp ~/libgstvideo-0.10.* ./
$cp ~/libgstbase-0.10.* ./
现在运行IR GUI可以看到USB camera图像出来了,gui也显示完好。
五、 触摸屏校验
1、设置环境变量:
$vim /etc/profile
export TSLIB_ROOT=/usr/local/tslib
export TSLIB_CONSOLEDEVICE=none
export TSLIB_TSDEVICE=/dev/input/touchscreen0
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_PLUGINDIR=$TSLIB_ROOT/lib/ts
export TSLIB_CONFFILE=$TSLIB_ROOT/etc/ts.conf
2、检验:
$reboot
$cd /usr/local/ts_calibrate
$ ./ ts_calibrate
$./ts_test
$reboot
六、 触摸屏和鼠标的切换
1、 触摸屏单独模式
#export QWS_MOUSE_PROTO=”tslib: /dev/input/touchscreen0”
2、 鼠标、触摸屏双模式
#export QWS_MOUSE_PROTO=””
这时候鼠标可以准确使用,触摸屏能正常使用。
七、 SD卡系统启动盘制作
#cd source/SD-install
#sudo fdisk -l
#sudo ./mkcard.sh /dev/sdc //carefully, not sdc1
虚拟机断开 SD 卡连接,重新连接上,用“df”命令就可以看到已经分好两个分区。 //Maybe need serveries times.
#df
#sudo cp MLO /media/boot
#sync
#sudo cp u-boot.bin /media/boot
#sudo cp uImage /media/boot
#sudo tar jxvf evm_fs.tar.bz2 -C /media/rootfs
#umount /media/boot
#umount /media/rootfs
从虚拟机里断开 USB 连接,取出 SD 卡插到开发板,上电启动开发板
八、 从NANDFlash启动
NAND Flash系统映像更新
ØNAND FLASH分区:
* 0x00000000-0x00080000 : "X-Loader"
* 0x00080000-0x00260000 : "U-Boot"
* 0x00260000-0x00280000 : "U-Boot environment data"
* 0x00280000-0x00680000 : "Kernel"
Ø对于128MB的核心板:
* 0x00680000-0x08000000 : "File System"
Ø对于256MB的核心板:
* 0x00680000-0x10000000 : "File System"
Ø下面的指南是使用SD卡引导将镜像写入到NAND FLASH
准备:
(1)准备一个可启动的SD卡。
(2)请确保以下文件在FAT32分区的SD卡里面:60
MLO (X-Loader)
u-boot.bin (U-Boot)
uImage (Linux kernel image)
ubi.img (UBIFS file system image)
上面列出的文件可以从这里下载http://code.google.com/p/ema3730/downloads/list
ØX-Loader是第一阶段引导加载程序,使用下面的命令烧写X-Loader到NAND FLASH:
OMAP3 Stalker #mmc init
OMAP3 Stalker #fatload mmc 0:1 80000000 MLO
OMAP3 Stalker #nandecc hw
OMAP3 Stalker #nand erase 0 80000
OMAP3 Stalker #nand write.i 80000000 0 80000
ØU-Boot是第二阶段引导加载程序,使用下面的命令烧写U-Boot到NAND FLASH:
OMAP3 Stalker #mmc init
OMAP3 Stalker #fatload mmc 0:1 80000000 u-boot.bin
OMAP3 Stalker #nandecc sw
OMAP3 Stalker #nand erase 80000 160000
OMAP3 Stalker #nand write.i 80000000 80000 160000
Ø使用下面的命令烧写内核镜像到NAND FLASH:
OMAP3 Stalker #mmc init
OMAP3 Stalker #fatload mmc 0:1 80000000 uImage
OMAP3 Stalker #nandecc sw
OMAP3 Stalker #nand erase 280000 400000
OMAP3 Stalker #nand write.i 80000000 280000 400000
Ø我们使用的文件系统UBIFS。使用下面的命令加载文件系统镜像到RAM。这里举例的文件系统镜像名是:ubi.img
OMAP3 Stalker #mmc init
OMAP3 Stalker #fatload mmc 0:1 84000000 ubi.img
OMAP3 Stalker #nandecc sw
Ø对于128MB的核心板,使用下面的命令擦除文件系统分区:
OMAP3 Stalker #nand erase 680000 8000000
Ø对于256MB的核心板,使用下面的命令擦除文件系统分区:
OMAP3 Stalker #nand erase 680000 10000000
Ø烧写文件系统镜像到NAND FLASH。这里举例的文件系统镜像的大小是0xD40000 (Bytes),具体大小可根据实际镜像大小来调整:
OMAP3 Stalker #nand write.i 84000000 680000 D40000
当所有上述工作完成后就可以关掉电源,把SD卡拔出来,设置好拨码开关(111100),重新上电启动开发板,在U-BOOT里设置好传给内核的参数就可以从NAND FLASH启动。
九、 设置显示方式(TV、LCD、TS)
进入bios设置:
1、TV:
# setenv dvimode 800x600MR-16@60
#setenv defaultdisplay
# saveenv
2、LCD:
# setenv dvimode 800x600MR-16@60
# setenv defaultdisplay dvi
# saveenv
3、TS(4.3寸触摸屏):
#setenv boardmodel SBC35X-B1-1880-LUAC0
#setenvdefaultdisplaylcd043
#setenv dvimode 480x272MR-16@60
#saveenv
图表1
在Android1.6里面,添加Listener的工作变得相当的简单(感觉更像在做网页编程!),具体步骤如下:
1.首先在layout里面定义Button并指定响应的Listener
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button
android:text="Button01"
android:id="@+id/Button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="myClickHandler01"
/>
<Button
android:text="Button02"
android:id="@+id/Button02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="myClickHandler02"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
其中以下这两行就是新增的特性:
android:onClick="myClickHandler01"
android:onClick="myClickHandler02"
2.在活动里面定义public的方法myClickHandler01、和myClickHandler02(注意这两个方法必须有一个
View的形参)。
package com.ray.test;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
public class TestOnClickListener extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void myClickHandler01(View target){
setTitle("myClickHandler01");
}
public void myClickHandler02(View target){
setTitle("myClickHandler02");
}
}
当然,你也可以采用这种写法:
将两个按钮设置到同一个Listener
android:onClick="myClickHandler"
android:onClick="myClickHandler"
package com.ray.test;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
public class TestOnClickListener extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void myClickHandler(View target){
switch (target.getId()) {
case R.id.Button01:
setTitle("myClickHandler01");
break;
case R.id.Button02:
setTitle("myClickHandler02");
break;
}
}
}
内容来自于:http://hellsing42.iteye.com/blog/564772
找了很多的资料,终于把时基定时器的给弄懂了,没有使用库函数,直接操作寄存器。
下面介绍STM32中的systick,Systick 部分内容属于NVIC控制部分,一共有4个寄存器,名称和地址分别是:
STK_CSR, 0xE000E010 -- 控制寄存器
STK_LOAD, 0xE000E014 -- 重载寄存器
STK_VAL, 0xE000E018 -- 当前值寄存器
STK_CALRB, 0xE000E01C -- 校准值寄存器
首先看STK_CSR控制寄存器:寄存器内有4个位t具有意义:
第0位:ENABLE,Systick 使能位 (0:关闭Systick功能;1:开启Systick功能)
第1位:TICKINT,Systick 中断使能位 (0:关闭Systick中断;1:开启Systick中断)
第2位:CLKSOURCE,Systick时钟源选择 (0:使用HCLK/8 作为Systick时钟;1:使用HCLK作为Systick时钟)
第3位:COUNTFLAG,Systick计数比较标志,如果在上次读取本寄存器后,SysTick 已经数到了0,则该位为1。如果读取该位,该位将自动清零
STK_VAL当前值寄存器:
也是个24位的寄存器,读取时返回当前倒计数的值,写它则使之清零,同时还会清除在SysTick 控制及状态寄存器中的COUNTFLAG 标志。
STK_CALRB
校准值寄存器:
这个寄存器好像目前的水平我还用不到,大体意思明白点,
位31 NOREF :1=没有外部参考时钟(STCLK 不可用)0=外部参考时钟可用
位30 SKEW:1=校准值不是准确的1ms 0=校准值是准确的1ms
STK_LOAD
重载寄存器:
Systick是一个递减的定时器,当定时器递减至0时,重载寄存器中的值就会被重装载,继续开始递减。STK_LOAD 重载寄存器是个24位的寄存器最大计数0xFFFFFF。
下面我们就应用SysTick定时器来裸奔,把它作为一个定时器来用,还是老一套,在寄存器头文件中添加定义寄存器:
#include "stm32f4_discovery.h" #define CALIB (*((volatile unsigned long *)0xE000E01C)) #define VAL (*((volatile unsigned long *)0xE000E018)) #define LOAD (*((volatile unsigned long *)0xE000E014)) #define SYSTICK_CSR (*((volatile unsigned long *)0xE000E010)) typedef struct { __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ } SysTick_Type; #define SysTick ((SysTick_Type *) SysTick_BASE ) void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); /* Configure PD12, PD13, PD14 and PD15 in output pushpull mode */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOE, &GPIO_InitStructure); } void SysTick_Configuration(void) { SysTick->VAL =0; //当前值寄存器 SysTick->LOAD=72000; //重装载寄存器,中断一次1mS SysTick->CTRL|=0x07;// HCLK作为Systick时钟,Systick中断使能位 } __IO uint32_t TimingDelay = 20000; int main() { while(1) { if(TimingDelay == 0) { TimingDelay = 20000; GPIO_SetBits(GPIOE, GPIO_Pin_8); } } } void SysTick_Handler(void) { SysTick->VAL =0; if (TimingDelay != 0x00) TimingDelay--; }