DICo – Dipartimento di Informatica e Comunicazione Università degli Studi di Milano DSP Application Day 2006 Milano - September 18, 2006 Impiego di sistemi operativi e kernel real-time sui DSP di nuova generazione Umberto Zanghieri - ZP Engineering srl Abstract: I nuovi prodotti richiedono integrazioni sempre più spinte. Una tendenza recente nel moderno sviluppo di applicazioni su DSP prevede l'impiego di un sistema operativo sullo stesso processore, per applicazioni con funzioni di controllo sofisticate, oppure l'utilizzo di un kernel real-time per gestire più task. Vengono illustrate alcune delle problematiche da affrontare nello sviluppo su DSP con sistema operativo uClinux, e una comparazione di vantaggi e svantaggi dell'utilizzo di kernel real-time su processori ad alte prestazioni. 1. Premessa Nel passato, i DSP sono stati impiegati in numerosi sistemi, tra cui schede audio, modem, dispositivi di telecomunicazione, apparati medicali, tutte basate su applicazioni di puro processing di segnale. I sistemi DSP erano in genere progettati specificatamente per le applicazioni previste, e disponevano solo delle funzionalità necessarie per rispettare i constraints di costo e prestazioni. Le funzionalità tipiche di un sistema operativo (comunicazione, gestione di memorie di massa, grafica, etc...) erano generalmente fornite da un processore che gestiva uno o più DSP. Con la rapida adozione di nuove architetture con funzionalità multimediali e di comunicazione, c’è ora mercato per un nuovo tipo di DSP. In precedenza, l’architettura più comune era un processore general-purpose che controllava un DSP con funzioni di coprocessore. Tale scelta progettuale non è ottimale dal punto di vista del costo, manutenibilità, potenza assorbita e dimensioni; in compenso, le varie funzioni possono in alcuni casi essere sviluppate indipendentemente. 2. Impiego di Linux su dispositivi embedded Anche se originariamente Linux non è nato per dispositivi embedded, è oggi disponibile su una notevole varietà di prodotti embedded. A partire dal rilascio del kernel in versione 2.0.x, e la comparsa di servizi di supporto per Linux su processori embedded (ARM7, ARM9, Freescale, MIPS, PowerPC, XScale), c’è stata una vera e propria esplosione di prodotti commerciali basati su Embedded Linux; nella maggior parte dei casi, la presenza di Linux a bordo di un dispositivo è non evidente agli occhi degli utenti di tali apparati. Ad oggi, la maggioranza dei router a banda larga, dei firewalls, dei punti di accesso e persino di alcuni lettori DVD impiegano Linux. Linux è nato agli inizi degli anni 90 ad opera di uno studente finlandese, Linus Torvalds; si è basato sulla disponibilità del compilatore C GNU sviluppato dalla Free Software Foundation, a partire dal 1984. Le versioni più rilevanti sono le seguenti: Linux 1.0 Linux 2.0 uClinux Linux 2.4 Linux 2.6 1994 1996 1998 2001 2004 2 Linux è nato originariamente per processori x86, e prevede l’impiego di una MMU (memory management unit). A partire dal 1998 si iniziò a sviluppare una variante per proecssori privi di MMU e come tali più simili ai classici microcontrollori, da cui il nome uClinux. Ad oggi, uClinux ha avuto una enorme diffusione in ambito embedded, nonstante sia nato come versione autonoma e con un abase di sviluppatori meno ampia del kernel Linux. Linux e uClinux offrono una notevole varietà di driver per ogni sorta di protocollo e hardware. Considerando inoltre, che questi sistemi operativi non richiedono royalties runtime, la loro diffusione in ambito embedded risulta più che giustificata. 3. Perchè un sistema operativo open source su DSP? Le richieste di funzionalità sempre più sofisticate, soprattuto dal punto di vista dei protocolli di comunicazione, e l’esigenza di minimizzare i costi in produzione hanno favorito l’adozione di Linux e uClinux sulle piattaforme più disparate. Nei casi in cui sia necessario disporre della potenza di un core DSP, la tendenza più recente è quella di progettare un processore con funzionalità miste RISC e DSP, in modo da favorire l’adattamento di un kernel di sistema operativo originariamente previsto per microcontrollori e processori tradizionali. La Analog Devices ha progettato in collaborazione con la Intel una nuova architettura [1] detta MSA (Micro Signal Architecture) che offre numerose istruzioni tipiche di un processore generalpurpose, rendendo possibile l’adattamento di un sistema operativo come uClinux. Nella architettura esiste una MMU ma è di tipo non compatibile con le necessità del kernel Linux, per cui è stato effettuato il port del kernel uClinux (inizialmente 2.4, ora 2.6). La famiglia Blackfin è uno dei processori basati sulla architettura MSA disponibili come prodotti off-the-shelf. Come ulteriore prova della natura ibrida dell’architettura MSA, alle varianti general-purpose di Blackfin (BF-531, 532 e 533 che si differenziamo per la quantità di memoria interna) sono state affiancate varianti con un Ethernet controller integrato, ed una interfaccia CAN. E’ evidente l’intento dei fabbricanti di semiconduttori di favorire la convergenza su un unico processore di funzionalità di controllo e comunicazione con le esigenze di processing. 3 L’adozione di un sistema operativo open-source su DSP è un trend in significativa evoluzione che compete in alcuni casi con processori ormai storici (Coldfire, SH). Linux/uClinux su processori embedded: trends di impiego Source: Embedded Linux Market Survey 2006, Linuxdevices Gli aspetti più salienti nella architettura Blackfin che rendono fattibile e utilizzabile un port uClinux sono i seguenti: Presenza di blocchi di SRAM interna impostabile come cache istruzioni e cache dati; in questo modo, non si è legati al collo di bottiglia dell’accesso a memoria esterna (generlamente 4-5 volte più lento dell ammeoria interna) set di istruzioni RISC-like supporto SDRAM, indispensabile per consentire l’impiego dei 16Mbytes minimi richiesti da un sistema operativo come uClinux disponibilità di numerosi canali DMA che consentono di rilassare le specifiche di risposta agli interrupts mediante buffering 4. Differenze tra Linux e uClinux Linux è derivato essenzialmente da UNIX, e consiste in un sistema operativo multi-utente e multitasking, in cui il kernel deve prendere particoalri precauzioni per assicurare il corretto e sicuro funzionamento di numerosi processi, fino a qualche migliaio sullo stesso sistema. Il modello UNUX protegge ogni processo in uno spazio di memoria dedicato. Inoltre, un sistema di memoria virtuale deve offrire meccanismi di allocazione dinamica della memoria e il mapping di regioni arbitrarie di memoria all’interno delle zone di memoria private dei singoli processi. Alcuni processori, come il Blackfin, non offrono una MMU completa, in quanto gli sviluppatori che intendono sviluppare le loro applicazioni senza utilizzare un sistema operativo generalmente non hanno bisogno di una MMU; inoltre, l’assenza di una MMU completa consente ulteriori ottimizzazioni di costo e consumo di potenza. Su questi presupporti, alcuni compromessi sono stati definiti nello sviluppo di uClinux, tra cui: assenza di un vero sistema di memoria protetta assenza della chiamata di sistema fork() disponibilità solo di semplici sistemi di allocazione della memoria Per quanto riguarda la protezione della memoria, uClinux non fa impiego di memoria virtuale. I processi uClinux non possono aumentare la memoria disponibile a run-time; ogni processo può accedere qualunque parte della memoria, e quindi potenzialmente causare un crash di altri 4 processi o dello stesso sistema operativo. Non è previsto l’impiego di memoria di swap (anche se generalmente i sistemi con uClinux non dispongono di un hard disk). Il secondo punto è più problematico; in Linux, la chiamata fork() crea una copia esatta del processo di partenza e lo esegue simultaneamente, facendo esplicito impiego della MMU; uClinux offre una versione modificata di fork() detta vfork(), in cui il processo originante è bloccato durante l’esecuzione del processo derivato. Quindi, il software che utilizza fork() deve essere riscritto per fare impiego di vfork(). Vengono supportati i threads in quanto fanno impiego dello stesso spazio di memoria. Inoltre, uClinux supporta su alcune piattaforme XIP (execution-inplace), consentendo l’esecuzione direttamente da ROM. La gran parte delle applicazioni disponibili per Linux possono essere facilmente ricompilate per uClinux senza variazioni o con poche modifiche. distribuzioni Linux per applicazioni in dispositivi embedded: trends di impiego Source: Embedded Linux Market Survey 2006, Linuxdevices Un altro aspetto non trascurabile è legato al tempo di context switch nei due sistemi operativi, soprattutto a causa della differente gestione di memoria dei processi. In un articolo del gruppo Samsung, è stato analizzato il comprtamento di Linux e uClinux sullo stesso processore (un ARM9). Il tempo per commutare processo è risultato nel caso di uClinux circa 5 volte inferiore rispetto a Linux. Source: Samsung Tech Conference 5 5. Sviluppo su uClinux Lo sviluppo su sistema operativo uClinux è piuttosto differente dallìapproccio tradizionale dello sviluppatore DSP, basato di solito su un ambiente grafico integrato che consente di editare i sorgenti, di creare progetti, di effettuare compilazione, linking e debug real-time senza cambiare applciazione su host. Nel caso di uClinux e Linux, la piattaforma preferenziale di sviluppo è un desktop Linux. Prendendo come esempio il port di uClinux per Blackfin, l’ambiente di sviluppo consiste in: GNU Compiler Collection (GCC cross compiler) Binutils (likner, assembler, etc…) per Blackfin In aggiunta, sono necessari ulteriori tools GNU come awk, sed, make, bash e Tcl/Tk, che generalmente fanno parte delle tipiche distribuzioni Linux per desktop. Le attività di sviluppo si possono suddividere nelle seguenti fasi: adattamento del kernel e del BSP caricamento iniziale sul target sviluppo della applicazione Gran parte delle attività iniziali consistono nel selezionare le opzioni di interesse per compilare il kernel e il relativo BSP (board support package), e nel rimuovere tutte le funzionalità che nonsono necessarie in modo da risparmiare spazio di memoria FLASH. Configurazione grafica del kernel La distribuzione uClinux offre un’ampia selezione di utilities e programmi sviluppati tenendo conto delle problematiche primarie di dimensioni del codice e di efficienza (apsetti non sempre prioritari su piattaforme host). Ad esempio, Busybox è un programma che può essere invocati con diversi nomi e racchiude le funzionalità di numerosi applicativi a console tipici di una distribuzione Linux; esso consente di ridurre significativamente le dimensioni dell’immagine binaria del kernel senza rinunciare a numerose utilities. Il target deve essere inzialmente caricato con il kernel, tipicamente con i tools standard del DSP (VisualDSP++ nel caso del Blackfin). Il passo successivo è l’ulitizzo di un bootloader (un applicativo più semplice che consente di aggiornare il firmware a board via seriale o LAN), rendendo così non indispensabile la presenza di un emulatore JTAG. Una volta che il kernel è caricato ed avviato, si può effettuare il debug mediante il classico GNU debugger GDB, che impiega i canali di comunicazione standard (seriale o LAN). 6 In questo modo, si opera in maniera molto simile allo sviluppo su host, perdendo la visibilità tipica di un simulatore o di emulatore JTAG L’impiego di un breakpoint a basso livello risulta quasi inutilizzabile nei contesti pratici, perchè blocca anche l’esecuzione del sistema operativo e quindi dei vari processi di comunicazione. L’ultimo passo è relativo òllo sviluppo della applicazione specifica del dispositivo; spesso si fa impiego di shell scripts o linguaggi interpretati come Perl o Phyton per dimnuire i tempi di sviluppo. Dove è necessario lo sviluppo in C, la presenza dimoltissimi protocolli, servizi e device drivers consente di focalizzarsi solo sulle porzioni specifiche del progetto. 6. Esempio di design basato su uClinux Per dare una veste più concreta a quanto detto sull’impiego di uClinux su piattaforma DSP, si analizza un prodotto commerciale di successo progettato dalla Roku Labs. Il Roku Soundbridge è un media player basato su singolo processore Blackfin, sul quale gira il sistema operativo uClinux più una collezione di algoritmi sviluppati internamente alla Roku Labs per le operazioni di decodifica e connessione ai vari tipi di server. Formati audio supportati: MP3 WMA AAC WAV, AIFF (lineare) Protocolli supportati: Roku Control Protocol Bonjour™* and iTunes DAAP UPnP AV Windows Media DRM 10 WEP, AutoIP DHCP,TCP,TELNET, HTTP Un singolo processore svolge le seguenti funzioni: funzioni da controllore o protocollo TCP/IP o protocolli di autenticazione e connettività o digital rights management o gestione di una interfaccia WiFi (su slot CompactFlash) o gestione grafica su display Gestione di una interfaccia Ethernet Funzioni da DSP o Compressed stream decoder o Gestione I/O digitale (su alcuni modelli) o Gestione uscite analogiche In questo modo, è possibile minimizzare il BOM (bill of materials) a livelli non raggiungibili con la tradizionale architettura RISC+DSP. Il sistema si basa su un BF531, la variante più economica della serie Blackfin. Non è noto quale versione o variante di uClinux venga utilizzata. 7 Real-time kernels Ci sono casi in cui l’impiego di un sistema operativo come uClinux non è la scelta più indicata, soprattutto quando: sono necessarie prestazioni hard-real-time che uClinux non può garantire ci sono constraints significativi di memoria esterna (FLASH, SDRAM e/o SRAM) l’applicazione non richiede particolari protocolli di comunicazione Le problematiche classiche di sviluppo embedded sono oggi sempre più frequentemente affrontate con l’impiego di kernel operativi real-time (detti anche RTOS, real-time operating system); si tratta di sistemi di dimensioni molto contenute e prestazioni elevate. Fino a qualche anno fa, l’utilizzo di RTOS in contesti embedded non era molto diffuso, soprattutto a causa dell’overhead di processing che risultava significativo sui normali processori, che avevano frequenze operative dai 20 ai 60 MHz. La situazione è notevolmente cambiata con la disponibillità di processori di potenza più elevata, in cui l’overhead dovuto al RTOS viene motlo contenuto, ed alla necessità di reagire con rapidità a variazioni di hardware e specifiche. Come esempio viene illustrata la disponibilitò di sistemi operativi per la piattaforma Blackfin: OS/Kernel Nucleus PLUS VDK kernel INTEGRITY & velocity RTOS RTXC RTOS Fusion RTOS uClinux Vendor Accelerated Technology Analog Devices Green Hills Software Quadros Systems Unicoi Systems Open source community Prendendo in esame il VDK (VisualDSP Kernel), un real-time kernel che fa parte dell’ambiente di sviluppo della Analog Devices, si possono notare i seguenti aspetti interssanti: supporto per numerose varianti di processori anche su famiglie diffeenti (floating-point e TigerSHARC), vedi tabella integrazione delle funzionalità di instrumentazione all’interno dell’ambiente di debug gestione multi-thread, con varie politiche di gestione dei threads impiego dei device drivers per astrarre dalle risorse hardware specifiche della variante utilizzata Processori SHARC Processori BLACKFIN Processori TigerSHARC ADSP-21060/21061/21062/21065L ADSP-BF531/2/3 ADSP-TS101 ADSP-21160/21161 ADSP-BF534/6/7/8/9 ADSP-TS201/2/3 ADSP-21261/2/6/7 ADSP-BF535 ADSP-21363/4/5/6/7/8/9 ADSP-BF561, AD6532, ADSP-BF566 Processori supportati dal VDK Gli obbiettivi che si prefigge il VDK sono i seguenti: evitare di sviluppare codice troppo specifico per il processore impiegato, in modo da favorire la riutilizzabilità del lavoro e l’adattamento a processori più moderni consentire l’integrazione di porzioni di codice scritte da persone o gruppi di lavoro diversi Alcune delle caratteristiche più interessanti del VDK sono: disponibilità di tre differenti versioni delle librerie VDK: semplici, con error checking, con intrumentation. Nella versione instrumented, il kernel mantiene informazioni di tipo 8 statistico e un log di tutti gli eventi significativi in un history buffer. Questo buffer può essere analizzato ad esecuzione bloccata, e rappresenta un tool molto potente per il debug (specie post-mortem) le funzionalità vanno sviluppate sotto forma di threads, un set di funzioni che implementano la funzione richiesta; il thread viene eseguito in modo ciclico o solo se invocato. Ogni thread dispone di un proprio stack, di uno sttao, una priorità ed altre variabii locali. Ogni thread richiede la creazione di 5 funzioni: Run, Error, Init, Create, Destruct ; le prime due sono obbligatorie, le altre sono opzionali e tipicamente fanno riferimento all’impiego di buffers di memoria da allocare e liberare Lo scheduler è un processo fondamentale del VDK, che gestisce i vari thread in base alle priorità ed alle metodologie di scheduling impostate Sono disponibili fino a 30 livelli di priorità, ed ogni thread può modificare dinamicamente la propria priorità La gestione dei thread e delle priorità è gestita dai segnali: semafori, eventi, device flags o messaggi È possibile disabilitare lo scheduler per porzioni di codice critiche, e se necessario anche gli interrupts Se si opera in modo instrumented, è possibile trarre vantaggio di analisi post-mortem del carico (effettuato misurando essenzialmente il tempo in cui è attivato il thread IDLE) e del passaggiodi stato tra threads. Il VDK opera sempre come un kernel preemptive, in cui lo scheduling può essere impostato sui vari threads in tre differenti modalità: cooperative round-robin preemptive Lo scheduling cooperative è la modalità più semplice, in cui ogni thread opera allo stesso livello di priorità e viene eseguito fino a quando non restituisce manualmente il controllo allo scheduler stesso. Lo scheduling in round-robin opera in time slicing, in cui i threads allo stesso livello di priorità vegono abilitati per un periodo prefissato di tempo. Non ci sono garanzie sul tempo esatto di esecuzione, per cui è inevitabilmente presente un jitter nel tempo di attivazione di un thread. Lo scheduling preemptive prevede che un thread a priorità maggiore di quello in esecuzione venga eseguito senza attendere altri eventi o segnali. Tipicamente, i processi non ciritici dal punto di vista del real-time possonon essere impostati in round-robin alla stessa priorità, mentre quelli time-critical vengono gestiti a priorità più alta. 9 References [1] R. K. Kolagotla, J. Fridman, M. M. Hoffman, W. C. Anderson, B. C. Aldrich, D. B. Witt, M. S. Allen, R. R. Dunton,, L. A. Booth Jr. “A 333-MHz dual-MAC DSP Architecture for NextGeneration Wireless Applications”, ICASSP 2001 [2] M. Durrant, J. Dionne and M. Leslie “Running Linux on a DSP? Exploiting the Computational Resources of a programmable DSP Micro-Processor with uClinux”, Ottawa Linux Sumposium, June 2002 [3] “World's first native-DSP Linux port?”, Linuxdevices, Nov. 05, 2003 [4] “Another native-DSP Linux port -- this one to ADI's Blackfin”, Linuxdevices, Nov. 06, 2003 [5] E. Drory, Or Sagi, “Symmetrical Hosting -- the MediaLinux Approach”, Linuxdevices, Nov. 11, 2003 [6] M. Hennerich, “uClinux as an Embedded OS on a DSP”, Linux Journal, July 2004 [7] HS Choi, HC Yun, “Context Switching and IPC Performance Comparison between uClinux and Linux on the ARM9 based Processor”, Technical report, Samsung Electronics, 2005 [8] VisualDSP++ 4.0 – Kernel (VDK) User’s Guide, Analog Devices, 2005 [9] Device Drivers and System Services Manual for Blackfin® Processors, Analog Devices, 2005