Developing Qt Applications for Embedded Targets

Yeah, so now that we have all the required libs (read previous post if you are still struggling for that part) so we are embarking on to develop some cute (read Qt) applications for a mini2440 or whatever embedded target you have. Just before we move any further I am about to make some stuff clear. So, your system looks something like this now that you have the Qt power with you

Qt on an Embedded Device

what we are going to do is create an app that uses the Qt APIs which inturn will use some libs that we just ported and therefore do whatever we tell it to. In this post I’ll just make use of a simple adder program that I have created. I’ll demonstrate how to develop for your x86 host machine and then how to get it working on the ARM target. As always, there are some pre-requisites

  • Toolchain
  • Qt SDK – Offline 689MB
  • Target Board  – ARM, PPC or whatever arch. I use mini2440.
  • Ear-muffs, in case you  can still hear your girlfriend’s shouts

You can however do away with the last part only if you have a geek girl or you are deaf 🙂 So we begin our journey.

Setting Up the Host

Install Qt SDK on your system. Its pretty straight forward. Once its done, get some feel of developing application using Qt for just your x86 host. This means going through the tutorials and the usual stuff of creating a hello world application etc. I’ll cover al this in another post if you wish. but for the time being we’ll just create a small project called adder. Now you can either start making your own app or use mine for testing. Get the simple adder utility that I have made. You can download it either as a tarball or just get it from Gitorious

Also, untar the toolchain and set it up in the PATH so that you get ready for cross-compiling.

Application Development on x86 Host

Now, the good thing is that you can first create an applications and test it on your host. the development is done in Qt Creator which comes with the complete installation of Qt SDK. Open the adder project you just got. You can even just browse through the available examples in your system and create your own if you are well versed with Qt Creator. The utility is quite simple to use and I shall explain how to start development in it in the next post. For now, you can build the ‘adder’ project simply for your desktop by selecting the project and pressing the build and execute button on the left panel.

So once the build is over, your application will get executed on your host successfully. SO we have cover now how to build and execute apps for your desktop host.

Application Development on ARM Target

Now you can have nay target architecture. To test the process, I have used my ol’ faithful ARM mini2440 as the target board. Lets begin then. Remember that in the previous post we ported and put the libs on the mini2440? We had our cross compiled Qt libs and other stuff stored in the  /usr/local/qt directory both on the host and the target. Now just browse to that directory and see if you have the qmake binary in usr/local/qt/ Now add this to the PATH variable so that you can run qmake.

No go to the adder directory and do a

qmake adder.pro
make

You will notice that in the same directory, a binary called adder will be created. if you do a file on it, you will see that its for an ARM target. Of course, make will throw some errors if you have not setup the toolchain properly. Now make sure that you have configured and built Qt with the -qt-mouse-tslib -qt-kbd-linuxinput if you are using a touchscreen interface or need to have a USB keyboard interface.

Also you may need to modify the width and height in the following environment variable according to the proper font size display and the screen. The value below works best for a 15″ VGA monitor

export QWS_DISPLAY=LinuxFB:mmWidth=310:mmHeight=190

Now, Its just a matter of transferring the cross-compiled binary to the target system and running it. I have tested running it on a mini2440 connected to a 3.5″ screen, 12.1″ screen and even on a standard LCD with a VGA interface. Upon execution, the aplication looks something like this :

So we have done it at last.  So just keep on developing whatever comes to your mind and port it on to your embedded target. The cool thing is that we can now just get anything made for Qt to work on your target. I have myself tested fully functional browsers (you need Webkit for that, don’t forget!) and image viewers, clock and small games too 🙂 the only limitation you may face of course is the hardware on your target! Feel free to ask for any help and or giving suggestions

Advertisements

Qt 4.6 on mini2440 – A Definitive Guide

Having Qt on your device is a awesome way to ensure that you and many other developers can enjoy developing applications and having fun in addition to doing rapid application development whenever required. The wealth of support provided by the Qt framework – right from OpenGL to WebKit tempts a embedded developer for sure. So I decided its time for a change. Lets dump the overkiiling Android and take shelter under Qt’s canvas for my device. I kept on roaming the intricately laid out web of information on having Qt 4.6.2 run successfully on my mini2440. But owing to the strange 12.1″ LCD that I have attached to it I was more-or-less stuck on the Touchscreen calibration part. So Now after hits and trials and many cups of tea, I am assembling a guide. I intend to make if definitive but only the willful enough to dare can tell.

What You Need

Qt 4.6.2 

GNU ARM Toolchain

Step 1

Setup the toolchain and modify the PATH variable accordingly. Untar qt-everywhere-opensource-src-4.6.2.tar.gz wherever you like. Mine is /usr/local/qt

Step 2

Replace the whole text in mkspecs/qws/linux-arm-g++/qmake.conf by the following:

