OpenAT SDK on Linux porting HOWTO

After discussing Linux in the GCC thread, I thought I’d post my notes on how to port the OpenAT SDK to Linux.

I’m using OpenAT SDK v4.22a. For other versions, you’ll probably have to fix up some of the version numbers in the paths.

My Linux distribution is CentOS 5.1, but there’s very little here that should be distrubution-dependent.

Step 1

Install OpenAT on a Windows PC.
From the Cygwin shell, run “arm-elf-gcc -v”. This will tell you what version of GCC you need and how to configure it. This information is used in Step 2.

Step 2

Install the ARM tools (binutils, GCC, and newlib). Here’s a script that I use to build and install the tools.

WARNING: This script has no error checking. It also calls sudo a few times, which means you’ll be prompted for a password without any explination. This script is more of an example of the steps needed, than an automated build tool.

#!/bin/bash

mkdir arm-build
cd arm-build

# Download the files (you may want to use closer mirrors)
wget http://ftp.gnu.org/gnu/binutils/binutils-2.16.1.tar.bz2
lftpget ftp://mirrors.laffeycomputer.com/pub/gcc.gnu.org/pub/gcc/releases/gcc-4.0.1/gcc-core-4.0.1.tar.bz2
lftpget ftp://sources.redhat.com/pub/newlib/newlib-1.13.0.tar.gz
# I don't know if this version of t-arm-elf is needed, but I used it anyway...
wget http://gnuarm.com/t-arm-elf

# Build & Install binutils
tar xvfj binutils-2.16.1.tar.bz2
mkdir binutils-2.16.1-arm
cd binutils-2.16.1-arm/
../binutils-2.16.1/configure --target=arm-elf --enable-shared --enable-threads --enable-interwork --enable-multilib --with-float=soft
make
sudo make install
cd ..

# Extract newlib (gcc needs it)
tar xvfz newlib-1.13.0.tar.gz

# Build & Install gcc
tar xvfj gcc-core-4.0.1.tar.bz2
cp t-arm-elf gcc-4.0.1/gcc/config/arm
mkdir gcc-4.0.1-arm
cd gcc-4.0.1-arm/
../gcc-4.0.1/configure --target=arm-elf --enable-shared --enable-threads --enable-interwork --enable-multilib --enable-languages="c" --with-newlib --without-headers --with-float=soft
make all-gcc
sudo make install-gcc
cd ..

# Finish building & install newlib
mkdir newlib-1.13.0-arm
cd newlib-1.13.0-arm/
../newlib-1.13.0/configure --target=arm-elf --enable-shared --enable-threads --enable-interwork --enable-multilib --with-float=soft
make
sudo make install
cd ..

# Finish building & installing gcc
cd gcc-4.0.1-arm/
../gcc-4.0.1/configure --target=arm-elf --enable-shared --enable-threads --enable-interwork --enable-multilib --enable-languages="c" --with-newlib --with-float=soft
make all
sudo make install
cd ..

# All done.  Leave the arm-build directory.
cd ..

Step 3

UPDATE: With the Makefile listed in this topic: viewtopic.php?t=2388 you can skip step 3 all together (except for copying the OpenAT directory to your Linux home directory).

To port OpenAT to Linux, copy the OpenAT directory from the Windows PC to your home directory on the Linux PC and run this script.

WARNING: This script has no error checking. It also calls sudo, which means you’ll be prompted for a password without any explination. This script is more of an example of the steps needed, than an automated build tool.

#!/bin/bash

####################
# create the ~/.oatrc file
cat >~/.oatrc <<OATRC_END
export WM_OAT_IDE_OS_DEFAULT="\$HOME/OpenAT/OS/4.21.01"
export WM_OAT_IDE_FW_DEFAULT="\$HOME/OpenAT/Firmware/663"
export WM_OAT_IDE_PLUGINS="\$HOME/OpenAT/Plug-ins"
export WM_OAT_IDE_GTS_GCC="/usr/local"
export WM_OAT_IDE_ECLIPSE="\$HOME/OpenAT/IDE/Eclipse/3.2.2"
OATRC_END

