Skip to content

Pico Computer 3 - Fuzix v0.20 - BASIC has the network

Choose a tag to compare

@UKTailwind UKTailwind released this 22 Aug 14:17
· 0 commits to master since this release

BASIC has the network: MMBasic's WEB family is translated, the card
ships a real web application to prove it, email works through Gmail,
and a radio fix makes the whole network feel faster.

BASIC has the network

v0.19 ended with "BASIC cannot reach the network yet". This release
deletes that sentence. mmbc now translates the WebMite's WEB
family, so an MMBasic program can be a network client — or a web
server:

WEB UDP SERVER PORT / INTERRUPT / SEND datagrams, with MM.MESSAGE$ and MM.ADDRESS$
WEB OPEN TCP CLIENT / TLS CLIENT the client, plain or TLS
WEB TCP CLIENT REQUEST / READ / WRITE with the WebMite's own reply-collection semantics
WEB TLS CA / NOVERIFY certificate checking, from /etc/ca.pem
WEB TCP SERVER PORT + INTERRUPT the eight-connection web server
WEB TCP READ / SEND / CLOSE per-connection, from the interrupt
WEB TRANSMIT CODE / FILE / PAGE status codes, files, and live pages
JSON$(a(), "path.to[3].value") the WebMite's JSON walker, to the letter
WEB NTP / PING / CONNECT the clock, ICMP, and the link gate

The one that deserves a sentence here is WEB TRANSMIT PAGE: a page
is HTML with {expression} in it, evaluated when the page is served.
A compiled program has no interpreter to evaluate with, so every
expression a page uses is compiled into the program at the
statement that names the page
— with that statement's own local
variables and parameters in scope — and matched by text at run time.
The page on the card can be edited freely afterwards; an expression
the program has never seen raises an error naming it.

Fidelity was the design rule throughout: interrupts fire between
statements, REQUEST discards what arrived before it writes (which
is what makes SMTP work), a program cannot fetch from its own server
(both firmwares deadlock that shape), and everything untranslated —
WEB MQTT, the STREAM forms — is refused by name at translate
time, never silently accepted. The manual has a new section,
Networking from BASIC: the WEB family, that documents all of it.

The card ships a whole product

/root/MMBasic/retic is Geoff Graham's reticulation controller
a real, shipped WebMite product: a sprinkler scheduler you configure
entirely from a browser, with weather from Open Weather Map, sunrise
and sunset times, rain skip, and email alerts. 49 KB of BASIC and
three web pages. It compiles on the machine and runs:

# cd /root/MMBasic/retic
# mmbc retic.bas -o retic.c
# cc -o retic retic.c
# ./retic

then point a browser at the machine's address. Its MIGRATION.md
lists every change the port needed, and the manual's new Migrating
a WebMite program
section is the general recipe those changes
illustrate — including the discovery that a shipped MMBasic product
carried four stray ) and a missing End Sub the interpreter
silently ignores and a compiler does not.

Email, through Gmail

SMTP from BASIC, proven against the real server: implicit TLS on
port 465, AUTH LOGIN with a Google App Password,
MATH(BASE64 ENCODE ...) doing the encoding, and the certificate
checked against the bundle the card already ships. The complete
recipe — including why the server's greeting needs no READ — is in
the manual's WEB section. retic's alerts use it.

The radio no longer dozes

The CYW43's power-save mode was never being disabled, so the access
point held packets for a sleeping client: pings wandered between 3
and 300 ms, UDP lost packets outright, and TCP's retransmits had
papered over it since networking arrived. Fixed in the kernel —
pings answer in about a millisecond now, and every network program
on the machine feels it.

Smaller pieces a WebMite program leans on

  • OPTION ESCAPE\q, \n, \064, \&41 and the rest,
    decoded in string literals exactly as the WebMite decodes them.
  • MATH(BASE64 ENCODE in$, out$) / DECODE — returns the
    length, writes the string into the second argument (that odd shape
    is the firmware's own, and programs use it).
  • MM.INFO(UPTIME), MM.INFO(DISK SIZE),
    MM.INFO(IP ADDRESS), MM.INFO(MAX CONNECTIONS).
  • Drive-letter pathsA:/settings.dat, A:\file and A:file
    all reach the plain name; a bare leading / stays a real absolute
    path, because /etc/ca.pem is one.
  • WATCHDOG is accepted and deliberately does nothing, with a
    translate-time warning saying so — the hardware watchdog belongs
    to the kernel on a machine that runs many processes; wedge
    recovery is a restart loop in /etc/rc.
  • CPU RESTART re-executes the program instead of rebooting the
    processor — which is what a program that says it means.
  • ntpdate grew -O seconds, so WEB NTP's half-hour timezones
    work.

Run on the hardware before release

Both boards were flashed with these binaries and this card image.
One compiled retic from the card and is running it — live schedule,
browser-driven, valves switching. The other ran the regression from
the fresh card, everything built by the card's own toolchain:
MM.VER answers 0.20, wifi -f joins, a compiled WEB program
passes its link gate, pings the gateway at 3 ms and sets the clock
to the half-hour-capable offsets, the Gmail send comes back
250 2.0.0 OK, and the language suite's output is byte-identical to
the reference.

The usual rule after upgrading: recompile

A .bc that uses the new statements asks the new bcrun for
functions an old one does not have, and is refused by name at load.
A freshly built program imports nothing version-specific. The card
ships the matched set.

Assets

fuzix.uf2 the kernel — hold BOOTSEL, copy it on
pc3-sd-cc.img.gz the SD card image, compiler and examples included
FUZIX-PC3-MANUAL.pdf the user manual, with the two new chapters
PC3-C-MANUAL.pdf C on the machine, sockets section extended