For everything onboarding, this is the place to be. We work hard to ensure you can contribute to NER firmware on any platform, but note that many of us who developed these docs are on Linux, and are less familiar with issues that may pop up on other platforms. With that being said, if anything below does not make sense or doesn’t seem to be working as expected, please reach out to one of us on slack in #s_
embbeddedembedded-software
channel!
Table of Contents | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Environment Setup
PLEASE READ IF USING Windows
We use WSL on Windows. All commands henceforth are either from WSL (labelled WSL) or the Windows “terminal” app (labelled Windows) .
To get ready for this guide, run with Windows Terminal app:
Code Block |
---|
wsl --update |
1. Install Python
...
We use various packages and tools from these ecosystems, and so its essential to have both installed on your machine. Obviously, you can skip this step if you already have these installed.
Info |
---|
if these are not properly installed, the setup script mentioned below will fail miserably unless I ever make it more robust :) |
Mac
Install python with whatever package manager you like, if not already installed
...
Code Block |
---|
brew install python |
Install Rust with rustup:
Code Block |
---|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh |
...
Linux and WSL
Install python with whatever package manager you like, if not already installed
ex on Debian based systems with apt (including WSL):
Code Block |
---|
sudo apt update sudo apt install python3 python3-pip |
Install Rust with rustup:
Code Block |
---|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh |
Windows
Install Python through the official installer
Download the Python installer from https://www.python.org/downloads/ .
Run the installer, and make sure to check the box that says "Add Python to PATH."
Follow the installation prompts.
Install Rust through the official installer
Download and run the Rust installer from https://rust-lang.org/ .
Follow the installation prompts.
2. Install Git
Same deal with package managers as above, but generally:
Mac
Code Block |
---|
brew install git |
Linux
Code Block |
---|
sudo apt install git |
Windows
Download git from the official installer https://gitforwindows.org/
Run the .exe and follow the steps
...
python3-venv |
2. Install and setup Docker (all platforms)
Follow the guidelines found here : to install Docker (Linux) or Docker Desktop (Macos and Windows) Setting Up Docker
...
Windows users: Turn on WSL integration in Docker Desktop settings. Do this by going to Settings → Resources → WSL Integration → Turn on “Ubuntu”
3. Setup Scripts
Info |
---|
It is strongly recommended to maintain a directory structure like the following |
To make installs easier, there is a python script found in our embedded-base repo that will install and build every python and rust package, along with building downloading our docker image.
Clone Embedded Base
To do this, you'll need to setup ssh keys on your machine. If you aren’t sure how to do this, take a look at some of our git resources linked further down in this doc, or the many resources online that can walk through this this resource. You'll also need to be added to our GitHub Organization - if you’ve gotten this far, hopefully you’ve been informed of a slack thread where you can add your username so that we can add you. If not reach out to the #s_embedded_software
channel
Info |
---|
Windows users: For better build performance, clone this to a folder within the Ubuntu disk. Do this by entering the ~ folder with |
Open the Embedded-Base repo, and run
Code Block |
---|
pythonpython3 ner_environment/ner_setup.py |
(if your default python version is 2, run “python3” instead of “python. You can find your default version by running “python --version”)
Info |
---|
This should work for any platform, but as mentioned above, it hasn’t been rigorously tested, so let someone know if it doesn't work |
...
^^^ WINDOWS USERS, do this from WSL. If you did not do it from WSL, remove the folder ner-venv
and start again.
This script does quite a bit behind the scenes. It pull our docker image, it creates a python venv, and installs packages and sets up aliases & entry-points for it. It also installs some other local packages, like probe-rs OpenOCD (an open source debugger written in Rust). For a list of all tools that we use, take a look at the next section.
This script will prompt you to answer ‘yes’ (or simply ‘y') or no (or simply 'n’) quite a bit. For most users, you should select yes to all of the prompts. These options are mostly just there in case you have a really weird linux distro (cough cough jack rubacha), or really know what you are doing and want to go about it manually.
(IF ON LINUX ONLY, ELSE SKIP) Fix Rust-Sudo Dynamic
...
...
Note: need to use “sudo” for steps 2 and 3 in the above link
Set up shell aliases
This is by no means mandatory, but it might be helpful and is a bit hard to automate in the above script. If you’d like to save time activating and de-activating the virtual environment, you can alias these commands for whichever shell you are using For now, I’m not going to walk through instructions for doing this here; there’s many shells you all might be using, and a million ways to do this, but if you are unsure of how to do it feel free to ask someone and they can help you through it. I use fish shell on Linux, so I’ve added this line to my config.fish file:
...
Without this alias, activating the ner-venv (or any python venv for that matter) is done by going to the directory where the venv is located (for this case, it should be one higher directory level than the “Embedded-Base” repo) and running:
On Windows (using bash)To begin developing on Linux/Mac/WSL:
Code Block |
---|
source ner-venv/Scriptsbin/activate |
On Linux/Mac:
...
...
Windows users, see below to https://nerdocs.atlassian.net/wiki/spaces/NER/pages/edit-v2/524451844#c.-(Windows-only)-WSL-passthrough when you want to interact with external hardware!
The virtual environment can then be deactivated from anywhere by running “deactivate”
Note |
---|
When activiating, you may see an error that says soemthing about ls: cant find /bin/bash. No worries if you do, it shouldnt prevent anything from workingYou always need the venv active when trying to interact with our build system |
Developing on our Team
a. Overview
Even if a lot of this is made easier for developers, it is still a good idea to become pretty familiar with what’s going on behind the scenes. As mentioned above, our embedded toolkit combines a python virtual environment with a docker container running Ubuntu to combine the ease and freedom of a local, pip-managed environment with the consistency and reliably of a single-platform backend. As long as docker, python. git and rust have been properly installed, everything below is set up automatically with the setup script!
...
Mainly, our Cmake build system and Renode Emulator work in docker. Whenever executing commands related to this, the command is passed into the container and run in there, streaming the output back to the user’s console. Most other tools, such as those to flash and debug, monitor serial output, and using git happen locally on the user’s machine inside of their venv.
b. Commands
We alias a lot of the most helpful commands to make them easier to use. Here is a (likely incomplete) list of some that you may use the most:
Build - runs the cmake build command in docker
Flash - runs the probe-rs command to upload code to a connected board
Debug - runs the probe-rs command to open a gdb server and debug code
Learning Resources
a. Git
View file | ||
---|---|---|
|
View file | ||
---|---|---|
|
Launchpad
Launchpad is our effort to help new members get acclimated with some of the skills they may use on our team. It is absolutely not going to teach everything, but its meant to be a small project to pick up as your first ticket on the team that will incorporate the general kind of coding that you may become familiar with.
Full disclosure: the boards + environment used here are ESP32s - we do not actually use them in NER (instead, currently all of our boards are STM32s). The tooling here is quite simple, but don't be surprised if its a bit different than what you use after completing this. Similarly, ESPs are known for their Bluetooth capabilities - and while our car doesn't use Bluetooth, I thought it would be really cool to take advantage of it here. Again, this is just supposed to be a fun intro into embedded development that is a little bit more advanced than what you may see in a class like cornerstone- nothing more. Have fun and please ask questions as they come up! We will have dedicated time in the first several meetings of the semester to talk about this, but please slack us anytime throughout the week as needed!
1. Setting Up
Hopefully you’ve done the full setup described throughout this doc. If you have, the launchpad subsystem is embedded into your venv already! in your terminal (with the venv active), simply run
Code Block |
---|
launchpad install |
You should be greeted with a bunch of installs- and this sets up the ESP32 specific tooling. In order for these changes to be recognized, you should deactivate and then reactivate the ner-venv. Also note, you may see some things “error”, but the install continues. This is generally okay, so feel free to ignore.
...
Unzip the file
Right click on the unzipped file called “silabser.inf”, and click install
Follow the prompts
...
Only if on Linux:
...
2. Clone the github classroom repo.
...
api.h/.c - These are the function calls you may need to use. While you should be able to complete the task using just this and other simple calls, you do not necessarily need to if you do not want. The purpose of this was to hide some of the messy syntax from you, and instead provide more clear APIs. Again, you do not need to edit this, but I encourage you to see what these do, since you' have to make calls to these functions. On top of the APIs defined there, I’ve included a comment in api.h with some more function signatures that you have access to that I found helpful to complete the task. Note: I did not create APis to hide FreeRTOS stuff, since you should become familiar with them !
Note |
---|
When testing with the magnet, do not let the magnet touch the board. It is a big piece of metal, and can short components together. It doesn't need to be too close to work! |
That’s all for now!
2. Create the app
Your goal is to create a simple application that utilizes a few of the tools embedded into the ESP chip:
Bluetooth
Hall Effect Sensor (magnetic field strength)
This application, running freeRTOS, should:
continuously read magnetic field data
blink an LED based on the strength of that field (stronger field == faster blinking)
Utilize an interrupt (ISR) to trigger the LED blink
Broadcast the raw data over Bluetooth
Broadcast this data over serial monitor
To complete this, find the comments labeled
Code Block |
---|
// TODO - |
This indicates some functionality that you must implement - and usually follows up with an explanation of what needs to be done. This should be doable with only the API functions in api.h/.c, the other function signatures shown in a comment within api.h, and some simple C logical code. You do not need to edit anything that isn't given a “TODO” comment
That's all! You are not expected to necessarily know anything about freeRTOS, interrupts, or any of these skills; Just because I haven’t in detail explained these things in this doc does not mean you are expected to understand it. I literally am keeping these instructions somewhat vague intentionally to ensure I don't sway you towards doing this a certain way, because there are multiple ways to do it. Ask questions, do some individual investigation, or use whatever tools you want to help. freeRTOS and interrupts are used extensively in our vehicle apps, so getting some experience with them here will help out.
...
Note |
---|
I may not be able to give everyone a board. Whether you get a board or need to come to the RIchards makerspace to test, you'll need to connect to an external LED, which will be setup in the makerspace, to view that component of the output. |
You’ll need a micro-USB cable to connect your laptop to the device. If you don’t have one around, stop by the Richards Makerspace and test it with one of ours down there.
Once your code is ready to build, and assuming you’ve run “launchpad install” in the venv, you can do so with the following command:
Code Block |
---|
lpbuild |
Your code may not compile due to user errors, but there is one error that you may encounter that wouldn’t be the fault of your code. Check the bottom of the Tips section below to see this
To upload the built code to the board, run
Code Block |
---|
lpflash |
...
Info |
---|
While I’ve done my best to automate all of this to work on all platforms, some stuff eventually gets pretty messy. if any of the launchpad commands do not work - either ask someone for help or look into the aliases themselves and try to debug the error (they just alias to platformio commands) . |
4. Tips/keep in mind
The value returned from the sensor is a raw ADC value. This means it is a unitless value, understood as a strength “percentage”. To understand this value, the resolution of the ADC needs to be known. For this device, the default resolution is 12 bits. This value is simply the number of bits used to depict this percentage - the more bits, the higher the precision you are able to achieve.
...
The hall sensor normally would need to be calibrated to account for the ambient magnetic field in your environment. Doing so is out of scope of this task, so don’t worry about it too much, just try to set it up so that the light does not blink much at the reading level it gets without the magnet nearby. Depending on your environment, this might be at different reading values. All apps have the same ADC resolution, but you may read stronger or weaker fields, which is okay. Regardless, the strength should increase as the magnet gets closer. To test this, you may want to simply guess and check - you should incorporate some sort of “offset” ADC value, where the LED doesnt/barely blinks if the reading is as low as you record when no magnet is nearby. Also, it doesn't need to be extremely precise. Maybe you only have 2 or 3 blink speeds for strength ranges - this doesn't need to be a continuous and fine grained speed increase for every tiny change in field strength
When Using multiple threads like in an RTOS application, data atomicity is important. If a piece of data is accessed from multiple threads, it is important to use a locking mechanism, like a mutex or semaphore, to make sure that sharing this data is done safely
Id suggest getting the Bluetooth working first. That way, you can monitor the adc value in real time on your phone as you try to get the blinking mechanism working
(POSSIBLE BUILD ERROR THAT ISN’T YOUR FAULT)
When building, if you get this error:Code Block platformio run --target menuconfig
This should open up a menu. From there, navigate down to “component” and hit enter, and then navigate to “Bluetooth” and hit enter, and then hit enter on the Bluetooth option. Save and exit, and try building again.
...
See /wiki/spaces/NER/pages/611516420 for a full overview of the NER build system
c. (Windows only) WSL passthrough
Basically, WSL doesnt get the USB devices such as our circuit boards, by default. A program usbipd
fixes that. But, it cannot be run from WSL and therefore not automated.
First, to install, run winget install usbipd
in a Windows (non WSL) terminal.
Now, every time a new circuit board is plugged in for the first time, open a adminstrator command prompt terminal and run:
Code Block | ||
---|---|---|
| ||
usbipd list
# identify the device from the list (usually called FTDI or CMSIS-DAP), and enter its bus ID below
usbipd bind --busid <BUS_ID> |
Every time you plug in the device, run from a non-adminstrator windows terminal (not wsl):
Code Block |
---|
usbipd attach --wsl --busid <BUS_ID> |