top of page

Firmware Design with Sam Moore | The Engineering Triangle Podcast




In Episode 3 of The Engineering Triangle podcast, Ayrton chats with Sam Moore, a firmware engineer with over eight years of experience building the hidden bridge between hardware and software, the silent workhorse behind the seamless operation of many smart devices and digital solutions!

 

Ayrton and Sam discuss the unique challenges of this field, including working with limited hardware resources, developing robust code, and ensuring optimal performance of devices from smart homes to IoT systems.

 

We look back on the development of the Koodaideri’s HydraTune system, which required precise firmware to control hydraulics remotely, ensuring safety and reliability in hazardous environments, and delved into the specifics of developing firmware for SRAM's TyreWiz 2.0, a sophisticated tyre pressure monitoring system for cyclists that provides riders with precise information on their ride quality.

 

Well-designed firmware can significantly impact device performance and user experience, but how can it be done quickly and cost effectively?


For those who would prefer to read rather than listen, here is a transcript of the conversation!



 

What is Firmware?

 

Ayrton: Not many people understand what firmware is. Your smart device asks you to do a firmware update, that's most people's interactions with firmware.

 

But firmware is the software that runs directly on the hardware, the electronic chips.

 

Sam: Yes. It's just fancy software, I suppose. But usually in firmware you're focused more on interacting with the real world rather than abstract concepts. Like controlling outputs and reading sensors.

 

Ayrton: Some examples of firmware that we've done here at Element are tiny Bluetooth microcontrollers that would be interfacing with sensors, as on the SRAM ShockWiz devices, that interface with three ACC accelerometers and Bluetooth. The electronics that actually makes the Bluetooth wireless communications, and how that microcontroller does all of those things in a timely manner to enable a person to interact with the device via Bluetooth. Or for the device to do its own job at sensing what the person's doing on the bicycle, things like that.

 

Firmware is quite a unique and challenging domain.

 

Sam's got a history with physics and mechatronics. He came to the business back in 2016 and started off as a testing engineer interfacing with the devices that we were creating for the ShockWiz at the time. He has gone on to become our senior firmware engineer working on all the electronic devices that we've created over the years.

 

Sam and I also made some decisions early on, about 2018, to try and make firmware a bit easier to do here at Element.


 

 

What makes for good firmware design?

 

Sam: In software, something that's good is usually something that doesn't piss off the user, I suppose. But with firmware, it's the part of the software that the user doesn't see as much, so it's a bit harder to tell.

 

I have two robotic vacuum cleaners. And I won't say what brands they are, but one of them is good and the other one is s***. But without actually knowing how the code is designed, I can't really comment on what's good about their design or not.

 

I suppose a good firmware design usually involves a lot of testing. It's similar to other software. You use modular design, you use testing. You use a lot of the same techniques. But there's the added complexity of often having to understand the electronics behind the systems. Like if you're driving a motor, you usually have to understand how that circuit is going to work, at least on a basic level.

 

Ayrton: Every IoT widget that you buy these days has firmware in it. With good firmware, the user has a somewhat seamless user experience to make it work, and the thing doesn't complain.

 

Sam: It doesn't beep at you like certain robotic vacuum cleaners do.

 

Ayrton: I've got sort of a smart home set up with Sensibo air conditioning devices. They are quite simple widgets that basically proxies commands from your phone, but connects through the Internet and then does an infrared remote control to your air conditioners. A really nice, seamless user experience.

 

There’s Chromecast, they're going next level where they're actually running an operating system. Firmware is usually not like an Android operating system, or it doesn't have a full operating system on it. It's basically the core that interfaces directly with the electronics and more simplistic devices, in a way, which a lot of the time may have to be doing quite complex things with sensors and actuators.

 

What are some of the worst examples of firmware design that you've seen?

 

Sam: I haven't actually seen a lot of terrible firmware. Usually stuff mostly does what it's supposed to do. You can tell if something's poorly designed because it's not very responsive. That usually becomes reflected in the user interface, which is outside of firmware.

 