####################
# modify environment variables
cat >>~/.bash_profile <<BASH_PROFILE_END

export WM_OAT_IDE=\$HOME/OpenAT/IDE/IDE/1.04.06
export WM_OAT_IDE_ENV=linux
export PATH=\$PATH:\$WM_OAT_IDE/bin:\$WM_OAT_IDE/sgt/script_sgt
export SGT_DIR=\$WM_OAT_IDE/sgt
export SGT_SCRIPT=\$WM_OAT_IDE/sgt/script_sgt
export SGT_VER=v1.2.12oat
BASH_PROFILE_END

####################
# fix for building BAT files (which we don't use anyway)
cd ~/OpenAT/IDE/IDE/1.04.06/
touch bin/crlf
chmod +x bin/crlf

####################
# fix embedded scripts with missing semicolons
for mak in `ls sgt/mak/*`; do sed -i "s/done\\\\/done;\\\\/;s/fi\\\\/fi;\\\\/" $mak; done

####################
# move script to where the build environment expects to find it
sudo install -m 755 ../../GCC/4.0.1.0/bin/fromelf /usr/local/bin/

####################
# don't specify the path to zip in the build environment, just use $PATH
sed -i "s./usr/local/bin/zip.zip." sgt/mak/tools.mak

####################
# fix the path to AXFshrinker
sed -i "s:/projet/tools/share/Tatoo/AXFshrinker/V1.0.0.1:\\\${SGT_DIR}/tools/linux:" bin/wmmake

####################
# remove unused directories
cd ~/OpenAT/IDE/
rm -rf Eclipse GCC MINGW IDE/1.04.06/cygwin IDE/1.04.06/MINGWlogger

That’s it. It should be usable. Since ~/.bash_profile was modified, you’ll need to restart bash to get it to reload it.
I haven’t tried Eclipse under Linux, but there’s no reason it shouldn’t work. (I believe building under Eclipse invokes LoadIde.bat, so that’ll need to change, but that eventually calls OpenAT/IDE/IDE/1.04.06/LoadIde.sh so it shouldn’t be hard to change.)
You may way to read chapter 8 in ~/OpenAT/IDE/IDE/1.04.06/doc/TM_Tools_Manual_for_Open_AT.pdf
to learn the command line tools for making new projects, etc. Here’s a quick primer:

To make a new project or to update an existing project, use wmnew.
An example of creating a new project:

wmnew -adl -app -mem 256KB -gts GCC -plugin WIP/3.00.09 -n -name my_new_proj

An example of updating the project:

wmnew -adl -app -mem 256KB -gts GCC -plugin WIP/3.00.09

To build code, use “wmmake”.

To load the code using minicom, I had to edit the file transfer protocols and add these two protocols (you really only need the first one):

J  xmodem-1K  /usr/bin/sx -vv --1k            Y    U    N       Y       N
  K  xmodem-1K  /usr/bin/rx -vv --1k            Y    D    N       Y       N

After typing “AT+WDWL”, I found that hitting Cntl-A a couple of times before starting the file transfer (Cntl-A, S) made the transfer work reliably. I have no idea why this works and I don’t like it. Eventually I’ll spend the time to understand what’s going on, but I usually update via DOTA so I haven’t been using minicom much.

Hopefully, this post isn’t information overkill. It’s a modified cut-and-paste of my notes, so I hope I didn’t get out of hand…

If you use Linux, make sure your Wavecom distributor knows. With enough feedback, the Wavecom developers may be motivated to make this easier. I’ve already bugged my Wavecom contacts. :slight_smile:

Thanks for the post! It couldn’t be easier!

I tried it with a debian/etch distribution. It worked quite well. However I have following suggestions:

For debian you need the following packages: gcc, g++, xsltproc, gawk

When you copy OpenAT from windows, you should probably do something like:

cd OpenAT/IDE/IDE/1.04.07/
chmod +x -R *

Last but not least, when importig existing projects make sure wmnew.opt is up-to-date, after that you only have to run

wmnew
wmmake all_clean
wmmake

