Go Down

Topic: Topic permanente di programmazione newbie (Read 38380 times) previous topic - next topic

Michele Menniti

#105
Mar 08, 2012, 06:48 pm Last Edit: Mar 08, 2012, 07:13 pm by menniti Reason: 1
Si nel frattempo ho visto che c'è il contrassegno default anche se mi pare che mi manchi l'attiny88 a prima vista, poi guardo meglio, al limite li leggo da uno vergine, ne ho più di qualcuno ancora nel contenitore.

chiarimenti: mi pare di ricordare che non necessariamente devo fissare il numero di righe per l'array, se è così potrei aggiungere di volta in volta i micro senza dover stare lì a variare quel "20", ricordo male? ci sono controindicazioni? se posso usarlo come faccio poi a sapere cosa devo mettere qui al posto del 20?
Quote
for(i=0;i<20;i++) modello = atmel[indice] ;


Inoltre se dal ritorno della funzione ho l'indice perché devo rileggere tutto per estrapolarmi il modello?

Infine (si fa per dire...) come faccio a leggere i 4 byte dell'array fuse? con qualcosa tipo indice, 1; indice,2 ecc?

Aggiugno quesito: perché leggo da qualche parte che NON tutti i micro ATMEL hanno il 3 fuse (p.es. il TINY85) quando invece il FuseCalc ha un campo "SELFPRGEN" che se flaggato agisce proprio sul 3° fuse di TUTTI i micro che ho visto finora?
Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

astrobeed


chiarimenti: mi pare di ricordare che non necessariamente devo fissare il numero di righe per l'array, se è così potrei aggiungere di volta in volta i micro senza dover stare lì a variare quel "20", ricordo male?


Dato che parliamo di dati statici è vitale che siano predefiniti come dimensioni, non sei obbligato ad inizializzare tutto l'array, ma le dimensioni massime devono essere inserite, ovviamente le puoi variare quando ti pare aggiornando il sorgente.

Quote

Inoltre se dal ritorno della funzione ho l'indice perché devo rileggere tutto per estrapolarmi il modello?


Leggi solo la riga, 20 caratteri nel mio esempio, che contiene il modello e la copi in una stringa che poi usi per inviarla sulla seriale, come faccio io, oppure per scrivere sul display, in realtà per questo puoi scrivere direttamente i caratteri all'interno della for senza usare un ulteriore array.

Quote

Infine
(si fa per dire...) come faccio a leggere i 4 byte dell'array fuse? con qualcosa tipo indice, 1; indice,2 ecc?


Esattamente come leggi la riga del modello, o li usi direttamente sotto forma di array, quindi "fuse[indice]
  • " per il primo e incrementando di 1-2-3 la seconda cifra per accedere agli altri byte, oppure li copi in quattro variabili unsigned char con nomi mnemonici, p.e. "low_fuse = fuse[indice]
  • ".

leo72


chiarimenti: mi pare di ricordare che non necessariamente devo fissare il numero di righe per l'array, se è così potrei aggiungere di volta in volta i micro senza dover stare lì a variare quel "20", ricordo male? ci sono controindicazioni? se posso usarlo come faccio poi a sapere cosa devo mettere qui al posto del 20?
Quote
for(i=0;i<20;i++) modello = atmel[indice] ;


Inoltre se dal ritorno della funzione ho l'indice perché devo rileggere tutto per estrapolarmi il modello?

Infine (si fa per dire...) come faccio a leggere i 4 byte dell'array fuse? con qualcosa tipo indice, 1; indice,2 ecc?

Ma non puoi usare la bozza di codice che ti avevo passato qualche post fa?
Confronta la firma con quella dell'archivio ed esce non appena ha trovato il modello giusto. Una volta uscita, conservati l'indice (dichiaralo fuori dal for) e poi quello ti indica il micro in tutte le altre tabelle.

Quote

Aggiugno quesito: perché leggo da qualche parte che NON tutti i micro ATMEL hanno il 3 fuse (p.es. il TINY85) quando invece il FuseCalc ha un campo "SELFPRGEN" che se flaggato agisce proprio sul 3° fuse di TUTTI i micro che ho visto finora?


I Tiny ce l'hanno. Un micro che non ce l'ha è l'Atmega32, per esempio

Michele Menniti