But there are other implications, I suppose. If your firmware’s designed poorly, you might be able to compensate for it by running more expensive hardware. That will make the firmware work because you have a more powerful processor, but it'll make the electronics cost more. So there's a trade-off when you make those decisions. And I guess good firmware balances the constraints and uses the resources it has efficiently.

 

Ayrton: Firmware is usually the software that goes directly on the chip that controls all the peripherals around the chip. But there’s any number of different chips that you can buy. You can buy an electronics microcontroller these days from a dollar all the way through to hundreds of dollars. And when you're mass producing something in the hundreds of thousands or tens of thousands of quantity, you've got to make a choice on what those things are.

 

Firmware primarily runs C code. And you have a certain amount of limited resources as well, usually one CPU, which means that you can do one instruction at a time, although some of them are coming out with new multi cores these days.

 

And you've got limited RAM resources, so you can only hold a certain amount of information within the chip itself, and you might only have access to rudimentary storage. The firmware engineer’s role really is to balance the requirements of the device with doing those things in a timely manner.

 

Sam: You might want to compensate for not having much RAM by adding external RAM to your design. But then the firmware now has to interface with that external RAM. So it's a trade off you have to make, whether or not it's worth the extra complexity of having the RAM controller.

 

Ayrton: In firmware design, you often have to create sort of an operating system of its own. You can use it as a device that basically just runs a script, almost like an Arduino where it initialises some peripherals then runs specific functions on those peripherals and just loops back around.

 

That's kind of the simplest firmware that we can run.

But if you need to be doing things asynchronously or in parallel, that's when the real challenges of firmware come in.

 

Sam: It usually gets hard once the firmware has to interface with an external device, which is what IoT is. Everything has to talk to Bluetooth or be on Wi-Fi or something like that.


You normally have to have other tasks that are running at the same time. Like for HydraTune, it's got to be moving the motor at the same time as it's updating the readings to the app.

 

Ayrton: Yeah, firmware is unusual field. And I guess it's not really truly appreciated how complex it is. It's nice to be talking about it today.


 

 

What is the key to developing firmware quickly?

 

Sam: Normally with conventional software, there's a lot of libraries and frameworks that people use to save them from having to do some of the low level coding.

 

In firmware there are tools like that you can use, but you have to be a lot more careful, mainly because of the limited resources. A lot of vendors have their own different tool sets and libraries, and it's not necessarily trivial to pull those things together.

 

If you want to use them together, generally what we try to focus on is identifying the features. And sometimes it's better to simplify the feature set of what the firmware does, rather than looking for a silver bullet library that you can download off the internet that does everything for you.  Because if the tools do too much, you don't really know what the scope of the firmware is.

 

It's also better to focus on the functional requirements of the firmware. A lot has been said in software about patterns and best practices, and it's not like you shouldn't obey those rules in firmware, but sometimes you have to take shortcuts that might be frowned upon because it's a different way of working. You're not building this huge monolithic feature set. You're focusing on making the thing do the one thing it's supposed to do.

 

An example is a singleton pattern, which is generally seen as bad in software, even though I think it's used in software anyway. They'll teach you not to do it. Whereas in the firmware, we end up doing that. The simple firmware can maybe only respond to one request at a time. Whereas a more general high level software design has to respond to any number of requests, up to however many the CPU can handle. But that changes the way you design the code a little bit.

 

Ayrton: We're talking about a $3 microcontroller that might operate at 64 megahertz. You're sort of talking the same computational resources as like a late 1990s PC. And the RAM might be in the 64 kilobytes of RAM, something like that. It’s tiny, like no file that you get off the Internet.

 

When you download a web page on the Internet, there is more information coming through just to show that web page than we have for the whole RAM required for running a device that might control your air conditioner or part of your mountain bike.

 

So the resource limitations are the major, major factor. And firmware is its own art because we are trying to work within those limitations. We're directly interfacing with the electronics that are surrounding the devices.

 

