Ora, Searle chiede di supporre che lui si sieda all'interno del calcolatore. In altre parole, egli si immagina in una piccola stanza (la stanza cinese) con un libro contenente la versione in italiano del programma utilizzato dal computer e carta e penna in abbondanza. Searle potrebbe ricevere scritte in cinese attraverso una finestra di ingresso, elaborarle seguendo le istruzioni del programma, e produrre altri simboli cinesi in uscita, in modo identico a quanto faceva il calcolatore. Searle fa notare che egli non capisce i simboli cinesi. Quindi la sua mancanza di comprensione dimostra che il calcolatore non può comprendere il cinese, poiché esso è nella sua stessa situazione. Il calcolatore è un semplice manipolatore di simboli, esattamente come lo è lui nella stanza cinese - e quindi i calcolatori non capiscono quello che stanno dicendo tanto quanto lui. ( tesi della stanza cinese di Searle )
Non impiego molto a comprendere che il sistema di sviluppo che ho a disposizione non supporta il nuovo microcontrollore e quindi mi scarico dalla IAR quello completo con licenza a 30 giorni. Compilo ma il codice si blocca in due punti.
Uno è all’interno di un modulo assembly di inizalizzazione della memoria interna. L’altro è nella misura della frequenza del DCO.
Spieghiamo meglio cosa è il DCO ( Digitally Controlled Oscillator ). E’ un vero e proprio oscillatore interno al micro estremamente veloce che è stato progettato come clock di sistema. Il micro MSP430F249 ha questa configurazione del clock.
XT2 Clock esterno Alta/Bassa frequenza ( 400 kHz / 16 MHz )
LFXT1 Clock esterno Alta/Bassa frequenza ( 400 kHz / 16 MHz )
DCO Clock interno
VLOCKL Clock interno frequenza fissa con bassissimi consumi ( tipicamente 12 kHz )
I device interni del micro possono prendere questi oscillatori attraverso queste impostazioni configurabili.
ACLK clock ausiliario
MCLK master clock
SMCLK submain clock
La lettura della frequenza del DCO è stata implementata ad solo uso diagnostico, ma è piuttosto importante perché il micro nella nostra applicazione lavora per il 90% del suo tempo con questa frequenza. L’oscillazione nella release precedente era un rc effettuata con una resistenza esterna mentre in questa release abbiamo utilizzato la resistenza interna. Descrivo velocemente come viene implementata la lettura di questa frequenza.
In pratica si sfrutta una tipica funzione chiamata capture dei timer. Questa funzione consente di rilevare lo stato del timer quando accade un certo evento. Questi eventi possono essere associati a pin esterni oppure come nel nostro caso possiamo avere come evento i fronti del quarzo esterno FLXT1 che è da 32 kHz. Il nostro timer per il conteggio lo associeremo invece al DCO interno. Ad ogni fronte del clock esterno il timer si resetta e inizia a contare alla frequenza data dal DCO. Al secondo fronte il dato letto viene trasferito nel buffer e resettandosi per consentire la prossima eventuale lettura. Se leggiamo 1 la nostra frequenza sarà 32 kHz, se leggiamo 2 64 kHz... e così via. ( e così abbiamo un lsb da 32 kHz... )
Ora ecco il fatidico codice che il mio predecessore aveva scritto per misurare questa frequenza.
//----------------------------------------------------------------------------------------------- // GetDCOFreq // Utilizza il TimerB e ACLK(32 kHz) per misurare la frequenza del DCO (torna valore in Hz) //----------------------------------------------------------------------------------------------- LONG MSP430_GetDCOFreq() { BYTE SmclkFromXt2; WORD n1,n2; // Setta un flag se SMCLK è ricavato da XT2 if (BCSCTL2 & SELS) SmclkFromXt2=1; else SmclkFromXt2=0; // Ricava il clock per SMCLK da DCO BCSCTL2 &= ~SELS; // Accende TimerB: conteggio continuo a 16 bit, clock = SMCLK TBCTL = TBSSEL1 | MC1 | TBCLR; // Capture da CC16B=ACLK, rising edge TBCCTL6 = CM1 | CCIS0 | SCS | CAP; // Attende il primo evento di capture while ( (TBCCTL6 & CCIFG)==0 ) {}; <--- DEAD LOCK // Memorizza valore attuale n1 = TBCCR6; // Azzera flag di capture e overflow TBCCTL6 &= ~(COV|CCIFG); // Attende il prossimo evento di capture while ( (TBCCTL6 & CCIFG)==0 ) {}; // Memorizza valore attuale n2 = TBCCR6; // Se si e' verificato un overflow azzera il valore, se no calcola la differenza if ( (TBCCTL6 & COV) != 0 ) n2=0; else n2=n2-n1; // Ferma il TimerB TBCTL = 0; TBCCTL6 = 0; // Ripristina il clock a SMCLK da XT2 se necessario if (SmclkFromXt2 != 0) BCSCTL2 |= SELS; // Ritorna il valore calcolato in KHertz return( (n2*32768L)/1000L ); }
L'interfaccia Jtag nasce come sistema di comunicazione dati con gli integrati per implementare il Boundary Scan. Tipicamente le aziende produttrici di elettronica si adoperavano per sviluppare attrezzature di collaudo per garantire un adeguato livello di qualità del prodotto.
Il collaudo si suddivide in due parti, il primo collaudo viene effettuato sulla scheda mentre il secondo sull'assieme.
Il boundary scan è una evoluzione del collaudo in circuit e il Jtag era il sistema di comunicazione. Questo sistema si è evoluto diventando l'interfaccia principale degli emulatori moderni.
Decadi or sono gli emulatori infatti erano dei sofisticati probe con sopra sostanzialmente un micro che aveva una interfaccia in grado di emulare a sua volta il micro del nostro progetto.
( come ad esempio la mitica Metalink.... )
Sviluppare firmware con questi oggetti era una pacchia. Break point condizionali, trace, call stack aggiornamenti in real time di variabili; tutte queste cose rendevano più semplice lo sviluppo di applicativi.
Ma se torniamo indietro nel tempo gli antesignani dei sitemi di sviluppo per il debug di schede embedded, erano gli emulatori; non dei micro ma bensì delle eeprom. ( ricordo bene il cassone della Deneb per emulare la eeprom dello z80....)
Adesso i costi si sono notevolemente ridimensionati con il risultato costringere il firmwarista a sviluppare software con sistemi talmente economici da essere regalati dal fornitore.
Ma veniamo alla nostra storia. Il punto dove si bloccava il codice è quello, nel codice soprastante, segnato nel commento Dead Lock.
Squilla il telefono. Un cliente ha effettuato un ordine da due mesi ma l’ordine non è stato evaso e nessuno ( cosa ben peggiore ) lo aveva chiamato.
Volevo dirgli che la cosa mi sembrava molto coerente... invece presi nota.
Salutai con garbo e chiusi il telefono.
Intanto mi chiama Mangusta, l’amministratore delegato della azienda che mi stupra, e nel frattempo mi estorce una settimana per finire il porting del progetto.
Ritorno in ufficio ancora stordito dal veloce meeting.
Commento le due sezioni di codice che bloccavano il programma e passo al porting che mi impegna allo spasmo per un paio di settimane.
Poi arriva Agosto che ha due settimane di ferie e Mangusta scende e viene a salutarmi augurandomi calorosamente buone vacanza.
Quando torno la licenza era scaduta e allora cerco una release dello IAR workbench con crack ma non riesco a trovarlo.
Navigo fra warez, altavista, torrent, siti pirata&porno e finisco la giornata bello arzillo ma niente crack.
Allora scarico un’altra licenza a 30 giorni e la installo in un portatile.... ma ho bisogno di un nuovo jtag perché quello che ho è solo parallelo, e i portatili hanno solo interfacce usb.
Mi faccio mandare il jtag personale del FAE dichiarando lo stato di emergenza.
Mangusta ogni giorno mi saluta e sembra che mi dica “... io ti perdono”
La situazione degenera il telefono squilla in continuazione, la produzione è bloccata e da Defcon5 arriviamo diritti a Defcon1.