Programowanie funkcjonalne z MCU (s)

12

Języki funkcjonalne, takie jak Haskell, LISP lub Scheme, umożliwiają programistom szybką pracę przy użyciu funkcjonalnego paradygmatu programowania . Mają swoje nieefektywności , ale moja aplikacja kładzie większy nacisk na wydajność programisty niż na wydajność samego programu.

Chciałbym użyć programowania funkcjonalnego na mikrokontrolerze do sterowania maszyną itp.

Jakie są ograniczenia, takie jak minimalne zasoby systemowe?
Jakie przykładowe implementacje tych języków są dostępne?

J. Polfer
źródło
1
Jeśli twoje pytanie brzmi: „Czy nie warto programować żadnej maszyny z najpotężniejszym językiem programowania, jaki możesz dostać w swoje ręce?”, Zaleca się przeczytanie pytań w C ++ i Javie (raczej o OOP niż o programowaniu funkcjonalnym).
Kevin Vermeer
1
Twój pierwszy akapit jest argumentacyjny, co dało ci kilka bliskich głosów. Zastanów się nad przeredagowaniem na coś bardziej pasywnego („Jestem zainteresowany wykorzystaniem programowania funkcjonalnego do sterowania maszyną, jakie są przykłady implementacji Haskell / LISP / Scheme dla systemów wbudowanych”) lub jego całkowitym usunięciem.
Kevin Vermeer
2
Nie kupuję twojego „nieefektywnego” oświadczenia. Wydajesz się wykazywać skrajne uprzedzenie w stosunku do strony hobbystów / prototypów - niski poziom głośności (aka: 1). C / C ++ / asm daje mniejszy, szybszy kod, który jest wzmacniany tysiące lub miliony razy, gdy można używać procesorów o wystarczającej szybkości i przestrzeni. Osadzony jest osadzony. Nie programujesz w systemie operacyjnym ogólnego przeznaczenia.
Nick T
4
@Nick T - „C / C ++ / asm daje mniejszy, szybszy kod, który jest wzmacniany tysiące lub miliony razy, gdy można używać procesorów o wystarczającej szybkości i przestrzeni” - co z konserwacją? Język funkcjonalny może często robić w jednym wierszu to, co program C wymaga 10s, co oznacza mniej miejsca na błędy. Ponadto można je spełnić (np. Haskell) i uruchomić na celu, który jest szybszy niż tłumacze. Chciałem trochę zbadać ten temat, ponieważ skompilowany Haskell może być równie szybki, ale szybszy w opracowaniu niż powiedzmy aplikacja C. Chciałem trochę zakwestionować status quo.
J. Polfer,
1
@Sheepsimulator Niestety, komentarze takie jak twoje ostatnie powodują takie pytania.
Kellenjb

Odpowiedzi:

11

ARMPIT SCHEME to interpreter języka Scheme (dialekt w języku leksykalnym Lisp), który działa na mikrokontrolerach RISC z rdzeniem ARM. Opiera się na opisie w zmienionym raporcie na temat algorytmu języka algorytmicznego (r5rs), z pewnymi rozszerzeniami (dla I / O) i pewnymi pominięciami (aby zmieściły się w pamięci MCU). Jest ponadto zaprojektowany do obsługi wielozadaniowości i wieloprocesowości. Oczekuje się, że program pod pachami będzie dobrze dostosowany do warunków edukacyjnych, w tym projektów studenckich na kursach dotyczących kontroli i oprzyrządowania lub kursów projektowania zwieńczenia, w których potrzebne są mikrokontrolery. Ma on na celu wzbogacenie spektrum języków interpretowanych dostępnych dla MCU (np. BASIC i FORTH) i może być alternatywą dla opartych na MCU interpreterów kodu bajtowego (np. Dla Scheme lub Java) i języków skompilowanych (np. C).

http://armpit.sourceforge.net/

Mówisz:

Używanie C, C ++, asemblera itp. Jest dość nieefektywne w porównaniu do języków takich jak Haskell, LISP lub Scheme

Używanie języków wysokiego poziomu jest bardziej wydajnym wykorzystaniem czasu programisty, ale często może być mniej wydajnym wykorzystaniem zasobów obliczeniowych. W przypadku systemów wbudowanych produkowanych w dużych ilościach koszt i wydajność mają często wyższy priorytet niż prace rozwojowe.

Toby Jaffey
źródło
5

