Programmation fonctionnelle avec MCU (s)

12

Les langages fonctionnels comme Haskell, LISP ou Scheme permettent à un programmeur de travailler rapidement en utilisant le paradigme de programmation fonctionnelle . Ils ont leurs inefficacités , mais mon application met davantage l'accent sur l'efficacité du programmeur que sur l'efficacité du programme lui-même.

J'aimerais utiliser la programmation fonctionnelle sur un microcontrôleur pour faire le contrôle de la machine, etc.

Quelles sont les limitations, telles que les ressources système minimales?
Quels exemples d'implémentations de ces langages sont disponibles?

J. Polfer
la source
1
Si votre question est "Ne vaut-il pas la peine de programmer n'importe quelle machine avec le langage de programmation le plus puissant sur lequel vous pouvez mettre la main", les questions C ++ et Java sont recommandées (à propos de la POO plutôt que de la programmation fonctionnelle).
Kevin Vermeer
1
Votre premier paragraphe apparaît comme argumentatif, ce qui vous a valu quelques votes serrés. Envisagez de reformuler quelque chose de plus passif ("Je suis intéressé par l'utilisation de la programmation fonctionnelle pour le contrôle de la machine, quels sont les exemples d'implémentations Haskell / LISP / Scheme pour les systèmes embarqués") ou supprimez-le complètement.
Kevin Vermeer
2
Je n'achète pas votre déclaration "inefficace". Vous semblez montrer un parti pris extrême vers le côté amateur / prototype - faible volume (aka: 1). C / C ++ / asm donne un code plus petit et plus rapide qui est amplifié des milliers ou des millions de fois lorsque vous pouvez utiliser des processeurs avec juste assez de vitesse et d'espace. Embedded est embarqué. Vous ne programmez pas sur un système d'exploitation polyvalent.
Nick T
4
@Nick T - "C / C ++ / asm donne un code plus petit et plus rapide qui est amplifié des milliers ou des millions de fois lorsque vous pouvez utiliser des processeurs avec juste assez de vitesse et d'espace" - qu'en est-il de la maintenance? Un langage fonctionnel peut souvent faire en une seule ligne ce qu'un programme C nécessite 10 secondes, ce qui signifie moins de place pour les bogues. De plus, ils peuvent être respectés (c'est-à-dire Haskell) et exécutés sur la cible, ce qui est plus rapide que les interprètes. Je voulais explorer ce sujet un peu parce qu'un Haskell compilé pourrait être tout aussi rapide, mais plus rapide à développer que, disons, une application C. Je voulais remettre en question un peu le statu quo.
J.Polfer
1
@Sheepsimulator Malheureusement, des commentaires comme le dernier font des questions comme celle-ci argumentative.
Kellenjb

Réponses:

11

ARMPIT SCHEME est un interpréteur pour le langage Scheme (dialecte à portée lexicale de Lisp) qui s'exécute sur des microcontrôleurs RISC avec noyau ARM. Il est basé sur la description du rapport révisé sur le schéma de langage algorithmique (r5rs), avec quelques extensions (pour les E / S) et quelques omissions (pour tenir dans la mémoire du MCU). Il est en outre conçu pour prendre en charge le multitâche et le multitraitement. On s'attend à ce que le régime des aisselles soit bien adapté aux environnements éducatifs, y compris les projets des étudiants dans les cours de contrôle et d'instrumentation, ou les cours de conception de capstone où des microcontrôleurs sont nécessaires. Il est destiné à enrichir le spectre des langages interprétés disponibles pour les MCU (par exemple BASIC et FORTH) et peut être une alternative aux interprètes de bytecode basés sur MCU (par exemple pour Scheme ou Java) et aux langages compilés (par exemple C).

http://armpit.sourceforge.net/

Vous dites:

L'utilisation de C, C ++, d'assemblage, etc. est assez inefficace par rapport à des langages comme Haskell, LISP ou Scheme

L'utilisation de langages de haut niveau est une utilisation plus efficace du temps du programmeur, mais peut souvent être une utilisation moins efficace des ressources informatiques. Pour les systèmes embarqués fabriqués en volume, les coûts et les performances sont souvent plus prioritaires que les efforts de développement.

Toby Jaffey
la source
5

C, C ++ et Assembly sont tous très proches du langage machine. En utilisant un langage de niveau supérieur, vous ajoutez des frais généraux supplémentaires en échange d'un développement plus rapide / plus facile / etc.

pfyon
la source
3
-1: Je ne suis pas vraiment d'accord avec cette réponse. Bien que vous ayez le droit que Assembly soit proche du langage machine, C et C ++ sont des langages de haut niveau très différents.
BG100
1
@ BG100, je dessinerais en fait la ligne "haut niveau / bas niveau" quelque part dans C plutôt que de l'appeler simplement un langage de haut niveau. Lors de l'exécution d'opérations arithmétiques, de pointeurs (chaînes) et d'autres tâches de base courantes, les instructions que les compilateurs produisent généralement demandent au processeur de manipuler directement les données sans aucune couche d'abstraction.
Nick T
@ Nick T: Je vois votre point, mais considérez ceci: si vous écrivez une routine d'interruption qui doit généralement s'exécuter aussi rapidement que possible, en C, vous n'auriez aucune idée du temps qu'il faudrait pour exécuter, mais dans l'assembleur, vous pouvez il suffit de compter les instructions. Je pense que le niveau bas est de savoir EXACTEMENT ce qui se passe dans votre programme, vous ne savez pas avec certitude si vous utilisez C.
BG100
@ BG100: la même instruction d'assembleur peut prendre différents nombres de cycles à exécuter en fonction des opérandes et de leurs modes d'adressage. Bien qu'en C, une fois que vous avez compilé, vous obtenez du code statique qui ne change pas (ne peut pas). C'est vrai, c'est un argument quelque peu ténu, mais si nous allons discuter des détails pour essayer de tracer une grande ligne rouge ...
Nick T
3

J'ai programmé une carte ARM en Python récemment, et je pense que c'est génial. Ce n'est pas bon pour le contrôle en temps réel, mais je fais plus de choses liées au Web, ce qui est beaucoup plus agréable dans un langage de haut niveau qu'en C.

pingswept
la source
3

La majorité des microcontrôleurs sont toujours des appareils 8 et 16 bits (bien que cela change lentement). Les deux instances de langages de niveau supérieur (Scheme et Python) mentionnées dans d'autres réponses jusqu'à présent fonctionnent toutes les deux sur des cœurs ARM 32 bits. Les petits appareils 8 et 16 bits (qui peuvent ne coûter que quelques dollars) n'ont pas assez de RAM pour prendre en charge les langues mentionnées - généralement, ils n'ont que quelques Ko de RAM.

En outre, ces langages de niveau supérieur ne sont pas conçus pour écrire des gestionnaires d'interruption à faible latence et similaires. Il n'est pas rare qu'un gestionnaire d'interruption de microcontrôleur soit appelé des centaines ou des milliers de fois par seconde, et chaque fois nécessaire pour effectuer sa tâche en quelques dizaines de microsecondes ou moins.

tcrosley
la source
1
Le programme a été développé à la mi-fin des années 70 et au tout début des années 80. Scheme ne nécessite en aucun cas un processeur 32 bits ou des mégaoctets de mémoire. Le schéma était disponible pour les PC de classe AT au milieu des années 80. Les implémentations récentes peuvent être optimisées pour des environnements plus riches en ressources, mais il existe des exemples clairs de schémas qui s'exécutent sur ce qui est aujourd'hui des plates-formes informatiques "minuscules".
The Photon
@ThePhoton je me tiens corrigé. Bien que je connaissais le projet BIT, qui cible les processeurs avec des dizaines de Ko de mémoire (plus que ce qui est disponible sur la plupart des petits microcontrôleurs), je viens de découvrir PICBIT , conçu par deux étudiants de l'Université de Montréal et de l'Université Laval, ce qui permet aux vrais programmes Scheme de s'exécuter sur des processeurs PIC avec aussi peu que 2K de RAM. Assez étonnant.
tcrosley
3

Il est possible de faire de la programmation fonctionnelle avec le langage Lua. Vraiment, Lua est une langue multi-paradigme; Wikipédia affirme qu'il s'agit d'un langage «scripté, impératif, fonctionnel, orienté objet, basé sur un prototype». Le langage n'applique pas un seul paradigme, mais est à la place suffisamment flexible pour permettre au programmeur de mettre en œuvre le paradigme applicable à la situation. Il a été influencé par Scheme.

Les fonctionnalités de Lua incluent des fonctions de première classe , la portée lexicale et les fermetures et coroutines , qui sont utiles pour la programmation fonctionnelle. Vous pouvez voir comment ces fonctionnalités sont utilisées sur le wiki des utilisateurs de Lua, qui a une page dédiée à la programmation fonctionnelle . J'ai également rencontré ce projet Google Code , mais je ne l'ai pas utilisé (il prétend être influencé par Haskell, une autre langue que vous avez mentionnée).

eLua est une implémentation disponible configurée pour un certain nombre de cartes de développement pour les architectures ARM7TMDI, Cortex-M3, ARM966E-S et AVR32, et est open-source afin que vous puissiez la configurer pour votre propre plate-forme. Lua est implémenté en ANSI C et la source entière pèse moins de 200 Ko, vous devriez donc pouvoir le construire pour la plupart des plates-formes avec un compilateur C. Au moins 128k de Flash et 32k de RAM est recommandé. Je travaille sur un port PIC32 pour celui-ci (toujours à l'étape "Get the PIC32 board", cependant) pour le moment.

La grande chose à propos de Lua est qu'il a été conçu comme un langage de collage, il est donc très facile d'écrire des extensions C pour les choses qui doivent être rapides (comme les interruptions, etc.), et d'utiliser les fonctionnalités dynamiques et interprétées du langage pour faire rapidement développement dans la logique du programme.

Lua n'est pas un langage purement fonctionnel, mais vous pouvez y faire beaucoup de programmation fonctionnelle, il est rapide et petit ( par rapport aux autres langages de script ), et vous n'avez pas besoin de reflasher votre appareil pour essayer un programme. Il y a même un interprète interactif!

Kevin Vermeer
la source
1

"Existe-t-il des moyens de faire une programmation fonctionnelle avec un langage fonctionnel sur un MCU pour résoudre des problèmes difficiles?"

Oui, il existe des moyens. Mais l'inconvénient est que vous avez besoin d'un processeur 32 bits, MMU, 128 Mo de RAM, SSD, un RTOS et $$$.

Les microcontrôleurs sont différents des microprocesseurs. Le microcontrôleur ne peut être qu'un processeur 8 bits, 1 Ko de RAM, 8 Ko de ROM, mais il a un UART, PWM, ADC intégré, etc. Et cela ne coûte que 1,30 $.

Donc, vous pourriez avoir toutes ces langues de haut niveau en cours d'exécution, mais cela coûte beaucoup plus cher à faire.

Robert
la source
2
Je pense que vous devez revoir votre définition de microcontrôleur. De nombreux microcontrôleurs ont maintenant 128 Ko ou plus de Flash et 64 Ko ou plus de RAM, beaucoup d'espace pour exécuter un interpréteur pour certaines langues de petite taille. Il semble que vous donniez des spécifications pour un périphérique Linux intégré; Je pense que l'OP demandait un port dédié.
Kevin Vermeer
1
Si vous payez 1,30 $ pour un MCU 8 bits, il existe plusieurs MCU 32 bits moins chers. Prenez également en compte que la plupart des microcontrôleurs 8 bits sur le marché sont des architectures horriblement inefficaces sur le code, avec des conceptions héritées du début des années 80.
Lundin
0

Ce livre fournit un moyen de faire de la programmation avec une sensation légère de FP. http://www.state-machine.com/psicc2/

Mais le vrai FP nécessite d'avoir la capacité de construire des fonctions en runtime et de les transmettre à travers votre programme. Ici, nous avons un problème: comment représenter cette fonction construite? et comment pouvons-nous exécuter efficacement cette fonction? Sur un grand système, nous pouvons utiliser une compilation dynamique qui génère du code machine réel sur une application de première fonction. Sur MCU, nous n'avons que de la RAM pour implémenter des compilateurs très primitifs comme le noyau du langage Forth.

La seule façon d'utiliser FP ou OOP si vous préférez c'est la métaprogrammation : écrire des programmes fonctionnels / OOP complexes qui génèrent des programmes pour MCU (code source C par exemple, ou LLVM IL). Dans cette variante, vous n'êtes pas limité par le paradigme ou la complexité des méthodes de programmation.

Dmitry Ponyatov
la source