Skip to content

Commit dd2f908

Browse files
committed
Create blinky application
Blinky is a rust port of the samples/blinky application from the main zephyr repo. It performs the same function, but using the DT and GPIO abstractions provided in the zephyr::sys module. Signed-off-by: David Brown <[email protected]>
1 parent 40df591 commit dd2f908

File tree

7 files changed

+248
-0
lines changed

7 files changed

+248
-0
lines changed

samples/blinky/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
5+
project(blinky)
6+
7+
rust_cargo_application()

samples/blinky/Cargo.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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 = "3.7.0"
17+
log = "0.4.22"

samples/blinky/README.rst

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
.. zephyr:code-sample:: blinky
2+
:name: Blinky
3+
:relevant-api: gpio_interface
4+
5+
Blink an LED forever using the GPIO API.
6+
7+
Overview
8+
********
9+
10+
The Blinky sample blinks an LED forever using the :ref:`GPIO API <gpio_api>`.
11+
12+
The source code shows how to:
13+
14+
#. Get a pin specification from the :ref:`devicetree <dt-guide>` as a
15+
:c:struct:`gpio_dt_spec`
16+
#. Configure the GPIO pin as an output
17+
#. Toggle the pin forever
18+
19+
See :zephyr:code-sample:`pwm-blinky` for a similar sample that uses the PWM API instead.
20+
21+
.. _blinky-sample-requirements:
22+
23+
Requirements
24+
************
25+
26+
Your board must:
27+
28+
#. Have an LED connected via a GPIO pin (these are called "User LEDs" on many of
29+
Zephyr's :ref:`boards`).
30+
#. Have the LED configured using the ``led0`` devicetree alias.
31+
32+
Building and Running
33+
********************
34+
35+
Build and flash Blinky as follows, changing ``reel_board`` for your board:
36+
37+
.. zephyr-app-commands::
38+
:zephyr-app: samples/basic/blinky
39+
:board: reel_board
40+
:goals: build flash
41+
:compact:
42+
43+
After flashing, the LED starts to blink and messages with the current LED state
44+
are printed on the console. If a runtime error occurs, the sample exits without
45+
printing to the console.
46+
47+
Build errors
48+
************
49+
50+
You will see a build error at the source code line defining the ``struct
51+
gpio_dt_spec led`` variable if you try to build Blinky for an unsupported
52+
board.
53+
54+
On GCC-based toolchains, the error looks like this:
55+
56+
.. code-block:: none
57+
58+
error: '__device_dts_ord_DT_N_ALIAS_led_P_gpios_IDX_0_PH_ORD' undeclared here (not in a function)
59+
60+
Adding board support
61+
********************
62+
63+
To add support for your board, add something like this to your devicetree:
64+
65+
.. code-block:: DTS
66+
67+
/ {
68+
aliases {
69+
led0 = &myled0;
70+
};
71+
72+
leds {
73+
compatible = "gpio-leds";
74+
myled0: led_0 {
75+
gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
76+
};
77+
};
78+
};
79+
80+
The above sets your board's ``led0`` alias to use pin 13 on GPIO controller
81+
``gpio0``. The pin flags :c:macro:`GPIO_ACTIVE_HIGH` mean the LED is on when
82+
the pin is set to its high state, and off when the pin is in its low state.
83+
84+
Tips:
85+
86+
- See :dtcompatible:`gpio-leds` for more information on defining GPIO-based LEDs
87+
in devicetree.
88+
89+
- If you're not sure what to do, check the devicetrees for supported boards which
90+
use the same SoC as your target. See :ref:`get-devicetree-outputs` for details.
91+
92+
- See :zephyr_file:`include/zephyr/dt-bindings/gpio/gpio.h` for the flags you can use
93+
in devicetree.
94+
95+
- If the LED is built in to your board hardware, the alias should be defined in
96+
your :ref:`BOARD.dts file <devicetree-in-out-files>`. Otherwise, you can
97+
define one in a :ref:`devicetree overlay <set-devicetree-overlays>`.