C, C ++ i asembler są bardzo zbliżone do języka maszynowego. Używając języka wyższego poziomu, dodajesz dodatkowy narzut w zamian za szybszy / łatwiejszy / itp. Rozwój.

pfyon
źródło
3
-1: Tak naprawdę nie zgadzam się z tą odpowiedzią. Chociaż masz rację, że asembler jest zbliżony do języka maszynowego, C i C ++ to bardzo różne języki wysokiego poziomu.
BG100
1
@ BG100, właściwie narysowałbym linię „wysokiego poziomu / niskiego poziomu” gdzieś w obrębie C, zamiast nazwać ją językiem wysokiego poziomu. Podczas wykonywania operacji arytmetycznych, wskaźnikowych (łańcuchowych) i innych typowych podstawowych zadań instrukcje generowane przez kompilatory mają procesor bezpośrednio przetwarzający dane bez żadnych warstw abstrakcji.
Nick T
@Nick T: Rozumiem, o co ci chodzi, ale zastanów się nad tym: jeśli napiszesz procedurę przerwania, która generalnie musi zostać wykonana tak szybko, jak to możliwe, w C nie będziesz miał pojęcia, ile czasu zajmie uruchomienie, ale w asemblerze możesz policz instrukcje. Myślę, że niski poziom wie, DOKŁADNIE dzieje się w twoim programie, nie wiesz tego na pewno, jeśli używasz C.
BG100
@ BG100: ta sama instrukcja asemblera może wymagać wykonania różnej liczby cykli w zależności od argumentów i ich trybów adresowania. Chociaż w C po kompilacji otrzymujesz kod statyczny, który się nie zmienia (nie może). To prawda, jest to nieco wątpliwy argument, ale jeśli mamy zamiar spierać się z drobiazgami, aby spróbować narysować wielką czerwoną linię ...
Nick T
3

Ostatnio programowałem tablicę ARM w Pythonie i myślę, że jest świetna. Nie nadaje się do kontroli w czasie rzeczywistym, ale robię więcej rzeczy związanych z siecią, co jest o wiele przyjemniejsze w języku wysokiego poziomu niż w C.

pingswept
źródło
3

Większość mikrokontrolerów to nadal urządzenia 8 i 16-bitowe (choć powoli się to zmienia). Dwa wystąpienia języków wyższego poziomu (Schemat i Python) wspomniane w innych odpowiedziach do tej pory działają na 32-bitowych rdzeniach ARM. Mniejsze 8 i 16-bitowe urządzenia (które mogą kosztować tylko kilka dolarów) nie mają wystarczającej ilości pamięci RAM do obsługi wymienionych języków - zazwyczaj mają tylko kilka KB pamięci RAM.

Ponadto te języki wyższego poziomu nie są przeznaczone do pisania programów obsługi przerwań o niskim opóźnieniu i tym podobnych. Nie jest niczym niezwykłym, że moduł obsługi przerwań mikrokontrolera jest wywoływany setki lub tysiące razy na sekundę i za każdym razem wymagany do wykonania swojego zadania w dziesiątkach mikrosekund lub mniej.

tcrosley
źródło
1
Program opracowano w połowie późnych lat 70. i bardzo wczesnych lat 80. W żadnym wypadku Schemat nie wymaga 32-bitowego procesora lub megabajtów pamięci. Schemat był dostępny dla komputerów klasy AT w połowie lat 80-tych. Najnowsze implementacje mogą być zoptymalizowane pod kątem środowisk bogatszych w zasoby, ale istnieją wyraźne przykłady schematów, które działają na dzisiejszych „miniaturowych” platformach obliczeniowych.
Photon
@ThePhoton I poprawiony. Chociaż byłem świadomy projektu BIT, który celuje w procesory z dziesiątkami KB pamięci (więcej niż jest to dostępne w większości małych mikrokontrolerów), właśnie odkryłem PICBIT , zaprojektowany przez kilku studentów z Université de Montréal i Université Laval, który pozwala prawdziwym programom Scheme działać na procesorach PIC z zaledwie 2 KB pamięci RAM. Całkiem niesamowite.
tcrosley,
3

Możliwe jest programowanie funkcjonalne w języku Lua. Naprawdę, Lua jest językiem paradygmatu; Wikipedia twierdzi, że jest to język „skryptowy, imperatywny, funkcjonalny, obiektowy, oparty na prototypach”. Język nie wymusza pojedynczego paradygmatu, ale jest wystarczająco elastyczny, aby pozwolić programiście na wdrożenie dowolnego paradygmatu mającego zastosowanie w danej sytuacji. Wpływ na to miał Schemat.

