RTOS per sistemi integrati


57

Ho visto molti articoli che mi dicono che dovrei usare RTOS per la gestione del tempo e delle risorse. Il mio tempo non ha permesso la mia ricerca, quindi vengo da chiphacker per un consiglio.

Uso microcontrollori a bassa risorsa (MSP430, PIC) e stavo cercando RTOS che posso usare.

Al punto:

  1. Costo delle risorse del sistema
  2. Vantaggi del sistema
  3. Svantaggi del sistema
  4. Trucchi di implementazione
  5. Situazioni in cui il RTOS non dovrebbe / non dovrebbe essere utilizzato.

Non uso sistemi come Arduino, i progetti con cui lavoro non possono sostenere i costi di un tale sistema.


2
Sono confuso su ciò che ha ricevuto un voto negativo. Se l'elettore può darmi un feedback, proverò a evitare tale azione in futuro.
Kortuk,

1
idem. È un'ottima domanda ....
Jason S,

Ho accettato una domanda perché, anche se questo è aperto, avevo una serie di ottime risposte e volevo premiare almeno uno scrittore per lo sforzo.
Kortuk,

Risposte:


29

Non ho avuto molta esperienza personale con RTOS diverso da QNX (il che è fantastico nel complesso ma non è economico e ho avuto un'esperienza davvero negativa con un particolare fornitore di schede e l'atteggiamento di QNX che non ci interessa per i sistemi altri rispetto al loro più comune) che è troppo grande per PIC e MSP430.

Dove trarrete beneficio da un RTOS è in settori come

  • gestione / programmazione thread
  • comunicazioni inter-thread + sincronizzazione
  • I / O su sistemi con stdin / stdout / stderr o porte seriali o supporto ethernet o un filesystem (non un MSP430 o PIC per la maggior parte, ad eccezione delle porte seriali)

Per le periferiche di un PIC o MSP430: per le porte seriali userei un buffer ad anello + interrupt ... qualcosa che scrivo una volta per sistema e che riuserei e basta; altre periferiche Non credo che troverai molto supporto da un RTOS, in quanto sono così specifici del fornitore.

Se hai bisogno di un tempismo solido al microsecondo, probabilmente un RTOS non ti aiuterà: gli RTOS hanno tempi limitati, ma in genere hanno jitter di tempismo nella loro programmazione a causa di ritardi nel cambio di contesto ... QNX in esecuzione su un PXA270 aveva jitter nelle decine di microsecondi tipici, massimo 100-200us, quindi non lo userei per cose che devono funzionare più velocemente di circa 100Hz o che richiedono tempi molto più precisi di circa 500us. Per quel tipo di cose probabilmente dovrai implementare la tua gestione degli interrupt. Alcuni RTOS giocheranno bene con quello, e altri lo renderanno un dolore reale: il tuo tempismo e il loro tempismo potrebbero non essere in grado di coesistere bene.

Se i tempi / la pianificazione non sono troppo complessi, è possibile che si stia meglio utilizzando una macchina a stati ben progettata. Consiglio vivamente di leggere gli Statechart pratici in C / C ++ se non l'hai già fatto. Abbiamo usato questo approccio in alcuni dei nostri progetti in cui lavoro, e ha alcuni vantaggi reali rispetto alle tradizionali macchine a stati per la gestione della complessità ... che è davvero l'unica ragione per cui hai bisogno di un RTOS.


