Kysymys:
Mitä mikro-ohjaimen eri muistityypeissä on?
Soju T Varghese
2016-06-02 12:04:07 UTC
view on stackexchange narkive permalink

On olemassa erilaisia ​​muistisegmenttejä, joille erityyppisiä tietoja laitetaan C-koodista kääntämisen jälkeen. Eli: .text , .data , .bss , pino ja kasa. Haluan vain tietää, missä kukin näistä segmenteistä asuisi mikro-ohjaimen muistissa. Eli mitkä tiedot menevät minkä tyyppiseen muistiin, kun muistityypit ovat RAM, NVRAM, ROM, EEPROM, FLASH jne.

Täältä löydät vastauksia vastaaviin kysymyksiin, mutta he eivät selittäneet mitä olisi kunkin eri muistityypin sisältö.

Kaikenlainen apu on erittäin arvostettua. Kiitos etukäteen!

NVRAM, ROM, EEPROM ja Flash ovat melkein vain eri nimiä samalle: haihtumaton muisti.
Hieman tangentiaalinen kysymykseen, mutta koodi voi (poikkeuksellisesti) esiintyä näennäisesti kaikissa näistä, varsinkin jos harkitset korjaustiedoston tai kalibroinnin käyttöä.Joskus sitä siirretään ennen teloitusta, toisinaan suoritetaan paikallaan.
@SeanHoulihane OP kysyy mikro-ohjaimista, jotka suoritetaan melkein * aina * Flashista (sait kommenttisi poikkeukselliseksi).Micro * -prosessorit *, joissa on MB: n ulkoista RAM-muistia, esimerkiksi Linux-käyttöjärjestelmällä, kopioisivat ohjelmansa RAM-muistiin suorittamaan ne, ehkä SD-kortilta, joka toimii asennettavana levynä.
@tcrosley TCM: llä on nyt mikrokontrollereita, ja joskus mikrokontrollerit ovat osa suurempaa SoC: tä.Epäilen myös, että on tapauksia, kuten eMMC-laitteet, joissa mcu käynnistää itsensä juoksemaan RAM-muistista omasta tallennustilastaan (perustuu joidenkin pari vuotta sitten tehtyjen puhelimen muistiin).Olen samaa mieltä, se ei ole suora vastaus - mutta mielestäni on erittäin merkityksellistä, että tyypilliset kartoitukset eivät ole millään tavalla kovia sääntöjä.
ei ole sääntöjä yhden asian yhdistämisestä toiseen, varmista, että vain luettavat asiat, kuten teksti ja rodata, haluaisivat mieluiten mennä flash-muodossa, mutta .data sekä .bss-siirto ja koko menevät sinne (ja kopioi sittenkäynnistyskoodikoodi).näillä termeillä (.text, jne.) ei ole mitään tekemistä mikro-ohjainten kanssa, se on kääntäjä / työkaluketju, joka koskee kaikkia kääntäjien / työkaluketjujen kohteita.päivän päättyessä ohjelmoija päättää, mihin asiat menevät, ja ilmoittaa työkaluketjulle linkkeriskriptin kautta yleensä.
Kolme vastused:
tcrosley
2016-06-02 12:17:35 UTC
view on stackexchange narkive permalink

.text

.text-segmentti sisältää todellisen koodin, ja se on ohjelmoitu mikrokontrollereiden Flash-muistiin. Tekstisegmenttejä voi olla useampi kuin yksi, kun Flash-muistia on useita, ei yhtenäisiä lohkoja; esim. aloitusvektorin ja keskeytysvektorit, jotka sijaitsevat muistin yläosassa, ja koodin, joka alkaa 0: sta; tai erilliset osiot käynnistyshihnalle ja pääohjelmalle.

.bss ja .data

