Consiglio Libri di programmazione MCUs

Salve Ragazzi,

Scusate la domanda banale, ma essendo che io, anche se "bazzico" coi i Microcontroller da vari anni ormai (ma non con l'impegno che vorrei) e che da un anno sto "praticando" con Arduino e la programmazione C++ ma tento di imparare anche il plain C per poter (un giorno) approfittare delle potenzialità del Atmega328p che purtroppo tramite la programmazione C++ non ri riesce a fare con la sufficiente velocità. Essendo autodidatta e con un minimo di bakground di elettronica, vorrei avere un consiglio da Voi esperti, su che libro potrei prendere che mi spieghi bene l'approccio della programmazione di MCU in C, specialmente come sfruttare al meglio interrupt, Timer, e come creare eventi ad intervalli prestabiliti affinchè non si sprechino cicli di clock, insomma, come si struttura un buon "codice" embedded.

Per il linguaggio C ho già acquistato l'ottimo libro: "C corso completo di programmazione" di Paul e Harvey Deitel. Devo dare atto che è un'ottimo libro, il tutto è ben spiegato chiaro anche per una "vecchia matricola" come me che ahimè, non ha più la memoria e la concentrazione per imparare velocemente. Purtroppo, vedo che è molto dedicato alla programmazione su PC e poco o nulla su MCU (non l'ho letto tutto ma così mi pare).

Quindi ogni vostro consiglio è bene accetto!!

Su google book ci sono alcuni libri in anteprima e io ne ho consultato un bel po e devo dire che quello che cerchi lo cerco anche io e non l'ho ancora trovato. Ho acquistato qualcosa ma non è quello che cerco o meglio avrei preferito si concentrasse sui pattern legati alla architettura e invece parla di Queue, event driven ecc e il libro da per scontato che ci sia sotto un RTOS o comunque uno scheduler time sharing.

In attesa che si trovi un libro da acquistare ti consiglio di usare un IDE standard e il linguaggi C, partendo da zero.
Evidentemente lo sviluppo di applicazione embedded si affronta in modo totalmente differente da come lo si affronta sul PC, tuttavia usare il PC facendo finta che poi il codice verrà eseguito da un microcontroller è cosa fattibile che porta grandi vantaggi. Ad esempio imparare le struct, union, puntatori a void, a funzioni a tipi base o a tipo utente ecc su un dispositivo embedded equivale ad essere masochisti. Usare il PC facendo finta che sia un dispositivo embedded richieda la conoscenza delle differenze tra questi e la principale sta nella dimensione occupata da un puntatore che sul PC occupa 8 byte e 2 su AVR.

Io faccio così, scrivo e testo il codice sul PC e ormai scrivo come se si trattasse di AVR tanto che il codice testato poi non ha bisogno di ritocchi. Ovviamente si tratta di codice che realizza funzionalità con le quali non mi sono mai cimentato, mentre per il codice legato alla architettura mi arrangio ad esempio con un timer che richiama periodicamente una funzione e io mi dico quella funzione è una ISR di arduino, come faccio ad agganciare una mia funzione alla ISR, gira e rigira trovo e provo varie soluzione comodamente sul PC con l'output in shell.

Se trovi qualche libro interessante consultabile in anteprima postalo qui.

Ciao.

Premesso che il sito che linkerò dichiara espressamente :

Reproduction of site books is authorized only for informative purposes and strictly for personal, private use.

e che risulta legale e non pirata, consiglio di scaricare i seguenti libri :

... oltre naturalmente a tutti gli altri di vostro interesse che vengono fuori se, sulla barra in alto di ricerca, fate una ricerca per "Arduino" :wink:

Guglielmo

Grazie Guglielmo per gli ottimi link! ci darò un'occhiata.
MauroTec, grazie anche a te per la risposta, peccato che ci abbia capito poco, causa la mia ignoranza in materia di programmazione in generale (PC men che meno!) si ho capito il nocciolo del tuo discorso, ma non saprei come applicarlo a sviluppi con microcontrollori (almeno per progetti complessi).

Hiper passami la mail con un messaggio privato che ti faccio un regalone.

Intanto ti suggerisco anche di darti una guardata al megapost intitolato: [OT] PIC, 8051 e altre MCU...

lock:

hiperformance71:
almeno per progetti complessi

complessi di che tipo ? esemplifica.

Un blink a frequenza variabile! XD

lock:
una centralina automotive in fondo fa questo, schedula una catena lunghissima di aggeggi sincroni entro la deadline, e tiene conto di eventi asincroni variabili.

Indovinato! sto propio pianificando una mia applicazione personale e vorrei creare la mia propia centralina! D'altronde, con le centraline auto stradali e da corsa ci lavoro da anni, e vorrei poter "un giorno" :grin: avere un prodotto che possa dire "questa l'ho fatta io" ma sono consapevole che per un eventuale prodotto remotamente commerciale, richiederà la re ingegnerizzazione del tutto da parte di personale qualificato, ma per ora, non ci sono risorse economiche per commissionare lavori a terze persone, e poi, vuoi mettere la soddisfazione?

Ho trovato svariati progetti in rete, alcuni ben documentati, altri un pò meno, complesse e più semplici, ma mancandomi le basi fatico a stare dietro al codice ed io voglio imparare non copiare il lavoro altrui.

Faccio fatica a strutturare il codice in modo da suddividere i task in base alla loro importanza, sto appena ora incominciando a capire come si fa, ma vorrei poterlo studiare da un libro invece di impararlo da codice lungo svariate centinaia di pagine!

Per ora mi sto dilettando a sviluppare altre sezioni del codice, man mano ci lavoro ed imparo qualcosa di nuovo, applico delle ottimizzazioni e riduco l'imgombro del codice o l'utilizzo di RAM usando più spesso variabili locali invece di globali, ma la strada è lunga ed in salita, spero non rimanerci per strada!! :~

BaBBuino:
Hiper passami la mail con un messaggio privato che ti faccio un regalone.

Intanto ti suggerisco anche di darti una guardata al megapost intitolato: [OT] PIC, 8051 e altre MCU...

La mia email è nel mio profilo o meglio, appare sotto i miei posto. Grazie.

Non ho capito in che posto appare la tua mail... :roll_eyes:

La sua mail non appare in nessun posto, l'ha messa privata :wink:

leo72:
La sua mail non appare in nessun posto, l'ha messa privata :wink:

E allora sarà dura spedirgli il regalone! :slight_smile:

@hiperformance71
Un libro da comprare è questo: Making Embedded Systems - Free download, Code examples, Book reviews, Online preview, PDF

Per il tuo caso potrebbe essere necessario un RTOS o anche codice dedicato scritto di pugno per fare in modo che il tempo di esecuzione sia una costante. Supponiamo che le funzionalità principali della centralina sono state realizzate e sono state testate con successo, ora le funzionalità accessorie quando attivate non permettono alle funzioni principali di essere compiute nei vincoli di tempo imposti e quindi es il motore perde colpi o altra anomalia.

Una delle funzionalità accessorie da abilitare in fase di messa a punto potrebbe essere quella che ti permette di modificare tanti parametri in modo online (cioè con il motore acceso) attraverso la connessione seriale, ma come detto il codice per questa funzione fa fallire le funzioni principali. Questo è il caso in cui un RTOS generico o specifico può fare la differenza, purtroppo questo introduce altri potenziali problemi di cui si deve tenere conto e per fortuna ci sono metodi conosciuti da applicare, ma comunque si tratta sempre di una complicazione in più da gestire, che però potenzialmente risolve il problema di cui accennavo, problema che ci ha portato verso l'uso di un RTOS.

Per ora mi sto dilettando a sviluppare altre sezioni del codice, man mano ci lavoro ed imparo qualcosa di nuovo, applico delle ottimizzazioni e riduco l'imgombro del codice o l'utilizzo di RAM usando più spesso variabili locali invece di globali, ma la strada è lunga ed in salita, spero non rimanerci per strada!!

mmmm...forse non è l'atteggiamento giusto per non rimanerci per strada, anzi sarebbe proprio il caso di non fare questa considerazione sempre che non ci si stia attribuendo dei limiti invalicabili. Nel senso il risultato lo raggiungerai di sicuro prima o poi non importa se dovrai studiare 2 o 5 o più libri, e scrivere 10 versioni differenti del software.

In sostanza un solo libro non basta.

Ciao.

BaBBuino:
Non ho capito in che posto appare la tua mail... :roll_eyes:

Scusa avevo visto che ad ogni mio post, nel riquadro del nome, sotto vi è anche l'icona della e-mail, non avevo idea che lo potessi vedere solo io!
la mia email e: aufiero71@yahoo.com

Grazie della spiegazione, ne sono consapevole delle mie GRANDISSiMEEE limitazioni, e non ho intenzione di fare nulla di Astronomico come la F1 o altro, per ora è solo uno sfizzio, un sogno nel cassetto che voglio incominciare a "tirar fuori" anche se come ho detto, la strada per mè è tutta in salita e con la corrente che rema contro aggiungerei, ma tentar non nuoce.

Io per lavoro installo e mappo centraline da competizione ad un livello che ovviamente è anni luce da quello della F1, ma nel mio piccolo lavoro con svariate marche (Mectronik, EFI, TDD, DTA, Microtec, Sauro, Sybele, AEM, Megasquirt) e quindi conosco bene le funzionalità richieste da una mia ipotetica "creatura" ma in questo caso, la mia realizzazione in realtà sarà per un settore non coperto da quasi nessun fabricante, e comunque, come detto, è uno sfizzio personale, già riuscire a far partire la mia macchina e riuscire a tenerla a minimo, magari potendo accellerare giusto un pelo senza fare danni, per mè sarebbe già un grosso traguardo, poi, magari, come detto, mollo tutto a persone del mestiere per un'eventuale applicazione commerciale.

Un pochino di tutto quello che hai detto riguardante l'hardware lo sapevo già, anche vecchi sistemi OEM si basavano su integrati dedicati a specifiche funzioni per alleggerire il carico della MCU (si pensi alla venerabile IAW delle Delta & Co, alla sua epoca era la più avanzata ECU "stradale" , detto da esperti, era 8-10 anni avanti alla concorrenza).

Magari per questo progetto servirebbe una MCU molto potente, per poter far fronte a tutto, ma considerando che la mia realizzazione, almeno inizialmente sarebbe ridotta al minimo indispensabile, forse un ATMEGA328p potrebbe farcela, ma forse no, e a questo punto si potrebbe usare un ATMEGA2560 o direttamente uno a specifica automotive come AT32UC3C0512C, MCU a 32 bit con 512kb Flash ecc... ma ne esistono di più potenti ovviamente come appunto, il powerPC, molto usati in ambito OEM.

Sono daccordo con te sul fatto che non troverò in nessun libro come "progettare e/o programmare il firmware di una ECU" ma almeno mi chiarirebbe le idee del come approcciare il problema. il consiglio di studiare RTOS è sicuramente una soluzione, ma devo prima avere una base più solida secondo me.

Hai perfettamente ragione, un libro non basta, anzi, sarebbe controproducente, immagginati quante migliaia di pagine da consultare!! meglio se suddiviso sa vari libri, da ogn'uno si traggono alcune idee. in sostanza è quello che ho fatto io per arrivare dove sono adesso, ho preso spunto da esempi, codice esposto su libri e siti web, forum come questo e tanti altri che affrontano argomenti variegati sul tema embedded, solo da un anno a questa parte Arduino.

Da quello che so fin ora, la maggiorparte delle ECU siano esse stradali o da competizione che conosco, usano gli interrupt ed i timer per gestire il tutto, alcune con hardware dedicato, la maggiorparte dei calcoli / eventi vengono fatti in base alla posizione dell'albero motore, per esempio, ricordo di una ECU che dichiarava che ad ogni giro motore, essa ricalcolava 4 volte il tutto, mentre una più recente dichiarava che facesse 200 ricalcoli a giro per un max di 22000 giri (processore da 40MHz se ricordo bene).

Riuscire a schedulare ogni evento al momento giusto è alla base di questo tipo di progetto.

per esempio, per il mio progetto, devo avere degli eventi Interrupt esterni:

CRANK_Signal - ovvero segnale ruota fonica per posizione albero motore, vi sono 60 denti -2-2 ovvero, 28 denti + 2 vuoti + 28 denti + 2 vuoti per 360 gradi. quindi significa che se il mio motore gira a max 6000 rpm, avrò 5600 interrupt, da datasheet ATMEGA328p ho letto che ogni interrupt consuma circa 11 cicli clock e quindi solo per gli interrupt, consumerei: 61600 cicli clock senza contare però il codice da eseguire ad ogni interrupt e il resto del codice.

CAM_Signal - segnale fase camma, ruota fonica da 7 denti che fa capire alla ECU quale cilindro è in compressione. quindi girando alla metà dei giri del motore, ovvero 3000rpm max, e avendo 7 denti darebbe=350 interrupt ovvero altri 3850 cicli clock da aggiungere a quelli per il segnale CRANK (totale 65450 tick).

Se il 328p gira a 16MHz ovvero 16000000 cicli clock/sec significa che (per il mio modesto punto di vista frutto dell'ignoranza in materia, correggetemi se sbaglio) tra un interrupt e l'altro vi restano solo 244 cicli clock, forse pochini per completare la mole di calcoli e cose che deve gestire, o mi sbaglio? Per esempio, ho visto che l'accesso ai canali ADC rallenta l'esecuzione di brutto, anche se ho visto anche che può essere velocizzato mettendo mano ai registri potendoli portare fino a 1 MHz senza perdere troppo in accuratezza (l'ho letto da qualche parte in rete). Per esempio qui, dovrei schedularli in modo da non interferire con le funzionalità critiche, tanto i canali ADC sono parametri che tutte le ECU che conosco controllano con una frequenza minore, ma comunque, almeno 1 volta a giro e quindi intendo prove così.

che ne pensi?

Riuscire a schedulare ogni evento al momento giusto è alla base di questo tipo di progetto.

Almeno in questa fase dovresti avere le idee chiare e dei documenti su cui studiare nel dettaglio cosa accade.
Supponi di aver creato un programma (per il 328) che cambia stato di alcuni pin con la sequenza temporale identica a quella di un motore che viaggia alla velocità di 6000 giri/minuto e di collegare a questi pin un analizzatore di stati logici così da osservare come cambiano gli stati di ogni canale. Vedi immagine File:JTAG LOGIC ANALYZER.png - Wikimedia Commons

Sarebbe utile poter osservare i segnali anche senza poter scalare la base dei tempi, se potessi disegnare i principali stati logici dei segnali nel periodo di 1 secondo con il motore al minimo diciamo 1000 giri/minuto.

Gli interrupt sono 2 per ogni dente se vuoi rilevare entrambe in fronti di salita e discesa.

Non mi tornano i conti con i 244 cicli. Ogni clock dura 1/16000 000 = 62.5 ns
Quindi se è vero che un interrupt costa 11 cicli il tempo totale per eseguirlo sara 62.5 x 11 = 687.5 ns
Ora se 6000 giri/minuto /60 = 100 giri/secondo = 100 e quindi 56denti x 100 = 5600 denti ogni secondo
1000 / 5600 = 0,17857142857142857143, quindi un dente ogni 0.178 ms cioè 178us cioè in ns 178 x 1000 = 178000ns / 687ns = 159, cioè ci stanno 159 interrupt - 1, o se preferisci 159 * 11 = 1749 cicli di clock.

Sicuramente non abbiamo cicli di clock in abbondanza ma possono bastare almeno per adesso, il problema invece è gli altri interrupt quando accadono, se per caso ci fossere 3 interrupt nello stesso instante ci sarebbe uno slittamento di 687.5 x 3....be insomma se hai già le idee chiare sei pronto per pensare al codice o meglio all'applicazione embedded composta appunto di hardware e software dedicato, diversamente il codice al momento non è il problema su cui concentrarsi.

Ti serve per forza un analizzatore logico, non puoi farne a meno, come pure l'oscilloscopio che sicuramente avrai.
PS: mmm.... ricontrolla i calcoli perché a quest'ora...

Ciao.

Gli interrupt sono 2 per ogni dente se vuoi rilevare entrambe in fronti di salita e discesa.

no usualmente, per i sistemi ECU che conosco OEM e Motorsport si usa solo uno, Rising o Falling, si misura il tempo tra due interrupt per conoscere il tempo tra due denti e quindi, la velocità angolare, rpm ecc.. le tacche mancanti servono per identificare la posizione del cilindro al PMS valutando ad ogni interrupt se il tempoattuale > (tempoprecedente * 2) se la risposta è affermativa, azzera il contatore di "denti" e sincronizza i calcoli in base al cilindro in compressione (per la mia applicazione, e necessario l'uso anche di un segnale camma che identifica in modo univoco ogni cilindro al PMS in compressione. E questa parte è tosta da stabilire per il momento, la lascerà per quando avrò più info ed esperienza. Da quello che so, potrei farlo partire anche solo con il segnale CRANK, in effetti la ECU OEM così fa durante l'avviamento o in caso di segnale CAM assente o non plausibile.

Non mi tornano i conti con i 244 cicli. Ogni clock dura 1/16000 000 = 62.5 ns
Quindi se è vero che un interrupt costa 11 cicli il tempo totale per eseguirlo sara 62.5 x 11 = 687.5 ns
Ora se 6000 giri/minuto /60 = 100 giri/secondo = 100 e quindi 56denti x 100 = 5600 denti ogni secondo
1000 / 5600 = 0,17857142857142857143, quindi un dente ogni 0.178 ms cioè 178us cioè in ns 178 x 1000 = 178000ns / 687ns = 159, cioè ci stanno 159 interrupt - 1, o se preferisci 159 * 11 = 1749 cicli di clock.

sarà l'ora veramente! a me nemmeno mi tornano, ma sono più fiducioso nei tuoi calcoli che nei miei! non mi ritengo abbastanza bravo in questi calcoli e di sicuro mi è sfuggito qualcosa. i 244 cicli si riferiscono a quelli che ho calcolato mi rimangano tra due interrupt consecutivi:

6000 rpm = 100 giri/sec * 56 denti = 5600 denti /sec = 5600 interrupt/sec * 11 cicli= 61600 cicli e a questi gli ho sommato i cicli del segnale CAM, che sono altri 350... se a 16MHz facciamo 16000000 cicli/sec /65450 = 244 ma non so perchè non ci troviamo! dal tuo conteggio mi sembra logico quello che hai spiegato e se così, le cose andrebbero anche meglio!! ma ricalcolando i tuoi calcoli, mi risulta che sono 259 interrupt. Ma non ci sono 5600 interrupt/sec? forse il tuo risultato si riferisce al numero di interrupt "liberi" tra dente e dente no? così le cose promettono bene.

Grazie del tempo che mi stai dedicando.
Buona notte.

hiperformance71:
Scusa avevo visto che ad ogni mio post, nel riquadro del nome, sotto vi è anche l'icona della e-mail, non avevo idea che lo potessi vedere solo io!

E' una impostazione che devi modificare nel tuo profilo utente, devi rendere la mail pubblica altrimenti la vedi solo tu.

Ah, per le prox volte, evita ci citare dei papiri di post, in questa pagina ci sono già 4 km e mezzo di testo, di cui più della metà sono i tuoi 2 quote di inizio pagina :wink:
Cita solo la frase/periodo a cui vuoi rispondere.

Cita solo la frase/periodo a cui vuoi rispondere.

OK Leo72 scusami, è che non ricordavo come si fa a rispodere e quotare solo il testo interessato, poi mi sono ricordato come. Vedrò di modificare i post precedenti per renderli più leggibili. Grazie

Ti serve per forza un analizzatore logico, non puoi farne a meno, come pure l'oscilloscopio che sicuramente avrai.

Si lo so e mi sto impegnando all'acquisto, l'oscilloscopio DSO economico (OWON PDS5022S) dopo 3 anni di poco uso, improvvisamente mi ha abbandonato (forse lo schermo LCD visto che aveva dato segni di problemi in vista e dal costo di 90 euro + iva) e sto meditando l'acquisto di qualcosa di meglio (ma mi rode dover affrontare una spesa imprevista!!) l'analizzatore stati logici era nelle previsioni perchè effettivamente, per acquisire e controllare tutti i segnali è indispensabile. Ne ho trovati svariati e da un range di prezzi molto amplio, da uno ultra econonico cinese (meno di 20 euro!) a modell oltre i 300 euro. Per l'oscilloscopio, avevo messo pensiero al modello base Tektronics che una settimana fa trovai da Distrelec a 390 Euro + una seconda sonda-probe a 75 euro. Per essere un TEK niente male! ma sorpresa! meno di una settimana dopo, il prezzo è schizzato a 485 Euro ai quali va aggiunto anche la sonda probe (75 euro)! quindi mi sono guardati intorno ed ho trovato un RIGOL DS1074Z, di cui ho sentito ottime recensioni in giro (70MHz, 4 CH, 1Gs/s, 12Mpts (espandibile a 24Mpts) schermo TFT da 7 pollici, opzioni da generatore di funzioni a 2 CH, ecc. tutto per soli 536 Euro (sito ufficiale Europa)! mi sembra un'affarone! che ne pensate?