You can definitely buy faster microcontrollers that have more resources, but it's going to cost you more to make that widget. And it's also going to have more implication on the firmware design role, right? Like you're going to have to create a driver and then create a system that can integrate those more complex resources?

 

Sam: In some ways, it actually helps to have the limited resources, because you can restrict your scope a bit more. If you have all of the resources in the world, you might get too excited about what you can do with them.


 

 

How is firmware design different to other forms of software development?

 

Sam: I suppose you could say there's more focus on functional requirements than visuals. We still have all the same things, like arguing about programming languages, that regular software has.

 

I don't know what the electronics engineers think about it, but firm is in between hard and soft, so it's in between hardware and software. But at least the type of firmware we write here is more similar to software.

 

The main difference is, you have to be aware of how the pins are mapped on your microcontroller, and things like whether there's a pull up resistor or a pull down resistor.

 

We verify the electronics design, as a stage that happens in firmware. Obviously they test everything they can before that, but there's still things that might get missed.

 

Ayrton: One thing with firmware development that I think is quite different to software is we have to write the drivers that are configuring the different input output pins, then is talking with a peripheral. Either it's an analog input, it could be a digital input, it could be an array of multiple digital inputs.

 

There could be a communication protocol or a bus. So you might have USART or SPI or I²C, those sorts of things. And there may already be drivers that are written, but a lot of the time we’ll create drivers that are interfacing with those things.

 

And then we'll go to the next part of the software, kind of the operating system or the control system within the firmware itself.

 

Sam: There's usually layers involved in software. We have controllers, which is basically talking directly to the registers on the electronics. In that one, you're pretty much constrained to what the electronics design has determined, right?

 

Electronics engineering isn't software engineering. They can't just add JSON blobs into their CPUs or whatever. There's usually some electrical circuit involved, that's why this bit of this register is assigned to this value or something like that.

 

The starting point is usually modelling that in C. We define C data structures to represent all those registers, and then we try to make a common set of peripherals out of that. The peripherals is the next layer up you were mentioning, like USART, SPI, that type of stuff. Those are common things that we expect most systems to use, and we write functions we can call out from there. In our design we try to build a network interface or a network link around that.

 

Ayrton: Because we're doing everything in IoT, and...

 

Sam: Yeah, it gets a bit vague, but for our model we have the network link layer and network interface layer, which are kind of the same layer in our design, but they’re kind of separate. I guess a network interface is a generic abstraction for something that, well, sends data to a network. And the network link is the actual implementation of that.

 

We have an RS-485 link or a Wi-Fi link or a Bluetooth link. From the network layer we create things called sockets, which is like our data streams. And then for us we have our own message service. That's where the API design comes in, where we're designing things that other software can control by sending specific messages.

 

Ayrton: Sam and I made a decision back in 2018 after doing a couple of different projects for IoT with different customers. We had different projects which were all structured in firmware in different ways, and it was quite hard to not only work on a new project, but to have the same people work on a different project or bring them across.

 

We made a decision to do firmware and the software all the way through the entire stack. From the chip, from chip to the Internet, chip to app, and chip to the front end. Have all of those layers talking in the same language. And that's been a long and very valuable process, because now we've created an ecosystem that allows us to conquer any of these specific domains and still use the same firmware applied to the different parts.

 

One major difference between server and software is memory. To have performant firmware, we are controlling the memory directly. A lot of the software languages that web developers use already have a memory management system, or anything that you're running on an operating system.

 

Sam: It’s very complicated, but yes, we use compiled programming languages in firmware. It is possible to use interpreted languages or VMs like Java and that, but they all require more resources, and usually you spend so much time getting those things to work that you don't have any time left over to actually make the firmware do something.

 

I guess that would be an example of a mistake in firmware design, where you spend all this time trying to get Python running on your hardware and don't have any time left over to actually implement something. Or you do implement something, but because it's in Python, it's too slow.

 

