Newsgroup: it.comp.lang.c
Titolo: Chiarimenti sulla seguente istruzione.

Non riesco a capire cosa fa esattamente la seguente istruzione:
    #define BASE_ADDR ((volatile uCPUBusType*)0xA1000000)
dove "uCPUBusType" è definita come unsigned short.
So già che si usa volatile per variabili modificabili via hardware,
ciò che non capisco è l'uso del casting, in pratica si sta definendo
0xA1000000 del tipo uCPUBusType? E perché l'*?
Grazie mille per le eventuali risposte

 0xA1000000 del tipo uCPUBusType? E perché l'*?
Perche' e' definito come un indirizzo (volatile) di un unsigned short.
HTH
C:\>iao Angelo
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

     #define BASE_ADDR ((volatile uCPUBusType*)0xA1000000)
in pratica tu col #define dici al precompilatore di assegnare al nome
simbolico BASE_ADDR il valore diuCPUBusType moltiplicato  0x1000000;
col cast volatile gli dici che questovalore e' contenuto in un registro e
dunque ha size 4 bytes, mentre se non glielo dicssi il risutato sarebbe
troncato ai 2 bytes del short unsiged.
                        Donato
Gradite correzioni

 Gradite correzioni
Done:P
Matyx

     #define BASE_ADDR ((volatile uCPUBusType*)0xA1000000)
È un modo un po' "barbaro" per fare questo:
volatile uCPUBusType * BASE_ADDR = (uCPUBusType*)0xA1000000;
In pratica, BASE_ADDR si comporta in tutto e per tutto come un puntatore a
un oggetto di tipo BASE_ADDR.
Solo che il valore di questo puntatore, anziché essere automaticamente
assegnato dal compilatore e/o dal "loader" del progamma, viene assegnato
manualmente dal programmatore.
Questa è una cosa molto strana, assolutamente non portabile e nemmeno
possibile sugli ambienti run-time più evoluti, ma può avere un senso su
certi ambienti run time di "basso livello", come per esempio i processori
embedded.
La keyword "volatile" serve ad avvertire il compilatore che non deve
cercare di essere "furbo" con quell'indirizzo perché, se anche ci ha
appena messo dentro un certo valore, non è detto che all'istruzione
successiva l'indirizzo 0xA1000000 contenga ancora questo valore.
Esemmpio, dato questo codice C...
   uCPUBusType pippo;
   *BASE_ADDR = 27;
   pippo = *BASE_ADDR;
.. qualsiasi compilatore decente genererebbe un codice assembler di
questo tipo:
1: carica_costante    27         // acc = 27
2: scrivi_a_indirizzo 0xA1000000 // *BASE_ADDR = acc
3: scrivi_a_indirizzo 0x12345678 // pippo = acc
Siccome in *BASE_ADDR ha appena messo "27", il compilatore pensa di sapere
cosa contiene quest'indirizzo, e quindi di poter lo stesso valore (che ha
già caricato nell'accumulatore "acc") anche per l'assegnamento a "pippo",
risparmiare così un'istruzione macchina.
La keyword "volatile" gli fa sapere che questa ottimizzazione, in questo
caso, è rischiosa, e che deve dunque tradurre le istruzioni C alla lettera:
1: carica_costante    27         // acc = 27
2: scrivi_a_indirizzo 0xA1000000 // *BASE_ADDR = acc
3: leggi_da_indirizzo 0xA1000000 // acc = *BASE_ADDR
4: scrivi_a_indirizzo 0x12345678 // pippo = acc
L'istruzione 3 è apparentemente ridondante, ma il programmatore sa che non
lo è, perché 0xA1000000 su quel processore è una locazione di memoria
speciale.
--
Cingar
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 embedded.
I miei complimenti, infatti si tratta di un indirizzo di un banco di
memoria flash. Sto scrivendo un software che consenta di leggerevi e
scriverci passando attraverso un PIC, quell'istruzione l'ho trovata su
un'application note per una memoria analoga. Devo dire che l'argomento
è interessante.