2010-03-18 7 views
6

Come devo gestire la memoria nella mia applicazione embedded mission-critical?Risorse per la gestione della memoria nell'applicazione incorporata

Ho trovato alcuni articoli con google, ma non sono riuscito a individuare una guida pratica davvero utile.

Il DO-178b proibisce l'allocazione della memoria dinamica, ma come gestirai la memoria? Preallocare tutto in anticipo e inviare un puntatore a ciascuna funzione che necessita di allocazione? Assegnarlo in pila? Utilizzare un allocatore statico globale (ma è molto simile all'allocazione dinamica)?

Le risposte possono essere nella forma di una risposta regolare, di un riferimento a una risorsa o di un riferimento a un buon sistema incorporato opensource, ad esempio.

chiarimento: Il problema qui non è se la gestione della memoria è disponibile per il sistema incorporato. Ma cos'è un buon design per un sistema embedded, per massimizzare l'affidabilità.

Non capisco perché preallocare staticamente un pool di buffer e ottenerlo e rilasciarlo dinamicamente è diverso dall'allocazione dinamica della memoria.

risposta

3

Come qualcuno che ha affrontato con sistemi embedded, anche se non a tale rigore finora (ho letto DO-178B, però):

  • Se si guarda il bootloader u-boot, molto è fatto con una struttura posizionata globalmente. A seconda della tua esatta applicazione, potresti riuscire a farla franca con una struttura globale e stack. Naturalmente, ci sono re-entrancy e problemi correlati lì che non si applicano a un bootloader ma potrebbero fare al caso tuo.
  • Preallocazione, preallocazione, preallocazione. Se in fase di progettazione è possibile associare la dimensione di una matrice/struttura di elenco/ecc., Dichiararla come globale (o statica globale - aspetto Ma, incapsulamento).
  • Lo stack è molto utile, usalo dove serve, ma fai attenzione, perché può essere facile continuare a ripartire fino a quando non ci sono più spazi. Un po 'di codice che una volta ho trovato che eseguivo il debug assegnava 1k buffer per la gestione delle stringhe in più funzioni ... a volte l'utilizzo dei buffer avrebbe colpito lo spazio di stack di un altro programma, poiché la dimensione dello stack predefinita era 4k.
  • Il caso del pool di buffer può dipendere esattamente da come è implementato. Se si sa che è necessario passare attorno ai buffer a dimensione fissa di una dimensione nota in fase di compilazione, è più facile dimostrare che la gestione di un pool di buffer è corretta rispetto a un allocatore dinamico completo. Hai solo bisogno di verificare che i buffer non possano essere persi e convalidare la tua gestione non fallirà. Sembra che ci siano alcuni buoni consigli qui: http://www.cotsjournalonline.com/articles/view/101217

In realtà, però, credo che le risposte potrebbero essere trovate a far parte http://www.do178site.com/

0

L'allocazione di tutto dallo stack viene comunemente eseguita in sistemi embedded o altrove, dove la possibilità di un'allocazione non riuscita è inaccettabile. Non so cosa sia DO-178b, ma se il problema è che malloc non è disponibile sulla tua piattaforma, puoi anche implementarlo tu stesso (implementando il tuo heap), ma questo può ancora portare ad un'allocazione fallita quando corri fuori dallo spazio, ovviamente.

+0

DO-178b è uno standard per software avionico. Il problema non è la disponibilità di malloc, ma una buona progettazione del software mission-critical. –

1

I sistemi mission-critical in tempo reale e di lunga durata non devono allocare e liberare dinamicamente memoria dall'heap. Se hai necessario e non puoi disegnare attorno a esso per poi scrivere il tuo schema di gestione del pool assegnato e fisso. Sì, assegnato in anticipo quando possibile. Qualcos'altro sta chiedendo eventuali problemi.

0

Non c'è modo di essere sicuri al 100%.

Si può guardare esempi di allocatori di memoria di FreeRTOS. Quelli usano pool statici, se non sbaglio.

+0

Ma la memoria allocata dinamica utilizza pool statici accettabili nelle applicazioni mission-critical? –

+0

Sì e no. Proprio come in caso di qualsiasi tipo di allocazione dinamica, c'è una possibilità di rimanere fuori dalla piscina. Devi chiedertelo se puoi tollerarlo. Oltre a ciò, ci sono un sacco di problemi relativi all'attuazione di un allocatore personalizzato (frammentazione, ottimizzazione, yada yada) –

0

È anche possibile trovare this question interessante, l'allocazione dinamica è spesso proibita nelle impostazioni di spazio rigido (in realtà, la memoria di base è ancora utile lì).

In genere, quando malloc() non è disponibile, utilizzo semplicemente lo stack. Come ha detto Tronic, l'intero motivo dietro il non usare malloc() è che può fallire. Se si sta utilizzando un pool statico globale, è concepibile che l'implementazione interna di malloc() possa essere resa a prova di errore.

In realtà, davvero, davvero dipende dal compito che si sta svolgendo e da ciò che verrà esposto alla scheda.

+0

