---
title: "Samples"
canonical_url: https://developer.repebble.com/pebbleos/docs/samples/
last_updated: 2026-11-13
sdk_version: 4.44
---
# Samples

Source: https://developer.repebble.com/pebbleos/docs/samples/

A sample is a small [application](https://developer.repebble.com/pebbleos/docs/development/build_system/applications.md) that shows one part of PebbleOS in use: a kernel object, a subsystem, a driver class. They live in `samples/`, and are meant to be read, run and copied from.

Kernel

- [Threads](https://developer.repebble.com/pebbleos/docs/samples/kernel/threads.md)
- [Mutexes](https://developer.repebble.com/pebbleos/docs/samples/kernel/mutex.md)
- [Semaphores](https://developer.repebble.com/pebbleos/docs/samples/kernel/semaphore.md)
- [Message queues](https://developer.repebble.com/pebbleos/docs/samples/kernel/msgq.md)
- [Poll groups](https://developer.repebble.com/pebbleos/docs/samples/kernel/poll.md)
- [Timers](https://developer.repebble.com/pebbleos/docs/samples/kernel/timer.md)
- [Work queues](https://developer.repebble.com/pebbleos/docs/samples/kernel/work.md)
- [Delayed work](https://developer.repebble.com/pebbleos/docs/samples/kernel/delayed_work.md)
- [Heaps](https://developer.repebble.com/pebbleos/docs/samples/kernel/heap.md)
- [Time](https://developer.repebble.com/pebbleos/docs/samples/kernel/time.md)

Classic synchronization problems

- [Dining philosophers](https://developer.repebble.com/pebbleos/docs/samples/kernel/classic/dining_philosophers.md)
- [Bounded buffer](https://developer.repebble.com/pebbleos/docs/samples/kernel/classic/bounded_buffer.md)
- [Readers and writers](https://developer.repebble.com/pebbleos/docs/samples/kernel/classic/readers_writers.md)
- [Sleeping barber](https://developer.repebble.com/pebbleos/docs/samples/kernel/classic/sleeping_barber.md)
- [Priority inversion](https://developer.repebble.com/pebbleos/docs/samples/kernel/classic/priority_inversion.md)
- [Barrier](https://developer.repebble.com/pebbleos/docs/samples/kernel/classic/barrier.md)

Benchmarks

- [Kernel benchmark](https://developer.repebble.com/pebbleos/docs/samples/benchmarks/kernel.md)

`samples/hello_world` is the smallest one, described in [Applications](https://developer.repebble.com/pebbleos/docs/development/build_system/applications.md).

## Running one

A sample is configured, built and run as any application:

```
pbl configure --board qemu_emery samples/kernel/work
pbl build
pbl run
```

What it prints goes to the console ([pbl console](https://developer.repebble.com/pebbleos/docs/pbl/console.md)).

[pbl samples](https://developer.repebble.com/pebbleos/docs/pbl/samples.md) does all of it at once, without a window, and checks the output:

```
pbl samples samples/kernel/work
```

```
PASS kernel/work (3.6 s)
qemu_emery: 1 passed
```

## Samples are tests

Every sample states what it prints in its `sample.yml`, and CI runs them all on the emulator, so a sample that stops building or printing what its page shows fails a pull request.

```
description: A heap over a buffer of its own, its usage and what fragmentation does to itexpect:- 'heap: empty: 0 used, \d+ free, largest free block \d+'- 'heap: 200 bytes from a fragmented heap: refused'- 'Sample done'
```

Single quotes keep YAML from reading the backslashes.

| 

Key

 | 

Meaning

 |
| --- | --- |
| 

`description`

 | 

One line on what the sample shows, as listed by `pbl samples --list`

 |
| 

`expect`

 | 

Regular expressions the console has to match, each on a later line than the one before; other lines may come in between, but not a second boot, so a sample that panics fails. Its page shows them as its output

 |
| 

`timeout`

 | 

Seconds the sample gets to print them (default: 10)

 |
| 

`boards`

 | 

The boards the sample is for, when it needs hardware not all have (default: every board)

 |
| 

`skip`

 | 

The boards the sample is not for, when few lack what it needs

 |

## Writing a sample

```
samples/<area>/<name>/
  CMakeLists.txt
  sample.yml
  prj.conf what it enables, at least the console and logging
  boards/<board>.conf
  src/main.c
```

- **One subject.** A sample shows one API, in the way it is meant to be used, in about a hundred lines. What needs two belongs in two samples.

- **It ends, and says so.** A sample logs what it does as it goes and finishes with `Sample done`, the last line of `expect`.

- **The same output every time.** `expect` only names lines whose order the code guarantees, by priorities or by waiting on each other, never by how long something happens to take: the emulator’s clock can run late and then catch up, so two sleeps that end close to each other may end together.

- **Plain log formats.** The firmware hashes its logs on watches, which takes `%s`, `%d` and the like without widths or padding, so samples keep to those for their code to work there too.

- **Code to copy.** Errors are checked and returned as in the rest of the tree, and logged before `main()` returns one, so a failing run says why. What threads share is guarded, even a counter: threads of equal priority are time-sliced. Nothing is specific to a board: what differs between boards goes in `boards/<board>.conf`.

- **A page here.** `docs/samples/<area>/<name>.md` says what the sample shows, and the `pebbleos-sample` directive adds the rest from the sample itself, so the page cannot drift from it: how to run it, the boards it is for, the sources named in `:sources:` and, with `:output:`, its `expect`.

```
# MutexesThis sample has two threads add to a balance in two steps...

```{pebbleos-sample}
:path: samples/kernel/mutex
:sources: src/main.c
:output:
```
```

Generated from PebbleOS [f4926c952](https://github.com/coredevices/pebbleos/commit/f4926c952bf9b82bce9e3cdb44645a59531c0ee9). This page is maintained in the pebbleos repository: [docs/samples/index.md](https://github.com/coredevices/pebbleos/blob/f4926c952bf9b82bce9e3cdb44645a59531c0ee9/docs/samples/index.md).
