• Non ci sono risultati.

5.1 Elaborazione in tempo reale

N/A
N/A
Protected

Academic year: 2021

Condividi "5.1 Elaborazione in tempo reale "

Copied!
26
0
0

Testo completo

(1)

Capitolo 5

MVE II: Multimedia Video Engine II

5.1 Elaborazione in tempo reale

Un segnale video è composto da un insieme di fotogrammi disposti secondo una certa sequenza temporale; lo standard europeo (PAL) prevede 25 fotogrammi al secondo mentre quello americano (NTSC) ne prevede 30.

Parlando di video processing in algoritmi di stima del moto si fa sempre riferimento alla elaborazione di uno o più fotogrammi appartenenti ad un certo intervallo temporale (generalmente si elaborano coppie di immagini consecutive).

Un sistema di elaborazione video in tempo reale deve quindi, per ogni fotogramma del segnale di ingresso, effettuare un certo numero di operazioni e restituire in uscita un segnale video con lo stesso frame rate (numero di fotogrammi al secondo) di quello in ingresso.

Il concetto di tempo reale si concretizza infatti nel fornire un’uscita significativa entro un determinato intervallo di tempo, nel nostro caso 40 ms.

L’importanza dell’elaborazione in tempo reale in applicazioni biomediche, come l’ecografia ad esempio, sta nella possibilità di avere un feedback immediato sull’analisi in corso e nel poter controllare istantaneamente la variazione di parametri ottenuti dall’elaborazione; l’elevato numero di immagini a disposizione permette inoltre di mediare i parametri ricavati su più frame, ottenendo quindi valori più robusti nei confronti del rumore.

Nonostante le elevate potenze di calcolo offerte dai processori per sistemi Desktop e Workstation, è preferibile in questo contesto adottare una piattaforma specifica, come ad esempio un sistema basato su DSP ; i vantaggi di una scelta di questo tipo sono:

ƒ possibilità di lavorare su un sistema puramente dedicato all’elaborazione video

ƒ libertà nella configurazione in base alle caratteristiche dei segnali in gioco

ƒ possibilità di gestire le risorse in modo arbitrario, a seconda dell’applicazione

ƒ maggiore potenza di calcolo

(2)

Il sistema utilizzato in questo lavoro è il Multimedia Video Engine II ( MVEII ), una piattaforma di elaborazione video in tempo reale basata su DSP sviluppata presso il laboratorio di Computer Vision/DSPLab dell’Istituto di Fisiologia Clinica del CNR di Pisa.

5.2 Un’architettura DSP-based

Riportiamo lo schema a blocchi semplificato dell’ MVEII :

figura 46: schema a blocchi MVE II DSP

TMS320C6415 128 Kb L1D Data Cache 128 Kb L1P Program Cache 8 Mb L2 Cache

28 operazioni/ciclo 4800 MIPS fclock: 600 MHz

FPGA

2 Altera Cyclone

TM

EP1C3

MEMORY

128 MB SDRAM 133 MHz 2 MB memoria flash

VIDEO IN

4 multiplexed inputs

CVBS, Y/C, PAL, SECAM, NTSC LVDS

VIDEO OUT

XVGA fino a 1280x1024 Simultaneous Hardware Cursor and Pop-up Window

2D graphic accelerator Analog I/Os

8 channel inputs 4 channel outputs sample rate: 133 MHz

EXTERNAL PORTS USB 2.0 Host Controller USB 2.0 Device Controller 10/100 Base T LAN RS232 Serial Port XDS510 J-TAG

EXPANSION PORTS TI Daughter card (SPRA711) PCI

Isolated digital I/O

4 Dip switch

4 user led

(3)

Prima di approfondire l’architettura del sistema è doveroso dare qualche informazione preliminare sull’elemento centrale del sistema in oggetto: il DSP TMS320C6415 .

Innanzitutto dobbiamo giustificare la scelta del dispositivo: dovendo lavorare su immagini, ovvero su matrici a valori interi compresi tra 0 e 255, è consigliabile scegliere un DSP che lavori in modo efficiente su dati di 8 bit. Il nostro DSP ha ALU a 32 bit che esegue le operazioni su 4 dati ad 8 bit, questo significa che ad ogni ciclo è possibile eseguire ad esempio la moltiplicazione su 4 dati e memorizzare il risultato su 64 bit.

Questo meccanismo viene chiamato “splitting della ALU” ed è uno dei punti forza del DSP scelto.

Caratteristiche principali

ƒ frequenza di clock: 600 MHz

ƒ 8 istruzioni su 32 bit per ciclo di clock

ƒ 28 operazioni per ciclo di clock

ƒ 4800 MIPS

ƒ 6xALU - 32 bit

ƒ Registri a 32 – 64 bit

ƒ 128 Kbit (16 Kbyte) L1P program cache

ƒ 128 Kbit (16 Kbyte) L1D data cache

ƒ 8 Mbit (1 Mbyte) L2 RAM

ƒ 2 interfacce per memorie esterne: EMIFA (64 bit) ed EMIFB (16 bit)

