Friday, August 12, 2011

Cross Compiling Linphone(2)

It is time to compile the linphone. Command line argument list is quite long this case:

$ ./configure --prefix=$PREFIX --host=$HOSTTPL --with-gnu-ld \
        --disable-static --disable-glib --enable-gtk_ui=no \
        --enable-sdl --disable-x11 --disable-libv4l \
        --with-osip=$INSTALLDIR/usr/local \
        --with-readline=$INSTALLDIR/usr/local \
        SPEEX_CFLAGS="-I$INSTALLDIR/usr/local/include" \
        SPEEX_LIBS="-L$INCLUDEDIR/usr/local/lib -lspeex" \
        FFMPEG_CFLAGS="-I$INSTALLDIR/usr/local/include" \
        FFMPEG_LIBS="-L$INCLUDEDIR/usr/local/lib -lavcodec" \
        SWSCALE_CFLAGS="-I$INSTALLDIR/usr/local/include" \
        SWSCALE_LIBS="-L$INCLUDEDIR/usr/local/lib -lswscale" \
        SDL_CFLAGS="-I$INSTALLDIR/usr/local/include" \
        SDL_LIBS="-L$INCLUDEDIR/usr/local/lib -lSDL"

Still there are some Makefiles and a source file we have to fix before we build them.

mediastreamer2/tests/Makefile

Find the LIBS variable and change it as:

LIBS = -pthread -lpthread -lrt -lvorbisenc -lvorbis -logg -lspeexdsp


mediastreamer2/coreapi/Makefile

Find the LIBS variable and change it as:

LIBS = -losip2 -lspeex -lSDL -lvorbis -lvorbisenc -lspeexdsp -logg -lavutil


mediastreamer2/coreapi/help/Makefile

Find the LIBS variable and change it as:

LIBS = -leXosip2 -lspeex -lSDL -lvorbisenc -losipparser2 -losip2 -lvorbis \
        -lspeexdsp -logg

And find the helloworld_LADD variable and add $(EXOSIP_LIBS) as:

helloworld_LDADD = $(top_builddir)/coreapi/liblinphone.la \
        $(EXOSIP_LIBS) \
        $(MEDIASTREAMER_LIBS) \
        $(ORTP_LIBS)


mediastreamer2/console/Makefile

Find the LIBS variable and change it as:

LIBS = -leXosip2 -losip2 -lSDL -lvorbis -lvorbisenc -lspeexdsp -logg -losipparser2

And find linphonecsh_LDADD variable and change it as:

linphonecsh_LDADD = $(ORTP_LIBS) -L/home/user/linphone/install/usr/local/lib


mediastreamer2/src/videoout.c

This file contains some obsolete function calls such as ms_sws_freeContext, ms_sws_getContext and, so on. So it won't compile unless we fix them (replace them with correct function calls). Details are here:
https://bugs.gentoo.org/attachment.cgi?id=269363&action=diff
Finally, we are ready to build linphone. What you need is a good luck now.

$ make
$ make install DESTDIR=$INSTALLDIR

Cross Compiling Linphone(1)

In this post, we will cross compile linphone for ARM devices. When it comes to video capability, it will support video output via SDL but no web cam interface. Including camera support is not difficult as long as V4L library is prepared.

First gather the required sources:

  • libav-0.7.1
  • libeXosip2-3.5.0
  • libogg-1.3.0
  • libosip2-3.5.0
  • libvorbis-1..3.2
  • linphone-3.4.3
  • ncurses-5.9
  • readline-6.2
  • SDL-1.2.14
  • speex-1.2rc1

and extract them under a directory, say linphone. Then create a target output directory, say install. Your directory structure then will look like this:


To save tedious repetitive typing, prepare environmental variables

export PREFIX=/usr/local
export HOSTTPL=arm-none-linux-gnueabi
export INSTALLDIR=/home/user/linphone/install

These may vary on your situation. Most of the procedures for each library compilation basically consist of following three steps:

$ configure
$ make
$ make install

So we will just list the commands with arguments until the last step, which will requires some interventions. Before we start, we may need intltool package

$ sudo apt-get install intltool

Now, let's get started. We have a long way to go.

ncurses

We won't use gtk+ gui interface so we need this for better command line interface.

