Newsgroup: it.comp.lang.c
Titolo: Ottimizzazione e problemi con variabili usati in interrupt

Ho un processore dove trasmetto su una seriale mediante interrupt.
Dichiaro un buffer di trasmissione e due puntatori in questo modo:
  unsigned char uart1_buftx[UART1_BUFTX_LENGTH];
  unsigned char *uart1_buftx_ptr;
  unsigned char *uart1_buftx_end;
Il primo puntatore punta al primo carattere da trasmettere, il secondo
all'ultimo.
Nella routine di interrupt trasmetto il byte puntato dal primo e
incremento, fino
a quando il primo puntatore coincide con il secondo. A questo punto
disabilito
l'interrupt di trasmissione e finisce la trasmissione.
In una routine voglio trasmettere prima 5 byte dell'array, poi gli
altri 5:
  uart1_buftx_end = uart1_buftx + 5;
  uart1_buftx_ptr = uart1_buftx;
  UART1_ENABLETX();
  while(UART1_TRANSMITTING())
    WATCHDOG_RESET();
  uart1_buftx_ptr = uart1_buftx + 5;
  uart1_buftx_end = uart1_buftx + 10;
  UART1_ENABLETX();
Attivando il primo livello di ottimizzazione del mio compilatore,
però, non funziona
perchè le prime due istruzioni di assegnazione vengono completamente
ignorate.
Immagino che il compilatore pensi che è inutile assegnare ad un
puntatore
un valore e dopo un altro. Però a me serve proprio così perchè quel
primo valore
viene usato negli interrupt abilitati dalla UART1_ENABLETX().
Normalmente questi problemi con l'ottimizzazione vengono risolti
definendo
volatile le variabili incriminate. Cosa che però ho fatto senza
successo :-(
Come si potrebbe risolvere il problema utilizzando solo il C e senza
disabilitare
le ottimizzazioni?

 le ottimizzazioni?
Chiedendo al compilatore (nella sua lingua) di non ottimizzare quel
pezzo.

 >In una routine voglio trasmettere prima 5 byte dell'array, poi gli
 >altri 5:
 >  uart1_buftx_end = uart1_buftx + 5;
 >  uart1_buftx_ptr = uart1_buftx;
................
 > Attivando il primo livello di ottimizzazione del mio compilatore,
 > per�, non funziona perch� le prime due istruzioni di assegnazione
 > vengono completamente ignorate.
Ovvio  ;-)
Devi dichiarare i tuoi puntatori con la keyword 'volatile'
volatile unsigned char *uart1_buftx_ptr;
volatile unsigned char *uart1_buftx_end;
In questo modo il compilatore non *dovrebbe* fare
assunzioni e ti deve lasciare il codice 'as is'
A.

 A.
Non hai terminato di leggere il mio mex:


> senza successo :-(
Sorry ... finestrella del newsreader troppo piccola...
che compilatore usi?
E' strano che il compilatore ignori le prime due:
al limite dovrebbe ignorare le ultime due...
BTW, Effettivamente il "volatile" garantisce che il dato
'volatile' venga sempre letto/scritto (no chache), ma mi pare
che lo standard (C99) a riguardo del puntatore di tipo volatile
sia meno esplicito, quindi il compile ci fa le assunzioni che
ritiene.
Per forzare il caricamento a questo punto (a parte disabilitare
le ottimizzazioni) potresti usare una funzione:
int uart_start(volatile char* pData,int len)
{
   uart1_buftx_end = (pData+len;
   uart1_buftx_ptr = pData;
   UART1_ENABLETX();
   while(UART1_TRANSMITTING())
     WATCHDOG_RESET();
   return(len);
}
/////
   r= uart_start(&uart1_buftx[0],5);
   r= uart_start(&uart1_buftx[10],5);
A.

 successo :-(
Strano... hai messo "volatile" al posto giusto? Potresti mostrare il 
codice con il volatile (come direbbe Mike Bongiorno...)?
E.