Porting Firefox To Apple Silicon: Tales From The Trenches

For any smaller and larger software product that aims to be compatible with Apple’s MacOS, the recent introduction of its ARM-based Apple Silicon processors and MacBooks to go with them came as a bit of a shock. Suddenly one of the major desktop platforms was going to shift processor architectures, and with it likely abandon and change a number of APIs. Over at Mozilla HQ, they assumed that based on past experiences, Apple’s announcement of ‘first Apple Silicon hardware’ would also mean that those systems would be available for sale.

Indeed, one week after the November 10th announcement Apple did in fact do so. By then, Mozilla had worked to ensure that the Firefox codebase could be built for Apple Silicon-based MacOS. Fortunately, through the experiences of running Firefox on Windows-on-ARM, they already had gained a codebase that was compatible with 64-bit ARM. Ultimately, the biggest snag here was the immature Rust language and dependency support for Apple Silicon, which set back the first release.

When it came to the distributing of Firefox on Intel- and ARM-based Macs, the decision was made to package both versions of the application into a so-called Universal Binary. While this pads out the size of the installer, it also means easier distribution and would not affect the built-in updater in Firefox. This also allowed for an easy fix for the Google Widevine DRM module, for which no Apple Silicon version was available at first, allowing the same module for Intel to be used with either Firefox version via the Rosetta 2 binary translator in MacOS (as we covered previously).

After this it was more or less smooth sailing, with some Rosetta 2-based glitches and MacOS Big Sur-related bugs that spoiled some of the fun. What this experience shows is that porting even a big codebase like Firefox to Apple’s new platform is fairly straightforward, with lack of support from toolchains and other dependencies the most likely things that may trip one up.

The Rosetta 2 feature, while helpful, also comes with its share of gotchas as the Firefox developers found out, and of course there is a lot more optimization that can (and should) be done for such a new platform.

The (Probably) Most Thoroughly Commented Linker Script For The SAM D21 MCU

Linker scripts are one of those things which nobody who does software development really wants to deal with, but like many things in life sometimes they are inevitable to make things work. Although one could keep pretending linker scripts do not exist and let IDEs handle such pesky details, some of us suffer from this unfortunate condition called ‘curiosity’ and just have to know. People like [Thea].

Recently, [Thea] wrote a blog post on exactly what the linker script generated by the Microchip IDE for a Cortex-M-based SAM D21 project does. The result is a nicely annotated overview of the file’s contents, accompanied by links to the Arm and GCC documentation as well as other references where appropriate. The entire linker script (.ld file) can be viewed on GitHub. With the SAM D21 being a popular choice for Arduino and Arduino-compatible board, this article is a good starting point to understanding what a linker script does and how it affects one’s project.

For other (Cortex-M) MCUs this linker script is also useful as a starting point. Especially knowing which sections are required and what changing them affects in the final (ELF) binary and the firmware that is ultimately written to the MCU. We recently covered linker scripts for Cortex-M as well, along with the concept of memory-mapped I/O.

Hackability Matters

The Unix Way™ provides extreme hackability. The idea is that software should be written as tools to accomplish discrete tasks, and that it should be modular, extensible, and play well with others. It’s like software as a LEGO set — you can put the blocks together however you want, within limits, and make stuff that’s significantly cooler than any of the individual blocks alone.

Clearly this doesn’t work for all applications — things like graphics editors and web browsers don’t really lend themselves to being elegant tools that integrate well with others, right? It’s only natural that they’re bloaty walled gardens. What happens in the browser must stay in the browser, right?

But how sad is it that the one piece of software you use all day, your window into cyberspace, doesn’t play well with the rest of your system? I’d honestly never really been bothered by that fact until stumbling on TabFS. It’s an extension to Chrome that represents the tabs on your browser as if they were files on your local system — The Unix Way™. And what this means is that any other program that can read from or write to a file can open tabs, collect them, change webpages on the fly, and so on. It opens up the browser to you.

This is tremendously powerful. Don’t like the bookmarking paradigm of your particular browser? Writing your own would be a snap in Python — and you could do cleverer things like apply a little machine learning to handle putting them in categories. Want to pop open (or refresh) a set of webpages at a particular time every day? Cron, or its significantly more complicated counterpart systemd, and a couple lines of code will do that. Want to make a hardware button that converts dark mode to light mode and vice-versa for every website starting with “H”? Can do.

I’m picking on browsers, but many large pieces of software are inaccessible in the same way — even if they’re open source, they don’t open up channels for interaction with user code or scripts. (Everything “in the cloud” or “as a service”, I’m looking at you! But that’s a further rant for another day.) And that’s a shame, because most of these “big” pieces of software actually do the coolest things.

So please, if you’re working on a big software package, or even just writing a plug-in for one, do think about how you can make more of its abilities available to the casual scripter. Otherwise, it’s just plastic blocks that don’t fit with the rest of the set.

Remoticon Video: Pigweed Brings Embedded Unit Testing, Library Integration To Commandline

