Il contrario della speranza è la disperazione, la resa totale. L'unico peccato per il quale non c'è perdono, né in terra né in cielo. (Raul Montanari)
Il teorema di Cipolla prende spunto da una estensione del celebre pragmatico e paradigmatico rasoio di Occam, che illustri detrattori hanno chiamato per assonanza rasoio di Hanlon. Hanlon, riassumendo, sosteneva un concetto di questo tipo “Non attribuire a cattiveria ciò che puoi facilmente spiegare con la stupidità”. Introducendo di fatto nella vita dell’uomo un terzo e angosciante polo. Si scopre così che abbiamo indissolubilemnte insiti dentro di noi il bene, il male e la stupidità. Il Bene e il Male per natura sono coscienti, mentre la stupidità è invece devastante nella sua incoscienza. Secondo Cipolla la persona stupida è infatti la persona più pericolosa che esista.
Quella mattina lo so sarà diverso. Entro alle dieci, abbastanza nervoso con passo deciso e noto, mentre salgo le scale, lo stupore negli occhi delle persone che mi incontrano.
Squilla il telefono è Mangusta
“Si certo... si lo so... questa mattina dobbiamo metterlo a posto...ci sto lavorando... sono già arrivato... ma guardi sono molto fiducioso... lo so che andiamo a gambe all’aria... e oooo capito... va bene... va bene.. ing Mangusta certamente... farò del mio meglio … guardi non ho dormit.. ci sentiamo...arrivederci... si o capito.. devo andare.. si arrivederci... la sento male.. bbrrrr ssss chiudo arrivederci”.
Il pollice scivolò sulla cornetta rossa del cellulare.
Entro e il saluto dei colleghi divenne un cenno. Raggiungo l’ufficio, mi siedo, con un colpo di reni avvicino la sedia e nello stesso tempo accendo il PC sulla scrivania. Posiziono la scheda sopra una striscia di gomma piuma non conduttiva, collego gli alimentatori e l'accendo. Sopra di essa c’era la scheda tastiera il tutto montato su uno sportello con sopra il consueto foglio di policarbonato. Il display era un classico alfanumerico 4 x 20, di lato su una L di alluminio avevamo montato un GSM da tavolo.
Kalman è uno dei migliori filtri e ha la caratteristica notoria di essere di tipo predittivo. In questo link troverete un pregevolissimo articolo trovato su un forum di elettronica ( tutte le volte che gli do' un occhiata lo voto )... se non ricordo male si chiama Electroyou ;) Ma esistono anche altri tipi di filtri tipo quelli a particelle utilizzati in particolar modo nella robotica in grado di risolvere errori di sistema modellizzati dalle catene senza memoria di Markov, e visualizzate da reti Bayesane... ( ma che sto scrivendo... )
Possiamo anche inventarceli i filtri. Ad esempio un giorno mi sono inventato un filtro sulla misura che ho chiamato inseguitore differenziale di derivata.
In pratica prima si modellizza il sistema e per fare questo si deve attivare l’attuatore al suo valore massimo. Da quel momento si campiona il processo, attraverso il trasduttore, che utilizzerò come feedback del controllo. Poi si spenge l’attuatore ( o lo si mette al valore minimo ) e si continua a monitorare, sino a quando il sistema non si riequilibria.
Con un softwarello ( che aimè ho perduto, anzi se qualcuno conosce qualcosa di simile... ) interpolo i punti appena rilevati tirandone fuori la funzioncina corrispondente con l’errore medio più basso. Ottenuta la funzione vi calcolo, sul range che mi interessa, la derivata massima e quella minima, tipicamente sono funzioni lineari piuttosto semplici e alle volte coincidono.
Quando poi passerò all’interno del mio controllo, prima dei vari filtri, calcolo la derivata istantanea. Questo valore letto mi aspetto che debba essere all’interno del range delle due derivate calcolate precedentemente; in caso contrario le misure saranno filtrate clampandole al valore massimo o minimo corrispondente.
Il nostro nuovo firmwarista ha problemi con il sistema di sviluppo della IAR, sembra che non riesca a riconoscere il path delle directory contenenti gli header di sistema. Ma non è un problema della IAR è un problema di Vista. Da questo sistema operativo in poi ci sono delle differenze nelle installazioni dei programmi. Con Windows Vista la directory di default adesso viene sempre nominata "c:\Program Files\..." mentre prima veniva rinominata a seconda delle impostazioni di lingua della macchina. Vista ha incluso una nuova tecnica chiamata DataRedirection che consiste nel controllare le operazioni di scrittura dei file in zone protette. Oltre a questa funzione ne esiste una chiamata di Junction. Questa di fatto è una funzione di rinomina delle directory, che viene gestita dal sistema operativo ma non dal programma console. Quindi mentre da sistema operativo con le dialog di explorer si vede la directory c:\Programmi, da console invece la vediamo con il suo vero nome. Per risolvere il problema con lo IAR è bastato rinominare nella dialog di configurazione del programma il path da C:\Programmi a C:\Program Files...
vabbè... torniamo alla storia passata e al suo presente....
Sono lì che febbrilmente sto controllando tutto il firmware scritto nei mesi precedenti. Il modulo GSM con tutte le procedure per la gestione dei comandi AT, il modulo delle seriali con i vettori circolari , il modulo degli interrupt per la gestione dei caratteri rilevati sulla porta seriale...
Alzo la testa e guardo la veneziana a strisce che nasconde un orribile panorama suburbano. Il monitor non è un display a LCD ma un vecchio tubo catodico.
Di lato alla scrivania c'era il bancone del laboratorio con le centinaia di cassettiere per centinaia di componenti. All'inizio qualcuno sperava di includerli nel magazzino poi dopo un po' si scoprì che i numeri non corrispondevano mai e così la componentistica diventò un fattore K da poter utilizzare per il bilancio di fine anno.
9:00
Devo vedere quali sono le differenze fra la 2.20 e la 2.30... Ovviamente sono una marea. Fra le altre cose avevo aggiornato il modulo GSM con il parser per una decina di ulteriori comandi AT. Mi stampo il loop principale e evidenzio la chiamata al modulo contenente la macchina a stati del GSM. Tolgo i comandi AT aggiunti per prova ricompilo creo il binario e lo carico sulla Flash...Perfetto! Funziona ! Tutto sta andando a gonfie vele il problema è dentro il modulo... Allora riapro il modulo GSM e controllo le procedure aggiunte. Le controllo una ad una e niente da fare sono corrette... Allora prendo e tolgo una procedura alla volta ricompilo carico sulla flash e rincomincio daccapo
10:00
Niente da fare la scheda alle volte si pianta alle volte frullano i relè, si accendono i led in prefetto sincronismo con le parolacce..
Squilla il telefono, è Mangusta, dice che Outlook gli si blocca in continuazione. Quante volte gli ho detto che il database di outlook è lo stesso di access e ha un limite massimo di 1 GB...
Un crash di questo tipo però è davvero strano... troppo strano.. cosa vuole dire questo andamento anomalo del programma ? Controllo tutti gli accessi in memoria, la gestione dei puntatori, le funzioni di manipolazione diretta come la memcpy e inserisco all’interno delle funzioni diagnostiche che mi permettono di vedere sulla seriale locale lo stato della macchina.
>23/07/2002 10:03:25 State_Gsm : Reset
>23/07/2002 10:03:26 State_Gsm : Off
>23/07/2002 10:03:26 State_Gsm : Wait
>23/07/2002 10:03:27 State_Gsm : On
>23/07/2002 10:03:28 State_Gsm : Ignition ON
>23/07/2002 10:03:28 State_Gsm : Ignition OFF
>23/07/2002 10:03:30 State_Gsm : check ^SYSSTART ok...
Niente da fare la scheda impazzisce e continua ad impazzire...
Sono le 12:30 ho tempo ancora per un'ultima prova, sono arrivato alla fine della benzina... non ne posso più. Basta vado a mangiare.
Raggiungo il bar che sta a circa cento metri sul lato opposto della via. Ci sono due cameriere che si fanno un mazzo infinito tutti i giorni. Una si chiama Patrizia ed è in dolce attesa, dalla pancia direi un 6/8 mesi, e nonostante tutto non demorde. Cammina fra i tavolini col pancione e si vede che gli girano un po'... Quando arriva mi elenca i piatti del giorno e io gli chiedo un primo un bicchiere d’acqua poi un caffè anzi due... ne ho bisogno.
C’erano molte cose che erano un po’ sospese come la mappatura di memoria. Ma uno dei problemi più pericolosi dei sistemi embedded sviluppati in C erano gli overlay di memoria delle stringhe. Le stringhe in C per definizione hanno lo zero come terminatore e tutte le funzioni standard del C presumono stringhe di questo tipo. Le stringhe in Pascal prevedono invece anche un campo dimensione; per questo e per molto altro il Pascal era considerato molto più sicuro. Se per un qualsiasi motivo perdo il terminatore le funzioni standard di gestione delle stringhe eseguono pazzie di vario tipo, quando va bene, il più delle volte il crash immediato è assicurato.
14:00
Guardo tutte le memcpy e tutte i puntatori passati nelle varie procedure... me ne faccio una lista la stampo e faccio il check di ogni singola variabile... prima o poi ti trovo.
15:30
Prendo il file map con tutte le dichiarazioni mappate, nessun warning ... nessun avviso sospetto. Allora prendo il file listing finale. Scandisco tutto il codice assembly, il livello di ottimizzazioni è basso e così è possibile leggerlo senza grosse difficoltà. Spulcio tutti i moduli: il modulo Init, quello di protocollo e il modulo di trasferimento dati alla scheda di acquisizione dove avevamo messo un avveneristico AVR 103 dell’Atmel.
16:07
Arrivo al modulo GSM e non noto niente di sbagliato. Ad un certo punto, mi scappa l’occhio sull’ultima macchina a stati che avevo implementato con il classico costrutto del linguaggio switch case. Aguzzo gli occhi e guardo l’assembly.
11127 jmp $$$Unknown???
Torno a ritroso, i jmp con la stringa Unknown compaiono a partire dall’indirizzo fisico 11053 ( in hex ). Un leggero sudorino mi imperla la fronte. Cinque mesi prima avevamo previsto di mappare una Prom esterna che ci faceva da boot di sistema per poter caricare su flash il firmware aggiornato. La mappatura prevedeva che il boot iniziale partisse dalla locazione zero ed era di 4K ( 1000 in Hex ). Il micro ( che ricordo a chi legge è èun Mitsubishi 37700 ) prevede pagine da 64K e può arrivare ad indirizzare sino ad un massimo di 16Mb che era uno spazio immenso di memoria all’epoca. In quel momento mi accorsi che le ultime modifiche mi avevano fatto sforare la prima pagina da 64K di codice. Devo provare l’ipotesi e tolgo un modulo. Ricompilai e ricaricai il firmware... Per ogni download passa quasi un minuto che è una vera eternità.
Spengo la macchina e la riaccendo, guardo il display e la sequenza dei messaggi... Il contrasto del display è un po’ troppo alto. Tutte le volte che guardavo il display osservavo l’eccitazione dei pixel dell’LCD causata dalla tensione troppo alta che poteva essere tarata semplicemente girando il trimmer che era messo proprio dietro la scheda. Alle volte sono maniacalmente meticoloso, ma il contrasto non mi impedisce di leggere i messaggi che è quello che mi serve. Perché perdere tempo...
Caricamento della configurazione in corso...
Dopo qualche secondo comparve il menù, selezionai la voce gsm e il relativo sottomenù test gsm. Attesi qualche decina di secondi interminabili, quando il cellulare squillò con il soave doppio squillo. Bene, cioè volevo dire Male. Il linker mi ha sputtanato tutti gli indirizzi e tutti i salti relativi erano senza riferimento. Ma adesso la domanda era ed è sempre la solita
“e ora ?”
Mi guardo un attimo intorno i colleghi sono tutti a lavorare, clienti, ordini, fatture. Tutti hanno una marea di cose da fare, da dire, da scrivere. Guardo le loro facce cercando forse un minimo di inquietudine, un egoistico male condiviso. Sono convinto che se in quel preciso momento, qualcuno mi avesse invece guardato il mio viso, avrebbe visto la faccia di un uomo perplesso. Mi alzo in piedi e mi avvicino alla finestra. Guardo le persone che passano nel marciapiede sottostante. Ci sono una serie di negozi e un piccolo centro commerciale, tutti hanno cose da fare da dire, tutti hanno da arrivare a fine giornata. Rimettere mano alla mappatura è un disastro apocalittico, significherebbe rimettere forse mano alla GAL e rincominciare daccapo con tutti i test Hardware. Se la soluzione è questa siamo rovinati... e questa volta per davvero.
I microcontrollori si sono evoluti migliorando le prestazioni del sistema in modo considerevole. I consumi sono diminuiti di diversi punti percentuali e anche la velocità e aumentata in modo consistente. Anche se la struttura interna è rimasta pressoché identica alcune piccole differenze si incominciano a notare. Microchip sicuramente ma anche ST nelle ultime famiglie rendono disponibili una nuova funzionalità che è la rimappatura degli IO. Questa features permette interessanti applicazioni polimorfiche della scheda. Un core modulare di questo micro può essere scambiato sopra harware differenti, oppure possiamo sovrapporre delle funzionalità in tempi diversi del nostro sistema ad esempio delle porte IO che in certi momenti diventano porte seriali rendendo ancora più eclettica la progettazione dell’hardware.
Un’altra funzionalità, resa disponibile dai microcontrollori che è stata presa dai processori più blasonati e potenti è il DMA ( Direct Memory Access ). Questa potente funzione permette in pratica di trasferire automaticamente sezioni di memoria da una parte all’altra. Questa operazione viene eseguita da un processore esterno chiamato DMAC. Sono molte le applicazioni utili, ad esempio viene utilizzata per trasferire grossi frame di dati quando il nostro sistema prevede una porta ethernet. Ora il processo è virtualmente trasparente rispetto al core della cpu, ma alcune risorse sono per ovvi motivi condivise come ad esempio il bus dati e il bus indirizzi. Inevitabilmente quindi una parte del clock viene usato dalla DMAC. Ci sono delle tecniche particolari dette di Hidden dove il DMAC monitorizza continuamente la CPU e appena si accorge che il bus viene rilasciato lo prende per se scambiandogli le carte sotto il naso....
18:53
Mi risiedo, stampo il file xcl con all’interno tutti i segmenti che poi il linker utilizzerà per creare il binario finale. Così mi alzo e raggiungo l’ufficio della amministrazione, lì c’è la stampante di rete, Yappy mi guarda e fa forse un accenno per dirmi qualcosa, ma evidentemente l’espressione che ho non è molto invitante per una conversazione. Mi girano le balle a mille... no a diecimila... forse sono centomila i giri. Maledizione il firmware non ha bachi, solo che adesso rimappare il tutto è un casino.
-! TL37700.XCL Original was lnk77b.xcl
Use -mb switch ( Model Banked ) in 'c' compiling.
-!
-! First define CPU
-!
-c7700
-S
-Z(CODE)RCODE,FLIST,CONST,ZVECT,CCSTR=E000-EFFF
-b#(CODE)CODE=100000,10000,10000
-Z(HUGEC)CDATA0,CDATA1,CDATA2,CSTR=117000
-Z(DATA)FASTMEM=80-Z(DATA)UDATA0,NO_INIT,DATA0,IDATA0,ECSTR,WCSTR,TEMP=300
-Z(DATA)CSTACK+2000=C000-dfff
-! -Z(DATA)CSTACK+80=200-27F
-!-Z(FAR)IDATA1,DATA1,UDATA1=120000
-Z(HUGE)DATA2,IDATA2,UDATA2
-! The interrrupt vectors are assumed to start at FFD0, see also cstartup.s28 -Z( DATA)INTVEC=FFD0-FFFF -! cstartup ProtoTX putcharheap tl37700 m37scomm scc2691a channelsmemory sysfundisplay timerkey boardturbomenu edithooks CRC AlarmRX TestGSM -! Now load the 'C' library -! -C cl77b -! Code will now reside in file crpro95.a28 in MOTOROLA format -! -FMOTOROLA -! -FINTEL-EXTENDED -! -o tl37700.a28-l tl37700.map-xsm -! tl37700.xcl -!
Provo così a rimappare tutto spostando il codice di 4k... ma cosa sto facendo...
la Rom esterna non deve essere mappata dal linker...
Spengo la lampada, gli altri sono andati via da una buona mezz'ora. Adesso ho un grosso problema con il linker, il problema e che non capisco per quale motivo le istruzioni che non vengono indirizzate, siano seguenti all’indirizzo fisico 11000. Provo a vedere se ci sono parti del codice da poter tagliare, ma niente da fare non riesco a risolvere nulla. Ad un certo punto però mi viene in mente una cosa... no è meglio di no, sono convinto che adesso farei altre bischerate... è meglio riprenderla domani mattina. A mente fresca si ragiona meglio, e poi devo andare da Zio Flubbert.
Nel destino di ogni uomo può esserci una fine del mondo fatta solo per lui. Si chiama disperazione. L'anima è piena di stelle cadenti. (Victor Hugo)
8:12 del giorno dopo..
Oggi è il cinque maggio. Un giorno come gli altri. Sì un giorno che deve essere come gli altri nonostante tutto. Il primo maggio ho fatto l’anniversario di matrimonio, quest’anno sono passati 7 anni e tutti parlano della relativa crisi... Ma no sono tutti fantasmi nella testa, non ci sono stati di crisi, e grazie a Dio almeno non con mia moglie. C’era solo il fatto che quel linker aveva fatto un gran pasticcio.
Ma forse c’era il modo per venirne fuori.
Mi sembra che il problema del fuori pagina, sia dovuto dal codice della PROM ( il boot ), allora forse basta che il linker riallinei gli indirizzi tenendo conto di quei 4 K. Creo così un nuovo segmento e lo chiamo RIEMPI. In questo codice ci metto un modulo con 4K di codice pieno di nop. Compilo ma il compilatore mi vomita un out of memory (pork!).
Allora suddivido il modulo in due parti, questa volta il compilatore finisce con successo e il linker mi ritorna il modulo oggetto aggiornato.
La linea del file xcl diventa così
-b#(CODE)RIEMPI,CODE=100000,10000,10000
e aggiungo alla sequenza dei file
- riempi1
- riempi2
Ricompilo e ricreo il progetto. Apro il file lst e guardo il codice creato dal compilatore nel modulo GSM. Questa volta la linea di codice compare.
11127 jmp $0x112030
Sorrido. Che dire, stento a credere ai miei occhi la modifica ha funzionato. Sono da poco passate le 8:30 finisco di scrivere lo storico e dopo poco entra Mangusta, bello carico. Ha la faccia di chi deve andare alla Associazione Industriali e dichiarare fallimento. Attraversa il laboratorio e non mi dice niente mentre mi vede provare l’assieme. Nel frattempo finisco anche il cablaggio per il gsm, taglio gli spezzoni di filo e lo crimpo. Subito dopo entrò Yappi, lei invece aveva la faccia di chi avrebbe fatto l’ultimo giorno di lavoro. Rimase un attimo interdetta come se in un certo senso si aspettase qualcosa. Non la guardai e semplicemente dissi.
“Prepara la bolla... oggi spediamo"
”8:35 05.06.2002 Se, nel file .xcl, il segmento CODE viene dichiarato in questa maniera: b#(CODE)CODE=101000,10000,10000 il compilatore genera un codice diviso in due banchi da 64K ciascuno, a partire dall'indirizzo 101000 Hex, MA I BANCHI NON COMBACIANO CON LE PAGINE DELLA MEMORIA DEL CODICE (ogni pagina occupa 64k), con la conseguenza che le funzioni allocate in fondo al banco risultano a cavallo di due pagine di memoria: - dal file tl37700.map - CODE 101000 - 110FFF (primo banco) CODE 111000 - 120FFF (secondo banco) In questo modo, durante l'esecuzione di tali istruzioni, il programma si perde, e la macchina esegue istruzioni a caso... Nel file .xcl l'indirizzo di partenza era fissato a 101000 anziche' 100000 perche' nei primi 4K di codice sono mappate delle aree di memoria che fanno parte del Boot. Il problema e' stato risolto in questa maniera: e' stato aggiunto un blocco di codice vuoto di 4K a partire dall'indirizzo 100000, in maniera tale che il compilatore generasse un codice con banchi allineati alle pagine di memoria, con istruzioni nulle nei primi 4K di codice, dove il programma di conversione che genera il file immagine alloca il boot. file riempi1.s28 file assembler con istruzioni nop file riempi2.s28 secondo file assembler con istruzioni nop file tl37700.xcl b#(CODE)RIEMPI,CODE=100000,10000,10000 NOTA: occorrono due file assembler perche' altrimenti il compilatore da' un errore di out-of-memory.
La disperazione è follia. La follia, la percezione della impossibilità di vivere: esserci, ma come non esserci. La disperazione come esperienza di follia è incompatibile con la vita. Vede morte, progetta morte e ammazza sé e l'altro. La disperazione è una follia possibile all'uomo, a tutti gli uomini; è anzi una prospettiva dell'uomo, si lega al suo bisogno di stare con l'altro, al fatto che da solo non può vivere, perché la vita umana non è solitudine ma condivisione, appartenenza, attaccamento. (Vittorino Andreoli)