samples/blinky/prj.conf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CONFIG_GPIO=y
2+
3+
CONFIG_RUST=y
4+
CONFIG_RUST_ALLOC=y
5+
6+
CONFIG_DEBUG=y
7+
CONFIG_MAIN_STACK_SIZE=8192
8+
9+
# Verify that userspace builds work.
10+
# CONFIG_USERSPACE=y

samples/blinky/sample.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
sample:
2+
name: Blinky Sample
3+
tests:
4+
sample.basic.blinky:
5+
tags:
6+
- LED
7+
- gpio
8+
filter: dt_enabled_alias_with_parent_compat("led0", "gpio-leds")
9+
depends_on: gpio
10+
harness: led
11+
integration_platforms:
12+
- frdm_k64f

samples/blinky/src/lib.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright (c) 2024 Linaro LTD
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#![no_std]
5+
6+
use log::warn;
7+
8+
use core::ffi::c_void;
9+
10+
use zephyr::raw::GPIO_OUTPUT_ACTIVE;
11+
use zephyr::time::{ Duration, sleep };
12+
13+
#[no_mangle]
14+
extern "C" fn rust_main() {
15+
zephyr::set_logger();
16+
17+
warn!("Starting blinky");
18+
// println!("Blinky!");
19+
// Invoke "blink" as a user thread.
20+
// blink();
21+
if false {
22+
unsafe {
23+
zephyr::raw::k_thread_user_mode_enter
24+
(Some(blink),
25+
core::ptr::null_mut(),
26+
core::ptr::null_mut(),
27+
core::ptr::null_mut());
28+
}
29+
} else {
30+
unsafe {
31+
blink(core::ptr::null_mut(),
32+
core::ptr::null_mut(),
33+
core::ptr::null_mut());
34+
}
35+
}
36+
}
37+
38+
// fn blink() {
39+
unsafe extern "C" fn blink(_p1: *mut c_void, _p2: *mut c_void, _p3: *mut c_void) {
40+
warn!("Inside of blinky");
41+
42+
let mut led0 = zephyr::devicetree::aliases::led0::get_instance();
43+
44+
if !led0.is_ready() {
45+
warn!("LED is not ready");
46+
loop {
47+
}
48+
// return;
49+
}
50+
51+
led0.configure(GPIO_OUTPUT_ACTIVE);
52+
let duration = Duration::millis_at_least(500);
53+
loop {
54+
led0.toggle_pin();
55+
sleep(duration);
56+
}
57+
}

samples/blinky/src/main.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright (c) 2016 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <stdio.h>
8+
#include <zephyr/kernel.h>
9+
#include <zephyr/drivers/gpio.h>
10+
11+
/* 1000 msec = 1 sec */
12+
#define SLEEP_TIME_MS 1000
13+
14+
/* The devicetree node identifier for the "led0" alias. */
15+
#define LED0_NODE DT_ALIAS(led0)
16+
17+
/*
18+
* A build error on this line means your board is unsupported.
19+
* See the sample documentation for information on how to fix this.
20+
*/
21+
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
22+
23+
int main(void)
24+
{
25+
int ret;
26+
bool led_state = true;
27+
28+
if (!gpio_is_ready_dt(&led)) {
29+
return 0;
30+
}
31+
32+
ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
33+
if (ret < 0) {
34+
return 0;
35+
}
36+
37+
while (1) {
38+
ret = gpio_pin_toggle_dt(&led);
39+
if (ret < 0) {
40+
return 0;
41+
}
42+
43+
led_state = !led_state;
44+
printf("LED state: %s\n", led_state ? "ON" : "OFF");
45+
k_msleep(SLEEP_TIME_MS);
46+
}
47+
return 0;
48+
}

0 commit comments

Comments
 (0)