Newsgroup: it.comp.lang.c
Titolo: Compilatore C "elementare" per disabilitare ottimizzazioni interne

Ciao NG
Sono alle prese con la programmazione di un
microcontrollore ATMEL, che ha la sua versione di Gcc. Il
codice sul PC gira benissimo, ma quando lo carico sul
controllore si pianta. Ho controllato il controllabile;
gcc al massimo dei warning richiesti non ne emette manco
uno, e mi pare di aver capito che si tratta di un indice o
un puntatore fuori range perché modifica delle variabili
che sono sempre inizializzate a zero. Ma sul PC non lo fa,
sul controllore sì.
Potrebbe darsi che cgg faccia tante di quelle
ottimizzazioni da cambiare qualche tipo internamente; che
so, da unsigned a signed o altro, e che queste
ottimizzazioni siano così profonde da non poter essere
disabilitate. Potrebbe darsi che una di queste
ottimizzazioni faccia sì che il problema non si presenti.
Esiste un complilatore c come dire, rozzo, che una volta
che siano state disabilitate le ottimizzazioni, mi possa
provocare il tanto desiderato malfunzionamento sul PC,
così almeno capisco che sta succedendo?
Ovviamente altre possibilità sono benvenute, ma non vorrei
andare troppo OT.
grazie!
Apx.
-- 
Gli statistici probabilmente lo fanno.
Gli algebristi lo fanno in gruppo.
(I logici lo fanno) or [not (i logici lo fanno)].
Moebius l'ha sempre fatto sullo stesso lato.

 così almeno capisco che sta succedendo?
Dai un occhiata al manuale del gcc che viene con atmel.
Probabile che tu possa produrre codice non ottimizzato con
gcc -O0
Ciao

 ottimizzato con gcc -O0
Grazie infinitissime! Spero di risolvere e ti sarò molto
debitore :)


Il 31/08/2010 18.13, Agriturismo "La calendula seviziata" SnC ha scritto:
 > Ciao NG
 >
 > Sono alle prese con la programmazione di un
 > microcontrollore ATMEL, che ha la sua versione di Gcc. Il
 > codice sul PC gira benissimo, ma quando lo carico sul
 > controllore si pianta. Ho controllato il controllabile;
 > gcc al massimo dei warning richiesti non ne emette manco
 > uno, e mi pare di aver capito che si tratta di un indice o
 > un puntatore fuori range perché modifica delle variabili
 > che sono sempre inizializzate a zero. Ma sul PC non lo fa,
 > sul controllore sì.
 >
Su che microcontrollore lavori?
Hai fatto il debug con il simulatore?
Tieni presente che i pc sono a 32-64bit mentre i microcotroller sono 
solitamente a 8-16 bit. Si possono incappare in while infiniti e/o for 
infiniti.
In più ricordati che le variabili int cambiano di dimensione in base 
all'architettura.
Anche io ho scritto molto codice con gcc e non ho mai avuto problemi di 
questo tipo.
Sono anni che non li uso più ma mi ricordo che potevo caricare nel 
simulatore direttamente il codice compilato per il debug.
Era molto comodo!
Ciao

 Ciao
Il controllore è Atmega1284p e purtroppo non ho il
simulatore hardware. Io faccio solo una parte del software
che è molto isolata dal resto e si interfaccia con una
sola struttura al resto del software, bootloader e altro.
Sono abbastanza sicuro che sia un puntatore cannato. Se
inserisco un campo nella struttura appena prima di quello
insozzato, insozza quello precedente lasciando a zero
quello che prima veniva cambiato. Il problema è che se sul
PC con gcc i tipi cambiano, o chi sa per quale altra
ragione, sul PC tutto va a posto, gli "assert" non sforano
mai, eccetera. Non so più a che santo votarmi perché ho
due compilatori che fanno cose diverse e non ho
nessunissimo strumento di debug sul controllore. Posso
solo vedere sul display una variabile per volta, e per
giunta chiedendo ogni volta ai miei colleghi se mi fanno
vedere questo o quello. Io di controllori e hardware so
zero assoluto...
ciao!


 >
 > Il controllore è Atmega1284p e purtroppo non ho il
 > simulatore hardware. Io faccio solo una parte del software
 > che è molto isolata dal resto e si interfaccia con una
 > sola struttura al resto del software, bootloader e altro.
 >
 > Sono abbastanza sicuro che sia un puntatore cannato. Se
 > inserisco un campo nella struttura appena prima di quello
 > insozzato, insozza quello precedente lasciando a zero
 > quello che prima veniva cambiato. Il problema è che se sul
 > PC con gcc i tipi cambiano, o chi sa per quale altra
 > ragione, sul PC tutto va a posto, gli "assert" non sforano
 > mai, eccetera. Non so più a che santo votarmi perché ho
 > due compilatori che fanno cose diverse e non ho
 > nessunissimo strumento di debug sul controllore. Posso
 > solo vedere sul display una variabile per volta, e per
 > giunta chiedendo ogni volta ai miei colleghi se mi fanno
 > vedere questo o quello. Io di controllori e hardware so
 > zero assoluto...
