Newsgroup: it.hobby.elettronica.digitale
Titolo: Primi passi con Bertos

Ciao,
tra oggi e domani ho qualche ora di tempo "libero" e vorrei provare a 
riprendere in mano il nostro amico Bertos per utilizzarlo sugli AVR. Mi 
sento abbastanza idiota a volte (spesso in verità) ma non riesco a 
compilare nemmeno gli esempi forniti. Sarei grato a Francesco o a 
chiunque lo conosca di darmi una mano a capire cosa mi manca.
Premetto che ho scaricato e scompattato la versione 20080408, uso 
WinAVR-20071221 e AVRStudio 4.13 SP2.
La prima prova che ho fatto è stata di andare da riga di comando nella 
cartella dove c'è l'esempio per gli AVR:
[...]\bertos-20080408\app\triface
e dare un semplice 'make'.
"make: *** No targets specified and no makefile found.  Stop."
è stata la risposta. Correggendo il nome del makefile proprio in 
'makefile' ottengo:
"make: *** No targets.  Stop."
Guardandoci dentro in effetti è ben diverso da quello a cui sono 
abituato a usare con gli AVR. Prima di addentrarmi nei dettagli però mi 
sorge spontanea una domanda: se Bertos è compatibile con il GCC 
significa che dovrebbe essere abbastanza immediato compilare gli esempi 
forniti.
Ci sono dei passi da fare che non mi sono venuti in mente? Ho 
rispulciato il sito ma non ho trovato novità riguardo a tutorial o 
documentazione 'getting started'. Confermi che non vi nulla di nuovo?
Grazie :)
Marco / iw2nzm

 documentazione 'getting started'. Confermi che non vi nulla di nuovo?
Confermo, e confermo anche che ci vorrebbe, solo che il tempo per fare 
tutto è poco, siamo in pochi, e siamo anche troppo dentro il progetto 
per renderci conto di cosa manca per partire da zero.
Magari se dopo questa prova ti va puoi farci un report per segnalare 
quello che secondo te andrebbe fatto per permettere ad un newbie di 
iniziare a lavorare con BeRTOS, sarebbe molto apprezzato!
Ciao
P.S. C'è anche una mailing list specifica di BeRTOS, la trovi qui:
https://lists.develer.com/mailman/listinfo/bertos

 
https://lists.develer.com/mailman/listinfo/bertos
Mi iscrivo!
Grazie come sempre
Marco / iw2nzm

 Ma cosa c'entra la shell?
Risolto cancellando (o rinominando) il file sh.exe dalla cartella 
utils\bin di WinAVR... Why?
Comunque ora ho compilato correttamente l'esempio (5 warning, 0 errori) 
e in \images mi trovo i file rigurgitati dal compilatore :D
Ciao!
Marco / iw2nzm

Bene,
ora sto guardando un po' il codice e la documentazione (sempre per gli 
AVR). Ho preso un file a caso, \cpu\avr\drv\ser_simple che conoscerai 
bene :P
Ti faccio alcune domande generiche e non per capire meglio la filosofia 
del progetto... poi spero di essere autonomo per un po'!
Chiedo scusa per la lunghezza del post, rispondi con calma quando hai 
tempo non rovinarti la domenica :)
1) Se ho intenzione di usare una CPU diversa da quelle supportate di 
default devo andare a verificare ed eventualmente aggiornare le varie 
#define. Ok, nessun problema. Però c'è un criterio per il quale so dove 
aspettarmele o devo spulciarmi tutti i file? Esempio: il ser_simple.h le 
contiene, ma non il ser_simple.c. Invece nel caso del ser_avr le 
contengono entrambi (header e codice).
2) Parliamo del ser_simple.c. la _ser_open recita:
struct Serial * _ser_open(void)
{
	/*
	 * Set Rx and Tx pins as input to avoid short
	 * circuit when serial is disabled.
	 */
	DDRE  &= ~(BV(PE0)|BV(PE1));
	PORTE &= ~BV(PE0);
	PORTE |=  BV(PE1);
	/* Enable only Rx section */
	UCSR0B = BV(RXEN);
	return NULL;
}
Quale è il motivo per cui hai (dico hai perché immagino che hai scritto 
tu questo codice!) definito in maniera "hard coded" i pin delle seriali? 
Se cambio CPU devo mettere mano e modificare il sorgente. Quale è il 
vantaggio rispetto a passare PORT e PIN? Si risolverebbe anche la 
gestione di micro con doppia seriale che in questo caso mi *sembra* non 
siano supportati.
3) Funzione _ser_setbaudrate:
void _ser_setbaudrate(unsigned long rate)
{
	/* Compute baud-rate period */
	uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, rate) - 1;
	UBRR0H = (period) >> 8;
	UBRR0L = (period);
}
Sbaglio o non si può specificare se usare l'impostazione U2Xn per 
raddoppiare la frequenza del generatore di baud rate? Spesso è comodo!
4) Ho visto con estremo piacere la funzione  _ser_settimeouts()... ma 
guardando il codice è vuota! E' implementata o no?
5) La _ser_putchar(int c) disattiva la ricezione durante la trasmissione 
per evitare problemi nel caso in cui i due fili siano condivisi. Però 
nel caso opposto (IMHO il più frequente) così facendo non si può 
verificare la perdita di dati nel caso in cui ricevo un byte mentre ne 
trasmetto un altro? Non sarebbe più logico dare la possibilità di 
decidere il comportamento tramite #define o semplice flag?
Non sono critiche, ci mancherebbe! Ma "da fuori" ancora mi sono chiari i 
meccanismi di un RTOS per cui sicuramente ci saranno dei motivi che ora 
mi sfuggono a sostegno di queste scelte.
Ciao e grazie!
Marco / iw2nzm

 contengono entrambi (header e codice).
