world leader in high performance signal processing
Trace: » port_program_to_linux

Porting VDSP++ Algorithms to Linux

VDSP++ is an excellent development system for signal processing algorithms, however, it is not equipped to provide true operating system services like the Linux environment. It may be useful for some people to take C, C++ or assembly code algorithms that were written for the VDSP compiler, and recompile it with gcc, g++ or gas, in order that it can be used as part of a Linux application. Since Linux is a full-featured operating system, the application environment differs from the VDSP environment in many ways. Any porting work must be evaluated on an individual case. This page collects some common guidelines and tricks that deal with certain special cases.

Once an algorithm/application/library has been ported to gcc and debugged under the Linux kernel environment, it can be used just like any other Linux application/library.

Here are the equivalent tools.

Tool VDSP++ Implementation GNU Toolchain Implementation
executable file extension executable file extension
assembler easmBLKFN .asm bfin-xxx-as .S
C compiler .c bfin-xxx-gcc .c
C++ compiler pp .cpp bfin-xxx-cpp .cpp
archiver elfar .dlb bfin-xxx-ar .a
Bootrom file format elfloader bfin-xxx-ldr
Linker linker .ldf bfin-xxx-ld .lds

None of this information will help you link VDSP++ object files with gcc object files, or allow you to run VDSP++ objects in a Linux environment.

For those moving from VDSP++ to Linux and gcc, you also may be interested in the section on libs, to see how to use the existing libbfdsp.

However, porting standalone algorithms to Linux is a non-trivial task, as most standalone algorithms are not architected in a manner that are capable of running in a full featured Operating System like Linux, and must take the following items into consideration. Even the most simple algorithms must follow these rules:

  • Many Linux kernel developers feel that non-GPL kernel modules may inadvertently infringe on other's copyrights. We respect this position, and do not encourage any developer to develop closed source or non-GPL kernel modules. A good rule of Linux development is - if you don't want to or are not able to license works under the GPL, or if you do not have access to the source - make sure your algorithms are in userspace. For those interested licensing their code under the GPL, and putting algorithms into kernel space:
    • The kernel manages every piece of hardware and peripheral in the system. If you want a DMA channel - you ask the kernel's DMA manager - do not able to write directly to MMR registers behind the kernel's back - even in your own driver - since this will cause the kernel, or your application to fall apart when two different pieces of software are managing the same subset of hardware. The same holds true for interrupts - your algorithms must register for a kernel interrupt, and the kernel must handle alll interrupts, and pass execution flow eventually to you.
    • The kernel manages memory - including the Blackfin's internal L1 memory. Your application/driver must ask the kernel for memory, to ensure the other applications/drivers on the platforms do not get stomped overwrites memory locations, or your algorithm does not overwrites memory locations anything else. For algorithms which expect to be able to manage banks of SDRAM - this is not possible in Linux. You ask the kernel for a size of memory - and it gives it to you - it can be anywhere.
    • The Linux kernel manages all interrupts and exceptions - attempting to take over specific interrupts, or exceptions can cause the rest of the kernel to stop functioning properly.
    • There is no separation between kernel and hardware - the kernel manages everything.
  • Linux on the Blackfin is separated into user space (user mode) and kernel space (supervisor mode). It is not possible to run userspace in supervisor mode.
  • Hardware is not accessible from user space. The Linux kernel has a defined interface between userspace ↔ kernel ↔ hardware. It is not possible for an userspace application to talk directly to the hardware (like a Memory Mapped Register). This means that all interrupts, DMA, and other peripherals must have a proper kernel driver, and talk through that kernel driver.
  • Linux supports many executable file formats, and when running - the application has no idea where the data resides. This impacts both C/C++ and assembly code. In many stand alone algorithms, a memory map is defined at compile time with the linker script. When running inside the kernel, the kernel completely manages memory.
  • The only way to allocate memory in user space is via the standard c library - calloc, malloc, free, realloc. This applies to main buffers, and temporary buffers.
  • The Linux threading model - a process can be swapped out at any time - meaning that you can not share temp buffers between threads.
  • The amount of registers that a context switch must place on the stack, is every register in the Blackfin (even a few we don't use). Any type of algorithm that doesn't save/restore these same registers can cause a different thread or application to fail later. Your custom algorithm may cause busybox to fail.

Many of these design guidelines increase overhead, but this is just the way Linux works (they are done that way on purpose) - if you don't want to port your algorithm to an environment with this type of design (Linux kernel) - there are many other frameworks - like VDK, which can be used. We can not support attempts to work around these design rules. Doing so will cause the kernel to be unstable and make the project impossible to debug.

There have also been people asking about debugging the kernel or Linux using a non-gdb debugger. A thorough understanding of the Operating System is required to understand why this is not possible. Here are a few of the key issues:

  • only the minimal Linux kernel is linked statically. Most developers develop drivers as kernel modules, this is the preferred approach.
  • both applications and kernel modules are not statically linked. They have no fixed start address. Since gdb/kgdb/jtag gdb is aware of this, it can deal with this and provide source level debugging on applications that are in random pieces of memory. (kgdb and jtag gdb can only work with kernel modules, not install them).
  • Loading kernel modules or applications via JTAG is not possible. The way the kernel runs an application is first to load it from the file system into main memory. There is no way to get around this process as this is the only way the kernel will allocate the proper amounts of memory, manage memory locations in all the the correct places, ensure that existing threads are not over-written, and that the application is added to the running process table. JTAG debuggers (including gdb via JTAG) can not do this since they:
    • are not file system awarer (don't understand how to write a file into the file system),
    • are not kernel process aware (don't understand how to start a kernel process).

Developing with Linux requires that you learn the kernel architecture, and proper tools usage - gdb.