Skip to content

Commit 5eab99f

Browse files
mjcrossMartin Crossley
andauthored
Add simple async_context example (#721)
* Add simple async_context example * use status_led library, improve comments * use more intiuitive syntax for pointer to function --------- Co-authored-by: Martin Crossley <dev@crossleys.biz>
1 parent 1113ebe commit 5eab99f

12 files changed

Lines changed: 112 additions & 262 deletions

File tree

‎.gitignore‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,9 @@ build-*
77
build_*
88
.DS_Store
99
*.pdf
10+
pio/squarewave/generated/squarewave_wrap.pio.h
11+
pio/squarewave/generated/squarewave.hex
12+
pio/squarewave/generated/squarewave.pio.h
13+
pio/ws2812/generated/ws2812.pio.h
14+
pio/ws2812/generated/ws2812.py
15+
.gitignore

‎CMakeLists.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ endif()
6464

6565
# Hardware-specific examples in subdirectories:
6666
add_subdirectory(adc)
67+
add_subdirectory(async_context)
6768
add_subdirectory(binary_info)
6869
add_subdirectory(bootloaders)
6970
add_subdirectory(clocks)

‎README.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ App|Description
4444
[dma_capture](adc/dma_capture) | Use the DMA to capture many samples from the ADC.
4545
[read_vsys](adc/read_vsys) | Demonstrates how to read VSYS to get the voltage of the power supply.
4646

47+
### async_context
48+
App|Description
49+
---|---
50+
[simple_at_time_worker](async_context/simple_at_time_worker) | Use a worker on a threadsafe background context to blink the on-board LED.
51+
4752
### Binary Info
4853

4954
App|Description

‎async_context/CMakeLists.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_subdirectory_exclude_platforms(simple_at_time_worker)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
add_executable(simple_at_time_worker
2+
simple_at_time_worker.c
3+
)
4+
5+
# common dependencies
6+
target_link_libraries(simple_at_time_worker
7+
pico_stdlib
8+
pico_async_context_threadsafe_background
9+
pico_status_led # generic control of status LED on different boards
10+
)
11+
12+
# create map/bin/hex file etc.
13+
pico_add_extra_outputs(simple_at_time_worker)
14+
15+
# add url via pico_set_program_url
16+
example_auto_set_url(simple_at_time_worker)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Simple at-time worker
2+
3+
A simple example demonstrating how to add an *at-time* worker to an `async_context`.
4+
5+
The program creates an `async_context_threadsafe_background` and uses an *at-time* worker to flash the LED on a Pico or Pico-W board.
6+
7+
## note
8+
An `async_context_threadsafe_background` is generally used to ensure that a non-reentrant library such as lwIP can be used successfully in a multi tasking application; so a practical networking application would typically use the `async_context` provided by `cyw43_arch` rather than creating its own.
9+
10+
More details about `async_context` can be found under [High Level APIs](https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_async_context) in the SDK documentation.
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/**
2+
* Copyright (c) 2026 mjcross
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
#include "pico/stdlib.h"
8+
#include "pico/async_context_threadsafe_background.h"
9+
#include "pico/status_led.h"
10+
11+
#ifndef LED_DELAY_MS
12+
#define LED_DELAY_MS 500
13+
#endif
14+
15+
// define a user data type to be passed to our worker's callback function
16+
typedef struct {
17+
bool led_state;
18+
} my_data_t;
19+
20+
21+
// define a callback function for our worker (MUST be safe to call from an IRQ)
22+
void worker_cb(async_context_t *p_ctx, async_at_time_worker_t *p_worker) {
23+
// unpack our user data instance from `(void *)worker.user_data`
24+
my_data_t *p_my_data = p_worker->user_data;
25+
26+
// update the status LED from our user data and toggle it
27+
status_led_set_state(p_my_data->led_state);
28+
p_my_data->led_state = !p_my_data->led_state;
29+
30+
// re-schedule the worker, so as to flash the LED continuously (an at_time worker is
31+
// automatically removed from the context just before it runs)
32+
async_context_add_at_time_worker_in_ms(p_ctx, p_worker, LED_DELAY_MS);
33+
}
34+
35+
// create an instance of our user data type (MUST still exist when the worker runs)
36+
static my_data_t my_data = {
37+
.led_state = true
38+
};
39+
40+
// create an asynchronous at-time worker that points to our callback function and user
41+
// data (MUST still exist when the worker runs)
42+
static async_at_time_worker_t worker = {
43+
.do_work = &worker_cb,
44+
.user_data = &my_data
45+
};
46+
47+
48+
int main() {
49+
// initialise the status LED
50+
hard_assert(
51+
status_led_init() == true
52+
);
53+
54+
// create and initialise an asynchronous background context with default settings
55+
// note: in a networking application we'd probably reuse the existing cyw43_arch
56+
// context directly with `async_context_t ctx = cyw43_arch_async_context()`
57+
async_context_threadsafe_background_t background;
58+
hard_assert(
59+
async_context_threadsafe_background_init_with_defaults(&background) == true
60+
);
61+
62+
// add our at-time worker to the background context, to run after LED_DELAY_MS
63+
// note: `background.core` is the async_context_t of our threadsafe background. If
64+
// we were using the cyw43 context instead (see above) we'd just put `&ctx` here.
65+
hard_assert(
66+
async_context_add_at_time_worker_in_ms(&background.core, &worker, LED_DELAY_MS) == true
67+
);
68+
69+
// the LED will flash in the background
70+
while(true) {
71+
sleep_ms(5000);
72+
}
73+
}

‎pio/squarewave/generated/squarewave.hex‎

Lines changed: 0 additions & 4 deletions
This file was deleted.

‎pio/squarewave/generated/squarewave.pio.h‎

Lines changed: 0 additions & 45 deletions
This file was deleted.

‎pio/squarewave/generated/squarewave_wrap.pio.h‎

Lines changed: 0 additions & 44 deletions
This file was deleted.

0 commit comments

Comments
 (0)