Thursday 2 December 2010

XSVF Player on MicroBlaze (JTAG Interface)

This post describes how to implement a JTAG configuration device using C and general purpose input/output (GPIO) on a MicroBlaze based embedded sytem. A Digilent NEXYS-2 board and Xilinx ISE/EDK 10.1.03 are used for this example.

The code is based on Xilinx Application Note XAPP058 and the code provided with it.

An example EDK project can be downloaded here.

The idea is to:
  • run the system provided on a NEXYS-2 board.
  • connect the JTAG port of a another FPGA/ FPGA board to GPIO of the first one.
  • download the configuration file for the devices on the second board in XSVF format to the RAM of the NEXYS-2 board.
  • run the XSVF player on the NEXYS-2 board in order to configure the devices on the second board.
Here are the steps to be taken in a bit more detail:

A. Prepare the configuration file for the device(s) you want to configure:

  1. Create BIT file(s) for the devices you want to configure.
  2. Use Xilinx IMPACT tool to create an XSVF file for the device(s) you want to configure. This works simply by running impact in GUI mode, setting up a project with all devices of the target board in the configuration chain and assigning BIT files.
    The final step is then to go to Output -> XSVF File -> Create XSVF File in order to generate the XSVF configuration file that can be used by the XSVF player.

B. Create the hardware and software for the NEXYS-2 board:
  1. download the example EDK project, unzip it and open it in EDK.
  2. use Device Configuration -> Update Bitstream to create the BIT file for the NEXYS-2 board, which contains the MicroBlaze based hardware system.
  3. go to a console and change into the "code" subfolder within the EDK project folder.
  4. open the "Makefile" in a text editor and adjust the two variables EDK_PROJECT_PATH and EDK_LIB_PATH to point to the EDK project paths where you have unzipped it to on your harddisk.
  5. go back to the console and type Make to build the XSVF Player software application. Note that you now should have an ELF file "xsvf_player.elf" in the "code" folder.

C. Download and run the hardware and software system / configuration files:
  1. connect a Xilinx programming cable to the NEXYS-2 board.
  2. connect a serial cable to the NEXYS-2 and your PC for MicroBlaze OS printfs.
  3. connect the GPIO used for the XSVF Player to the JTAG port of the second board you want to configure.
  4. go to the top-level folder of your EDK project and configure the Spartan FPGA on the NEXYS-2 board:
    impact -batch ./etc/download.cmd
  5. go to the "code" folder containing the compiled ELF file of the XSVF Player.
  6. run the Xilinx Embedded Debugger XMD: xmd and download/ run the ELF file:
  7. connect mb mdm -cable type xilinx_platformusb port usb21
  8. stop
  9. dow -data 0xcbf00000
  10. dow JTAG_SVF_Player_MBlaze/xsvf_player.elf
  11. run
  12. exit
  13. after exiting XMD:
  14. change the serial port specified in the Python script "comm_mblaze.py" to the one where your NEXYS-2 board is attached, save and
  15. run the Python skript, which communicates with the FPGA:
  16. ./comm_mblaze.py
  17. when you are asked for input, type "R" and "Enter". This will then run the XSVF Player that reads the configuration file for the target device(s) from RAM and configure them.

Notes:

  • The JTAG signals are written to a log-file on your computer if you specify the flag -DDEBUG_MODE in the Makefile (see Makefile).
  • In case you do not have a target device attached, which can deliver appropriate TDO signals, you can do a DUMMY run by specifying -DDEBUG_TDO_DONTCARE in the Makefile (see Makefile).
  • In the example above, you can store the XSVF configuration file wherever you want in the RAM, by specifying other addresses within the RAM (see item 9). Make sure to change the address in "defines.h" as well.

Friday 15 October 2010

Install Player-Stage Robot Simulator under Linux

Make sure to install the necessary packages (particularly for graphics output)

sudo aptitude install libfltk-dev libfltk
sudo aptitude install autoconf automake

If someting fails during ''autoreconf -i'' later, fire up Synaptic and check whether the **latest** version is installed!


It's worth installing Player/Stage locally in your home!

This example will assume the PATH from below

cd
mkdir player-stage
cd player-stage

NOTE after installation, you'll end up with folders 'bin', 'include' and 'lib' here, which represents the local installation tree.


Check out the sources for player-stage from their SVN

I recommend version 2.1, as it is the most stable so far.

svn co https://playerstage.svn.sourceforge.net/svnroot/playerstage/code/player/branches/release-2-1-patches/ player-2.1
svn co https://playerstage.svn.sourceforge.net/svnroot/playerstage/code/stage/branches/release-2-1-patches/ stage-2.1


Install Player

INSTALL PLAYER FIRST! Stage is a module to Player and is compiled afterwards.