Funktiolle tai menettelylle voidaan jakaa kolmentyyppisiä tietoja; ensimmäinen on alustamaton data (jota kutsutaan historiallisesti .bss: ksi, joka sisältää myös 0 alustettua dataa) ja toinen on alustettu (ei-bss) tai .data. Nimi "bss" tulee historiallisesti nimellä "Symbolin aloittama lohko", jota kokoonpanija käytti noin 60 vuotta sitten. Molemmat alueet sijaitsevat RAM-muistissa.

Ohjelmaa laadittaessa muuttujat varataan yhdelle näistä kahdesta yleisestä alueesta. Linkittämisvaiheen aikana kaikki tietoerät kerätään yhdessä. Kaikilla muuttujilla, jotka on alustettava, on osa ohjelmamuistista, joka on varattu alkuarvojen pitämiseen, ja juuri ennen kuin main () kutsutaan, muuttujat alustetaan, tyypillisesti moduulilla nimeltä crt0. Bss-osa alustetaan kaikille nollille samalla käynnistyskoodilla.

Muutamilla mikro-ohjaimilla on lyhyempiä ohjeita, jotka sallivat pääsyn RAM-muistin ensimmäiselle sivulle (ensimmäiset 256 sijaintia, joskus kutsutaan sivuksi 0). Näiden prosessorien kääntäjä voi varata avainsanan, kuten lähellä , määrittelemään siellä olevat muuttujat. Vastaavasti on myös mikro-ohjaimia, jotka voivat viitata tiettyihin alueisiin vain osoitinrekisterin kautta (vaatii lisäohjeita), ja tällaiset muuttujat nimetään far . Lopuksi jotkut prosessorit voivat osoittaa osan muistista bitti kerrallaan, ja kääntäjällä on tapa määrittää se (kuten avainsana bit ).

Joten saattaa olla muita segmenttejä, kuten .nearbss ja .neardata, jne., joihin nämä muuttujat kerätään.

.rodata

Kolmas funktion ulkopuolinen tietotyyppi tai menettely on kuin alustetut muuttujat, paitsi että se on vain luku -ohjelma eikä ohjelma voi muokata sitä. C-kielellä nämä muuttujat merkitään const -avainsanalla. Ne tallennetaan yleensä osana ohjelman flash-muistia. Joskus ne tunnistetaan osana .rodata (vain luku -tietoja) -segmenttiä. Mikrokontrollereissa, joissa käytetään Harvard-arkkitehtuuria, kääntäjän on käytettävä erityisiä ohjeita näiden muuttujien käyttämiseen.

pino ja kasa

Sekä pino että kasa sijoitetaan RAM. Prosessorin arkkitehtuurista riippuen pino voi kasvaa tai kasvaa. Jos se kasvaa, se sijoitetaan RAM-muistin alaosaan. Jos se kasvaa alas, se sijoitetaan RAM-muistin loppuun. Kasa käyttää jäljellä olevaa RAM-muistia, jota ei ole varattu muuttujille, ja kasvaa pinon vastakkaiseen suuntaan. Pinon ja kasan enimmäiskoko voidaan yleensä määrittää linkkiparametreina.

Pinoon asetetut muuttujat ovat mitä tahansa muuttujia, jotka on määritelty toiminnossa tai menettelyssä ilman avainsanaa static . Niitä kutsuttiin aikoinaan automaattisiksi muuttujiksi ( auto keyword), mutta kyseistä avainsanaa ei tarvita. Historiallisesti auto on olemassa, koska se oli osa C: tä edeltävää B-kieltä, ja siellä sitä tarvittiin. Toimintaparametrit sijoitetaan myös pinoon.

Tässä on tyypillinen RAM-asettelut (olettaen, että ei ole erityistä sivu 0 -osaa):

enter image description here

EEPROM, ROM ja NVRAM

