Domanda

Relativo a:

Se stai scrivendo un codice per un microcontroller c'è una vera differenza se scrivi in ??assembly o in C o in qualche altro linguaggio di alto livello? Se scrivessi il codice C, come lo compileresti?

Grazie

È stato utile?

Soluzione

Diversi commenti:

1) Assolutamente non assemblaggio a meno che i vincoli di prestazioni o ottimizzazione non lo garantiscano. Le seguenti metriche attraversano il tetto con l'assemblaggio:

  • tempo di codificarlo
  • tempo di debug
  • tempo di testarlo
  • tempo di documentarlo
  • tempo di capire (1 anno dopo) cosa stavi facendo quando lo hai codificato
  • possibilità di sbagliare

2) La mia preferenza sarebbe C ++ piuttosto che C per l'incapsulamento del suo spazio dei nomi & amp; agevolare le pratiche orientate agli oggetti tempo di compilazione . C ha troppe opportunità per le variabili globali e le collisioni dello spazio dei nomi. (Java in tempo reale sarebbe carino ma da quello che ho capito i suoi requisiti sono ancora piuttosto elevati)

O meglio un sottoinsieme di C ++: escludere eccezioni, funzioni virtuali, identificazione del tipo di runtime, anche allocazione dinamica della memoria nella maggior parte dei casi - praticamente tutto ciò che è rimasto non specificato al momento della compilazione, poiché di solito richiederà molte risorse extra durante il runtime. Questo è il "bloat" di C ++.

Ho usato entrambi i compilatori di TI e IAR per C ++, per i microcontrollori TMS320 e MSP430 (rispettivamente) e con adeguate impostazioni di ottimizzazione, fanno un lavoro fantastico nel ridurre l'overhead che ci si potrebbe aspettare da C ++. (Soprattutto se lo aiuti con un uso oculato della parola chiave inline )

Ho persino usato modelli per alcuni dei loro vantaggi in fase di compilazione che promuovono un buon riutilizzo del codice: ad es. scrivere un singolo file di codice sorgente per gestire CRC a 8, 16 e 32 bit; e polimorfismo in fase di compilazione per consentire di specificare il comportamento abituale di una classe, quindi riutilizzarlo ma sovrascrive alcune delle sue funzioni. Ancora una volta, il compilatore TI aveva un sovraccarico estremamente basso con impostazioni di ottimizzazione appropriate.

Ho cercato un compilatore C ++ per i PIC Microchip; l'unica azienda che ho trovato che ne produce una è la IAR. ($$$ è stato un ostacolo ma spero di acquistarne una copia qualche volta) I compilatori Microchip C18 / C30 sono abbastanza buoni ma sono C, non C ++.

3) Un avvertimento specifico sull'ottimizzazione del compilatore: può / renderà molto difficile il debug; spesso è impossibile passare in rassegna il codice C / C ++ ottimizzato e le finestre di controllo potrebbero mostrare variabili che non hanno alcuna correlazione con ciò che ritieni debbano contenere con codice non ottimizzato. (Un buon debugger ti avvertirebbe che una particolare variabile è stata ottimizzata dall'esistenza o in un registro anziché in una posizione di memoria. Molti debugger non lo fanno. & Gt; :(

Anche un buon compilatore ti permetterebbe di scegliere / scegliere l'ottimizzazione a livello di funzione tramite #pragmas. Quelli che ho usato ti consentono solo di specificare l'ottimizzazione a livello di file.

4) Interfaccia del codice C per l'assemblaggio: questo di solito è difficile. Il modo più semplice è creare una funzione stub con la firma desiderata, ad es. uint16_t foo (uint16_t a, uint32_t b) {return 0; } , dove uint16_t = unsigned short, di solito rendiamo esplicito il numero di bit. Quindi compilalo e modifica l'assembly che produce (assicurati di lasciare le parti di inizio / uscita del codice) e fai attenzione a non ostruire alcun registro senza ripristinarlo dopo aver finito.