Lavoro in una startup dove i ragazzi dei sistemi embedded più esperti sono appena usciti dal college (cioè io e l'altro che ha lavorato con me per circa 2 anni). Trascorro molto tempo a insegnarmi sulle pratiche del settore durante la settimana lavorativa. Mentre stavo leggendo sono stato informato per tutti, ma il nostro sistema a basso costo un RTOS sarebbe un grande miglioramento.
Kortuk,

Sembra che ci sia un sistema RTOS a risorse molto basse per cose come PIC e MSP430 che può aiutare a creare un sistema deterministico da uno molto complicato, ripulendo notevolmente la nostra gestione di mantenere separati i moduli. Ho fatto parte di un team di due uomini che ha effettivamente costruito un sistema di raccolta e routing dei dati sul campo. Ora che guardo RTOS, vedo che è perfetto per quello che abbiamo progettato.
Kortuk,

Ci scusiamo per l'utilizzo di tre post slot, la tua risposta è molto utile, sto cercando una soluzione di risorse molto bassa, ma questa informazione è preziosa da avere, grazie per l'aiuto.
Kortuk,

non preoccuparti del conteggio dei commenti (IMHO una cosa che manca al framework StackExchange è il supporto per le discussioni ... il formato Q / A copre la maggior parte delle cose ma non alcune) ... sembra che tu abbia una buona padronanza su ciò che stai cercando. Non ho esaminato FreeRTOS che Steve ha menzionato, ma se è stato portato su microcontrollori di fascia bassa, forse farà la gestione della pianificazione di cui hai bisogno.
Jason S,

Sembra salvare lo stato di ogni thread attraverso lo stack (qualcosa come 50 istruzioni push / pull) e può gestire interruzioni temporizzate. Il mio sistema normalmente usa un interrupt di porta per il cambio di thread, ma l'attività sembra fattibile. Vorrei che questo tipo di sito gestisse la discussione in un formato migliore.
Kortuk,

26

Hai provato FreeRTOS ? È gratuito (soggetto a T&C) ed è stato portato sia su MSP430, sia su diverse versioni di PIC.

È piccolo rispetto ad alcuni altri, ma questo rende anche facile da imparare, soprattutto se non hai mai usato un RTOS prima.

È disponibile una licenza commerciale (non gratuita) e una versione IEC 61508 / SIL 3.


Grazie mille, la esaminerò entro una settimana, lascerò la domanda aperta per altre risposte, ma tu sei di grande aiuto!
Kortuk,

12

Ho appena scoperto NOSX RTOS, che può persino funzionare su un sistema 8052 (8 bit). Non ha molte porte, ma sembra interessante. POSIX può essere un vantaggio, perché potrebbe rendere un po 'più portatile un po' del tuo codice se passi a un processore più robusto e vuoi eseguire Linux o QNX in tempo reale.

Non ho alcuna esperienza con RTOS commerciali da me, ma ho usato quelli fatti in casa per anni! Sono fantastici nell'aiutarti a dividere lo sviluppo del tuo codice tra molti programmatori, perché possono essenzialmente ottenere un "task" o un "thread" per lavorare da parte loro. Devi ancora coordinarti e qualcuno deve supervisionare l'intero progetto per assicurarsi che ogni attività possa rispettare la scadenza.

Ti consiglio anche di effettuare ricerche sull'analisi monotonica della frequenza o RMA quando si utilizza un RTOS. Questo ti aiuterà a garantire che i tuoi compiti critici rispettino le loro scadenze.

Vorrei anche esaminare il framework di programmazione basato sugli eventi QP-nano di Miro Samek che può funzionare con o senza RTOS e offrirti comunque funzionalità in tempo reale. Con esso, stai dividendo il tuo progetto in macchine a stati gerarchiche anziché in attività tradizionali. Jason S ha menzionato il libro di Miro nel suo post. Una lettura eccellente!


9

Una cosa che ho trovato utile su un numero di macchine è un semplice switcher di stack. In realtà non ne ho scritto uno per il PIC, ma mi aspetto che l'approccio funzioni perfettamente sul PIC18 se entrambi / tutti i thread utilizzano un totale di 31 o meno livelli di stack. Sull'8051, la routine principale è:

_taskswitch:
  xch a, SP
  xch a, _altSP
  xch a, SP
  macerare

Sul PIC, ho dimenticato il nome del puntatore dello stack, ma la routine sarebbe qualcosa del tipo:

_taskswitch:
  movlb _altSP >> 8
  movf _altSP, w, b
  movff _STKPTR, altSP 
  movwf _STKPTR, c
  ritorno

All'inizio del programma, chiama una routine task2 () che carica altSP con l'indirizzo dello stack alternativo (16 probabilmente funzionerebbe bene per un PIC18Fxx) ed esegue il ciclo task2; questa routine non deve mai tornare altrimenti le cose moriranno in una morte dolorosa. Invece, dovrebbe chiamare _taskswitch ogni volta che vuole cedere il controllo all'attività principale; l'attività primaria dovrebbe quindi chiamare _taskswitch ogni volta che vuole cedere all'attività secondaria. Spesso si avranno piccole routine carine come:

void delay_t1 (valore breve senza segno)
{
  fare
    taskswitch ();
  while ((unsigned short) (millisecond_clock - val)> 0xFF00);  
}

Si noti che il commutatore di attività non ha alcun mezzo per eseguire alcuna "attesa di condizione"; tutto ciò che supporta è uno spinwait. D'altra parte, l'interruttore di attività è così veloce che un tentativo di interruttore di attività () mentre l'altra attività è in attesa della scadenza di un timer passerà all'altra attività, controllerà il timer e tornerà più velocemente di un tipico switcher di attività determinerebbe che non è necessario cambiare task.

Si noti che il multitasking cooperativo presenta alcune limitazioni, ma evita la necessità di molti blocchi e altri codici relativi al mutex nei casi in cui gli invarianti temporaneamente disturbati possono essere ristabiliti rapidamente.

(Modifica): un paio di avvertimenti riguardanti le variabili automatiche e simili:

  1. se una routine che utilizza il cambio di attività viene chiamata da entrambi i thread, sarà generalmente necessario compilare due copie della routine (possibilmente # includendo due volte lo stesso file sorgente, con diverse istruzioni #define). Ogni dato file sorgente conterrà il codice per un solo thread, oppure conterrà il codice che verrà compilato due volte - una volta per ogni thread - in modo da poter utilizzare macro come "#define delay (x) delay_t1 (x)" o #define delay (x) delay_tx (x) "a seconda del thread che sto usando.
  2. Credo che i compilatori PIC che non possono "vedere" una funzione chiamata supporranno che tale funzione possa eliminare tutti i registri della CPU, evitando così la necessità di salvare i registri nella routine switch-task [un bel vantaggio rispetto a multitasking preventivo]. Chiunque consideri un task switcher simile per qualsiasi altra CPU deve essere a conoscenza delle convenzioni del registro in uso. Spingere i registri prima di un cambio di attività e farli scoppiare dopo è un modo semplice per prendersi cura delle cose, supponendo che esista uno spazio di stack adeguato.

Il multitasking cooperativo non consente di sfuggire completamente ai problemi di blocco e simili, ma semplifica notevolmente le cose. In un RTOS preventivo con un Garbage Collector compatto, ad esempio, è necessario consentire agli oggetti di essere bloccati. Quando si utilizza uno switcher cooperativo, ciò non è necessario a condizione che il codice presupponga che gli oggetti GC possano spostarsi ogni volta che viene chiamato taskwitch (). Un collettore compatto che non deve preoccuparsi di oggetti appuntati può essere molto più semplice di uno che lo fa.


1
Risposta fantastica. Penso che sarebbe interessante ottenere alcuni link sulle risorse per avvicinarmi al mio RTOS. Il mio obiettivo qui era davvero ottenere un RTOS di alta qualità da un fornitore che ha fatto il lavoro per garantire un duro momento in tempo reale, ma questo potrebbe essere un progetto hobbistico divertente per me stesso.
Kortuk,

1
Fantastico, non
ho

1
@JGord: ho fatto minuscoli commutatori di attività sull'8x51 e su un DSP TI. L'8051, mostrato sopra, è progettato per esattamente due compiti. Quello DSP è usato con quattro ed è un po 'più complicato. Ho avuto un'idea folle, però: uno poteva gestire quattro attività semplicemente usando tre task switcher. Ogni volta che una delle prime due attività vuole cambiare task, dovrebbe chiamare TaskSwitch1 e TaskSwitch2. Quando una delle seconde due attività vuole cambiare task, dovrebbe chiamare Taskswitch1 e Taskswitch3. Supponiamo che il codice inizi nello stack0 e che ogni commutatore di attività sia impostato con il numero dello stack corrispondente.
supercat

@JGord: Hmm ... che non funziona del tutto; sembra produrre un round robin a 3 vie e ignora il terzo switcher. Bene, sperimenta e penso che probabilmente troverai una buona formula.
supercat,

7

Ho usato Salvo su MSP430. Questo è stato molto leggero sulle risorse del processore e, a condizione che tu obbedisca alle regole di implementazione, molto facile da usare e affidabile. Questo è un sistema operativo cooperativo e richiede che gli switch di attività vengano eseguiti a livello di chiamata di funzione esterna delle funzioni di attività. Questo vincolo consente al sistema operativo di funzionare su dispositivi di memoria molto piccoli senza utilizzare grandi quantità di spazio di stack mantenendo contesti di attività.

Sull'AVR32 sto usando FreeRTOS. Ancora una volta molto affidabile finora, ma ho avuto alcune discrepanze di configurazione / versione tra la versione che FreeRTOS pubblica e la versione fornita con il framework Atmel. Questo ha comunque il vantaggio di essere gratuito!


5

L'edizione di dicembre di Everyday Practical Electronics ha la parte 3 di una serie di sistemi operativi in ​​tempo reale per PIC (nella colonna PIC n 'Mix) e contiene dettagli sull'impostazione di FreeRTOS con MPLAB e un PICKit 2. I due precedenti articoli (che io non ho visto) sembra aver discusso i meriti di vari RTOS e optato per FreeRTOS. Una volta che l'articolo corrente ha impostato l'ambiente di sviluppo, continuano a progettare un orologio digitale binario. Sembra che ci sia almeno un'altra parte su questo argomento.

Non sono sicuro di quanto sia disponibile EPE negli Stati Uniti, ma sembra che ci sia un negozio degli Stati Uniti collegato dal loro sito e potrebbero essere disponibili copie elettroniche.


4

Il compilatore CCS per PIC viene fornito con un semplice RTOS. Non l'ho provato, ma se si dispone di questo compilatore, sarebbe facile sperimentare.


1
In realtà ho provato questo come il mio primo. Non è un RTOS in alcun senso reale della parola. Non è in alcun modo preventivo. Richiede un uso regolare dei comandi di rendimento in modo che RTOS possa decidere chi verrà eseguito successivamente, è necessario inserirli intenzionalmente costantemente nel caso in cui un altro programma debba subentrare.
Kortuk,

2
Penso che sia ancora chiamato RTOS. Sembra solo che abbia uno scheduler cooperativo invece di uno scheduler completamente preventivo.
Jay Atkinson,

Sì, è ancora tecnicamente un RTOS, ma avevo e ho ancora poco valore per questo. So che è una cosa personale, ma per me deve essere preventivo per essere prezioso. Ho ancora +1 in quanto è stata una buona risposta e di valore.
Kortuk,

3

Grazie! Sembra che molte persone non abbiano capito la domanda, ma è comunque interessante.
Kortuk,

Ho pubblicato la domanda su SO invitando l'utente a venire a E&R per aiuto!
Kortuk,

Penso che abbiamo "ottenuto" la domanda su SO, stava facendo qualcosa di diverso ma legato a questa domanda. Per quanto riguarda il tuo commento lì sulla certificazione; dipende da molte cose. Guardando le risposte qui, mi piace la risposta di DoxaLogos riferita a QP-nano; la mia esperienza mi porta a preferire il codice event driven rispetto ai thread e il cambio di contesto implicito dei thread.
Jan

2

Non hai detto molto sulla tua domanda. Se usi un RTOS dipende molto da cosa devi fare nel PIC. A meno che tu non stia facendo diverse cose asincrone, che richiedono limiti di tempo rigorosi o che hanno diversi thread in esecuzione, un RTOS potrebbe essere eccessivo.

Esistono molti modi per organizzare il tempo su un microcontrollore a seconda di ciò che è più importante:

  1. Frame rate costante: per un PIC che esegue un servo controller che deve funzionare ad esempio a 1000Hz. Se l'esecuzione dell'algoritmo PID richiede meno di 1 ms, è possibile utilizzare il resto del millisecondo per eseguire altre attività, come controllare il bus CAN, leggere i sensori, ecc.

  2. Tutti gli interrupt: tutto ciò che accade nel PIC viene attivato da un interrupt. Le interruzioni possono essere prioritarie in base all'importanza dell'evento.

  3. Attaccalo in un ciclo e fai tutto il più velocemente possibile. È possibile che ciò fornisca limiti di tempo adeguati.


Comprendo altri metodi, ma voglio espandermi in un RTOS. Eseguirò più attività e avrò un sistema in tempo reale difficile, ma sono disposto a iniziare senza i requisiti di tempo reale difficile. Grazie per aver dedicato del tempo per rispondere, ma voglio imparare un RTOS in modo da poterlo utilizzare in una situazione di grande richiesta.
Kortuk,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.