ƒ memoria max esterna indirizzabile: 1280 Mbyte

ƒ Controllore EDMA (Enhanched Direct Memory Access)

ƒ Interfaccia PCI master/slave (32 bit – 33 MHz)

ƒ 4 interfacce seriali a memorie EEPROM

ƒ Interfacciamento diretto verso T1/E1

ƒ 3 timers general purpose a 32 bit

ƒ 16 pin general pur pose I/O

ƒ clock generato con PLL programmabile

Analizziamo ora il sistema nel dettaglio, focalizzando l’attenzione su ciascuno dei suoi

componenti; trattandosi di una piattaforma di elaborazione video, è interessante

affrontare la descrizione seguendo il flusso del segnale, dall’acquisizione alla

presentazione su un dispositivo di uscita, passando per la elaborazione, ad opera del DSP :

(4)

figura 47: acquisizione > elaborazione > video out

E’ importante sottolineare che verranno approfondite solo le caratteristiche dei dispositivi utili alla comprensione del funzionamento del sistema.

5.3 Stadio di ingresso: acquisizione video

Il sistema può ricevere in ingresso un segnale video composito oppure s-video: il video composito (CVBS) è un formato nel quale sono miscelati i segnali di luminanza e crominanza, l’s-video (Y/C) invece è un formato nel quale i segnali di luminanza (Y) e di crominanza (C) sono separati su due linee diverse, così da ottenere una qualità dell’immagine migliore rispetto a quella con video composito.

Lo stadio di acquisizione del segnale video può essere schematizzato come segue:

figura 48: stadio di acquisizione video

L’ SAA7114 è un decoder video: riceve in ingresso un segnale analogico e restituisce un

segnale video campionato. In figura 49 ne viene riportato lo schema a blocchi:

(5)

figura 49: schema a blocchi SAA7114

Il chip ha 6 ingressi analogici ( AI11-AI24 ) che possono essere configurati dall’utente per accettare segnali video composito oppure s-video.

A seguito del campionamento del segnale di ingresso viene generata una matrice delle dimensioni dell’immagine ad opera del DIGITAL DECODER ; segue uno stadio che si occupa di un eventuale ridimensionamento dell’immagine, così da adattare il segnale ad una particolare risoluzione oppure ottenere degli zoom: dal momento che queste operazioni risultano molto onerose in termini di calcolo, poter svicolare il DSP dalla loro esecuzione risulta sicuramente un vantaggio in un sistema di questo tipo

Sui pin IPD[7:0] troviamo infine il segnale di uscita su 8 bit paralleli (si trasmette un byte alla volta).

Il chip è programmabile via seriale, secondo lo standard I 2 C (sviluppato da Philips); i

parametri di programmazione/configurazione risiedono in una RAM e devono quindi

essere impostati ad ogni avvio del chip: è quindi il DSP che, in fase di inizializzazione, si

preoccupa di impostare tali parametri.

(6)

Il DSP non ha un’interfaccia I 2 C , per questo si appoggia all’ FPGA Cyclone EP1C3

( FPGA1 ) che contiene un modulo di conversione SPI-I 2 C ( SPI: Serial Peripheral Interface) .

Sulla scheda sono presenti 2 FPGA (Field Programmable Gated Array) appartenenti alla famiglia Cyclone di Altera.

L’ EP1C3 ha 2910 elementi logici, 59904 Mbit di RAM , 1 PLL , si programma via seriale e la configurazione risiede nella sua RAM .

Il segnale in uscita all’ SAA7114 viene ricevuto dall’ FPGA1 ; nel caso di immagini su scala di grigi ogni byte indica l’intensità del livello di grigio di ciascun pixel, mentre nel caso di immagini a colori i byte necessari per ogni pixel sono 2: uno per l’intensità del livello di grigio ed uno per l’informazione sulla crominanza.

In quest’ultimo caso abbiamo quindi 16 bit per ogni pixel dell’immagine; l’ FPGA1 si preoccupa in ogni caso di immagazzinare in una sua memoria interna, organizzata a FIFO , l’informazione necessaria alla ricostruzione di una linea dell’immagine, dopodiché lancia un segnale di interrupt al DSP che a quel punto avvia il trasferimento dei dati di riga dalla

FIFO alla sua memoria interna. La FIFO può contenere fino a 2 linee, così da bufferizzare l’informazione.

Un processo di memorizzazione e trasferimento dati di questo tipo si trova frequentemente nei sistemi di acquisizione ed elaborazione video: immagazzinando infatti i dati nella FIFO e trasferendo solo le righe complete si lascia il DSP libero di eseguire i task di elaborazione e di essere quindi interrotto per inizializzare il trasferimento solo al completamento di ogni linea. Il trasferimento dei dati dalla FIFO alla memoria interna del DSP viene effettuato dal controllore DMA .

Osserviamo poi che nel caso di immagini in scala di grigi il tempo necessario per il trasferimento dell’immagine campionata nella memoria interna del DSP è la metà rispetto al caso di immagini a colori: questo perché in ogni pacchetto di 16 bit l’informazione è relativa a due pixel invece che uno, quindi il tempo è dimezzato.