L'assemblaggio in linea di solito può avere problemi a meno che tu non stia facendo qualcosa molto semplice come abilitare / disabilitare gli interrupt.

L'approccio che mi piace di più è intrinseco del compilatore / "ASM esteso" sintassi. Il compilatore C di Microchip si basa sul compilatore C GNU e ha " ASM esteso " che consente di codificare bit di assembly inline ma è possibile fornire molti suggerimenti per dirgli quali registri / variabili a cui si fa riferimento e gestirà al

Altri suggerimenti

La maggior parte dei produttori di microcontrollori fornisce una sorta di cross-compilatore in cui è possibile compilare il codice sul PC e quindi trasferirlo sul microcontrollore.

Perché C?
Un vantaggio di C è che in futuro il tuo codice sarà più facile da trasferire ad altri microcontrollori. La storia dell'informatica ha dimostrato che il codice in genere supera le implementazioni hardware.
Un secondo vantaggio sono le strutture di controllo (se, per, mentre) che rendono il codice più leggibile e gestibile.

Perché la lingua dell'assembly?
Puoi ottimizzare a mano le creazioni.

Verdetto
Come spesso accade con questo tipo di domanda, i compromessi dipendono molto dall'uso specifico.
Tieni presente che spesso è possibile mescolare i due effettuando chiamate di assembly all'interno del codice C, in modo da trovare un equilibrio adatto al tuo progetto.

Specifico per l'hardware PIC
It sembra che non hai l'opzione di GCC con la maggior parte dell'hardware PIC. D'altra parte, come ha osservato un commentatore, il compilatore Microchip C30 per PIC24 a 16 bit e dsPIC33 è gcc.
PIC non è ancora supportato da SDCC .
Nuove informazioni: secondo un commento, SDCC ha un supporto praticabile per PIC.
Esistono altre opzioni open source, ma non ho esperienza con esse.

Probabilmente l'opzione migliore è codificare in C, quindi per i pochissimi casi in cui è necessario ottimizzare manualmente e fare un lavoro migliore rispetto al compilatore, è necessario codificare l'assembly nei file c.

La codifica degli assemblaggi è un ricordo del passato per PC, ma è molto rilevante in embedded.

La scrittura di assembly in embedded è diversa dalla scrittura di assembly su PC. I compilatori per PC sono "migliori degli umani" nel generare istruzioni ottimizzate. I sistemi integrati hanno spesso architetture strane e i loro compilatori ottimizzanti non sono così maturi come un compilatore ottimizzatore per PC.

Un problema che ho riscontrato con la scrittura di assembly per un microcontrollore è la necessità di essere molto attenti a come è stato disposto il codice. Avere una tabella di salto oltre i confini della memoria e far saltare il codice in posti davvero strani è piuttosto inquietante. Codificando in C, il compilatore copre quella base per te.

Andrei sicuramente con C. È più veloce e crea software più affidabile. L'assemblea ha molto poco da offrire e in rare occasioni. Tieni presente che in C:

  • Saresti in grado di trasferire facilmente il codice da piattaforme esistenti, anche da PC.
  • Puoi sviluppare in un linguaggio di alto livello senza compromettere la velocità di esecuzione o la dimensione del codice. A condizione che sia disponibile un compilatore di qualità (ci sono molte scelte per PIC18), molto probabilmente sarebbe meglio con C rispetto all'assemblaggio realizzato a mano.
  • È molto più facile eseguire il debug, testare e mantenere il codice. C produce un codice più affidabile.

Un'altra cosa che ha a che fare specificamente con PIC18. Non dovrai avere a che fare con l'architettura PIC non intuitiva e cose come Memory BANKs.

Ho avuto una buona esperienza con IAR compilatori C per 8051 in passato.

Il mio approccio recente è sempre stato questo: -

