MIME-Version: 1.0 Content-Location: file:///C:/D9031D6F/ProgrammingConsiderationsforReal-timeIO.htm Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset="us-ascii" DSP 101 Part 4

 <= /o:p>

 

 =

 =


DSP 101 Part 4:

Programming Considerations for Real-time I/O

Also see:  (Part 1) (Part 2) (Part 3)

by Noam Levine and David Skolnick

So far, this series has introduced the following topics:

  • Part 1 (vol. 31-1): DSP architecture and DSP advantages over traditionally analog circui= try
  • Part 2 (vol. 31-2): digital filtering concepts and DSP filtering algorithms
  • Part 3 (vol. 31-3): implementation of a finite-impulse- response (FIR) filter algorithm = and an overview of a demonstration hardware platform, the ADSP-2181 EZ-K= it Lite.

Now, we look more closely at DSP programming concerns that are unique = to real-time systems. This article focuses on how to develop algorithms for = DSP systems with a variety of I/O interfaces.

What does "real-time" mean? In an analog system, every task is performed in "real time" with continuous signals and processing. In a digital signal-processing (DSP) system, signals are represented with sets of samples, i.e., values at discrete points in time. Thus the time for processing a given number of samples in a DSP system can have an arbitrary interpretation in "real time", depending on t= he sampling rate. The first article in this series introduces the concept of sampling and the Nyquist criterion--that in real-time applications, the sampling frequency must be at least twice the frequency of the highest frequency component of interest in the (analog) signal (Nyquist rate). The time between samples is referred to as the sampling interval. To consider= a system as operating in "real time," all processing of a given s= et of data (one or more samples, depending on the algorithm) must be complet= ed before new data arrives.

This definition of real time implies that, for a processor operating a= t a given clock rate, the speed and quantity of the input data determines how= much processing can be applied to the data without falling behind the data str= eam. The idea of having a limited amount of time with which to handle data may seem odd to analog designers because this concept does not have a paralle= l in analog systems. In analog systems, signals are processed continuously. The only penalty in a slow system is limited frequency response. By compariso= n, digital systems process parts of the signal, enough for very accurate approximations, but only within a limited block of time. Figure 1 shows a comparison. Real-time DSP can be limited by the amount of data or type of processing that can be completed within the algorithm's time budget. For example, a given DSP processor handling data values sampled at, say, 48-k= Hz (audio signals), has less time to process those data values, including execution of all necessary tasks, than one sampling 8-kHz voice-band data= .

In the filter example described earlier in this series, the input samp= ling rate is 8 kHz. For the DSP in the example to keep up with real-time data,= all processing has to be done within a time budget of 1/(= 8 kHz), or 125 µs. On a 33-MHz digital signal-processor (30ens per cycle), the time budget provides 125 µs/30 ns, or 4166 instruction cycles, to complete processing and any other required tasks.

Since there is a finite amount of time that can be budgeted to perform= any given algorithm, managing time is a central part of DSP system software design. Time management strategy determines how the processor gets notifi= ed about events, influences data handling, and shapes processor communicatio= ns.

3D"Comparison

Figure 1. Comparison of analog and di= gital signal processing. a. Analog: A response value corresponds to each data v= alue at all instants of time. b. Digital: For each sample, the data must be transferred in and processed, an event marks the end of processing (contr= ol), and extra time may be necessary for other tasks within the cycle after the designated process occurs.

Event Notification: Interrupts: One can program a DSP to process data using one of several strategies for handling the "event," = the arrival of data. A status bit or flag pin could be read periodically to determine whether new data is available. But--"polling" wastes processor cycles. The data may arrive just after the last poll, but it ca= n't make its presence known until the next poll. This makes it difficult to develop real-time systems.

The second strategy is for the data to interrupt the processor = on arrival. Using interrupts to notify the processor is efficient, though no= t as easy to program; clock cycles can be wasted during the wait for an interr= upt. Nevertheless, event-driven interrupt programming being well-suited to processing real-world signals promptly, most DSPs are designed to deal efficiently with them. In fact, they are designed to respond very quickly= to interrupts. The ADSP-2181's response time to an interrupt is about three processor cycles; i.e., within 75 ns the DSP has stopped doing what it was doing and is handling the interrupt event (vector).

In many DSP-based systems, the interrupt rates, based on the input data sampling rate, are often totally unrelated to the DSP's clock rate. In the FIR example seen earlier in this series, the processor is interrupted at 125-µs intervals to receive new data.