La comunicazione tra FPGA1 e DSP avviene ad una frequenza di 133 MHz tramite un BUS

sincrono a 16 bit; il DSP si interfaccia al BUS tramite la EMIFB ( External Memory

InterFace ).

(7)

Nella nostra applicazione (vedremo più avanti) lo standard video utilizzato è il CIF, con una risoluzione di 352*288 pixel: ogni linea è quindi costituita da 352 pixel.

Nel caso di immagini a colori, in cui l’informazione su un pixel è codificata su 16 bit, il tempo necessario a trasferire una linea è pari a 352 133 10 sec 2.6 s ( ⋅ 6 ) ≈ µ ed il periodo di trasmissione è pari a 1/ 25* 625 ( ) = 64 s µ , dove 25 è il numero di frame al secondo e 625 è il numero di linee per lo standard PAL.

5.4 Stadio di elaborazione: DSP

Ora che il dato è disponibile, il DSP può immagazzinarlo nella sua memoria interna.

Consideriamo lo schema a blocchi dell’architettura del DSP :

figura 50: schema a blocchi architettura DSP

(8)

Come si vede il core del DSP si interfaccia alla RAM L2 solo attraverso due memorie cache L1 ( data cache e program cache ); se il dato è gia presente in L1 , la lettura avviene in un ciclo di clock, altrimenti il DSP va a cercare il dato in L2 oppure all’esterno:

ƒ nel caso in cui il dato sia presente in L2 questo viene letto direttamente dal CORE ; il tempo impiegato per la lettura in questo caso è pari a due cicli di clock: un ciclo pr controllare se il dato è in L1 ed un altro ciclo per leggere il dato da L2

ƒ se invece il dato risiede nella memoria esterna, il processo di lettura avviene tramite trasferimento DMA , gestito in modo automatico dal DSP in quanto impostato dal costruttore: è una modalità sulla quale il progettista non può intervenire. In questo caso il tempo necessario per la lettura del dato è pari a circa 13-14 cicli di clock, durante i quali il core del DSP è come congelato, non può eseguire nessuna operazione.

Vediamo ora come avviene l’immagazzinamento dei frame nella memoria L2 .

In un segnale video PAL (frame rate = 25 fps), il tempo che intercorre tra un frame ed il successivo è pari a 40 ms: in questo intervallo temporale il nostro sistema deve acquisire completamente il segnale, elaborarlo ed inviarlo al dispositivo di uscita.

In realtà le operazioni di acquisizione ed elaborazione sono organizzate come illustrato in figura:

figura 51: sequenza acquisizione/elaborazione frame

In ogni intervallo della durata di 40 ms il DSP si preoccupa di memorizzare il frame in arrivo nella RAM e di elaborare il frame acquisito nell’intervallo precedente.

Da questo si deduce che la memoria deve contenere contemporaneamente due frame:

quello in elaborazione e quello in acquisizione.

(9)

La figura 52 riporta il contenuto della memoria negli istanti t’ e t” appartenenti a due intervalli consecutivi:

figura 52: memory map in acquisizione/elaborazione

All’istante t’ nella porzione di memoria indicata con A è presente il frame f n-1 acquisito all’intervallo precedente che quindi è pronto per essere elaborato; durante la elaborazione, il DSP riceverà un interrupt per ogni linea del frame corrente f n completata e la immagazzinerà nella porzione di memoria indicata con B .

All’istante t” la situazione sarà opposta, ovvero verrà elaborato il frame nella regione B e verranno memorizzate le linee nella regione A : questo meccanismo prendo il nome di

ping pong , ad indicare il continuo scambio di ruolo tra le due porzioni di memoria.

Questo meccanismo permette di garantire un flusso di elaborazione video in tempo reale, lasciando al DSP la maggior parte del tempo disponibile all’elaborazione del frame.

Continuando a seguire il flusso del segnale video, descriviamo ora il trasferimento dei dati elaborati verso l’interfaccia di uscita.

5.5 Stadio di uscita: video out

Per trasferire il segnale in uscita, possiamo pensare di riservare un’ulteriore area di

memoria per il frame elaborato ( triple buffering ) e trasferirlo verso l’uscita con un

procedimento analogo a quello di acquisizione: questa soluzione è vantaggiosa solo nel

caso in cui il tempo necessario a trasferire il segnale sia paragonabile a quello di

acquisizione, se ad esempio il dispositivo di uscita è lento e quindi il trasferimento dei

(10)

dati impegna il DSP per quasi tutto l’intervallo di tempo concesso dal vincolo del real time; in alternativa possiamo portare fuori tutti i dati in blocco al termine dell’elaborazione. La soluzione adottata è stata quest’ultima, dove il tempo impiegato a trasferire i dati è 1,5ms e va sottratto ai 40ms a disposizione per l’elaborazione.

figura 53: stadio di uscita - video out

Il DSP è collegato ad un chip video, il B69000 , tramite un BUS PCI a 32 bit ad una frequenza di 33 MHz , sul quale vengono multiplexati dati ed indirizzi.

