Misc

Code-optimalisatie in microcontrollers

Schrijver: Laura McKinney
Datum Van Creatie: 4 April 2021
Updatedatum: 16 Kunnen 2024
Anonim
Optimizing C for Microcontrollers - Best Practices - Khem Raj, Comcast RDK
Video: Optimizing C for Microcontrollers - Best Practices - Khem Raj, Comcast RDK

Inhoud

De auteur voltooide zijn laatste jaar engineeringproject met de dsPic-microcontrollers, waardoor hij uitgebreid inzicht kreeg in deze apparaten.

De C-taalcode van een microcontroller moet mogelijk worden geoptimaliseerd in bepaalde geavanceerde toepassingen. Deze code-optimalisatie wordt toegepast om twee cruciale dingen te verminderen:

  1. Code Maat: Microcontrollers kunnen beperkte gegevens en instructies opslaan vanwege de beperkte omvang van hun RAM. Daarom moet de code worden geoptimaliseerd, zodat het beschikbare instructie- en datageheugen op de meest efficiënte manier kan worden gebruikt.
  2. Tijden voor uitvoering van code: Microcontrollers zijn opeenvolgende apparaten die één instructie tegelijk uitvoeren. Elke montage-instructie verbruikt een bepaald aantal klokcycli om zichzelf uit te voeren. Daarom moet de code worden geoptimaliseerd om ervoor te zorgen dat deze de vereiste taak uitvoert in het minste aantal klokcycli of montage-instructies. Hoe minder klokcycli een code gebruikt, hoe sneller deze werkt. Dit betekent dat applicaties sneller kunnen draaien omdat de doorlooptijden worden geminimaliseerd.

Dit artikel bevat tips en trucs die kunnen worden gebruikt om de grootte en uitvoeringstijd van een microcontrollercode te verminderen.


De MplabX-ontwikkelings-IDE van Microchip zal worden gebruikt om waar nodig voorbeelden te demonstreren.

Hoe u de uitvoeringstijd van code experimenteel kunt meten

Om een ​​idee te krijgen van hoeveel tijd uw code werkelijk nodig heeft om in realtime uit te voeren, moet u deze experimenteel meten. Een logic analyzer kan handig worden gebruikt om de code-uitvoeringstijd te meten en geïnteresseerden kunnen via e-mail bij mij informeren naar het proces hiervoor. Naast dit:

  • Sommige compilers hebben de mogelijkheid om klokcycli te tellen die een code verbruikt.
  • Sommige debuggers, bijvoorbeeld de ICD 3 van microchip, kunnen de uitvoeringstijd rechtstreeks meten via een stopwatch.

1. Ken de verwerkingskracht en geheugengrootte van uw microcontroller

Het is niet altijd de klokfrequentie (Mhz) die het ware beeld geeft van de verwerkingssnelheid van een microcontroller, een meer realistische maat is MIPS (mega-instructies per seconde) of het aantal instructies dat MCU in een seconde kan uitvoeren.

MCU's variëren gewoonlijk van 60-70 MIPS in de high-end categorie tot 20 MIPS 8-bit AVR's. Een hoge MIPS-microcontroller is waarschijnlijk duurder dan een low-end apparaat, dus hier heb je een afweging tussen kosten en verwerkingssnelheid.


Microcontrollers hebben een apart geheugen voor het opslaan van gegevens en programmacode. De grootte van beide is te vinden op de datasheet. Mogelijk hebt u een MCU met een grotere geheugengrootte nodig als uw code aanzienlijk groot is.

2. Keuze van variabelen voor optimalisatie in codegrootte

Microcontrollers hebben een beperkt datageheugen, meestal variërend van 1 tot 4 Kbytes. In dit geval is het verstandig om het meest geschikte type variabele te kiezen op basis van het verwachte bereik van de opgeslagen datum. De onderstaande tabel vat deze variabelen samen:

Samenvatting van variabelen die worden gebruikt in C-taal.

Variabel typeGrootte in bytesBereik

bool

1

Alleen 0 of 1

char

1


-128 tot 127

int

2

-32.768 tot 32.767

unsigned int

2

0 tot 65.535

lang

4

-2.147.483.648 tot 2.147.483.647

vlotter

4

Nauwkeurig tot 6 decimalen

dubbele

8

Nauwkeurig tot 15 decimalen

lang dubbel

10

Nauwkeurig tot 19 decimalen