Ennen kuin Flash-muisti tuli, EEPROMia (sähköisesti pyyhittävä ohjelmoitava vain luku -muisti) käytettiin ohjelman ja const-tietojen (.text ja .rodata-segmenttien) tallentamiseen. Nyt käytettävissä on vain pieni määrä (esim. 2 kt - 8 kt tavua) EEPROMia, jos sellaista on ollenkaan, ja sitä käytetään tyypillisesti kokoonpanotietojen tai muiden pienten tietomäärien tallentamiseen, jotka on säilytettävä virrankatkaisun aikana sykli. Näitä ei ilmoiteta muuttujina ohjelmassa, vaan ne kirjoitetaan mikrokontrollerin erityisrekistereihin. EEPROM voidaan myös toteuttaa erillisenä siruna ja käyttää sitä SPI- tai IC-väylän kautta.

ROM on olennaisesti sama kuin Flash, paitsi että se on ohjelmoitu tehtaalla (käyttäjä ei voi ohjelmoida sitä). Sitä käytetään vain erittäin suuren äänenvoimakkuuden omaaville laitteille.

NVRAM (haihtumaton RAM) on vaihtoehto EEPROMille, ja se toteutetaan yleensä ulkoisena IC: nä. Säännöllistä RAM-muistia voidaan pitää haihtumattomana, jos se on varmuuskopioitu paristolla; siinä tapauksessa ei tarvita erityisiä käyttömenetelmiä.

Vaikka tietoja voidaan tallentaa Flashiin, Flash-muistilla on rajallinen määrä pyyhkäisy- / ohjelmakierroksia (1000–10 000), joten sitä ei ole todella suunniteltu siihen. Se vaatii myös muistilohkojen poistamisen kerralla, joten vain muutaman tavun päivittäminen on hankalaa. Se on tarkoitettu koodille ja vain luku -muuttujille.

EEPROMilla on paljon korkeammat poisto- / ohjelmasyklit (100 000 - 1 000 000), joten se on paljon parempi tähän tarkoitukseen. Jos mikro-ohjaimessa on käytettävissä EEPROM ja se on riittävän suuri, sinne haluat tallentaa haihtumattoman datan. Sinun on kuitenkin ensin myös tyhjennettävä lohkoina (yleensä 4 kt) ennen kirjoittamista.

Jos EEPROMia ei ole tai se on liian pieni, tarvitaan ulkoinen siru. 32 kt: n EEPROM on vain 66 ¢ ja se voidaan poistaa / kirjoittaa 1 000 000 kertaa. NVRAM, jolla on sama määrä poisto- / ohjelmatoimintoja, on paljon kalliimpaa (x10) NVRAM-muistia on tyypillisesti nopeampi lukea kuin EEPROM-tiedostoja, mutta hitaammin kirjoitettaessa. Ne voidaan kirjoittaa tavuun kerrallaan tai lohkoina.

Parempi vaihtoehto molemmille on FRAM (ferrosähköinen RAM), jolla on olennaisesti ääretön kirjoitusjakso (100 biljoonaa) eikä kirjoitusviiveitä. . Se on suunnilleen sama hinta kuin NVRAM, noin 5 dollaria 32 kt: lla.