Il B69000 è un chip video che fornisce in uscita un segnale VGA standard oppure un segnale TV-out ; essendo un modello un po’ datato, la gestione delle due uscite non può avvenire contemporaneamente.

Le due modalità di uscita possono essere configurate dall’utente, così come la risoluzione del segnale video-out; il chip memorizza in una struttura interna le informazioni sul segnale video di uscita ricevute dal DSP , relative all’immagine di ingresso eventualmente elaborata, all’interfaccia grafica ( GUI: Graphic User Interface ) e ad eventuali forme geometriche (linee, punti) da rappresentare sopra l’immagine ( overlay ).

Come abbiamo detto, la comunicazione tra DSP e B6900 avviene tramite un BUS PCI sul quale si basa il chip VGA utilizzato; nella comunicazione interviene un FPGA identico a quello che troviamo nella catena di ingresso; chiameremo questo secondo chip FPGA2 . La sua presenza è giustificata dal fatto che su un bus PCI è necessario un dispositivo che regoli la comunicazione e che inizializzi i dispositivi: un ARBITRO PCI .

I compiti dell’arbitro consistono nel:

ƒ interrogare ciascun dispositivo connesso al BUS per identificarlo

ƒ inizializzare, all’avvio, tutti i dispositivi connessi

(11)

ƒ assegnare ad ogni dispositivo un indirizzo

ƒ regolare i trasferimenti di dati fra dispositivi

Per sua natura il PCI è predisposto ad accettare diversi dispositivi (è lo stesso che si utilizza nella motherboard del PC , dove le schede possono essere cambiate continuamente) e a priori non sa cosa può essere connesso al BUS .

In questo modo l’arbitro gestisce le comunicazioni ed identifica i dispositivi connessi assegnando ciascuno un indirizzo virtuale; l’insieme delle periferiche connesse al BUS è quindi visto come unico spazio di memoria, ed il dialogo con ciascun dispositivo avviene tramite il trasferimento di dati in ogni sua locazione virtuale.

Quando il trasferimento delle informazioni al B69000 è terminato, la matrice che

descrive il video out è completa; un RAM-DAC interno al chip video si preoccupa di

convertire in analogico i dati presenti nella matrice e fornire in uscita il segnale VGA ; nel

nostro caso il segnale video presenta canali RGB separati e risoluzione 800x600 pixel .

(12)
(13)

5.6 Periferiche

Dopo aver percorso il flusso del segnale video, continuiamo la descrizione della scheda con riferimento allo schema a blocchi riportato.

Memoria RAM esterna

L’ MVE II è equipaggiato con 4 chip di memoria SDRAM esterna da 256 Mbit ciascuno, per un totale di 128 Mbyte complessivi, collegati alla interfaccia EMIFA del DSP tramite un

BUS a 64 bit che lavora a 133 MHz .

Ciascun chip di memoria lavora su dati a 16 bit ed è organizzato in modo da leggere ciascun dato in contemporanea agli altri, per formare un unico dato a 64 bit.

Memoria flash

Sulla piattaforma è presente una memoria flash asincrona da 2 Mbyte con bus dati a 16 bit , montata sul BUS connesso alla EMIFB .

Lo scopo principale della flash è quello di contenere il firmware del DSP ed il codice utente, ovvero l’insieme delle istruzioni che devono essere eseguite per la gestione del sistema e per l’esecuzione della specifica applicazione implementata.

All’interno del DSP è infatti presente un piccolo modulo che tramite l’interfaccia EMIFB

va a leggere il contenuto di una memoria esterna e lo copia nella RAM , dopodiché lo esegue

Il modulo di boot va a copiare solo una regione di 1Kbyte della flash nella RAM interna, a partire dalla prima locazione di memoria all’indirizzo 0x00000000; il firmware avrà dimensioni molto maggiori di 1Kbyte , quindi è possibile sfruttare questo meccanismo:

- nella flash viene caricato il firmware più un piccolo codice eseguibile chiamato

BOOTLOADER

- all’avvio del sistema, il modulo di boot del DSP copia 1Kbyte di dati dalla flash

alla RAM : dobbiamo fare in modo che questi dati contengano il codice del

BOOTLOADER

- una volta copiato il codice nella RAM , il DSP lo esegue

A questo punto è chiaro che se nel BOOTLOADER c’è scritto di prendere il contenuto

restante della flash, ovvero il firmware, e copiarlo nella RAM , alla fine del trasferimento il

(14)

DSP ha in memoria tutte le routine da utilizzare per l’esecuzione del programma e da questo momento in poi procede in modo autonomo: il modulo di boot verrà utilizzato solo al prossimo riavvio del sistema.

Ovviamente dovremo aver cura di proteggere le prime locazioni di memoria interna, nelle quali è presente il BOOTLOADER , così da non accedervi mai durante la esecuzione del programma; approfondiremo questo argomento parlando del firmware del DSP .

Controller USB: ISP1161

Il controller USB ha il compito di interfacciare il sistema con periferiche come mouse o tastiera; può funzionare sia come HOST che come DEVICE , anche se nel nostro sistema svolge solo la funzione di host.

