uClinux on the Blackfin DSP Architecture: Part 2 - Embedded.com

uClinux on the Blackfin DSP Architecture: Part 2

Go to part 3 of this article

When selecting development hardware, developers should not onlycarefully make their selection with price and availabilityconsiderations in mind, but also look for readily available open sourcedrivers and documentation, as well as development tools that makes lifeeasier e.g. Kernel, driver and application debugger, profiler, strace .

Especially when developing with open source ” where software isgiven as is – developers making a platform decision should alsocarefully have a eye on the test methodology for kernel, drivers,libraries and tool chain.

The Linux Test Project (LTP) [8] as an example is a joint projectstarted by SGI and maintained by IBM, that has a goal to deliver testsuites to the open source community that validate the reliability,robustness, and stability of Linux. The LTP testsuite contains acollection of tools for testing the Linux kernel and related features.Analog Devices, Inc. sponsored the porting of LTP to architecturesrunning uClinux.

Trust is good, control is better ” not only the kernel, also all othertools involved during the development process needs to be tested. Ifyou can't trust your compiler or debugger, then you are lost.Blackfin/uClinux uses DejaGnu [9] to ease and automate the over 44,000toolchain tests, checking of their expected results while running onthe real target hardware. In addition there are testsuits included inBlackfin/uClinux to do automated stress tests on kernel and devicedrivers using expect scripts. All these tests can be easily reproducedbecause they are well documented [10].

A typical uClinux development environment consists of a low costBlackfin STAMP board [11], and the GNU Compiler Collection [12] (gcccross compiler) and the binutils (linker, assembler, etc.) for theBlackfin Processor. Additionally, some GNU tools like awk, sed, make,bash … plus tcl/tk are needed, although they usually come by defaultwith the desktop Linux distribution.

All sources and tools (compiler, binutils, gnu debugger) needed tocreate a working uClinux kernel on the Blackfin Processors can befreely obtained from http://www.blackfin.uclinux.org. To use the binaryrpms, a PC with a Linux distribution like RedHat or SuSE is needed.Developers who can't install Linux on their PC, have a alternative.

Cooperative Linux (coLinux) [15] is a relatively new means toprovide Linux services on a Windows host. There already exists anout-of-the-box solution that can be downloaded for free from http://blackfin.uclinux.org/projects/bfin-colinux.This package comes with a complete Blackfin uClinux distribution,including all user space applications and a graphical Windows-likeinstaller.

After the installation of the development environment and thedecompression of the uClinux distribution, development may start.

First the developer uses the graphical configuration utility toselect an appropriate Board Support Package (BSP) for his targethardware. Supported target platforms are STAMP for BF533, BF537 or theEZ-KIT for the Dual Core Blackfin BF561. Other Blackfin derivatives notlisted like BF531, BF532, BF536 or BF534 are also supported but thereisn't a default configuration file included.

After the default kernel is configured and successfully compiled,there is a full featured Linux kernel and a file system image that canbe downloaded and executed or flashed via NFS, tftp or Kermit protocolonto the target hardware with the help of preinstalled u-boot [16]boot-loader. Once successful, further development can proceed.

A further step could be the creation of a simple “Hello World”program as shown in the code example below.

The first step is to cross compile 'hello.c' on the development hostPC:

bfin-uclinux-gcc -Wl,-elf2flt hello.c -o hello

The output executable is 'hello'.

When compiling programs that run on the uClinux -bfin-uclinux-gcc is the usedcompiler. Executables are linked against the uClibc runtime library. uClibc is a Clibrary for developing embedded Linux systems. It is much smaller thanthe GNU C Library, but nearly all applications supported by glibc alsowork perfectly with uClibc.

Library function calls likeprintf() invoke a system call, telling theoperating system to print a string to stdout , the console. The elf2flt command line option tells thelinker to generate a flat binary – elf2flt converts a fully linked ELF object file created by the toolchain into abinary flat (BFLT) file for use with uClinux.

The next step is to download 'hello' to the target hardware. The aremany ways to accomplish that. One convenient way is be to place 'hello'into a NFS or SAMBA exported file share on the development host, whilemounting the share form the target uClinux system. Other alternativesare placing 'hello' in a web server's root directory and use the wgetcommand on the target board. Or simply use ftp or tftp to transfer theexecutable.

Debugging is in this case not a necessity, but as programs becomemore sophisticated, the available debugging tools become valuable.Sometimes an application just terminates after being executed, withoutprinting an appropriate error message. Reasons for this are almostinfinite, but most of the time it can be traced back to somethingreally simple, e.g. it can't open a file, device driver, etc.

strace is a debugging tool whichprints out a trace of all the system calls made by a another program.System calls and signals are events that happen at the user/kernelinterface. A close examination of this boundary is very useful for bugisolation, sanity checking and attempting to capture race conditions.