Se oli todella hyödyllinen tieto.Voisitko antaa viitteen selitykseesi?Kuten oppikirjat tai lehdet, jos haluan lukea lisää tästä ..?
vielä yksi kysymys, voisitteko antaa käsityksen yhden muistin eduista tai haitoista toiseen (EEPROM, NVRAM ja FLASH) verrattuna?
Hieno vastaus.Lähetin täydentävän, jossa keskityin tarkemmin siihen, mikä menee minne C-kielellä.
@SojuTVarghese Päivitin vastaukseni ja sisällytin myös joitain tietoja FRAM: sta.
@Lundin käytimme samoja segmenttien nimiä (esim. .Data), joten vastaukset täydentävät toisiaan hienosti.
Kaikki muuttujat, joilla on * staattinen tallennuksen kesto *, alustetaan, mikä sisältää kaikki muuttujat tiedostojen laajuudessa ja sisäisissä toiminnoissa "staattinen" avainsanalla.Joten `.bss` on aina alustettava nollaan.
@starblue Muistan, että käytin Microsoftin Visual C 6.0 -kääntäjää noin 20 vuotta sitten ja että ohjelmassani oli virheitä alustamattomien muuttujien vuoksi.Virheenkorjausrakenne alustaisi kaikki ei-automaattiset muuttujat arvoon 0, mukaan lukien useille tiedostoille määritetyt globaalit muuttujat, mutta julkaisun koontiversio muuttajat alustaisi vain nimenomaisella alustuksella.Erittäin turhauttavaa.
@starblue Luen, että vaatimus kaikkien .bss-segmentin muuttujien alustamisesta tapahtui vasta C89: ssä ja / tai ANSI C: ssä. Vaikka tämä edeltää Visual C: tä useita vuosia, Microsoft oli tunnettu siitä, että se ei ottanut standardeja käyttöönajoissa.Joten sen vuoksi törmäsin tällaiseen käyttäytymiseen, eikä ohjelmoijien tarvitse enää huolehtia siitä.Lisähuomautus on, joskus ihmiset * haluavat *, että jotkut muuttujat ovat alustamattomia;esimerkiksi paristovarmennettu RAM, jossa muuttujat haluavat pysyä samana palautuksen aikana.Yleensä voit tehdä sen asettamalla ne nimettyyn segmenttiin.
@tcrosley Voi myös tapahtua, että muuttujat asetetaan * ennen * koodin `.data` ja` .bss` alustamista varten, ja pyyhkiytyvät sitten alustamalla.Esimerkiksi tämä on tapahtunut meille ARM Cortex-M -ohjaimien muuttujan `SystemCoreClock` kanssa.Se on asetettava erityiseen osaan alustamisen välttämiseksi.
Lundin
2016-06-02 13:31:16 UTC
view on stackexchange narkive permalink

Normaali sulautettu järjestelmä:

  Segmentoi muistin sisältö.data RAM Alustetut muuttujat nimenomaisesti staattisella tallennuksen kestolla. bbs RAM Nolla-alustetut muuttujat staattisella tallennustilalla duration.stack RAM Paikalliset muuttujat ja toimintokutsuparametrit. kasaan RAM-muistia Dynaamisesti varatut muuttujat (ei yleensä käytetä sulautetuissa järjestelmissä) .data-ROM-muuttujat, joilla on staattinen tallennuksen kesto. Merkkijononoppaat..teksti ROM Ohjelma. Kokonaisvakiot. Alustusluettelot.  

Lisäksi käynnistyskoodille ja keskeytysvektoreille on yleensä erilliset flash-segmentit.


Selitys:

Muuttujalla on staattinen tallennuksen kesto, jos se ilmoitetaan staattisena tai jos se sijaitsee tiedoston laajuudessa (joskus hitaasti kutsutaan "globaaliksi"). C: llä on sääntö, jonka mukaan kaikki staattisen tallennuksen kestomuuttujat, joita ohjelmoija ei nimenomaan alustanut, on alustettava nollaan.

Jokainen staattisen tallennustilan kestomuuttuja, joka alustetaan nollaksi, implisiittisesti tai eksplisiittisesti, päätyy kohtaan .bss . Ne, jotka nimenomaisesti alustetaan muuhun kuin nolla-arvoon, päätyvät kohtaan .data.

Esimerkkejä:

  staattinen int a; // .bssstatic int b = 0; // .bss int c; // .bssstatic int d = 1; // .tiedot e = 1; // .datavoid func (void) {staattinen int x; // .bss staattinen int y = 0; // .bss staattinen int z = 1; // .data staattinen int * ptr = NULL; // .bss}  