Davvero davvero non capisco come il malloc implementato internamente possa essere reso a prova di errore. Se stai davvero provando a calcolare qualcosa (ad esempio, numero il percorso che il tuo robot dovrebbe compiere per raggiungere la sua destinazione) e ti capita di avere un input troppo lungo, potresti eseguire uno spazio per memorizzare tutti i passaggi necessari al robot. Devi prenderti cura di questo, se stai usando l'allocazione di memoria dinamica o statica. –

+0

@Elazar Leibovich: Se si dispone di un pool allocato staticamente, si _know_ si dispone della memoria per eseguire l'attività, dati i limiti di progettazione di qualsiasi cosa si stia lavorando. Un robot che doveva attraversare un continente suggeriva una configurazione hardware completamente diversa da quella che doveva camminare da una stanza all'altra. Inoltre, probabilmente non implementerei un malloc interno() su una scheda madre. La tua domanda è buona, ma piuttosto generale in quanto questi problemi tendono ad essere estremamente specifici. –

+0

Abbastanza corretto, è necessario disporre di memoria sufficiente per eseguire l'attività specifica necessaria all'hardware incorporato. Ma a volte ti ritrovi a scrivere pezzi generali di codice, che potrebbero essere rilevanti per altri progetti incorporati. Ad esempio, stai implementando Dijkstra. Il tuo scopo generale Dijkstra potrebbe aver bisogno di allocare memoria, e dovrebbe fallire con grazia se non ha memoria sufficiente. Ovviamente il sistema non fallirebbe mai, in quanto non userebbe Dijkstra se non ha memoria sufficiente, ma Dijkstra potrebbe fallire. –

1

Disclaimer: Non ho lavorato specificamente con DO-178b, ma ho scritto software per sistemi certificati.

Nei sistemi certificati per i quali sono stato uno sviluppatore, ...

  1. allocazione dinamica della memoria era accettabile solo durante la fase di inizializzazione .
  2. La de-allocazione della memoria dinamica non è MAI accettabile.

Questo ci ha lasciato con le seguenti opzioni ...

  • Usa strutture allocate in modo statico.
  • Creare un pool di strutture e quindi ottenerle/rilasciarle da/back alla piscina.
  • Per flessibilità, è possibile allocare dinamicamente la dimensione dei pool o il numero di strutture durante la fase di inizializzazione. Tuttavia, una volta passata la fase di init, siamo rimasti bloccati su ciò che avevamo.

La nostra azienda ha trovato che le piscine di strutture e quindi ottenere/rilasciando da/indietro nella piscina era più utile. Siamo stati in grado di mantenere il modello e mantenere le cose deterministiche con problemi minimi.

Spero che questo aiuti.

+1

Ma i pool di memoria get/release non sono equivalenti all'implementazione dell'allocazione dinamica autonomamente? –

+2

No. Sono simili ma non equivalenti. L'allocazione dinamica usando malloc() e free() porta alla frammentazione della memoria e alla possibilità di un malfunzionamento di malloc() a causa della frammentazione. I sistemi certificati lo evitano perché è un PITA reale da certificare. Gli articoli nel pool possono essere sparsi, ma la routine di recupero dell'elemento è garantita per riuscire a condizione che ci siano elementi inutilizzati. Non importa quanto siano sparsi gli oggetti nella piscina. – Sparky

+0

Non sono affatto un esperto del sistema operativo, quindi correggimi se sbaglio, ma, supponendo che ci sia solo un thread che usa malloc() e free(), non ci sarà alcuna frammentazione se sei davvero libero " hai tutto ciò che hai dimenticato? E nel caso in cui non lo fai, naturalmente tu corri nei guai comunque ... In ogni caso, il fatto che due thread utilizzino lo stesso pool è davvero un grosso problema con la gestione tradizionale della memoria. –

2

Ho lavorato in un ambiente DO-178B (sistemi per aerei). Quello che ho capito, è che la ragione principale per non consentire l'allocazione dinamica è principalmente la certificazione. La certificazione viene effettuata attraverso test (unitari, copertura, integrazione, ...). Con questi test devi dimostrare che il comportamento del tuo programma è prevedibile al 100%, quasi al punto che l'impronta di memoria del tuo processo è la stessa da una esecuzione all'altra. Dato che l'allocazione dinamica viene eseguita sull'heap (e può fallire) non è facile dimostrarlo (immagino che dovrebbe essere possibile se si padroneggia tutti gli strumenti dall'hardware a qualsiasi pezzo di codice scritto, ma ...). Non hai questo problema con l'allocazione statica. Questo è anche il motivo per cui C++ non è stato usato in questo momento in tali ambienti. (era circa 15 anni fa, che potrebbe essere cambiato ...)

Praticamente, devi scrivere un sacco di struct pools e funzioni di allocazione che ti garantiscono di avere qualcosa di deterministico. Puoi immaginare molte soluzioni. La chiave è che devi dimostrare (con tonnellate di test) un alto livello di comportamento deterministico.È più facile dimostrare che lo sviluppo della tua mano funziona in modo deterministico per dimostrare che linux + gcc è deterministico nell'allocazione della memoria.

Solo i miei 2 centesimi. È stato molto tempo fa, le cose potrebbero essere cambiate, ma per quanto riguarda la certificazione come DO-178B, il punto è dimostrare che la tua app funzionerà in qualsiasi momento e in qualsiasi contesto.