Per aggiungere il supporto ad una nuova CPU della famiglia AVR devi 
modificare il file bertos/cpu/detect.h aggiundendo gli #ifdef mancanti 
(se vedi il codice ti renderai conto che è banale). La filosofia 
generale usata durante lo sviluppo di BeRTOS è stata quella di fare le 
cose in modo incrementale. Questo vuol dire che le cose vengono fatte 
quando servono e non prima, un pezzettino alla volta. Altra linea 
guida fondamentale è il riuso del codice. Inoltre tutto viene 
mantenuto al livello più semplice possibile, in modo da evitare sprechi.
Tutto questo discorso per spiegare che non tutte le CPU AVR sono 
supportate (solo quelle che sono state usate lo sono), ma il codice 
viene via via refactorato ogni volta che ne aggiungiamo una, in modo 
da renderlo più generico.
Nel tuo caso il modo migliore di procedere è modificare 
bertos/cpu/detect.h, fare un'applicazione con i driver che necessiti e 
provare a compilare. Vedrai che in giro per il codice schianteranno 
vari #error, che sono stati messi apposta per modificare il codice nel 
punto giusto.
Purtroppo i file da te scelti sono un esempio un po' infelice. Questi 
file (ser_simple) erano stati sviluppati per un'applicazione di boot 
minimale in cui c'erano scarsissime risorse. La CPU era un ATMega64 e 
i fili di TX e RX erano condivisi. Tutte le tue osservazioni fatte 
sono più che giuste, infatti il modulo è veramente minimale e tagliato 
su misura per le richieste dell'applicazione, tanto che non l'abbiamo 
nemmeno menzionato tra i driver presenti. Però abbiamo ritenuto lo 
stesso giusto aggiungerlo, perché seguendo la filosofia descritta 
prima, anche un modulo poco generico è meglio che nulla. Magari in 
futuro potrà riservire, ed allora verrà migliorato e reso più generico.
Le tue osservazioni sono quindi tutte giuste, il modulo è poco 
generico e cablato appositamente per un caso specifico, non mirava ad 
essere un driver completo ma solo un sotto-set semplice (da qui il 
nome) del vero driver seriale.
Il driver seriale completo è quello implementato nei file ser_avr.[c|h].
Lì vedrai che è stata prestata l'attenzione che hai visto mancare nel 
modulo ser_simple.
Noi abbiamo sempre usato il driver completo (che ha i timeouts, buffer 
circolari di ricezione, funziona con il kernel, etc..), solo in rari 
casi (per adesso solo uno :-) ) abbiamo avuto la necessità di ridurre.
Se però a te serve, puoi modificarlo e adattarlo alla tue esigenze. Se 
mandi le modifiche in lista saremo molto contenti di discutere il modo 
migliore di procedere e darti consigli durante lo sviluppo!
Ciao

 e in \images mi trovo i file rigurgitati dal compilatore :D
Esattamente, sono lì.
Ciao

 applicazioni in 'sorgenti'?
BeRTOS, per comodità, fornisce un'infrastruttura di build che permette 
a più applicazioni di condividere lo stesso tree di sorgenti del S.O.
Questo perché succede molto spesso che un progetto sia formato in 
realtà da più firmware che girano su CPU anche diverse e che devono 
essere compilati allo stesso tempo.
E' possibile fare anche quello che vuoi tu.
Il modo più semplice per farlo è lasciare BeRTOS nella 'library' e 
copiare nella root della tua applicazione il makefile di BeRTOS.
Poi è necessario aggiustare i path dei file che include (in 
particolare 
rules.mk
 e 
config.mk
). Dovrai anche modificare il path 
degli include per aggiungere la directory dove si trova BeRTOS.
Tieni presente che questo modo di lavorare non è molto comune, di 
solito ogni progetto ha la *sua* specifica copia di BeRTOS. Può 
sembrare un controsenso ma è molto comodo, ti permette di avere ogni 
progetto completamente separato ed autonomo dal resto.
Le librerie (e anche BeRTOS) in genere evolvono, e a volte non sono 
più compatibili all'indietro. Metti il caso che hai due progetti, uno 
nuovo e uno vecchio, che usano la stessa libreria.
Quello vecchio non lo puoi modificare perché è già in maintenance, ma 
il nuovo ha bisogno della nuova versione della libreria a causa di 
nuove funzionalità. Cosa fai?
Ciao

 funzionalità. Cosa fai?
Mi era già successo in passato con altre librerie e avevo risolto 
mettendo le due versioni in due cartelle diverse ad esempio:
\Libreria ver. 1
\Libreria ver. 2
e poi includevo i file corretti nei diversi progetti.
Ma concordo che può essere più utile copiare l'intera copia della 
struttura in ogni progetto.
Ciao!
Marco / iw2nzm

 migliore di procedere e darti consigli durante lo sviluppo!
Lo farò senz'altro. Non necessariamente sul ser_simple, ma in generale 
se apporterò modifiche ve le sottoporrò in lista.
Ciao e grazie come sempre
Marco / iw2nzm

 moduli saranno solamente questi ad essere aggiornati con la nuova CPU...
Sì ok, sempre meglio poche cose fatte bene che nessuna :-)
Ciao