Funkcje Luy obejmują najwyższej klasy funkcje , zakresy leksykalne oraz zamknięcia i coroutines , które są przydatne do programowania funkcjonalnego. Możesz zobaczyć, jak te funkcje są używane na wiki użytkowników Lua, która ma stronę poświęconą programowaniu funkcjonalnemu . Natknąłem się również na ten projekt Google Code , ale go nie użyłem (twierdzi, że ma na niego wpływ Haskell, inny język, o którym wspomniałeś).

eLua jest implementacją dostępną skonfigurowaną dla wielu płyt programistycznych dla architektur ARM7TMDI, Cortex-M3, ARM966E-S i AVR32, i jest open source, dzięki czemu możesz skonfigurować ją dla własnej platformy. Lua jest zaimplementowana w ANSI C, a całe źródło waży poniżej 200kB, więc powinieneś być w stanie zbudować ją dla większości platform z kompilatorem C. Zalecane jest co najmniej 128 kB Flasha i 32 kB RAM. Obecnie pracuję nad portem PIC32 (wciąż na etapie „Pobierz kartę PIC32”).

Wspaniałą rzeczą w Lua jest to, że został zaprojektowany jako język kleju, więc bardzo łatwo jest pisać rozszerzenia C dla rzeczy, które muszą być szybkie (takie jak przerwania itp.), I używać dynamicznych, interpretowanych funkcji języka, aby robić szybkie rozwój w logice programu.

Lua nie jest językiem czysto funkcjonalnym, ale można w nim wykonać wiele funkcjonalnych programów, jest szybki i mały (w porównaniu do innych języków skryptowych ) i nie trzeba ponownie instalować urządzenia, aby wypróbować program. Jest nawet interaktywny tłumacz!

Kevin Vermeer
źródło
1

„Czy istnieją sposoby programowania funkcjonalnego za pomocą funkcjonalnego języka na MCU, aby rozwiązać trudne problemy?”

Tak, są sposoby. Ale wadą jest to, że potrzebujesz procesora 32-bitowego, MMU, 128 MB RAM, SSD, RTOS i $$$.

Mikrokontrolery różnią się od mikroprocesorów. Mikrokontroler może być tylko 8-bitowym procesorem, 1K RAM, 8K ROM, ale ma wbudowane UART, PWM, ADC itp. I kosztuje tylko 1,30 USD.

Możesz mieć uruchomione wszystkie języki wysokiego poziomu, ale zrobienie tego kosztuje o wiele więcej.

Robert
źródło
2
Myślę, że musisz ponownie sprawdzić swoją definicję mikrokontrolera. Wiele mikrokontrolerów ma teraz 128 kB lub więcej pamięci Flash i 64 kB lub więcej pamięci RAM, dużo miejsca na uruchomienie interpretera dla niektórych małych języków. Wygląda na to, że podajesz specyfikacje dla wbudowanego urządzenia Linux; Myślę, że OP poprosił o dedykowany port.
Kevin Vermeer
1
Jeśli płacisz 1,30 USD za 8-bitowy MCU, oznacza to, że istnieje kilka 32-bitowych MCU, które są tańsze. Weź również pod uwagę, że większość 8-bitowych MCU na rynku to okropnie nieefektywna architektura, a projekty odziedziczone od wczesnych lat 80-tych.
Lundin,
0

Ta książka zapewnia programowanie z lekkim wyczuciem FP. http://www.state-machine.com/psicc2/

Ale prawdziwe FP wymagają umiejętności konstruowania funkcji w czasie wykonywania i przekazywania ich w całym programie. Mamy tutaj problem: jak możemy przedstawić tę skonstruowaną funkcję? i jak możemy skutecznie wykonać tę funkcję? W dużym systemie możemy użyć kompilacji dynamicznej, która generuje prawdziwy kod maszynowy w aplikacji pierwszej funkcji. Na MCU mamy tylko pamięć RAM do implementacji bardzo prymitywnych kompilatorów, takich jak rdzeń języka Forth.

Jedynym sposobem na użycie FP lub OOP, jeśli wolisz, jest metaprogramowanie : pisanie złożonych programów funkcjonalnych / OOP , które generują programy dla MCU (na przykład kod źródłowy C lub LLVM IL). W tym wariancie nie ogranicza Cię złożoność paradygmatu ani metod programowania.

Dmitrij Ponyatov
źródło