#
# qmake configuration for building with arm-linux-g++
#

include(../../common/g++.conf)
include(../../common/linux.conf)
include(../../common/qws.conf)

# modifications to g++.conf
QMAKE_CC                = arm-none-linux-gnueabi-gcc -msoft-float -D_GCC_FLOAT_NOT_NEEDED -march=armv4t -mtune=arm920t -O0 -lts
QMAKE_CXX               = arm-none-linux-gnueabi-g++ -msoft-float -D_GCC_FLOAT_NOT_NEEDED -march=armv4t -mtune=arm920t -O0 -lts
QMAKE_LINK              = arm-none-linux-gnueabi-g++ -msoft-float -D_GCC_FLOAT_NOT_NEEDED -march=armv4t -mtune=arm920t -O0 -lts
QMAKE_LINK_SHLIB        = arm-none-linux-gnueabi-g++ -msoft-float -D_GCC_FLOAT_NOT_NEEDED -march=armv4t -mtune=arm920t -O0 -lts

# modifications to linux.conf
QMAKE_AR                = arm-none-linux-gnueabi-ar cqs
QMAKE_OBJCOPY           = arm-none-linux-gnueabi-objcopy
QMAKE_STRIP             = arm-none-linux-gnueabi-strip
QMAKE_RANLIB            = arm-none-linux-gnueabi-ranlib

load(qt_config)

Remember that the PATH variable should have the location of arm-none-linux-gnueabi-gcc etc.

Step 3

Now turn off compiler optimization by making changes in /mkspecs/common/g++.conf Just change the following line to this :

QMAKE_CFLAGS_RELEASE  += -O0

Step 4

Now we have to configure Qt the way we want it by doing ./configure but we need to specify some options according to our requirements.

./configure -embedded arm -xplatform qws/linux-arm-g++ -prefix \
/usr/local/qt -little-endian -webkit -no-qt3support -no-cups -no-largefile \
-optimized-qmake -no-openssl -nomake tools -qt-mouse-tslib -qt-kbd-linuxinput

Now, this configuration is what I needed, for example for my network enabled device I needed a webkit based application so I provided -webkit option. You can drop in or add whatever you want. Some handy options that you may (or may not require) are :

Enable touchscreen library support : -qt-mouse-tslib

Enable USB keyboard support : -qt-kbd-linuxinput

The above options affect the QtGui library so you need to replace only QtGui.so.x.x file on your root filesystem if you are planning to make changes.

Step 5

So more or less you are done. Its time to do some creative stuff (blah!) just do

make

Wait for a couple of hours or so and find your cross compiled freshly baked libraries in /usr/local/qt/lib/

Setting up Qt 4.6 libs on mini2440

So now, its time to put the libs on your mini machine! You may choose to create a separate filesystem using busybox too. Elaborate tutorials on that are available on the web. Just Google it up. What I will do is, modify the rootfs that came with my mini and remove all unnecessary stuff from it. Create a dir /usr/local/qt on your mini2440’s stock root filesystem and copy the complete lib directory from step 5 to that location using a USB stick/SD Card or something. Remember to do a df on the mini beforehand to see the free NAND you have got. In case the memory is low, delete some stock data – the small video file, mp3 file and some sample images that are present on it.Also remove unnecessary applications viz konqueror and old qt 2.2.0 libraries from the system.

Environment Variables

To make the mini understand the new Qt libs, we’ll add some variables

On your mini2440, edit /etc/inint.d/rcS and add the following line to it

source /etc/qt46profile

Now create the /etc/qt46profile file and the following text to it :

export LD_LIBRARY_PATH=/usr/local/qt/lib
export QTDIR=/usr/local/qt
export QWS_MOUSE_PROTO=IntelliMouse:/dev/input/event0
export QWS_DISPLAY=LinuxFB:mmWidth=310:mmHeight=190

Remember that these variables may change according to your qt libs location and mouse/touchscreen drivers. Go to /dev/input/ and see which file is responsible for which device. For eg. if tslib is configured on your device then the QWS_MOUSE_PROTO  variable will have the value something like

QWS_MOUSE_PROTO=Tslib:/dev/input/event1

