Problema con F() e goto

Rieccomi con un paio di domandine:

Ho bisogno di saltare direttamente da una funzione al loop principale, inizialmente pensavo di usare il goto ma non funziona fra funzioni diverse. Sapreste suggerirmi un’alternativa?

Leggevo che se aggiungo F() mi salva la stringa sulla flash e non m’intasa la RAM. Pensavo di applicarla alla variabile String universalStringOUT. Utilizzo la variabile String universalStringOUT come tramite fra le varie funzioni e ciò che viene visualizzato sull’lcd. Ecco la riga di codice che mi da errore:

lcd.print(F(universalStringOUT));

Ecco invece che errore mi da:

Arduino:1.6.3 (Windows 8.1), Scheda:“Arduino Due (Programming Port)”

error: invalid cast from type ‘String’ to type ‘const __FlashStringHelper*’

#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))

^
note: in expansion of macro ‘F’

Errore durante la compilazione

Sapreste aiutarmi? Grazie =)

Prova a pensarci, se una stringa viene memorizzata nella flash, e non può essere spostata nella RAM, come può essere modificata? F([String]) vale solo per le costanti.

F("Testo fisso che non cambia nel tempo")

Quello che serve a te è una variabile globale, che sia accessibile da tutte le funzioni dello sketch. Basta dichiararla prima del setup().

Il problema è con il goto in sé: non si usa, punto. Esci prima dalla tua funzione e propaga un'eventuale condizione di uscita verso l'alto finché non torni a loop().

Per uscire da una funzione usa return(). Lo sketch continuerá dopo la chiamata della funzione da cui si ritorna. Ciao Uwe

Per saltare da una funzione molto annidata al suo parent si usa la setjmp(), tale tecnica è pericolosa se non si sa quello che si sta facendo, è anche l'unica che ottimizza tale processo e lo semplifica esponenzialmente. Per allocare memoria nella flash bisogna dichiarare la variabile come PROGMEM.

vbextreme: Per allocare memoria nella flash bisogna dichiarare la variabile come PROGMEM.

Sicuro che PROGMEM sia supportata da Arduino DUE ? ... perché a vedere dalla compilazione, lui ha una DUE ... ::)

Guglielmo

P:S: Se ben ricordo NON si può usare né la PROGMEM (che usa avr/pgmspace e che è per AVR), né la macro F ;) P.P.S: piccolo modo per aggirare il problema QUI :D

ops, non conosco la due, ma non può leggere dalla flash? non ho letto il datasheet. acciderbolona!

Si, può leggere e scrivere sulla flash in qualunque punto del programma

pablos: Si, può leggere e scrivere sulla flash in qualunque punto del programma

... e quindi perché non esiste un porting della PROGMEM né della macro F() ? ? ? Non credo per mancanza di volontà ... ci deve essere qualche cosa sotto ::)

Guglielmo

https://github.com/sebnil/DueFlashStorage

http://forum.arduino.cc/index.php?topic=259357.0

... frena Pablos ... NON mi interessa la EEPROM, stiamo parlando della PROGMEM che è tutt'altra cosa !!! ;D

In fase di COMPILAZIONE devi mettere le costanti nella memoria Flash e poi ... devi poterle usare da programma ... ben diverso da quello che fa la libreria che hai indicato e il thread linkato ;)

Io invece ho trovato un'interessante discussione QUI ... ... è relativa alla Teensy3, ma i concetti sono gli stessi :)

Guglielmo

praticamente sulla due basta "const" per finire in un'area di sola lettura s quindi in flash giusto?

vbextreme: praticamente sulla due basta "const" per finire in un'area di sola lettura s quindi in flash giusto?

... c'è da fare un po' di prove ::)

L'amante della DUE è Pablos ... a lui divertircisi :D :D :D

Guglielmo

Quella libreria è semplice, in realtà l'ho definita io eeprom virtuale dato che il sam3x non ha eeprom. Non si chiama Progmem e non l'ho scritto, si chiama DueFlashStorage.

Vanno creati degli indici ben precisi per risalire alla parola o alla frase, io l'ho usata per salvare 8000 +/- byte caricati da un file txt su SD, diciamo una prima installazione che prende la configurazione hardware da un file.

Il vantaggio che mi da questa lib e la DUE rispetto al progmem è che quelle posizioni flash possono essere cambiate durante il run del chip, mentre il progmem sull'AVR scrive solo su compilazione, anzi non è possibile proprio scrivere sulla flash del 328/2560 durante l'esecuzione del programma, forse si può con un bootloader modificato, ma io non sono in grado di toccare un bootloader

pablos: Il vantaggio che mi da questa lib e la DUE rispetto al progmem è che quelle posizioni flash possono essere cambiate durante il run del chip ...

... si, va bene, ma non è il concetto di PROGMEM di cui stiamo discutendo.

Hai provato a dare un'occhiata a quel thread sulla Teeny3 che ho linkato ?

Guglielmo

Ah pensavo parlassimo di F() inteso come funzione Flash... Sì io clicco tutti i link l'ho visto ma non ho approfondito .. Dopo leggo meglio

Per tornare alla domanda:

lascia perdere il goto e struttura diversamente il programma

metti i return e gioca di IF, WHILE, ... frammenta le funzioni, ... dipende.

vbextreme: praticamente sulla due basta "const" per finire in un'area di sola lettura s quindi in flash giusto?

Sembrerebbe sensato, essendo questa una delle ragioni per cui la keyword const è stata introdotta nel C. A leggere dalla scheda prodotto, poi, sulla Due:

All the available memory (Flash, RAM and ROM) can be accessed directly as a flat addressing space.

Cosa che vorrebbe dire che l'implementazione di ciò è estremamente banale. In ogni caso, se non hanno definito le macro di compatibilità per fare almeno in ogni caso compilare il codice, questo sicuramente sarebbe da sistemare, IMHO.

Comunque, alla fine dei conti, la Due ha tanta RAM quanta ne hanno 12 Mega (o 48 Uno!), per cui forse nella maggior parte dei casi si può evitare di farsi troppi problemi con questa scheda, almeno in questo senso :).

Grazie mille a tutti, in questi giorni vedo di seguire i vostri consigli e, nel caso non mi venisse qualcosa, vi scriverò nuovamente qui. :slight_smile:

brioches95

SukkoPera: Sembrerebbe sensato, essendo questa una delle ragioni per cui la keyword const è stata introdotta nel C. A leggere dalla scheda prodotto, poi, sulla Due:

La keyword "const" esiste fin dalla prima comparsa del C, è citata anche nel K&R, non ha nulla a che vedere con il concetto di memoria flash, sopratutto non ha nulla a che vedere con l'architettura Harvard, modificata o meno, usata in quasi tutte le mcu che è la "causa" primaria dei problemi di memoria. :) In alcuni compilatori C/C++ per mcu, p.e. quelli di Microchip, è stata introdotta la keyword "rom" che dice al compilatore di porre il dato indicato nella flash, ovviamente è una costante. Dato che la DUE usa un processore SAM3 con core ARM, che non ha nulla a che vedere con gli AVR, sarebbe il caso di verificare se esiste la direttiva "rom" nel suo compilatore. Pensare di fare il porting di progmem su un ARM è volersi fare del male da solo, oltretutto progmem è decisamente poco efficiente, però la colpa è degli AVR e non del codice, sugli ARM usare la flash come pseudo memoria ram, scrivibile a run time, è possibile, un esempio è il programma che permette di usare una porzione della flash in emulazione EEPROM.