Border line programming: Compilato ed installato il NET MicroFramework sulla scheda Olimex STM32-E407

Costruire apparecchiature embedded trovo che sia estremamente più divertente e soddisfacente che passare ore a scrivere software gestionale in Visual Basic.

Ogni tanto mi incaponisco su una cosa, e generalmente riesco a portarla alla fine. Questa volta mi è beccata la fissa di fare i porting del NetMF sulla scheda STM32-E407 della Olimex, che mi sono comperato per giocare con il Chibios, e che potete trovare  qui. In realtà non è che la cosa sia una “novità” assoluta, visto che la ricompilazione l’avevo già fatta per la STM32F4Discovery di ST, tuttavia stavolta mi muovevo su un terreno un po’ “diverso” visto che si trattava di modificare il porting per una nuova piattaforma, nonché di caricarlo con procedure diverse, stante la mancanza di doc in giro.

Non solo, visto che mi piace farmi del male, ho voluto compilare il framework non con il solito MDK della Keil, ma con il gratuito GCC.

Dopo un paio di settimane di imprecazioni, di attese davanti alla shell per vedere il risultato, il risultato è un porting discretamente funzionante (ha ancora un grosso bug sul quale sto lavorando), ed una scheda con grosse potenzialità sulla quale lavorare.

Per compilare ho usato il GCC nella distribuzione 4.7.3 di launchpad, scaricabile da  qui.

Questo

Screenshot 2014-02-18 14.06.56

è il risultato della compilazione.

Per scaricare il bootloader nel micro ho usato il CooCox (free pure lui) e come programmatore l’ARM-USB-OCD-H sempre di Olimex.

Dopo aver scaricato il bootloader ho riavviato la scheda ed ho quindi scaricato il resto del NetMF tramite l’MFDeploy, nella cartella Tools del NetMF stesso.

Al termine ho controllato il risultato e…

Screenshot 2014-02-18 17.14.26

Come si vede, il CLR risponde correttamente.

Ho quindi scritto la solita applicazione idiota per fare blinkare il led

Option Explicit On
Option Strict On
Imports System
Imports System.Threading
Imports Microsoft.SPOT
Imports Microsoft.SPOT.Hardware

Namespace STM32E407_First_Project

    Public Module Module1

        Sub Main()
            Dim Led As New OutputPort(Microsoft.SPOT.Hardware.STM32F4.Pins.GPIO_PIN_C_13, False)
            While True
                Led.Write(True)
                Thread.Sleep(1000)
                Led.Write(False)
                Thread.Sleep(1000)
            End While
        End Sub

    End Module

End Namespace

e dopo 5 secondi, ecco che sono riuscito a gestire il tutto dal visual studio.

A breve con altre novità

Interfacciarsi con il mondo esterno. Lezione 0

Di tutorial che insegnano più o meno bene a collegare un pc ad una scheda esterna ne esistono a bizzeffe. C’è gente che privilegia collegare delle schede di interfaccia alla parallela o alla seriale, c’è gente che usa Arduino o similari, c’è gente che le sue interfacce se le costruisce. A quanto pare, però, di tutorial in questo senso ne esistono ancora troppo pochi, o, mi viene da pensare, danno delle informazioni parziali o danno alcuni assunti che rendono frustrante cose che sono, in realtà, abbastanza semplici.

Questo vuole essere un tutorial passo passo senza presupposti se non la buona volontà ed un minimo di manualità, le cose che faccio sono tutte SPERIMENTATE PERSONALMENTE ed il codice che allegherò può essere preso e compilato (contrariamente alla mia abitudine di allegare solo snippet). Il “caveat”, leggasi warning, che lascio è che giocare con l’hardware può avere effetti anche distruttivi, e, nel caso di danni, avrete tutta la mia umana comprensione e solidarietà… ma sono cavoli vostri. Le cose che pubblico funzionano. Se friggete il PC con le foto del vostro matrimonio e vostra moglie vi fucila ha ragione di farlo.

