Tics un sistema operativo real-time

Dalla sua introduzione nel mercato embedded, dal giugno 1992, Tics è utilizzato in diverse applicazioni: dalla telefonia cellulare all’automazione industriale. Uno dei suoi pregi è quello di occupare poco spazio di memoria ed è distribuito in accordo alla licenza GNU, General Public License. I processi concorrenti in Tics sono le funzioni C che diventano dei veri task mediante l’uso delle primitive RTOS disponibili all’utilizzatore.

I task sotto Tics comunicano tra loro attraverso i costrutti messages e mail: i task possono sospendersi per aspettare un messaggio, cancellare i messaggi ricevuti o controllarne periodicamente l’arrivo. Inoltre, i task invocano servizi quali pause e impiegare primitive basati su eventi temporali, timer, messi a disposizione dal kernel. I task, poi, possono utilizzare ciascuno uno stack proprietario o, anche, impiegarne uno comune. Le funzioni C che, grazie alle interfacce disponibili, diventano dei veri task devono avere una struttura come mostrata nel listato 1: non hanno argomenti e non restituiscono nessun valore.

void task(void)
{
/* Perform one time operations here. */
while (TRUE) {
      /* Main code for task here. */
      }
}
Listato 1

Tipicamente  un  task  è  una  funzione  C  dove corpo della funzione stessa è in sostanza costituito da un’iterazione infinita. La funzione C, prima del ciclo infinito, può svolgere alcune inizializzazioni per adempiere al suo compito. Con Tics viene anche distribuito il suo codice sorgente, in C, e una discreta quantità di esempi per illustrare meglio il suo impiego. Il codice, poi, è ben documentato e non presenta grosse difficoltà per la sua comprensione. Tics  è scritto,  per  la maggior parte,  in  ANSI C  e questo  lo  rende molto portabile su qualsiasi microprocessore. Inoltre, il kernel è stato realizzato per essere utilizzato in ambiente MS-DOS tanto che sono fornite delle primitive appositamente realizzate. L’occupazione di memoria richiesta da Tics è di circa 8k bytes ed è pienamente ROMable. Tics è impiegato su varie piattaforme, per esempio  su  68040,  68360,  68332,  6809,  80186, 80188, 68030, TI320c50, TI320c30 e piattaforme basate su x86. Il compilatore utilizzato per sviluppare il kernel è il famoso Borland, ma il kernel risulta pienamente portabile verso Microsoft C e/o altri compilatori commerciali o open. Vediamo un piccolo esempio: la creazione e l’attivazione di un task. In ambiente Tics occorrono due passaggi:

  1. Uso di makeTask. Con questa API si crea un TCB (Task Control Block) per il task taskName (il nome della funzione C) con un identificatore univoco che consente di individuare il task senza ambiguità, così:
    typeTcb * tcb;
    tcb = makeTask(taskName, taskNum);
  2. startTask. Questa chiamata API aggiunge il task nella coda ready, in base alla sua priorità, e predispone 1 Kbyte di stack se si vuole sottoporre il task alla politica di schedulazione di tipo cooperative. Così:
    typeTcb * tcb;
    tcb = makeTask(taskName, taskNum);
    startTask(tcb);

Quando è creato un task, allora è definita una struttura dati che, per default, assume i seguenti valori:

La priorità è uguale a DEF_PRI (definito in Tics header file).
Il Time-slicing è disabilitato
Sono definite tre mailboxes
È definita una coda dei messaggi
Il bit associato alla politica di schedulazione,
cooperative, è azzerato

Un TCB minimale è definito in questo modo:

typedef struct {
int taskNum,  /* The task number is used
to identify the task */
int  pri; /* the priority is used to determine
when the task should run */
} typeTcb;

Tabella 1. Tics Realtime System Calls: User Level Kernel Interface

Tabella 1. Tics Realtime System Calls: User Level Kernel Interface

 

Tabella 2. Tics Realtime System Calls: Extended Kernel Interface

Tabella 2. Tics Realtime System Calls: Extended Kernel Interface

Tabella 3. Tics Realtime System Calls: Serial Communication Interface

Tabella 3. Tics Realtime System Calls: Serial Communication Interface

Tabella 4. Tics Realtime System Calls: Seri System Level Kernel Interface

Tabella 4. Tics Realtime System Calls: Seri System Level Kernel Interface

LA  DISTRIBUZIONE

La distribuzione basata su Tics include due kernel real-time: uno è di tipo  preemptive (Tics) e l’altro è un kernel più compatto basato su roundrobin (Tiny Tics). Il codice sorgente è fornito per tutte e due le versioni. Tics si compone di una libreria C che permette all’utilizzatore di creare e attivare multipli threads (task). Tipicamente, i task utente sono inizializzati e posti in esecuzione nella funzione principale C, utilizzando a questo proposito la funzione startTask. Quando i task sono stati inizializzati e posti  in  esecuzione,  la  funzione  principale,  il main, viene sospesa in questo modo i task utente sono posti in esecuzione come thread indipendenti secondo quanto stabilito dalla loro priorità. Oltre a  gestire la shedulazione dei task, Tics implementa anche un timer management system, un memory management, una RS-232 communications library, e una libreria di inter-task communication. Di seguito sono evidenziate sommariamente alcune loro caratteristiche:

 Tasking Modes