cd player-2.1
autoreconf -i
./configure --prefix=$HOME/player-stage/ps-2.1
make install

NOTE after running "autoreconf", insert the following line into "Makefile.am":
ACLOCAL_AMFLAGS = -I m4,

and the following one into "configure.ac":
AC_CONFIG_MACRO_DIR([m4])


Install Stage

Set the player/stage environment variables:

export PKG_CONFIG_PATH=$HOME/player-stage/ps-2.1/lib/pkgconfig
export PATH=$PATH:$HOME/player-stage/ps-2.1/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/player-stage/ps-2.1/lib

Configure and install stage:

cd stage-2.1
./bootstrap
./configure --prefix=$HOME/player-stage/ps-2.1
make install

NOTE after running "autoreconf", insert the following line into "Makefile.am":
ACLOCAL_AMFLAGS = -I m4,

and the following one into "configure.ac":
AC_CONFIG_MACRO_DIR([m4])

Now you should be good to go using Player/Stage



Tweaks & Error Messages During Install and how to Resolve Them


* glibc detected * ./stage_prob_controller: double free or corruption (!prev): 0x093e46d0 *

This is an old glibc++ error, which can be solved by setting the environment variable:

export MALLOC_CHECK_=0


Compile your own STAGE module: stage_test.cpp:21: error: ‘VERSION’ was not declared in this scope

You need to copy a config header file from the stage directory:

cp $HOME/player-stage/stage-2.1/config.h $HOME/player-stage/include/stage-2.1/
cp $HOME/player-stage/player-2.1/config.h $HOME/player-stage/include/player-2.1/


Stage is running and you want to know which TCP port it is listening on?

netstat --inet --tcp -lp

will tell you on a Linux box


In case of an error "unable to open color database"

sudo mkdir /usr/X11R6/lib/X11
sudo cp /etc/X11/rgb.txt /usr/X11R6/lib/X11/rgb.txt



Running a simple example from the include examples


Start the world simulator

player $HOME/player-stage/stage-2.1/worlds/simple.cfg


Start an example player (robot) from the included C++ examples

$HOME/player-stage/player-2.1/examples/libplayerc++/randomwalk



How to compile and run your own examples


Set the player/stage environment variables:

export PKG_CONFIG_PATH=$HOME/player-stage/lib/pkgconfig
export PATH=$PATH:$HOME/player-stage/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/player-stage/lib


Compile the demos

make OR
make files


Run Stage (check the Makefile for commands)

make start


Run your player (controller), for example

./prob_controller

Cross-compile Player/Stage for the ARM architecture (E-Puck)

Although the example given refers to an ARM based embedded system running Linux on an E-Puck robot, the procedure should be similar for any robot platform. As long as the target architecture is an ARM processor running Linux of course.

