Vraag:
Wat kan ik doen als het Flash-geheugen of SRAM op is?
Peter Bloomfield
2014-02-15 07:09:33 UTC
view on stackexchange narkive permalink

Volgens de Arduino-documentatie heeft de ATmega328 32 KB Flash-geheugen voor de bootloader + geüploade sketch en slechts 2 KB SRAM voor runtime-gegevens. De ATmega2560 heeft nogal wat meer, in totaal respectievelijk 256 KB en 8 KB.

In beide gevallen lijken die limieten vrij klein, vooral in vergelijking met consumentenapparaten van vergelijkbare grootte, zoals smartphones.

Wat kunt u doen als u opraakt? Bijv. als je sketch te groot is, of als je tijdens runtime veel data (zoals strings) moet verwerken? Is er een manier om Flash of SRAM uit te breiden?

Probeer wat variabele optimalisatie te gebruiken. Enkele verschillende variabelen worden [hier] besproken (http://arduino.stackexchange.com/questions/196/when-to-use-different-variable-types)
Gebruik de juiste scopes voor uw variabelen, als u dit nog niet doet, zal de compiler het RAM-gebruik voor u optimaliseren wanneer variabelen niet worden gebruikt.
Je zou eigenlijk een Teensy 3.2 (met Teensyduino Software) kunnen gebruiken, die vergelijkbaar zou zijn met een Arduino. Aangezien je RAM / PROGMEM bijna op is, zou het ook betekenen dat je waarschijnlijk ook probeert je Arduino te pushen. Een Teensy 3.2 is niet veel duurder. maar heeft: 32bit, 72MHz (wtf !?) 256KB FLASH en 64KB RAM en 3x UART. Niet meer programmageheugen als de ATmega2560, maar de toename van RAM en snelheid zou moeten volstaan.
Vier antwoorden:
#1
+30
Peter Bloomfield
2014-02-15 07:09:33 UTC
view on stackexchange narkive permalink

Optimalisatie
Programmeren op laag niveau voor embedded systemen is heel anders dan programmeren voor apparaten voor algemeen gebruik, zoals computers en mobiele telefoons. Efficiëntie (in termen van snelheid en ruimte) is veel belangrijker omdat middelen schaars zijn. Dat betekent dat het allereerste dat u moet doen als u onvoldoende ruimte heeft, is kijken naar welke delen van uw code u kunt optimaliseren.

In termen van het verminderen van het gebruik van programmaruimte (Flash), kan de codegrootte best moeilijk te optimaliseren als je onervaren bent, of als je meer gewend bent aan programmeren voor desktopcomputers die die vaardigheid meestal niet nodig hebben. Helaas is er geen 'magische kogel'-benadering die in alle situaties werkt, hoewel het helpt als je serieus bedenkt wat je sketch echt nodig heeft . Als een functie niet nodig is, verwijder deze dan.

Soms is het ook handig om te bepalen waar meerdere delen van uw code hetzelfde zijn (of erg op elkaar lijken). Mogelijk kunt u ze condenseren tot herbruikbare functies die vanaf meerdere plaatsen kunnen worden aangeroepen. Houd er echter rekening mee dat als u probeert code ook herbruikbaar te maken, deze uiteindelijk meer uitgebreid maakt. Het is een lastige balans om te vinden die meestal met oefenen gepaard gaat. Het kan helpen om wat tijd te besteden aan het bekijken van hoe codewijzigingen de compileruitvoer beïnvloeden.

Runtime-gegevens (SRAM) -optimalisatie is meestal wat gemakkelijker als je eraan gewend bent. Een veel voorkomende valkuil voor beginnende programmeurs is het gebruik van te veel globale data. Alles dat op globaal niveau wordt gedeclareerd, blijft bestaan ​​gedurende de hele levensduur van de schets, en dat is niet altijd nodig. Als een variabele alleen binnen één functie wordt gebruikt en deze niet hoeft te blijven bestaan ​​tussen aanroepen, maak er dan een lokale variabele van. Als een waarde tussen functies moet worden gedeeld, overweeg dan of u deze als parameter kunt doorgeven in plaats van deze globaal te maken. Op die manier gebruik je SRAM alleen voor die variabelen wanneer je het echt nodig hebt.

Een andere moordenaar voor SRAM-gebruik is tekstverwerking (bijvoorbeeld door de klasse String te gebruiken). Over het algemeen moet u indien mogelijk String-bewerkingen vermijden. Het zijn enorme geheugenvarkens. Als u bijvoorbeeld veel tekst naar serieel uitvoert, gebruikt u meerdere aanroepen naar Serial.print () in plaats van stringconcatenatie. Probeer indien mogelijk ook het aantal letterlijke tekenreeksen in uw code te verminderen.

Voorkom ook indien mogelijk recursie. Elke keer dat een recursieve call wordt gedaan, wordt de stack een niveau dieper. Refactoreer uw recursieve functies om in plaats daarvan iteratief te zijn.

Gebruik EEPROM
EEPROM wordt gebruikt voor langdurige opslag van dingen die slechts af en toe veranderen. Als u grote lijsten of opzoektabellen met vaste gegevens moet gebruiken, overweeg dan om deze van tevoren in EEPROM op te slaan en alleen te verwijderen wat u nodig heeft wanneer dat nodig is.

Het is duidelijk dat EEPROM vrij beperkt is in omvang en snelheid, en heeft een beperkt aantal schrijfcycli. Het is geen geweldige oplossing voor gegevensbeperkingen, maar het kan voldoende zijn om de belasting van Flash of SRAM te verlichten. Het is ook heel goed mogelijk om te communiceren met vergelijkbare externe opslag, zoals een SD-kaart.

Uitbreiding
Als je alle andere opties hebt uitgeput, is uitbreiding misschien een mogelijkheid . Helaas is het niet mogelijk om het Flash-geheugen uit te breiden om de programmaruimte te vergroten. Het is echter mogelijk om SRAM uit te breiden. Dit betekent dat u uw sketch wellicht kunt refactoren om de codegrootte te verkleinen ten koste van de grotere gegevensomvang.

Meer SRAM verkrijgen is eigenlijk vrij eenvoudig. Een mogelijkheid is om een ​​of meer 23K256 chips te gebruiken. Ze zijn toegankelijk via SPI en er is de SpiRAM-bibliotheek om u te helpen ze te gebruiken. Pas echter op dat ze werken op 3,3V niet 5V!

Als je de Mega gebruikt, kun je als alternatief SRAM-uitbreidingsschilden krijgen van Lagrangian Point of Rugged Circuits .

U kunt ook constante gegevens in het programmageheugen opslaan, in plaats van SRAM, als u problemen hebt met SRAM-ruimte en vrij programmageheugen. Zie [hier] (http://jeelabs.org/2011/05/23/saving-ram-space/) of [hier] (http://www.nongnu.org/avr-libc/user-manual/pgmspace .html)
Een ander geweldig alternatief voor EEPROM is een SD-kaart. Het neemt wel een paar IO-poorten in beslag, maar als je een groot stuk ruimte nodig hebt voor bijvoorbeeld kaartgegevens of iets dergelijks, kan het gemakkelijk zijn om uit te wisselen en te bewerken met een aangepast programma op een pc.
Mensen moeten niet worden aangemoedigd om SPI SRAM's of RAM-uitbreidingen te gebruiken als ze te weinig geheugen hebben. Dat is gewoon geldverspilling. Het kiezen van een grotere MCU zou goedkoper zijn. Bovendien kunnen de prestaties erg slecht zijn. Men moet eerst een schatting maken van het honkbalveld: als het geschatte RAM-gebruik te dicht bij de limiet ligt, dan kiest u het verkeerde bord / microcontroller / ontwikkelplatform. Zeker, goed gebruik (strings opslaan in flash) en optimalisatie (het gebruik van sommige bibliotheken vermijden) kunnen echte game-changers zijn. Op dit moment zie ik echter geen voordelen van het gebruik van het Arduino Software-platform.
#2
+25
sachleen
2014-02-15 09:24:15 UTC
view on stackexchange narkive permalink

Wanneer u uw code uploadt naar uw Arduino, bijvoorbeeld een Uno, zal deze u vertellen hoeveel bytes het verbruikt van de beschikbare 32K. Dat is hoeveel flash-geheugen je hebt (denk aan de harde schijf van een computer). Terwijl je programma draait, gebruikt het wat SRAM heet, en daar is veel minder van beschikbaar.

Soms zul je merken dat je programma zich vreemd gedraagt ​​op een punt dat je al een tijdje niet eens hebt aangeraakt . Het kan zijn dat uw meest recente wijzigingen ervoor zorgen dat er onvoldoende geheugen (SRAM) is. Hier zijn een paar tips om wat SRAM vrij te maken.

Strings opslaan in Flash in plaats van SRAM.

Een van de meest voorkomende dingen die ik heb gezien, is dat de chip opraakt geheugen omdat er te veel lange strings zijn.

Gebruik de functie F () bij het gebruik van strings zodat ze worden opgeslagen in Flash in plaats van SRAM, aangezien je er veel meer van hebt beschikbaar.

  Serial.println (F ("Deze string wordt opgeslagen in flash-geheugen"));  

Gebruik de juiste datatypes

U kunt een byte opslaan door over te schakelen van een int (2 bytes) naar een byte (1 byte). Een niet-ondertekende byte geeft je 0-255, dus als je nummers hebt die niet hoger zijn dan 255, sla dan een byte op!

Hoe weet ik of het geheugen bijna op is?

Meestal zie je dat je programma zich vreemd gedraagt ​​en vraag je je af wat er mis is gegaan ... Je hebt niets in de code veranderd in de buurt van het punt waar het in de war raakt, dus wat geeft? Het geheugen is bijna vol.

Er zijn een aantal functies die u vertellen hoeveel beschikbaar geheugen u heeft.

Beschikbaar geheugen

Weet je of het `F ()` ding een Arduino-specifieke functie is of staat het in de AVR-bibliotheken? Je zou kunnen overwegen om ook `PROGMEM const ...` te noemen.
U kunt ook bitstructuren gebruiken om de ruimte die wordt gebruikt door uw variabelen 5eg verder te verminderen als u met veel boolean te maken heeft).
#3
+17
jfpoilpret
2014-02-15 23:28:24 UTC
view on stackexchange narkive permalink

Naast wat anderen hebben gezegd (waar ik het volledig mee eens ben), zou ik adviseren om dit adafruit-artikel over geheugen te lezen; het is goed geschreven, legt veel dingen uit over het geheugen en geeft hints om het te optimaliseren.

Aan het einde van het lezen denk ik dat je een vrij compleet antwoord op je vraag zou krijgen.

Om het samen te vatten, je hebt 2 mogelijke optimalisatiedoelen (afhankelijk van waar je geheugenproblemen zich bevinden):

  • Flash (dwz Programmageheugen); hiervoor kun je:
    • dode code verwijderen (bijv. elke code die is opgenomen maar niet gebruikt) en ongebruikte variabelen (die ook helpt bij SRAM)
    • gedupliceerde code weglaten
    • verwijder de bootloader helemaal (je kunt tussen 0,5K winnen voor een UNO en 2 of 4K voor andere Arduino-modellen); dit heeft echter enkele nadelen.
  • SRAM (dwz stack, heap en statische gegevens); hiervoor kun je:
    • ongebruikte variabelen verwijderen
    • de grootte van elke variabele optimaliseren (gebruik bijvoorbeeld geen lange -4 bytes - als je maar int -2 bytes nodig hebt)
    • gebruik het juiste bereik voor uw variabelen (en geef de voorkeur aan stapelen boven statische gegevens indien mogelijk)
    • verklein de buffergrootte tot het strikte minimum
    • verplaats constante gegevens naar PROGMEM (dwz uw statische gegevens blijven in het Flash-geheugen en worden niet naar SRAM gekopieerd bij het starten van het programma); dat geldt ook voor constante strings waarvoor u F () macro) kunt gebruiken
    • vermijd dynamische toewijzing als dit niet absoluut noodzakelijk is; u vermijdt een gefragmenteerde heap die misschien niet krimpt, zelfs niet na het vrijmaken van geheugen

