Programación funcional con MCU (s)

12

Los lenguajes funcionales como Haskell, LISP o Scheme permiten que un programador trabaje rápidamente usando el paradigma de programación funcional . Tienen sus ineficiencias , pero mi aplicación pone mayor énfasis en la eficiencia del programador que en la eficiencia del programa en sí.

Me gustaría usar la programación funcional en un microcontrolador para hacer el control de la máquina, etc.

¿Qué limitaciones existen, como los recursos mínimos del sistema?
¿Qué implementaciones de ejemplo de estos idiomas están disponibles?

J. Polfer
fuente
1
Si su pregunta es "¿No vale la pena programar cualquier máquina con el lenguaje de programación más potente que pueda tener en sus manos", se recomienda leer las preguntas de C ++ y Java (sobre OOP en lugar de programación funcional).
Kevin Vermeer
1
Su primer párrafo se presenta como argumentativo, lo que le ha valido algunos votos cercanos. Considere la posibilidad de volver a redactar algo más pasivo ("Estoy interesado en utilizar la programación funcional para el control de la máquina, qué ejemplos hay de implementaciones Haskell / LISP / Scheme para sistemas integrados") o eliminarlo por completo.
Kevin Vermeer
2
No compro su declaración "ineficiente". Parece exhibir un sesgo extremo hacia el lado del aficionado / prototipo: bajo volumen (también conocido como: 1). C / C ++ / asm da como resultado un código más pequeño y rápido que se amplifica miles o millones de veces cuando puede usar procesadores con la velocidad y el espacio suficientes. Embebido está incrustado. No está programando en un sistema operativo de uso general.
Nick T
44
@Nick T: "C / C ++ / asm da como resultado un código más pequeño y rápido que se amplifica miles o millones de veces cuando puede usar procesadores con la velocidad y el espacio suficientes", ¿qué pasa con el mantenimiento? Un lenguaje funcional con frecuencia puede hacer en una sola línea lo que un programa C requiere 10s para hacer, lo que significa menos espacio para errores. Además, se pueden cumplir (es decir, Haskell) y hacer que se ejecuten en el objetivo, que es más rápido que los intérpretes. Quería explorar este tema un poco porque un Haskell compilado podría ser igual de rápido, pero más rápido de desarrollar que decir una aplicación C. Quería cuestionar un poco el status quo.
J. Polfer
1
@Sheepsimulator Desafortunadamente, comentarios como el último hacen preguntas como esta argumentativas.
Kellenjb

Respuestas:

11

ARMPIT SCHEME es un intérprete para el lenguaje Scheme (dialecto léxico de Lisp) que se ejecuta en microcontroladores RISC con núcleo ARM. Se basa en la descripción en el Informe revisado sobre el esquema de lenguaje algorítmico (r5rs), con algunas extensiones (para E / S) y algunas omisiones (para caber dentro de la memoria MCU). Además, está diseñado para admitir la multitarea y el multiprocesamiento. Se espera que el Esquema de axilas se adapte bien a entornos educativos, incluidos proyectos de estudiantes en cursos de control e instrumentación, o cursos de diseño final donde se necesitan microcontroladores. Su objetivo es enriquecer el espectro de idiomas interpretados disponibles para MCU (por ejemplo, BASIC y FORTH) y puede ser una alternativa a los intérpretes de código de bytes basados ​​en MCU (por ejemplo, para Scheme o Java) y a los lenguajes compilados (por ejemplo, C).

http://armpit.sourceforge.net/

Tu dices:

Usar C, C ++, ensamblaje, etc. es bastante ineficiente en comparación con lenguajes como Haskell, LISP o Scheme

El uso de lenguajes de alto nivel es un uso más eficiente del tiempo del programador, pero a menudo puede ser un uso menos eficiente de los recursos informáticos. Para los sistemas embebidos fabricados en volumen, el costo y el rendimiento son a menudo de mayor prioridad que el esfuerzo de desarrollo.

Toby Jaffey
fuente
5