E’ connesso direttamente sulla EMIFB , trasferisce dati in modo asincrono ed è completamente programmabile dall’utente.

ADC (MAX1202) / DAC (DAC7614)

Sulla scheda sono presenti un convertitore analogico-digitale ed uno digitale-analogico;

lo scambio di dati con il DSP avviene tramite un canale seriale sincrono, mentre dall’ FPGA1 ricevono il segnale di SELECT , che indica quindi quale dei due dispositivi utilizzare.

Entrambi i convertitori sono a 12 bit , hanno l’interfaccia analogica verso il mondo esterno e quella digitale verso il sistema.

Ethernet (X-port)

E’ presente poi una interfaccia LAN ( X-port ), costituita da un connettore Ethernet e da un microcontrollore il quale gestisce vari protocolli di comunicazione (http, telnet etc…); lo scambio di dati con il DSP avviene tramite connessione seriale asincrona.

Dal momento che il DSP non ha una interfaccia asincrona, la comunicazione è gestita da

una UART ( Universal Asynchronus Receiver Transmitter ) implementata direttamente

nell’ FPGA1 ; lo stesso segnale seriale asincrono può essere portato verso l’esterno tramite

l’interfaccia RS232 .

(15)

WATCHDOG: TPS3106

Dispositivo che mantiene in reset il DSP finché non si è stabilizzata la tensione esterna.

Lo stesso segnale è portato a tutte le periferiche di sistema, ed è messo in AND con un reset fornito dal DSP .

Alimentazioni

Il DSP necessita di due diverse tensioni di alimentazione:

ƒ 1.4 V è la tensione di CORE

ƒ 3.3 V è la tensione con cui si alimentano i buffer sui pin di I/O

Le FPGA necessitano di due diverse tensioni di alimentazione:

ƒ 1.5 V è la tensione di CORE

ƒ 3.3 V è la tensione con cui si alimentano i buffer sui pin di I/O

Le alimentazioni fornite dall’esterno sono quindi:

ƒ 5 V: da questa ricavo la 1.4 V, la 3.3 V e la 1.5 V

ƒ ±12 V: da questa, con due regolatori serie (7805 e 7905) ricavo le tensioni ±5V per l’alimentazione del DAC e dell’ ADC

Clock

ƒ il DSP lavora con una frequenza di clock di 600 MHz, fornita da un cristallo esterno a 50 MHz e moltiplicata internamente per 12 da un PLL .

ƒ per le EMIFx serve un clock a 133 MHz, fornito separatamente da un quarzo da 133 MHz

ƒ il PCI lavora invece a 33 MHz, ed il suo clock è generato dall’arbitro PCI che ha un

PLL interno e moltiplica per 8/9 una frequenza di 37.5MHz proveniente dalla seriale sincrona del DSP

ƒ l’ FPGA1 lavora a 133 MHz prelevando il segnale dal bus, mentre l’FPGA2 lavora a 33

MHz e sfrutta la frequenza generata internamente.

(16)

5.7 Firmware

Livelli di astrazione

Dallo schema a blocchi e dalla descrizione dell’hardware del sistema si capisce che il

DSP è l’elemento centrale della piattaforma, sia per quanto riguarda l’esecuzione degli algoritmi che la configurazione delle periferiche.

Oltre al codice dell’algoritmo implementato, sul DSP girerà un piccolo sistema operativo che si occuperà della gestione dei thread in esecuzione, della memoria, dei processi etc.

L’MVEII presenta all’utente dei livelli di astrazione che possono essere schematizzati in questo modo:

codice utente (UC) events Framework (FW) Board Support Libraries (BSL) Chip Support Libraries (CSL)

DSP/Bios

Hardware (HW)

Il livello più basso è quello hardware , composto dalle periferiche di sistema, la memoria esterna, il DSP , i chip di interfaccia, i convertitori etc.

Per capire i livelli superiori è necessario prima presentare alcuni concetti strettamente legati al DSP : Board Support Libraries , Chip Support Libraries e DSP/BIOS

L’insieme dei livelli riportati in azzurro prende generalmente il nome di middleware , mentre tutto l’insieme, fatta eccezione dell’ hardware , prende generalmente il nome di

firmware .

Lo scopo di questa impostazione è la realizzazione di un sistema sul quale l’utente possa implementare in tempi relativamente brevi algoritmi di elaborazione video svincolandosi quasi completamente dalla gestione hardware del sistema.

Una piattaforma di questo tipo risulta molto utile per l’implementazione ed il testing di operatori per l’elaborazione delle immagini e per la realizzazione di prototipi.

Chip Support Libraries

Il DSP utilizzato è un TMS32C6415 prodotto dalla Texas Instruments ed appartiene alla

famiglia che fornisce prestazioni maggiori per l’elaborazione video.

(17)

L’ambiente di sviluppo fornito a corredo è il Code Composer ; grazie a questo software possiamo scrivere il codice, compilarlo, gestire i moduli del DSP e svolgere funzioni di debug durante l’esecuzione dell’algoritmo sul dispositivo.

