Aiuto per compilazione STK500boot.c

Altra possibile soluzione, più semplice da implementare a livello di bootloader, usare una cella della EEPROM come flag di attivazione, in pratica il bootloader come prima cose legge questa cella se contiene un certo valore procede con la normale procedura, in caso contrario cede immediatamente il controllo al programma utente.
Ovviamente tocca prevedere a livello software sul 2560 un modo per settare questa cella della EEPROM tramite un qualche comando inviato sulla seriale tramite USB e serial monitor così diventa possibile fare tutto direttamente dall'IDE di Arduino.

Io butto li qualche idea:

La mia esigenza primaria è che arduino faccia partire lo sketch anche se ci sono dati sulla seriale rs485.
Se questo avviene istantaneamente oppure dopo 10 secondi non è grave.L'importante è che se si resetta oppure manca tensione questo riparta.Sempre. Adesso questo non avviene.

L'esigenza secondaria è poter fare l'upgrade del software tramite IDE di Arduino,operazione da fare manualmente,staccando la RS485 manualmente.

Ho 8 pulsanti sul frontale e 8 dipswitch. Eventualmente potrei anche adibire un dipswitch alla funzione di upload dello sketch tramite usb.

Oppure si potrebbe semplicemente dire una cosa tipo "se non ti arriva uno sketch entro 10 secondi fa partire lo sketch prevaricato ignorando eventuali dati sulla seriale.."
che è poi quello che ho provato a fare tutto il giorno,ottenendo le più svariate cose.. :slight_smile:

E adesso, vi prego, svagatevi con le vostre famiglie, ne riparliamo lunedì, se no abuso troppo dell'altrui disponibilità :slight_smile:
Un caloroso augurio di buon weekend a tutti.E ancora grazie.
Ciao

La soluzione della cella EEPROM è stata usata anche nel bootloader della 2009 XD
Ho visto che usavano il tempo di scrittura come delay per qualche attesa interna.

Tornando alla questione, ti chiedo: ma tu programmi il chip tramite porta USB oppure tramite connettore ICSP con l'MKII?
Se c'è il connettore ICSP non hai bisogno di altro, sei a posto. Ti costruisci un cavetto ICSP, carichi lo sketch ArduinoISP su un Arduino e poi programma il micro tramite IDE.

Giorgio:
Oppure si potrebbe semplicemente dire una cosa tipo "se non ti arriva uno sketch entro 10 secondi fa partire lo sketch prevaricato ignorando eventuali dati sulla seriale.."

Questo non puoi farlo senza modificare pesantemente la parte di avvio del bootloader.
Visto che hai a disposizione dei pulsanti la soluzione diventa semplicissima, basta che il bootloader come prima cosa verifica se un pulsante è premuto, in caso positivo fai procedere il tutto nel modo normale, in caso contrario lo consideri come un timeout e attivi il programma.
La modifica al bootloader è semplicissima in questo caso, basta aggiungere poche righe nel main loop per attivare l'input che vuoi verificare, l'eventuale pullup interna se necessaria, una if per controllare se il tasto è premuto e avvia la "while (boot_state==0)" oppure la salta completamente facendo partire il programma utente.

in risposta a leo:

non ci sarebbe nemmeno bisogni di un altro arduino, compri un usbasp a 5 euro e lo usi in modo diretto dall'ide 1.x, ma il problema non e' questo, ha gia' detto che vorrebbe tenere in piedi il discorso usb per non modificare meccanicamente la scatola.
Io cmq andrei verso questa soluzione, cioe' prendi tutte queste scatole e modificale meccanicamente al fine di portare fuori il connettore ICSP, oltre a non avere problemi con il bootloader non ti perdi nessuna funzionalita' dell'ide, e non devi nemmeno staccare il bus manualmente per la programmazione

Ma lui ha detto che quando deve fare l'aggiornamento prende la scatola "in mano", quindi aprirla non è un problema. Forse non può modificare però a livello HW ciò che ha fatto.
Inoltre il suo interesse è quello di fare tutto dall'IDE, se non ho capito male.

ma con usbasp (o altri) e ide 1.x fai appunto tutto dall'IDE :slight_smile: oppure devo modificare la mia guida

La modifica al bootloader è semplicissima in questo caso, basta aggiungere poche righe nel main loop per attivare l'input che vuoi verificare, l'eventuale pullup interna se necessaria, una if per controllare se il tasto è premuto e avvia la "while (boot_state==0)" oppure la salta completamente facendo partire il programma utente.

