This content was presented (with some edits) May 16th, 2020
Introduction
Welcome to the firmware team! We’re glad to have you. Your teaching team for this term will be Jess Douglas Muir (Deactivated) as firmware lead and Catherine Cai as project manager.
In this lesson we’ll be covering:
What firmware is
An overview of our firmware system
How we’re working remotely
What our process for writing firmware is
Just a quick preface before we jump into the content, here’s what these lessons are not:
A C programming tutorial. Although we have a number of videos on C programming, joining up in the hopes it’ll teach you programming is unlikely to get you very far. We really don’t have the resources to teach you programming right from scratch, and there are much more qualified people out on the internet to teach you the basics.
An insult to your intelligence. Aside from C, there are plenty of other skills members may or may not have acquired through hobbies, co-ops, or classes. If you feel like we’re moving too slowly, try to work ahead, but these lessons are targeting the lowest common denominator.
All-encompassing. There’s so many diverse skills that are useful to have as a firmware member, so we’re gonna do our best to cover the important stuff, but you’ll definitely need to google for answers when you’re working on a project.
With that out of the way, let’s get started!
What’s firmware?
It’s not software.
It’s not hardware.
It’s firmware! (thank u for coming to my ted talk)
… That joke definitely worked better in person.
To understand what firmware is, let’s first examine what software is.
What’s Software?
Software is a set of instructions that you run on a computer. For example, your favorite video game or code editor is software. It’s normally stored on your hard drive, then when you want to execute it, your operating system (windows or mac os or linux) will grab those instructions, put them into working memory (RAM), and execute those instructions. Once you’re done with the program, they’ll be erased from RAM to make room for other things.
Software vs. Firmware
Firmware is also a set of instructions, but instead of being stored on your hard drive, they’re stored forever in memory that’s wired directly to the electrical components of the computer. As soon as the computer is powered on, it’ll start executing the instructions it has in firmware.
An example of some firmware can be found in your laptop: something called your BIOS (basic input/output system) is the first program that runs when you power on, which then loads your operating system.
Why does it matter?
Firmware generally has a lot more restrictions than software. Firstly, the processor isn’t very fast and there isn’t much memory available, so our code needs to be simple and not too demanding. We partially get around this restriction by breaking the firmware into small projects and running it on different boards, each responsible for controlling a different part of the car. Breaking it down also helps us work on different parts at the same time.
The purpose of firmware
At the end of the day, in midnight sun, the firmware is there to support the hardware, not the other way around. This means we’re not the protagonist!
If you’re a budding software engineer with big dreams of making the world a better place through AI and block chain or whatever other buzzwords are trending nowadays, this team might not be for you. We keep things simple.
Systems overview
Here’s a diagram of the car’s electrical system:
If this scares you, don’t worry! It scares us too. Thankfully, implementing what’s in this diagram is the hardware team’s job, not ours!
Firmware system overview
See, we don’t even need to worry about wires. Much cleaner and easier to understand.
Each non-bolded line in the diagram represents a firmware project that controls a part of the car’s electrical system, grouped under the groupings in bold. Here’s a quick rundown of what each group of firmware projects does:
Battery: Ensures the battery doesn’t explode.
Driver controls: Takes input from the driver and passes it on to the rest of the system.
Power distribution: Turns other boards on and off (think of it like turning off a normal car, but leaving the radio playing).
Drivetrain: Turns pedal presses into setting current levels for the motors.
Charging: Manages charging the battery from an off-the-shelf wall electric car wall charger or from the solar array.
For the most part, our firmware projects are detailed in confluence. Boards Each sub page is the home for an electrical board’s documentation, most of which have a sub page for firmware.
How we’re working remotely
Even though you write code on a computer, since it’s meant to be run directly on the hardware, it’s not quite the same process when we’re working remotely. Here’s an explanation of how we’re able to do it.
Quick disclaimer: if this section doesn’t really make sense to you, that’s ok! You can still write code without it. But, this should help you understand what the difference is between working remotely and working directly with hardware.
First, let’s talk about compiling code.
Compiling code
As you may or may not know, to run C code, first you have to compile it. This means turning the higher level instructions you write as code into simpler instructions for the computer to understand.
An important caveat here is that not all computers understand the same instructions. For example, the processor in your laptop understands instructions called x86, while the computer chips we run our firmware on understands instructions called ARM.
Compiling our code
To do things like turn lights on or off and read voltages from our hardware components through code, we use pieces of code that are called libraries. Our firmware projects implement the logic parts we need, like determining when and how often to flash a light, then we use the library to actually talk to the light to turn it on or off. What this allows us to do is have different version of the libraries for different type of computers:
This is the key to letting us work remotely! We can write all our C code and run it on our laptops, and never worry about actually touching the hardware, right?
Unfortunately, it’s not quite that simple. Some things are really hard to emulate on x86, especially things that are time sensitive, since you don’t know what else your laptop might also be working on. However, it still gives us enough capability to write code and test our main logic.
Also, the hardware is still around, we’re just not close to it anymore. Good thing zoom, discord, and slack all exist! If we want to run our code on real hardware, we just have to call up the hardware member with the board and ask them to run it for us. Yes this is more inconvenient, but it’s better than showing up a month later without having tested anything at all on hardware.
Writing code
As for actually writing code, it’s important now more than ever that we follow a process for writing code, since it’s a little harder for me to peek over your shoulder and ask how you’re doing. Our process for writing firmware is as follows:
High-level design: we come up with a high level structure of the project that fulfills the requirements.
Detail design: we sort out the specifics, like what events or messages need to be passed between modules of the project.
Implementation: we write the code.
Unit testing: we write tests that test specific parts of the code to make sure our logic works the way we think it does.
IO testing: input/output testing. We run the project on hardware, and make sure the hardware works the way we expect it to.
Integration testing: we connect multiple boards together and make sure they work together the way we expect them to.
Notice how much testing we go through! This is really important. In firmware, writing the code is often only half the battle, and there can be many unforeseen delays when you actually start interacting with hardware.
Collaboration
The TL;DR of this is that we use GitHub and JIRA. We’ll be going over the detailed processes for these in later lessons, but otherwise if you’re familiar with the basics, feel free to skip this section.
GitHub is a version control system that lets us have a master version of our firmware code as well as “branches”. Each branch can have modifications made to it in an isolated environment, then once the changes are checked and verified, they can be “merged” back into master. We use this as a way to give each member an isolated environment to work on their changes in. Excellent tutorials can be found here: https://www.atlassian.com/git/tutorials/using-branches
as well as from our own retired firmware lead Arshan Khanifar: https://www.youtube.com/watch?v=n0attCkKQUU&list=PLwHCeNgf9lKdt6LN6D54__moOb4Mkj5NQ&index=3.
JIRA is a project tracking tool that lets us easily keep track of all the tasks people are assigned to and their progress.
Specifically, we use a kanban board, which is just a visual way of looking at work that helps us make sure not too much is assigned to someone at once. This is part of a much bigger work process called Agile which you should read up on if you’re interested in project management, but we’re just sticking to the very basics and using this board to track tasks.
We put “tickets” on the board, which include the task, the assignee, and some other information about the task.
Again, we’ll be going over how we use these two tools in more depth as part of later lessons.
Conclusion
Thanks for sticking through! In conclusion, here’s what you should come away from reading this with an understanding of:
What firmware is
What our firmware systems do at a high level
How we’re able to work on firmware without direct access to the hardware
Our process for completing firmware projects
Next in firmware 102, we’ll go into more depth on our firmware system, controller boards, our project structure, testing and validation, and our collaboration platforms. We hope to see you there!
Homework
Your homework before the next lesson is to follow the instructions here: Module 1: Setup
Once you’ve got your box set up and have pulled the firmware_xiv repository, build the can_communication project, and run it on the x86 platform with the command (fill in the blanks):
make run PROJECT=... PLATFORM=...
Once it’s started, take a screenshot and send it to the firmware lead (Jess Muir). It should look something like this:
Don’t worry about what anything means, this is just to make sure you’ve got things up and running. You can find other information on make
commands here: https://github.com/uw-midsun/firmware_xiv#usage
Tip: press ctrl+C to exit.