Dobbiamo ora chiederci come è possibile eseguire applicativi sul DSP sfruttando tutte le sue risorse: partiamo dalle Chip Support Libraries (CSL) .

Il costruttore, nel nostro caso la Texas Instruments, mette a disposizione dell’utente delle librerie di funzioni (le CSL ), diverse a seconda del modello di DSP , che permettono di gestire, ad esempio:

ƒ porte seriali del DSP

ƒ DMA/EDMA

ƒ cache

ƒ timers etc.

Le CSL servono quindi per interagire con le periferiche interne del DSP , e su queste possiamo iniziare a costruire le nostre applicazioni.

Il DSP però è generalmente inserito in un sistema più complesso dove sussiste uno scambio di dati con altre periferiche e con il mondo esterno; per interagire con tali periferiche, esterne al DSP , possiamo appoggiarci alle Board Support Libraries (BSL).

Board Support Libraries

Tramite le BSL l’utente può quindi gestire le periferiche della scheda come ad esempio:

ƒ led

ƒ switch

ƒ codec

ƒ memorie flash

ƒ ADC/DAC

Basandosi sulle CSL e sulle BSL possiamo allora impostare la gestione del sistema, in particolare il flusso di acquisizione – elaborazione – uscita del segnale video, viste le finalità dell’ MVE II .

Il concetto che sta alla base dei livelli di astrazione è quello di avere una piattaforma di

elaborazione video in tempo reale dove uno sviluppatore possa costruire la propria

(18)

applicazione senza quasi doversi preoccupare di quello che accade ai livelli inferiori: un ruolo fondamentale in questa architettura lo riveste il DSP/BIOS .

Il DSP/BIOS

Per comprendere il DSP/BIOS dobbiamo riprendere alcuni concetti legati ad un generico sistema operativo.

Quando un programma va in esecuzione su un sistema (ad esempio un PC), le sue istruzioni vengono caricate in memoria e poi vengono eseguite in modo continuo secondo particolari routines fino al termine dell’esecuzione del programma stesso.

Può accadere che durante l’esecuzione ci sia la necessità di eseguire un secondo programma: a questo punto è necessario gestire le risorse della CPU per poter eseguire entrambi i programmi.

Si parla allora di multitasking , in quanto ogni programma, o meglio, ogni sua parte, viene chiamato task .

Diamo alcune definizioni utili per la comprensione dell’argomento

ƒ thread : compito che la CPU deve assolvere

ƒ scheduler : gestore della sincronia dei thread

ƒ preemption : possibilità di interrompere un compito da parte dello scheduler

ƒ post : segnalazione, richiesta di esecuzione

ƒ pend : segnalazione, richiesta di sospensione

ƒ Interrupt : segnale di interruzione di un thread per l’esecuzione di un altro thread

ƒ Hardware Interrupt (HWI) : thread messo in esecuzione in seguito all’arrivo di

interrupt fisici, provenienti da periferiche HW sia interne che esterne alla CPU ; è breve, ha alta priorità ed esegue compiti molto importanti

ƒ Software Interrupt (SWI) : ha un comportamento simile all’ HWI ma viene attivato via software e non da uno stimolo esterno (gli HWI hanno priorità più alta dei SWI ); in genere è usato in risposta ad altri interrupt

ƒ Idle (IDL) : esecuzione di background; è un thread in cui la CPU “non fa nulla”

ƒ Task (TSK) : thread che, una volta avviato, rimane sempre in esecuzione; la sua

gestione è generalmente legata ad agenti esterni come ad esempio i semafori

(19)

Date queste definizioni possiamo introdurre la problematica della gestione dei thread nel nostro sistema, nel quale il tempo a disposizione per l’esecuzione delle operazioni è limitato dai vincoli del tempo reale.

In questa situazione, dovendo eseguire più thread , c’è il rischio di non rispettare i vincoli temporali, di non eseguire un thread oppure di eseguirlo solo in parte.

Se il numero di thread è ridotto si può pensare di utilizzare interruzioni reciproche (nesting interrupts), oppure impostare il sistema come una macchina a stati finiti e gestire in fase di programmazione l’esecuzione dei thread come la successione di stati in cui la macchina si trova: questo risulta molto complesso da realizzare ed inoltre vincola strettamente il funzionamento agli stati creati; una piccola modifica all’applicazione comporta infatti la riscrittura della gestione dei thread .

In generale, quando le cose si complicano, nasce la necessità di utilizzare un vero e proprio sistema operativo per la gestione dello scheduling : per questo esiste il DSP/BIOS . Tramite la distinzione tra HWI, SWI e TSK , il DSP/BIOS ha cura di eseguire tutti i thread

necessari nell’intervallo di tempo richiesto, basandosi su segnali di interrupt e sulle priorità, come illustrato in figura (dall’alto verso il basso diminuisce la priorità dei

thread ):

HWI

SWI2 SWI1

TSK2

TSK1

main()

IDL

figura 54: esempio di gestione dei task del DSP/Bios

(20)

ƒ inizialmente è in esecuzione il main()

ƒ al termine di main() viene messo in esecuzione TSK2