Pidä mielessä, että upotettujen järjestelmien hyvin yleisessä epätyypillisessä asennuksessa on oltava "minimaalinen käynnistys", mikä tarkoittaa, että ohjelma ohittaa staattisesti tallennetun objektin kaikki alustuksen kesto. Siksi saattaa olla viisasta olla koskaan kirjoittamatta ohjelmia, jotka perustuvat tällaisten muuttujien alustusarvoihin, vaan asettavat ne "ajoaikaan" ennen niiden ensimmäistä käyttöä.

Esimerkkejä muista segmenteistä :

  const int a = 0; // .rodataconst int b; // .data (hölynpölykoodi, mutta C sallii sen, toisin kuin C ++) staattinen const int c = 0; // .rodatastaattinen vakio int d = 1; // .rodatavoid func (int param) // .pino {int e; // .pino int f = 0; //. pino int g = 1; // .pino const int h = param; // .pinoa staattinen const int i = 1; // .data, staattisen tallennuksen kesto char * ptr; // ptr menee .pino ptr = malloc (1); // huomautettu muisti menee .heap}  

Pinoon voi siirtyä muuttujia, jotka saattavat usein päätyä CPU-rekistereihin optimoinnin aikana. Nyrkkisääntönä kaikki muuttujat, joiden osoitetta ei ole otettu, voidaan sijoittaa CPU-rekisteriin.

Huomaa, että osoittimet ovat hieman monimutkaisempia kuin muut muuttujat, koska ne sallivat kaksi erilaista const -tyyppiä riippuen siitä, pitäisikö teräväpiirtotietojen olla vain luku -tilassa vai jos osoittimen itsensä pitäisi olla. On erittäin tärkeää tietää ero, jotta osoitimesi eivät päädy RAM-muistiin vahingossa, kun halusit niiden olevan flash-tilassa.

  int * j = 0; // .bssconst int * k = 0; // .bss, ei-const-osoitin const-dataan * const l = 0; // .data, const-osoitin ei-const-datakohtaiseen int * const m = 0; // .data, const-osoitin const datavoidiin (* fptr1) (mitätön); // .bssvoid (* const fptr2) (mitätön); // .rodatavoid (const * fptr3) (mitätön); // virheellinen, ei ole järkevää, koska toimintoja ei voi muokata

Jos kyseessä ovat kokonaisluvut, alustusluettelot, merkkijono-literaalit jne., ne voivat päätyä joko .text- tai .rodata-tiedostoihin kääntäjän mukaan. Todennäköisesti ne päätyvät seuraavasti:

  #define n 0 // .textint o = 5; // 5 siirtyy .text (osa käskyä) int p [] = {1,2,3}; // {1,2,3} menee .textchar q [] = "hei"; // "hei" menee hakemistoon .rodata  