uffff, ho fatto tutto, cose da ignoranti fatali :smiley-red:
Comunque tutto perfetto, metto il micro nel suo zoccolo (non posso andare alla cieca solo nel caso dei micro a 20 pin visto che ho dovuto prevedere due diversi zoccoli) e mi tira fuori in automatico: modello, signature e fuse di default.
Ora ho a disposizione il 4° byte (che ho definito FLAGS) che mi servirà per leggere, con la giusta modalità i due o tre fuse (anche il tiny13 ne ha 2, ora ho visto che è vero...), ed eventualmente per riprogrammarli.
Anche oggi, GRAZIE AL VOSTRO PREZIOSO AIUTO (E TANTA PAZIENZA :*), è stata una giornata molto fruttuosa.
Qualche minuto per inserire qualche altro micro nella tabella e poi smetto, sono stanchissimo.

Una sola nota, Astro, nei casi di non presenza in tabella aveva inserito un messaggio in seriale (ma chiaramente era per farmi capire la problematica), poiché in quella fase non uso la seriale e piché non sono riuscito in alcun modo ad assegnare un testo a modello, per incompatibilità di tipi, mi è parso di aver capito, ho fatto una cosa che ha una sua logica, secondo me: nell'ultima posizione del solo array "atmel" (quello che contiene le descrizioni dei modelli), ho messo in ultima posizione (la ventesima o quel che sarà) una descrizione "NON IN TABELLA"; in tal modo se metto un micro compatibile in uno zoccolo ma che non è in tabella, la procedura mi legge la signature e mi avvisa che non è in tabella e che quindi non conosce i fuses di default, ma a quel punto lo posso programmare senza problemi. Inoltre non mi piaceva molto il fatto di dare un valore fisso numerico ai tre array; visto che tale valore è usato in 6-7 punti del firmware, ad ogni variazione in aumento avrei dovuto modificare 6-7 valori col rischio di dimenticare qualcosa, allora ho definito una costante TOT a cui assegno il valore 20 (per ora) e che sarà l'unica che dovrò variare quando aumenteranno i micro definiti. Non va bene?
Ah, una nota: avevo messo la
Quote
char modello[TOT],i;
nelle variabili globali, l'ho dovuta rimettere dov'era perché in fase di visualizzazione dei dati si infilavano caratteri strani, non ho capito perché ma l'importante è che ora funzioni.
Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

leo72

Nel mio lunghissimo post avevo anche messo:

Basta un if con un triplo controllo all'interno di un for. Mettiamo che firma[..] contenga la firma digitale letta dal micro e archivioFirme[..][..] le firme memorizzate:
Code: [Select]
boolean trovato=false;
for (byte i=0; i<num_firme; i++) {
 if ((firma[0]==archivioFirme[i][0]) && (firma[1]==archivioFirme[i][1]) && (firma[2]==archivioFirme[i][2])) {
   .....codice per firma trovata....
   trovato=true;
   break;
 }
}
if (!trovato) {
 ....micro non riconosciuto...
}

"trovato" è false all'uscita del ciclo for se non è stato trovato nessun corrispondente modello nell'archivio

Quindi un semplice flag per verificare che l'uscita dal ciclo di controllo delle signature sia avvenuto recuperando un modello oppure no.
Se ora tu estrai la definizione di "byte i" dal for e la metti come variabile esterna, all'uscita del ciclo for, "i" contiene l'indice del modello che puoi poi usare per estrarre i dati dalle altre tabelle.

astrobeed


Nel mio lunghissimo post avevo anche messo:


Scusa Leo, ma in questo caso dissento totalmente dalla tua soluzione.
Prima di tutto scansioni tutto l'array sempre, tempo cpu sprecato, e poi a Michele serve un indice per trovare tutti i parametri, la mia soluzione non solo è più elegante, più compatta ed efficiente, si ferma non appena trova il modello di micro e ritorna il relativo indice.


leo72


Prima di tutto scansioni tutto l'array sempre, tempo cpu sprecato

a Michele serve un indice per trovare tutti i parametri, la mia soluzione non solo è più elegante, più compatta ed efficiente, si ferma non appena trova il modello di micro e ritorna il relativo indice.


Questo è un discorso relativo perché si hanno da passare in rassegna 10/20 modelli non di più. Si sprecano risorse ma parliamo di un ciclo che non sempre arriverà fino alle ultime posizioni dell'array dei micro. Inoltre non scansiono l'intero array ma mi fermo quando trovo una corrispondenza. Lo stesso fa il tuo ciclo for, perché esce solo nel momento in cui trova il micro, non prima.

