Programmazione funzionale con MCU (s)


12

Linguaggi funzionali come Haskell, LISP o Scheme consentono a un programmatore di lavorare rapidamente utilizzando il paradigma di programmazione funzionale . Hanno le loro inefficienze , ma la mia applicazione pone maggiore enfasi sull'efficienza del programmatore rispetto all'efficienza del programma stesso.

Vorrei usare la programmazione funzionale su un microcontrollore per eseguire il controllo della macchina, ecc.

Quali sono le limitazioni, come le risorse di sistema minime?
Quali esempi di implementazioni di queste lingue sono disponibili?


1
Se la tua domanda è "Non vale la pena programmare una macchina con il linguaggio di programmazione più potente su cui puoi mettere le mani", si consiglia di leggere le domande C ++ e Java (su OOP piuttosto che sulla programmazione funzionale).
Kevin Vermeer,

1
Il tuo primo paragrafo si presenta come argomentativo, il che ti ha permesso di ottenere alcuni voti stretti. Prendi in considerazione l'idea di riformulare qualcosa di più passivo ("Sono interessato a utilizzare la programmazione funzionale per il controllo della macchina, quali esempi ci sono delle implementazioni di Haskell / LISP / Scheme per sistemi integrati") o di rimuoverlo del tutto.
Kevin Vermeer,

2
Non compro la tua dichiarazione "inefficiente". Sembra che mostri un'estrema propensione verso l'hobbista / lato prototipo - volume basso (aka: 1). C / C ++ / asm produce codice più piccolo e più veloce che viene amplificato migliaia o milioni di volte quando è possibile utilizzare processori con velocità e spazio sufficienti. Incorporato è incorporato. Non si sta programmando su un sistema operativo generico.
Nick T,

4
@Nick T - "C / C ++ / asm si traduce in un codice più piccolo e più veloce che viene amplificato migliaia o milioni di volte quando è possibile utilizzare processori con velocità e spazio sufficienti" - che dire della manutenzione? Un linguaggio funzionale può spesso fare in una sola riga ciò che un programma C richiede 10 secondi, il che significa meno spazio per i bug. Inoltre, possono essere rispettati (cioè Haskell) e fatti funzionare sul bersaglio, che è più veloce degli interpreti. Volevo esplorare questo argomento un po 'perché un Haskell compilato potrebbe essere altrettanto veloce, ma più veloce da sviluppare di una app in C. Volevo mettere in discussione lo status quo un po '.
J. Polfer,

1
@Sheepsimulator Sfortunatamente, commenti come il tuo ultimo fanno domande come questa argomentativa.
Kellenjb,

Risposte:


11

ARMPIT SCHEME è un interprete per il linguaggio Scheme (dialetto con finalità lessicale di Lisp) che gira su microcontrollori RISC con core ARM. Si basa sulla descrizione contenuta nella relazione rivista sullo schema del linguaggio algoritmico (r5rs), con alcune estensioni (per I / O) e alcune omissioni (per adattarsi alla memoria MCU). È inoltre progettato per supportare il multitasking e il multiprocessing. Si prevede che lo schema delle ascelle sia adatto agli ambienti educativi, compresi i progetti degli studenti in corsi di controllo e strumentazione o corsi di progettazione capstone in cui sono necessari microcontrollori. Ha lo scopo di arricchire lo spettro di linguaggi interpretati disponibili per MCU (es. BASIC e FORTH) e può essere un'alternativa agli interpreti bytecode basati su MCU (es. Per Scheme o Java) e linguaggi compilati (es. C).

http://armpit.sourceforge.net/

Tu dici:

L'uso di C, C ++, assembly, ecc. È abbastanza inefficiente rispetto a linguaggi come Haskell, LISP o Scheme

L'uso di linguaggi di alto livello è un uso più efficiente del tempo del programmatore, ma spesso può essere un uso meno efficiente delle risorse di elaborazione. Per i sistemi embedded prodotti in volume, i costi e le prestazioni sono spesso una priorità più alta rispetto allo sforzo di sviluppo.



5