ƒ il semaforo di TSK2 viene messo in pending ed inizia l’esecuzione di TSK1

ƒ arriva un’interrupt e viene messo in esecuzione HWI , a priorità più alta di TSK1

ƒ durante l’esecuzione di HWI viene postato uno SWI1 , quindi appena termina l’esecuzione di HWI viene messo in esecuzione SWI1

ƒ durante l’esecuzione di SWI1 arriva un altro interrupt ed HWI torna in esecuzione

ƒ durante l’esecuzione di HWI viene postato uno SWI2 ; quando termina l’esecuzione di

HWI viene messo in esecuzione SWI2 , che ha priorità maggiore di SWI1

ƒ terminato SWI2 possiamo tornare ad eseguire SWI1

ƒ terminato SWI1 possiamo tornare ad eseguire TSK1

ƒ durante l’esecuzione di TSK1 arriva un interrupt ed entra nuovamente in esecuzione

HWI ; durante l’esecuzione di HWI viene postato il semaforo di TSK2

ƒ TSK2 viene messo in esecuzione quando HWI è terminato

ƒ TSK2 termina quando il suo semaforo va in pending

ƒ a questo punto possiamo riprendere l’esecuzione di TSK1 che termina con il suo semaforo in pending

ƒ alla fine viene messo in esecuzione IDL , il thread a più bassa priorità

l DSP/BIOS è quindi un sistema operativo minimale che gira sul DSP , il quale ad esempio si occupa di gestire funzioni di debug in real-time, permette di gestire la memoria, di impostare la priorità di ciascun thread , di definire gli HWI , i SWI e le funzioni periodiche, ovvero funzioni che devono essere necessariamente eseguite ogni intervallo di tempo prefissato.

La configurazione dei parametri del DSP/BIOS avviene completamente tramite il Code

Composer.

(21)

Figura 55: gestione del DSP/Bios tramite Code Composer

Il Framework

Sulla base di queste considerazioni passiamo a descrivere il framework di base dell’ MVE II , sul quale l’utente costruisce la sua applicazione; per come è stato progettato il sistema infatti, l’implementazione di un algoritmo sulla scheda coinvolge soltanto il livello più alto, quello del codice utente, svincolato dalla gestione dei flussi di ingresso/uscita del segnale video.

Abbiamo descritto al paragrafo 5.3 il flusso di acquisizione del segnale video, in particolare abbiamo detto che nell’ FPGA1 è presente una memoria FIFO che immagazzina le righe del frame e le trasferisce nella memoria interna del DSP tramite trasferimenti

DMA ; riprendiamo quindi questo discorso affrontando la questione dal punto di vista della gestione dei thread.

Fondamentalmente possiamo attribuire il flusso di acquisizione/elaborazione a due task :

video_elab e main_elab ; ricordiamo che l’esecuzione dei task è regolata dai semafori.

(22)

Quando un intero frame è stato acquisito, l’ FPGA1 lo comunica al DSP tramite un interrupt esterno: in seguito all’interrupt va in esecuzione la ISR che, tra le altre cose, si preoccupa di mettere in esecuzione video_elab , il quale dopo aver eseguito alcune operazioni necessarie alla gestione del flusso di dati in entrata va a postare a sua volta il semaforo del task main_elab . Lo scheduler del DSP/BIOS manda in esecuzione il task main_elab sospendendo video_elab .

Riportiamo lo pseudo-codice del task main_elab :

void main_elab()

SEM_pending(&sem_main_elab) A while(1)

CODICE UTENTE

SEM_pending(&sem_main_elab) B

Accade quindi che quando viene postato la prima volta il semaforo del main_elab da parte del video_elab , la situazione ferma al punto A si sblocca e si esegue quindi il codice utente sul frame appena acquisito.

Alla fine della elaborazione arriviamo al punto B in cui il semaforo viene messo in

pending , ovvero in rosso; a questo punto lo scheduler fa riprendere l’esecuzione al

video_elab , il quale si preoccupa di trasferire il frame elaborato nella SDRAM , nella quale verrà opportunamente convertito per essere inviato al B69000 , si occuperà della gestione dell’overlay e posterà lo SWI PCI_video_move .

La funzione PCI_video_move infine si occuperà del trasferimento del video_out dalla

SDRAM al B69000 tramite bus PCI .

Riportiamo lo pseudo-codice per il task video_elab :

void video_elab()

SEM_pending(&sem_video_elab) C while(1)