Ayrton:  Another difference would be, say, people using Rust now, which is a memory safe coding language.

 

Sam: Yeah, Rust is very popular. We haven't had the chance to use it here yet though. I don't know too much about it, I looked at it, it has weird syntaxes. I've been told it's good.

 

Ayrton: Having to manage your own memory is something that a lot of software engineers wouldn't be doing, generally.

 

Sam: We try not to use too much dynamic memory allocation, but it's sort of unavoidable the way our firmware has evolved. We do have dynamic memory management, but it's up to the programmer to free their memory most of the time.

 

Ayrton: And make sure you’re being safe with it and not overriding someone else!

 

Sam: Yes, we do design things in a way that makes it easier with event systems and stuff like that. But we don't have garbage collection. You can't just add stuff to structures dynamically, like the structure’s precompiled.

 

 

Designing firmware for Koodaideri’s HydraTune

 

Ayrton: We helped design and manufacture Koodaideri’s HydraTune system for technicians to remotely perform maintenance on dangerous hydraulics out in the field. Part of that project was firmware design. How did you and your team approach this, and what did you learn?

 

Sam: The team was me and Yonathan at the time. Yonathan got to concentrate on the lower-level code, the driver for the stepper motor, controlling the current and phase. I did the API and communication between the two processors, one for Bluetooth and one for the motor control.

 

Ayrton: The motor controller is quite a powerful chip, it runs at a much higher clock speed than the Bluetooth processor. If we used the Bluetooth processor, we could have our Cranio firmware on that device, but it may not have enough resources to be able to do both the Bluetooth communications and the control system.

 

Sam: Yes. And we didn't want the stepper motor being screwed up because of some Bluetooth thing.

 

For the Bluetooth, we got a SoftDevice from the vendor. Firmware runs on top of that SoftDevice, but the SoftDevice takes total control over all timers and interrupts.

Nordic’s done a great job with it. But if you really want something to happen exactly at a specific time, it's not really guaranteed, especially if there's a lot of Bluetooth transmissions happening in the background.

 

Ayrton: The HydraTune is a safety critical device that takes the Bluetooth communications from an app and has to basically perform real time control of a stepper motor.

 

You've got a lot of things happening in parallel. You've got to be communicating consistently with the Bluetooth app, then looking for commands from the user, then executing those commands on the actual stepper motor itself, feeding back its real time position. So you might say, I want to move ten degrees, but that wouldn't happen instantaneously. There will be some actions happening, and some real time feedback.

 

Sam: I guess that's another difference between software and firmware. Some of the interactions in firmware take longer to happen than they do in software.

 

If you used a web browser it seems like everything's slow, but most of that's just network traffic. Whereas in firmware, sometimes it's physically not possible for a stepper motor to move 90 degrees instantaneously.

 

Ayrton: Yeah. The role of the firmware being asynchronous and having one processor doing Bluetooth and comms and having the other processor being able to make sure it's available to be able to do real time control and take those asynchronous communications is a challenge.

 

And a challenge that I think you’ve addressed pretty well, Sam. That's been a major part of your work for the last sort of three or four years, right?

 

Sam: Yes. The major challenge with getting that ready was the performance. We ended up having to optimise a lot of stuff to get it responding to the app, sending all those pressure samples at the same time that it was really in the motor.

 

Ayrton: We had Ravinder, our senior native app software engineer, on the podcast last week. He said that you and he worked very closely together.

 

Sam: That’s correct. That was very helpful because, unfortunately, there may be a certain way to do something that makes it very easy for the app, but it's not necessarily making it easy for the firmware.

 

Or in this case, it might not even be safe. Like I think the first assumption was, we'll get the app to move the dial to a position, and it'll just send one command to the firmware. And the firmware will go, move 45 degrees, or whatever. I don't know what that translates to in the movement of the actuator, but you’d want to move it quite a large distance. But once you've committed to that motion, it's pretty hard to back out of it.

 