Da una parte quello che voglio dare è un insieme di informazioni su come fare le cose, dall’altro quello che immodestamente vorrei che passasse ai disperati che leggono queste mie è piuttosto un metodo di lavoro, anche perché lavorare con l’hardware è bello ma può portare a molte frustrazioni quando le cose non vanno come devono, ed uno si ritrova con una scheda che non funziona o funziona male.

Prima regola: si fa sempre un passo alla volta. Non si passa allo step successivo finché non si è fatto, collaudato (e possibilmente capito) quanto c’è in un passo.

Seconda regola: non si parte da metà. Le cose devono essere fatte in un determinato ordine. E c’è un perché le cose devono essere fatte in quell’ordine. Non è detto che il mio metodo sia il migliore, ma funziona.

Terza regola: siate ben consci delle vostre capacità. Non potete pretendere di fare una scheda che gira ad 1 GHZ se non ne avete mai fatta una (peraltro non è così difficile, ma da soli e su una basetta dubito che ce la farebbe anche mister FF).

Se potete investire qualche decina di migliaia di euro, allora mettete nella lista della spesa un paio di logic analyzer, un buon compilatore per microcontrollori, licenze per lo sviluppo di driver, un bell’oscilloscopio, lo sviluppo e lo sbroglio di un paio di schede di interfaccia, un microscopio, un saldatore ad infrarossi ed uno ad aria calda e quant’altro.

Come? Non li avete? Tranquilli. Si può fare anche senza. Non costruiremo interfacce custom, ma sceglieremo di usare Arduino o similari, oppure ci attacchiamo alla seriale o alla parallela. Un momento… il mio portatile del 2003 non ha più la parallela e la seriale, e neanche i 5 che ho preso dopo, quindi non saprei come provarli, e a che serve se le porte legacy sono state definite come outdated nella PC Hardware Design Guide del 1996 (eppure c’è gente che le usa ancora, magari insieme al Geloso ed alla macchina da scrivere).

Quindi, gioco forza la scelta è usare una scheda ESTERNA, possibilmente già fatta, sulla quale risiede un firmware che consenta di fare le operazioni che ci servono. Il lavoro che dovremo fare sarà quindi costituito non solo di una parte, ovvero l’ennesimo sarchiapon…. ahem… programma da sviluppare sul pc, ma dovremo occuparci di fare 3 cose:

  1. Costruire un hardware
  2. Scrivere sulla scheda esterna il firmware che si occupi della gestione di questo hardware e della comunicazione con il PC
  3. Scrivere il programma di interfaccia che gestisca la comunicazione lato PC

Quale scheda esterna? A dire la verità sono stato molto combattuto, ma dovendo pensare ad una cosa “per tutti” sono giunto alla conclusione che la scelta ideale sia quella di lavorare su piattaforma ARDUINO, per motivi sia di reperibilità (non dico che le troviate anche dal farmacista, ma poco ci manca), che di costi (io farò esatto riferimento ad una scheda acquistata per 13,5 sterline), ma anche di espansioni.

Avrei potuto usare una Netduino, tanto per rimanere in ambiente .NET, ma è decisamente più costosa e meno diffusa.  Tant’è, molto (per non dire tutto) può essere rifatto su Netduino o similari. Il metodo è lo stesso.

Cosa serve, quindi?

La lista della spesa per la prossima lezione comprende:

1 scheda Arduino o similare (la mia è una compatibilaccia FUNDUINO MEGA 2560)

1 cavo usb AB standard

L’ambiente di sviluppo di Arduino, liberamente scaricabile dal sito www.arduino.cc

Il visual basic o c# installato sul PC

un emulatore di terminale (io uso Teraterm, ma  anche l’Hyperterminal va benissimo, peccato che non ci sia sotto W7).

A parte l’Arduino che ha un costo modesto, oscillate tra i 10 ed i 30 euro, tutto il resto è liberamente scaricabile.