Interrupt Handling and Interrupt Vectors: Because interrupt processing is such a vital element in DSP systems, processors typically h= ave built-in hardware mechanisms to handle interrupts efficiently. Hard-wired mechanisms are more efficacious than software alone because a DSP's inter= rupt service routines (ISRs) may have to meet all of the following demands:

  • Fast context switching--switch from working on one task and its data (a contex= t) to another context without the time loss and complication associated with writing programs to save register contents and chip status information.
  • Nested-interrupt handling--handle multiple interrupts of different priorities "simultaneously." The DSP handles one interrupt at a time,= but an interrupt of higher priority can take precedence over the handlin= g of a lower-priority interrupt.
  • Continue to accept data/record status--while the DSP services an interrupt, events keep= on occurring in the real world and data keeps on arriving. To keep up w= ith the "real-world," the DSP must record these events and acc= ept the data--then process them when it has finished servicing the inter= rupt.

On Analog Devices DSPs, fast context switching is accomplished using t= wo sets of data registers. Only one set is active at a time, containing all = the data in process during that context. When servicing an interrupt, the computer can switch from the active to the alternate set without having to temporarily save the data in memory. This facilitates rapid switching bet= ween tasks.

To handle multiple interrupts, Analog Devices DSPs record their state = for each one. Processor state information is kept on a set of status "stacks" located in the DSP's Program Sequencer. A "stack" consists of a set of hardware registers. Current status information is "pushed" onto the stack when an event occurs. Th= is stack mechanism also allows interrupts to be nested; one with high= er priority can interrupt one with lower priority.

Two hardware features, interrupt latch and automated I/O, let Analog Devices DSPs stay abreast of the "real world" while processing = an interrupt. The latch keeps the DSP from missing important events while servicing an interrupt. The other feature, comprising various forms of automated I/O (including serial ports, DMA, autobuffering, etc.) lets external devices pump data into the DSP's memory without requiring intervention from the DSP. So no data is missed while the DSP is "busy."

When an interrupt request is generated, by an external source or an internal resource, the DSP processor automatically stores its current sta= te of operation, and prepares to execute the interrupt routine. Interrupt routines are dispatched from an interrupt vector table. An interrupt vect= or table is an area in Program Memory with instruction addresses assigned to particular DSP interrupt functions. For example, in the table below, a Transmit (Tx) interrupt at serial port 1 (SPORT1) of an ADSP-2181 process= or will cause the next instruction to be executed at program memory (PM) location 0x0020, followed by the contents of the next three locations, through 0x0023 (the interrupt routine). As the 12 items in the tab= le indicate, an ADSP-2181 can handle interrupts from 11 locations (external hardware, DMA ports, and the serial ports) and the processor Reset. The t= able lists the programmed instructions assigned to each interrupt vector sourc= e in memory locations 0x0000 to 0x002F for an FIR filter program.

Jump start; nop; nop; nop; &nbs=
p;   /* PM(0x0000-03): Reset vector */
rti; nop;=
 nop; nop;            /* PM(0x0004-=
07): IRQ2 vector */
rti; nop; nop; nop;            /* PM(0x0008-=
0B): IRQL1 vector */
rti; nop; nop; nop;            /* PM(0x000C-=
0F): IRQL0 vector */
ar =3D dm(stat_flag); ar =
=3D pass ar; if eq_rti; jump next_cmd;
              &nb=
sp;            =
     /* PM(0x0010-13): SPORT0 Tx vector */
=
jump input_samples; nop; nop; nop; 
              &nb=
sp;            =
     /* PM(0x0014-17): SPORT0 Rx vector */<=
/pre>
jump irqe; nop; nop; nop;      /* PM(0x0=
018-1B): IRQE vector */
rti; nop; nop; nop;            /* PM(0x001C-=
1F): BDMA vector */
rti; nop; nop; nop;            /* PM(0x0020-=
23): SPORT1 Tx vector */
rti; nop; nop; nop;            /* PM(0x0024-=
27): SPORT1 Rx vector */
rti; nop; nop; nop;            /* PM(0x0028-=
2B): Timer vector */
rti; nop; nop; nop;            /* PM(0x002C-=
2F): Powerdown vector */

Each interrupt vector has four instruction locations. Typically, these instructions will cause the processor to jump to another area of memory in order to process the data, as is shown in the Reset (at 0x0000), SPORT0 Rx (0x0014), and IRQE (0x0018) interrupt vectors. If there are just a few steps--such as reading a value, checking status, or loading memory--that = can be done within the four available instruction locations, they are program= med directly, as shown in the SPORT0 Tx vector (0x0010-13). Any unused interr= upt vectors call for return from interrupt (rti), with three nop (no operatio= n) instructions.

