News Kaluma: Javascript-Ausführungsumgebung für den RP2040


von Tam H. (Firma: Tamoggemon Holding k.s.) (tamhanna)


Angehängte Dateien:

Lesenswert?

Die Ausführung von Hochsprachen auf Mikrocontrollern trägt - seit jeher - zu einer Reduktion der Code-Koppelung in der Gesamtlösung bei. Mit Kaluma steht eine Runtime zur Verfügung, die auf die Bedürfnisse von Ebenezer Uptons Mikrocontrollerfamilie optimiert ist.

In diesem Artikel werden wir Experimente mit der Architektur und der Runtime durchführen, um mehr über Handling und internen Aufbau der Engine zu erfahren. Grundkenntnisse im Bereich der Mikrocontrollerhardware werden dabei als gegeben vorausgesetzt.

Auswahl der Zielarchitektur.

Der RP2040 wird - Drittanbieterboards wollen wir an dieser Stelle ignorieren - vor allem in zwei Varianten angeboten. Einerseits gibt es den alleinstehenden Raspberry Pi Pico, während sein später ausgelieferter und mit einem Infineon-WLAN-Modul ausgestattete Kollege Raspberry Pi Pico W mittlerweile ebenfalls gut verfügbar ist. Zum Zeitpunkt der Drucklegung dieses Artikels gilt dabei, dass Kaluma in Version 1.0 nur den „klassischen“ Pico unterstützt. Unterstützung für die WLAN-fähige Variante ist - siehe Abbildung - erst für die derzeit noch als Beta vorliegende Version 1.1 geplant.

Bildquelle: https://kalumajs.org/download/.

Von der Architektur

Nach dem Ende der (für die Javascript-Performance-Steigerung primär verantwortlichen) Browserkriege hat sich Node.JS und die diversen Projekte als quasi Standard für alles, was da Javascript interpretiert, herauskristallisiert. Im Fall von Kaluma gilt dabei, dass die eigentliche Javascript-Intelligenz durch das quelloffene Projekt JerryScript gestellt wird. Der Code der Runtime findet sich dann auf GitHub unter https://github.com/kaluma-project/kaluma und steht unter der Apache-Lizenz. Im Bereich der auf dem Mikrocontroller zur Ausführung gelangenden Software setzt man auf einen zweigleisigen Approach: Im ersten Schritt wird die in Form einer .UF2-Datei vorliegende Javascript-Runtime auf den Controller geladen. Sie kommuniziert danach über einen simulierten seriellen Port mit einer Node.JS-Anwendung, und legt die auszuführenden Javascript-Dateien im Remanentspeicher des Controllers ab. Dieser auf den ersten Blick pedantisch klingende Hinweis ist von wichtiger Bedeutung: Tötet eine Javascript-Datei die Runtime und blockiert die Kommunikation mit der Mater-Anwendung, so gilt, dass ein „reines“ Deployen der Runtime nicht zur Wiederherstellung eines funktionsfähigen Zustands ausreicht. Stattdessen ist unbedingt auch die Nutzung der unter der URL https://github.com/dwelch67/raspberrypi-pico/blob/main/flash_nuke.uf2 bereitstehenden Flash Nuke erforderlich; das Deployment der anderen .UF2 -Datei darf erst danach erfolgen. Apropos Deployment: Auf Seiten der Workstation ist die Installation des Pakets kaluma/cli erforderlich. Je nach Konfiguration Ihres Systems ist dazu eine der beiden folgenden Befehle zu verwenden:

1
tamhan@TAMHAN18:~$ npm install -g @kaluma/cli
2
tamhan@TAMHAN18:~$ sudo npm install -g @kaluma/cli

Analyse der inneren Architektur der Runtime.

Im nächsten Schritt bietet es sich an, folgendes Programm zur Ausführung zu bringen. Es enthält eine Endlosschleife, die permanent eine Rechteckwelle am GPIO-Pin ausgibt:

1
pinMode(2, OUTPUT);
2
3
while(1==1)
4
{
5
        digitalWrite(2, HIGH);
6
        digitalWrite(2, LOW);
7
}

Speichern Sie den Javascript-Code in einer mehr oder weniger beliebigen Textdatei, und erledigen Sie die Auslieferung nach folgendem Schema über die Node.JS-Companionapplikation:

