PebbleOS is the kernel, the drivers, the subsystems and the libraries. What
runs on top of it is an application: the code that provides main(), built
against PebbleOS from its own directory. The watch firmware under pebble/
is one, and so is anything else, from a driver test to a product that is
not a watch.
samples/hello_world is the smallest one:
samples/hello_world/
CMakeLists.txt
src/main.c
cmake_minimum_required(VERSION 3.20)
find_package(PebbleOS REQUIRED HINTS $ENV{PEBBLEOS_BASE})
project(hello_world)
target_sources(app PRIVATE src/main.c)
#include <pbl/logging/logging.h>
int main(void) {
PBL_LOG_ALWAYS("Hello World! %s", CONFIG_BOARD);
return 0;
}
find_package(PebbleOS) configures the build for the board, adds PebbleOS
and defines app, the library the application’s sources go to. It comes
before project(), as it also selects the toolchain. The image is linked
once the application’s CMakeLists.txt has been read, so the application
can use every pbl_* helper described in CMake.
pbl configure takes the application’s directory:
pbl configure --board qemu_emery samples/hello_world
pbl build
pbl run
The message goes to the console once, at boot. Attach pbl console
from another shell, then restart the emulator with system_reset in the
QEMU monitor:
* - 00:00:00.000 init.c:38> *** Booting PebbleOS v4.45.0 ***
* - 00:00:00.004 main.c:7> Hello World! qemu_emery
Plain CMake needs to be told where PebbleOS is, with the PEBBLEOS_BASE
environment variable or with -DPebbleOS_DIR=:
cmake -B build -GNinja -S samples/hello_world -DBOARD=qemu_emery \
-DPebbleOS_DIR=$PWD/cmake
cmake --build build
The image is pebbleos.elf, .hex and .bin in the build directory,
whatever the application calls its project.
The kernel brings the system up before it calls main(), on the main
thread: logging and the task watchdog are running, when enabled
(CONFIG_LOG, CONFIG_TASK_WDT), and every device the board defines has
been initialized (see Device model).
main() may return; the other threads go on.
The kernel and the task watchdog call a few functions an application may override, to decide what a failure does. Their defaults log and reset:
Function |
Called when |
|---|---|
|
An assertion or a panic stops the system |
|
An allocation that must not fail does |
|
A syscall made from unprivileged code returns, or is given bad arguments |
|
A watched thread stops making progress |
An application configures PebbleOS with files in its own directory, applied on top of the board’s defconfig (see Kconfig):
File |
Purpose |
|---|---|
|
What the application enables on every board |
|
What a variant ( |
|
What it enables or tunes on one board |
|
The same, for one variant only |
|
The application’s own options |
|
The device of each role, over the board’s; see Roles |
|
The same, on one board |
|
Changes to the board’s devicetree; see Overlays |
|
The same, on one board |
An application with a Kconfig makes it the root of the configuration
tree: it defines its options and sources PebbleOS’s with
source "Kconfig.pebbleos". Defaults it gives before that line take
precedence over PebbleOS’s own.
Driver classes, subsystems and optional kernel features are off unless
the application asks for them, e.g. CONFIG_ACCEL=y or CONFIG_BT=y: a
board’s defconfig only selects its SoC, platform, boot chain and console
UART, so hello_world builds little more than the kernel. Even the
console and logging are the application’s choice: hello_world enables
them with CONFIG_CONSOLE=y and CONFIG_LOG=y in its prj.conf. The drivers follow from the board’s
Devicetree, and the buses and supplies they use from the drivers.
What an application does with the hardware, such as the firmware’s
backlight levels on obelix, goes in the application’s
boards/obelix.conf.
The firmware is built the same way, from pebble/CMakeLists.txt, and its
configuration follows the same layout: pebble/prj.conf,
pebble/prj_normal.conf, pebble/prj_prf.conf, pebble/boards/ and
pebble/Kconfig.
Generated from PebbleOS f4926c952. This page is maintained in the pebbleos repository: docs/development/build_system/applications.md.