Skip to content

Commit 93b6f5b

Browse files
committed
# Conflicts: # zephyr-sys/wrapper.h
2 parents 830b748 + a683eb8 commit 93b6f5b

File tree

37 files changed

+1459
-1992
lines changed

37 files changed

+1459
-1992
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ ${config_paths}
195195
add_custom_target(librustapp ALL
196196
DEPENDS ${DUMMY_FILE}
197197
# The variables, defined at the top level, don't seem to be accessible here.
198+
offsets_h
198199
syscall_list_h_target
199200
driver_validation_h_target
200201
kobj_types_h_target
@@ -237,6 +238,7 @@ ${config_paths}
237238
add_custom_target(rustdoc
238239
DEPENDS generate_rust_docs
239240
# The variables, defined at the top level, don't seem to be accessible here.
241+
offsets_h
240242
syscall_list_h_target
241243
driver_validation_h_target
242244
kobj_types_h_target

dt-rust.yaml

Lines changed: 25 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,10 @@
77
# few instances were we can actually just match on a property.
88
- name: gpio-controller
99
rules:
10-
- type: has_prop
11-
value: gpio-controller
10+
- !HasProp gpio-controller
1211
actions:
13-
- type: instance
14-
value:
15-
raw:
16-
type: myself
12+
- !Instance
13+
raw: !Myself
1714
device: crate::device::gpio::Gpio
1815
static_type: crate::device::gpio::GpioStatic
1916

@@ -22,68 +19,53 @@
2219
# with each gpio.
2320
- name: gpio-leds
2421
rules:
25-
- type: compatible
26-
value:
27-
names:
28-
- gpio-leds
22+
- !Compatible
23+
names: [gpio-leds]
2924
level: 1
3025
actions:
31-
- type: instance
32-
value:
33-
raw:
34-
type: phandle
35-
value: gpios
26+
- !Instance
27+
raw: !Phandle gpios
3628
device: crate::device::gpio::GpioPin
3729

3830
# Flash controllers don't have any particular property to identify them, so we need a list of
3931
# compatible values that should match.
4032
- name: flash-controller
4133
rules:
42-
- type: compatible
43-
value:
34+
- !Compatible
4435
names:
45-
- "nordic,nrf52-flash-controller"
46-
- "nordic,nrf51-flash-controller"
47-
- "raspberrypi,pico-flash-controller"
48-
- "zephyr,sim-flash"
36+
- "nordic,nrf52-flash-controller"
37+
- "nordic,nrf51-flash-controller"
38+
- "raspberrypi,pico-flash-controller"
39+
- "zephyr,sim-flash"
4940
level: 0
5041
actions:
51-
- type: instance
52-
value:
53-
raw:
54-
type: myself
42+
- !Instance
43+
raw: !Myself
5544
device: crate::device::flash::FlashController
5645

5746
# Flash partitions exist as children of a node compatible with "soc-nv-flash" that itself is a child
5847
# of the controller itself.
5948
# TODO: Get the write and erase property from the DT if present.
6049
- name: flash-partition
6150
rules:
62-
- type: compatible
63-
value:
51+
- !Compatible
6452
names:
65-
- "fixed-partitions"
53+
- "fixed-partitions"
6654
level: 1
67-
- type: compatible
68-
value:
55+
- !Compatible
6956
names:
70-
- "soc-nv-flash"
57+
- "soc-nv-flash"
7158
level: 2
7259
actions:
73-
- type: instance
74-
value:
75-
raw:
76-
type: parent
77-
value:
78-
level: 3
79-
args:
80-
- type: reg
60+
- !Instance
61+
raw: !Parent
62+
level: 3
63+
args:
64+
- !Reg
8165
device: "crate::device::flash::FlashPartition"
8266

8367
# Generate a pseudo node that matches all of the labels across the tree with their nodes.
8468
- name: labels
85-
rules:
86-
- type: root
69+
rules: !Root
8770
actions:
88-
- type: labels
89-
71+
- !Labels

samples/work-philosophers/CMakeLists.txt renamed to samples/async-philosophers/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
cmake_minimum_required(VERSION 3.20.0)
44

55
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
6-
project(work_philosophers)
6+
project(async_philosophers)
77

88
rust_cargo_application()

samples/async-philosophers/Cargo.toml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Copyright (c) 2024 Linaro LTD
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
[package]
5+
# This must be rustapp for now.
6+
name = "rustapp"
7+
version = "0.1.0"
8+
edition = "2021"
9+
description = "A sample hello world application in Rust"
10+
license = "Apache-2.0 or MIT"
11+
12+
[lib]
13+
crate-type = ["staticlib"]
14+
15+
[dependencies]
16+
zephyr = { version = "0.1.0", features = ["time-driver", "executor-zephyr"] }
17+
static_cell = "2.1"
18+
19+
embassy-executor = { version = "0.7.0", features = ["log", "task-arena-size-2048"] }
20+
embassy-sync = "0.6.2"
21+
22+
# For real builds, you should figure out your target's tick rate and set the appropriate feature,
23+
# like in these examples. Without this, embassy-time will assume a 1Mhz tick rate, and every time
24+
# operation will involve a conversion.
25+
embassy-time = "0.4.0"
26+
# embassy-time = { version = "0.4.0", features = ["tick-hz-10_000"] }
27+
# embassy-time = { version = "0.4.0", features = ["tick-hz-100"] }
28+
29+
# Dependencies that are used by build.rs.
30+
[build-dependencies]
31+
zephyr-build = "0.1.0"
32+
33+
[profile.release]
34+
debug-assertions = true
35+
overflow-checks = true
36+
debug = true

samples/work-philosophers/prj.conf renamed to samples/async-philosophers/prj.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ CONFIG_MAIN_STACK_SIZE=8192
77
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
88

99
CONFIG_POLL=y
10+
CONFIG_STACK_CANARIES=y
1011

1112
# CONFIG_DEBUG=y
1213

samples/work-philosophers/sample.yaml renamed to samples/async-philosophers/sample.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
sample:
2-
description: Philosphers, in Rust
3-
name: workq philosophers rust
2+
description: Async Philosphers, in Rust
3+
name: async philosophers rust
44
common:
55
harness: console
66
harness_config:
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//! Async Semaphore based demo
2+
//!
3+
//! This implementation on the dining philosopher problem uses Zephyr semaphores to represent the
4+
//! forks. Each philosopher dines as per the algorithm a number of times, and when the are all
5+
//! finished, the test is considered successful. Deadlock will result in the primary thread not
6+
//! completing.
7+
//!
8+
//! Notably, this uses Rc and RefCell along with spawn_local to demonstrate that multiple async
9+
//! tasks run on the same worker do not need Send. It is just important that write operations on
10+
//! the RefCell do not `.await` or a panic is likely.
11+
12+
use embassy_executor::Spawner;
13+
use embassy_sync::{
14+
blocking_mutex::raw::CriticalSectionRawMutex,
15+
mutex::Mutex,
16+
semaphore::{FairSemaphore, Semaphore},
17+
};
18+
use embassy_time::Timer;
19+
use zephyr::{printkln, sync::Arc};
20+
21+
use crate::{get_random_delay, ResultSignal, Stats, NUM_PHIL};
22+
23+
type ESemaphore = FairSemaphore<CriticalSectionRawMutex, NUM_PHIL>;
24+
25+
/// The semaphores for the forks.
26+
static FORKS: [ESemaphore; NUM_PHIL] = [const { ESemaphore::new(1) }; NUM_PHIL];
27+
28+
/// The semaphore to wait for them all to finish.
29+
static DONE_SEM: ESemaphore = ESemaphore::new(0);
30+
31+
/// Number of iterations of each philospher.
32+
///
33+
/// Should be long enough to exercise the test, but too
34+
/// long and the test will timeout. The delay calculated will randomly be between 25 and 775, and
35+
/// there are two waits, so typically, each "eat" will take about a second.
36+
const EAT_COUNT: usize = 10;
37+
38+
#[embassy_executor::task]
39+
pub async fn phil(spawner: Spawner, stats_sig: &'static ResultSignal) {
40+
// Our overall stats.
41+
let stats = Arc::new(Mutex::new(Stats::default()));
42+
43+
// Spawn off each philosopher.
44+
for i in 0..NUM_PHIL {
45+
let forks = if i == NUM_PHIL - 1 {
46+
[&FORKS[0], &FORKS[i]]
47+
} else {
48+
[&FORKS[i], &FORKS[i + 1]]
49+
};
50+
51+
spawner.spawn(one_phil(forks, i, stats.clone())).unwrap();
52+
}
53+
54+
// Wait for them all to finish.
55+
DONE_SEM.acquire(NUM_PHIL).await.unwrap();
56+
57+
// Send the stats back.
58+
stats_sig.signal(stats);
59+
}
60+
61+
/// Simulate a single philospher.
62+
///
63+
/// The forks must be ordered with the first fork having th lowest number, otherwise this will
64+
/// likely deadlock.
65+
///
66+
/// This will run for EAT_COUNT times, and then return.
67+
#[embassy_executor::task(pool_size = NUM_PHIL)]
68+
async fn one_phil(
69+
forks: [&'static ESemaphore; 2],
70+
n: usize,
71+
stats: Arc<Mutex<CriticalSectionRawMutex, Stats>>,
72+
) {
73+
for i in 0..EAT_COUNT {
74+
// Acquire the forks.
75+
// printkln!("Child {n} take left fork");
76+
forks[0].acquire(1).await.unwrap().disarm();
77+
// printkln!("Child {n} take right fork");
78+
forks[1].acquire(1).await.unwrap().disarm();
79+
80+
// printkln!("Child {n} eating");
81+
let delay = get_random_delay(n, 25);
82+
Timer::after(delay).await;
83+
stats.lock().await.record_eat(n, delay);
84+
85+
// Release the forks.
86+
// printkln!("Child {n} giving up forks");
87+
forks[1].release(1);
88+
forks[0].release(1);
89+
90+
let delay = get_random_delay(n, 25);
91+
Timer::after(delay).await;
92+
stats.lock().await.record_think(n, delay);
93+
94+
printkln!("Philospher {n} finished eating time {i}");
95+
}
96+
97+
DONE_SEM.release(1);
98+
}

0 commit comments

Comments
 (0)