So, you are done at last and have your system ready with Qt 4.6.2 libs. Try running a simple application (viz a Analog Clock from the cross-compiled qt examples at /usr/local/qt/examples/widgets/analogclock/analogclock by giving the -qws option on the mini2440 shell as

./analogclock -qws

Thats it! Do tell me if you are able to reach here. In the next two posts I shall be discussing about rapidly developing a GUI application for your mini using Qt Creator and compiling and configuring Tslib for mini2440.

GNUnify 2011 Days

As usual, I am late with updating my blog on the recent acivities owing to the fact that I have lots of other tasks (a Fringe and Big Bang Theory marathon for the record) But still let me try to recollect what all hapened those days.

Day #1

I remember collecting Hiemanshu from Pune station and then taking him to my room and spending the night having some generic FOSS talks and getting to know each other. We did some initial planning for the first GNUnify day but that didn´t do any good owing to the fact that our arrival led us straight to a chaos. Apparently some miscommunication led to some speaker names being wrongly declared for a couple of talks they had specified for the Fedora Track, but soon things were under control and Neependra and Hiemanshu started with ¨Contributing to Fedora”and ¨Introduction to Virtualization¨ as mentioned on the Fedora GNUnify 2011 Wiki. Soon, the discs and the swag came and it was Fedora all over Room 706. The after lunch session taken by Tanushri was a small demo of the upcoming Gnome3 and issues related to developing GUI apps on it. Soon I met Shakthi Kannan whom I had got in touch on some occassions and our Embedded NIrvana gang (Chaitannya, Amit Karpe, Ksinkar & Co) :p It started feeling like home already 🙂 I interacted with so many interested students and shared ideas with them. Apart from the already heated up Fedora sessions, the air was charged with guys like Ksinkar interested un Embedded Linux. We brainstormed for sometime about the lame Hawkboard and mini2440 and then called it a day. We went for the Firefox dinner at SIMS where I met some other FF contributors.  I returned with Hiemanshu back to my den and we started planning about an awesome idea on Day 2 🙂

Day #2

What we planned last night was somewhat interesting. Actually I designed a PyGTK app PyQrencode sometime back and had been stuck somewhere (I admit I am a lame coder) and Hiemanshu willingly helped me out. Soon we planned to do it all over using PyQt and take the same concept to showcase app development using both platforms. In the process, I learnt some stuff from Hiemanshu too and our sessions the next day were awesomely interesting! I took up an into to Python and PyGTK and HIemanshu showcased the power of PyQt. Sadly, and apparently, Qt was more powerful in terms of ease of development and features and I lost the mini battle we had. By this time I had missed al the interesting stuff that was going on at GNUnify and my Main Session talk was approaching too. I started a quick review of my talk (which was immediateley after Siji Sunny) and started gearing up. After the FOSS.in MiniConf talk, this was somewhat  a not so different experience. The attendence in my talk was moderate but loyal. I could see some familiar and interested faces and knew that question of all sorts would come :-p

My talk Tux Under the Hood was about some personal experiences of mine, gathered while playing around with Linux on embedded devices. I mostly talked about the basics of embedded devices, structure of the Linux OS on them and ended with an elaborate hands-on/demo on QEMU.

Other interesting main session talks were by Neependra and Shakthi on setting up kgdb, GNU Make and Kickstarting C, GCC respectively – which I obviously missed 😦 However, Neependra was kind enough to teach me some stuff during our Embedded NIrvana Sessions at CoEP. I was tired and hungry by this time, and there was a prize ceremony going on for the winners of programming contest. As soon as it was over, I met some other senior PLUG guys and soon me and He-Man-Sue were on our way back pondering what all we did.

It was a nice experience and I got to know a lot about what goes on inside a FOSS contributorś mind. some pics from the event are here :

Modding Android for mini2440 & 12″ Screen

I have been playing for sometime with the FriendlyARM mini2440 development board and trying out Android on it with various touchscreens at various resolutions. However, my application demanded a 12.1″ screen and all I was doing was just fooling around with the 3.5″ screen. This post will clear up some doubts (or probably add more confusion in this regard), but it surely would get you an ‘awe’ feel. This is also not meant to be a tutorial, but intermediate level embedded guys would love to burn their boards upon reading this for sure 🙂

Note : Android performance on mini2440 is actually very poor. the touchscreen is still not calibrated, but I’m working on it. Also, the kernel and the rootFS have been modded to some extent (not by me of course)

Things you should have :

  • FriendlyARM mini2440 of course
  • 12.1″ screen, make : Sharp
  • All the necessary cabling : USB, Serial etc.
  • A Fedora/Ubuntu box
  • A net connection
  • 375ml of breezer (or a cup of coffee for the nocturnals), earplugs and patience 🙂

Things you should get :

Kernel Mod

The kernel source you downloaded has a display configured for the 3.5″ default screen. We shall be adding a new module to the Kernel and making changes to some source files to get our 12.1″ screen working perfectly.

[1] Making a new Module : In the kernel source open the file drivers/video/Kconfig and staring from line 1920, replace

#config FB_S3C2410_TFT800480
#boolean "7 inch 800x480 TFT LCD"
#depends on FB_S3C2410
#help
#7 inch 800x480 TFT LCD

with

config FB_S3C2410_TFT800600
boolean "12 inch 800x600 TFT LCD"
depends on FB_S3C2410
help
12 inch 800x600 TFT LCD

[2] Now, the driver for touchscreen is located at drivers/input/touchscreen/s3c2410_ts.c Here, the original resolution is 320×240 and we have to modify it to 800×600. Add the following after line 19

#ifdef CONFIG_FB_S3C2410_TFT800600
#define SCREEN_X 800
#define SCREEN_Y 600
#else
#define SCREEN_X 240
#define SCREEN_Y 320
#endif

Modify as follows after line 99,

//disX = disX * 1024 / 240;
//disY = disY * 1024 / 320;
disX = SCREEN_X - disX;
disX = disX * 1024 / SCREEN_X;
disY = disY * 1024 / SCREEN_Y;

[3] Some more modding is required for front and back porch settings of LCD. It varies for different LCD vendors. Refer the LCD datasheet for your reference. Considering my Sharp LCD, you can try it out on your’s too, modify the file arch/arm/mach-s3c2440/mach-mini2440.c in your kernel source as follows

#elif defined(CONFIG_FB_S3C2410_TFT800600)
#define LCD_WIDTH 800
#define LCD_HEIGHT 600
#define LCD_PIXCLOCK 40000

#define LCD_RIGHT_MARGIN 120
#define LCD_LEFT_MARGIN 40
#define LCD_HSYNC_LEN 60

#define LCD_UPPER_MARGIN 25
#define LCD_LOWER_MARGIN 20
#define LCD_VSYNC_LEN 1

Play with the right,left,upper and lower margins till you get the perfect display once compilation is over.

Kernel Compilation

make menuconfig

Save the .config file when asked to do so. Now,

cp config_mini2440 .config
make menuconfig

Now select Device Drives -> Graphic support -> Support for frame buffer devices -> S3C2410 LCD framebuffer support -> [x] 12 inch 800×600 TFT LCD

Assuming that the Cross Compiler is set and the PATH variable knows about it, bake the kernel by doing

make

The kernel can then be found at arch/arm/boot/zImage Viola! the kernel is ready!

Android Filesystem Modifications

[1]Creating the console file. Untar the Android FS and do,

cd fs/dev
sudo mknod console c 5 1

[2]Pointer Callibration file (WARNING : GREY AREA)

cd fs/system/etc/shine
echo "134 57734 -3147464 -40090 1465 35070384 65536" > pointercal

Now I have been unsuccessful in this stuff till now. Actually, the pointercal stores the calibration values for touchscreen which is automatically generated once the ts_calibrate utility runs. unfortunately, I haven’t got a clear idea on how tslib works yet.

Creating Android Filesystem Image

Untar the mkyaffs2image-128M binary to /usr/sbin or any other place of your choice. Considering the directory ‘fs’ stores your modified FS,

mkyaffs2image-128M fs 12inch_android.img

So now, you have the kernel zImage and the 12inch_android.img file system ready for you. Start the board in NOR mode and write the kernel and Android FS to the board after formatting the NAND Flash. Connect the USB and use the s3c2410_boot_USB tool (after compiling the tool itself for your host, of course) Then,

./s3c2410_boot_usb zImage

After the transfer is complete, (it gives some error, ignore it),

./s3c2410_boot_usb 12inch_android.img

Boot the board in NAND mode after the transfer is complete. Thats all. I’m sharing some pics of my trials. Feel free to suggest and/or educate me or for any other queries.

Android on mini2440+12"
Android on mini2440+12"
Android on mini2440+12"
Android on mini2440+12"

OpenARMLabs Session : Android on ARM and Kernel Compilation

Android on ARM and Linux Kernel Compilation – Open ARM Lab Session

The Open ARM Lab session for this week will be held on Sunday, 5th December 2010.

Agenda:

1) Android on ARM
2) Linux Kernel Compilation
3) What happens when an ARM based board is powered ON?

Speakers:

1) Suchakra
2) Tuxdna

Date: Sunday, 5th December 2010

Time: 11 PM to 2 PM

Venue:

DSK Digital Technologies Pvt. Ltd. “Ramashree”, 3rd Floor, 1206/30 Off J.M. Road, Shivaji Nagar,
Pune 411005 Maharashtra, India Tel No.:: 020- 25511481/ 482.

More-Info

Session : Hands on with Toolchain for Friendly Arm Board


Date: 20 Nov 2010 – Saturday
Time: 11 AM to 5 PM

Agenda: Hands on with Toolchain for Friendly Arm

Venue: Embedded Design Center, Instrumentation Department, COEP, Pune.
Venue Map: http://bit.ly/9UMAiF

Day long session on this Saturday 11AM to 5 PM

  1. Host and Target OS blueprint.
  2. Install and configure toolchain for Friendly Arm on Host.
  3. Build Linux OS for target device.
  4. Develop a few apps for Friendly arm board.
  5. Document & publish the build process.

Visit http://openarmlab.org