If strace doesn't lead to an quick result,developers can follow the unspectacular way most Linux developers go “using printf or printk to add debug statements in the code and recompile/rerun.

Because this method can be exhausting,  the standard Linux GNU Debugger (GDB) with it'sgraphical front-ends can be used instead to debug user applications.GDB supports single stepping, backtrace, breakpoints, watchpoints,etc.. There are several options to have gdb connected to the gdbserver on thetarget board. Gdb can connect over Ethernet, Serial or JTAG (rproxy).For debugging in the kernel space, for instance device drivers,developers can use the kgdb Blackfin patch for the gdb debugger.

If a target application doesn't work, because of hiddeninefficiencies ” profiling is the key to success. OProfile is a system-wide profilerfor Linux based systems, capable of profiling all running code at lowoverhead. OProfile uses thehardware performance counters of the CPU to enable profiling of avariety of interesting statistics, also including basic time-spentprofiling. All code is profiled: hardware and software interrupthandlers, kernel modules, the kernel, shared libraries, andapplications.

The Blackfin gcc compiler has very favorable performance, acomparison with other gcc compilers can be found here: GCC Code-SizeBenchmark Environment (CSiBE) [17]. But sometimes it might be necessaryto do some hand optimization, to utilize all enhanced instructioncapabilities a processor architecture provides. There are a fewalternatives: Use Inline assembly, assembly macros or C callableassembly.

Example: C callable assembly
For a C program to be able to call an assembly function, the names ofthe function must be known to the C program. The function prototype istherefore declared as an external function.

extern int minimum(int,int);

In the assembly file, the same function name is used as the label atthe jump address to which the function call branches. Names defined inC are used with a leading underscore. So the function is defined asshown below:

The function name must be declared using the .global directive inthe assembly file to let the .global_minimum; assembler and compiler know that it's used by another file.

In this case registers R0 and R1 correspondto the first and second function parameter. The function return valueis passed in R0. Developers should make themselves comfortable with the C runtimeparameter passing model of the used architecture.

Not only on a processor where floating point is not nativelysupported, virtually all signal processing is performed usingfractional arithmetic. Unfortunately, C doesn't have a fixed pointfractional data type. However, fractional operations can be implementedin C using integer operations. Most fractional operations must beimplemented in multiple steps, and therefore consume many C statementsfor a single operation, which makes them hard to implement on a generalpurpose processor.

DSP processors directly support single cycle fractional and integerarithmetic, while fractional arithmetic is used for the actual signalprocessing operations and integer arithmetic is used for controloperations such as memory address calculations, loop counters andcontrol variables.

The numeric format in signed fractional notation makes sense to usein all kind of signal processing computations, because it is hard tooverflow a fractional result, because multiplying a fraction by afraction results in a smaller number, which is then either truncated orrounded.

The highest full-scale positive fractional number is 0.99999, whilethe highest full scale negative number is -1.0. To convert a fractionalback to an integer number, the fractional must be multiplied by ascaling factor so the result will be always between ±2^(N-1) for signed and 2^(N) for unsigned integer.

The standard uClinux distribution contains a rich set of available Clibraries for compression, cryptography and other purposes (openssl, libpcap, libldap, libm, libdes,libaes, zlib, libpng, libjpeg, ncurses, etc .) TheBlackfin/uClinux distribution [4] additionally includes: libaudio,libao, libSTL, flac, tremor, libid3tag, mpfr, etc.

Furthermore Blackfin/uClinux developers [4] currently incorporate aDSP library into uClinux with highly optimized assembly funtions toperform all kind of common signal processing algorithms such asConvolution, FFT, DCT and IIR/FIR Filters, with low MIPS overhead.

The next step would be the development of the special applicationsfor the target device or the porting of additional software. A lot ofdevelopment can be done in shell scripts or languages like Perl orPython. Where C programming is mandatory, Linux, with its extraordinarysupport for protocols and device drivers, provides a powerfulenvironment for the development of new applications.

In Part 3 of this series, theauthor covers a number of real world examples of the use of uClinux,including in a CMOS Camera Sensor, a network oscilloscope and well asadapting Linux to some real time embedded applications.

Sinceobtaining his MSc (Computer Based Engineering) and Dipl-Ing.(FH)(Electronics and Information Technologies) Degree from the ReutlingenUniversity , Michael Hennerich has worked as a design engineer on avariety of DSP based applications. Michael now works as a DSPApplications and Systems Engineer at AnalogDevices Inc. in Munich.

This article is excerpted from apaper of the same name presented at the Embedded Systems ConferenceSilicon Valley 2006. Used with permission of the Embedded SystemsConference. For more information, please visit www.embedded.com/esc/sv.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.