Kysymys:
Miksi en voi käyttää osoittimia matriisin sijaan PROGMEM: in kanssa?
Cybergibbons
2014-03-05 17:52:45 UTC
view on stackexchange narkive permalink

Muutan tällä hetkellä joitain kirjastoja käyttämään flash-muistia merkkijonotallennuksen RAM-muistin sijaan, jotta SRAM ei loppu projektissa.

Jotkin kirjaston merkkijonot ilmoitetaan tällä tavalla:

  const char * testStringA = "ABC";  

Tämä eroaa tavallisesti siitä, miten tämä tehdään:

  const char testStringB [] = "DEF";  

Luulen kuitenkin, että nämä kaksi ovat vastaavia, kun ne julistetaan const ja alustetaan ilmoituksessa. Molemmat toimivat hyvin koodissa.

Yritin siirtää nämä vilkkumaan:

  const prog_char * testStringC PROGMEM = "GHI";  

Huomasin sitten, että tämä ei toiminut. Se tuotti gobbledegookia tulostettaessa.

Noudattamalla kuitenkin tavallisempaa mallia:

  const prog_char testStringD [] PROGMEM = "JKL";  

toimii hyvin.

Voin nähdä purkamisen:

  00000068 <testStringC>: 68: 04 01 ..0000006a <_ZL11testStringD>: 4a: 4a JKL.  

Joten on selvää, että osoitin ja PROGMEM johtavat siihen, että merkkijonoa / taulukkoa ei alusteta.

Miksi tämä on?

Esimerkki koodi:

  #include <avr / pgmspace.h>const int BUFFER_LEN = 20; const char * testStringA = "ABC"; const char testStringB [] = "DEF"; const prog_char * testStringC PROG GHI "; const prog_char testStringD [] PROGMEM =" JKL "; mitätön asennus () {Serial.begin (9600);} void loop () {char puskuri [BUFFER_LEN]; Serial.println (testStringA); Serial.println (testStringB); strncpy_P (puskuri, testStringC, BUFFER_LEN); Serial.println (puskuri); strncpy_P (puskuri, testStringD, BUFFER_LEN); Serial.println (puskuri); viive (1000);}  
Kaksi vastused:
#1
+7
zmo
2014-03-05 19:10:12 UTC
view on stackexchange narkive permalink

No, tähän kysymykseen on vastattu viisaasti vastauksessa pinon ylivuotokysymykseen C: erot hiiriosoittimen ja taulukon välillä .

Pohjimmiltaan mitä ilmoitat PROGMEMiksi,

  const prog_char testStringD [] PROGMEM = "JKL";  

on sekä matriisi että sen osoittama muisti eli matriisin elementteihin, molemmat nykyisen laajuuden pinossa. Kun: mutta ei ilmoitettu PROGMEM-merkkijonoksi.

Vaikka en testannut sitä en , mutta sinun on yritettävä julistaa:

  const prog_char * testStringC PROGMEM = F ("GHI");  

kohdistaa terävä merkkijono PROGMEM-tilaan. Luulen , että sen pitäisi toimia, käyttämällä Arduinon F () -makroa, joka lisää paljon kattilakoodia saadakseen saman tuloksen kuin taulukon ilmoitus.

Kuten kommenteissa todettiin, ellei globaalissa kontekstissa, makroa PSTR () voitaisiin käyttää F () -mallin sijasta. makro.

Yksinkertaisempi on parempi: käytä taulukkoilmoitusta, älä osoitinta!

Vrt. tuo toinen vastaus, __flash karsinta on kolmas ratkaisu ;-)

Olen täysin samaa mieltä siitä, että "yksinkertaisempi on parempi" - taulukko on paljon selkeämpi. Minua kiinnostaa aina, kun jokin ei ole heti ilmeinen.
F () palauttaa FlashStringHelperin, joka on olennaisesti sama, mutta PSTR (): n käyttö toimii hyvin (niin kauan kuin tuodaan muodot funktion sisälle).
Itse asiassa ehdotin ensin `` PSTR () '' -makroa, mutta muutin muotoon `F () 'ennen lähettämistä, koska teidän kongisi ovat globaaleja Q: ssanne, joten halusin pitää kiinni siitä, jonka pitäisi toimia molemmissa yhteyksissä.
#2
+3
Ignacio Vazquez-Abrams
2014-03-05 19:07:27 UTC
view on stackexchange narkive permalink

Tämä rivi:

  const prog_char * testStringC PROGMEM = "GHI";  

tarkoittaa prologikoodin kirjoittamista merkkien kopioimiseksi merkkijono SRAM-muotoon ja alustaa sitten flash-muodossa tallennetun osoitin tälle SRAM-sijainnille. Sinun on ladattava osoitin tavanomaisin keinoin ja poista sitten osoitin tavalliseen tapaan.

  const char * str = pgm_read_word (&testStringC); Serial.println (str);  

Tämä rivi:

  const prog_char testStringD [] PROGMEM = "JKL";  

luo merkkiryhmän flash-muodossa, jolloin voit käyttää sitä odotetulla tavalla.



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...