Как удалить программирование с сигнализацией лоджикар 4

До сих пор в этой серии были представлены следующие темы:

  • Часть 1 (том 31-1): Архитектура DSP и преимущества DSP перед традиционными аналоговыми схемами
  • Часть 2 (том 31-2): концепции цифровой фильтрации и алгоритмы фильтрации DSP
  • Часть 3 (т. 31-3): реализация алгоритма фильтра с конечным импульсным откликом (FIR) и обзор демонстрационной аппаратной платформы ADSP-2181 EZ-Kit Lite.

Теперь мы более внимательно рассмотрим проблемы программирования DSP. Которые являются уникальными для систем реального времени. Данная статья посвящена разработке алгоритмов для систем DSP с различными интерфейсами ввода-вывода.

Что значит В аналоговой системе каждая задача выполняется в В системе цифровой обработки сигналов (DSP) сигналы представляются наборами отсчетов. Т. е. значениями в дискретные моменты времени. Таким образом. Время обработки заданного числа выборок в системе DSP может иметь произвольную интерпретацию в В первой статье этой серии вводится понятие дискретизации и критерий Найквиста–что в приложениях реального времени частота дискретизации должна быть как минимум вдвое больше частоты самой высокой частотной составляющей. Представляющей интерес в (аналоговом) сигнале (частота Найквиста).

Время между выборками называется интервалом выборки. Чтобы рассматривать систему как работающую в

Это определение реального времени подразумевает. Что для процессора. Работающего с заданной тактовой частотой. Скорость и количество входных данных определяют. Какой объем обработки может быть применен к данным. Не отставая от потока данных. Идея иметь ограниченное количество времени для обработки данных может показаться странной разработчикам аналоговых систем. Потому что эта концепция не имеет параллели в аналоговых системах. В аналоговых системах сигналы обрабатываются непрерывно.

Единственным наказанием в медленной системе является ограниченная частотная характеристика. Для сравнения. Цифровые системы обрабатывают части сигнала. Достаточные для очень точных приближений. Но только в течение ограниченного промежутка времени. На рис. 1 показано сравнение. DSP в реальном времени может быть ограничен объемом данных или типом обработки. Который может быть завершен в рамках временного бюджета алгоритма. Например, данный DSP-процессор. Обрабатывающий значения данных. Дискретизированные, скажем. На частоте 48 кГц (аудиосигналы). Имеет меньше времени для обработки этих значений данных. Включая выполнение всех необходимых задач. Чем одна выборка данных голосового диапазона 8 кГц.

В примере фильтра. Описанном ранее в этой серии. Частота дискретизации входного сигнала составляет 8 кГц. Чтобы DSP в этом примере не отставал от данных реального времени. Вся обработка должна выполняться в пределах временного бюджета 1/(8 кГц) или 125 мкс. На цифровом сигнальном процессоре с частотой 33 МГц (30 мгц за цикл) бюджет времени обеспечивает 125 мкс/30 нс. Или 4166 циклов команд. Для завершения обработки и любых других необходимых задач.

Поскольку существует конечное количество времени. Которое может быть заложено в бюджет для выполнения любого заданного алгоритма. Управление временем является центральной частью разработки программного обеспечения системы DSP. Стратегия управления временем определяет. Как процессор получает уведомления о событиях. Влияет на обработку данных и формирует процессорные коммуникации.

Рисунок 1
Рис. 1. Сравнение аналоговой и цифровой обработки сигналов. а. Аналоговая: Значение отклика соответствует каждому значению данных во все моменты времени. б. Цифровая: Для каждого образца данные должны быть переданы и обработаны. Событие отмечает конец обработки (контроль). И дополнительное время может потребоваться для других задач в цикле после того. Как произойдет указанный процесс.

Уведомление о событии: Прерывания: Можно запрограммировать DSP для обработки данных. Используя одну из нескольких стратегий обработки Бит состояния или пин-код флага можно периодически считывать. Чтобы определить. Доступны ли новые данные. Но–Данные могут поступать сразу после последнего опроса. Но они не могут сообщить о своем присутствии до следующего опроса. Это затрудняет разработку систем реального времени.

Вторая стратегия заключается в том. Чтобы данные прерывались процессор по прибытии. Использование прерываний для уведомления процессора эффективно. Хотя и не так легко программировать; тактовые циклы могут быть потрачены впустую во время ожидания прерывания. Тем не менее. Поскольку событийное программирование прерываний хорошо подходит для оперативной обработки реальных сигналов. Большинство DSP предназначены для эффективной работы с ними. На самом деле они предназначены для того. Чтобы очень быстро реагировать на прерывания. Время отклика ADSP-2181 на прерывание составляет около трех тактов процессора. То есть в течение 75 нс DSP перестает делать то. Что он делал. И обрабатывает событие прерывания (вектор).

Во многих системах на базе DSP частота прерываний. Основанная на частоте дискретизации входных данных. Часто совершенно не связана с тактовой частотой DSP. В примере FIR. Рассмотренном ранее в этой серии. Процессор прерывается с интервалом 125 мкс для получения новых данных.

Обработка прерываний и векторы прерываний: Поскольку обработка прерываний является жизненно важным элементом в системах DSP. Процессоры обычно имеют встроенные аппаратные механизмы для эффективной обработки прерываний. Проводные механизмы более эффективны. Чем только программное обеспечение. Поскольку процедуры обслуживания прерываний DSP (ISR) могут отвечать всем следующим требованиям:

  • Fast context switching–switch from working on one task and its data (a context) 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 handling 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 with the «real-world,» the DSP must record these events and accept the data–then process them when it has finished servicing the interrupt.