An einem angeschlossenen Digitalspeicheroszilloskop ist dann die gezeigte Wellenform zu sehen.

Bildquelle: Autor.

Die erfolgreiche Ausgabe der Wellenform informiert uns darüber, dass der Zugriff auf die Hardware in Kaluma synchron implementiert ist. Problematisch ist allerdings, dass eine Endlosschleife keine Rechenzeit an das Betriebssystem bzw. die zugrunde liegende Infrastruktur abtritt. Bei Annahme von kooperativem Multitasking gilt dann, dass die Kommunikation mit der CLI-Applikation nicht mehr möglich ist. Diese Annahme ist dadurch bestätigbar, dass die Ausführung des nächsten Flashbefehls scheitert – unter https://youtu.be/g9WbyE8tHYs findet sich ein Video, das dies en Detail demonstriert. Eine funktionsfähige Variante des Programms würde nach folgendem Schema auf SetInterval setzen:

1
pinMode(2, OUTPUT);
2
var timerId = setInterval(function () {
3
        digitalWrite(2, HIGH);
4
        digitalWrite(2, LOW);
5
}, 1);

Zu beachten ist allerdings, dass die von dieser Variante ausgegebene Wellenform wesentlich langsamer ist.

Interaktion mit Hardware

Die Durchführung von Bit Banging-Experimenten erlaubt interessante Rückschlüsse auf die Architektur des zugrunde liegenden Systems. In der Praxis gilt aber, dass Hardware-Zugriff heute - normalerweise - über die diversen im Controller implementierten Hardware-Peripheriegeräte erfolgt, die die verschiedenen Bus-Protokolle ohne permanente Überwachung des Hauptprozessors umsetzen. Die Kaluma-Ausführungsumgebung implementiert schon zum Zeitpunkt der Drucklegung dieses Artikels so gut wie alle am RP2040 befindlichen Interfaces. Unter der URL https://kalumajs.org/docs findet sich dabei die umfangreiche Dokumentation, während unter https://github.com/kaluma-project/examples schlüsselfertige Beispiele verfügbar sind.

Fazit

Trotz des noch vergleichsweise frühen Entwicklungsstands gilt, dass Kaluma die Ausführung von Javascript am RP 2040 ermöglicht. Wer in seinem Unternehmen Javascript-IP hält, kann durch Nutzung dieses Systems Duplikation im Gesamtsystem reduzieren und die Wartbarkeit erhöhen. Dies ist ökonomisch sinnvoll - dass man als am Achtbitter mit Assembler aufgewachsener Entwickler dabei eine große und dichte Nasenklammer braucht, gibt der Autor allerdings vollumfänglich zu.


: Bearbeitet durch NewsPoster
von Benedikt M. (bmuessig)


Lesenswert?

JavaScript auf Embedded tut mir in der Seele weh :/

Da ein Produkt funktionssicher zu bekommen klingt nach einem Albtraum. 
Keine Typisierung, fehlende Performance und Anwendungsentwickler die 
noch nie von Embedded gehört haben.

: Bearbeitet durch User
von Tam H. (Firma: Tamoggemon Holding k.s.) (tamhanna)


Lesenswert?

Benedikt M. schrieb:
> JavaScript auf Embedded tut mir in der Seele weh :/
>
> Da ein Produkt funktionssicher zu bekommen klingt nach einem Albtraum.
> Keine Typisierung, fehlende Performance und Anwendungsentwickler die
> noch nie von Embedded gehört haben.

Stimme völlig zu.

Aber: wenn es um eine unkritische Aufgabe geht? Oder man eine MCU 
nachschaltet, die die kritischen Aufgaben regelt?

Die Reduktion der Koppelung ist und bleibt leider ein nicht zu 
vernachlässigendes Argument...

von Benedikt M. (bmuessig)


Lesenswert?

Tam H. schrieb:
> wenn es um eine unkritische Aufgabe geht? Oder man eine MCU
> nachschaltet, die die kritischen Aufgaben regelt?

Aber wäre das nicht ein Fall, in dem die BOM durch die Verwendung von 
JavaScript unnötig aufgebläht werden würde, da eine zweite oder 
leistungsfähigere CPU verwendet werden würde, als mit C/C++/Rust 
erforderlich wäre?

In der Serie sind meiner Ansicht nach die evtl. leicht höheren 
Entwicklungskosten durch eine stärkere Kopplung vmtl. vernachlässigbar 
gegenüber den gestiegenen Kosten pro Einheit oder einer höheren 
Ausfallwahrscheinlichkeit des Produktes.