SEM_post(&sem_main_elab); D video_conv_move(##);

draw_overlay(##);

SWI_post(&PCI_video_move_swi);

SEM_pend(&SEM_videoelab); E

(23)

La ISR che viene messa in esecuzione in risposta all’interrupt di end_frame posterà il semaforo C la prima volta, dopodiché in video_elab si entra nel ciclo infinito nel quale si posta il semaforo del main_elab e si attende il termine dell’esecuzione del codice utente, fino al punto B, nel quale il main_elab va in pending e prosegue il video_elab fino al punto E.

Nel punto E il video_elab va in pending ed attende nuovamente un interrupt di

end_frame , per ripartire dal while(1) , postare il main_elab e così via.

Schematizziamo la gestione dei task da parte dello scheduler:

figura 56: gestione task di elaborazione video

GUI ed eventi

Sulla base di quanto detto, si capisce che l’ MVE II presenta allo sviluppatore un framework nel quale inserire le specifiche applicazioni in modo semplice: parlando in termini pratici di programmazione infatti tutto il codice utente deve essere inserito all’interno del ciclo while del task main_elab .

Parlando di sistemi multimediali si da per scontato il fatto che ci sia una certa interazione con l’utente che va ad utilizzarli: il dispositivo di uscita della scheda è un monitor VGA, e le periferiche di controllo in ingresso sono mouse e tastiera.

L’esecuzione delle applicazioni deve prevedere l’interazione da parte dell’utente finale tramite il mouse, ad esempio, e quindi c’è bisogno di un’interfaccia grafica (GUI) con finestre, pulsanti, display numerici, grafici etc.

Il sistema deve inoltre permettere l’esecuzione dell’algoritmo condizionato dagli eventi

generati da chi lo utilizza, in particolare la pressione dei pulsanti del mouse; da questo si

deduce la necessità di thread che gestiscano la gui e gli eventi: il nome dei thread è

proprio “gui” ed “events” .

(24)

Nello sviluppo delle applicazioni dobbiamo quindi occuparci del disegno della gui avendo a disposizione una libreria di oggetti grafici (pulsanti, linee, punti, box, stringhe di testo etc..).

Nel file gui.c possiamo disegnare l’interfaccia grafica dichiarando gli oggetti da inserire, le caratteristiche (colore, dimensioni) e la posizione; ad ogni oggetto è associata una struttura con un campo che lo identifica in maniera univoca così che possa gestire gli eventi associati ad esso nel file events.c .

La gestione degli eventi si riconduce sostanzialmente al controllo sulla posizione del mouse, sullo stato dei suoi pulsanti (premuto, rilasciato) e di quelli della interfaccia.

In questo modo possiamo gestire l’interazione dell’utente con il sistema.

Riportiamo infine un esempio di interfaccia grafica del sistema insieme ad alcune parti del codice scritto per disegnarla e per gestirne gli eventi.

figura 57: MVEII - esempio di interfaccia grafica

(25)

gui.c

[…] /******************************************************************************\

* layout: prepara la GUI

\******************************************************************************/

void layout()

{ draw_box(0,0,800,600,GRAYWIN); //mette lo sfondo grigio a tutto schermo

// --- TASTI ---

create_button(1,t_switch,plain_blu,400,175,32,32); // start/stop elab create_button(2,t_switch,plain_blu,400,221,32,32); // reset elaborazione create_button(3,t_switch,plain_blu,400,267,32,32); // selezione zona // --- LINEE ---

draw_line_hor(400,50,380,BLACK);

// --- STRINGHE ---

create_string(1,BLACK,400,10,"B-Flow 0.0 - rel. 15/12/2005");

create_string(6,BLUE,400,28,"Op. Baricentro");

create_string(3,BLUE,440,185,"START/STOP");

create_string(4,RED,440,231,"RESET");

create_string(5,YELLOW,440,277,"ZONE SELECTION");

// --- ZONE ATTIVE ---

create_zone(1,10,10,352,288); // sotto la playback window // --- PLAYBACK WINDOW ---

create_video_win (352, //Size_X,

288, //Size_Y,

RGB565, //Mode,

Corner_frame, //Pos_X, Corner_frame, //Pos_Y

bitblt);

draw_emboss(Corner_frame-1,Corner_frame-1,354,290);

} […]

events.c […]

/******************************************************************************\

* on_click_button: codice utente per oggetti button

\******************************************************************************/

void on_click_button(int nr_button) { // variabili locali

switch (nr_button)

{case 1:

if(check_status_button(1) == down) // inizio/fine elab start_elab = 1;

else

start_elab = 0;

break;

case 2:

if(check_status_button(2) == down) // reset {

reset = 1;

change_status_button(2);

}

(26)

else

reset = 0;

break;

case 3:

if(check_status_button(3) == down) // enable selezione zona

select_zone = 1;

else

select_zone = 0;

break;

} }

[…]

Riferimenti

Documenti correlati

PutRegistrazioneCronoScarico si crea una nuova registrazione cronologica nel.. sistema SIS con i dati specificati. La registrazione è associata ad un Registro Cronologico

Il sistema deve essere in grado di rispondere agli eventi esterni (sistema reattivo) entro un certo tempo limite (sistema real-time). Esempio in un sistema di controllo con periodo

– If one process tries to access a memory location outside its space, a processor exception is raised (trap) and the.. process

 one blocked thread must be removed from state RUNNING and be moved in the semaphore blocking queue.

 a closed chain of threads exists such that each thread holds at least one resources needed by the next thread in the chain.  then a deadlock

Browser Shell Videogame Printer.

– If number of processors = 1 -> threads execute in time- sharing. – If number of processors < number of

– The handler saves the registers that will be modified on the stack. – Executes the interrupt