Se la variabile viene messa fuori dal ciclo, nel momento in cui esce dal for conserva la posizione del micro trovato, quindi l'indice della corrispondenza trovata.

Poi è ovvio: ogni scarrafone è bello a mamma sua  ;)

ratto93

Non vorrei dire una boiata, ma la Ricerca Dicotomica vi dice niente ?  :smiley-mr-green:
Credo che non darebbe nessun problema durante l'implementazione ne durante il funzionamento..
Se corri veloce come un fulmine, ti schianterai come un tuono.

Michele Menniti

Buongiorno, è doverosa la premessa che dovete sempre tener presente leggendo il titolo del Topic :smiley-red:
Quindi io accetto e rispetto ogni suggerimento e davvero ringrazio di cuore chiunque mi dia una mano, poi ho due priorità: "comprendere" il suggerimento in quanto lo dovrò poi spiegare, ed "impossessarmi" di esso in quanto certamente devo manipolarlo; inoltre i tempi sono stretti quindi magari capita che prendo una soluzione tecnicamente meno favorevole di un'altra, ma se la capisco e funziona per me è un grande balzo avanti come state comprendendo; ancora, ovvio che se oltre a spiegarmi mi postate un code copia/incolla mi ci butto a pesce, salvo poi a chiedere spiegazioni. Ieri con grande fatica :smiley-sweat: sono riuscito ad arrivare al punto che ho scritto nell'ultimo post, ora mi sembra giusto, prima di andare al lavoro (ma spero di sbrigarmi presto) postare la soluzione adottata, che mi sembra semplice e chiara, e che ora non so nemmeno più di chi è figlia, avendola perlatro "snaturata" tutta con interventi da newbie, che ora vi faranno imprecare, ma che funzionano, e per me, almeno per ora, tanto basta. Il prossimo passaggio consiste secondo me nel creare un 4° array con 6 righe e tre colonne nel quale memorizzo i sei valori del 4° byte dell'array "fuses" ed i corrispondenti valori di EFUSE si/no e programming mode HVSP/HVPP/HVP13; oppure con un semplice select case, da aggiungere alla base del code che vi sto postando, ottengo lo stesso risultato, ditemi Voi; una volta in possesso dei dati per la programmazione devo passare all'ultimo stadio, che è quello della scrittura dei fuses e poi ho finito; resta da immplementare l'erase, ma mi verrà semplice una volta ristrutturato il software, come sto facendo, man mano che procedo.
Code: [Select]
#define  TOT            4
char atmel [TOT] [20] = {      {"ATtiny13"},
                               {"ATtiny25"},
                               {"ATtiny45"}
          {"NON IN TABELLA"}   
};

byte signature [TOT] [3] = {   {0x1E,0x90,0x07},
                               {""},
                               {""}
};

byte fuses [TOT] [4] =    {    {0x6A,0xFF,0xFF,0x00},
{0x62,0xD9,0xFF,0x04},
                               {0x62,0xDF,0xFF,0x05}
};

IN LOOP:

// arrivati a questo punto sono in possesso della sola signature del micro

unsigned char indice;
    unsigned char LFUSE;
    unsigned char HFUSE;
    unsigned char EFUSE;
    unsigned char FLAGS;
    char modello[TOT],i;
    delay(500);
    indice = cfr_signature(read_signature2,read_signature3);
    if (indice < TOT)
      {
       for(i=0;i<20;i++) modello[i] = atmel[indice] [i];
       LFUSE = fuses[indice] [0];
       HFUSE = fuses[indice] [1];
       EFUSE = fuses[indice] [2];
       FLAGS = fuses[indice] [3];
      } 
    else for(i=0;i<20;i++) modello[TOT] = atmel[indice] [i];


NELLA SEZIONE FUNCTIONS & VOIDS

unsigned char cfr_signature(unsigned char byte2, unsigned char byte3)
{
char i;
unsigned int temp1, temp2;

temp1 = (unsigned int)(byte2 << 8) + byte3;

for (i=0;i<TOT;i++)
{
  temp2 = (unsigned int) (signature[i] [1] <<8) + signature[i] [2];
  if (temp1 == temp2) return i; // esce dalla funzione con il valore dell'indice
}
i = TOT-1; // corrispondenza non trovata, i assume l'ultimo valore dell'array "NON IN TABELLA"
return i;
}