The nop instructions serve as place holders--instruction space used to ensure that the correct interrupt action lines up with the hardware-speci= fied interrupt vector. The rti instruction at the beginning of each unused vec= tor location is both placeholder and safety valve. If an unused interrupt is mistakenly unmasked or inadvertently triggered, "rti" causes a return to normal execution.

Data I/O

In DSP systems, interrupts are typically generated by the arrival of d= ata or the requirement to provide new output data. Interrupts may occur with = each sample, or they may occur after a frame of data has been collected. The differences greatly influence how the DSP algorithm deals with data.

For algorithms that operate on a sample-by-sample basis, DSP software = may be required to handle each incoming and outgoing data value. Each DSP ser= ial port incorporates two data I/O registers, a receiv= e register (Rx), and a transmit register (Tx). When a serial word is received, the port will typically generate a Receive interrupt. The proce= ssor stops what it is doing, begins executing code at the interrupt vector location, reads the incoming value from the Rx register into a processor = data register, and either operates on that data value or returns to its backgr= ound task. In the table above, the computer jumps to a program segment, "input_samples", performs whatever instructions are programmed = in that segment, and returns from the interrupt, either directly or via a re= turn to the interrupt vector.

To transmit data, the serial port can generate a Transmit interrupt, i= ndicating that new data can be written to the SPORT Tx register. The DSP can then b= egin code execution at the SPORT Tx interrupt vector and typically transfer a value from a data register to the SPORT Tx register. If data input and ou= tput are controlled by the same sampling clock, only one interrupt is necessar= y. For example, if a program segment is initiated by Receive interrupt timin= g, new data would be read during the interrupt routine; then either the previously computed result, which is being held in a register, would be transmitted, or a new result would be computed and immediately transmitted--as the final step of the interrupt routine.

All of these mechanisms help a DSP to approach the ability to emulate = what an analog system does naturally--continuously process data in real time--= but with digital precision and flexibility. In addition, in an efficiently programmed digital system, spare processor cycles left between processing data sets can be used to handle other tasks.

Programming Considerations

In a "real-time" system, processing speed is of the essence.= By using SPORT autobuffering, no time is lost to data I/O. Instead, the data management goal is to make sure that the selected address points to the n= ew data.

In the FIR filter example (Analog Dialogue 31-3, page 15), a SP= ORT Receive interrupt request is generated when the input autobuffer is full, meaning that the DSP has received three data words: status, left channel data, and right channel data. Since this simplified application uses sing= le-channel data, only the data value that resides at location rx_buf+1 is used by the algorithm.

Filter Algorithm Expansion In other applications, the data hand= ling can be more involved. For example, if the FIR filter of the example were expanded to a two-channel implementation, the core DSP algorithm code wou= ld not have to change. The code relating to data handling, however, would ha= ve to be modified to account for a second data stream and a second set of coefficients.

In the filter code, two new buffers in memory would be required to han= dle both the additional data stream and the additional set of coefficients. T= he core filter loop may be isolated as a separate "callable" funct= ion. This technique lets the same code be used, regardless of the input data v= alues. Benefits of this programming style include readable code, re-usable algorithms, and reduced code size. If a modular approach is not taken, the filter loop would have to be repeated, using additional DSP memory space.=

The SPORT Receive interrupt routine would then consist of the setting = of pointer and calling the filter. The revised filter routine is shown in the following listing:

Filter: cntr =3D taps - 1;
mr =3D 0, mx0 =3D dm(i2,m1), my=
0 =3D pm(i5,m5);
              &nb=
sp;            =
  /* clear accumulator, get first data
              &nb=
sp;            =
     and coefficient value */
do filt_=
loop until ce;  =
    /* set-up zero-overhead loop */
filt_lo=
op: mr =3D mr + mx0*my0(ss), mx0 =3D dm(i2,m1), 
my0 =3D pm(i5,m5=
);            /* MAC and tw=
o data fetches */
mr =3D mr + mx0 * my0 (rnd);   /* final multiply, round to 16-bit
<= pre>              &nb= sp;            =      result */
if mv sat mr;  =
             / * check for overflow*/
rts;              &nb=
sp;          /* return =
*/

It's important to note that the only modifications to the core filter = loop were the addition of a label, "Filter:" at the beginning of the routine, and the addition of an "rts" (return from subroutine) instruction at the end. These additions change filter code from a stand-a= lone routine into a subroutine that can be called from other routines. No long= er a single-purpose routine, it has become a re-usable, callable subroutine. <= /p>