L’invito è, dunque, a quanti interessa la problematica, di procurarsi il materiale mentre io preparo la prossima lezione. 

Down il sito di Apple Developer

A causa di accessi indesiderati il sito web di Apple Developer è stato messo temporaneamente in Down, come visibile qui.

Per chi, come il sottoscritto, lavora anche su dispositivi mobili di Apple è una bella rogna, anche perché, in questi giorni di ferie, contavo proprio di provare il nuovo IOS.

Speriamo si risolva presto.

Gestione delle seriali virtuali. Deep Inside.

Quanto di seguito è il risultato di esperimenti, studi e ricerche effettuati dal sottoscritto e da altri sull’utilizzo delle seriali virtuali e trascende dalle best practice, perché in questo caso queste o non esistono, o sono destinate a fallire miseramente.

Se non vi occupate di firmware, se il vostro concetto di fare hardware consiste nel saper usare il cacciavite a croce per assemblare un pc, allora questo mio sproloquio è per voi assolutamente inutile. Se invece credete che fare hardware sia un’altra cosa, allora potrete trovare nelle righe che seguono qualche informazione utile.

Quando il pc si interfaccia con una qualche periferica esterna, magari custom, via USB, bisogna considerare il sistema complessivo nelle sue varie parti, che vanno dall’applicativo, alle API che permettono all’applicativo di interfacciarsi con il dispositivo fisico, e dalla parte del dispositivo esterno un sistema complementare. Per rendere meglio l’idea si può immaginare il sistema costituito in maniera analoga al classico modello ISO/OSI di derivazione “retistica”.

Grazie al fatto che l’USB è “universal” o “general purpose”, uno sviluppatore può costruirsi ed adattarsi il proprio schema di comunicazione, scrivendosi lo stack sul dispositivo ed anche i device driver così come le api per interfacciarsi a quest’ultimo. Tuttavia, pur non essendo un lavoro impossibile, tale discorso è assolutamente sconsigliato e scarsamente praticato, proprio perché richiede conoscenze molto ampie e molto approfondite, ed anche perché tipicamente ci si può riportare (anche magari con qualche artificio) a situazioni già note, utilizzando ed implementando nel proprio dispositivo e nei propri driver un cosiddetto profilo o classe di dispositivo. I più comuni profili adottati dagli sviluppatori di firmware sono HID (human interface device), MSC (Mass storage device class) e CDC (Communication Device Class), mentre maggiori informazioni possono essere trovate qui.

Il profilo più usato nella fase di transizione tra i dispositivi “classici” e quelli USB è normalmente il profilo CDC grazie al quale dal PC vedo il dispositivo come se comunicassi con una porta seriale. Egualmente, dal dispositivo, se lo stack è fatto almeno decentemente,  comunico con il pc in maniera identica, come se stessi comunicando con una seriale fisica. Questo significa che dal pc posso utilizzare le stesse API per comunicare con il dispositivo che utilizzerei per utilizzare una seriale fisica. Idem dal mio device.

Il .NET framework ci fornisce delle classi per la gestione delle porte seriali che rendono le operazioni decisamente semplici e con pochi sforzi si possono costruire funzioni anche thread safe per la gestione delle seriali stesse.

Dall’altra parte è possibile scrivere, con uno sforzo modesto, uno stack in grado di far riconoscere un dispositivo collegato su USB come porta seriale virtuale. Diciamolo subito, non è una cosa per tutti, c’è chi può e chi non può. Esistono comunque una serie di ASIC (Application Specific Integrated Circuit… parolone che significa… Circuito integrato che si occupa di fare una certa applicazione) quali i dispositivi di FTDI, SILABS, Prolific, Etc… che convertono in maniera automatica e completa una porta USB in una porta di un certo tipo (normalmente una seriale RS232 a 3,3V) e che si possono usare senza grosse modifiche hardware e/o senza grossi tempi di sviluppo ed impegno, anche con microprocessori o microcontrollori di fascia bassa (ma proprio bassa).