En ymmärrä ensimmäisessä esimerkkikoodissasi, miksi 'staattinen int b = 0;'menee .bss: ään ja miksi 'staattinen int d = 1;'menee .data ..?Ymmärtääkseni molemmat ovat staattisia muuttujia, jotka ohjelmoija on alustanut .. mitä sitten ero tekee?@Lundin
@SojuTVarghese Koska .bss-tiedot alustetaan nollaksi lohkona;tietyt arvot, kuten d = 1, on tallennettava salamavaloon.
@SojuTVarghese Lisäsi selvennystä.
@Lundin Tarkoittaako viimeisestä esimerkkikoodistasi myös sitä, että kaikki alustetut arvot menevät .text- tai .rodata-tiedostoihin ja niiden muuttujat yksinään .bss- tai .data-tietoihin?Jos on, miten muuttujat ja niitä vastaavat arvot kartoitetaan toisiinsa (ts. .Bss / .data- ja .text / .rodata-segmenttien väliin)?
@SojuTVarghese Ei, `.data` -laitteessa on tyypillisesti ns. Flash-osoite, johon alkuperäiset arvot on tallennettu, ja ns. Virtuaalinen osoite (ei oikeastaan virtuaalinen mikrokontrollerissa) RAM-muistissa, johon muuttuja tallennetaan suorituksen aikana.Ennen `pää`-aloitusta alkuperäiset arvot kopioidaan latausosoitteesta virtuaaliosoitteeseen.Sinun ei tarvitse tallentaa nollia, joten `.bss` ei tarvitse tallentaa alkuperäisiä arvoja.https://sourceware.org/binutils/docs/ld/Output-Section-LMA.html#Output-Section-LMA
"const int h = 1; // .pino staattinen const int i = 1;// .rodata, staattinen tallennuksen kesto ". Tarkoittaako funktion laajuus const menee Ramiin eikä Romiin?
@AkshayImmanuelD Yleensä se voi vaihdella työkaluketjujen välillä.Oletan, että se tarkoittaa pikemminkin, ettet voi _ olettaa, että se päätyy ROM-levylle.Jos sen arvo riippuu parametreista, se päätyy varmasti RAM-muistiin.Minun pitäisi selventää esimerkkiä.
Mistä sait tämän taulukon "Segmentti / Muisti / Sisältö"?
@DannyS Kirjoitin sen itse?
Miksi kokonaislukujen alustusohjelmat eivät myöskään mene hakemistoon ".rodata"?Ymmärrän, että se on kääntäjän tehtävä, mutta miksi esimerkkikääntäjä voisi valita ".text" intoille mutta ".rodata" merkkijono-literaaleille?
@RastaJedi Kuten olen kirjoittanut, se on hieman yksinkertaistettu, koska mihin vakiot päätyvät, riippuu suuresti optimointiasetuksista.Kokonaisvakiot päätyvät usein `.tekstiin ', koska ne ladataan itse konekoodiin.Tämä osa riippuu enemmän kääntäjistä / linkkeristä kuin muut.
Hyvää tietoa!- Näen useaan otteeseen viittaavan "haihtumattomaan" kommenteissa, mutta ei yhtään "haihtuvaan".mikä muistiosio sisältäisi muuttujia, joita on muokattu sanalla `volatile`
@ryyker Sekoitat kaksi erilaista käsitettä.Haihtumaton muisti (NVM) on sähköinen termi fyysisille muisteille, jotka eivät menetä tietojaan, kun syöttöjännite poistetaan, kuten EEPROM ja Flash."Haihtuva" avainsana C-kielellä tarkoittaa muuttujaa, jota voidaan muuttaa milloin tahansa ulkoisista lähteistä.Mikä tahansa muuttuja voi olla "haihtuvan" pätevyys riippumatta sen tyypistä, kytkennästä tai paikasta.
Neil_UK
2016-06-02 12:19:34 UTC
view on stackexchange narkive permalink

Vaikka mitä tahansa tietoa voi mennä mihin tahansa ohjelmoijan valitsemaan muistiin, järjestelmä toimii yleensä parhaiten (ja se on tarkoitettu käytettäväksi), missä tietojen käyttöprofiili sovitetaan muistin luku- / kirjoitusprofiileihin.

Esimerkiksi ohjelmakoodi on WFRM (kirjoita muutama lukenut useita), ja sitä on paljon. Tämä sopii FLASHiin hienosti. ROM OTOH on W kerran RM.

Pino ja kasa ovat pieniä, lukemisen ja kirjoittamisen kanssa paljon. Se sopisi RAM-muistiin parhaiten.

EEPROM ei sovi kumpaankaan näistä käyttötarkoituksista, mutta se sopii pienen tietomäärän profiiliin, joka pysyy jatkuvasti käynnistyksen aikana, joten käyttäjäkohtaiset alustustiedot ja ehkä lokitulokset.



Tämä Q & A käännettiin automaattisesti englanniksi.Alkuperäinen sisältö on saatavilla stackexchange-palvelussa, jota kiitämme cc by-sa 3.0-lisenssistä, jolla sitä jaetaan.
Loading...