Important things to consider when compiling player for the E-Puck:

  • install the Embedian Armel cross-compiler + libraries (see above)
  • download the library "libtool" (works at least up to libtool 2.4 incl. libltdl 7.3 on the E-Puck) and install using "configure" as described above. NOTE it is important to put the libraries into the tool-chains "lib" folder!
  • download and install the "boost" library (recommended version: boost 1.34.1) (http://goodliffe.blogspot.com/2008/05/cross-compiling-boost.html)

FIRST: convince the "boost" build system to use your cross-compiler:

cd ./boost_1_34_1/tools/jam/src
./build.sh
cp bin.linux/bjam .
export PATH=/boost_1_34_1/tools/jam/src:$PATH
cd ../../../
add the following line to "./tools/v2/user-config.jam"
using gcc : 4.3 : /usr/bin/arm-linux-gnueabi-g++ ;


NOTE this does NOT work using "configure", instead use:

bjam -d2 --toolset=gcc '-sBUILD=release static multi/single' link=static --prefix=/usr/arm-linux-gnueabi --layout=system --with-thread --with-signals --with-filesystem install
bjam -d2 --toolset=gcc '-sBUILD=release static multi/single' --prefix=/usr/arm-linux-gnueabi --layout=system --with-thread --with-signals --with-filesystem install

to create both, static and dynamically linked libraries.

Finally, you can compile "player" as described above, although tell "configure" to use the cross-compiler!

Cross-Compiler for ARM Based Embedded System

Installing a cross-compiler for ARM

For an embeded Debian3 operating system, Emdebian4, on an Armel5 (ARM/ATMEL) processor. The cross-compiler toolchain will be installed on a Linux box running Ubuntu 10.04 (Lucid Lynx).

Adding Embedian repositories to the aptitude install system

sudo gedit /etc/apt/sources.list

Add the following lines to that file:

#
# -- Emdebian cross toolchains
#
deb http://buildd.emdebian.org/debian/ lenny main
deb-src http://buildd.emdebian.org/debian/ lenny main

NOTE: Since late 2010, the repository location has been changed to:

# deb http://www.emdebian.org/debian/ unstable main
# deb http://www.emdebian.org/debian/ testing main
deb http://www.emdebian.org/debian/ lenny main
deb-src http://www.emdebian.org/debian/ lenny main

In order to verify and be able to use the repositories they have to be authenticated via GPG.

The simple way to do this is:

sudo apt-get install emdebian-archive-keyring

If you want to do it manually, please check http://www.emdebian.org/packages/keys.html.


Installing the tool-chain via aptitude

sudo apt-cache search armel
sudo apt-get install linux-libc-dev-armel-cross
sudo apt-get install libc6-armel-cross libc6-dev-armel-cross
sudo apt-get install binutils-arm-linux-gnueabi
sudo apt-get install gcc-4.3-arm-linux-gnueabi
sudo apt-get install g++-4.3-arm-linux-gnueabi

In the case of library version conflicts the following might help:

sudo apt-get autoremove


Installing the cross-tools own aptitude and dpkg

The embedian tool-chain comes along with it's own package management, that will allow you to install pre-compiled versions of essential basic libraries that will make it easier to get going.

sudo apt-get install apt-cross dpkg-cross

Update the list of available software and list/install packages using:

sudo apt-cross -a armel -u
sudo apt-cross -a armel -l
sudo apt-cross -a armel -i


Using the Embedian cross-compiler

In order to compile code using the cross-compiler, you need to tell your PC explicitly to use it.

NOTE that the binaries created do NOT run on your PC as they are compiled to run on an ARM architecture! You can check for which platform etc. a file is by displaying it's ELF header:

readelf -h


Custom Makefile

Make sure that the following variables are set in your Makefile/environment:

CC = arm-linux-gnueabi-gcc (or arm-linux-gnueabi-g++)
CXX = arm-linux-gnueabi-g++

If you want to link static libraries, which can be helpful in the case of embedded systems where not necessarily all libraries are available as dynamically linked versions on the target system, use:

CFLAGS += -static


Software that uses the "configure" workflow (usually the case!)

./configure --prefix=/usr/arm-linux-gnueabi --host=arm-linux-gnueabi

E-Puck Link to Demos that run on the PIC Processor

You can find some demos that get the lights flashing on the E-Puck robots here:

http://www.gctronic.com/doc/index.php/E-Puck/

WLAN network setup for E-Puck and Linux Box

Setting up network for AD-HOC (point-to-point between PC and E-Puck)

We are working with a private local network using static IP addresses!

Add entries to file "/etc/network/interfaces" (on the PC):

auto wlan0
#iface wlan0 inet dhcp
iface wlan0 inet static
address 192.168.0.100
network 192.168.0.0
netmask 255.255.255.0
broadcast 192.168.0.255
#pointopoint 192.168.0.1
wireless-mode ad-hoc

and ''"/etc/network/interfaces"'' (on the E-Puck)

auto wlan1
#iface wlan1 inet dhcp
iface wlan1 inet static
address 192.168.0.1
network 192.168.0.0
netmask 255.255.255.0
broadcast 192.168.0.255
#pointopoint 192.168.0.100
wireless-mode ad-hoc


Invoke on both systems either

sudo /etc/init.d/networking restart

or

sudo ifdown wlan0 (or wlan1)
sudo ifup wlan0 (or wlan1)



Setting up network for ACCESS POINT (the PC needs a wireless router attached)

We are working with a private local network using static IP addresses!

Add entries to file "/etc/network/interfaces" (on the PC)

auto wlan0
#iface wlan0 inet dhcp
iface wlan0 inet static
address 192.168.0.100
network 192.168.0.0
netmask 255.255.255.0
gateway 192.168.0.200 (address of router!)
broadcast 192.168.0.255
wireless-essid 'name'
#wireless-key 1234567890
wireless-mode managed

and "/etc/network/interfaces" (on the E-Puck)

auto wlan1
#iface wlan1 inet dhcp
iface wlan1 inet static
address 192.168.0.1
network 192.168.0.0
netmask 255.255.255.0
gateway 192.168.0.200 (address of router!)
broadcast 192.168.0.255
wireless-essid 'name'
wireless-mode managed
#there is a line missing adjusting the power, look up on E-Puck


Invoke on both systems either

sudo /etc/init.d/networking restart

or

sudo ifdown wlan0 (or wlan1)
sudo ifup wlan0 (or wlan1)

Tuesday 6 July 2010

Python Matplotlib: Using Scientific Number Format on Axes

This post will help you with formatting the numbers on axes of your graphs, if you are using Python Matplotlib. When the data you are plotting exceeds a pre-defined value range, Matplotlib will automatically switch to using scientific number formatting.

However, sometimes this can happen a bit erratic or you might want to always use scientific notation (which might be good practice in most cases anyways). This can be done via the following set of commands:

yfm = axScatter.yaxis.get_major_formatter()
yfm.set_powerlimits([ -3, 3])

In order to use these command, matplotlib needs to be included, of course. For plotting examples in Python please refer to the Matplotlib Example Gallery.

Ubuntu Linux: Which Version am I Running?

If you are running Linux on your machine, in particular Ubuntu, it can be tedious if you just quickly want to find out the version of the Kernel you are running and which Ubuntu release you are running (including it's nickname/codename!).

So here are two quick ways of getting the information from the command line:

lsb_release -a

... will give you a good idea of which version you are running, e.g.:

No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 9.10
Release: 9.10
Codename: karmic

... and if you want to find out more about the kernel version, this can be done via typing

uname -a

Wednesday 2 June 2010

ERROR: Programming Cable Locked

In case you get this error message when using the Xilinx Platform cable, he cable can be unlocked using impact with the command:

echo -e 'cleancablelock\nexit' | impact -batch

Xilinx Debugger XMD - MicroBlaze & External RAM

Just a quick recipe on how to download and run an application from externally connected memory on the MicroBlaze processor.

1.) Create a project in Xilinx EDK (start with xps from the command line), including MicroBlaze with debugging enabled.

2.) If you want speed then also enable cache and select the external memory to be cached later in the setup procedure. Enabling cache makes a huge difference in speed!