A questo punto si può quindi connettere il dispositivo USB al nostro sistema, questi viene riconosciuto come porta seriale virtuale, e quindi utilizzarlo dal nostro programma .NET come una seriale (la faccio facile, ovviamente. In realtà prima di arrivare a questo punto bisogna scriversi lo stack, riprogrammare i driver, che NORMALMENTE nella CDC si trovano già fatti abbastanza ben funzionanti, ma è roba che, fatta una volta, si ricicla)

Tutto a posto, quindi?

Neanche per sogno, perché una porta seriale virtuale non è una porta seriale VERA. E non essendo una seriale vera pone in essere alcuni comportamenti diversi, talora bizzarri, grazie anche a “interazioni umane” non troppo ortodosse.

Vediamo di analizzare e di capire quali sono le differenze tra un dispositivo seriale reale ed uno virtuale.

La prima differenza sta nel numero della porta. Una porta seriale reale ha NORMALMENTE un suo ben preciso indirizzo fisico di I/O e nel numero con il quale la identifico. In realtà non è vera né la prima, né la seconda affermazione, poiché gli indirizzi sono decisi e riprogrammabili dalla logica del Pnp (il famoso Plug and play, conosciuto dai tecnici come Plug and PRAY, e dagli hardwaristi seri come PLUG AND CRY), ed il numero della porta seriale è modificabile.

Tuttavia nella vita di un normale PC questa cambierà BEN POCHE VOLTE.

Nelle seriali virtuali USB, invece, c’è buona probabilità che il numero della porta seriale non sia così… stabile, e questo dipende anche fortemente dalla versione del SO, e dal numero delle periferiche collegate e dall’ordine con cui queste vengono collegate. Non solo, anche cambiando l’ingresso USB fisico al quale il dispositivo viene collegato può cambiare il numero della COMport.

A dire il vero mi è capitato molto spesso su wXP, decisamente meno spesso su w7, segno che le cose su XP erano fatte decisamente più ad mentula canis di quanto non siano state fatte sui moderni sistemi operativi.

Tuttavia, se vengono collegati e scollegati numerosi dispositivi diversi la probabilità che si verifichi è tutt’altro che nulla, anche su w7. Tanto più se si lavora con il debugger e virtual-com attaccati contemporaneamente e si riprogramma il firmware a seriale aperta.

Questo implica quindi che a monte delle funzioni di comunicazione sia “buona pratica” cercare il numero della COMPort “incriminata”. Non solo. Implica pure che la porta seriale virtuale, o più correttamente, il dispositivo fisico possa non essere non connesso al PC, o che magari venga collegato o scollegato a programma aperto, magari mentre la comunicazione è in corso.

Nella mia attività di documentazione non ho mai trovato qualcuno che mi spiegasse come gestire queste situazioni, per le quali mi ero già rassegnato a “tacconare”

Nella mia funzione LeggiEScrivi trattata in uno dei miei post precedenti, ero riuscito a far si che il programma non andasse miseramente in crash in caso di disconnessione nella comunicazione. Tuttavia il problema era stato solo “tacconato” e non risolto.

Infatti, all’uscita del programma, veniva comunque ritornata una segnalazione di errore, dovuto al fatto che si tentava di distruggere un oggetto occupato o altre amenità del genere. Si tratta per lo più di pratiche “limite”, nel senso che bisogna che uno si ingegni per farle capitare. Tuttavia per quanto uno costruisca sistemi a prova di imbecille, esisterà sempre un imbecille a prova di tali sistemi.

La domanda è quindi una. Sono riuscito a risolvere ogni tipo di problema? La risposta è NO. Sono riuscito a risolvere ogni tipo di problema PER ORA NOTO. Rimango in attesa dell’ imbecille che rovini le mie certezze.

OK, adesso basta chiacchiere.

Cerca che ti ricerca ho trovato su CodeProject una bella libreria che svolge un buon 70% del lavoro sporco. Questa è stata scritta da Stéphane LELONG nel 2010 ed è reperibile a questo indirizzo.