What we ended up with was splitting the motion up into a lot smaller segments, and the app is basically waiting for confirmation on every adjustment. The amount that it can move kind of unsupervised would be very small. I think it's less than half a degree or something.

 

Ayrton: That was a call you guys had to make to optimise for speed. Again the Engineering Triangle - good, fast, and cost effective.

 

But for us to do firmware design fast, effectively, was a compromise between the app development team and the firmware team. The app team had to do a bit more coding on their side to then decrease the amount of work on the firmware side.

 

Sam: We put the app in front of you with the first firmware we came out with. It would queue up the commands. Every time you pushed a button, the app would send a new command to the firmware. And the firmware was still busy processing the previous commands. It would queue up the command, which we thought was a great idea, right? Because that means everything you tell it to do gets done.

 

But eventually something ran out of memory and the thing just crashed, which looked embarrassing. And even if you didn't manage to crash it, you waited like 90 minutes for it to finish processing all those meaningless commands before it could do anything. We had to rethink how we did that.

 

Ayrton: I had a discussion with a client today about functional testing of piece parts of a project. We try as fast as we possibly can to get something that is meaningful, in this case some circuit board. We would get off-the-shelf circuit boards that are available to us, wire them together, get some firmware running to be representative of what the end product might be, and we would have a demo app.

 

But the particular case you were talking about was kind of like the first demo device where all the teams come together to try and get this thing working. And usually what happens is it works for like all the general use cases. But then...

 

Sam: Then we give it to the user, and they break it.

 

Ayrton: That's always the best testing, giving it to the end user or someone who's from outside of the engineering team. Emulating the end user experience as early as possible is one of the best things you can possibly do for product development.

 

And we do have automated testing and things like that. But you'll never create a chaos monkey automated test unless you actually really have to.

 

Sam: Well, we might one day. We don't have end-to-end tests between the app and firmware yet, so...

 

Ayrton: Yeah, those things are hard. But firmware is hard.

 

 

Designing firmware for SRAM TyreWiz 2.0

 

Ayrton: For some time now, we've partnered with cycling tech company SRAM on their pressure sensor devices, including the recent release of TyreWiz 2.0. How did we help design the firmware?

 

Sam: SRAM already has a pretty good embedded team that did most of the design for TyreWiz. When working on a customer's code base or an existing code base, we try to be conservative and fit within their vision of what the design should be like.

In this case they were a bit short and needed our help.

 

Most of our work was on testing and the stuff that happens on the factory floor, interfacing with, I guess it's not really firmware because you're running it on a PC with a lot of USB devices, but interfacing with the end-of-line fixture, we call it, basically to program and calibrate the sensors.

 

Their first TyreWiz was done in a separate build system. We helped to port that into SRAM's newer build system. It almost needs its own area of engineering, like Build Engineer or something. The build system is the software that you use to basically compile other software. They can be pretty intricate and customised.

 

Ayrton: It basically ends up in flashing that device with the code that you need?

 

Sam: Yes. And there's software for supporting the testing and all of that.

 

As a firmware engineer, I spend 60% of my time writing software that doesn't go in the devices. That's sort of decreasing a little bit now, but yeah, there's a lot of testing software, and you usually run your tests on a PC. Like with the Bluetooth stuff, I said we don't have apps to do Bluetooth tests, but we have software that you can run on a Linux workstation that can interface with Bluetooth and run a set of predefined tests. So this SRAM project was a lot of that, using their systems.

 

We debugged some of their issues along the way, but it was a collaborative effort, I'd say. We got plenty of support from them as well.

 

Ayrton: It was a project where we did a whole new electronics design. A lot of the challenges we met were a hangover from COVID. There were some chips that went end-of-life, and we tried to decrease the cost of the device by using new chips or even eliminating some chips from the system.

 