With the core filter set up as a callable subroutine, the two-channel = data handling requirements can now be addressed. To simplify some of the programming issues, this example assumes that both the left and right channels use the same filter coefficients.

In the third installment of this series, the entire filter application assembly code was displayed. At the top of the code listing, all of the required memory buffers were declared. To expand the filter application to handle two channels of data, the required new variables and buffers need = to be declared. For the incoming data, the buffer declaration,

.var/dm/circ_filt_data[taps];  =
/* input data buffer */

would need to be replaced with two buffers, declared as

.var/dm/circ_filt1_data[taps]; /* left channel input data buffer */
.var/dm/circ_filt2_data[ta=
ps]; /* right channel input data buffer */
  

Because both channels are to have the same filter coefficients applied= to them, the data buffers are of equal length.

The filter loop subroutine expects certain data and coefficient values= to be accessed using particular address registers. Specifically, address register I2 must point to the oldest data sample, and I5 must point to the proper coefficient value prior to the filter routine being called.

Because the filters for both the left and right channel will be sharing the same memory pointers, there has to be a mechanism for differentiating= the two data streams. For the data pointer, I2, two new variables need to be defined, "filter1_ptr" and "filter2_ptr."

These locations in memory are going to be used to store address values appropriate for each data stream. The circular buffering capability of the ADSP-2181 is used to ensure that the data pointer is always in the correct place in the buffer whenever the filter is executed. Because the subrouti= ne is now dealing with two buffers, the pointer locations need to be saved w= hen processing for each channel is completed.

To set up the pointers, two variables in data memory need to be declar= ed as follows:

.var/dm filter1_ptr;   /* data pointer for left channel data */
.var/dm filter2_ptr;=
   /* data pointer for right c=
hannel data */

These variable then need to be initialized with the starting address
of each of the data buffers;

.init filter1_ptr: ^filt1_data; =
;      /* initialize starting point,
<= pre>              &nb= sp;            =      left channel */
.init filter2_ptr=
: ^filt2_data;       /* =
initialize starting point,
              &nb=
sp;      &=
nbsp;          rig=
ht channel */

The DSP assembler software recognizes the symbol "^" to mean "address of." The DSP linker software fills in the appropriate address value. In this way, the pointer variables in the executable progr= am are initialized with the starting addresses of the appropriate memory buffers.

The following listing shows how the FIR Filter interrupt routine uses these new memory elements. The original Filter subroutine from the 3rd installment has been modified to provide two separate channels of filteri= ng. Instead of launching directly into the filter calculation, the routine mu= st first load the appropriate data pointer. The filter routine is then calle= d, and the resulting output is placed in the correct location for transmissi= on.

/*--------------------FIR Filter--------------------*/
inp=
ut_samples:
   =
ena sec_reg;  =
       /* use shadow register bank */<=
/pre>
 
/* set up for filter 1 */
i=
2 =3D dm(filter1_ptr);  /* set data pointer for filter 1 =
*/
ax0 =3D dm(rx_buf + 1);  /* read left channel data */
dm(i2,m1) =3D ax0;       /* =
write new data into delay line,
              &nb=
sp;       pointer now pointing to olde=
st data */
 
call filter;           /* perform the firs=
t filter for left
              &nb=
sp;         channel data */<=
/pre>
 
dm(tx_buf+1) =3D mr1;     /* write left-channel outp=
ut data */
dm(filter1_ptr) =3D i2;  /* save updated filter1 data poin=
ter */
 
/* set up for filter 2 */
i2 =3D dm(filter2_ptr);  /* set data pointer for filter 2 =
*/
ax0 =3D dm(rx_buf + 2);  /* read right channel data */
dm(i2,m1) =3D ax0;   =
;     /* write new data into delay line,
              &nb= sp;            pointer now pointing to oldest data */
 
<= pre>call filter;           /* perform the filt= er again for the
              &nb=
sp;         right channel da=
ta */
 
dm(tx_buf+2) =3D mr1;    /* write right channe=
l output data */
dm(filter2_ptr) =3D i2;  /* save updated filter2 data poin=
ter */
 
rti;              &nb=
sp;     /* return from interrupt */

Because the core filter algorithm no longer handles data I/O, this subroutine can be expanded to more channels of filtering by merely adding more pointer variables and declaring more buffer space (as long as sufficient memory exists!) Similarly, different coefficients can be used for the two filters by setting up variables that contain coefficient-buffer pointer information. In either case, the filte= r algorithm does not need to be altered. By using this style of modular programming, = the user can build up a library of callable DSP functions. Differences for particular systems can thus be reduced to data-handling issues rather than the development of new algorithms. While this programming style does not necessarily allow the algorithm to perform its task more quickly, the sys= tem designer has more flexibility in establishing how data flows through the system.