3.) In EDK's Applications tab, select 'Default: microblaze_0_bootloop' to initialise the block RAMs (BRAMs). This basically creates an infinite loop one the processor comes out of reset, preventing the system to crash, enabling the Xilinx debugger (XMD) to connect to the processor.

4.) Use impact to download the bit-file. Note that after this the processor is up and running and carrying out an infinite loop.

5.) Go to the command line and start XMD:

xmd
connect mb mdm
dow myapplication.elf
run
stop

These commands are quite straight forward (once you know them ;-)). They connect to the MicroBlaze (mb) memory debugger (mdm). With that kind of control over the memory, you can then download the binary (elf) of the application and tell the processor to run it.

Note that the elf file can be compiled either from EDK Applications tab or using mb-gcc, which is the microblaze C compiler.

Nexys2 - Configure Via USB

The Nexys2 is a low-cost FPGA development board from Digilent. It features a Xilinx Spartan-3E FPGA (500K or 1200K gate version), 16 MByte Flash/SDRAM, USB and an RS232.

The board can be powered via USB, which makes it quite convenient to use. The board can be configured in two different ways:

1.) Using a Xilinx Platform Cable

- attach cable (separade leads) to J5.
- pins 1 to 6: TMS, TDI, TDO, TCK, GND, VREF

Using the platform cable provides convenient access to the FPGA + attached SPI flash as well as the platform flash (PROM) using the impact tool from the Xilinx suite.

2.) Configuring via USB

... which does not require the expensive platform cable!

In case you run Windows, just download the Digilent Adept tool from the digilent website.

In case you run Linux you are fine thanks to the guy who wrote a nice tool called nexys2prog. It is fairly straight forward to set it up and works like a charm (example for Ubuntu / Debian):

apt-get install fxload
apt-get install libftdi
download UrJTAG and install it via:
./configure
make
make install

Now you should be ready to run the nexys2prog configuration script

nexys2prog myfile.bit

It will detect and configure the Nexys2 board when it is connected to the USB port. In order to do so, custom firmware is loaded into the board's USB controller. Unplug and replug the board in order to restore the original configuration, which is required to use Digilent Adept.

Tuesday 18 May 2010

Convert PDF to PNG Using ImageMagick

Here is a short bash script that will try to convert all images in your folder into PNGs. The tricky bit is actually to specify the right options when running convert in order to achieve a decent quality.

Here's the code:

for file in *.pdf; do \
echo $file;\
convert -density 600x600 -resize 800x560 -quality 90 $file `echo $file|cut -f1 -d'.'`.png;\
done

The important bit is density, which specifies the resolution of the image in DPI. Resizing and setting a quality is optional, but allows you to tweak the resulting file size. Quality 90 means 90% quality in the case of PNGs and JPGs.

Note that you can run convert also from the command line to convert a single image:

convert -density 600x600 input.pdf output.pdf
convert -density 600x600 -resize 800x560 -quality 90 input.pdf output.pdf

Convert is part of the Linux package ImageMagic, which should be included in most distributions (Ubuntu, Debian, Mandrake, Red Hat etc...).