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 falshed 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
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
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.
- Unify overlay in loader with the one provided in variant for interoperability with GSoC project
- Autogenerate
defines.txt,includes.txt,cflags.txtfromllext-edkoutput - 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
Debugbuilds (eg. shell over USB) - Fix corner cases with
std::includes (like<iterator>)
- To add a new board (already supported by mainline Zephyr), you'll first need to create its
dts overlayand.confin loader. The overlay MUST contains:- A flash partition called
user_sketch, usually near the end of the flash - A
zephyr,usersection 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.analogWriteif PWM section is empty)
- A flash partition called
- Run
./extra.build.sh $your_board $your_boardand start debugging the errors 😁 - Add an entry in
boards.txtfor your board, manually filling the required fields - If your boards supports
1200pbs touchmethod, implement_on_1200_bpsin a file insidevariant/your_boardfolder - Temporary: create
includes.txtbased 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.