C, C ++ e Assembly sono tutti molto vicini al linguaggio macchina. Utilizzando un linguaggio di livello superiore, si aggiunge un sovraccarico aggiuntivo in cambio di uno sviluppo più rapido / più semplice / ecc.


3
-1: Non sono davvero d'accordo con questa risposta. Sebbene il diritto di Assembly sia vicino al linguaggio macchina, C e C ++ sono linguaggi di alto livello molto diversi.
BG100,

1
@ BG100, in realtà traccerei la linea "alto / basso livello" da qualche parte all'interno di C piuttosto che chiamarla semplicemente un linguaggio di alto livello. Quando si eseguono operazioni aritmetiche, di puntatore (stringa) e altre attività di base comuni, le istruzioni che i compilatori generano generalmente fanno sì che la CPU manipoli direttamente i dati senza alcun livello di astrazione.
Nick T,

@Nick T: Vedo il tuo punto, ma considero questo: se scrivi una routine di interrupt che generalmente deve essere eseguita il più rapidamente possibile, in C non avresti idea di quanto tempo ci vorrebbe per eseguire, ma in assemblatore puoi basta contare le istruzioni. Penso che il livello basso sappia che ESATTAMENTE stava succedendo nel tuo programma, non lo sai con certezza se usi C.
BG100

@ BG100: l'esecuzione della stessa istruzione assembler può richiedere diversi numeri di cicli in base agli operandi e alle loro modalità di indirizzamento. Anche se in C, una volta compilato ottieni codice statico che non può (non può) cambiare. È vero, questo è un argomento piuttosto tenue, ma se discuteremo delle minuzie per provare a tracciare una grande linea rossa ...
Nick T,

3

Di recente ho programmato una scheda ARM in Python e penso che sia fantastico. Non va bene per il controllo in tempo reale, ma sto facendo più cose legate al web, il che è molto più piacevole in un linguaggio di alto livello che in C.


3

La maggior parte dei microcontrollori sono ancora dispositivi a 8 e 16 bit (anche se questo sta lentamente cambiando). Le due istanze di linguaggi di livello superiore (Scheme e Python) menzionate finora in altre risposte sono entrambe in esecuzione su core ARM a 32 bit. I dispositivi più piccoli a 8 e 16 bit (che possono costare solo un paio di dollari) non hanno abbastanza RAM per supportare le lingue menzionate - in genere hanno solo pochi KB di RAM.

Inoltre, questi linguaggi di livello superiore non sono progettati per scrivere gestori di interrupt a bassa latenza e simili. Non è insolito che un gestore di interrupt di microcontrollori venga chiamato centinaia o migliaia di volte al secondo, e ogni volta richiesto di svolgere il proprio compito in decine di microsecondi o meno.


1
Lo schema è stato sviluppato tra la metà degli anni '70 e l'inizio degli anni '80. Scheme non richiede in alcun modo un processore a 32 bit o megabyte di memoria. Lo schema era disponibile per PC di classe AT a metà degli anni '80. Le implementazioni recenti potrebbero essere ottimizzate per ambienti più ricchi di risorse, ma ci sono chiari esempi di schemi che girano su quelle che oggi sono piattaforme di elaborazione "minuscole".
The Photon,

@ThePhoton Sono corretto. Sebbene fossi a conoscenza del progetto BIT, che si rivolge a processori con decine di KB di memoria (più di quello che è disponibile sulla maggior parte dei microcontrollori), ho appena scoperto PICBIT , progettato da un paio di studenti all'Università di Montréal e all'Università Laval, che consente l'esecuzione di programmi Scheme reali su processori PIC con un minimo di 2 KB di RAM. Piuttosto sorprendente.
Tcrosley,

3

È possibile eseguire alcune programmazioni funzionali con il linguaggio Lua. Davvero, Lua è un linguaggio a più paradigmi; Wikipedia afferma che è un linguaggio "scripting, imperativo, funzionale, orientato agli oggetti, basato sui prototipi". Il linguaggio non applica un singolo paradigma, ma è abbastanza flessibile da consentire al programmatore di implementare qualunque paradigma applicabile alla situazione. È stato influenzato da Scheme.