Si questa è la soluzione semplice visto che ha dei pulsanti collegati alla board.

Ok buon fine settimana a tutti.

Ciao.

C'è comunque un problema.
Con l'USBasp, così come l'USBtinyISP, hai il difetto che non programmi oltre i 64 kB di flash. Serve un firmware aggiornato, avevo controllato tempo fa sul sito del creatore dell'SUBasp. Per l'USBtiny invece non ci sono aggiornamenti ufficiali che fanno ciò.

Testato:
ma con usbasp (o altri) e ide 1.x fai appunto tutto dall'IDE :slight_smile: oppure devo modificare la mia guida

La deve programmare dalla porta USB, la scheda, e non è una MEGA2560, è dentro una scatola e non ha accesso al connettore ISP, ha anche postato le foto del tutto.

astrobeed:
Per me state usando un approccio sbagliato, potete mettere tutti i delay che volete però non serve a nulla per il semplice motivo che il bootloader si aspetta di vedere dei dati sulla seriale per attivarsi, solo se per un certo tempo non arriva nulla cede il controllo al programma principale.
Dato che in questo caso specifico la seriale è connessa ad un bus dati con un certo traffico alla fine il bootloader vedrà sempre arrivare dei byte con la conseguente attivazione e blocco della scheda.
La soluzione è una sola, il bootloader si deve attivare solo se riceve una ben precisa sequenza di caratteri entro un certo timeout, p.e. la stringa "@***#", va da se che poi tocca usare uno script per inviare questa stringa e subito dopo far partire AvrDude per la programmazione, il timeout del bootloader dovrebbe essere di almeno 1 secondo per dare modo ad AvrDude di partire.

non sono d'accordo. anzi, ho osservato il codice ed è più facile del previsto.

lasciamo intatto il codice che abbiamo visto fin'ora. riceveremo il carattere che fa entrare il boot-loader in stato di programmzione (boot_state==1).

osserviamo questa parte di codice;

  1. notiamo che il ciclo è condizionato da isLeave
  2. ciclo che legge un byte fino a formare un comando
  3. switch che contrlla il comando.
    notamo nello switch 2 cose interessanti:
    a. il comando
case CMD_LEAVE_PROGMODE_ISP:
					isLeave	=	1;
					//*	fall thru

b. il caso default:

default:
msgLength		=	2;
msgBuffer[1]	=	STATUS_CMD_FAILED;
break;

iniziamo a dire di uscire dal while se trova un comando che non è valido:

default:
msgLength		=	2;
msgBuffer[1]	=	STATUS_CMD_FAILED;
isLeave	=	1;  //<<<<<<< modified by lesto, start sketch if command not found
break;

ora passiamo al ciclo acquisiszione comando. (che nel ciclo è precedente, riga 571)
come si può notare il ciclo è condizionasto da while ( msgParseState != ST_PROCESS )
e nello switch, in caso che il comando rilevato sia erroneo, viene azzerato tutto il processo di lettura messaggio attarverso l'istruzione
msgParseState = ST_START;
ma noi non vogliamo che lui ricominci la lettura, quindi nei vari casi dello switch sostituiamo il reset del comando con invece il termine comando:
msgParseState = ST_PROCESS;
i casi da modificare sono ST_GET_SEQ_NUM, ST_GET_TOKEN, ST_GET_CHECK

ed ecco che il nostro boot-loader sarà molto schizzinoso sui comandi che gli arrivano: mentre prima un comando che arrivava con sequenza o sintassi errata veniva scartato e ci si metteva in attesa del prossimo comando, ora si esce dai vari cicli e si procede ad eseguire il codice utente.

Buongiorno a tutti.

@lesto

Ho provato minuziosamente quanto suggerisci,
aggiungendo cioè l'istruzione isLeave=1; e l'ST_PROCESS nei 3 casi switch. Il bootloader si comporta normalmente, nessun problema a caricare gli sketch.

Tuttavia, se una volta caricato e messo in esecuzione il mio sketch provo a spegnere o resettare il modulo con la seriale collegata e all'avvia si blocca ancora con il led fisso acceso :frowning:

Spero che potremmo adottare la tua soluzione perché è quella che di gran lunga mi piace di più.
Allego il file qualora tu volessi controllare, le modifiche le ho commentate con //mod by giorgio