$ ./configure --prefix=$PREFIX --host=$HOSTTPL --with-shared --with-gnu-ld
$ make
$ make install DESTDIR=$INSTALLDIR

Before going further, there is one thing you have to remember. As it is directed by the INSTALLDIR variable, the outputs will reside on the directory:

/home/user/linphone/install/usr/local

Under that directory you can find lib subdirectory where all the resulting libraries will populate. You can also find libtool archive files (*.la) there. Because we are doing cross compilation, these files usually contains wrong information so it should be deleted as soon as it is created. If you meet compilation error with strange library reference (looking for a library in the wrong place), then you should check the *.la files there.

readline

$ ./configure --prefix=$PREFIX --host=$HOSTTPL --disable-static
$ make
$ make install DESTDIR=$INSTALLDIR


libosip2

$ ./configure --prefix=$PREFIX --host=$HOSTTPL --with-gnu-ld --disable-static
$ make
$ make install DESTDIR=$INSTALLDIR


libogg

$ ./configure --prefix=$PREFIX --host=$HOSTTPL --with-gnu-ld
$ make
$ make install DESTDIR=$INSTALLDIR


libeXosip2

$ ./configure --prefix=$PREFIX --host=$HOSTTPL --with-gnu-ld --disable-static \
        OSIP_CFLAGS="-I$INSTALLDIR//usr/local/include" \
        OSIP_LIBS="-L$INSTALLDIR/usr/local/lib -losip2 -losipparser2"
$ make
$ make install DESTDIR=$INSTALLDIR

It is the good time to check the target library for the "la" files and delete them.

speex

$ ./configure --prefix=$PREFIX --host=$HOSTTPL --with-gnu-ld --disable-static \
        --enable-fixed-point --enable-arm-asm --with-ogg="$INSTALLDIR/usr/local"
$ make
$ make install DESTDIR=$INSTALLDIR


libav

$ ./configure --prefix=$PREFIX --enable-cross-compile \
        --cross-prefix=arm-none-linux-gnueabi- \
        --arch=armv6 --target-os=linux \
        --disable-ffserver --disable-ffplay --disable-ffprobe
$ make
$ make install DESTDIR=$INSTALLDIR

There are a bunch of --enable-xxx and --disable-xxx options are there. You can spend some time to fine tune the options to minimize the size of the output.

SDL

$ ./configure --prefix=$PREFIX --host=$HOSTTPL --with-gnu-ld
$ make
$ make install DESTDIR=$INSTALLDIR


libvorbis

$ ./configure --prefix=$PREFIX --host=$HOSTTPL --with-gnu-ld \
        --with-ogg="$INSTALLDIR/usr/local"
$ make
$ make install DESTDIR=$INSTALLDIR

Wednesday, August 10, 2011

Using UBIFS with CRAMFS(2)

As emphasized here, there is better (faster) method of creating UBI file system on our FLASH. We can prepare UBI volume image file with mkfs.ubifs + ubinize and populate it to our FLASH when we format the memory with ubiformat.

First create a ubi file system image with mkfs.ubifs

$ cd /home/user/nfsroot/usr
$ mkfs.ubifs -v -q -r local -m 2048 -e 258048 -c 4020 -o usrlocal.ubifs

mkfs.ubifs
      root:        local/
      min_io_size: 2048
      leb_size:    258048
      max_leb_cnt: 4020
      output:      usrlocal.ubifs
      jrn_size:    8388608
      reserved:    0
      compr:       lzo
      keyhash:     r5
      fanout:      8
      orph_lebs:   1
      super lebs:  1
      master lebs: 2
      log_lebs:    4
      lpt_lebs:    2
      orph_lebs:   1
      main_lebs:   206
      gc lebs:     1
      index lebs:  5
      leb_cnt:     216
      UUID:        910D9091-011A-4F91-AAE8-A70F1930CA08
Success!

Note that the parameter values should match with the ones we would get when we execute ubiattach on our device, such as minimum I/O unit size, size of logical erase block, maximum logical erase block count. Please refer to the previous post.

Next, we can create a ubi volume image from the file system image (usrlocal.ubifs) just created. To do that, we need to prepare configuration file, ubinize.cfg:

[ubifs]
mode=ubi
image=usrlocal.ubifs
vol_id=0
vol_type=dynamic
vol_name=usrlocal
vol_flag=autoresize

