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.

Monday, June 27, 2011

STM32F GCC IDE on Windows(2)

Test Project Build
Let's test build with some examples provided by ST. First copy the GPIO/IOToggle source files to the project directory just created.



Then create a make file and linker script file for the project. In this state, you can build(F7) and clean the project as you typed in the previous post. Actually everything is done by make utility and CodeLite is just invoking it.

It would be nice you can navigate and edit each file. At the left Workspace pane, right click on the project name and select the "Import Files from Directory".


Then you can select directories(and files) you want to show on your Workspace pane, which will probably match the source list of your Makefile. If there is no (sub)directories to select, you can choose as many as you want by clicking the Browse button on the top right of the dialog.


Resulting directory structure probably matches the source list of your Makefile. Be sure to remember that this tree is created regardless of project structure itself and you are not suppose to compile each individual file.

Flash Utility Integration
You can bring up the external flash utilities by registering those as external tools. Select Plugins-> External tools ->Configure external tools or just click the corresponding button from the menu bar


Then you can register your flash program.


Surely it is not as convenient as a native flasher but it is still useful.

Sunday, June 26, 2011

STM32F GCC IDE on Windows(1)

You can easily build a GCC IDE for Cortex-M3 using a open source IDE.  If you are not a big fan of Eclipse like me, you will probably like CodeLite or Geany. Both programs are cross platform, open source, and light-weight. Geany is more minimalistic of two. If you are familiar with Visual Studio, you will find CodeLite is more comfortable.

I'm going to use the following programs:


GCC and Make
For the CSG++ Lite, be sure to download the installer version(EABI). Install is straight forward. You don't have to change any settings. After install, you should add the following directory to your PATH.

> C:\Program Files\CodeSourcery\Sourcery G++ Lite\bin

You can verify that your PATH is set up correctly by running

> arm-none-eabi-gcc -v

on your console window.
Other than the compiler collection, you may need at least GNU make utility. You can install Cygwin for the make utility. But the simplest way is using GnuWin32. Download and install the GnuWin32 make package. You also have to add its bin directory to you PATH. You can install as many GnuWin32 packages as you need.

> C:\Program Files\GnuWin32\bin

STM32F Library and CodeLite Project
Download the library(stm32f10x_stdperiph_lib.zip) and extract it on your work directory. Then install CodeLite and fire it up to create initial workspace and project. For convenience, create a Codelite workspace under the STM32F library directory. (Workspace->New Workspace)


By selecting the workspace name and path as shown and deselecting the "Create the workspace under a separate directory" check box, you can use the STM32F library project directory as your workspace. But it is only for convenience sake. You can choose your workspace anywhere you like.

Now create a new project.(Workspace->New Project)


For the Categories, choose "Others" then you can select "Custom Makefile" type for the template. Type in your project name. And select compiler type. Compiler type here is not important because you will use your own build and compile command strings. Resulting directory structure would be



For now, there is no file under GpioTest directory except the CodeLite project file.

After the  project creation, go to the project settings by right click on the project "GpioTest" and select the last menu item.


Go to "Customize" on the left, then check "Enable custom build". You want  change "Working Directory" from $(WorkspacePath) to $(ProjectPath) where you have your own Makefile. Now fill in the Build Command with "make" and the Clean Command with "make clean". In this way, you can use your Makefile to build your project instead of CodeLite's own makefile.

Sunday, May 8, 2011

JLink with BeagleBoard

If you hook-up JLink to BeagleBoard and execute JLink commander, then you probably get the following error:

****** Error: DBEGN is not asserted.

And fail to recognise the target. This is because TI OMAP3530 needs a special setup sequence for JLink to connect, which is controlled by JLink script file (Default.JLinkScript)

Find the script file:

$JLINK_INST_DIR$\Samples\JLink\Scripts\ScriptBeagleBoard...

Copy it to the base directory(Windows) or the current directory(Linux) and rename it to

Default.JLinkScript

Then you can successfully connect to the board.

VMware Player on Xubuntu

Xubuntu : 10.10 / 11.04
VMware-Player : 3.1.3-385536

Be sure to install the following packages before installing vmware-player

- libglibmm-2.4-1c2a
- libgnomecanvasmm-2.6-1c2a

Otherwise you cannot fire-up the installer, not to mention the player itself.
If you encounter another issue after the install, check this out.

Thursday, April 7, 2011

NTFS-3G options: umask, dmask, and fmask

If you mount your ntfs partition with default options, you may have different 'default file creation permission' with your linux partition. Sometimes, this makes nasty issues. For example, when you clone a git repository from a remote, your checked-out files and directories might have different permissions with the original ones.

Basically, for the newly created directories and files, linux assigns permission 777 for the directories and assigns permission 666 for the files. And umask  (/etc/profile) is applied here.  Default value of umask is 022(0022). So if you create a directory, it will have the default permission value 755. If it is a file, it's permission will be 644.

