This repository contains the official implementation of Arduino Core for Zephyr based board.
Easily install the core and its toolchains via Board Manager using this URL: https://downloads.arduino.cc/packages/package_zephyr_index.json
Unlike every other Arduino implementation (where the final compilation step is a standalone binary, eventually loaded by a bootloader), this one creates a freestanding elf file that can be dynamically loaded by a static (precompiled) Zephyr firmware.
The most important parts of this project are:
- Zephyr based loader
- LLEXT
- Actual core with variants and the usual
{platform,boards}.txt
- ArduinoCore-API
- post_build_tool
The loader
project should be kept generic and any modification required for a given board should be added to its dts overlay or a special fixup
file (with the proper guards). The loader changes its behaviour based on the Mode
menu. Standard
means that the sketch is loaded automatically, while Debug
requires the user to type sketch
in Zephyr's shell (exposed over the default UART).
For the end user, installing the loader
only requires running Burn Bootloader
while the board is in bootloader mode (double clicking the RESET button should be do the trick). Due to Arduino IDE limitiations, you must select a bogus programmer from Programmers
menu.
Loading the first sketch also requires the board to be placed forcefully in bootloader mode. From then on, the usual "autoload" method will kick in.
We provide some shell scripts to ease installation (Windows not supported ATM) On a new terminal, run
mkdir my_new_zephyr_folder && cd my_new_zephyr_folder git clone https://github.com/arduino/ArduinoCore-zephyr cd ArduinoCore-zephyr ./extra/bootstrap.sh
Then you need to download and install the Zephyr SDK for your OS from https://github.com/zephyrproject-rtos/sdk-ng/releases/tag/v0.16.8
To build a loader, run
export ZEPHYR_SDK_INSTALL_DIR=$folder_where_you_installed_the_sdk ./extra/build.sh $zephyr_board_name $arduino_variant_board_name # eg: ./extra/build.sh arduino_portenta_h7//m7 arduino_portenta_h7
The firmwares will be copied to firmwares folder.
If the board is fully supported by Zephyr, they can also be directly flashed with west flash
After runnign the bootstrap
script, you should be able to symlink the core to $sketchbook/hardware/arduino-git/zephyr
and it will appear in the IDE/CLI. Boards FQBN will then become arduino-git:zephyr:name_from_boards_txt
Q: My Sketch doesn't start (Serial doen't appear)
A: Connect a USB-to-UART adapter to the default UART (eg. TX0/RX0 on Giga, TX,RX on Nano) and read the error message (with the sketch compiled in Default
mode). If you don't own a USB-to-UART adapter, compile the sketch in Debug
mode; this will force the shell to wait until you open the Serial Monitor. Then, run sketch
command and probably you'll be able to read the error (if generated by llext
). For OS crashes, the USB-to-UART adapter is the only way to collect the crash.
Q: I did it and I get a <err> llext: Undefined symbol with no entry in symbol table ...
A: This means you are trying to use a Zephyr function which has not yet been exported. Open llext_exports.c
, add the function you need and recompile/upload the loader.
Q: I want to use a Zephyr subsystem which is not compiled in
A: Open the .conf
file for your board, add the required CONFIG_
, recompile/upload the loader.
Q: I get an OS crash, like <err> os: ***** USAGE FAULT *****
A: This is usally do to some buffer overflow/coding error in the user's own code. However, since the project is still in Beta, a good bug report could help identifying an issue in our code.
Q: I get an out of memory error
A: Since at this point in time collecting bug reports is very important, we are keeping Zephyr's shell enabled and able to load a full sketch (so its stack is very big). Tune your board's .conf
to reduce that size if your platform down't have enough RAM
To report a bug, open the issues and follow the instructions. Any issue opened without the needed information will be discarded.
BLE stack is enabled for Nano 33 BLE; please use this branch to test it.
- Unify overlay in loader with the one provided in variant for interoperability with GSoC project
- Autogenerate
defines.txt
,includes.txt
,cflags.txt
fromllext-edk
output - Network: support UDP and TLS
- USB: switch to USB_DEVICE_STACK_NEXT to support PluggableUSB
- Relocate RODATA in flash to accomodate sketches with large assets
- Provide better error reporting for failed llext operations
- Replace llext_exports.c with proper symbols generation (via inclues)
- Provide better usability for
Debug
builds (eg. shell over USB) - Fix corner cases with
std::
includes (like<iterator>
) - Get rid of all warnings
- To add a new board (already supported by mainline Zephyr), you'll first need to create its
dts overlay
and.conf
in loader. The overlay MUST contains:- A flash partition called
user_sketch
, usually near the end of the flash - A
zephyr,user
section containing the description for GPIOs, Analog, UART, SPI and I2C devices. Feel free to leave some fields empty in case Zephyr support is missing. This will result in some APIs not being available at runtime (eg.analogWrite
if PWM section is empty)
- A flash partition called
- Run
./extra.build.sh $your_board $your_board
and start debugging the errors 😁 - Add an entry in
boards.txt
for your board, manually filling the required fields - If your boards supports
1200pbs touch
method, implement_on_1200_bps
in a file insidevariant/your_board
folder - Temporary: create
includes.txt
based onllext-edk/Makefile.cflags
, taking inspiration for other variants - Temporary: amend
your_board.compiler.zephyr.*
with information fromllext-edk/Makefile.cflags
- Profit!
This effort would have been very hard without the GSoC project and in general the Zephyr community.