Er wordt ook een aanvullende benadering beschreven om het gebruik van SRAM te verminderen (maar wordt zelden gebruikt, omdat het een beetje zwaar is bij het coderen en niet erg efficiënt), het bestaat uit het gebruik van EEPROM om gegevens op te slaan die door uw programma zijn gebouwd, maar wordt pas later gebruikt wanneer zich bepaalde omstandigheden voordoen, wanneer gegevens kunnen worden teruggeladen vanuit EEPROM .

Het verwijderen van dode code - de compiler kan dit echt goed voor je afhandelen - het maakt geen verschil als je veel code hebt die nooit wordt aangeroepen. Als je per ongeluk code belt die je niet nodig hebt, dan is dat natuurlijk anders.
#4
+9
David Cary
2014-02-16 03:21:35 UTC
view on stackexchange narkive permalink

Er zijn twee dingen die u moet doen als u geen opslagruimte meer heeft:

  • Op de een of andere manier "optimaliseert" u uw code zodat deze minder opslagruimte nodig heeft; of gebruikt in ieder geval minder van het specifieke soort opslag dat je opraakt (en gebruikt meer van het soort opslag dat je nog in overvloed hebt). Of,
  • Voeg meer opslagruimte toe.

Er zijn veel tips online over hoe je de eerste moet doen (en voor de overgrote meerderheid van de dingen die mensen doen met de Arduino, de ingebouwde opslag is meer dan voldoende na "optimaliseren") Dus ik zal me concentreren op de tweede:

Er zijn 3 dingen die flash of SRAM verbruiken; elk heeft een iets andere benadering nodig om opslag toe te voegen:

  • variabele opslag: het is mogelijk om SRAM uit te breiden, zoals Sachleen al aangaf. SRAM, FRAM en NVSRAM zijn allemaal geschikt voor snel veranderende variabelen. (hoewel je in principe flash zou kunnen gebruiken om variabelen op te slaan, moet je je zorgen maken over flash-slijtage). SPI (een serieel protocol) is het gemakkelijkst om verbinding te maken met de Arduino. De SpiRAM-bibliotheek werkt met de Microchip 23K256 seriële SRAM-chip. De Ramtron FM25W256 seriële FRAM -chip (nu eigendom van Cypress) maakt ook gebruik van SPI .De Cypress CY14B101 NVSRAM gebruikt ook SPI.Etc.

  • constante gegevens die er nog moeten zijn de volgende keer dat de stroom wordt ingeschakeld: dit is bijna net zo eenvoudig als het uitbreiden van SRAM. Er zijn veel externe EEPROM-, FRAM-, NVSRAM- en FLASH -opslagapparaten beschikbaar. Momenteel zijn de laagste kosten per MB SD-flashkaarten (die toegankelijk zijn via SPI). De Ramtron FM25W256 (zie hierboven), de Cypress CY14B101 (zie hierboven), enz. Kunnen ook constante gegevens opslaan. Veel uitbreidingsschilden bevatten een SD-kaartsleuf en verschillende bibliotheken en tutorials ondersteuning voor het lezen en schrijven naar (flash) SD-kaarten. (We kunnen SRAM hiervoor niet gebruiken, omdat SRAM alles vergeet als de stroom uitvalt).

  • uitvoerbare code: Helaas is het niet mogelijk om het Flash-geheugen van een Arduino uit te breiden om de programmaruimte te vergroten. Een programmeur kan echter altijd een schets refactoren om de codegrootte te verkleinen, ten koste van de gegevensomvang en het iets langzamer laten werken. (In theorie zou je zo ver kunnen gaan dat je je hele schets in een of andere geïnterpreteerde taal vertaalt, die versie van je schets op een SD-kaart opslaat en vervolgens een tolk voor die taal schrijft die op de Arduino draait om instructies van de Arduino op te halen en uit te voeren. SD-kaart - Forth op Arduino, een BASIC-tolk, een Tom Napier Picaro-tolk, een toepassingsspecifieke taal, enz.).



Deze Q&A is automatisch vertaald vanuit de Engelse taal.De originele inhoud is beschikbaar op stackexchange, waarvoor we bedanken voor de cc by-sa 3.0-licentie waaronder het wordt gedistribueerd.
Loading...