grazie ancora

stk500boot.c (49.3 KB)

siamo a cavallo. se lìupload va bene, allora attiva la DEBUG_SERIAL e controlla dove si blocca durante il reset...

E come faccio a controllarlo?
se ho la seriale collegata a sparare dati come posso debuggare?

Giorgio:
E come faccio a controllarlo?
se ho la seriale collegata a sparare dati come posso debuggare?

Ma perché ti devi complicare la vita per nulla ?
Fai come ti ho detto io, usa uno dei pulsanti che hai sul box, se è premuto dopo reset avvia il bootloader altrimenti salta tutta la parte del timeout in modo da far avviare subito il tuo programma.
Devi solo inserire una if nel codice e attivare in lettura, più eventuale pull up, il pin dove è connesso il pulsante.

astrobeed:
Ma perché ti devi complicare la vita per nulla ?
Fai come ti ho detto io, usa uno dei pulsanti che hai sul box, se è premuto dopo reset avvia il bootloader altrimenti salta tutta la parte del timeout in modo da far avviare subito il tuo programma.
Devi solo inserire una if nel codice e attivare in lettura, più eventuale pull up, il pin dove è connesso il pulsante.

Effettivamente... avendo i pulsanti disponibili...

Giusto per capirci, l'unica modifica che devi fare, oltre ad attivare il pin per leggere il tasto, è questa:

if (tastopremuto) // modifica
{
	while (boot_state==0)
	{
		while ((!(Serial_Available())) && (boot_state == 0))		// wait for data
		{
			_delay_ms(0.001);
			boot_timer++;
			if (boot_timer > boot_timeout)
			{
				boot_state	=	1; // (after ++ -> boot_state=2 bootloader timeout, jump to main 0x00000 )
			}
		#ifdef BLINK_LED_WHILE_WAITING
			if ((boot_timer % 7000) == 0)
			{
				//*	toggle the LED
				PROGLED_PORT	^=	(1<<PROGLED_PIN);	// turn LED ON
			}
		#endif
		}
		boot_state++; // ( if boot_state=1 bootloader received byte from UART, enter bootloader mode)
	}
}
else  boot_state=0; // garantisce l'esecuzione immediata del programma utente

@astrobeed
Non voglio complicarmi la vita,diciamo che questa sarebbe la soluzione meno complicata per evitare di dover premere un pulsante e resettare il modulo per caricare lo sketch..nell'altro caso basterebbe scollegare la linea seriale e uploadare lo sketch.Diciamo che se si riuscisse questa sarebbe proprio la soluzione a 5 stelle :wink: vista la comodità che si avrebbe lavorando all'interno del quadro elettrico dove vanno alloggiati i moduli.

Non ultimo non conosco la sintassi per leggere lo stato di un bottone all'interno del bootloader :frowning:
Ho chiaro quale parte saltare, ma come leggo lo stato?
Il mio bottone è il PIN22 che dovrebbe corrispondere a PA0 (AD0) sull'atmel.

grazie

Giorgio:
Non voglio complicarmi la vita,diciamo che questa sarebbe la soluzione meno complicata per evitare di dover premere un pulsante e resettare il modulo per caricare lo sketch..

Non devi resettare nulla, ci pensa l'IDE ad attivare l'autoreset quando trasferisci lo sketch, in pratica non devi fare altro che collegare l'usb, premere il pulsante e fare l'upload dello sketch dall'IDE.
Non appena parte l'upload puoi rilasciare il pulsante.

Non ultimo non conosco la sintassi per leggere lo stato di un bottone all'interno del bootloader :frowning:
Ho chiaro quale parte saltare, ma come leggo lo stato?
Il mio bottone è il PIN22 che dovrebbe corrispondere a PA0 (AD0) sull'atmel.

Se non hai fretta nel tardo pomeriggio ti posto il bootloader già modificato per partire tenendo premuto un pulsante su PA0, mi devi solo dire se il pulsante chiude a GND, in questo caso devi avere una R di pull down sulla scheda, o VDD, in questo caso se è già presente una pull up sulla scheda oppure devo attivare quella del GPIO utilizzato.

@astrobeed
grazie, non ho grande fretta..ma niente pappa pronta, spiegami magari solo qual'e' la sintassi corretta che ci provo io... va bene aiutare ma non esageriamo :wink:

I pulsanti chiudono a VDD e ho già previsto sul pcb la resistenza di pull-up.