Küsimus:
Miks ei saa ma PROGMEM-iga massiivi asemel osutada?
Cybergibbons
2014-03-05 17:52:45 UTC
view on stackexchange narkive permalink

Ma muudan praegu mõnda teeki, et stringide salvestamiseks kasutada RAM-i asemel välklampi, et projektil SRAM-i otsa ei saaks.

Mõned teegi stringid deklareeritakse järgmiselt:

  const char * testStringA = "ABC";  

See erineb sellest, kuidas ma seda tavaliselt näen:

  const char testStringB [] = "DEF";  

Kuid arvan, et need kaks on samaväärsed, kui deklareeritakse const ja initsialiseeritakse deklaratsioonis. Mõlemad toimivad koodis hästi.

Püüdsin neid vilkuma viia:

  const prog_char * testStringC PROGMEM = "GHI";  

siis leidsin, et see ei toimi. See tootis printimisel gobbledegooki.

Kuid järgides tavapärasemat mustrit:

  const prog_char testStringD [] PROGMEM = "JKL";  

töötab hästi.

Näen lahtivõtmisel:

  00000068 <testStringC>: 68: 04 01 ..0000006a <_ZL11testStringD>: 6a: 4a 4b 4c 00 JKL.  

Seega on selge, et kursori ja programmi PROGMEM tulemuseks on stringi / massiivi initsialiseerimine.

Miks see nii on?

Näide kood:

  #include <avr / pgmspace.h>const int BUFFER_LEN = 20; const char * testStringA = "ABC"; const char testStringB [] = "DEF"; const prog_char * testStringC PROGMEM = GHI "; const prog_char testStringD [] PROGMEM =" JKL "; tühine seadistamine () {Serial.begin (9600);} void loop () {char buffer [BUFFER_LEN]; Serial.println (testStringA); Serial.println (testStringB); strncpy_P (puhver, testStringC, BUFFER_LEN); Serial.println (puhver); strncpy_P (puhver, testStringD, BUFFER_LEN); Serial.println (puhver); viivitus (1000);}  
Kaks vastused:
#1
+7
zmo
2014-03-05 19:10:12 UTC
view on stackexchange narkive permalink

Noh, sellele küsimusele on targalt vastatud vastuses virna ületäitumise küsimusele C: erinevused sümboli kursori ja massiivi vahel. millega te deklareerite kui PROGMEM,

  const prog_char testStringD [] PROGMEM = "JKL";  

on nii massiiv kui ka mälu, mida see osutab ehk massiivi elementidele, nii praeguse haardeüles. Koos:

  const prog_char * testStringC PROGMEM = "GHI";  

deklareerite PROGMEM-i kursori konstantseks stringiks, mis võib jääda mujale mällu, kuid pole deklareeritud stringina PROGMEM.

Kuigi ma seda ei testinud, peaksite proovima deklareerida:

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

teravneva stringi tegelikuks jaotamiseks ruumi PROGMEM. Ma arvan, et see peaks töötama, kasutades Arduino makrot F () , mis lisab palju katlakoodi, et tegelikult saada sama tulemus kui massiivi deklaratsioon.

Nagu kommentaarides öeldud, kui mitte globaalses kontekstis, võiks F () asemel kasutada makrot PSTR () makro.

Parem on lihtsam: kasutage massiivdeklaratsiooni, mitte kursori!

Vt see teine ​​vastus, __flash kvalifikatsioon on kolmas lahendus ;-)

Olen täiesti nõus arvamusega, et "lihtsam on parem" - massiiv on palju selgem. Mul on alati alati huvi, kui midagi pole kohe ilmne.
F () tagastab FlashStringHelperi, mis on sisuliselt sama, kuid PSTR () kasutamine töötab hästi (seni, kuni konstruktsioonid funktsiooni sisse viiakse).
tõepoolest, tegelikult soovitasin kõigepealt makrot `PSTR ()`, kuid muutsin enne esitamist väärtuseks `F (), sest teie konst on teie Q-s globaalne, seega eelistasin jääda sellele, mis peaks mõlemas kontekstis töötama.
#2
+3
Ignacio Vazquez-Abrams
2014-03-05 19:07:27 UTC
view on stackexchange narkive permalink

Mida see rida teeb:

  const prog_char * testStringC PROGMEM = "GHI";  

tähendab proloogikoodi kirjutamist string SRAM-ile ja seejärel lähtestatakse välklambi salvestatud pointer sellesse SRAM-i asukohta. Peate laadima kursori tavalisel viisil ja seejärel viima kursori tavapärasel viisil kõrvale.

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

See rida:

  const prog_char testStringD [] PROGMEM = "JKL";  

loob tähemassiivi välklambiga, mis võimaldab teil sellele ootuspäraselt juurde pääseda.



See küsimus ja vastus tõlgiti automaatselt inglise keelest.Algne sisu on saadaval stackexchange-is, mida täname cc by-sa 3.0-litsentsi eest, mille all seda levitatakse.
Loading...