Di che periferiche hw hai bisogno?
cose molto particolari ?
Io usavo il simulatore software fornito dall'atmel
http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2725
e mi debuggavo le variabili.
Adesso non ricordo più come si faceva ma producevi con il compilatore 
qualcosa tipo ciff. Quando lo aprivi di la ti veniva fuori il codice c.
Adesso non mi ricordo più ma se googli un po' trovi la modalità per 
farti sparare fuori il file in formato giusto per lavorarci.
Ti copi solo il pezzo di codice che ti da problemi e vai di simulatore.
Io toglievo tutte le funzioni che lavoravano con l'io e le simulavo a mano.
CIAO

 > Il controllore è Atmega1284p e purtroppo non ho il
 > simulatore hardware. Io faccio solo una parte del software
 > che è molto isolata dal resto e si interfaccia con una
 > sola struttura al resto del software, bootloader e altro.
 >
 > Sono abbastanza sicuro che sia un puntatore cannato. Se
 > inserisco un campo nella struttura appena prima di quello
 > insozzato, insozza quello precedente lasciando a zero
 > quello che prima veniva cambiato. Il problema è che se sul
 > PC con gcc i tipi cambiano, o chi sa per quale altra
 > ragione, sul PC tutto va a posto, gli "assert" non sforano
 > mai, eccetera. Non so più a che santo votarmi perché ho
 > due compilatori che fanno cose diverse e non ho
 > nessunissimo strumento di debug sul controllore. Posso
 > solo vedere sul display una variabile per volta, e per
 > giunta chiedendo ogni volta ai miei colleghi se mi fanno
 > vedere questo o quello. Io di controllori e hardware so
 > zero assoluto...
 >
 > ciao!
 >
 > Apx.
 >
Ma come lo programmi? JTAG?

 così almeno capisco che sta succedendo?
se stai usando questo 
http://winavr.sourceforge.net/
penso sia buono per i tuoi scopi. Consulta la documentazione
prima di fare qualsiasi assunzione che esuli dallo Standard.
Non posso aiutarti sulla programmazione di microcontrollori,
non è il mio campo, piuttosto sul codice C che hai scritto.
-- 
Vincenzo Mercuri

 codice C che hai scritto.
Mi accodo qua per altre info (sono sempre io, ovvero questo sono davvero
io e la calendula è uno dei miei personaggi).
Anzitutto: disgraziatamente e sventuratamente sviluppo sotto win. I miei
colleghi usano linux e mi "tollerano" così :) perché ancora non c'è
stato modo per me di avere quella confidenza con linux necessaria a un
progetto (per le cose di tutti i giorni lo saprei usare...).
Secondo poi, mi sono già scontrato con i problemi dei tipi. Fin dai
primi giorni mi è stato detto di programmare esclusivamente con
"uint16_t", 8, 32 e via dicendo. Mi sono anche scontrato con problemi di
instabilità numerica di uno sviluppo in serie e ho imparato in
quell'occasione, di fare esplicitamente ogni conversione ad esempio tra
dividendo e divisore, per evitare over/underflow e poi, sapendo per
esempio che il risultato per forza entra in un tipo più piccolo,
convertire esplicitamente l'assegnazione. Le operazioni numeriche sono
confinate in pochissime routines di basso livello chiamate a man bassa,
quindi sarei sorpreso se i problemi fossero lì.
Per quanto sopra dubito che ci possano essere overflow che portano a
loop senza uscita. Il fatto è che viene sporcato un campo specifico (e
probabilmente altri) perché se ne metto uno prima, si sporca quello,
come dicevo prima.
Per problemi di porte, timers, e altre cose molto legate all'hardware e
che non ho capito, quel che accade sul compilatore AVR - che ho e uso
per controllare la compilazione sul controllore prima di passare i
sorgenti ai colleghi - non accade sul microcontrollore e viceversa. Mi
hanno detto di non contare troppo sul compilatore AVR ai fini del debug;
relata refero.
Ovviamente fin da subito ho sviluppato con -Wall e altre opzioni che
controllano le assegnazioni e conversioni (a quanto pare -Wall non dà
proprio tutti ma tutti i warning). Gli unici che ricevevo erano di
strutture annidate una nell'altra. Abituato al C++ le usavo per
questioni di leggibilità, e adesso che le ho elmininate non c'è nemmeno
un warning in nessuno dei compilatori, sia GCC che quello nativo
dell'atmel. Sul PC ho testato il codice in modo molto approfondito e
funziona come è previsto funzioni.
Per questo non saprei proprio qual è la parte critica. Sono 500 k di C e
a questo punto è come cercare un ago in un pagliaio.
Purtroppo quel che posso dire di questa faccenda finisce qua. Io devo
fare una parte molto "isolata" che ha bisogno solo di conoscere il
valore di un tempo in secondi, e un solo dicasi un solo parametro
fornito da un sensore. Per questo non sono mai stato costretto a
interessarmi dell'hardware che del resto non è il mio campo. L'unica
soluzione che intravedevo (e non so se avrebbe funzionato) è, appunto,
un compilatore che non faccia ottimizzazioni e se gli dico "uint8_t",
non me lo porti a un intero a 32 bit perché tale è la lunghezza della
parola sul processore del PC :/ O cose simili.
Probabilmente sarà qualche conversione di puntatore ma non so nemmeno da
dove iniziare a cercare...
grazie per ora a tutti voi!
Apx.

 "uint16_t", 8, 32 e via dicendo. Mi sono anche scontrato con problemi di