Voorbeeld:

  • Als twee variabelen X en Y moeten worden toegevoegd en het resultaat moet worden opgeslagen in Z, maar de waarde van Z zal naar verwachting hoger zijn dan 65.535 na optelling, dan mag Z worden gedeclareerd als een lang en kunnen X en Y worden gedeclareerd als ongetekend int, wordt niet verwacht dat de waarden van X en Y negatief worden. Dit bespaart 04 bytes in het datageheugen die anders zouden zijn opgebruikt als alle variabelen zo lang zouden worden gedeclareerd.
  • Twee variabelen X en Y, waarvan de waarden naar verwachting in hele getallen zijn, moeten worden gedeeld, maar het resultaat van deling kan een decimaal opleveren, dan kunnen X en Y worden gedeclareerd tot int en het resultaat kan worden gedeclareerd als float of double, afhankelijk van de vereiste precisie.

De keuze van het gegevenstype kan cruciaal zijn bij het declareren van arrays met een groot aantal elementen.

3. Keuze van variabelen voor optimalisatie in uitvoeringstijd van code

  • Het is een vaststaand feit dat drijvende-kommaberekeningen langer duren dan berekeningen met vaste komma. Gebruik geen variabele met drijvende komma als een decimale waarde niet vereist is. Werk waar mogelijk met gehele getallen zonder teken.
  • Lokale variabelen hebben de voorkeur boven globale variabelen. Als een variabele alleen in een functie wordt gebruikt, moet deze in die functie worden gedeclareerd omdat toegang tot globale variabelen langzamer is dan lokale variabelen.
  • Een 8-bits MCU zal een variabele van één byte sneller vinden om toegang te krijgen en een 16-bits MCU zal een 2-byte variabele gemakkelijker toegankelijk vinden vanwege de lengte van het gegenereerde adres.

4. Optimalisatie van rekenkundige bewerkingen

Rekenkundige bewerkingen kunnen op de volgende manieren worden geoptimaliseerd.

  1. Gebruik opzoektabellen met vooraf berekende waarden in plaats van een sinus of een andere trigonometrische functie of een andere bewerking te evalueren waarvan het resultaat vooraf in de code bekend kan zijn.
  2. In het geval dat een sinusopzoektabel al in het geheugen is opgeslagen, kan een cosinus worden geëvalueerd door de array-aanwijzer gelijk aan 90 graden vooruit te schuiven.
  3. Van de vier rekenkundige bewerkingen nemen delen en vermenigvuldigen de meeste verwerkingstijd in beslag, in de praktijk kan dit in het bereik van honderden microseconden of zo zijn in het geval van drijvende-kommawaarden.
  4. Gebruik bitverschuivingsinstructies in plaats van delen en vermenigvuldigen. Een rechter schakelinstructie 3 dient om te delen door 23 waar als een linker shift instructie 1 zal dienen om te vermenigvuldigen met 21.

5. Gebruik een DSP-compatibele microcontroller voor intensieve berekeningen

Sommige microcontrollers hebben een andere DSP-verwerkingseenheid dan de conventionele ALU die in hun architectuur is ingebouwd. Deze DSP-engine is erop gericht om zeer snel rekenkundige berekeningen uit te voeren in het minste aantal klokcycli (in de meeste gevallen één), vele malen sneller dan de ALU.

Instructies die een DSP-processor sneller kan uitvoeren dan een ALU zijn:

  • Bit shift en roteer instructies.
  • Vermenigvuldigingen, verdelingen en andere rekenkundige bewerkingen.
  • Evaluatie van sinussen en andere trigonometrische functies.
  • Alle DSP-bewerkingen zoals FFT, DFT, convolutie en FIR-filtering.

Het gebruik van de DSP-engine van een microcontroller vereist dat:

  • Afzonderlijke DSP-bibliotheken zijn in het project opgenomen.
  • Namen van functies verschillen van de standaard wiskundige bibliotheek van C-taal. Documentatie van deze bibliotheken en functies is beschikbaar op de website van de respectievelijke fabrikanten.
  • DSP-engine gebruikt een ander variabel type 'fractioneel'. Leer hoe u variabelen van het fractionele type gebruikt voordat u verder gaat met dsp-bibliotheekfuncties.

Merk op dat standaard wiskundebibliotheekfuncties de DSP-engine niet aanroepen omdat ze worden vertaald in ALU-montage-instructies.