Per essere usata c’è bisogno di “ritoccare” il codice. Niente di simile ad un trapianto di cuore, ma la cosa è discretamente invasiva. Le cose IMHO interessanti di questa libreria sono fondamentalmente due. La prima è la possibilità, dati VID e PID di un dispositivo, di recuperare in maniera semplice il numero della seriale virtuale. La seconda è la possibilità di intercettare l’inserimento ed il disinserimento del dispositivo incriminato. L’unico che mi pare realmente interessante è il disinserimento.

Come risalire al numero di porta seriale dal VID e dal PID.

La cosa è ABBASTANZA semplice.

Scaricare la libreria, quindi includerla nel proprio progetto (eventualmente anche in sorgente), quindi, all’interno della Form di comunicazione, dichiarare un oggetto di tipo DeviceProperties

Public USBDeviceProperties As USBClassLibrary.USBClass.DeviceProperties

quindi inizializzarlo con il metodo New

USBDeviceProperties = New USBClassLibrary.USBClass.DeviceProperties

Dopo di che si chiama la funzione shared GetUSBDevice della libreria, che, se il riesce a ritrovare il dispositivo, ci fornisce pure il numero della porta seriale

 If USBClassLibrary.USBClass.GetUSBDevice(CNST_VID_DISPOSITIVO, CNST_PID_DISPOSITIVO, USBDeviceProperties, True) = False Then             
	' Dispositivo non trovato... Messaggio di errore 	
	Exit Sub         
End If ComPortDispositivo = Me.USBDeviceProperties.COMPort

Incredibile ma vero… Tutto qui. Non facciamoci però prendere dai facili entusiasmi. Questa parte della libreria NON FUNZIONA (provato personalmente) con i dispositivi FTDI che tuttavia hanno analoghe librerie scritte apposta. Tuttavia funziona (provato personalmente) con SiLabs CP210X e con i miei dispositivi custom.

Veniamo ora alla parte più divertente. Come intercettare la rimozione del device.

Per prima cosa bisogna dichiarare un oggetto (io lo faccio normalmente a livello di Form) di tipo USBClass, ovviamente WithEvents.

    Public WithEvents USBPort As USBClassLibrary.USBClass

Quindi lo si inizializza, si associa il gestore dell’evento e si registra la Form chiamante per la ricezione dei messaggi da parte del sistema (Tutto fatto, quindi tranquilli)

	Me.USBPort = New USBClassLibrary.USBClass         
	AddHandler Me.USBPort.USBDeviceRemoved, AddressOf USBPort_USBDeviceRemoved         
	USBPort.RegisterForDeviceChange(True, Me)

A questo punto bisogna andare a modificare il ciclo messaggi della Form per inviare all’oggetto USBPort i messaggi che questi deve elaborare.

	Protected Overrides Sub WndProc(ByRef msg As System.Windows.Forms.Message)         
		If Not USBPort Is Nothing Then
             		USBPort.ProcessWindowsMessage(msg)         
		End If         
		MyBase.WndProc(msg)     End Sub

Nel funzionamento quindi, quando arriveranno messaggi da parte di Windows questi verranno interpretati sia dalla Form stessa che, a monte, dall’USBPort.

Questi, nella versione riveduta e corretta (da me) gestisce la rimozione della porta stessa in maniera opportuna e fa scattare l’evento di device rimosso, che io gestisco nella mia Form in maniera semplicissima

	Private Sub USBPort_USBDeviceRemoved(sender As Object, e As USBClassLibrary.USBClass.USBDeviceEventArgs)         
		If USBClassLibrary.USBClass.GetUSBDevice(CNST_VID_DISPOSITIVO, CNST_PID_DISPOSITIVO, USBDeviceProperties, True) = False Then
	        	PortaScollegata = True 	
			' Restante gestione         
		End If     
	End Sub