C, C ++ y Assembly están muy cerca del lenguaje de máquina. Al utilizar un lenguaje de nivel superior, está agregando una sobrecarga adicional a cambio de un desarrollo más rápido / más fácil / etc.

pfyon
fuente
3
-1: Realmente no estoy de acuerdo con esta respuesta. Aunque tiene razón acerca de que Assembly está cerca del lenguaje de máquina, C y C ++ son lenguajes de alto nivel muy diferentes.
BG100
1
@ BG100, en realidad dibujaría la línea de "alto nivel / bajo nivel" en algún lugar dentro de C en lugar de simplemente llamarlo un lenguaje de alto nivel. Al realizar operaciones aritméticas, de puntero (cadena) y otras tareas básicas comunes, las instrucciones que los compiladores generalmente producen hacen que la CPU manipule directamente los datos sin ninguna capa de abstracción.
Nick T
@ Nick T: veo su punto, pero considere esto: si escribe una rutina de interrupción que generalmente necesita ejecutarse lo más rápido posible, en C no tendría idea de cuánto tiempo tomaría ejecutar, pero en ensamblador podría solo cuenta las instrucciones. Creo que el nivel bajo es saber que EXACTAMENTE estaba sucediendo en su programa, no lo sabe con certeza si está usando C.
BG100
@ BG100: la misma instrucción de ensamblador puede tomar diferentes números de ciclos para ejecutarse según los operandos y sus modos de direccionamiento. Aunque en C, una vez que compila, obtiene un código estático que no cambia (no puede). Es cierto, este es un argumento algo tenue, pero si vamos a discutir las minucias para tratar de dibujar una gran línea roja ...
Nick T
3

He estado programando una placa ARM en Python recientemente, y creo que es genial. No es bueno para el control en tiempo real, pero estoy haciendo más cosas relacionadas con la web, lo que es mucho más agradable en un lenguaje de alto nivel que en C.

pingswept
fuente
3

La mayoría de los microcontroladores siguen siendo dispositivos de 8 y 16 bits (aunque esto está cambiando lentamente). Las dos instancias de lenguajes de nivel superior (Scheme y Python) mencionados en otras respuestas hasta ahora se ejecutan en núcleos ARM de 32 bits. Los dispositivos más pequeños de 8 y 16 bits (que pueden costar solo un par de dólares) no tienen suficiente RAM para admitir los idiomas que se mencionan, por lo general, solo tienen unos pocos KB de RAM.

Además, estos lenguajes de nivel superior no están diseñados para escribir manejadores de interrupciones de baja latencia y similares. No es inusual que un controlador de interrupciones de microcontrolador sea llamado cientos o miles de veces por segundo, y cada vez que sea necesario para realizar su tarea en decenas de microsegundos o menos.

tcrosley
fuente
1
El esquema se desarrolló a mediados de los años 70 y principios de los 80. Scheme de ninguna manera requiere un procesador de 32 bits o megabytes de memoria. Scheme estaba disponible para PC de clase AT a mediados de los 80. Las implementaciones recientes pueden optimizarse para entornos con más recursos, pero hay ejemplos claros de esquemas que se ejecutan en lo que hoy son plataformas informáticas "minúsculas".
The Photon
@ThePhoton Estoy corregido. Aunque conocía el proyecto BIT, que apunta a procesadores con decenas de KB de memoria (más de lo que está disponible en la mayoría de los microcontroladores pequeños), acabo de descubrir PICBIT , diseñado por un par de estudiantes de la Universidad de Montreal y la Universidad Laval, lo que permite que los programas Scheme reales se ejecuten en procesadores PIC con tan solo 2K de RAM. Bastante impresionante.
tcrosley
3

Es posible hacer una programación funcional con el lenguaje Lua. Realmente, Lua es un lenguaje de paradigmas múltiples; Wikipedia afirma que es un lenguaje 'scripting, imperativo, funcional, orientado a objetos y basado en prototipos'. El lenguaje no aplica un solo paradigma, sino que es lo suficientemente flexible como para permitir que el programador implemente cualquier paradigma que sea aplicable a la situación. Ha sido influenciado por Scheme.

