3 Installing and
Running the RF5 Base Application
This section
describes how to build and run Reference Framework Level 5 (RF5) as it is.
Later sections describe how the application works and how it can be adapted.
3.1 Preparing the Hardware
The following
steps provide an overview of how to connect hardware to your host PC in order
to run the default RF5 application. Although the default application uses audio
inputs and outputs, RF5 is well suited for use with video or other types of
signals.
For details
and diagrams about board-specific steps, see the documentation provided with
your board. For additional board-specific information, see the readme.txt file
in the RF_DIR\src\driver folder for your board (for example, RF_DIR\src\teb6416pcm3002).
NOTE:
The top-level folder of the Reference Frameworks distribution is called "referenceframeworks".
The full path to this folder is called RF_DIR in this application note.
1. Shut down and power off your PC.
2. Connect the appropriate data connection cable to the
board.
3. Connect the other end of the data connection cable to
the appropriate port on your PC.
4. Connect an audio input device such as a microphone or
the headphone output of a CD player to the audio input jack (or jacks) on the
board. You can also connect the audio output of your PC sound card to the audio
input of the board.
5. Connect a speaker (or speakers) or other audio output
device(s) to the audio output port(s) of the board.
6. Plug the power cable into the board.
7. Plug the other end of the power cable into a power
outlet.
8. Start the PC.
3.2 Preparing the Software
The following
list outlines the software installation and setup steps required to run RF5.
For details, see the appropriate Quick Start Guides, online help, or the
readme.txt file.
1. If you have not already done so, install CCStudio 2.2
or a later version. It is recommended that you have the latest version of the
CCStudio software, as it may contain important features or problem fixes.
2. Check the configuration of your parallel printer (LPT)
port. Make sure the parallel port is in ECP or EPP mode and note the first
address of the port. This is normally 0x378. For details on checking the
parallel port configuration, see the Quick Start Guide provided with your
board. If you are using an emulator such as TI XDS560, connect the cable to
the 14-pin
JTAG header on your board and follow the instructions the emulator vendor has
provided.
3. Use the Setup Code Composer Studio application to
configure the software for your board. For details, see the documentation
provided with your board.
4. Download the Reference Frameworks code distribution
file from the Reference Frameworks area of the DSPvillage website
(www.dspvillage.com). Place this file in any location, and unzip the file. The
c:\ti\myprojects folder is a suggested location for these files.
Make sure to
use directory names when you unzip the file. You may need to enable an option
called something similar to "Use folder names" in your zip utility.
Do not extract
the zip file into a directory with a path that contains spaces such as c:\Program
Files. Spaces in directory paths are not currently supported by the TI Code Generation
Tools.
3.3 Building and Running the RF5 Application
The targets
supported for RF5 as of the publication date are listed in Appendix E:
Reference Framework Board Ports, page 83. Additional boards may be added in
the future. If you want to run RF5 on a different target, you need to port
hardware-dependent parts of the application.
After
installing the package, you are ready to build and run the RF5 application.
1. Verify that CCStudio is using the correct startup GEL
file for your board. For example, for a 'C6416 TEB board, the startup GEL file
should be c:\ti\cc\gel\TEB6416.gel.
2. Within CCStudio, choose Project→Open and select the app.pjt project in RF_DIR\apps\rf5\projects\target,
where target matches your board. (For example, RF_DIR\apps\rf5\projects\teb6416.)
3. Choose Project→Build
to build the RF5 application. Alternatively, you can choose to just load the
pre-built application located in RF_DIR\apps\rf5\projects\teb6416\Debug
folder.
NOTE: If
you have recently upgraded to a newer version of CCStudio, you are encouraged
to run the RF_DIR\build.bat from an MS-DOS window command line. This
simple batch file rebuilds all RF projects. It ensures that all modules
are in sync with the latest TI Code Generation Tools. Note that you must first
run c:\ti\dosrun.bat so that the paths in the build.bat file are recognized.
4. Choose File→Load
Program and load the app.out file in the Debug folder.
5. Start your CD player or other audio input.
6. Choose Debug→Run
(or F5). You should hear the FIR filtered audio output through the speakers
connected to the target board.
NOTE: The
'C64x device on the 'C6416 TEB board does not support RTDX, which is used for
real-time target to host data transfer. As a result, instrumentation data
provided by DSP/BIOS is available in stop-mode only. That is, they can be seen
in Code Composer Studio only if the program halts or reaches a break point.
7. Choose File→Load
GEL and select the appControl.gel file from the project folder (above the Debug
folder).
NOTE: The
appControl.gel file is a GEL script file that displays sliders to control
algorithm parameters. When you move these controls, the script writes values to
program variables on the target.
8. Choose GEL→Process
Control→Volume. A slider appears with
values ranging from 0 to 200. The default value is 100. Sliding this controls
the output volume on a stereo codec.
NOTE: On
the 'C6416 TEB, the output is stereo even if the GEL control is modified to
allow the volume balance to be set to the extreme left or right (effectively
mono output) and the codec is configured for internal loop-back (that is, data
does not go to the MCBSP). This observation was made on two separate 'C6416 TEB
boards, making it unlikely that
the only some
boards show this problem. No workaround has been found for this problem; this
is probably a limitation arising from boardspecific hardware circuitry.
9. Choose GEL→Process
Control→Filter1 (or Filter2). A slider
appears with values ranging from 0 to 2. The default value is 1. Sliding this
controls the FIR filter coefficients.
4 RF5 Overview
This section
provides overviews of several aspects of RF5. Included are an overview of the application
requirements, application building blocks, the folder hierarchy, the module
hierarchy, and the application parameters and function call hierarchy.
4.1 Application Behavior
The
application specifications for the base RF5 application are as follows.
Although the default application uses audio inputs and outputs, RF5 is well
suited for use with video or other types of signals. Application notes that
describe how RF5 can be adapted to other application domains are listed in
Section 13, References, page 71.
The
application takes the incoming stereo audio signal and converts it to digital
data at a given sampling rate. One sampling of the signal gives a block of two
signed 16-bit integers, one for the left and one for the right channel. The
application groups these blocks into frames of given size before processing
them.
For
processing, the application splits each incoming interleaved stereo frame into
two singlechannel frames. One frame contains only left-channel samples; the
other contains only rightchannel samples. The application processes these
frames separately. To process one channel frame, the application applies a FIR
filter and a volume control algorithm to it. Filter coefficients (low-pass,
high-pass, or passthrough) and amplification/attenuation values may be
controlled by
the user via
GEL, CCStudio's scripting language for accessing target memory, with a
simulated slider that writes values to designated variables that the target
reads periodically.
After it
processes each channel, the application joins the independent channel frames
back into one interleaved stereo frame. This frame is then sent to the output
where the codec converts it into analog stereo signal.
Figure 3. Application Processing Flow
The number of
channels in the application is a modifiable constant, which allows the
application to be easily scaled to a large number of channels. The number of
channels in the codec (1=mono, 2=stereo) is also a modifiable constant.
The supplied
FIR XDAIS algorithm is used for filtering and the supplied VOL XDAIS algorithm
is used for volume control.
4.2 Application Building Blocks and Structure
Let us look
briefly at what data processing elements and what data communication elements
we have in RF5, and how we pass control messages. Then we will see how
they all fit together in the RF5 data path.
4.2.1 Data Processing Elements in RF5
The four basic
data processing elements in RF5 are tasks, channels, cells,
and XDAIS algorithms.
Figure 4. Processing Elements in RF5
At the top
level is a DSP/BIOS task. A task is a collection of channels, a
channel is a collection of cells, and a cell is a wrapper for a XDAIS
algorithm. Each of these elements can have multiple instances. For example,
there are two instances of the filtering algorithm we use, one for each channel.
They use different filtering parameters and remember different history. The
data describing each instance object is different, but both instances share the
code that operates on the data. The same is true for cells and channels (but
rarely tasks). Typically, when we talk about an element, we actually refer to
an instance of that element.
A XDAIS
algorithm is an off-the shelf, reusable data processing component, that
implements a certain interface (IALG). Typically it implements, via the
interface, a fairly complex function, for example JPEG encoding or audio
enhancement; but it can be as simple as audio signal amplification, which is
the VOL algorithm that comes with RF5. XDAIS algorithms in your application can
be purchased from a third party, or you can incorporate your own custom ones.
A cell is
a wrapper around a XDAIS algorithm. XDAIS algorithms have standardized resource
management functions (for requesting memory and DMA). However, the actual data
processing function, which lies at the heart of the algorithm, has no standard
naming convention. The processing functions can vary not only in function
signatures (some take two or more buffers, etc.), but often also in their
number. The purpose of a cell is to provide a standard interface
between the
algorithm and the outside world, by defining only one processing function. Each
cell implements a simple ICELL interface, which defines up to four functions
for a cell: open, execute, close, and control. All functions other than execute
are optional.
Most cell
wrappers are simple, though they can perform whatever operations are necessary
in addition to what the algorithm does. The application integrator writes the
cell code, (or modifies code of existing cells for their algorithms). In the
future, some XDAIS algorithms vendors may supply cell wrappers as well. It is
also possible to create a cell that does not contain a XDAIS algorithm.
A channel is
a collection of cells, and its purpose is to execute its cells in series.
Channels always perform a fixed operation—executing cells serially—so they do
not need any additional code to be written. Typically several channels contain
sets of cell instances that perform identical functions, possibly with
different parameters.
Finally, a task
is collection of channels, which executes them in series. The purpose of
the task is to organize data communication at a higher level, that is by
talking to device drivers, other tasks, and similar constructs. Unlike
channels, tasks do have task-specific code, which the user writes. This code is
usually just sending and receiving data to and from the outside world, and executing
channels. A task has freedom to execute channels in whatever way it desires,
which may be dictated by data flow and control information. A task can also
have no channels at all.
One important
feature of tasks is that they can occasionally send control messages to one another
(in addition to streaming data they regularly send). For that reason, each task
that runs get-data/execute-channels/send-data iterations, checks for the
presence of control messages at the beginning of each iteration. If there are
any, the task applies them to perhaps change its control logic, or to control
the cells contained in its channels.
The term task
refers to an actual DSP/BIOS object, and the term thread refers to
user code that the task executes and pertinent data. We use terms task and
thread interchangeably, since the supplied RF5 application uses tasks but not
software interrupts (SWIs). It also uses hardware interrupts (HWIs) for
high-priority event processing triggered by peripherals.
4.2.2 Data Communication Elements in RF5
We divide the
elements for passing data between processing elements into task-level data communication
elements and cell-level data communication elements. Rather than
just using global variables to inform processing elements where the data is, we
introduce structured objects for passing that information.
For task-level
communication, which uses semaphore-based synchronization, we have SIO objects
and SCOM messages.
SIO objects interface
with device drivers and tasks. These are standard DSP/BIOS objects, and are
typically double-buffered:
Figure 5.
Communication Between a Task and a Device Driver via an SIO Object
Typically the
task allocates two buffers for the data, and passes empty buffers to the input device
driver and collects buffers full of data from it (and the other way round for
output).
Note that in
some applications, a task may talk to a device driver without using SIO
objects; instead it uses whatever format the driver prescribes.
SCOM messages are
user-defined, structured data objects that tasks exchange among themselves.
SCOM stands for Synchronized Communication. Tasks allocate buffers that they
want some other task to write data to or read data from. They need to
communicate to the other task where the buffer is, but also to synchronize with
it to prevent simultaneous access. To do that, they use SCOM messages as buffer
descriptors, which tasks pass among themselves. In that sense, an SCOM message
is like a token for a buffer it describes: the task that holds the message—the
token—can read from the buffer or write to it exclusively. When finished, the
writer passes the message along to the reader task and vice versa.
Figure 6.
Communication Between Two Tasks via SCOM Messages
Each task
creates its own receiving SCOM queue (or more than one if necessary),
and puts SCOM messages to other tasks' receiving queues. A task only needs to
know the name (a character string) of a queue it wants to put messages on. More
than one task can send SCOM messages to the same queue.
For cell-level
communication, we have inter-cell communication (ICC) objects and lists
of those objects. The purpose of an ICC object is to describe the buffer from
which a cell reads the data, or to which the cell writes the data. Each cell
has one input list and one output list of those objects. Two cells in effect
communicate by having the same ICC object in their lists: the cell that writes
to a buffer described by an ICC object has the object in its output list, and
the cell that
reads the
buffer has the object in its input list.
This allows
for an arbitrary, and flexible, topology between cells in a channel. In fact,
cells within different channels (but still in the same task) can communicate
this way. More importantly, a task that receives data from another task can
pass the data to its cells using ICCs, "unwrapping" the data first if
necessary.
We see this in
Figure 7, which shows a task's channel with three cells and various
input/output and intermediate buffers:
Figure 7.
Communication Between Cells via ICC Objects
Cell 1 reads
its data from the task (the tasks writes into the buffer described by Cell 1's
input ICC object), Cell 1 stores its output in two buffers, one read by cell 2
and one read by cell 3. Cell 3 also reads cell 2's output, and cell 3's output
is finally read by the task.
ICC objects
come in different, and user-definable, flavors. The simplest ICC is the one
that describes a plain buffer, in terms of its address and size. This is called
a linear ICC buffer. For example, in Figure 7, cell 1's input ICC would
likely point to the same buffer the tasks uses for receiving data via SIO or
SCOM.
The user is
free to define their own ICC types, which can have pre-processing or
postprocessing operations the cell can call before or after accessing data
described by the buffer.
4.2.3 Application Control in RF5
We have noted
earlier that tasks can pass control messages among themselves. In baseline RF5,
there is only one task that passes messages around, the control task, and only
to one other task, the task that contains the FIR+VOL processing channels.
As the
specifications require, the user can control the application via a GEL script
that has one slider for each channel to control filter coefficients (selection
among low-pass, high-pass, and passthrough filter), and one slider for volume
control. For simplicity one slider controls both channels, although since the
channels operate independently, the GEL script could have one slider for each
channel's volume.
The GEL script
follows user's actions and writes new filter/volume values in a global variable
on the target. The control task periodically reads this variable, and when it
detects a change, it sends a control message to the processing task. Tasks use
the DSP/BIOS MBX (mailbox) module for control messages. The MBX module, unlike
SCOM, makes a copy of the sender's message before placing it on the mailbox
queue, and it makes a copy of the message in queue when delivering it to the
recipient. For that reason it is more convenient for small asynchronous messages—as
is the case with control messages. Each control message is a simple set of
three 32-bit values: command, first command argument, second command argument.
In RF5, the
MBX object is created dynamically in the thrProcessInit() function because the
call to MBX_create can obtain and use the message size and mailbox length when
creating the object.
Figure 8 shows
a task that has both one SCOM queue for receiving data messages and one dynamically-created
MBX object for receiving control messages. Unlike SCOM queues, a task should
only have one mailbox.
Figure 8.
Example of Task Receiving Both SCOM Messages and Control Messages
4.2.4 RF5 Data Path
Figure 9 shows
the specific instances of various processing and communication components, connected
together to form the application that is RF5. Figure 14 provides a somewhat simplified
picture of the data path.
Figure 9.
Complete RF5 Data Path
All the
components of the data path are explained in separate sections, but here is a
brief overview of the processing dynamics:
The data path
begins with the device driver streaming the data into the RxSplit thread's
double buffer bufRx. The low-level IOM mini-driver, programs the serial port
and the DMA (or EDMA on platforms that have it) to transfer and group the
incoming samples into frames. The RxSplit thread does not communicate with the
driver directly; instead, RxSplit owns the inStream SIO object, which
interfaces to a mini-driver via another small module, DIO. Through SIO, RxSplit
tells the
driver where it wants the data (in one or the other half of its private buffer
bufRx), and when it wants it. Because of double buffering, the mini-driver can
keep pumping the data into one half of bufRx at the same time when RxSplit
works to process the other half to prepare data for the Process thread.
When it
receives input frames via SIO, RxSplit then collects the scomMsgRx SCOM message
from its scomRxSplit queue, block-waiting if the message is not there. The
message describes two buffers owned by the processing task. To those buffers
RxSplit writes separated channel data. Afterwards, it puts the scomMsgRx
message back on the Process thread's receiving SCOM queue.
When the
Process thread collects scomMsgRx message, that message is a signal to the Process
thread that the new input frame has been separated into channels and stored
into Process' private buffers bufInput[ NUMCHANNELS ]. These two buffers are
connected to FIR cells' input ICC objects, so the thread executes its NUMCHANNELS
(2) channels. In each channel, its FIR cell reads from its respective bufInput
buffer, processes the data, and stores it in
the
bufIntermediate buffer. The VOL cell reads from that buffer and stores its
result in the bufOutput part of the buffer for that channel. Thanks to ICCs,
however, the cells do not need to know actual buffer names, so they can
function in any channel and task.
The
architecture of RF5 is such that it is easy to change the number of channels.
For each channel, you can specify the cells it contains, and thus the XDAIS
algorithms it executes.
When adapting
RF5 for other applications, a common adaptation is to modify or replace the tskRxSplit
and tskTxJoin tasks, since they may not even be required. Another common modification
is to adapt the use of the control thread to the needs of the application.
4.3
Folder Hierarchy
The
Reference Framework folder tree contains application sources and library
modules. All the code that different RF5-based applications could possibly
share has been pushed into libraries, for reusability (although you can find
source code for these libraries in the RF5 tree, too). Application specific
files, such as task code and cell wrappers, are in the \apps sub-tree.
You can
begin to explore RF5 by examining the folder tree that contains the application
and associated files. We recommend that you retain the provided structure for
your development.
Figure
10 shows the folders used by RF5 and highlights some important files they
contain.
Figure
10. RF5 Folder Structure
Folders
to notice include:
apps\rf5.
The root folder for the RF5 application. To modify RF5, make a copy of
the rf5\tree at the same folder level, and modify the copy.
– appConfig.
Contains DSP/BIOS TextConf scripts that are generic to all platforms.
These
scripts are imported by the board-specific appcfg.tcf file.
– cells.
- Contains application-side cell implementation code. Here the system
integrator
adds
simple "glue code" to match up the XDAIS algorithm interface(s) to
the framework APIs. This provides a consistent execution interface and makes it
easier to group algorithms into channels. There is one folder for each
algorithm or algorithm encode/decode pair. For example, you might create a
cells\mp3 folder to house cellMp3.h, cellMp3encode.c, and cellMp3decode.c.
– projects.
Contains hardware-specific files for the RF5 application. This includes
boardspecific
configuration
files, project, GEL, and linker files. These files are placed in
platform-named
folders so that RF5 can be provided for multiple platforms. Targets
supported
as of the publication date are listed in Appendix E: Reference Framework
Board
Ports, page 83.
– threads.
Contains hardware-independent source files for the threads (tasks).
include.
Contains a number of public header files used by Reference Frameworks.
RF5 uses some, but not all, of these header files.
Public
header files are referenced by both algorithm and framework code. In contrast,
private
header files are stored with the source code that includes them and are not
intended for use by other modules. Each library module has one header file in
this folder.
lib. Contains
a number of library files linked in with Reference Framework applications. RF5
uses some, but not all, of these libraries. Each library module has one library
per DSP family in this folder. In addition, libraries are built for each target
flavor. For example, RF modules are provided for both 55x small data model
(.l55) and large model (.l55l).
src. Contains
folders with source files for modules in the include and lib folders. The
readme.txt
files in each of these folders provide information about the modules and their
use. Library modules typically need little or no modification.
4.4
Module Hierarchy
RF5
uses several collections of modules. Figure 11 shows the high-level framework
architecture.
Figure
11. Topology of Modules in RF5
Table 3
describes the components of this architecture diagram. API function descriptions
are provided in the Reference Frameworks for eXpressDSP Software: API
Reference (SPRA147) application note.
Table
3. Architecture Components
Component / Description / Adaptation Required
Application
Framework / Reference Frameworks can be adapted for use in many applications,
including telecommunication, audio, video, and more. Such changes are not
detailed in this application note / Modification likely
Threads / Threads perform processing. Threads are specified via the DSP/BIOS configuration
and through the code run as the function for each thread Threads are generally
hardware-independent./ Yes, to customize for your application.
Cell
wrappers / Application-side cell implementation code. Contains simple
"glue code" to match the XDAIS algorithm interface to the framework
APIs./ Typically minimal, to switch algorithms
XDAIS
algorithms - TI’s eXpressDSP-compliant implementation of the simple algorithms
used by default. Algorithms may be written by you or provided by a vendor – No
ALGRF /
Functions such as ALGRF_create() for creating IALG-based instances of
XDAIS algorithms. Uses DSP/BIOS MEM module for dynamic memory allocation. The
functions are similar to the functions in the CCStudio's ALG module. / No, but
source code is provided.
CHAN /
Manages the serial execution of XDAIS algorithms contained in cells. - No, but
source code is provided
SCOM -
Implements synchronized message passing among tasks. In RF5, tasks use it to
give and take ownership of buffers so they can write to buffers or read from
them exclusively. - No, but source code is provided.
ICELL -
Interface specification for encapsulating XDAIS algorithm instances in cells.- Interface
must be implemented for each algorithm used.
ICC -
Provides an Inter-Cell Communication mechanism to move input and output data
from a cell. Describes how data flows in and out of a cell. - No, but source
code is provided
SSCR -
Manages the overlaying of on-chip scratch data memory requested by XDAIS algorithms
- No, but source code is provided
UTL -
Provided to support debugging and diagnostics. - No, but source code is
provided
DIO -
Stream device adapter. The upper layer of the device driver. Provides an
interface between an IOM mini-driver and an SIO data stream object. Executes
DSP/BIOS calls to manage buffer transfers. This layer is hardware-agnostic.
Described in SPRU616. – No
IOM
mini-driver - Simple, low-level device driver interface between application
threads and hardware devices. For example, "teb6416pcm3002".
Defines a set of device-agnostic APIs to interface with. Described in SPRU616.
- Yes, to port controller to your hardware.
DSP/BIOS
- The set of modules provided as a scalable real-time kernel. This includes
modules for scheduling, memory management, instrumentation, and I/O. – No
CSL -
Chip Support Library. Simplifies the job of developing device drivers and
interacting with peripherals. – No
Hardware / The target board, including codecs and other peripherals ----
4.4.1 Rebuilding and Debugging Libraries
Source code is
provided for the additional libraries used by RF5 not only so you can modify
and recompile the libraries, but for debugging purposes as well. If you halt
execution while within code in a library module, CCStudio asks if you want to
locate and open the appropriate source file for the module. This allows you to
step into module procedures and inspect internal and external variables, even
if you do not intend to modify the code.
Hint: In
CCStudio, using Options→Customize→Directories menu option, you can specify which folders
CCStudio should search to locate the source file. If you specify source code
folders for the modules used in RF5, CCStudio opens windows with their source
code automatically as you step into a library module procedure.
A readme.txt
file is provided in each library source folder. These readme.txt files list the
module files, tell which frameworks use the module, and answer questions about
the module.
Libraries are
built with debugging enabled (-g) and no optimization. For performance reasons you
may wish to rebuild the libraries using optimization switches for
post-development versions of your applications.
If you rebuild
a library and then rebuild the Reference Framework application, either delete
the executable file (app.out) or use Project→Rebuild
All in order to build with the new library. CCStudio does not currently check
for dependencies on rebuilt libraries.
The Reference
Frameworks distribution does not include source code for IOM device driver modules.
Such files can be obtained as part of the DSP/BIOS Driver Developer's Kit
(DDK). You do not need the DDK in order to run the Reference Frameworks—the
driver library and public header files are included in the Reference Frameworks
distribution. For details about the DDK and mini-driver development and use,
see the DSP/BIOS Driver Developer's Guide (SPRU616).
4.5 Application Parameters and Function Calls Hierarchy
When you start
exploring RF5, you will best understand its flow if you look at the hierarchy
of function calls in it. You can easily identify where a function or a data
structure is defined by lookingat its name. If a name begins with MOD_,
it is a library module defined in module mod—meaning that its public
interface is in include\mod.h directory, and its source is in src\mod.
If a global name does not have the prefix with the underscore, it means it's an
application module,
and its file
of origination is still determined by the first part of the name. (For example,
the thrProcessRun() function is declared in the thrProcess.h file and defined
in the thrProcess.c file.)
Global symbols
use a simplified Hungarian notation (for example, the Process thread's state variable,
tskProcess, is an object of type "task," which uses the TSK module),
and local names usually follow less strict naming convention.
Before we
examine the function call hierarchy, let us first look at two important
parameters you will see throughout the code:
4.5.1 Number of Channels and Data Frame Sizes
The number of
channels in the RF5 application is specified in appResources.h:
#define NUMCHANNELS 2
For
some applications, different threads may have different number of channels, so
their number of channels would be defined in their header files.
In
appIO.h, the following constant identifies the number of channels in the codec:
/* The 6416TEB has a stereo codec */
#define NUMCODECCHANS 2
A
constant in appResources.h specifies the size of data buffers used in the
application. The size of a per-channel data buffer—that is, the size after the
signal has been split—is defined as:
#define FRAMELEN 80
typedef Short Sample; // signed 16-bit integer
The
size in bytes of the frame for one channel is expressed with the formula:
FRAMELEN *
sizeof( Sample )
Similarly, the
size in bytes for all the channels is expressed as:
NUMCODECCHANS * FRAMELEN * sizeof( Sample )
The heartbeat
of the system comes from the codec and the CSL modules used by the controller (EDMA
and MCBSP for the 'C6416). Because the controller uses EDMA, the CPU does
little work to receive and transmit the frames. Therefore, the larger the frame
size, the less time the CPU spends on I/O, and the more time remains for
processing. Larger buffer sizes, however, result in larger latencies, and
consume more memory, so a compromise must be found.
For example,
the 'C6416 TEB, has a stereo codec (PCM3002) with a sampling frequency of 48 kHz.
Each sample is 16 bits. The calculation for how often data is processed is as
follows:
1 second /
frequency (Hz) * FRAMELEN =
1/48000 * 80 =
0.00166 s =
1.66 ms per frame
You can
measure the period it takes to process one frame by looking at stsTime0
statistic (STS) BIOS object, if you choose the units for stsTime0 to be in
milliseconds or microseconds.
The Process
thread uses the stsTime0 object and the UTL module to measure elapsed time between
two iterations.
4.5.2 Function Call Hierarchy
The following
diagram shows the hierarchy of the important function calls in RF5 (on the
'C6416 TEB as an example, and without instrumentation calls and most of the
standard DSP/BIOS functions, for simplicity.)
5 Application Configuration and Startup
Like other
conventional real-time operating systems, DSP/BIOS enables an application to dynamically
create objects, such as tasks and semaphores, at any time during program execution.
However, in reality, many real-time applications simply create all the
necessary objects at the start of the application. This wastes program memory
since the code for creating objects must be present in target memory even
though it is only used once.
Instead of
using APIs for dynamic creation, DSP/BIOS enables developers to statically
generate a configuration tailored to the needs of the application. This
significantly reduces the target memory footprint by eliminating the need to
code the creation logic.
Typically, a
module, consisting of a header file and a library file, implements a class of
objects and lets the user create as many instances of it as needed. The concept
is similar to the class concept in object-oriented programming, but the API is
C-based (and the underlying implementation is often in assembly, for
performance). For instance, one module implements a task, and with its
code the user can create as many task instances as needed.
Information
about the DSP processor and DSP/BIOS objects are stored in a configuration database
(.cdb).
Traditionally,
DSP/BIOS used a Configuration Tool with a graphical interface for the creation
and configuration of static objects. This tool is still available as part of
CCStudio 2.2, and users who may want to continue using it in their workflow can
ignore the remaining contents of this section. For those who are interested in
a more flexible, script-based configuration tool, DSP/BIOS TextConf (tconf) now
offers an alternative for configuring your application at design-time. The main
benefits of using TextConf in the Reference Frameworks are as follows:
Easily port
frameworks to new target boards and platforms. The
configuration scripts clearly separate application-specific settings from
target-specific settings. This makes it easy to port applications to new target
boards and platforms. Only those settings made for target-specific reasons
require modification when porting to a new board.
Eliminate
potential update issues. The configuration database (CDB) file used with the graphical
configuration tool must be updated with every new version of CCStudio. In some cases,
this conversion can be problematic. Textual configuration uses scripts as
source files, and eliminates this conversion altogether. These scripts are much
smaller and easier to maintain than their CDB counterparts.
Configuration
scripts are written in JavaScript, a powerful scripting language that has a
C-like syntax, which helps to reduce the learning curve for a typical C
programmer.