If you mount your ntfs partition with default options, umask, dmask, and fmask are all 0000.  It implies that all the directories and files you created on the ntfs partition will have the permission 777. For the compatibility, you have to set:

umask= 0022
dmask=0000 (makes default directory permision 777)
fmask=0111 (makes default file permission 666)

Friday, March 4, 2011

AT91SAM7S-EK linux toolchain

SAM-BA

AT91SAM series, equipped with USB device capability, provide SAM-BA interface for easy downloading their firmware without JTAGs or any ISP tools.  First, you may want ATMEL SAM-BA software for linux here. Depending on your linux settings (kernel maybe) you may need usbserial module also.

Just plug in your SAM board to the usb port and see what happens. lsusb shows how your linux box recognize your SAM board:

Bus 002 Device 023: ID 03eb:6124 Atmel Corp. ......

The vendor id 0x03eb is dedicated to Atmel. Then you can check how you linux box connect it to a device driver by running dmesg

[50341.865033] cdc-acm 2-5.2:1.0: ttyACM0: USB ACM device

If you find the message like above, you probably have newly created device in /dev:

crw-rw---- 1 root dialout 166, 0 2011-03-04 12:15 /dev/ttyACM0

Since SAM-BA uses /dev/ttyUSBx, you have to create a symbolic link:

$ sudo ln -s /dev/ttyACM0 /dev/ttyUSB0

Now, you are ready to fire up the SAM-BA

$ ./sam-ba

If the above senario is not the case for you, you may need usbserial kernel module, which is explained in the README.linux file of the SAM-BA linux software, i.e., you load the usbserial module:

$ sudo modprobe usbserial vendor=0x03eb product=0x6124

Then you will have /dev/ttyUSBx device when you plug in your SAM board.

Thursday, March 3, 2011

EFM32STK linux toolchain

Sourcery G++ (Lite)

EFM32STK comes with CodeSourcery examples so you don't have to bother with constructing your own startup code and linker script. Install the CodeSourcery toolchain(bare metal), then all you have to do is changing a couple of lines in the Makefile

  TOOLDIR = /your/CodeSourcery/toolchain/root
  GCCVERSION = x.x.x

You can get your compiler version by firing up

  $ arm-none-eabi-gcc --version

All the examples would be compiled without any complaints and ready to go. You can find your executable image files in the 'exe' subdirectory

Segger embedded J-Link

Thanks to the segger J-Link module embedded in the EFM32 STK board, you can use segger linux driver. Actually the STK itself could be utilized as a (standard) j-link tool. Unlike other vendor specific J-Link tools, there seems to be no limitation in using this. It might be used to other ARM devices (ARM7, ARM9/11, Cortex-M) as well as EFM32G devices. I will give it a try later. (UPDATE: It seems that the embedded J-Link does not work as a standard J-Link tool. You cannot even change the target chain from SWD to JTAG without help of EnergyCommander, which runs only on Windows, not to mention detecting a device on its JTAG connector) Anyway, grab the segger linux driver here and install it. Then you can flash your STK board with the J-Link Commander(just run start):

  J-Link>exec device = EFM32G890F128
  J-Link>loadbin /your/image/file/directory/xxx.bin 0x0
  J-Link>r
  J-Link>g

When is comes to debugging, you want execute gdb server with SWD option, because the efm32g processor is not on the JTAG chain but on the SWD,

  $ JLinkGDBServer -if SWD

then, gdb

  $ arm-none-eabi-gdb  /your/exe/directory/xxx.out

Unfortunately, when you connect the jlinkgdbserver,

  (gdb) target remote localhost:2331

you will get the following error:

  Remote 'g' packet reply is too long: 00000000000....

This is an known issue (at least for JLink_Linux_V422 with arm-2010.09-51-arm-none-eabi). You have to wait until they release  a fixed version of linux driver. So for now, without gdb compatibility EFM32STK provides quite limited usage on linux. To make things worse, segger windows j-link driver does not work on virtual machine (vmware player).

Flowgraph generation for the examples

By adding a few lines in the Makefile provided with the examples, you can easily generate a flowgraph of the source, i.e., you may want to add, at the end of the Makefile,

    CFLOWFLAGS = -a --omit-arguments --omit-symbol-names
    CPPFLAGS = --cpp='arm-none-eabi-cpp -E -D $(DEVICE)'
    cflow: $(C_SRC) Makefile
        cflow -o $(LST_DIR)/$(PROJECTNAME).cflow \
        $(CFLOWFLAGS)$(INCLUDEPATHS) $(CPPFLAGS) $(C_SRC)

Then execute :
  
    make cflow

will generate cflow outout in the lst directory. It is needless to mention that you have to install cflow first before using it.