Las características de Lua incluyen funciones de primera clase , alcance léxico y cierres y corutinas , que son útiles para la programación funcional. Puede ver cómo se utilizan estas funciones en el wiki de usuarios de Lua, que tiene una página dedicada a la programación funcional . También me encontré con este proyecto de Google Code , pero no lo he usado (afirma estar influenciado por Haskell, otro idioma que mencionaste).

eLua es una implementación que está disponible configurada para varias placas de desarrollo para las arquitecturas ARM7TMDI, Cortex-M3, ARM966E-S y AVR32, y es de código abierto para que pueda configurarla para su propia plataforma. Lua se implementa en ANSI C y toda la fuente pesa menos de 200kB, por lo que debería poder compilarla para la mayoría de las plataformas con un compilador de C. Se recomienda al menos 128k de Flash y 32k de RAM. Estoy trabajando en un puerto PIC32 para él (todavía en la etapa 'Obtener la placa PIC32') en este momento.

Lo mejor de Lua es que fue diseñado como un lenguaje de pegamento, por lo que es muy fácil escribir extensiones C para las cosas que deben ser rápidas (como interrupciones, etc.) y usar las características dinámicas e interpretadas del lenguaje para hacerlo rápido desarrollo en la lógica del programa.

Lua no es un lenguaje puramente funcional, pero puede hacer mucha programación funcional en él, es rápido y pequeño (en comparación con otros lenguajes de secuencias de comandos ), y no necesita volver a actualizar su dispositivo para probar un programa. ¡Incluso hay un intérprete interactivo!

Kevin Vermeer
fuente
1

"¿Hay maneras de hacer programación funcional con un lenguaje funcional en una MCU para resolver problemas difíciles?"

Sí, hay formas Pero la desventaja es que necesita un procesador de 32 bits, MMU, 128 MB de RAM, SSD, un RTOS y $$$.

Los microcontroladores son diferentes a los microprocesadores. El microcontrolador solo puede ser una CPU de 8 bits, 1K RAM, 8K ROM, pero tiene un UART, PWM, ADC incorporado, etc. Y solo cuesta $ 1.30.

Por lo tanto, podría tener todos esos lenguajes de alto nivel ejecutándose, pero cuesta mucho más hacerlos.

Robert
fuente
2
Creo que necesita revisar su definición de microcontrolador. Muchos microcontroladores ahora tienen 128kB o más de Flash y 64kB o más de RAM, mucho espacio para ejecutar un intérprete para algunos idiomas más pequeños. Parece que estás dando especificaciones para un dispositivo Linux incorporado; Creo que el OP estaba pidiendo un puerto dedicado.
Kevin Vermeer
1
Si está pagando $ 1.30 por una MCU de 8 bits, existen varias MCU de 32 bits que son más baratas. Además, tenga en cuenta que la mayoría de las MCU de 8 bits en el mercado son arquitecturas terriblemente ineficaces para el código, con diseños heredados de principios de los años 80.
Lundin
0

Este libro proporciona alguna forma de programar con una ligera sensación de FP. http://www.state-machine.com/psicc2/

Pero la FP real requiere tener la capacidad de construir funciones en tiempo de ejecución y pasarlas a través de su programa. Aquí tenemos un problema: ¿cómo podemos representar esta función construida? ¿Y cómo podemos ejecutar efectivamente esta función? En un sistema grande, podemos usar una compilación dinámica que genera código de máquina real en una aplicación de primera función. En MCU solo tenemos RAM para implementar compiladores muy primitivos como Forth Language Core.

La única forma en que puede usar FP u OOP si lo prefiere es la metaprogramación : escriba programas funcionales / OOP complejos que generen programas para MCU (código fuente C, por ejemplo, o LLVM IL). En esta variante, no está limitado por la complejidad del paradigma o los métodos de programación.

Dmitry Ponyatov
fuente