mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
examples: Add second Rust example (gcoap)
This commit is contained in:
parent
49403c7781
commit
6246ab70d1
BIN
examples/rust-gcoap/Cargo.lock
generated
Normal file
BIN
examples/rust-gcoap/Cargo.lock
generated
Normal file
Binary file not shown.
16
examples/rust-gcoap/Cargo.toml
Normal file
16
examples/rust-gcoap/Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[package]
|
||||||
|
name = "rust-gcoap"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Christian Amsüss <chrysn@fsfe.org>"]
|
||||||
|
edition = "2018"
|
||||||
|
resolver = "2"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["staticlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
riot-wrappers = { version = "^0.7", features = [ "with_coap_message", "with_coap_handler" ] }
|
||||||
|
|
||||||
|
coap-message-demos = { git = "https://gitlab.com/chrysn/coap-message-demos/", default-features = false }
|
||||||
|
coap-handler-implementations = "0.1"
|
||||||
|
riot-coap-handler-demos = { git = "https://gitlab.com/etonomy/riot-module-examples/", features = [ "vfs" ] }
|
39
examples/rust-gcoap/Makefile
Normal file
39
examples/rust-gcoap/Makefile
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# name of your application
|
||||||
|
APPLICATION = rust_gcoap
|
||||||
|
|
||||||
|
# If no BOARD is found in the environment, use this default:
|
||||||
|
BOARD ?= native
|
||||||
|
|
||||||
|
# This has to be the absolute path to the RIOT base directory:
|
||||||
|
RIOTBASE ?= $(CURDIR)/../..
|
||||||
|
|
||||||
|
# Basic networking, and gcoap
|
||||||
|
USEMODULE += gcoap
|
||||||
|
USEMODULE += netdev_default
|
||||||
|
USEMODULE += auto_init_gnrc_netif
|
||||||
|
USEMODULE += gnrc_ipv6_default
|
||||||
|
USEMODULE += gnrc_icmpv6_echo
|
||||||
|
|
||||||
|
USEMODULE += ztimer
|
||||||
|
USEMODULE += ztimer_usec
|
||||||
|
USEMODULE += ztimer_msec
|
||||||
|
USEMODULE += ztimer_sec
|
||||||
|
|
||||||
|
USEMODULE += vfs
|
||||||
|
USEMODULE += constfs
|
||||||
|
|
||||||
|
# Comment this out to disable code in RIOT that does safety checking
|
||||||
|
# which is not needed in a production environment but helps in the
|
||||||
|
# development process:
|
||||||
|
DEVELHELP ?= 1
|
||||||
|
|
||||||
|
# Change this to 0 show compiler invocation lines by default:
|
||||||
|
QUIET ?= 1
|
||||||
|
|
||||||
|
# The name of crate (as per Cargo.toml package name, but with '-' replaced with '_')
|
||||||
|
APPLICATION_RUST_MODULE = rust_gcoap
|
||||||
|
BASELIBS += $(APPLICATION_RUST_MODULE).module
|
||||||
|
|
||||||
|
FEATURES_REQUIRED += rust_target
|
||||||
|
|
||||||
|
include $(RIOTBASE)/Makefile.include
|
8
examples/rust-gcoap/Makefile.ci
Normal file
8
examples/rust-gcoap/Makefile.ci
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
BOARD_INSUFFICIENT_MEMORY := \
|
||||||
|
blackpill \
|
||||||
|
bluepill \
|
||||||
|
nucleo-f302r8 \
|
||||||
|
nucleo-f303k8 \
|
||||||
|
nucleo-f334r8 \
|
||||||
|
stm32mp157c-dk2 \
|
||||||
|
#
|
53
examples/rust-gcoap/README.md
Normal file
53
examples/rust-gcoap/README.md
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
gcoap used with Rust
|
||||||
|
====================
|
||||||
|
|
||||||
|
This is the advanced Rust example; see ../rust-hello-world/ for the basics.
|
||||||
|
|
||||||
|
In extension to the basic example, it shows:
|
||||||
|
|
||||||
|
* C code can be mixed with Rust code easily; any C file is built and linked
|
||||||
|
as in applications without Rust.
|
||||||
|
|
||||||
|
While it's technically possible to have header files for that code,
|
||||||
|
it is easier (and likewise often done in C applications)
|
||||||
|
to just translate the entry function's signature manually,
|
||||||
|
as is done with the `do_vfs_init()` function.
|
||||||
|
|
||||||
|
* Code of Rust applications can be spread out into modules,
|
||||||
|
even if it builds on RIOT components.
|
||||||
|
|
||||||
|
The CoAP handler built in the main function
|
||||||
|
combines generic CoAP components (from `coap_message_demos`)
|
||||||
|
with RIOT specific components (from `riot-coap-handler-demos`).
|
||||||
|
|
||||||
|
* Many features of RIOT are exposed to Rust through the riot-wrappers crate,
|
||||||
|
which provides safe wrappers around RIOT structures.
|
||||||
|
|
||||||
|
In this example, the abovementioned CoAP handler is run on the gcoap server,
|
||||||
|
for which the wrappers provide adaptation to the platform independent handler interface.
|
||||||
|
|
||||||
|
Then, ztimer is used to sleep until the network interfaces are expected to be ready.
|
||||||
|
|
||||||
|
Finally, the available network interfaces are iterated over
|
||||||
|
and queried for their IP addresses,
|
||||||
|
which makes it easier (in absence of an interactive shell) to find which address CoAP requests can be directed at.
|
||||||
|
|
||||||
|
How to use
|
||||||
|
----------
|
||||||
|
|
||||||
|
```
|
||||||
|
$ make all flash term
|
||||||
|
[...]
|
||||||
|
main(): This is RIOT! (Version: 2022.01-devel-560-g7f8ed-rust-application)
|
||||||
|
constfs mounted successfully
|
||||||
|
CoAP server ready; waiting for interfaces to settle before reporting addresses...
|
||||||
|
Active interface from PID KernelPID(6) ("gnrc_netdev_tap")
|
||||||
|
Address fe80:0000:0000:0000:1234:56ff:fe78:90ab
|
||||||
|
Address 2a02:0b18:c13b:8018:1234:56ff:fe78:90ab
|
||||||
|
```
|
||||||
|
|
||||||
|
Once that is ready, in a parallel shell, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ aiocoap-client 'coap://[2a02:0b18:c13b:8018:1234:56ff:fe78:90ab]/.well-known/core'
|
||||||
|
```
|
57
examples/rust-gcoap/src/lib.rs
Normal file
57
examples/rust-gcoap/src/lib.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// Copyright (C) 2020 Christian Amsüss
|
||||||
|
//
|
||||||
|
// This file is subject to the terms and conditions of the GNU Lesser
|
||||||
|
// General Public License v2.1. See the file LICENSE in the top level
|
||||||
|
// directory for more details.
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
use riot_wrappers::{riot_main, println};
|
||||||
|
use riot_wrappers::{gcoap, thread, ztimer, gnrc};
|
||||||
|
|
||||||
|
use coap_handler_implementations::{ReportingHandlerBuilder, HandlerBuilder};
|
||||||
|
|
||||||
|
riot_main!(main);
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
extern "C" {
|
||||||
|
fn do_vfs_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe { do_vfs_init() };
|
||||||
|
|
||||||
|
let handler = coap_message_demos::full_application_tree(None)
|
||||||
|
.below(&["ps"], riot_coap_handler_demos::ps::ps_tree())
|
||||||
|
.below(&["vfs"], riot_coap_handler_demos::vfs::vfs("/const"))
|
||||||
|
.with_wkc()
|
||||||
|
;
|
||||||
|
let mut handler = riot_wrappers::coap_handler::GcoapHandler(handler);
|
||||||
|
|
||||||
|
let mut listener = gcoap::SingleHandlerListener::new_catch_all(&mut handler);
|
||||||
|
|
||||||
|
gcoap::scope(|greg| {
|
||||||
|
greg.register(&mut listener);
|
||||||
|
|
||||||
|
println!("CoAP server ready; waiting for interfaces to settle before reporting addresses...");
|
||||||
|
|
||||||
|
let sectimer = ztimer::ZTimer::sec();
|
||||||
|
sectimer.sleep_ticks(2);
|
||||||
|
|
||||||
|
for netif in gnrc::Netif::all() {
|
||||||
|
println!("Active interface from PID {:?} ({:?})", netif.pid(), netif.pid().get_name().unwrap_or("unnamed"));
|
||||||
|
match netif.ipv6_addrs() {
|
||||||
|
Ok(addrs) => {
|
||||||
|
for a in addrs.addresses() {
|
||||||
|
println!(" Address {:?}", a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
println!(" Does not support IPv6.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sending main thread to sleep; can't return or the Gcoap handler would need to be
|
||||||
|
// deregistered (which it can't).
|
||||||
|
loop { thread::sleep(); }
|
||||||
|
})
|
||||||
|
}
|
72
examples/rust-gcoap/vfs.c
Normal file
72
examples/rust-gcoap/vfs.c
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 OTA keys S.A.
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU Lesser
|
||||||
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
|
* directory for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file demonstrates how C code can be mixed with Rust code in an
|
||||||
|
* application in an ad-hoc fashion.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <vfs.h>
|
||||||
|
#include "fs/constfs.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define HELLO_WORLD_CONTENT "Hello World!\n"
|
||||||
|
#define HELLO_RIOT_CONTENT "Hello RIOT!\n"
|
||||||
|
|
||||||
|
#define LARGE "1234567890---------\n" \
|
||||||
|
"1234567890---------\n" \
|
||||||
|
"1234567890---------\n" \
|
||||||
|
"1234567890---------\n" \
|
||||||
|
"1234567890---------\n" \
|
||||||
|
"1234567890---------\n" \
|
||||||
|
"1234567890---------\n" \
|
||||||
|
"1234567890---------\n" \
|
||||||
|
"1234567890---------\n" \
|
||||||
|
"1234567890---------\n" \
|
||||||
|
"1234567890---------\n" \
|
||||||
|
"1234567890---------\n" \
|
||||||
|
"1234567890---------\n"
|
||||||
|
|
||||||
|
static constfs_file_t constfs_files[] = {
|
||||||
|
{
|
||||||
|
.path = "/hello-world",
|
||||||
|
.size = sizeof(HELLO_WORLD_CONTENT),
|
||||||
|
.data = (const uint8_t *)HELLO_WORLD_CONTENT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.path = "/hello-riot",
|
||||||
|
.size = sizeof(HELLO_RIOT_CONTENT),
|
||||||
|
.data = (const uint8_t *)HELLO_RIOT_CONTENT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.path = "/large",
|
||||||
|
.size = sizeof(LARGE),
|
||||||
|
.data = (const uint8_t *)LARGE,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static constfs_t constfs_desc = {
|
||||||
|
.nfiles = ARRAY_SIZE(constfs_files),
|
||||||
|
.files = constfs_files,
|
||||||
|
};
|
||||||
|
|
||||||
|
static vfs_mount_t const_mount = {
|
||||||
|
.fs = &constfs_file_system,
|
||||||
|
.mount_point = "/const",
|
||||||
|
.private_data = &constfs_desc,
|
||||||
|
};
|
||||||
|
|
||||||
|
void do_vfs_init(void) {
|
||||||
|
int res = vfs_mount(&const_mount);
|
||||||
|
if (res < 0) {
|
||||||
|
puts("Error while mounting constfs");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
puts("constfs mounted successfully");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user