von Jack V. (jackv)


Lesenswert?

Benedikt M. schrieb:
> Da ein Produkt funktionssicher zu bekommen klingt nach einem Albtraum.

Es richtet sich vermutlich nicht an Produktentwickler, sondern an 
Bastler, die eh schon mit JS und Frameworks (die Anlehnung an Node.js 
wird ja deutlich herausgestellt) basteln. Dass denen Funktionssicherheit 
nicht übermäßig wichtig ist, sieht man ja an vielen ihrer Webseiten.

von Jens B. (dasjens)


Lesenswert?

Jack V. schrieb:
> Benedikt M. schrieb:
>> Da ein Produkt funktionssicher zu bekommen klingt nach einem Albtraum.
>
> Es richtet sich vermutlich nicht an Produktentwickler, sondern an
> Bastler, die eh schon mit JS und Frameworks (die Anlehnung an Node.js
> wird ja deutlich herausgestellt) basteln. Dass denen Funktionssicherheit
> nicht übermäßig wichtig ist, sieht man ja an vielen ihrer Webseiten.

Naja, leider nimmt frickelware immer mehr zu bei Entwicklern die auch 
"richtiges" Zeuch entwickeln.

von N. M. (mani)


Lesenswert?

Wenn von 130MHz nur noch 46,5kHz übrig bleiben für einen einfachen Pin 
toggle und eine "funktionsfähige Variante" auch noch "deutlich 
langsamer" ist, dann zeigt mir das hier vorgestellte zumindest dass 
brutal viel Ressource verbrannt wird dabei.

Ich bin kein Hochsprachen-Hater wie andere hier, im Gegenteil. Aber das 
ist doch einfach am Ziel vorbei.
Ein Embedded Controller mit so wenig Ressourcen dafür zu missbrauchen 
ist für mich das gleiche Kaliber wie manche Linux auf einen ATMEGA 
portieren.
Einfach eine Machbarkeitsstudie, nicht mehr.

Das einzige Argument für so eine Umsetzung wäre für mich der Preis, wenn 
ich keinen Embedded Entwickler habe und gleichzeitig sehr sehr sehr hohe 
Stückzahlen habe.
Wobei ich das nicht als realistisch empfinde. Wenn ich Stückzahl habe, 
dann leiste ich mir einen richtigen Embedded Entwickler.
Alleine schon die Plattform Abhängigkeit wäre Wahnsinn...

Edit: Bezogen auf Preis /Javascript Abhängigkeit gemeint.

: Bearbeitet durch User
von Vanye R. (vanye_rijan)


Lesenswert?

> Naja, leider nimmt frickelware immer mehr zu bei Entwicklern die auch
> "richtiges" Zeuch entwickeln.

Naja, solange es nur fuer irgendeinen Testaufbau oder ein Produktiontool 
ist, ist das ja IMHO auch okay. Auch man sich fragt schon "wieso" weil 
man nicht Entwickler sein kann ohne C zu koennen und dann muss man sich 
sowas ja sicher nicht mehr antun.

Vanye

von Harald K. (kirnbichler)


Lesenswert?

Vanye R. schrieb:
> Auch man sich fragt schon "wieso" weil
> man nicht Entwickler sein kann ohne C zu koennen und dann muss man sich
> sowas ja sicher nicht mehr antun.

Er hat Jehova gesagt!

von Klaus R. (klausro)


Lesenswert?

1
pinMode(2, OUTPUT);
2
var timerId = setInterval(function () {
3
        digitalWrite(2, HIGH);
4
        digitalWrite(2, LOW);
5
6
}, 1);
Diese Version ist eh nicht gut, da dann der Wechsel von HIGH -> LOW sehr 
schnell geht und dann bis zum nächsten Aufruf der Pin auf LOW bleibt. 
Besser wäre (gibt es das?) ein "digitalWrite(2,TOGGLE)"

N. M. schrieb:
> Aber das ist doch einfach am Ziel vorbei.

