[LINUX] Port FreeRTOS to Raspberry Pi 4B


When I wanted to integrate Unikernel into an embedded system in a good way, I needed equipment that could run RTOS and Linux at the same time, so I ported it as the title suggests.

I feel that there are many FreeRTOS independent boot configurations when porting for Raspberry Pi, but this time FreeRTOS allows you to boot with Linux at the same time after kicking from u-boot.

It would be very easy if you bring an i.MX8M or ZynqMP SoC that already has an implementation that runs RTOS and Linux at the same time, but if you use Raspberry Pi, it should save you money and acquire knowledge.


You can find it here (https://github.com/TImada/raspi4_freertos). See README.md for how to build and use it.

The base implementation is @eggman's [FreeRTOS] for Raspberry Pi 3 (https://qiita.com/eggman/items/2b6eb18b297673bab6c0). Thank you for the efforts of our predecessors m (_ _) m.

About transplantation

What changed from the base implementation

  1. Since it is premised on "booting from u-boot" and "simultaneous booting with Linux", the startup routine is changed to work from EL2.
  2. Changed FreeRTOS binaries to work with CPU core # 3 (CPU core # 0-2 is for Linux)
  3. Raspberry Pi 4B can use GIC as an interrupt controller, so change to use it
  4. UART changed to use UART2 (by PL011) (UART1 is for Linux)
  5. Added a routine to handle GIC configuration changes by Linux so that it can be started simultaneously with Linux.
  6. Update FreeRTOS kernel version to v10.3.0

Implementation tips

Binary kick on CPU core # 3

As described in detail in Raspberry Pi stub code commentary article, the memory area up to 0xD8 --0xF7 is 8 bytes. Each one is labeled spin_cpuX: X = 0,1,2,3. If you want to kick the binary with CPU core # 3, write the start address of the vector table to spin_cpu3 (= address 0xF0) and issue the SEV instruction, and CPU core # 3 will start working properly.

In this porting, the vector table address writing to address 0xF0 was left to the u-boot mw command, but when this command is executed on CPU core # 0, the writing result stays in the cache and is stored in physical memory. There was a situation where it was not reflected (Alee ...). CPU core # 3 sets the program counter by looking at the value at address 0xF0, but if the value is not reflected in the physical memory, the value at address 0xF0 remains 0x0. At this time, CPU core # 3 has a stub code implemented so that the WFE instruction is issued and a nap is taken.

To solve this problem, it would be nice if u-boot's dcache flush command could be used, but u-boot included in Ubuntu 20.04 LTS for Raspberry Pi 4B did not have this command, so u-boot I had to recompile ...

Simultaneous boot with Linux

If you kick Linux after kicking the FreeRTOS sample from the u-boot prompt, Linux will set GIC for Linux and the GIC configuration you set earlier in FreeRTOS will be overwritten (especially the problem). It was a rewrite of the GIC Distributor settings by Linux). If that happens, the tick timer and UART interrupts will not come in.

So, this time, I implemented a mechanism on the FreeRTOS side to detect the timing when Linux finishes the GIC Distributor setting, and FreeRTOS resets the GIC setting again after Linux finishes the GIC setting. Detection mechanism is a busy loop x2 process that is not friendly to the earth. Eventually we will have to rethink the method.

Code implementation for UART2 (PL011)

If you are familiar with it, you may have already noticed it. Actually, if you use UART1 (mini UART) on the FreeRTOS side, you don't need to implement the UART2 part because UART1 was already in the base implementation.

Yes, of course I knew it, but I dared to do it. Smile.

Next milestone

Ported remoteproc / rpmsg so that Linux and FreeRTOS can communicate.

Recommended Posts

Port FreeRTOS to Raspberry Pi 4B
Introduced python3-OpenCV3 to Raspberry Pi
Raspberry Pi 4B initial setting
I talked to Raspberry Pi
Introducing PyMySQL to raspberry pi3
raspberry pi 1 model b, python
raspberry pi 1 model b, node-red part 17
Output from Raspberry Pi to Line
[Raspberry Pi] Changed Python default to Python3
Connect two USB cameras to Raspberry Pi 4
USB boot on Raspberry Pi 4 Model B
Build OpenCV-Python environment on Raspberry Pi B +
How to install NumPy on Raspberry Pi
Raspberry Pi backup
Why detectMultiScale () is slow on Raspberry Pi B +
How to use Raspberry Pi pie camera Python
Introduced Ceph on Kubernetes on Raspberry Pi 4B (ARM64)
Connect your Raspberry Pi to your smartphone using Blynk
Connect to MySQL with Python on Raspberry Pi
GPS tracking with Raspberry Pi 4B + BU-353S4 (Python)
From setting up Raspberry Pi to installing Python environment
Memo of migrating Django's DB from SQLite 3 to MySQL on Docker on Raspberry Pi 4B
Run LEDmatrix interactively with Raspberry Pi 3B + on Slackbot
What is Raspberry Pi?
Easy IoT to start with Raspberry Pi and MESH
GPGPU with Raspberry Pi
Try to visualize the room with Raspberry Pi, part 1
How to use the Raspberry Pi relay module Python
pigpio on Raspberry pi
Raspberry Pi video camera
Raspberry Pi Bad Knowledge
Let's do Raspberry Pi?
USB boot with Raspberry Pi 4 Model B (3) LVM edition
Control power on / off of USB port of Raspberry Pi
DigitalSignage with Raspberry Pi
Raspberry Pi 4 setup memo
Output to "7-segment LED" using python on Raspberry Pi 3!
Cython on Raspberry Pi
Raspberry Pi system monitoring
Easy introduction to home hack with Raspberry Pi and discord.py
Update Python for Raspberry Pi to 3.7 or later with pyenv
[Note] Installing vmware ESXi on Arm Fling on Raspberry Pi 4B
[Raspberry PI & Garmin GLO] Until you connect Bluetooth GPS to Raspberry Pi
Run BNO055 python sample code with I2C (Raspberry Pi 3B)
I want to disable interrupts on Raspberry Pi (‚Čí DI / EI)
I tried to automate [a certain task] using Raspberry Pi
getrpimodel: Recognize Raspberry Pi model (A, B, B +, B2, B3, etc) with python
Change the message displayed when logging in to Raspberry Pi
How to get temperature from switchBot thermo-hygrometer using raspberry Pi
[Raspberry Pi] Minimum device driver creation memo to output GPIO
Translate I2C device driver for Arduino to Python for Raspberry pi
Connect Raspberry Pi to Alibaba Cloud IoT Platform with Python
I sent the data of Raspberry Pi to GCP (free)
Indoor monitoring using Raspberry Pi
Mutter plants with Raspberry Pi
Install Raspberry Pi OS (Raspbian)
Raspberry Pi + Python + OpenGL memo
Raspbian initial settings (Raspberry Pi 4)
Introduced pyenv on Raspberry Pi
Use NeoPixel on Raspberry Pi
Install OpenCV4 on Raspberry Pi 3