Scrivilo in C con un buon compilatore di ottimizzazione e SOLO POI in caso di problemi con dimensioni o velocità, considera di riscrivere alcune parti nell'assemblatore.

Tuttavia, da quando ho adottato questo approccio non ho mai necessario scrivere una sola riga di assemblatore ...

Vai per c!

Ho lavorato per un grande produttore CE. L'ultima volta che ho visto l'assemblaggio è stato intorno al 1996 in alcune piccole routine di servizi di interruzione per gli algoritmi di decodifica e sintonizzazione RC5 e RC6. Dopodiché ha sempre usato c e C ++ (solo classi usate, no stl, eccezioni o rtti). Ho buone esperienze con il vecchio compilatore KEIL per 8051 e con il compilatore greenhills (MIPS) e il set di strumenti VxWorks (basato su PowerPC).

Come dice Roddy, prima scrivi in ??C e ottimizza nell'assemblaggio in seguito (se necessario).

L'assemblaggio può in molti casi essere più veloce; quando sei su un desktop, i compilatori tendono ad essere ottimizzati al punto che l'assemblaggio manuale è raramente una necessità, ma nel mondo degli Stati Uniti lo è spesso. Inoltre, se devi scrivere routine di gestione degli interrupt e cose del genere, spesso non puoi farlo in C.

Per quanto riguarda la compilazione, google in giro per un compilatore C per il tuo obiettivo.

Sicuramente C, tranne quando

    La memoria del programma
  • è estremamente limitata. Dì che dopo aver meticolosamente ottimizzato a mano il tuo codice assembler riesci ad adattare il tuo programma a questi 1024 byte di Flash, con 0 byte rimasti. In questo caso nessun compilatore C andrà bene.

  • vuoi avere il controllo assoluto del timing. Se la quantità di latenza di interruzione è troppo lunga, dovrai fare affidamento sull'assemblatore.

Il problema in questi giorni è che l'embedded può essere qualsiasi cosa, da un ATTiny con 6 pin e pochi byte di RAM a uno SBC multi-core che esegue un sistema operativo incorporato che farebbe vergognare i computer desktop di alcune persone.

In quanto tale, la scelta del langauge / dell'ambiente di sviluppo deve tener conto dell'efficienza necessaria per essere vs quanto sia complesso il sistema.

Prima di tutto: C funziona ovunque e si adatta abbastanza bene, più vai avanti più finirai per chiamare librerie esterne ecc. per gestire la complessità.

Per micros molto piccoli (misurazione flash / ram in byte) è meglio usare ASM, quando si arriva al range di kb, è possibile utilizzare C o qualsiasi altra lingua tradizionale poiché non è necessario contare ogni byte. Una volta che hai megabyte con cui giocare, hai sia la possibilità che la probabilità di utilizzare un RTOS per occuparti di tutto e ridurre i tempi di sviluppo. Quando hai un hardware su cui puoi eseguire un sistema operativo completo, puoi probabilmente sottrarti dall'hardware e scrivere semplicemente tutto in una cella imbottita come Java o qualcosa del genere senza preoccuparti troppo di quanto sia terribilmente dispendioso e di come sei non è più un vero programmatore ...;)

L'eccezione a quanto sopra è quando hai bisogno di tutte le prestazioni che puoi strappare dall'hardware, a quel punto potresti dover abbassare un livello o due per mantenere le cose efficienti.

Questa è la linea di fondo se usi C che puoi ottimizzare a mano in seguito, non userei altro che C o assemblatore (no C ++, ecc.).