Tics fornisce all’utilizzatore tre metodi per il multi-tasking:  priority  based  preemptive  scheduling, time-sliced scheduling e cooperative scheduling. Queste politiche di multi-tasking possono essere anche combinate  tra  loro:  alcuni  task  possono essere time-slicing, altri preemption e alcuni cooperation nella stessa applicazione. Questo consente un’estrema flessibilità. Nella politica di tipo cooperative i tasks possono anche condividere uno stack comune. La politica di schedulazione di un task deve essere decisa in fase d’istanziazione. Non esiste una quantità massima di task presenti nel sistema, il loro numero dipende unicamente dalla quantità di memoria disponibile: infatti, ad ogni task corrisponde una porzione di stack, la quantità di stack è poi variabile task per task. Nel context switch è possibile abilitare il cosiddetto dynamic stack checking, questo controlla l’integrità dello stack ad ogni context switch.

Serial Communications

Tics include una libreria per la gestione della linea seriale, la serial communication library. Quando si accede alla linea seriale si utilizzano chiamate sospensive: un task quando aspetta un carattere dal terminale è posto in uno stato di waits. La COM library di Tics si poggia direttamente sul componente seriale, UART. In questo modo né il BIOS e né il sistema MS-DOS sono utilizzati. È possibile aggiungere diverse porte seriali, COM ports, nel sistema: infatti, il codice è completamente table driver senza limitazioni al numero delle porte presenti nel sistema.

Messages

I task possono comunicare tra loro attraverso le message queue: la comunicazione avviene mediante l’uso dei messaggi tra task. Ogni messaggio che viene spedito viene messo nella code di destinazione. Questa modalità di scambio di messaggio è utilizzata come inter-task communication, l’altra possibilità è quella di utilizzare le mailboxes. I messaggi possono anche essere spediti da una ISR verso qualsiasi task del sistema. Inoltre, anche per i messaggi, è previsto l’uso della priorità per definire casistiche di messaggi più urgenti rispetto agli altri.

Memory Management

Il memory management consente di gestire l’allocazione o la deallocazione di buffer di memoria. Possono essere creati un numero variabile di buffer (memory pool): la quantità di memoria allocata per memory pool è determinate dall’utente in fase di inizializzazione. In questo sistema i block size sono fissi e determinati sempre dall’utente mediante l’uso delle interfacce API.

Mail

Questo è un metodo alternativo per la comunicazione tra task. Questa modalità non richiede una coda, i dati nuovi sono sovrascritti ai vecchi. Questo sistema ha il pregio di essere molto più veloce rispetto ai messages.

Timer Management

In questo kernel esistono tre tipi di timers: pause, one-shot  e  periodico.  La  modalità  identificata come pause sospende il task per un determinato numero di millisecondi. La modalità di tipo one-shot permette al task di continuare  l’esecuzione  fino  a  quando  il  timer associato termina il conteggio e a questo punto il task invia un messaggio di TIMEOUT. La modalità periodico spedisce al task un TIMEOUT su base periodica. Non esistono limiti sui numeri di timers pendenti. A questi timer, timer messages, può essere assegnata una priorità.

Multi-tasking & MS-DOS

Tics è un prodotto che oltre a poter essere eseguito in modalità stand-alone è anche utilizzabile con il sistema operativo MS-DOS su PC. In questo caso il timer del PC è riprogrammato con la granularità richiesta. Tics è pienamente preemptive e fornisce i meccanismi di protezione per evitare le caratteristiche di rientranza previste da MS-DOS e BIOS. Per le attività di debugging può essere utilizzato i vari debugger disponibili in ambiente Borland, come Turbo Debugger, o Microsoft.

Sezioni critiche

Anche in Tics è possibile gestire le regioni critiche, critical region managenent. Questa funzionalità è garantita grazie ai semafori.

UN  PICCOLO ESEMPIO

Tics dispone di diverse interfacce, le tabelle allegate all’articolo mostrano le chiamate API disponibili per le varie applicazioni. Il listato 2 evidenzia un piccolo esempio sull’uso della chiamata yield.

void ioTask(void)
{
  while (TRUE) {
    readIOData();
    yield();
  }
}
void keyboardTask(void)
{
  while (TRUE) {
    if (kbhit()) {processKey();}
    yield();
  }
}
Listato 2

Questa interfaccia rilascia volontariamente il controllo ad un altro task: questa chiamata è tipicamente utilizzata per condividere il tempo di CPU tra due o più task con la stessa priorità. Il listato 3 mostra un altro esempio che vede coinvolti due task.

void taskA(void)
{
   while (TRUE) {
         printf(“Hello from taskA... “);
         yield();
    }
}
void taskB(void)
{
    while (TRUE) {
           printf(“Hello from taskB... “);
           yield();
    }
}

void main()
{
     startTics(makeTics(MsgSpace,
               NUM_MSGS));

     startTask(makeTask(taskA, 0));

     startTask(makeTask(taskB, 0));

     suspend();
}
Listato 3

CONCLUSIONE

Nel panorama dei kernel real-time questo sistema certamente  è abbastanza interessante. È riccamente illustrato e commentato cosa che consente la sua portabilità verso sistemi diversi. In ogni caso può  essere  un  valido  strumento  didattico  per conoscere come realizzare e funziona un kernel real-time.

 

 

Scarica subito una copia gratis

Scrivi un commento

Seguici anche sul tuo Social Network preferito!

Send this to a friend