Le caratteristiche di Lua includono funzioni di prima classe , scoping e chiusure lessicali e coroutine , utili per la programmazione funzionale. Puoi vedere come vengono utilizzate queste funzionalità nella wiki degli utenti Lua, che ha una pagina dedicata alla programmazione funzionale . Mi sono anche imbattuto in questo progetto di Google Code , ma non l'ho usato (afferma di essere influenzato da Haskell, un'altra lingua che hai menzionato).

eLua è un'implementazione disponibile configurata per una serie di schede di sviluppo per le architetture ARM7TMDI, Cortex-M3, ARM966E-S e AVR32 ed è open source in modo da poterlo configurare per la propria piattaforma. Lua è implementato in ANSI C e l'intera sorgente pesa meno di 200 kB, quindi dovresti essere in grado di costruirlo per la maggior parte delle piattaforme con un compilatore C. Si raccomandano almeno 128k di Flash e 32k di RAM. Al momento sto lavorando su una porta PIC32 (ancora nella fase 'Ottieni la scheda PIC32').

La cosa grandiosa di Lua è che è stato progettato come un linguaggio di colla, quindi è molto facile scrivere estensioni in C per le cose che devono essere veloci (come interruzioni, ecc.) E usare le caratteristiche dinamiche e interpretate del linguaggio per fare rapidamente sviluppo nella logica del programma.

Lua non è un linguaggio puramente funzionale, ma puoi fare molta programmazione funzionale, è veloce e piccolo ( rispetto ad altri linguaggi di scripting ) e non è necessario eseguire il reflash del dispositivo per provare un programma. C'è persino un interprete interattivo!


1

"Esistono modi per eseguire la programmazione funzionale con un linguaggio funzionale su un MCU per risolvere problemi difficili?"

Sì, ci sono modi. Ma il rovescio della medaglia è che hai bisogno di un processore a 32 bit, MMU, 128 MB di RAM, SSD, un RTOS e $$$.

I microcontrollori sono diversi dai microprocessori. Il microcontrollore può essere solo una CPU a 8 bit, 1K RAM, 8K ROM, ma ha un UART integrato, PWM, ADC, ecc. E costa solo $ 1,30.

Quindi potresti avere tutte quelle lingue di alto livello in esecuzione, ma costa molto di più da realizzare.


2
Penso che devi rivisitare la tua definizione di microcontrollore. Molti microcontrollori ora hanno 128kB o più di Flash e 64kB o più di RAM, un sacco di spazio per eseguire un interprete per alcune lingue di piccole dimensioni. Sembra che tu stia fornendo specifiche per un dispositivo Linux incorporato; Penso che l'OP chiedesse una porta dedicata.
Kevin Vermeer,

1
Se stai pagando $ 1,30 per un MCU a 8 bit, allora ci sono diversi MCU a 32 bit che sono più economici. Inoltre, tieni presente che la maggior parte degli MCU a 8 bit sul mercato sono architetture orribilmente inefficaci dal codice, con progetti ereditati dai primi anni '80.
Lundin,

0

Questo libro fornisce un modo per fare la programmazione con una leggera sensazione di FP. http://www.state-machine.com/psicc2/

Ma il vero FP richiede di avere la capacità di costruire funzioni in fase di esecuzione e passarle attraverso il programma. Qui abbiamo un problema: come possiamo rappresentare questa funzione costruita? e come possiamo eseguire efficacemente questa funzione? Su un sistema di grandi dimensioni, possiamo usare la compilazione dinamica che genera codice macchina reale su una prima applicazione di funzione. Su MCU abbiamo solo RAM per implementare compilatori molto primitivi come il core del linguaggio Forth.

L'unico modo in cui puoi usare FP o OOP se preferisci è la metaprogrammazione : scrivere programmi funzionali / OOP complessi che generano programmi per MCU (ad esempio codice sorgente C o LLVM IL). In questa variante, non sei limitato dal paradigma o dalla complessità dei metodi di programmazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.