Sam: The main change was the pressure sensor, which was the most important and most expensive component, I think. It was actually quite a different design, it wasn't as straightforward as just swapping out one thing and everything works the same. The new sensor is slightly less accurate, but it's accurate enough for the user that they're probably not going to notice the difference.

 

But it was a pretty big change in the firmware. We did do the firmware to implement that sensor module and fit it into the existing code.

 

Ayrton: That's a classic case of the Engineering Triangle again, good, fast, cost effective. Choosing chips or firmware code that satisfies the end user experience. If the user doesn't need 0.1% accuracy and they only need 1% accuracy, maybe not required to this particular case, but...

 

Sam: I think that’s pretty close! Then you need to, as an engineer, holistically choose components and systems that are going to satisfy that.

 

Ayrton: And this particular solution had major advantages to bill of materials, cost of goods reduction. Being able to get that end device down to a price point that was more acceptable to many users.

 

I think the number of sold devices was, increased dramatically because the price point was able to be decreased, a lot of it due to the selection of components, and the non-recurring engineering (NRE) upfront that's required to do that engineering to get the thing to work.

 

Sam: A lot of time was spent both by us and SRAM on just characterising that new sensor and how it needed to be calibrated.

 

Ayrton: When we choose any chip that goes in a different product, we have to know it intimately. And Sam's come across this many times. Most chips will have a datasheet. The datasheet could be ten pages long, it could be 10,000 pages long. When you start using different modules in there, the datasheet is usually right, but there's usually bugs. And those bugs are usually some sort of electronics nuance that crops up.

 

Sam: I mean, when it breaks your code, you usually call it a bug. Sometimes if you read the datasheet, it's a bit technical. Maybe it was supposed to work that way all along. But you do have to be careful and read the datasheet when you're interfacing with stuff.

 

Ayrton: Yeah. So, you know, when we go through a project for any IoT product, we’re usually choosing chips that we've used before that we know work, and we know where those bugs are. Any new chip that we put in, we have to understand it intimately. Because that chip is then going to be purchased thousands, tens of thousands, hundreds of thousands of times.

 

And the user experience needs to be seamless, right? We need to design systems which are going to work, in this case, from -40°C all the way to 50°C.

 

Sam: The users of TyreWiz, in terms of performance, won't know the difference between TyreWiz v1 and TyreWiz v2. But in terms of the firmware, they're very different, both the stuff SRAM already did and the stuff we added to it.

 

But they both do the same thing, so the user won’t know the difference, right? Which means we did our job.

 

Ayrton: For testing, we have a PC that connects to a fixture via USB. We put a partially assembled or fully assembled device into that fixture, then start it up and pressurise it. Do a low pressure check, high pressure check. Put a calibration in there, then do a third point pressure check.

 

With the calibration that got put in there, it'll check that the pressure it's reading or that it's outputting is the same as what it's expecting. It'll also functionally test all the other things, like the accelerometer or temperature sensors.

 

Creating the calibration system is inherently a part of firmware design.

 

Sam: Yes, you need to write code that's in your firmware just to talk to your testing software.

 

I think one of the things we're trying to do with Cranio is have the tests use the same API that the production applications are going to use. Something I've noticed is that you end up writing, like, special debug interface code that is intended to never be used by anyone except engineers.

 

But it takes a lot of engineering effort just to maintain that. If you wrote a good application interface, then you don't have to have two interfaces, one for engineers and one for the app.

 

Ayrton: Yeah, fair enough. We kind of did the same thing with ShockWiz, right?

 

Sam: I was much less experienced with ShockWiz. But it works.

 

 

Firmware design for Cranio

 

Ayrton: We're currently working on our very own data logging and control system, Cranio, to make it cheaper and easier for everyone to develop their own digital solutions.

 

One of the key components of Cranio is a library of firmware that can be applied to almost any conceivable application, using our experience developing firmware for different clients over the years.

 

How did this project begin and what have the challenges been thus far?

 

Sam: I think you've been trying to make something like Cranio since before I even started!

 