Ovviamente leggasi anche "int?", ovviamente se un intero ha segno uso il 
tipo che serve! :)

 parola sul processore del PC :/ O cose simili.
come già detto, il rischio delle conversioni c'è quando si fanno
operazioni aritmetiche con tipi interi misti per esempio, indipendente-
mente dalle ottimizzazioni. Nessuna ottimizzazione al mondo è autoriz-
zata a fare 'giochi' alle tue spalle che non siano previsti dal comporta-
mento designato dallo Standard riguardo alle conversioni implicite di
tipo. Sicuramente il consiglio di usare uint8_t al posto di (ad es.)
unsigned char (ad es.) è validissimo, in quanto i tipi intN_t e uintN_t
garantiscono che vengano usati effettivamente N bits e che vengano usati
tutti (sembra strano, ma un generico tipo intero puo' contenere bits
non usati per rappresentare un valore valido, pertanto potrebbe dar
luogo a 'trap representations', l'accesso alle quali ha "comportamento
indefinito"). Inoltre nel linguaggio C dire byte e dire 8 bits non è
assolutamente la stessa cosa. Il C prevede il caso in cui il byte possa
non essere di 8 bits. Con uint8_t invece hai la certezza di usare 8 bits 
e di usarli tutti.
-- 
Vincenzo Mercuri

 usare 8 bits e di usarli tutti.
Grazie pure a te... :) Non mi resta che esaminare linea
per linea... non ho il coraggio di usare wc per sapere
quante sono :/
ciao!


 linea... non ho il coraggio di usare wc per sapere quante sono :/
Controlla come usi lo stack.  Dubito che nell'ambiente del micro ci 
sia l'allocazione dinamica come sul PC.
Ciao
Giovanni
-- 
   A computer is like an air conditioner,
   it stops working when you open Windows.
   < 
http://giovanni.homelinux.net/
 >

 Giovanni
WOW, se ne impara una più del diavolo! Grazie pure a te, poi do' 
un'occhiata...

Il 02/09/2010 9.14, Giovanni ha scritto:
 > On 09/02/10 08:57, Archaeopteryx wrote:
 >
 >> Grazie pure a te... :) Non mi resta che esaminare linea per
 >> linea... non ho il coraggio di usare wc per sapere quante sono :/
 >
 > Controlla come usi lo stack. Dubito che nell'ambiente del micro ci sia
 > l'allocazione dinamica come sul PC.
 >
 > Ciao
 > Giovanni
In effetti mi era capitato anche a me ma non mi ricordavo più!
Sui micro con poca ram capita che se usi in modo "aggressivo" le 
funzioni ricorsive, lo stack sovrascrive le variabili del programma!


Solo per un suggerimento leggero: prova a identificare/isolare dove hai 
  il baco alla 'vecchia maniera':  a seconda di come hai strutturato il 
codice, potresti provare a commentare delle chiamate ( o avere delle 
simil fn. che fanno subito return con valori plausibili (stub)) e vedere 
quando non hai piu' il problema sul microcontrollore.
My 2 cents
Gio