The C programming language has become the language of choice for many engineering applications, especially digital signal processing. The C language is extremely portable, compact, and lends itself well to structured programming techniques. It has been ported to virtually every major programming platform and is the predominant system programming language for the major operating systems used today.
Programmers familiar with the C language on PC or UNIX platforms should be aware of some key differences between C programming for general-purpose workstations and C programming for DSPs. Areas of attention include differences between native and cross compilers, simulators, I/O library support, run-time libraries, and linker and memory modules.
The major difference in C compilers for DSP, as compared to typical C compilers found in most workstations, is that the object code produced does not execute on the host CPU, but rather on the DSP chip in the target board.
This type of C compiler is called a cross compiler. The more conventional C compiler which produces code for the host CPU is known as a native compiler.
The reason that cross compilers are so much more appropriate than native compilers for DSP is that virtually no DSP processor environment can come close to providing all of the supporting I/O resources available on even the most modest workstation. In fact, most DSP vendors do not even offer a native compiler for their chips.
Since the DSP code produced by the cross compiler cannot execute on the host CPU, there are two methods of testing and developing DSP code.
First, the DSP processor can be simulated by a host program known as a simulator. The simulator closely mimics the operation of the DSP chip so that executable DSP object code is processed as it would be by the DSP chip. Memory and I/O is also simulated so that the DSP target environment is matched as closely as possible. Simulators can be very useful for developing algorithms and for developing program flow and integrity.
However, this rather sterile environment insulates the programmer from the hardware-specific features of the target board which often represent some of the most critical aspects of application development, usually dealing with I/O.
As an alternative to simulation or as the next step after simulation, one can move the executable code directly into a DSP target environment and then use debug software to start it running and control execution. Running code on "the real thing" has the advantages of using actual hardware for input/output data and in evaluating real-time performance. Pentek's SwiftTools and SwiftNet greatly facilitate all phases of this development approach.
Standard I/O A fundamental aspect of the C language is that it contains no environment- specific input or output resources. Therefore, each incarnation of a C compiler requires a standard I/O library tailored specifically for each operating environment. For example, the getchar() function allows the C program to get one character at a time from the standard input device, usually the operator keyboard.
A DSP simulator running on the host, must provide the getchar() function in its standard I/O library to perform a call to the host OS for keyboard input.
However, a DSP program executing on a target DSP board needs a different mechanism for getchar(), depending on where the standard I/O device is defined to be. In an embedded environment, the getchar() function may need to access a serial port on the DSP board and requires a driver for that device.
During debugging and development, however, it may be required that standard I/O be redirected to the host. In this case, the getchar() function must accommodate a communication link from target to host. Whatever the link, the collection of standard I/O library functions must be chosen to support the desired operation.
In complex DSP environments utilizing an operating system executing on the DSP, an abstract path may exist between target and host, often involving several layers of calls. Pentek's SwiftNet accommodates all of these needs using uniform protocols for all types of environments.
Run-time Libraries The C language itself contains no inherent routines for the many math functions, string operations, and memory management tasks required by all DSP applications. Instead, as with the standard I/O functions, the ANSI C standard defines a set of run-time library functions to be supplied as part of a C compiler package.
Most DSP C compilers incorporate an extensive set of run-time library functions, including trigonometric and transcendental functions; range limit functions for different types of variables supported; string manipulation functions; data type declaration functions; and time functions handling seconds to years with calendar notations.
The run-time libraries are often written as very efficient assembly language routines, optimized to take advantage of the special architectural features of the target DSP.
DSP Libraries The need to extend the scope of the run-time libraries to include more exotic and powerful routines common to DSP applications is satisfied by a class of routines called DSP libraries.
They include, among others, vector and matrix arithmetic operations, fast Fourier transforms (FFT's), digital filtering routines, windowing functions, and image processing routines.
These functions allow the DSP code developer to work at a much higher level and alleviate the burden of reinventing common signal processing tasks. In some cases, however, the routines involve trade-offs in execution speed vs. ease of use. Custom versions of these functions can be easily substituted in these cases.
Some of these library functions are supplied with the C compiler and some, like the Tartan library products for 'C30 and 'C40 are available from third party vendors. |