Ayrton: Firmware has always been a challenge. Before you started, we were creating different electronic devices, I'm pretty good at electronics design. But firmware is a real art of its own.

 

We've tried over many years to do things in different ways, and we've had varying success. But whenever we try to develop a new product, it seems like there is a large amount of rework or doing things in a different way. Cranio is a combination of the experiences we've had over the years.

 

Sam and I were away in America at SRAM back in 2018. We had a conversation, and made the decision to say, let's just do it one way so that we can apply the same code, all the assets we've created, and we can reuse them in different projects.

 

Sam: In a way, it's similar to what SRAM was doing with TyreWiz. The way they used to do things was, a firmware engineer would set up a new project for every product, and then each project would be self-contained and use all its own tools.

 

The engineer would write all the interfaces that didn't exist, and they used the SDK from the microchip vendor. But there's a lot of stuff you have to do, especially for some of the more complicated sensors where there's not just a library. You have to understand the physics behind those sensors.

 

SRAM started unifying all that stuff into one build system where there's shared libraries for all of their products. And you can still build individual products. but they are able to share code from other products, rather than all being self-contained.

 

There are advantages to having things be self-contained and independent. But when, you know, you've got to do a lot of them and you have limited engineers available, it saves people time if there's only one source of truth.

 

I think we did have some attempts to do things that way, but it was always a bit rushed. And when there was a new demo, we’d just spin up a new project. A lot of stuff was being replicated or it was copy pasted.

 

I think the worst example, which is a bit technical, there was a library that was supposed to use an SPI interface. And at some point either the external chip had been changed, or it was the same chip, but they were using the I²C interface instead.

 

And the programmer had put a big defineSPI_I2C_ in their header file. The code all looked like it was for SPI, but it was actually for I²C, like the first argument or the address argument was ignored or whatever.

 

It was a bit frustrating to deal with stuff like that. Because you read the code and the code leads you down a rabbit hole that isn't how it actually works. And you never want to be working on a code base like that.

 

We were thinking about, you know, working with the existing code base and cleaning it up. For HydraTune, we had to come up with the proof of concept. We realised that the microcontrollers we had been using weren't powerful enough, so we took the opportunity. Like switching to a new microcontroller, we'd have to redo a lot of work anyway. Why not start it as a new project?

 

Ayrton: We were also very specific requirements on what we were trying to do. We know we're interfacing with sensors, we know we're outputting things to actuators. With IoT and with Cranio, we're always talking with a control device, either via Bluetooth or an app or the Internet.

 

There's a plethora of different operating systems we can use for IoT. We looked at RTOS Real Time Operating System.

 

Sam: There weren't as many in 2018 as there are now.

 

But the big thing about Cranio really isn't the low level scheduling. It's the integration with the high-level API. We designed the firmware in a way that it's easy to interface with it from a higher-level programming language by using the Google protobuf messages. It's not just as simple as, just use protobuf, but we designed our structures so that it is easy for something outside the firmware to control it. \

 

Then the firmware’s focus is on making that interface as flexible as possible, but not necessarily defining exactly what the user's going to do with it. So even in HydraTune, the app has a lot of flexibility in how it can control the hardware.

 

We were talking about how the app can't move it too far, but that's a restriction we can configure when we build the firmware. The app chooses how often it wants to send messages.

 

Ayrton: That design has given us the ability to have a single device that can operate by itself. A microcontroller that can talk to another microcontroller. A microcontroller that can talk to the Internet or an app via Bluetooth or cellular or Wi-Fi or even LoRa, those sorts of things. That same API is all the way through to, say, the Internet, say the web interface, or the app itself.

 

Sam: Yes. It's been designed to be easy for a web browser to render the different data structures we have.

 

The challenges are that it's very much not a REST compatible API, which can confuse the web developers. We’ve solved some of that in the back end by, like, converting parts of it to things that are a bit more familiar.

 

We can also have, you know, React apps that talk more or less directly to firmware. It gets translated through all our stack.

 