La funzione ScriviELeggi, deve essere quindi opportunamente modificata per gestire gli eventuali scollegamenti asincroni. Io l’ho quindi modificata così.

	Private Shared Function ScriviELeggi(Messaggio As String, TimeOutMilliseconds As Integer, ByRef Risultato As String) As Integer         
		Dim TimeOutCounter As Integer = 0         
		Dim SB As New StringBuilder         
		Dim c As String = ""         
		If PortaScollegata = False Then             
			If SPDispositivo Is Nothing Then                 
				Return 6             
			End If             
			If SPDispositivo.IsOpen = False Then                 
				Return 7             
			End If             
			SPDispositivo.DiscardInBuffer()             
			SPDispositivo.DiscardOutBuffer()         
		End If          
		Thread.Sleep(10)         
		Try             
			If PortaScollegata = False Then                 
				SPDispositivo.Write(Messaggio)             
			End If         
		Catch ex As Exception             
			Return 1         
		End Try          
		Thread.Sleep(10)         
		Try             
			While True                 
				If SPDispositivo Is Nothing Then                     
					Return 3
				End If                 
				If SPDispositivo.IsOpen = False Then                     
					Return 4                 
				End If                 
				While SPDispositivo.BytesToRead > 0                     
					If PortaScollegata = False Then
						c = Chr(SPDispositivo.ReadChar)
					End If                     
					If CondizioneDiUscita Then                         
						Risultato = SB.ToString
						Return 0                     
					Else                         
						SB.Append(c)                     
					End If                 
				End While                 
				Thread.Sleep(10)                 
				TimeOutCounter = TimeOutCounter + 10                 
				If TimeOutCounter > TimeOutMilliseconds Then 	
					Return 2                 
				End If             
			End While         
		Catch ex As Exception             
			Return 5         
		End Try          
		Return 0     
	End Function

Questa NON SONO RIUSCITO AD INCHIODARLA NEANCHE VOLENDO.

Rimane quindi la gestione dell’eliminazione dell’oggetto SerialPort che va fatta in una maniera un po’ turpe, alla chiusura della Form.

Questo è un risultato PRATICO che funziona

	If Not SPDispositivo Is Nothing Then             
		If Not PortaScollegata Then                 
			If SPDispositivo.IsOpen = True Then                     
				SPDispositivo.Close()                 
			End If              
		End If             
		Try                 
			SPDispositivo.Dispose()             
		Catch ex As Exception              
		End Try             
		SPDispositivo = Nothing         
	End If

Spero qualcuno possa trovare utili queste mie e rimango in attesa di commenti e/o correzioni.

Alla prossima

Mondo Embedded. Per gioco e per lavoro.

Tempo fa ero rimasto impressionato dalla STM32F4 Discovery, una scheda che, per la pazzesca cifra di circa 20 euro iva e spedizione inclusi, permetteva di fare esperimenti con il .NET Micro Framework. L’installazione del Net MF è un minimo “macchinosa”, ma una volta scaricato, si può cominciare.

Di contro, la scheda ha una serie di “limiti”. Essendo una “doppia faccia” (GLOM!) sono parecchio dubbioso sulle masse e sui disaccoppiamenti, manca un PHY per la rete, uno zoccolo per la SD ed il Codec Audio lo trovo piuttosto “limitato” rispetto alle applicazioni che si potrebbero effettuare con i dispositivi di cui sopra, ma per 20 euro non sono troppo autorizzato a rompere.

Fatti gli esperimenti e giocato un minimo mi sono riservato di preparare una scheda un minimo più funzionale, con le alimentazioni ed i disaccoppiamenti fatti un minimo più decentemente, con la periferia che mi serve, in formato SODIMM, che vedrà il mercato da fine settembre (trattandosi di prodotto commerciale, che oltretutto deve ancora uscire, mi è impossibile postare immagini e, ancora di più, schemi)

Ho quindi iniziato a fare il porting del firmware dell’apparecchiatura definitiva sul NetMF… salvo scoprire a metà del lavoro… che avevo due problemi.