The reason we need this is that the ubinize is designed to create multiple, heterogeneous file system on a same volume image. So, fire up ubinize to create a volume image :

$ ubinize -v -o usrlocal.ubi -m 2048 -p 256KiB ubinize.cfg

ubinize: LEB size: 258048
ubinize: PEB size: 262144
ubinize: min. I/O size: 2048
ubinize: sub-page size: 2048
ubinize: VID offset: 2048
ubinize: data offset: 4096
ubinize: UBI image sequence number: 2101116498
ubinize: loaded the ini-file "ubinize.cfg"
ubinize: count of sections: 1

ubinize: parsing section "ubifs"
ubinize: mode=ubi, keep parsing
ubinize: volume type: dynamic
ubinize: volume ID: 0
ubinize: volume size was not specified in section "ubifs", assume minimum ...
ubinize: volume name: usrlocal
ubinize: volume alignment: 1
ubinize: autoresize flags found
ubinize: adding volume 0
ubinize: writing volume 0
ubinize: image file: usrlocal.ubifs

ubinize: writing layout volume
ubinize: done

Note here that the -p parameter value denotes the physical erase block size, which is different from the logical erase block size.

Now, put this ubi volume image (usrlocal.ubi) to SD card, mount it on our device to be available for ubiformat.

At the device side, unmount and detach the partition first if the ubi partition is attached and mounted as previous post:

# umount /usr/local
# ubidetach /dev/ubi_ctrl -d 0

All we have to do is just execute ubiformat utility with the prepared volume image

# ubiformat -y /dev/mtd3 -f /mnt/sdcard/usrlocal.ubi

ubiformat: warning!: your MTD system is old and it is impossible to detect ...
ubiformat: assume sub-page to be 2048
ubiformat: mtd3 (nand), size 1065353216 bytes (1016.0 MiB), 4064 eraseblocks ...
libscan: scanning eraseblock 4063 -- 100 % complete
ubiformat: 4064 eraseblocks have valid erase counter, mean value is 1
ubiformat: flashing eraseblock 217 -- 100 % complete
ubiformat: formatting eraseblock 4063 -- 100 % complete

Here we assume that the target partition is /dev/mtd3 and the ubi volume image is located at /mnt/sdcard. The warnig message about sub-page size is because we use MLC FLASH which has no sub-page.

And that's it!. UBI volume is just created with formatting. We can attach and mount the volume as before:

# ubiattach /dev/ubi_ctrl -m 3
# mount -t ubifs ubi0:usrlocal /usr/local

Using UBIFS with CRAMFS(1)