6. Werk met onderbrekingen

Gebruik interrupts voor het uitvoeren van specifieke functies, zoals:

  • ADC-waarden lezen.
  • Verzenden en ontvangen van UART.
  • PWM-duty-cycle-registers bijwerken.
  • CAN- of I2C-communicatie.

Interrupts zullen deze functies snel bedienen in vergelijking met het uitvoeren ervan in de hoofdtekst door middel van een functieaanroep of inline code.

Onderbrekingen worden ook alleen geactiveerd wanneer dat nodig is, terwijl als de code in de hoofdtekst wordt gecodeerd, de code in elke iteratie van de while (1) -lus wordt uitgevoerd.

7. Gebruik de best beschikbare compilers

Compilers kunnen automatisch enkele van de hierboven besproken optimalisaties implementeren tijdens het vertalen van de code van C-taal naar assembleertaal, indien correct geconfigureerd. Zoek naar optimaliseringsopties in uw compiler en upgrade indien mogelijk naar professionele versies van compilers omdat dit krachtigere code-optimizers zijn.

8. Gebruik voorwaardelijke uitspraken op een intelligente manier

  • Houd bij het gebruik van een reeks if-else-statements eerst de meest waarschijnlijke voorwaarde aan. Op deze manier hoeft de MCU niet door alle condities te scannen nadat deze de ware conditie heeft gevonden.
  • Een switch-case-instructie is meestal sneller dan een if-else.
  • Gebruik geneste if-else-instructies in plaats van een reeks instructies. Een if-else-blok met veel instructies kan worden onderverdeeld in kleinere subvertakkingen om te optimaliseren voor de slechtste (laatste) toestand.

9. Gebruik inline-functies

Functies die slechts één keer in de code moeten worden gebruikt, kunnen als statisch worden gedeclareerd. Dit zorgt ervoor dat de compiler die functie optimaliseert naar een inline-functie en daarom zal er geen assemblagecode worden vertaald voor de functie-aanroep.

  • Een functie kan inline gedeclareerd worden door er het trefwoord 'static' bij te gebruiken.

10. Gebruik verminderde lussen

Een verlaagde lus zal minder assemblagecode genereren in vergelijking met een opgehoogde lus.

Dat komt omdat in een oplopende lus een vergelijkingsinstructie nodig is om de lusindex te vergelijken met de maximale waarde in elke lus om te controleren of de lusindex de maximale waarde bereikt. In tegendeel, in een verlagingslus is deze vergelijking niet meer nodig omdat het verlaagde resultaat van de lusindex de nulvlag in SREG zal zetten als het nul bereikt.

Gegeven het feit dat de lus honderd keer moet herhalen, zal het verminderen van één instructie uit de lus voorkomen dat deze honderd keer wordt uitgevoerd, zodat de impact waarschijnlijk groter is wanneer de lus vele keren moet herhalen.

Afsluiten

Deze tips kunnen nuttig zijn, maar hun werkelijke toepassing en potentie hangt af van de vaardigheid van de programmeur en het commando dat hij heeft over zijn code. Onthoud dat de grootte van het programma niet altijd de uitvoeringstijden bepaalt, sommige instructies kunnen meer klokcycli verbruiken dan de andere, dus opnieuw moeten de vaardigheden van het programma hun rol spelen.

Dit artikel is nauwkeurig en waar voor zover de auteur weet. De inhoud is alleen bedoeld voor informatieve of amusementsdoeleinden en vervangt geen persoonlijk advies of professioneel advies op zakelijk, financieel, juridisch of technisch gebied.

Verse Artikelen

Populair Op De Portal

Optimaal gebruikmaken van foto's van personeel en vrijwilligers
Misc

Optimaal gebruikmaken van foto's van personeel en vrijwilligers

imon i al ind de tijd van papieren tape betrokken bij oftwareontwikkeling. Hij heeft niche oftware ontwikkeld voor informatiemanagement.Foto' van per oneel of vrijwilliger in organi atie worden v...
Eenvoudige stappen voor het instellen van Skype op een Windows 10-computer
Computers

Eenvoudige stappen voor het instellen van Skype op een Windows 10-computer

Eugene i een gekwalificeerde be turing - / in trumentatie-ingenieur B c (Eng) en heeft gewerkt al ontwikkelaar van elektronica en oftware voor CADA- y temen. kype i een telecommunicatietoepa ing waarm...