Ayrton: That's due to limitations of resources. Having to run a web server on a little microcontroller would mean that that microcontroller has to be a bigger device, has to be more complex, can't be as cheap as we want it to be.

 

Sam: I think something people don't realise, because as humans we're used to reading natural language, is that parsing text is one of the most computationally expensive things that a lot of firmware ends up having to do. Because it seems easy, because you want to create an interface that you can understand, so you'll, say, use human readable English command words to control the firmware.

 

But that's a trap. It might seem like it's easy because you can understand it, but it's actually doing things in the hardware that are not easy for the processor to deal with, which is why the performance isn't so great. A lot of web based stuff is great, but it's all based around human understandable text.

 

Ayrton: And having a computer that's super powerful!

 

Sam: As a firmware engineer, if I want to see the human understandable representation of an object, I have to attach a debugger to it, or an external tool. I don't just see the human understandable representation.

 

Ayrton: The constraints of the microcontrollers that we're working with is a major part of the design in which we’ve created Cranio. To try and do IoT at lower cost, faster, and better.

 

And it's definitely getting to the point now where we can apply it to nearly any application. It’s part of a couple of big projects like HydraTune and Wear Detection Systems.

 

We did a project for WesTrac with a fan controller device, which was up and running within a week because we had the same firmware that we know is tried and tested with certain electronics.  We built a specific electronics design to control this fan and have some inputs, applied the Cranio firmware to it, wrote a special small bit of code that did that control system. And it was done within weeks.

 

That's the kind of thing we're trying to do with Cranio. But it comes with a s***load of work in the background.

 

 

The need for C code in firmware design

 

Sam: C isn't really a script. It gets compiled to assembly.

 

Ayrton: Firmware and C code is a funny one, because C code is the most performant coding language that every other coding language gets compared to.

 

Sam: It's the best performing practical language. We're past the stage of people writing hand coded assembly, although we need to do that sometimes.

 

Ayrton: One of the challenges with firmware is writing code in C. It's highly performant, but it's kind of seen as old school, and there's not many people who actually do C code these days.

 

Sam: It's a bit niche. I mean, there's Rust, which seems extremely popular. But the challenge I had with Rust was that it requires the C standard library to even work. So you still need C to get Rust to work, at least when I tried it. Maybe they fixed that now.

 

It's probably a good choice if you're developing a web browser, but there are still places for C programming.

 

Ayrton: Yeah, C programming is its own skill set. On a microcontroller where you're interfacing with the electronics and having to understand how to use registers and allocate memory and things like that, it's an art of its own.

 

When we hire software engineers, we look for people who have gone down that path. Not just used C code in some software project, but actually used C code on an embedded project.

 

Sam: I think sometimes in software, it's more of a challenge of finding the right tools to stick together. Of course being able to write code yourself is still important, but I think in firmware you do need to be able to write your algorithms yourself sometimes. And you have to have an understanding of how to write data analysis using C algorithms.

 

Especially with stuff like ShockWiz, which is unique. It's the only thing that does that. And it has to do it in a very resource constrained environment. The first version of ShockWiz didn't have a floating point unit, which is something that you would take for granted in higher level softwares to, say, multiply two numbers together. But in ShockWiz that actually becomes a performance bottleneck, because it has to fall back to software libraries to do that mathematics. Instead of using a normal floating point number, you might end up using a fixed point number.

 

It isn't as big a concern now, as most processors have floating point units. It's only the really cheap ones that don't. But that's something I always remember, and it was pretty fun actually having to solve those challenges with ShockWiz.

 

Ayrton: We love meeting people who do interesting things. If you've worked on any embedded design projects, please contact us. It’s a very niche thing to do, and it's also very hard.

 

Finding good people in firmware engineering is always interesting, to share stories. War stories.


 

📢 Don't miss out - subscribe to The Engineering Triangle Podcast for more.

👍 Like and share the video to spread the knowledge about firmware design!

Comments


bottom of page