La chiave è l'insieme di istruzioni del microcontrollore se si utilizza un PIC o anche un 8051, utilizzare solo l'assemblatore. Se è un compilatore compatibile con isa come arm o avr o msp430, allora usa C per salvare un po 'di battitura ma probabilmente avrai alcune routine in assemblatore per vari motivi. Allo stesso modo probabilmente vuoi evitare una libreria C, anche newlib può essere troppo ingombrante, prendere in prestito codice o idee da loro ma non collegarne uno. Oh, tornando alla domanda, guarda quali compilatori C sono disponibili per il target, di nuovo arm e avr non avrai problemi. Probabilmente va bene anche msp. Solo perché Keil o Iar ti VENDERANNO un compilatore non significa che dovresti acquistarlo o usarlo, l'output di pay per così come i compilatori gratuiti possono essere terribili. Devi comunque essere esperto nell'asm ed esaminare l'output (probabilmente dovrai scrivere un disassemblatore per farlo).

Linea di fondo (un'altra linea di fondo), non esiste una risposta globale (beh, evita che qualcosa di più alto di C sia una risposta globale) dipende sempre da quale piattaforma è quali sono le tue risorse, quali sono le tue attività, quali sono i requisiti di prestazione i requisiti di portabilità sono (se è veramente incorporato in un microcontrollore, in gran parte per definizione non è portatile) quali compilatori, debugger, jtag, ecc. sono disponibili, anche se il sistema operativo host su cui stai sviluppando può essere un fattore determinante .

È possibile che sia necessario scrivere un'altra volta in assembly: se è necessario eseguire un test RAM di basso livello o simile, che richiede il controllo assoluto su dove vengono archiviati i dati.

Ad esempio, un software che conferma SIL -2 (livello di integrità della sicurezza) e versioni successive potrebbe richiedere controlli continui sulla RAM, al fine di rilevare l'eventuale corruzione dei dati. L'area della RAM che stai controllando non può cambiare mentre viene controllata, quindi scrivere il test in assembler ti consente di assicurarti che ciò sia vero, ad esempio memorizzando qualsiasi variabile locale in registri specifici o in un'altra area di RAM . Ciò sarebbe difficile, se non impossibile, in C.

Il codice di avvio che azzera la RAM e inizializza variabili statiche diverse da zero può anche essere scritto in assemblatore per lo stesso scritto, sebbene questo tipo di codice sia normalmente fornito.

Se stai scrivendo un codice che dipende fortemente dalle periferiche specifiche del dispositivo e la catena di strumenti che stai utilizzando non fornisce gli intrinseci necessari per utilizzarli in modo efficiente (come il compilatore DSP563CC di Freescale), allora usa assembly .

Oltre a ciò, penso che le regole non scritte dell'utilizzo dell'assembly rispetto a un linguaggio di alto livello siano più o meno le stesse dello sviluppo di software desktop: mantenere il codice pulito, gestibile e ottimizzare l'hot code con il linguaggio macchina.

Il codice in linguaggio assembler è veramente veloce con ingombro ridotto, ma il codice scritto in linguaggio assembler non è codice riutilizzabile. Questa funzionalità di riusabilità per il codice è la caratteristica più importante per la progettazione del software. Ad esempio, se si dispone del codice di progetto dell'assemblatore per il processore x86, può essere utilizzato solo per il processore x86, non per il processore ARM. Ma se si dispone del codice C / C ++ di progetto per il processore x86, è possibile utilizzare questo codice per il processore ARM. Quindi, è meglio evitare assemblatore per lo sviluppo di software.

È un peccato che nessuno abbia menzionato Forth o Scheme finora. Entrambi possono essere appropriati per piccoli ambienti e possono offrire notevoli miglioramenti della produttività.

Pianura C o Pascal, Modula2. Ma a causa della disponibilità del compilatore questo significa C.

Gli extra di C ++ e simili sono interessanti solo per motivi di stile, poiché l'allocazione dinamica e le dimensioni del programma sono generalmente molto limitate.

Anche un runtime più complicato può essere una seccatura se le tue app diventano strette.

Anche l'assemblatore può essere utile, ma solo se vendi quantità davvero gigantesche e un firmware più piccolo significa un chip più piccolo ed economico (meno flash) e le dimensioni del programma sono rilevabili (leggi: c'è qualche possibilità che tu lo ottenga bugfree in time)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top