Buongiorno, ieri sera era un tantino cotto e stavo lavorando, ho letto i vari passaggi in modo veloce ma qualche cosa mi ha lasciato perplesso. Questa mattina li ho riletti e vorrei chiedere a
giovannispina alcune delucidazioni su un paio di aspetti che mi lasciano perplesso.
Cominciamo da questa:
giovannispina ha scritto:I2C_Rd aspetta finché non viene letto il messaggio ...
Ammetto di aver studiato I2C da autodidatta ma io ho compreso che:
- a generare il segnale di clock nel bus è sempre il master (il mio PIC nell'esempio)
- quando il master vuole comunicare con uno slave invia l'indirizzo dello slave (7 impulsi di clock), un bit di lettura/scrittura (un impulso di clock) e
legge (al nono impulso di clock) se lo slave risponde con ACK o con NACK
- quando il master vuole scrivere sullo slave, genera 9 implusi di clock: i primi 8 per inviare i dati allo slave, il 9° per leggere se lo slave risponde con ACK o con NACK
- quando il master vuole leggere dallo slave, genera 9 impulsi di clock: con i primi 8 legge il segnale dati del bus, con il 9° impulso di clock il master genera un segnale di ACK o NACK
Da questo ho interpretato (mia interpretazione personale) che sia sempre il master a governare il bus e per nessun motivo esso possa bloccarsi, al più potrebbe leggere un segnale ACK o NACK dallo slave in alcune condizioni e dovrebbe agire di conseguenza. Ma mai bloccarsi.
In particolare nella read, come potrebbe il master sapere se lo slave è o non è connesso? Quando uno slave non è presente il master leggerà tutti '1' (resistenze di pull-up presenti nel bus), stessa condizione che potrebbe incontrare se lo slave fosse presente e rispondesse al master con tutti '1'.
Come fa quindi la I2C_Rd() a capire quando ha ricevuto un messaggio?
Chi e come comunica al master che il messaggio ricevuto (gli 8 bit letti) è corretto (è lui a generare ACK o NACK)?
Il secondo aspetto che non mi è chiaro è il seguente:
giovannispina ha scritto:Sì, in mC, in assenza di uno stack riservato, lo spazio delle variabili locali (parametri compresi) viene riutilizzato da funzione a funzione,
Provo a fare un esempio per vedere se ho compreso:
- Codice: Seleziona tutto
void func_a(void) {
int pippo;
// qui il codice fa qualche cosa utilizzando anche pippo
}
void func_b(void) {
int topo;
// qui il codice fa qualche cosa utilizzando anche topo
}
Tu dici che il compilatore potrebbe riutilizzare lo stesso spazio di memoria per salvare le variabili locali pippo e topo, a meno di non dichiarare le variabili locali come statiche.
Quindi se pippo viene salvata all'indirizzo (esempio) 0x123, anche la topo potrebbe essere salvata in 0x123 sovrascrivendo il contenuto di pippo.
Ero convinto che qualsiasi compilatore si comportasse il questo modo, mi stupirei del contrario. E sono sicuro, anche se non ho mai controllato, che anche il C18 si comporta così.
Ma il caso portato come esempio da
TardoFreak è una situazione totalmente diversa dall'esempio che ho appena scritto. Il suo caso è simile (attenzione
solo simile) a questo:
- Codice: Seleziona tutto
void func_a(void) {
int pippo;
// qui il codice fa qualche cosa utilizzando anche pippo
}
void func_b(void) {
int topo;
topo=0;
while (topo<10) {
// qui il codice fa qualche cosa;
func_a();
topo++;
}
}
In questo semplice esempio se topo e pippo venissero posizionate dal compilatore allo stesso indirizzo di memoria la func_b non funzionerebbe a dovere perché:
- quando termina la func_a topo potrebbe essere già maggiore di 10 e quindi il while termina subito, anche dopo un solo ciclo: Errore!
- quando termina la func_a topo ha sempre un valore inferiore a 9 con conseguente loop della func_b: Errore!
In questo caso un compilatore serio dovrebbe garantire la separazione degli indirizzi di memoria tra le variabili locali della func_b e le variabili locali della func_a.
Nell'esempio di
TardoFreak a mio avviso la situazione è ancora più complessa perché il parametro passato è un puntatore a variabile (magari definita come globale) e questo puntatore non può, non deve mai cambiare, qualsiasi sia il numero di chiamate nidificate che vengono eseguite.
Concludendo: ho interpretato male quanto volevi affermare con?
giovannispina ha scritto:Sì, in mC, in assenza di uno stack riservato, lo spazio delle variabili locali (parametri compresi) viene riutilizzato da funzione a funzione,
Mi spieghi cosa intendevi?
Grazie.