Il primo era di velocità, il secondo era di spazio. La cosa, devo ammettere, mi ha lasciato basito visto che, trattandosi di PORTING ho già una apparecchiatura funzionante su un microcontrollore di classe decisamente inferiore (NXP LPC2368 a 57.6MHz). Tutto questo “merito” (scusate la sottile ironia) dell’ overhead del NetMF. Ok, ammetto di essere un minimo “carogna” perché come progetto di partenza ho usato un sistema hard real time con 42 task contemporanei (che nella nuova scheda aumenteranno di una decina per ovvi motivi), ma il micro in quanto tale ha sicuramente la capacità di effettuare tutte queste operazioni.

Con L’hardware definito ho voluto provare a valutare Kernel Real Time aventi caratteristiche di overhead di spazio e di tempo decisamente diversi. Uno lo conosco e lo uso da tempo, l’altro che non conoscevo e sono rispettivamente il FreeRTOS ed il ChibiOS/RT. Non è che ci siano differenze allucinanti tra il primo ed il secondo, se si conoscono i principi non ci sono grosse differenze di “usabilità” tra i due sistemi operativi. Secondo quella che è una opinione puramente personale, ho trovato il secondo decisamente più completo a livello di porting, mentre il primo è decisamente più “snello”. Ciò è anche dovuto al fatto che il ChibiOS/RT ha un porting veramente completo (grazie all’ottimo lavoro di Giovanni Di Sirio, deus ex machina di ChibiOS e dei suoi collaboratori), mentre il porting di FreeRTOS è abbastanza minimale e soprattutto non esistente per molti IDE.

Visto che adoro complicarmi la vita, per non lasciarmi mancare niente, per il FreeRTOS ho voluto usare l’IDE di CooCox, chiamato CoIDE, che è free ed usabile anche da un principiante. Il drawback è che rispetto agli altri IDE basati su Eclipse, alcune impostazioni della compilazione sono un po’ “nascoste”, o meglio, non sono dove sei abituato che siano. Il plus non indifferente è che in 10 minuti puoi partire a sviluppare sul silicio. Un altro plus altrettanto interessante è il numero enorme di “JTAG” supportati nativamente. Purtroppo CooCox supporta il PROPRIO sistema operativo (CoOS), che però non ha un porting ufficiale per il Cortex M4 e altrettanto non supporta il FreeRTOS (nel senso che esistono un paio di sample che però non sono riuscito a far funzionare). Data la mia elasticità mentale degna di un muro di granito, ho preso e fatto il porting praticamente “from scatch” partendo dai sorgenti e, alla fine, ho chiuso “la pratica” in un pomeriggio, facendo il porting sia per la STM32F4 Discovery che per la STM32-E407 di Olimex, una scheda decisamente più completa avente caratteristiche simili alla NetDuino Plus (il phy è decisamente migliore, due USB invece di uno, uno sfracello di I/O) ma di costo minore (così appare dal sito RobotItaly). Ovviamente mancano il porting del LWIP, della FatFS e dello stack USB. L’unico che mi da una qualche preoccupazione è comunque l’ultimo.

Rimane quindi da fare una piccolissima valutazione dell’overhead introdotto dal kernel in termini di spazio.

Dovendo far lampeggiare il classico led, lavorando sul “freddo silicio” si può scrivere un programma di qualche decina di byte in assembler, di qualche centinaio in C. Il FreeRTOS compilato in O0, comprensivo di codice per creare un thread ed il codice necessario per far lampeggiare un led “costa”, in termini di flash, circa 5650 bytes (configurazione minima) che fanno impallidire i quasi 640 del NetMF. In realtà il paragone è fuorviante visto che in questo momento il porting è minimale e praticamente senza periferia. Prometto di essere più preciso alla fine del porting, pari periferiche.

Compilazione

Qualora ci sia qualcuno altrettanto malato che voglia fare prove simili o voglia il mio porting del FreeRTOS su STM32F4 per CooCox, mi contatti pure.

A Presto