When it comes to embedded engineering, toolchains are the worst. Getting a new toolchain up and running correctly is often hard, and often prone to breaking when the IDE or other software is upgraded. A plethora of different toolchains for different hardware makes things even more murky, and if you want to get into time-saving tricks like automated testing, you’re in for a wild ride.

Those pain points led to the creation of the Pigweed project. As Keir Mierle demonstrates in this workshop from the 2020 Hackaday Remoticon, Pigweed is a set of libraries to make working with embedded development more hacker-friendly. The collection is accessed via commandline, and coordinates work with existing libraries to deliver unit testing, linting, static analysis, logging, and handling key-value stores, all alongside more commonly called-for tasks like compiling and flashing.

Demonstrated on a Teensy microcontroller and an STM32 Discovery board, the presentation drives home the utility of Pigweed, a Google project that was released as open source back in March of 2020. Graphical IDEs for these platforms are nowhere in sight, yet test firmware is built and flashed to these devices with relative ease. Unit testing, traditionally a sticky subject for on-chip applications, is demonstrated both emulated on the computer side, and running on the boards themselves. As the capabilities of microcontrollers have ballooned in recent years, writing tests for existing functions and confirming them during new development is becoming a must-have in your skillset.

There’s much more shown off here, so grab the workshop repository to follow along. It’s still considered experimental, and the irony of having to learn the intricacies of the Pigweed toolchain to ease the pain of other toolchains is not lost on us. However, most people reading will have their own affinity for the ability to use unified tools and commandline automation; this is a fascinating way to deliver a number of powerful software development techniques to low-level hardware projects.

Continue reading “Remoticon Video: Pigweed Brings Embedded Unit Testing, Library Integration To Commandline”

Bare-Metal STM32: Universal, Asynchronous Communication With UARTs

One of the most basic and also most versatile communication interfaces on an MCU is the UART, or Universal Asynchronous Receiver/Transmitter. Usually found in the form of either a UART or USART, the former allows for pure asynchronous serial communication, whereas the latter adds flow control. When working with MCUs, they’re also one of the most common ways to output debug information.

While somewhat trickier to set up and use than a GPIO peripheral, the U(S)ART of ST’s STM32 families is fairly uncomplicated to use, and immediately provides one with an easy way to communicate in a bi-directional fashion with a device. In this article we’ll see what it takes to get started with basic UART communication on STM32 microcontrollers.

Continue reading “Bare-Metal STM32: Universal, Asynchronous Communication With UARTs”

Building A Pocket Sized Python Playground

Like many of us, [Ramin Assadollahi] has a certain fondness for the computers of yesteryear. Finding his itch for nearly instant boot times and bare metal programming weren’t being adequately scratched by any of his modern devices, he decided to build the PortablePy: a pocket-sized device that can drop him directly into a Python prompt wherever and whenever the urge hits him.

The device is powered by the Adafruit PyPortal Titano, which combines a ATSAMD51J20, ESP32, an array of sensors, and a 3.5″ diagonal 320 x 480 color TFT into one turn-key unit. The PyPortal is designed to run CircuitPython, but the scripts are usually dropped on the device over USB. That’s fine for most applications, but [Ramin] wanted his portable to be usable without the need for a host computer.

For a truly mobile experience, he had to figure out a way to bang out some Python code on the device itself. The answer ended up being the M5Stack CardKB, a tiny QWERTY board that communicates over I2C. Once he verified the concept was sound, he wrote a simple file management application and minimal Python editor that could run right on the PyPortal.

The final step was packaging the whole thing up into something he could actually take off the bench. He designed a 3D printed clamshell case inspired by the classic Game Boy Advance SP, making sure to leave enough room in the bottom half to pack in a charging board and LiPo pouch battery. He did have to remove some of the connectors from the back of the PyPortal to get everything to fit inside the case, but the compact final result seems worth the effort.

While an overall success, [Ramin] notes there are a few lingering issues. For one thing, the keyboard is literally a pain to type on. He’s considering building a custom keyboard with softer buttons, but it’s a long-term goal. More immediately he’s focusing on improving the software side of things so its easier to write code and manage multiple files.

It sounds like [Ramin] isn’t looking to compromise on his goal of making the PortablePy completely standalone, but if your convictions aren’t as strong, you could always connect a device like this up to your mobile to make things a bit easier.

Continue reading “Building A Pocket Sized Python Playground”

Bare-Metal STM32: Exploring Memory-Mapped I/O And Linker Scripts

In the first installment of this series we had a brief look at the steps needed to get a bare-metal application running on an STM32 microcontroller. While this allowed us to quickly get to the juicy stuff, there are two essential elements which make an MCU so easy to use. One is found on the hardware side, in the form of so-called memory-mapped I/O (input/output), the other is the information contained in the files that are passed to the linker when we build a firmware image.

Memory-mapping of hardware peripheral registers is a straightforward way to make them accessible to the processor core, as each register is accessible as a memory address. This is both convenient when writing the firmware code, as well as for testing, as we can use a memory mapping specific for unit or integration testing.

We will take an in-depth look at this way of testing, as well as how these linker script files are connected to the memory layout. Continue reading “Bare-Metal STM32: Exploring Memory-Mapped I/O And Linker Scripts”