On Analog Devices DSPs. Fast context switching is accomplished using two 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 between 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. This stack mechanism also allows interrupts to be nested; one with higher 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 state of operation. And prepares to execute the interrupt routine. Interrupt routines are dispatched from an interrupt vector table. An interrupt vector 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 processor 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 table indicate. An ADSP-2181 can handle interrupts from 11 locations (external hardware, DMA ports. And the serial ports) and the processor Reset. The table lists the programmed instructions assigned to each interrupt vector source in memory locations 0x0000 to 0x002F for an FIR filter program.

Jump start; nop; nop; nop; /* 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 = dm(stat_flag); ar = pass ar; if eq_rti; jump next_cmd;
                       /* PM(0x0010-13): SPORT0 Tx vector */
jump input_samples; nop; nop; nop;
                       /* PM(0x0014-17): SPORT0 Rx vector */
jump irqe; nop; nop; nop; /* PM(0x0018-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 programmed directly. As shown in the SPORT0 Tx vector (0x0010-13). Any unused interrupt vectors call for return from interrupt (rti). With three nop (no operation) instructions.

The nop instructions serve as place holders–instruction space used to ensure that the correct interrupt action lines up with the hardware-specified interrupt vector. The rti instruction at the beginning of each unused vector 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 data 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 serial port incorporates two data I/O registers, a receive register (Rx). And a transmit register (Tx). When a serial word is received. The port will typically generate a Receive interrupt. The processor 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 background 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 return to the interrupt vector.

To transmit data. The serial port can generate a Transmit interrupt. Indicating that new data can be written to the SPORT Tx register. The DSP can then begin 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 output are controlled by the same sampling clock. Only one interrupt is necessary. For example. If a program segment is initiated by Receive interrupt timing. 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 new data.

In the FIR filter example (Analog Dialogue 31-3, page 15). A SPORT 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 single-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 handling 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 would not have to change. The code relating to data handling, however. Would have 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 handle both the additional data stream and the additional set of coefficients. The core filter loop may be isolated as a separate «callable» function. This technique lets the same code be used. Regardless of the input data values. 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 = taps — 1;
mr = 0, mx0 = dm(i2,m1). My0 = pm(i5,m5);
                    /* clear accumulator. Get first data
                       and coefficient value */
do filt_loop until ce;     /* set-up zero-overhead loop */
filt_loop: mr = mr + mx0*my0(ss). Mx0 = dm(i2,m1),
my0 = pm(i5,m5);     /* MAC and two data fetches */
mr = mr + mx0 * my0 (rnd);   /* final multiply. Round to 16-bit
                       result */
if mv sat mr;             / * check for overflow*/
rts;                     /* 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-alone routine into a subroutine that can be called from other routines. No longer a single-purpose routine. It has become a re-usable. Callable subroutine.

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[taps]; /* 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 subroutine is now dealing with two buffers. The pointer locations need to be saved when processing for each channel is completed.

To set up the pointers. Two variables in data memory need to be declared as follows:

.var/dm filter1_ptr; /* data pointer for left channel data */
.var/dm filter2_ptr; /* data pointer for right channel 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,
                       left channel */
.init filter2_ptr: ^filt2_data; /* initialize starting point,
                       right 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 program 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 filtering. Instead of launching directly into the filter calculation. The routine must first load the appropriate data pointer. The filter routine is then called. And the resulting output is placed in the correct location for transmission.

/*———————FIR Filter———————*/
input_samples:
   ena sec_reg;        /* use shadow register bank */

/* set up for filter 1 */
i2 = dm(filter1_ptr); /* set data pointer for filter 1 */
ax0 = dm(rx_buf + 1); /* read left channel data */
dm(i2,m1) = ax0; /* write new data into delay line,
             pointer now pointing to oldest data */

call filter;        /* perform the first filter for left
               channel data */

dm(tx_buf+1) = mr1;     /* write left-channel output data */
dm(filter1_ptr) = i2; /* save updated filter1 data pointer */

/* set up for filter 2 */
i2 = dm(filter2_ptr); /* set data pointer for filter 2 */
ax0 = dm(rx_buf + 2); /* read right channel data */
dm(i2,m1) = ax0;        /* write new data into delay line,
                  pointer now pointing to oldest data */

call filter;        /* perform the filter again for the
               right channel data */

dm(tx_buf+2) = mr1; /* write right channel output data */
dm(filter2_ptr) = i2; /* save updated filter2 data pointer */

rti;                /* 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 filter 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 system designer has more flexibility in establishing how data flows through the system.

Real-Time Interface Issues: So far, we have examined how real-time programming in embedded systems relies on rapid interrupt response. Efficient 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 wide as the native data word of the processor’s architecture (16 bits for an ADSP-2100 Family processor, 32 bits for the SHARC®). Parallel transfers occur via the external memory bus or external host interface bus of the processor. Serial data transfers require considerably fewer interconnections; 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 Receive 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). Serial interfacing between digital signal processor and I/O device

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

Parallel Interface: Even with a serial bit clock running as fast 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 chips. 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 is a general-purpose entity handling all sorts of data. It does not have dedicated 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 for triggering by an external device. Such as an A/D converter or codec. Such an interface is shown in Figure 3, involving a parallel device and the ADSP-2181 DSP. Parallel I/O interfacing for a DSP

Figure 3
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 = IO(ad_converter); dm(i2,m1) = 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 that DSP developers face when handling I/O and other events in real-time systems. Issues introduced include real-time data (samples and frames). Interrupts and interrupt-handling. Automated I/O. And generalizing routines to make callable subroutines. This brief article could not do justice to the many levels of detail associated with each of these topics. Further information is available in the references below. Future topics in this series will continue to build on this application. The next article will add more features to our growing 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)