Regards,

wismo_coder

Excellent. Thanks very much for the post

Dan

I’m installing on Ubuntu and I’ve run into some problems with wmnew. I get the following error:

dan@dan:~/geobox/tracker$ wmnew -adl -app -mem 256KB -gts GCC -plugin WIP/3.00.09 -plugin C-GPS/1.01.2000 -n -name tracker
Copying New_Project sample files…
awk: node.c:515: unref: Assertion (tmp->flags & 4096) != 0' failed. /home/dan/OpenAT/IDE/IDE/1.04.06/bin/wmnew: line 602: 24634 Aborted (core dumped) wmtxtpp ${AddPrefix}../resources "file://$SampleSetRootResources/resources" "${AddPrefix}../generic/Libraries" "Libraries" $RootReadmeReplaceStr $i Building tracker project settings file... awk: node.c:515: unref: Assertion(tmp->flags & 4096) != 0’ failed.
/home/dan/OpenAT/IDE/IDE/1.04.06/bin/wmnew: line 901: 24648 Aborted (core dumped) wmtxtpp “{DELIVERY}” “$Delivery” “{OBJ_DELIVERY}” “$ObjDelivery” “{OS}” “$WM_OAT_PRJ_OS” “{FW}” “$WM_OAT_PRJ_FW” “{GTS}” “$gts” “{MEM}” “$mem” “{IDE}” “$ide” “{NAME}” “$name” “{PROJECT}” “$tgt” “{API}” “$api” “{GCC_STACK_FACTOR}” “$StackSizeFactor” “{VERSION}” “$Version” $name.scs
awk: node.c:515: unref: Assertion `(tmp->flags & 4096) != 0’ failed.
/home/dan/OpenAT/IDE/IDE/1.04.06/bin/wmnew: line 1100: 24734 Aborted (core dumped) wmtxtpp “” “${srclist}” “” “${asmlist}” $name.scs

When I run wmcheck it comes up with this error:
[wmcheck error #12] Unable to load the {OS} OS required by the project.

Hope someone can help.

Thanks

Dan

Dan,

I don’t know the exact cause of the error, but doing a little googling shows that a few bugs that caused that error message have been fixed in recent versions of awk. What version of gawk are you using? Can you update it to 3.1.6 and try again?

What version of Ubuntu are you using? Are you using a language other than English? It looks like there’s at least one of the gawk bugs had to do with Unicode. If I can reproduce your environment, maybe I could debug the error.

I’m using gawk 3.1.5 on Ubuntu 7.04. Gawk 3.1.5 is the most current for any Ubuntu release, so to upgrade looks like I’ll have to install from the source code.

I’m getting closer. Installed gawk 3.1.6 from source. If anyone else does this note that you have to change the awk link to point to the new gawk. This time the wmnew did what it was supposed to do.

So I did a wmmake and it built in seconds rather than minutes!

But I get a rather cryptic link error:
make: *** [make_single_bin] Error 1

Went back to the “hello world” sample:
wmnew -adl -app -mem 256KB -gts GCC -n -name hello

But I get the same link error.

Do the Wavecom libraries need to be re-built?

Dan

There should have been another error message buried in the text above that message. That message is just saying that a program that was called by make returned an error. Whatever program make called should have printed out it’s own (more helpful) error message. If you don’t see anything useful, run ‘wmmake all_clean’ and then ‘wmmake’ and then post the output of wmmake.

No.

EDIT: Out of curiosity, I’ve installed Ubuntu and will be trying this out. But setting everything up is taking a while, so I won’t finish until tomorrow…

Well I’ve found the source of the link error, and no, there wasn’t much of any diagnostic output when it originally came up. I’ve had these link errors before and they don’t tell you what the problem is.

The wmnew command creates a file called appli.c in the src directory. It’s just a stub but it has it’s own adl_main which conflicted with the ‘real’ adl_main in another file. I commented out all the code in applic.c and now the build works. I’m obviously doing something wrong with wmnew but it shouldn’t be too hard to figure out how to fix it with something other than the hack I’ve done.

At any rate it’s good to have this up and running, almost, on Linux. Wavecom needs to get their act together because I’m sure that the excessively long build times under Windows are putting developers off.

I have some questions about gcc but will save them for another post.

Thanks for you help, it has been much appreciated.

Well I’m extremely happy. I’ve sorted out my build problems and have successfully built and downloaded from Ubuntu. Build time is down to seconds rather than minutes. Minicom lets me scroll back to see where I’ve been (something that hyperterminal doesn’t do). And I no longer have to work from Windows.

Note to Minicom users on Ubuntu, you will need to install the lrzsz package separately in order to get xmodem transfers.

Many thanks to Matt for starting the Howto.

Sounds like you asked it to create a New project, rather than update an existing one?

Excellent post! Worked like a charm on Fedora Core 8 1.06.04.

All suggested replacements on the scripts were necessary for this version also.

I only needed to add a .oatrc file in my home directory with the following lines (or add them to ~.bash_profile):

export WM_OAT_IDE_OS_DEFAULT="$OAT_HOME/OS/4.23.02"
export WM_OAT_IDE_FW_DEFAULT="$OAT_HOME/Firmware/663c00"
export WM_OAT_IDE_PLUGINS="$OAT_HOME/Plug-ins"
export WM_OAT_IDE_GTS_GCC=/usr/local/

where OAT_HOME points to the OpenAT installation directory.

When migrating my app to OS 6.01.07, I had to perform an additional task to build on Fedora Core 8. Apparently, wm_types.h requires stdint.h to be available in the arm-elf/include directory installed by GCC.

However, stdint.h is not included in GCC; it’s a part of glibc. Therefore my apps failed to compile. OpenAT SDK seems to use a GCC 4.0.1.1 version, which, AFAIK, doesn’t exist (4.0.1 does), maybe is a version modified by wavecom to include this file (since the rest of the files included by GCC 4.0.1 re a perfect match to Wavecom’s).

I had to copy the stdint.h file included in Wavecom’s GCC for windows (OpenAT/IDE/GCC/4.0.1.1/arm-elf/include/stdint.h) to the arm-elf/include dir installed by GCC. After that everything compiled ok.

Well, in theory, you should get stdint.h from newlib, but I just checked and stdint.h isn’t in /usr/local/arm-elf/include/. Apparently, stdint.h only gets installed if the target is “linux” (not “arm”, which what we use for Wavecom), because the file is in newlib-1.13.0/newlib/libc/sys/linux/include/stdint.h but not …/sys/arm/.

Hmm, it looks like every SDK version has its own quirks. Glad you hear you got it working!

Talking about quirks…

After having used FW 6.63 successfully for months on linux I wanted to upgrade to FW R72 and OS 6.11.01. I had to do the following changes for it to work:

  • manually copy stdint.h like santi mentioned
  • make a few more scripts executable with chmod +x
  • change the SGT version from 1.2.12oat to 1.12.20 (and change all the other versions, too, of course)
    That’s all it takes for the compilation process to go smoothly.
    Now imagine my surprise when I wanted install the freshly generated binaries on my Q2686 and I got error messages repeatedly that the .dwl file cannot be installed. No matter what program I use to flash my module, the result is always the same.

I’m still trying to figure out what went wrong… If somebody has any idea at all about all that, please post it!

Best regards,

wismo_coder

I have tried to port OpenAT SDK on Linux too. I made a toolchain using script, posted at the begining of this thread.
I compiled it using the following Makefile (using linker.opt file from my windows compilation):

# Name of the resulting application, without extension
APP_NAME    = sample-app

# Basic paths
OAT_ROOT = /opt/OpenAT
GCC_ROOT = /usr/local
OAT_GCC_ROOT = /opt/OpenAT/IDE/GCC/4.0.1.0

OS = linux

# Version numbers
OS_VERSION  = 4.22.00
IDE_VERSION = 1.04.07
WIP_VERSION = 3.10.2034
GCC_VERSION = 4.0.1
OAT_GCC_VERSION = 4.0.1

#
# With luck, you shouldn't need to edit anything below here.
#

# use the first two parts of the version, and remove the period between them
OAT_API_VERSION = $(word 1, $(subst ., ,$(OS_VERSION)))$(word 2, $(subst ., ,$(OS_VERSION)))
WIP_PLUGIN_VERSION = $(word 1, $(subst ., ,$(WIP_VERSION)))$(word 2, $(subst ., ,$(WIP_VERSION)))

# Paths to Open AT header files
INCLUDES = \
   -I$(OAT_ROOT)/OS/$(OS_VERSION)/ADL/itf \
   -I$(OAT_ROOT)/OS/$(OS_VERSION)/ADL/basic \
   -I$(OAT_ROOT)/Plug-ins/WIP/$(WIP_VERSION)/WIP/itf \
   -I$(OAT_GCC_ROOT)/lib/gcc/arm-elf/$(OAT_GCC_VERSION)/include \
   -I$(GCC_ROOT)/arm-elf/include \

# Paths to local header files
INCLUDES += \
   -I../itf \
   -I../inc \

# Paths to other user-defined library headers
INCLUDES +=

# Paths where source files might be found (relative or absolute, space-separated)
VPATH = ../src

# Either list all source files of this project (excluding libraries),
# or use the second option, which automatically uses all .c files in VPATH
#SRC = appli.c
SRC := $(notdir $(foreach dir, $(VPATH), $(wildcard $(dir)/*.c)))

# C compiler settings
CC     = $(GCC_ROOT)/bin/arm-elf-gcc
#CC_COMMON_FLAGS = -Os -O2 -fshort-enums -nostartfiles -mapcs -mthumb -mthumb-interwork -mno-apcs-stack-check -msoft-float -mfpu=fpa -fdollars-in-identifiers -fomit-frame-pointer -ggdb3 -nostdinc -march=armv5te
CC_COMMON_FLAGS = -O2 -fshort-enums -nostartfiles -mapcs -mthumb -mthumb-interwork -mno-apcs-stack-check -msoft-float -mfpu=fpa -fdollars-in-identifiers -fomit-frame-pointer -ggdb3 -nostdinc -march=armv5te
CFLAGS = -D__WIP_PLUGIN_VERSION__=$(WIP_PLUGIN_VERSION) -D__OAT_API_VERSION__=$(OAT_API_VERSION) -D__DEBUG_APP__ -D__arm -D__GNU_GCC__  $(CC_COMMON_FLAGS)

# C linker settings for application generation
LINK       = $(GCC_ROOT)/bin/arm-elf-gcc
LINK_FLAGS = $(CC_COMMON_FLAGS) -Wl,--script,$(OAT_ROOT)/linker.opt,--nmagic,-Map,mapfile

# GCC tools
AR = $(GCC_ROOT)/bin/arm-elf-ar
OBJCOPY = $(GCC_ROOT)/bin/arm-elf-objcopy

# Various tools, from Open AT
ADDCHECK = $(OAT_ROOT)/IDE/IDE/$(IDE_VERSION)/sgt/tools/$(OS)/addchk
AXFSHRINKER = $(OAT_ROOT)/IDE/IDE/$(IDE_VERSION)/sgt/tools/$(OS)/AXFshrinker
WZPACKER = $(OAT_ROOT)/IDE/IDE/$(IDE_VERSION)/sgt/tools/$(OS)/wzpacker
GENDWL   = $(OAT_ROOT)/IDE/IDE/$(IDE_VERSION)/sgt/tools/$(OS)/genbin

# Library binaries to link to the project
LIBRARIES  = $(wildcard $(OAT_ROOT)/OS/$(OS_VERSION)/ADL/gcc_wmadl_*.lib)
LIBRARIES += $(wildcard $(OAT_ROOT)/Plug-ins/WIP/$(WIP_VERSION)/WIP/gcc_wmwip_*.lib)
LIBRARIES += $(wildcard $(OAT_ROOT)/Plug-ins/WIP/$(WIP_VERSION)/WIP/gcc_wmwipSoft_*.lib)

# By default, build the compressed binary
all: $(APP_NAME).wpb.dwl

clean:
        rm *.axf *.elf *.bin *.wpb *.o *.dwl s mapfile opec_header.o genBin.trc

# Generation of TMT traces file. Not functional yet.
backtraces.axf: $(APP_NAME).elf
        $(AXFSHRINKER) $< $@

# Usual C compilation rule
%.o: %.c
        $(CC) -MD $(CFLAGS) $(INCLUDES) -c $< -o $@
        @cp $*.d $*.P; \
            sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
                -e '/^$$/ d' -e 's/$$/ :/' < $*.d >> $*.P; \
            rm -f $*.d

-include $(SRC:.c=.P)

opec_header.o:
        $(AR) -x $(wildcard $(OAT_ROOT)/OS/$(OS_VERSION)/ADL/gcc_wmadl_*.lib) $@

# Link of object files and libraries
$(APP_NAME).elf: $(SRC:.c=.o) opec_header.o
        $(LINK) $(LINK_FLAGS) $+ $(LIBRARIES) -o $@

# Convert linked binary into a signed .bin file
# the first four lines were copied from the Linux version of fromelf
%.bin: %.elf
        $(OBJCOPY) --strip-all --strip-debug --strip-unneeded --discard-all --weaken $*.elf $*.tmp || (RVAL=$$?; rm -f $*.tmp; exit $$RVAL)
        $(OBJCOPY) --output-target binary $*.tmp $*.tmp2 || (RVAL=$$?; rm -f $*.tmp $*.tmp2; exit $$RVAL)
        dd if=$*.tmp2 of=$*.bin bs=4 conv=sync || (RVAL=$$?; rm -f $*.tmp $*.tmp2; exit $$RVAL)
        rm -f $*.tmp $*.tmp2
        $(ADDCHECK) $@

# Compressed version of the .bin file
%.wpb: %.bin
        $(WZPACKER) -b 0x00210000 $<

# Non-compressed, X-MODEM downloadable of the .bin file
%.dwl: %.bin
        $(GENDWL) -bin $< -dwl $@ -adr 0x00210000

# X-MODEM downloadable version of the compressed binary file
%.wpb.dwl: %.wpb
        $(GENDWL) -bin $< -dwl $@ -adr 0x00210000 -header BINCOM

.PHONY: all clean

It compiled successfully. I sent it to my Wavecom Q2686 Wireless CPU, sucessfully completed upload process, and typed:

AT+CFUN=1 (reboot)
AT+WOPEN=1 (start application)

After that Wireless CPU stopped answering to my communication (AT commands etc), and didn’t start my application at all. I also have to add, that this application works, when compiled on Windows, using Wavecom’s gui-tools from SDK, with cygwin-gcc as a compiler.

Has anybody had the same issue or know what I did wrong?

Are you using the Windows gcc that ships with the SDK? I recommend you build a Linux version if you are. (I don’t know if this would cause your problem, but it’s certainly not as efficent.)

Does a simple “Hello World” program work? It’s hard to know what’s going on (is it hung, or continuously rebooting, etc.), so starting with a simple program may help understand the problem.

I use Linux-GCC to compile it; I needed OAT_GCC_ROOT variable in my Makefile to include some files, which doesn’t came with mine linux-gcc.

Ok - I found the problem. When I use:

const u16 wm_apmCustomStackSize = 1024;

everything works fine. When I change it to:

const u16 wm_apmCustomStackSize = 2048;

it doesn’t (even a simple “Hello world” application). Whats more, on windows both versions works…

Has anybody any idea why that happens and how to fix it?

That’s odd… Mine’s:

const u16 wm_apmCustomStackSize = 4096;

You said you used the linker.opt from your Windows environment. How does it compare to the one I posted here: viewtopic.php?t=2388#p8847

All I can think of is that your memory layout isn’t quite right. :confused:

I compared mine and yours liknker.opt files and they are the same. I also tried:

const u16 wm_apmCustomStackSize = 4096;

and it works… It’s weird but I don’t think I need to care about it if 4096 value works.