@ ratto93: per quanto mi riguarda non so di che parli  :~
Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

astrobeed

#114
Mar 09, 2012, 08:32 am Last Edit: Mar 09, 2012, 09:30 am by astrobeed Reason: 1
,Non vorrei dire una boiata,  :smiley-mr-green:


Si l'hai detta   :)
La ricerca dicotomica è applicabile solo se hai una lista ordinata, in senso crescente o decrescente, il che implica l'uso di un sort oppure obbligare Michele ad un lavoraccio per mettere tutte le signature in ordine, se gli fai questa proposta come minimo telefona alla tua scuola e ti fa bocciare in anticipo  :smiley-mr-green:
Dato che parliamo di array di piccole dimensioni, non penso andrà mai oltre i cento elementi, non è che ci sono tutti questi grandi vantaggi nell'applicare algoritmi di ricerca particolari, la banale scansione con stop sul match va più che bene.

leo72


, ma la Ricerca Dicotomica vi dice niente ?  :smiley-mr-green:


Si l'hai detta   :)
La ricerca dicotomica è applicabile solo se hai una lista ordinata, in senso crescente o decrescente, il che implica l'uso di un sort oppure obbligare Michele ad un lavoraccio per mettere tutte le signature in ordine, se gli fai questa proposta come minimo telefona alla tua scuola e ti fa bocciare in anticipo  :smiley-mr-green:
Dato che parliamo di array di piccole dimensioni, non penso andrà mai oltre i cento elementi, non è che ci sono tutti questi grandi vantaggi nell'applicare algoritmi di ricerca particolari, la banale scansione con stop sul match va più che bene.

Allora usiamo lo Gnome sort per ordinare la lista  :P

Michele Menniti

#116
Mar 09, 2012, 12:30 pm Last Edit: Mar 09, 2012, 12:32 pm by menniti Reason: 1

,Non vorrei dire una boiata,  :smiley-mr-green:


Si l'hai detta   :)
La ricerca dicotomica è applicabile solo se hai una lista ordinata, in senso crescente o decrescente, il che implica l'uso di un sort oppure obbligare Michele ad un lavoraccio per mettere tutte le signature in ordine, se gli fai questa proposta come minimo telefona alla tua scuola e ti fa bocciare in anticipo  :smiley-mr-green:
Dato che parliamo di array di piccole dimensioni, non penso andrà mai oltre i cento elementi, non è che ci sono tutti questi grandi vantaggi nell'applicare algoritmi di ricerca particolari, la banale scansione con stop sul match va più che bene.

Ratto, puoi smettere di lavorare alla tua tesina, non serve più, almeno per quest'anno ]:D
Scherzi a parte io li sto già inserendo in ordine, ma in base alla Tabella che ho preparato circa i 25 controllori programmabili con certezza, con questo strumento. I successivi in serimenti saranno fatti in coda agli array.

Sì, concordo col fatto che è inutile cercare algoritmi particolari, perché VI confermo che la ricerca è immediata, anzi un ritardo è introdotto da un delay che Astro non mi ha spiegato, subito dopo la dichiarazione delle variabili.

@ Leo buono per quando implementerò le zoccolature qfn & co e programmeremo qualche migliaio di micro :smiley-mr-green:
Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

ratto93

Ragazzi, non faccio programmazione strutturata da 2 anni e ne abbiamo fatta anche poca quindi non prendetevela più di tanto  :*

Per di più se sono già in ordine, può funzionare  :smiley-zipper:
Mi riservo comunque il beneficio di dire boiate  :smiley-yell:
Se corri veloce come un fulmine, ti schianterai come un tuono.

astrobeed


anzi un ritardo è introdotto da un delay che Astro non mi ha spiegato, subito dopo la dichiarazione delle variabili.


Il delay è solo per non bombardare la seriale con una marea di dati, dato che per l'esempio ho inserito tutto nella loop giusto per non farti vedere una marea di righe correre a velocità luce sul serial monitor ho messo quel ritardo.

astrobeed


Mi riservo comunque il beneficio di dire boiate  :smiley-yell:


E noi quello di cazziarti  quando le dici  :D :smiley-mr-green: :D

Go Up