Naja, früher hat man auch prof. Steuerungen z.B. mit dem Basic des 
8052AH gemacht, oder mit dem MSR BASIC des Z80. Hat von der 
Geschwindigkeit ja oft gereicht. Natürlich haben trotzdem viele diese 
CPUs in Assembler programmiert. Ich sehe das eher als Ergänzung zu 
Python oder MMBasic auf dem RP2040. Das entscheidende wird sein, wie 
stabil dass dann läuft und wie gut die Doku ist bzw. ob damit Sachen 
gehen, die mit µPython nicht möglich sind. Inzwischen kann man doch 
viele Probleme mit µPython "erschlagen". Es gibt z.B. eine Art 
"Compiler", den Viper Code Emitter für zeitkritische Funktionen. Das 
geht dann teilweise deutlich flotter: 
https://forums.raspberrypi.com/viewtopic.php?t=313023. und 
https://docs.micropython.org/en/v1.9.3/pyboard/reference/speed_python.html#the-viper-code-emitter

N. M. schrieb:
> Einfach eine Machbarkeitsstudie, nicht mehr.

So ist es.

: Bearbeitet durch User
von Thomas T. (runout)


Lesenswert?

naja, wenn der Oszi-Screenshot als 46,5MHz zu interpretieren wäre...

Wenn tatsächlich bei einem "frei laufenden" Pin-Togggler nur 46,5kHz
übrigbleiben und das an der JavaScript-Umgebung liegt,
dann  gute Nacht.

Runout

von Steve van de Grens (roehrmond)


Lesenswert?

Ich verstehe jetzt auch irgendwie nicht den Sinn einer weiteren 
Scriptsprache neben Micropython. Zumal Mikrocontroller mit 
Script-Interpreter bisher immer seltene Sonderlocken waren. Kennt noch 
jemand C-Control?

von Harald K. (kirnbichler)


Lesenswert?

Thomas T. schrieb:
> Wenn tatsächlich bei einem "frei laufenden" Pin-Togggler nur 46,5kHz
> übrigbleiben

Wie schnell läuft denn ein "frei laufender" Pin-Toggler auf dem RP2040, 
wenn er z.B. in C oder Assembler geschrieben wird?

Mit welchem Takt läuft der Bus, an dem die I/O-Pins hängen, kann der 
konfiguriert werden, müssen CPU-Zugriffe auf diesen Bus synchronisiert 
werden?

von Steve van de Grens (roehrmond)


Lesenswert?

Harald K. schrieb:
> Wie schnell läuft denn ein "frei laufender" Pin-Toggler auf dem RP2040,
> wenn er z.B. in C oder Assembler geschrieben wird?

Fast 18 Megahertz. Was mich zu der Behauptung verleitet, dass dieser 
Script Interpreter verglichen mit anderen extrem schlecht ist.

Mit DMA und unter Ausnutzung der speziellen HW Features geht es noch 
sehr viel schneller. 
https://forums.raspberrypi.com/viewtopic.php?t=318251

: Bearbeitet durch User
von Stefan K. (stk)


Lesenswert?

Harald K. schrieb:
> Wie schnell läuft denn ein "frei laufender" Pin-Toggler auf dem RP2040,
> wenn er z.B. in C oder Assembler geschrieben wird?

Wenn man den PIO-Assembler nimmt maximal mit dem halben Systemtakt, also 
62,5MHz bei 133MHz Systemtakt.
Und man hat dann noch beide Prozessor-Cores und die anderen PIO State 
Machines frei.
Und dann kann man den Controller noch übertakten, 250MHz sind möglich. 
Darüber funktioniert dann das Lesen aus dem Flash nich mehr.

von Mi N. (msx)


Lesenswert?

Stefan K. schrieb:
> Und dann kann man den Controller noch übertakten, 250MHz sind möglich.
> Darüber funktioniert dann das Lesen aus dem Flash nich mehr.

Kleiner Tipp: erhöhe die Anzahl der Wartezyklen für's Flash. Dann laufen 
die Programme auch mit 350 - 400 MHz, wenn man es braucht. Diese 
Wartezyklen "stören" eh nur beim Nachladen in den internen 
Programm-Cache.
Es gibt Berichte über Laufzeitunterschiede, wenn ein Flash nicht per 
QSPI sondern nur mit einfach SPI betrieben wird: Die Laufzeit wird nur 
unwesentlich erhöht.

Beim BASIC PicoMite für den RP2040 beispielsweise kann man den Takt bis 
zu 378 MHz einstellen: Handbuch Seite 10.
Das scheint alle Erfahrungswerte zu bestätigen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.