In this post, we are going to port Qt embedded on S3C6410 platform. The main CPU module consists of:
  • CPU: S3C6410(ARM1176
  • RAM: SRAM 256MB
  • FLASH: NAND 1GB(MLC type)
We assume that we have already u-boot and kernel running on the machine and that root file system (busybox) and Qt embedded are ready on our host (nfsroot).

Although, UBIFS is a good FLASH file system in most cases, we cannot use UBIFS as our root file system for some reasons. Most of all, the version of u-boot we can use for S3C6410 is v1.3.4, which has no UBIFS support features unlike recent ones. (I don't want to talk about the pathetic support from samsung for their products here but my recommendation is just avoid their products as far as you can.) Still we can use nfsroot to create UBI volume on the FLASH. But if we consider the (mass) production or on-site service, this is hardly a good choice.

Anyway, we take CRAMFS as our root file system and mount UBIFS on the /usr/local. Since CRAMFS is read-only file system, we put on the CRAMFS only minimum files required to load UBIFS, which would be busybox plus some mtd utils. For the rest of files we can locate under /usr/local directory including Qt embedded. I'm not going to describe the details here. But as usual, you can test your initial file system on NFS and deploy afterwards.

First we need an appropriate partition on our FLASH system, which is hard-coded in our kernel. For kernel-2.6.28.6 (with samsung modification), you can find the FLASH partition information here:

arch/arm/plat-s3c/include/plat/partition.h

and its contents would be:

struct mtd_partition s3c_partition_info[] = {

  /* u-boot : 0x0000.0000 - 0x0004.0000 */
  {
    .name = "bootloader",
    .offset = 0,
    .size = (256*SZ_1K),
    .mask_flags = MTD_CAP_NANDFLASH,
  },
  /* kernel : 0x0004.0000 - 0x0040.0000 */
  {
    .name = "kernel",
    .offset = (256*SZ_1K),
    .size = (4*SZ_1M) - (256*SZ_1K),
    .mask_flags = MTD_CAP_NANDFLASH,
  },
  /* cramfs : 0x40.0000 - 0x0080.0000 */
  {
    .name = "rootfs",
    .offset = (4*SZ_1M),
    .size = (4*SZ_1M),
  },
  /* ubifs : 0x0080.0000 - (end_of_FLASH) */
  {
    .name = "ubifs",
    .offset = MTDPART_OFS_APPEND,
    .size = MTDPART_SIZ_FULL,
  }
};

This will make 4 partitions  on your FLASH memory. You can check this on your device by

# cat /proc/mtd

dev:    size   erasesize  name
mtd0: 00040000 00040000 "bootloader"
mtd1: 003c0000 00040000 "kernel"
mtd2: 00400000 00040000 "rootfs"
mtd3: 3f800000 00040000 "ubifs"

At the same time, you can find corresponding devices under /dev

/dev/mtd0 - /dev/mtd3 : character devices
/dev/mtdblock0 - /dev/mtdblock3 : block devices

We will use the mtd3 partition for mounting /usr/local directory. Rest of them have no meaning for now. First erase the partition:

# flash_erase /dev/mtd3 0 0

Erasing 256 Kibyte @ 3f7c0000 -- 100 % complete

For the MTD utils used here, please refer to other post about how to cross-compile them. Then attach this partition(mtd3) to ubi drive 0:

# ubiattach /dev/ubi_ctrl -m 3

UBI: attaching mtd3 to ubi0
UBI: physical eraseblock size:   262144 bytes (256 KiB)
UBI: logical eraseblock size:    258048 bytes
UBI: smallest flash I/O unit:    2048
UBI: VID header offset:          2048 (aligned 2048)
UBI: data offset:                4096
UBI: empty MTD device detected
UBI: create volume table (copy #1)
UBI: create volume table (copy #2)
UBI: attached mtd3 to ubi0
UBI: MTD device name:            "ubifs"
UBI: MTD device size:            1016 MiB
UBI: number of good PEBs:        4064
UBI: number of bad PEBs:         0
UBI: max. allowed volumes:       128
UBI: wear-leveling threshold:    4096
UBI: number of internal volumes: 1
UBI: number of user volumes:     0
UBI: available PEBs:             4020
UBI: total number of reserved PEBs: 44
UBI: number of PEBs reserved for bad PEB handling: 40
UBI: max/mean erase counter: 0/0
UBI: background thread "ubi_bgt0d" started, PID 1253
UBI device number 0, total 4064 LEBs (1048707072 bytes, 1000.1 MiB), available 4020 LEB)

You can find some useful information about your FLASH memory here, which will be used later, such as:
  • physical erase block (PEB) size : 256KiB
  • logical erase block (LEB) size : 258048 bytes
  • available PEBs / LEBs : 4020 / 4020
  • minimum I/O unit size : 2048
If you want to detach  the partition from the ubi drive 0 then you can execute:

ubidetach /dev/ubi_ctrl -d 0

UBI: mtd3 is detached from ubi0

any time. But for now, let us just move on.

Next thing we have to do is create a volume on the drive

# ubimkvol /dev/ubi0 -N usrlocal -m

Set volume size to 1037352960
Volume ID 0, size 4020 LEBs (1037352960 bytes, 989.3 MiB), LEB size 258048 bytes ...

where usrlocal is the volume name. Now we can mount this volume to the point we want

# mount -t ubifs ubi0:usrlocal /usr/local

UBIFS: default file-system created
UBIFS: mounted UBI device 0, volume 0, name "usrlocal"
UBIFS: file system size:   1034514432 bytes (1010268 KiB, 986 MiB, 4009 LEBs)
UBIFS: journal size:       33546240 bytes (32760 KiB, 31 MiB, 130 LEBs)
UBIFS: media format:       4 (latest is 4)
UBIFS: default compressor: LZO
UBIFS: reserved for root:  5182151 bytes (5060 KiB)

At this point, we have additional MTD device :

# cat /proc/mtd

mtd0: 00040000 00040000 "bootloader"
mtd1: 003c0000 00040000 "kernel"
mtd2: 00400000 00040000 "rootfs"
mtd3: 3f800000 00040000 "ubifs"
mtd4: 3dd4c000 0003f000 "usrlocal"

Now, we can populate the directory with files we want. For example, we can archive the whole local directory in the host machine, copy the archive file on SD card, mount it on the device, and populate the directory.

# mount /dev/mmcblk0p1 /mnt
# cd /usr
# tar xvf /mnt/usrlocal.tgz local/

To mount this volume automatically every time the device boots up, we have to add the following line on the file /etc/init.d/rcS :

ubiattach /dev/ubi_ctrl -m 3
mount -t ubifs ubi0:usrlocal /usr/local

Be sure to remember that our root file system is CRAMFS. so all the change should be done on the host machine (NFS directory) and be prepared by mkcramfs utility:

$ cd /home/user
$ mkcramfs -v local/ /var/lib/tftpboot/cramfs.image

Then download and flash on your device with u-boot

> tftp 51000000 cramfs.image
> nand erase 400000 400000
> nand write 51000000 40000 40000
> reset

Many executables including Qt application, use /tmp directory for their temporary data storage. So it is required to mount tmpfs on /tmp since our root file system is read-only. Add the following line to /etc/init.d/rcS as well:

mount -n -t tmpfs -o size-32m tmpfs /tmp


Sunday, July 31, 2011

Compiling Qt Embedded 4.7.3

The version of Qt and tslib used in this article are:

qt-everywhere-opensource-src-4.7.3
tslib 2011.07.01 snapshot

Assume that the working directory is

/home/user

and all the required cross tool chain setting are already done. Be sure that you are using the same version of tool chain you have used for your ARM kernel. Otherwise tslib utilities won't work properly. If you don't have the following packages, get them now:

$ sudo apt-get install autoconf
$ sudo apt-get install libtool

tslib

Before you compile Qt embedded you may want compile tslib first. Fortunately it is quite straightforward. Get the most recent version of tslib via git

$ git clone https://github.com/kergoth/tslib.git

Configure it

$ cd tslib
$ ./autogen.sh
$ ./configure --prefix=$HOME/tslib_arm --host=arm-none-linux-gnueabi

Compile and install it

$ make
$ make install

Then you can find the resulting directories like:



At this point, you can test this on your device. Copy the resulting directories bin, etc, and lib with its subdirectory ts to the corresponding directories of your device, e.g.,

/usr/local/bin
/usr/local/etc
/usr/local/lib

The etc directory contains the configuration file, ts.conf. You need to edit the file and uncomment the line to load at least one input raw module, such as

module_raw input

And you set the following environment variables:

export TSLIB_TSDEVICE=/dev/input/event1
export TSLIB_CALIBFILE=/usr/local/etc/pointercal
export TSLIB_CONFFILE=/usr/local/etc/ts.conf
export TSLIB_PLUGINDIR=/usr/local/lib/ts
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0

You may also have to add the lib (/usr/local/lib) directory to your LD_LIBRARY_PATH :

export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

You want to put the above in your default profile (/etc/profile). Each device name varies depending on your kernel. For the detailed explanation about the variables, you can refer README file comes with tslib source.

Now you can run some executable files comes with the tslib, such as

ts_calibrate
ts_test

For the plugins (/usr/local/lib/ts), you can safely delete files you don't need. Usually you need:

dejitter.so
input.so
linear.so
pthres.so
variance.so

for your plugins.

Qt embedded

Download the qt embedded source and expand it on your working directory, e.g.,

/home/user/qt-everywhere-opensource-src-4.7.3

Before do anything, edit qmake.conf for your toolchain
mkspecs/qws/linux-arm-gnueabi-g++/qmake.conf
and add the following lines:

QMAKE_INCDIR = /home/user/tslib_arm/include
QMAKE_LIBDIR = /home/user/tslib_arm/lib
QMAKE_LFLAGS = -lts

The last line is important although it is not mentioned elsewhere.
Now you can run configure with basic parameters:

./configure -embedded arm -xplatform qws/linux-arm-gnueabi-g++ \
-qt-kbd-linuxinput -qt-mouse-tslib -qt-gfx-linuxfb \
-little-endian -prefix-install -depths 16,18,24 -optimized-qmake

You can add some additional parameters for your convenience:

-release -opensource -confirm-license

And you can also opt out unused components:

-no-webkit -no-cups -no-largefile -no-openssl -no-mmx -no-sse -no-sse2

For the explanation of each parameter you can find by running:

./configure -embedded -help

After the configure, you may want to edit ./src/corelib/Makefile and add librt link option:

set LFLAGS = -lrt ......

Now, you are ready to go

$ make
$ sudo make install

It will take more than 30minutes to finish. After deploying Qt to your device, you may have to copy additional libraries from your tool chain system such as:

(from arm-none-linux-gnueabi/libc/lib)
libdl*, libptread*, librt*
(from arm-none-linux-gnueabi/libc/usr/lib)
libstdc++.so*

Qt also requires some environmental variables to run. Add following line to your profile

export QTDIR=/usr/local/QtEmbedded-4.7.3-arm
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/lib:/usr/local/lib:$LD_LIBRARY_PATH
export QWS_MOUSE_PROTO="TSLIB:/dev/input/event1"
export QWS_KEYBOARD=TTY:/dev/tty1

Be sure to give -qws option for the first qt application you want to run.

If you have a warning like

Could not read calibration: "/etc/pointercal"

when you run qt application, then probably your calibration file is located elsewhere (/usr/local/etc) as in this example. So you have to set an environmental variable

export POINTERCAL_FILE=/usr/local/etc/pointercal

to override the default hard coded calibration file location.

additional information

Qt embedded uses /tmp as its temporary data storage. To change this, use

#define QT_PRIVATE_QWS 1
#define QT_QWS_TEMP_DIR "/usr/local/tmp

when you compile Qt.

Tuesday, July 19, 2011

Cross Compiling MTD Utils

Cross-compiling MTD utils is tricky and eLinux wiki article is out-dated. So you may need some tweaks. As of this writing, we will use the most recent versions of :
  • mtd-utils - Jul. 4 2011 snapshot
  • e2fsprogs-1.41.14
  • lzo-2.05
  • zlib-1.2.5
As in the eLinux wiki, we take

/home/user/mtd

as build directory and

/home/user/mtd/install

as target path. First, you want extract all sources under /home/user/mtd, so your build directory looks like


zlib

Go to the source directory and execute configuration utility

~/mtd$ cd zlib-1.2.5
~/mtd/zlib-1.2.5$ ./configure --prefix=/usr

prefix option here is required if you want /usr as your target root for resulting output, otherwise /usr/local will be the target directory like most cases. We have chosen to use /usr. It is yours to decide. Before building anything you have to edit the Makefile.

CROSS = arm-none-linux-gnueabi-
CC = $(CROSS)gcc
LDSHARED = $(CROSS)gcc -shared ...
CPP = $(CROSS)gcc -E
AR = $(CROSS)ar rc
RANLIB = $(CROSS)ranlib

Then you are ready to go

~/mtd/zlib-1.2.5$ make
~/mtd/zlib-1.2.5$ make install DESTDIR=/home/user/mtd/install


lzo

lzo is cross build friendly. So it is straightforward to do.

~/mtd/lzo-2.05$ ./configure --host=arm-none-linux-gnueabi --prefix=/usr
~/mtd/lzo-2.05$ make
~/mtd/lzo-2.05$ make install DESTDIR=/home/user/mtd/install


e2fsprogs

Building e2fsprogs is same with lzo

~/mtd/e2fsprogs-1.41.14$ ./configure --host=arm-none-linux-gnueabi --prefix=/usr
~/mtd/e2fsprogs-1.41.14$ make
~/mtd/e2fsprogs-1.41.14$ make install DESTDIR=/home/user/mtd/install

But for some reason, you have to copy following two files to the target directory

~/mtd/e2fsprogs-1.41.14$ mkdir ../install/usr/include/uuid
~/mtd/e2fsprogs-1.41.14$ cp lib/uuid/uuid.h ../install/usr/include/uuid
~/mtd/e2fsprogs-1.41.14$ cp lib/libuuid.a ../install/usr/lib

Note that the target directories for the above cp operation are related to your choice of --prefix option before. If you have chosen not to change the default directory, then you have to do like:

~/mtd/e2fsprogs-1.41.14$ mkdir ../install/usr/local/include/uuid
~/mtd/e2fsprogs-1.41.14$ cp lib/uuid/uuid.h ../install/usr/local/include/uuid
~/mtd/e2fsprogs-1.41.14$ cp lib/libuuid.a ../install/usr/local/lib


mtd-utils

First, You have to edit Makefile and add following at the top of the file

INSTALLDIR = /home/user/mtd/install/usr
ZLIBCPPFLAGS = -I$(INSTALLDIR)/include
LZOCPPFLAGS = -I$(INSTALLDIR)/include
ZLIBLDFLAGS = -L$(INSTALLDIR)/lib
LZOLDFLAGS = -L$(INSTALLDIR)/lib
WITHOUT_XATTR = 1
CROSS = arm-none-linux-gnueabi-
LDFLAGS += $(ZLIBLDFLAGS) $(LZOLDFLAGS)

Again note that INSTALLDIR corresponds to --prefix option before. If you have chosen not to change the target, then your INSTALLDIR here should be

INSTALLDIR = /home/user/mtd/install/usr/local

Edit common.mk and change the CFLAGS,

CFLAGS ?= -O2 -g $(ZLIBCPPFLAGS) $(LZOCPPFLAGS)

and replace the BUILDDIR

ifndef BUILDDIR
#ifeq ($(origin CROSS),undefined)
# BUILDDIR := $(CURDIR)
#else
## Remove the trailing slash to make the directory name
# BUILDDIR := $(CURDIR)/$(CROSS:-=)
#endif
BUILDDIR := $(CURDIR)
endif

Now, you are ready to build mtd-utils

~/mtd/mtd-utils$ make
~/mtd/mtd-utils$ make install DESTDIR=/home/user/mtd/install

You can find some of precompiled files here.

Tuesday, June 28, 2011

Porting FreeRTOS on miniSTM32

FreeRTOS source comes with a bunch of demos for various boards. You can choose the project for Atollic (CORTEX_STM32F100_Atollic) for your starting point. Atollic TrueSTUDIO is nothing but Eclipse with GCC, so it is almost ready to go if you are using gnu tool-chain. Besides, it has recent version of ST peripheral library. Actually this is only ST library compliant with CMSIS standard among the FreeRTOS demos.

First, gather the source code you need and put them under the ST peripheral library tree (stm32f10x_stdperiph_lib). There is a batch file in the CORTEX_STM32F100_Atollic directory:

$ CreateProjectDirectoryStructure.bat

So, you just fire it up then it will do the job for you. It collects the FreeRTOS source files and put them in the

$ FreeRTOS_Source

directory. Copy this directory under the ST library tree. Also create a demo project directory(you can use CodeLite as described in the previous post) and copy these two files:

$ Simple_Demo\FreeRTOSConfig.h
$ main.c


into the project directory. Then the directory structure would be


In the above tree, FreeRTOS_Demo is the project directory. Other file you need in the project directory is

$ stm32f10x_conf.h

Unlike other project,

$ stm32f10x_it.c
$ stm32f10x_it.h


are not used here. It's routines are replaced by FreeRTOS.

As usual, prepare Makefile and a linker script. Be sure to include the following paths

$ INCLUDEPATHS += -I ../../FreeRTOS_Source/include
$ INCLUDEPATHS += -I ../../FreeRTOS_Source/portable/GCC/ARM_CM3


in your INCLUDEPATHES and the following source codes

$ C_SRC += ../../FreeRTOS_Source/list.c
$ C_SRC += ../../FreeRTOS_Source/queue.c
$ C_SRC += ../../FreeRTOS_Source/tasks.c
$ C_SRC += ../../FreeRTOS_Source/timers.c
$ C_SRC += ../../FreeRTOS_Source/portable/GCC/ARM_CM3/port.c
$ C_SRC += ../../FreeRTOS_Source/portable/MemMang/heap_1.c


in your source list to compile. Others are pretty much the same with other projects.

In order to run the demo, you will need BSP(board support package) for your board. Fortunately, ST library comes with plenty of BSP source code for varous STM32 evaluation board and it is quite well organized. So, it is easy to make a BSP by yourself. Create a directory under Utilities/STM32_EVAL tree for miniSTM32


and write your BSP files there. STM32100E_EVAL source would be a good reference. If there is no error in the BSP, FreeRTOS demo code will be compiled with no problem.