Real-Time Interface Issues: So far, we have examined how real-t= ime programming in embedded systems relies on rapid interrupt response, effic= ient data handling, and fast program execution. In addition, the flow of data = into and out of the processor also influences how well the system will work in= a real-time embedded environment.

The primary data flows into and out of a digital signal processor can = be both parallel and serial. Parallel transfers are typically at least as wi= de as the native data word of the processor's architecture (16 bits for an ADSP-2100 Family processor, 32 bits for the SHARC®). Parallel transfe= rs occur via the external memory bus or external host interface bus of the processor. Serial data transfers require considerably fewer interconnecti= ons; they are frequently used to communicate with data converters.

Serial Interface: Ease of hardware interfacing is an important element of efficient DSP system implementation. The ADSP-2181 EZ-Kit Lite system uses an AD1847 serial codec (COder/DECoder). Serial codecs permit = data transfers via a serial port (SPORT) on the DSP. This serial port is not an RS-232 PC-style asynchronous serial port; it is a 5-wire synchronous interface that passes bit-clock, Receive-data, Transmit-data, and frame-synchronization signals. Major benefits of serial interfaces are low pin count and ease of hardware hookup. The AD1847 requires only 4 signals= to interface to the DSP: serial clock, Receive data, Transmit data, and Rece= ive frame-synchronization signal. The serial data stream is time-division multiplexed (TDM), meaning that the same physical line can carry more than one type of information in serial order. In the case of the AD1847 application on EZ-Kit Lite, initiated in the last issue, the serial line carries both left- and right-channel audio information, along with codec control and status information.

As noted earlier, the processor has various means = for handling this data. SPORT Interrupts are generated automatically by the serial port hardware for either Receive or Transmit data and for either= a single word or a block of words (Figure 2).

3D"Serial3D"Serial

 

Figure 2. Serial interfacing between
digital signal processor and I/O device.

Parallel Interface: Even with a serial bit clock running as fas= t as the DSP processor, a serial interface trades data transfer speed for simplicity of wiring, transferring a data word at a fraction of the DSP processor speed. For system performance that requires higher data rates, a parallel interface can be used. When interfacing in parallel, the DSP exercises its external data and address busses to read or write data to a peripheral device. On the ADSP-2181, the buses can interface with up to 16 bits of data.

Parallel data transfer is always faster than serial transfers. The DSP= can perform an external access every processor cycle, but this requires really fast parallel peripherals that can keep up with it, such as fast SRAM chi= ps. Parallel data transfers with other entities usually occur at less than one per processor cycle.

Interrupt handling is different for the serial and parallel interfaces. Since the external data bus of the DSP processor i= s a general-purpose entity handling all sorts of data, it does not have ded= icated signal lines for interrupt generation and control; however, other DSP resources are available. On the ADSP-2181, several external hardware interrupt lines, such as the one for I/O memory select, are available f= or triggering by an external device, such as an A/D converter or codec. Su= ch an interface is shown in Figure 3, involving a parallel device and the ADSP-2181 DSP.

3D"Parallel

 

Figure 3. Parallel I/O
interfacing for a DSP.

When responding to the interrupt for parallel data, the processor reads the appropriate source and typically places that data value in memory, by= executing instructions similar to those shown here:

irq2_svc: ax0 =3D IO(ad_converter); dm(i2,m1) =3D ax0; rti;

"ad_converter" is a previously defined address in I/O space.=

REVIEW AND PREVIEW

The goal of this article has been to detail the programming concerns t= hat DSP developers face when handling I/O and other events in real-time syste= ms. Issues introduced include real-time data (samples and frames), interrupts= and interrupt-handling, automated I/O, and generalizing routines to make call= able subroutines. This brief article could not do justice to the many levels of detail associated with each of these topics. Further information is avail= able in the references below. Future topics in this series will continue to bu= ild on this application. The next article will add more features to our growi= ng example program and describe software validation (i.e., debugging) techniques.

REFERENCES

ADSP-2100 Family Assembler Tools & Simulator Manual. Consult your local Analog Devices Sales Office.
ADSP-2100 Family User's Manual. Analog Devices. Free.

Many valuable publications can be found in the Design Support area of = our Web site under Product Documentation.

Also see:  (Part 1) (Part 2) (Part 3)

 <= /o:p>

 

Conta= ct ADI | Site Map | Registratio= n

 

© 1995- Analog Devices, Inc. All Rights Reserved