When it comes to programming, I seem to be guided by the moon. No, no, not in that sense. Even though the moon at least does have some real influence on our lives here, as evidenced by the tides of the seas. Or the stability of the inclination of the Earth’s rotational axis. Unlike the esoteric nonsense of astrology and all that. It’s always funny to read, or hear, when people say that we see a star. We don’t. We see light that emanated from the star possibly dozens, if not hundreds, of years ago. We do have a relationship to the stars, though, in that each and every atom in our body, as well as the world around us in general, was forged by a dying star. Our bodies consist of atoms most likely even created by many different stars. We are made of stardust, poetically speaking. That gives me pause at times. But I digress. Back to the moon.
Touching the Moon
Just about a year ago, I wrote an ode to the computer technology that made the first landing on the moon possible. I am still fascinated by that video, knowing about the measly computing power that actually flew the lunar module, controlling attitude, doing manoeuvres, and keeping course. Armstrong was only flying the module in the sense that he gave commands to the computer, which did the actual flying.
Lua means moon in Portuguese. It’s also the name of a programming language. I had come in contact with Lua some 15 years ago, as an extension language for a Mac program, I don’t even remember which. I was fascinated right at first contact. In fact, I love it. Is this weird to say about a programming language, of all things?
Lua is a simple and small language, based on clean concepts, as one often finds with programming languages that are defined and maintained by a single person, or a small group of people, as is the case with Lua. Lua is dynamically typed, and every value is a first-class object. The only data structure is the so called table, an associative array. Everything can be both table key and value. Everything. A table can be the key for an element in another table. Or a function. No, not the function value, that would be trivial, but the function itself. Even modules are tables. And there are meta-tables. It’s very powerful in its simplicity. Right up my alley.
I have since used Lua on the Raspberry Pie to implement an HTTP server. I needed something simple to implement user interfaces. Apache and nginx do offer Lua extensions to write responders, but the installations get heavy quickly, so I wrote my own. It’s very basic, but it was fun to design and program, especially as I had only faint ideas how such a server works. Learning is a Good Thing.™
My main use of Lua over the past years is in the context of the on-line game World of Warcraft, which allows to write extensions in the form of so called addons. I have written about it here. My addon Asha has gone through quite a few iterations over the years, due to learning and experience, functional extensions, as well as adaptations to new game versions, including for the Classic version last year.
Not happy with the in-game development and inspection tools, I have also written a command shell that can be run right in the game. With proper command line parsing based on a syntax-driven finite state machine. Just for the kicks. It took me forever to figure that out, though.
The backbone of a Lua system is a global table ‘_G’. All addons are plugged in there as tables, including Blizzard’s own – a lot of the basic game functionality is realised as addons as well. Well-structured addons contain other tables, recursively. You realise the similarity with a file system, and the possibility to inspect all these tables and their values at run-time, moving up and down in the table-tree. My command shell allows exactly that, namely inspecting and manipulating all tables accessible from _G. It has turned out to be very useful when debugging addons. Apart from commands, it also offers aliasing, history, and work environments, and it’s extensible by additional command sets. Also, it’s a combination of command input as text and mouse clicking, in that I can move around the table structures by clicking on the text output. It’s pretty neat.
Enter another moon. Oberon is a major moon of planet Uranus. It’s named after a mythical king of the fairies. Oberon is also the name of a programming language.
Oberon is the brain-child of Niklaus Wirth, formerly at ETH Zurich. Last year, I wrote a post of appreciation about his work and way of thinking. Newly intrigued, I had decided to have a closer look at Oberon again. I searched the interwebs, and to my astonishment I found a programming environment for Oberon, called Astrobe. It targets ARM Cortex microprocessors, that is, it’s made to create embedded programs that run on the bare processor.
Yay! Up my alley indeed. Exactly what I had been looking for.1
Oberon is a – you guessed it – simple and small language. It’s defined on 17 A4 pages, and no, not using a six point font. 17 pages. Compare that to way over 1,000 pages for the C or C++ languages. Or Ada. Wirth developed Oberon as an evolution of Modula-2 – mostly by removing elements, only adding type extensions. Wirth considers type extensions to be a refinement of modules, which were introduced in Modula-2. Evolution by removing and refinement. Pretty unique, and a signature of Wirth’s relentless endeavour for allowing his students, and us engineers, to really understand things. Of course, being a Wirth language, Oberon is strongly and statically typed. Unless you do byte and address juggling, type errors are caught by the compiler, also across all modules.
Did I mention that I love simple languages? And even more so as I get older, I guess. That is, if the simplicity does not stand in the way of creating real solutions. Which it does not if the simplicity is based on the right concepts. In fact, if you get the concepts right, simplicity often follows. See also Lua above.
I have since used Oberon and the Astrobe programming environment to program ARM Cortex-M3 microprocessors. I have implemented processes and scheduling based on coroutines, written interrupt-based device drivers, display drivers, event loggers, stuff of that nature. Just for the kicks.
Chris, the creator of Astrobe, is a super-nice guy, and always there to help and support, relentlessly answering questions, and also accepting improvement proposals. Alas, I seem to have a knack for finding issues, because I make stupid mistakes, and because I use all language features, which both test the compiler with edge cases. But I was also able to make some contributions for the latest Astrobe release. I even got an honorable mention in the release notes! Yay.
My main contribution was a concept and algorithm, plus some code, to display a detailed stack trace upon run-time error exceptions. Tracing the stack backwards, but also scanning the program code. It’s all there at your fingertips when programming at that level.
On the Bare Metal
I love computing on the bare metal, where I am in full control of what’s going on, and, more importantly, where I understand everything, down to juggling stack pointers upon context switch, replacing the return address on the stack of an exception handler with the entry address of a recovery procedure, that sort of thing. The Cortex-M3 processor expects the address of the first instruction to execute at address 4, and the initial stack pointer at address 0. That’s it. Thereafter, it’s my code. Only my code. Nothing happens that I didn’t program myself.1 This is nerdily gratifying, probably in a way only few people can understand.
My real-time process kernel for the Cortex-M3 is just shy of three kBytes of executable code. The kernel can recover from exceptions due to run-time errors and even hardware faults, by restarting single processes, or restarting the whole program in the worst case, checking for repeated restarts. Misbehaving processes can be shut down if not essential. And there’s a watchdog to catch run-away processes.
Will anyone ever use my kernel for a product? No. But that’s not the point. Tinkering is, solving problems, finding parsimonious and elegant solutions. It’s a mind game. Some solve Sudokus, I program. For example, implementing recovery from run-time error exceptions, I spent the better part of a day to implement a solution that actually did work, but was convoluted. No elegance, no joy. The next day, with some distance, having my morning coffee on the verandah, the right solution flashed through my mind. Two or three lines of code, everything nicely in line with the overall concept. Simple. Now there’s elegance. I know, nerdy.
Inside the Bare Metal
In a forthcoming follow-up post, I’ll describe how I have since moved from programming on the bare metal to programming inside the bare metal. Tinkering with the silicon itself.
Ehrm. Yes, it’s on Windows. Life is not without compromise. ↩︎