examples init

This commit is contained in:
Priec
2025-10-09 12:30:07 +02:00
commit 42ef7c380d
297 changed files with 5093 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
[target.thumbv6m-none-eabi]
runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel"
[target.thumbv7m-none-eabi]
runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel"
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
rustflags = [
"-C", "link-arg=-Tlink.x",
]
[build]
target = "thumbv7m-none-eabi"

910
examples/Cargo.lock generated Normal file
View File

@@ -0,0 +1,910 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "bare-metal"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
dependencies = [
"rustc_version",
]
[[package]]
name = "bare-metal"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603"
[[package]]
name = "bitfield"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cc"
version = "1.2.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "956a5e21988b87f372569b66183b78babf23ebc2e744b733e4350a752c4dafac"
dependencies = [
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cortex-m"
version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9"
dependencies = [
"bare-metal 0.2.5",
"bitfield",
"critical-section",
"embedded-hal 0.2.7",
"volatile-register",
]
[[package]]
name = "cortex-m-rt"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee84e813d593101b1723e13ec38b6ab6abbdbaaa4546553f5395ed274079ddb1"
dependencies = [
"cortex-m-rt-macros",
]
[[package]]
name = "cortex-m-rt-macros"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0f6f3e36f203cfedbc78b357fb28730aa2c6dc1ab060ee5c2405e843988d3c7"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "cortex-m-semihosting"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c23234600452033cc77e4b761e740e02d2c4168e11dbf36ab14a0f58973592b0"
dependencies = [
"cortex-m",
]
[[package]]
name = "critical-section"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
[[package]]
name = "embedded-hal"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
dependencies = [
"nb 0.1.3",
"void",
]
[[package]]
name = "embedded-hal"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89"
[[package]]
name = "embedded-hal-async"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884"
dependencies = [
"embedded-hal 1.0.0",
]
[[package]]
name = "embedded-hal-bus"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "513e0b3a8fb7d3013a8ae17a834283f170deaf7d0eeab0a7c1a36ad4dd356d22"
dependencies = [
"critical-section",
"embedded-hal 1.0.0",
"embedded-hal-async",
]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "fugit"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17186ad64927d5ac8f02c1e77ccefa08ccd9eaa314d5a4772278aa204a22f7e7"
dependencies = [
"gcd",
]
[[package]]
name = "futures"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
name = "futures-core"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
[[package]]
name = "futures-io"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
[[package]]
name = "futures-macro"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.49",
]
[[package]]
name = "futures-sink"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
[[package]]
name = "futures-task"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
[[package]]
name = "futures-util"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
dependencies = [
"futures-core",
"futures-macro",
"futures-sink",
"futures-task",
"pin-project-lite",
"pin-utils",
]
[[package]]
name = "gcd"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a"
[[package]]
name = "generator"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d18470a76cb7f8ff746cf1f7470914f900252ec36bbc40b569d74b1258446827"
dependencies = [
"cc",
"cfg-if",
"libc",
"log",
"rustversion",
"windows",
]
[[package]]
name = "hash32"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606"
dependencies = [
"byteorder",
]
[[package]]
name = "hashbrown"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]]
name = "heapless"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad"
dependencies = [
"hash32",
"stable_deref_trait",
]
[[package]]
name = "indexmap"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.172"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
[[package]]
name = "lm3s6965"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13d7ed5360fee8fd434cf7995ef1d7ad42697abb538e34383a39da8df5495446"
dependencies = [
"cortex-m",
"cortex-m-rt",
]
[[package]]
name = "log"
version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "loom"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca"
dependencies = [
"cfg-if",
"generator",
"pin-utils",
"scoped-tls",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "matchers"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9"
dependencies = [
"regex-automata",
]
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "nb"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
dependencies = [
"nb 1.1.0",
]
[[package]]
name = "nb"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
[[package]]
name = "nu-ansi-term"
version = "0.50.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399"
dependencies = [
"windows-sys",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "panic-semihosting"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee8a3e1233d9073d76a870223512ce4eeea43c067a94a445c13bd6d792d7b1ab"
dependencies = [
"cortex-m",
"cortex-m-semihosting",
]
[[package]]
name = "pin-project-lite"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "portable-atomic"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0"
dependencies = [
"critical-section",
]
[[package]]
name = "proc-macro-error-attr2"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5"
dependencies = [
"proc-macro2",
"quote",
]
[[package]]
name = "proc-macro-error2"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802"
dependencies = [
"proc-macro-error-attr2",
"proc-macro2",
"quote",
"syn 2.0.49",
]
[[package]]
name = "proc-macro2"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "rtic"
version = "2.2.0"
dependencies = [
"bare-metal 1.0.0",
"cortex-m",
"critical-section",
"portable-atomic",
"rtic-core",
"rtic-macros",
]
[[package]]
name = "rtic-common"
version = "1.1.0"
dependencies = [
"critical-section",
"portable-atomic",
]
[[package]]
name = "rtic-core"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9369355b04d06a3780ec0f51ea2d225624db777acbc60abd8ca4832da5c1a42"
[[package]]
name = "rtic-macros"
version = "2.2.0"
dependencies = [
"indexmap",
"proc-macro-error2",
"proc-macro2",
"quote",
"syn 2.0.49",
]
[[package]]
name = "rtic-monotonics"
version = "2.1.0"
dependencies = [
"cfg-if",
"cortex-m",
"fugit",
"portable-atomic",
"rtic-time",
]
[[package]]
name = "rtic-sync"
version = "1.4.0"
dependencies = [
"critical-section",
"embedded-hal 1.0.0",
"embedded-hal-async",
"embedded-hal-bus",
"heapless",
"loom",
"portable-atomic",
"rtic-common",
]
[[package]]
name = "rtic-time"
version = "2.0.1"
dependencies = [
"critical-section",
"embedded-hal 1.0.0",
"embedded-hal-async",
"fugit",
"futures-util",
"rtic-common",
]
[[package]]
name = "rtic_lm3s6965"
version = "0.1.0"
dependencies = [
"bare-metal 1.0.0",
"cfg-if",
"cortex-m",
"cortex-m-semihosting",
"futures",
"heapless",
"lm3s6965",
"panic-semihosting",
"rtic",
"rtic-common",
"rtic-monotonics",
"rtic-sync",
"rtic-time",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver",
]
[[package]]
name = "rustversion"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
[[package]]
name = "scoped-tls"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "sharded-slab"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
dependencies = [
"lazy_static",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "smallvec"
version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "915aea9e586f80826ee59f8453c1101f9d1c4b3964cd2460185ee8e299ada496"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thread_local"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
dependencies = [
"cfg-if",
"once_cell",
]
[[package]]
name = "tracing"
version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
dependencies = [
"pin-project-lite",
"tracing-core",
]
[[package]]
name = "tracing-core"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
dependencies = [
"once_cell",
"valuable",
]
[[package]]
name = "tracing-log"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
dependencies = [
"log",
"once_cell",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5"
dependencies = [
"matchers",
"nu-ansi-term",
"once_cell",
"regex-automata",
"sharded-slab",
"smallvec",
"thread_local",
"tracing",
"tracing-core",
"tracing-log",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "valuable"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]]
name = "vcell"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002"
[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
[[package]]
name = "volatile-register"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc"
dependencies = [
"vcell",
]
[[package]]
name = "windows"
version = "0.61.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419"
dependencies = [
"windows-collections",
"windows-core",
"windows-future",
"windows-link",
"windows-numerics",
]
[[package]]
name = "windows-collections"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
dependencies = [
"windows-core",
]
[[package]]
name = "windows-core"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
dependencies = [
"windows-implement",
"windows-interface",
"windows-link",
"windows-result",
"windows-strings",
]
[[package]]
name = "windows-future"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
dependencies = [
"windows-core",
"windows-link",
"windows-threading",
]
[[package]]
name = "windows-implement"
version = "0.60.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.49",
]
[[package]]
name = "windows-interface"
version = "0.59.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.49",
]
[[package]]
name = "windows-link"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
[[package]]
name = "windows-numerics"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
dependencies = [
"windows-core",
"windows-link",
]
[[package]]
name = "windows-result"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-strings"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows-threading"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
dependencies = [
"windows-link",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"

41
examples/Cargo.toml Normal file
View File

@@ -0,0 +1,41 @@
[package]
name = "rtic_lm3s6965"
categories = ["embedded", "no-std"]
description = "Examples of RTIC apps for the lm3s6965 chip"
license = "MIT OR Apache-2.0"
version = "0.1.0"
edition = "2021"
[workspace]
[dependencies]
heapless = "0.8"
lm3s6965 = "0.2"
cortex-m = "0.7.0"
bare-metal = "1.0.0"
cortex-m-semihosting = "0.5.0"
rtic-time = { path = "../../rtic-time" }
rtic-sync = { path = "../../rtic-sync" }
rtic-common = { path = "../../rtic-common" }
rtic-monotonics = { path = "../../rtic-monotonics", features = ["cortex-m-systick"] }
rtic = { path = "../../rtic" }
cfg-if = "1.0"
[dependencies.futures]
version = "0.3.26"
default-features = false
features = ["async-await"]
[dependencies.panic-semihosting]
features = ["exit"]
version = "0.6.0"
[features]
test-critical-section = [
"rtic/test-critical-section",
"cortex-m/critical-section-single-core",
]
thumbv6-backend = ["rtic/thumbv6-backend"]
thumbv7-backend = ["rtic/thumbv7-backend"]
thumbv8base-backend = ["rtic/thumbv8base-backend"]
thumbv8main-backend = ["rtic/thumbv8main-backend"]

View File

@@ -0,0 +1,65 @@
//! examples/async-channel-done.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
use rtic_sync::{channel::*, make_channel};
#[shared]
struct Shared {}
#[local]
struct Local {}
const CAPACITY: usize = 1;
#[init]
fn init(_: init::Context) -> (Shared, Local) {
let (s, r) = make_channel!(u32, CAPACITY);
receiver::spawn(r).unwrap();
sender1::spawn(s.clone()).unwrap();
sender2::spawn(s.clone()).unwrap();
sender3::spawn(s).unwrap();
(Shared {}, Local {})
}
#[task]
async fn receiver(_c: receiver::Context, mut receiver: Receiver<'static, u32, CAPACITY>) {
while let Ok(val) = receiver.recv().await {
hprintln!("Receiver got: {}", val);
if val == 3 {
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
}
}
#[task]
async fn sender1(_c: sender1::Context, mut sender: Sender<'static, u32, CAPACITY>) {
hprintln!("Sender 1 sending: 1");
sender.send(1).await.unwrap();
hprintln!("Sender 1 done");
}
#[task]
async fn sender2(_c: sender2::Context, mut sender: Sender<'static, u32, CAPACITY>) {
hprintln!("Sender 2 sending: 2");
sender.send(2).await.unwrap();
hprintln!("Sender 2 done");
}
#[task]
async fn sender3(_c: sender3::Context, mut sender: Sender<'static, u32, CAPACITY>) {
hprintln!("Sender 3 sending: 3");
sender.send(3).await.unwrap();
hprintln!("Sender 3 done");
}
}

View File

@@ -0,0 +1,37 @@
//! examples/async-channel-no-receiver.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
use rtic_sync::{channel::*, make_channel};
#[shared]
struct Shared {}
#[local]
struct Local {}
const CAPACITY: usize = 1;
#[init]
fn init(_: init::Context) -> (Shared, Local) {
let (s, _r) = make_channel!(u32, CAPACITY);
sender1::spawn(s.clone()).unwrap();
(Shared {}, Local {})
}
#[task]
async fn sender1(_c: sender1::Context, mut sender: Sender<'static, u32, CAPACITY>) {
hprintln!("Sender 1 sending: 1 {:?}", sender.send(1).await);
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
}

View File

@@ -0,0 +1,38 @@
//! examples/async-channel-no-sender.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
use rtic_sync::{channel::*, make_channel};
#[shared]
struct Shared {}
#[local]
struct Local {}
const CAPACITY: usize = 1;
#[init]
fn init(_: init::Context) -> (Shared, Local) {
let (_s, r) = make_channel!(u32, CAPACITY);
receiver::spawn(r).unwrap();
(Shared {}, Local {})
}
#[task]
async fn receiver(_c: receiver::Context, mut receiver: Receiver<'static, u32, CAPACITY>) {
hprintln!("Receiver got: {:?}", receiver.recv().await);
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
}

View File

@@ -0,0 +1,56 @@
//! examples/async-channel-try.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
use rtic_sync::{channel::*, make_channel};
#[shared]
struct Shared {}
#[local]
struct Local {
sender: Sender<'static, u32, CAPACITY>,
}
const CAPACITY: usize = 1;
#[init]
fn init(_: init::Context) -> (Shared, Local) {
let (s, r) = make_channel!(u32, CAPACITY);
receiver::spawn(r).unwrap();
sender1::spawn(s.clone()).unwrap();
(Shared {}, Local { sender: s.clone() })
}
#[task]
async fn receiver(_c: receiver::Context, mut receiver: Receiver<'static, u32, CAPACITY>) {
while let Ok(val) = receiver.recv().await {
hprintln!("Receiver got: {}", val);
}
}
#[task]
async fn sender1(_c: sender1::Context, mut sender: Sender<'static, u32, CAPACITY>) {
hprintln!("Sender 1 sending: 1");
sender.send(1).await.unwrap();
hprintln!("Sender 1 try sending: 2 {:?}", sender.try_send(2));
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
// This interrupt is never triggered, but is used to demonstrate that
// one can (try to) send data into a channel from a hardware task.
#[task(binds = GPIOA, local = [sender])]
fn hw_task(cx: hw_task::Context) {
cx.local.sender.try_send(3).ok();
}
}

View File

@@ -0,0 +1,62 @@
//! examples/async-channel.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
use rtic_sync::{channel::*, make_channel};
#[shared]
struct Shared {}
#[local]
struct Local {}
const CAPACITY: usize = 5;
#[init]
fn init(_: init::Context) -> (Shared, Local) {
let (s, r) = make_channel!(u32, CAPACITY);
receiver::spawn(r).unwrap();
sender1::spawn(s.clone()).unwrap();
sender2::spawn(s.clone()).unwrap();
sender3::spawn(s).unwrap();
(Shared {}, Local {})
}
#[task]
async fn receiver(_c: receiver::Context, mut receiver: Receiver<'static, u32, CAPACITY>) {
while let Ok(val) = receiver.recv().await {
hprintln!("Receiver got: {}", val);
if val == 3 {
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
}
}
#[task]
async fn sender1(_c: sender1::Context, mut sender: Sender<'static, u32, CAPACITY>) {
hprintln!("Sender 1 sending: 1");
sender.send(1).await.unwrap();
}
#[task]
async fn sender2(_c: sender2::Context, mut sender: Sender<'static, u32, CAPACITY>) {
hprintln!("Sender 2 sending: 2");
sender.send(2).await.unwrap();
}
#[task]
async fn sender3(_c: sender3::Context, mut sender: Sender<'static, u32, CAPACITY>) {
hprintln!("Sender 3 sending: 3");
sender.send(3).await.unwrap();
}
}

View File

@@ -0,0 +1,59 @@
//! examples/async-delay.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [SSI0, UART0], peripherals = true)]
mod app {
use cortex_m_semihosting::{debug, hprintln};
use rtic_monotonics::systick::prelude::*;
systick_monotonic!(Mono, 100);
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(cx: init::Context) -> (Shared, Local) {
hprintln!("init");
Mono::start(cx.core.SYST, 12_000_000);
foo::spawn().ok();
bar::spawn().ok();
baz::spawn().ok();
(Shared {}, Local {})
}
#[task]
async fn foo(_cx: foo::Context) {
hprintln!("hello from foo");
Mono::delay(100.millis()).await;
hprintln!("bye from foo");
}
#[task]
async fn bar(_cx: bar::Context) {
hprintln!("hello from bar");
Mono::delay(200.millis()).await;
hprintln!("bye from bar");
}
#[task]
async fn baz(_cx: baz::Context) {
hprintln!("hello from baz");
Mono::delay(300.millis()).await;
hprintln!("bye from baz");
debug::exit(debug::EXIT_SUCCESS);
}
}

View File

@@ -0,0 +1,93 @@
//! examples/async-task-multiple-prios.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
// NOTES:
//
// - Async tasks cannot have `#[lock_free]` resources, as they can interleave and each async
// task can have a mutable reference stored.
// - Spawning an async task equates to it being polled once.
#[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {
a: u32,
b: u32,
}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
hprintln!("init");
async_task1::spawn(1).ok();
async_task2::spawn().ok();
async_task3::spawn().ok();
async_task4::spawn().ok();
(Shared { a: 0, b: 0 }, Local {})
}
#[idle]
fn idle(_: idle::Context) -> ! {
loop {
hprintln!("idle");
debug::exit(debug::EXIT_SUCCESS);
}
}
#[task(priority = 1, shared = [a, b])]
async fn async_task1(mut cx: async_task1::Context, inc: u32) {
hprintln!(
"hello from async 1 a {}",
cx.shared.a.lock(|a| {
*a += inc;
*a
})
);
}
#[task(priority = 1, shared = [a, b])]
async fn async_task2(mut cx: async_task2::Context) {
hprintln!(
"hello from async 2 a {}",
cx.shared.a.lock(|a| {
*a += 1;
*a
})
);
}
#[task(priority = 2, shared = [a, b])]
async fn async_task3(mut cx: async_task3::Context) {
hprintln!(
"hello from async 3 a {}",
cx.shared.a.lock(|a| {
*a += 1;
*a
})
);
}
#[task(priority = 2, shared = [a, b])]
async fn async_task4(mut cx: async_task4::Context) {
hprintln!(
"hello from async 4 a {}",
cx.shared.a.lock(|a| {
*a += 1;
*a
})
);
}
}

View File

@@ -0,0 +1,71 @@
//! examples/async-task.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
// NOTES:
//
// - Async tasks cannot have `#[lock_free]` resources, as they can interleave and each async
// task can have a mutable reference stored.
// - Spawning an async task equates to it being polled once.
#[rtic::app(device = lm3s6965, dispatchers = [SSI0, UART0], peripherals = true)]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {
a: u32,
}
#[local]
struct Local {}
#[init]
fn init(_cx: init::Context) -> (Shared, Local) {
hprintln!("init");
async_task::spawn().unwrap();
async_task_args::spawn(1, 2).unwrap();
async_task2::spawn().unwrap();
(Shared { a: 0 }, Local {})
}
#[idle(shared = [a])]
fn idle(_: idle::Context) -> ! {
loop {
hprintln!("idle");
debug::exit(debug::EXIT_SUCCESS);
cortex_m::asm::wfi(); // put the MCU in sleep mode until interrupt occurs
}
}
#[task(binds = UART1, shared = [a])]
fn hw_task(cx: hw_task::Context) {
let hw_task::SharedResources { a: _, .. } = cx.shared;
hprintln!("hello from hw");
}
#[task(shared = [a], priority = 1)]
async fn async_task(cx: async_task::Context) {
let async_task::SharedResources { a: _, .. } = cx.shared;
hprintln!("hello from async");
}
#[task(priority = 1)]
async fn async_task_args(_cx: async_task_args::Context, a: u32, b: i32) {
hprintln!("hello from async with args a: {}, b: {}", a, b);
}
#[task(priority = 2, shared = [a])]
async fn async_task2(cx: async_task2::Context) {
let async_task2::SharedResources { a: _, .. } = cx.shared;
hprintln!("hello from async2");
}
}

View File

@@ -0,0 +1,95 @@
//! examples/async-timeout.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use cortex_m_semihosting::{debug, hprintln};
use panic_semihosting as _;
use rtic_monotonics::systick::prelude::*;
systick_monotonic!(Mono, 100);
#[rtic::app(device = lm3s6965, dispatchers = [SSI0, UART0], peripherals = true)]
mod app {
use super::*;
use futures::{future::FutureExt, select_biased};
#[shared]
struct Shared {}
#[local]
struct Local {}
// ANCHOR: init
#[init]
fn init(cx: init::Context) -> (Shared, Local) {
hprintln!("init");
Mono::start(cx.core.SYST, 12_000_000);
// ANCHOR_END: init
foo::spawn().ok();
(Shared {}, Local {})
}
#[task]
async fn foo(_cx: foo::Context) {
// ANCHOR: select_biased
// Call hal with short relative timeout using `select_biased`
select_biased! {
v = hal_get(1).fuse() => hprintln!("hal returned {}", v),
_ = Mono::delay(200.millis()).fuse() => hprintln!("timeout", ), // this will finish first
}
// Call hal with long relative timeout using `select_biased`
select_biased! {
v = hal_get(1).fuse() => hprintln!("hal returned {}", v), // hal finish first
_ = Mono::delay(1000.millis()).fuse() => hprintln!("timeout", ),
}
// ANCHOR_END: select_biased
// ANCHOR: timeout_after_basic
// Call hal with long relative timeout using monotonic `timeout_after`
match Mono::timeout_after(1000.millis(), hal_get(1)).await {
Ok(v) => hprintln!("hal returned {}", v),
_ => hprintln!("timeout"),
}
// ANCHOR_END: timeout_after_basic
// ANCHOR: timeout_at_basic
// get the current time instance
let mut instant = Mono::now();
// do this 3 times
for n in 0..3 {
// absolute point in time without drift
instant += 1000.millis();
Mono::delay_until(instant).await;
// absolute point in time for timeout
let timeout = instant + 500.millis();
hprintln!("now is {:?}, timeout at {:?}", Mono::now(), timeout);
match Mono::timeout_at(timeout, hal_get(n)).await {
Ok(v) => hprintln!("hal returned {} at time {:?}", v, Mono::now()),
_ => hprintln!("timeout"),
}
}
// ANCHOR_END: timeout_at_basic
debug::exit(debug::EXIT_SUCCESS);
}
}
// Emulate some hal
async fn hal_get(n: u32) -> u32 {
// emulate some delay time dependent on n
let d = 350.millis() + n * 100.millis();
hprintln!("the hal takes a duration of {:?}", d);
Mono::delay(d).await;
// emulate some return value
5
}

View File

@@ -0,0 +1,80 @@
//! examples/big-struct-opt.rs
//!
//! Example on how to initialize a large struct without needing to copy it via `LateResources`,
//! effectively saving stack space needed for the copies.
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(missing_docs)]
use panic_semihosting as _;
/// Some big struct
pub struct BigStruct {
/// Big content
pub data: [u8; 2048],
}
impl BigStruct {
fn new() -> Self {
BigStruct { data: [22; 2048] }
}
}
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
mod app {
use super::BigStruct;
use core::mem::MaybeUninit;
use cortex_m_semihosting::{debug, hprintln};
use lm3s6965::Interrupt;
#[shared]
struct Shared {
big_struct: &'static mut BigStruct,
}
#[local]
struct Local {}
#[init(local = [bs: MaybeUninit<BigStruct> = MaybeUninit::uninit()])]
fn init(cx: init::Context) -> (Shared, Local) {
let big_struct = unsafe {
// write directly into the static storage
cx.local.bs.as_mut_ptr().write(BigStruct::new());
&mut *cx.local.bs.as_mut_ptr()
};
rtic::pend(Interrupt::UART0);
async_task::spawn().unwrap();
(
Shared {
// assign the reference so we can use the resource
big_struct,
},
Local {},
)
}
#[idle]
fn idle(_: idle::Context) -> ! {
loop {
hprintln!("idle");
debug::exit(debug::EXIT_SUCCESS);
}
}
#[task(binds = UART0, shared = [big_struct])]
fn uart0(mut cx: uart0::Context) {
cx.shared
.big_struct
.lock(|b| hprintln!("uart0 data:{:?}", &b.data[0..5]));
}
#[task(shared = [big_struct], priority = 2)]
async fn async_task(mut cx: async_task::Context) {
cx.shared
.big_struct
.lock(|b| hprintln!("async_task data:{:?}", &b.data[0..5]));
}
}

View File

@@ -0,0 +1,54 @@
//! examples/binds.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
// `examples/interrupt.rs` rewritten to use `binds`
#[rtic::app(device = lm3s6965)]
mod app {
use cortex_m_semihosting::{debug, hprintln};
use lm3s6965::Interrupt;
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
rtic::pend(Interrupt::UART0);
hprintln!("init");
(Shared {}, Local {})
}
#[idle]
fn idle(_: idle::Context) -> ! {
hprintln!("idle");
rtic::pend(Interrupt::UART0);
loop {
cortex_m::asm::nop();
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
}
#[task(binds = UART0, local = [times: u32 = 0])]
fn foo(cx: foo::Context) {
*cx.local.times += 1;
hprintln!(
"foo called {} time{}",
*cx.local.times,
if *cx.local.times > 1 { "s" } else { "" }
);
}
}

View File

@@ -0,0 +1,86 @@
//! examples/common.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [UART0, UART1])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {}
#[local]
struct Local {
local_to_foo: i64,
local_to_bar: i64,
local_to_idle: i64,
}
// `#[init]` cannot access locals from the `#[local]` struct as they are initialized here.
#[init]
fn init(_: init::Context) -> (Shared, Local) {
foo::spawn().unwrap();
bar::spawn().unwrap();
(
Shared {},
// initial values for the `#[local]` resources
Local {
local_to_foo: 0,
local_to_bar: 0,
local_to_idle: 0,
},
)
}
// `local_to_idle` can only be accessed from this context
#[idle(local = [local_to_idle])]
fn idle(cx: idle::Context) -> ! {
let local_to_idle = cx.local.local_to_idle;
*local_to_idle += 1;
hprintln!("idle: local_to_idle = {}", local_to_idle);
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
// error: no `local_to_foo` field in `idle::LocalResources`
// _cx.local.local_to_foo += 1;
// error: no `local_to_bar` field in `idle::LocalResources`
// _cx.local.local_to_bar += 1;
loop {
cortex_m::asm::nop();
}
}
// `local_to_foo` can only be accessed from this context
#[task(local = [local_to_foo], priority = 1)]
async fn foo(cx: foo::Context) {
let local_to_foo = cx.local.local_to_foo;
*local_to_foo += 1;
// error: no `local_to_bar` field in `foo::LocalResources`
// cx.local.local_to_bar += 1;
hprintln!("foo: local_to_foo = {}", local_to_foo);
}
// `local_to_bar` can only be accessed from this context
#[task(local = [local_to_bar], priority = 1)]
async fn bar(cx: bar::Context) {
let local_to_bar = cx.local.local_to_bar;
*local_to_bar += 1;
// error: no `local_to_foo` field in `bar::LocalResources`
// cx.local.local_to_foo += 1;
hprintln!("bar: local_to_bar = {}", local_to_bar);
}
}

View File

@@ -0,0 +1,129 @@
//! examples/complex.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965)]
mod app {
use cortex_m_semihosting::{debug, hprintln};
use lm3s6965::Interrupt;
#[shared]
struct Shared {
s2: u32, // shared with ceiling 2
s3: u32, // shared with ceiling 3
s4: u32, // shared with ceiling 4
}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
hprintln!("init");
(
Shared {
s2: 0,
s3: 0,
s4: 0,
},
Local {},
)
}
#[idle(shared = [s2, s3])]
fn idle(mut cx: idle::Context) -> ! {
hprintln!("idle p0 started");
rtic::pend(Interrupt::GPIOC);
cx.shared.s3.lock(|s| {
hprintln!("idle enter lock s3 {}", s);
hprintln!("idle pend t0");
rtic::pend(Interrupt::GPIOA); // t0 p2, with shared ceiling 3
hprintln!("idle pend t1");
rtic::pend(Interrupt::GPIOB); // t1 p3, with shared ceiling 3
hprintln!("idle pend t2");
rtic::pend(Interrupt::GPIOC); // t2 p4, no sharing
hprintln!("idle still in lock s3 {}", s);
});
hprintln!("\nback in idle");
cx.shared.s2.lock(|s| {
hprintln!("enter lock s2 {}", s);
hprintln!("idle pend t0");
rtic::pend(Interrupt::GPIOA); // t0 p2, with shared ceiling 2
hprintln!("idle pend t1");
rtic::pend(Interrupt::GPIOB); // t1 p3, no sharing
hprintln!("idle pend t2");
rtic::pend(Interrupt::GPIOC); // t2 p4, no sharing
hprintln!("idle still in lock s2 {}", s);
});
hprintln!("\nidle exit");
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
loop {
cortex_m::asm::nop();
}
}
#[task(binds = GPIOA, priority = 2, local = [times: u32 = 0], shared = [s2, s3])]
fn t0(cx: t0::Context) {
// Safe access to local `static mut` variable
*cx.local.times += 1;
hprintln!(
"t0 p2 called {} time{}",
*cx.local.times,
if *cx.local.times > 1 { "s" } else { "" }
);
hprintln!("t0 p2 exit");
}
#[task(binds = GPIOB, priority = 3, local = [times: u32 = 0], shared = [s3, s4])]
fn t1(mut cx: t1::Context) {
// Safe access to local `static mut` variable
*cx.local.times += 1;
hprintln!(
"t1 p3 called {} time{}",
*cx.local.times,
if *cx.local.times > 1 { "s" } else { "" }
);
cx.shared.s4.lock(|s| {
hprintln!("t1 enter lock s4 {}", s);
hprintln!("t1 pend t0");
rtic::pend(Interrupt::GPIOA); // t0 p2, with shared ceiling 2
hprintln!("t1 pend t2");
rtic::pend(Interrupt::GPIOC); // t2 p4, no sharing
hprintln!("t1 still in lock s4 {}", s);
});
hprintln!("t1 p3 exit");
}
#[task(binds = GPIOC, priority = 4, local = [times: u32 = 0], shared = [s4])]
fn t2(mut cx: t2::Context) {
// Safe access to local `static mut` variable
*cx.local.times += 1;
hprintln!(
"t2 p4 called {} time{}",
*cx.local.times,
if *cx.local.times > 1 { "s" } else { "" }
);
cx.shared.s4.lock(|s| {
hprintln!("enter lock s4 {}", s);
*s += 1;
});
hprintln!("t3 p4 exit");
}
}

View File

@@ -0,0 +1,47 @@
//! examples/declared_locals.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965)]
mod app {
use cortex_m_semihosting::debug;
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init(local = [a: u32 = 0])]
fn init(cx: init::Context) -> (Shared, Local) {
// Locals in `#[init]` have 'static lifetime
let _a: &'static mut u32 = cx.local.a;
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
(Shared {}, Local {})
}
#[idle(local = [a: u32 = 0])]
fn idle(cx: idle::Context) -> ! {
// Locals in `#[idle]` have 'static lifetime
let _a: &'static mut u32 = cx.local.a;
loop {}
}
#[task(binds = UART0, local = [a: u32 = 0])]
fn foo(cx: foo::Context) {
// Locals in `#[task]`s have a local lifetime
let _a: &mut u32 = cx.local.a;
// error: explicit lifetime required in the type of `cx`
// let _a: &'static mut u32 = cx.local.a;
}
}

View File

@@ -0,0 +1,56 @@
//! examples/destructure.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [UART0])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {
a: u32,
b: u32,
c: u32,
}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
foo::spawn().unwrap();
bar::spawn().unwrap();
(Shared { a: 0, b: 1, c: 2 }, Local {})
}
#[idle]
fn idle(_: idle::Context) -> ! {
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
loop {}
}
// Direct destructure
#[task(shared = [&a, &b, &c], priority = 1)]
async fn foo(cx: foo::Context) {
let a = cx.shared.a;
let b = cx.shared.b;
let c = cx.shared.c;
hprintln!("foo: a = {}, b = {}, c = {}", a, b, c);
}
// De-structure-ing syntax
#[task(shared = [&a, &b, &c], priority = 1)]
async fn bar(cx: bar::Context) {
let bar::SharedResources { a, b, c, .. } = cx.shared;
hprintln!("bar: a = {}, b = {}, c = {}", a, b, c);
}
}

View File

@@ -0,0 +1,42 @@
//! examples/executor-size.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [SSI0, UART0], peripherals = true)]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(cx: init::Context) -> (Shared, Local) {
hprintln!("init, total executor size = {}", cx.executors_size);
foo::spawn().ok();
bar::spawn().ok();
baz::spawn().ok();
(Shared {}, Local {})
}
#[task]
async fn foo(_cx: foo::Context) {}
#[task]
async fn bar(_cx: bar::Context) {}
#[task]
async fn baz(_cx: baz::Context) {
debug::exit(debug::EXIT_SUCCESS);
}
}

View File

@@ -0,0 +1,59 @@
//! examples/extern_binds.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use cortex_m_semihosting::{debug, hprintln};
use lm3s6965::Interrupt;
use panic_semihosting as _;
// Free function implementing `init`.
fn init(_: app::init::Context) -> (app::Shared, app::Local) {
rtic::pend(Interrupt::UART0);
hprintln!("init");
(app::Shared {}, app::Local {})
}
// Free function implementing `idle`.
fn idle(_: app::idle::Context) -> ! {
hprintln!("idle");
rtic::pend(Interrupt::UART0);
loop {
cortex_m::asm::nop();
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
}
// Free function implementing the interrupt bound task `foo`.
fn foo(_: app::foo::Context) {
hprintln!("foo called");
}
#[rtic::app(device = lm3s6965)]
mod app {
use crate::{foo, idle, init};
#[shared]
pub struct Shared {}
#[local]
pub struct Local {}
extern "Rust" {
#[init]
fn init(_: init::Context) -> (Shared, Local);
#[idle]
fn idle(_: idle::Context) -> !;
#[task(binds = UART0)]
fn foo(_: foo::Context);
}
}

View File

@@ -0,0 +1,40 @@
//! examples/extern_spawn.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use cortex_m_semihosting::{debug, hprintln};
use panic_semihosting as _;
// Free function implementing the spawnable task `foo`.
// Notice, you need to indicate an anonymous lifetime <'a_>
async fn foo(_c: app::foo::Context<'_>) {
hprintln!("foo");
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
mod app {
use crate::foo;
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
foo::spawn().unwrap();
(Shared {}, Local {})
}
extern "Rust" {
#[task()]
async fn foo(_c: foo::Context);
}
}

View File

@@ -0,0 +1,67 @@
//! examples/generics.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use cortex_m_semihosting::hprintln;
use panic_semihosting as _;
use rtic::Mutex;
#[rtic::app(device = lm3s6965)]
mod app {
use cortex_m_semihosting::{debug, hprintln};
use lm3s6965::Interrupt;
#[shared]
struct Shared {
shared: u32,
}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
rtic::pend(Interrupt::UART0);
rtic::pend(Interrupt::UART1);
(Shared { shared: 0 }, Local {})
}
#[task(binds = UART0, shared = [shared], local = [state: u32 = 0])]
fn uart0(c: uart0::Context) {
hprintln!("UART0(STATE = {})", *c.local.state);
// second argument has type `shared::shared`
super::advance(c.local.state, c.shared.shared);
rtic::pend(Interrupt::UART1);
cortex_m::asm::nop();
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
#[task(binds = UART1, priority = 2, shared = [shared], local = [state: u32 = 0])]
fn uart1(c: uart1::Context) {
hprintln!("UART1(STATE = {})", *c.local.state);
// second argument has type `shared::shared`
super::advance(c.local.state, c.shared.shared);
}
}
// the second parameter is generic: it can be any type that implements the `Mutex` trait
fn advance(state: &mut u32, mut shared: impl Mutex<T = u32>) {
*state += 1;
let (old, new) = shared.lock(|shared: &mut u32| {
let old = *shared;
*shared += *state;
(old, *shared)
});
hprintln!("shared: {} -> {}", old, new);
}

View File

@@ -0,0 +1,60 @@
//! examples/hardware.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965)]
mod app {
use cortex_m_semihosting::{debug, hprintln};
use lm3s6965::Interrupt;
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
// Pends the UART0 interrupt but its handler won't run until *after*
// `init` returns because interrupts are disabled
rtic::pend(Interrupt::UART0); // equivalent to NVIC::pend
hprintln!("init");
(Shared {}, Local {})
}
#[idle]
fn idle(_: idle::Context) -> ! {
// interrupts are enabled again; the `UART0` handler runs at this point
hprintln!("idle");
// Some backends provide a manual way of pending an
// interrupt.
rtic::pend(Interrupt::UART0);
loop {
cortex_m::asm::nop();
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
}
#[task(binds = UART0, local = [times: u32 = 0])]
fn uart0(cx: uart0::Context) {
// Safe access to local `static mut` variable
*cx.local.times += 1;
hprintln!(
"UART0 called {} time{}",
*cx.local.times,
if *cx.local.times > 1 { "s" } else { "" }
);
}
}

View File

@@ -0,0 +1,48 @@
//! examples/idle-wfi.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965)]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(mut cx: init::Context) -> (Shared, Local) {
hprintln!("init");
// Set the ARM SLEEPONEXIT bit to go to sleep after handling interrupts
// See https://developer.arm.com/docs/100737/0100/power-management/sleep-mode/sleep-on-exit-bit
cx.core.SCB.set_sleepdeep();
(Shared {}, Local {})
}
#[idle(local = [x: u32 = 0])]
fn idle(cx: idle::Context) -> ! {
// Locals in idle have lifetime 'static
let _x: &'static mut u32 = cx.local.x;
hprintln!("idle");
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
loop {
// Now Wait For Interrupt is used instead of a busy-wait loop
// to allow MCU to sleep between interrupts
// https://developer.arm.com/documentation/ddi0406/c/Application-Level-Architecture/Instruction-Details/Alphabetical-list-of-instructions/WFI
rtic::export::wfi()
}
}
}

41
examples/examples/idle.rs Normal file
View File

@@ -0,0 +1,41 @@
//! examples/idle.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965)]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
hprintln!("init");
(Shared {}, Local {})
}
#[idle(local = [x: u32 = 0])]
fn idle(cx: idle::Context) -> ! {
// Locals in idle have lifetime 'static
let _x: &'static mut u32 = cx.local.x;
hprintln!("idle");
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
loop {
cortex_m::asm::nop();
}
}
}

42
examples/examples/init.rs Normal file
View File

@@ -0,0 +1,42 @@
//! examples/init.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, peripherals = true)]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init(local = [x: u32 = 0])]
fn init(cx: init::Context) -> (Shared, Local) {
// Cortex-M peripherals
let _core: cortex_m::Peripherals = cx.core;
// Device specific peripherals
let _device: lm3s6965::Peripherals = cx.device;
// Locals in `init` have 'static lifetime
let _x: &'static mut u32 = cx.local.x;
// Access to the critical section token,
// to indicate that this is a critical section
let _cs_token: bare_metal::CriticalSection = cx.cs;
hprintln!("init");
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
(Shared {}, Local {})
}
}

View File

@@ -0,0 +1,86 @@
//! examples/locals.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [UART0, UART1])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {}
#[local]
struct Local {
local_to_foo: i64,
local_to_bar: i64,
local_to_idle: i64,
}
// `#[init]` cannot access locals from the `#[local]` struct as they are initialized here.
#[init]
fn init(_: init::Context) -> (Shared, Local) {
foo::spawn().unwrap();
bar::spawn().unwrap();
(
Shared {},
// initial values for the `#[local]` resources
Local {
local_to_foo: 0,
local_to_bar: 0,
local_to_idle: 0,
},
)
}
// `local_to_idle` can only be accessed from this context
#[idle(local = [local_to_idle])]
fn idle(cx: idle::Context) -> ! {
let local_to_idle = cx.local.local_to_idle;
*local_to_idle += 1;
hprintln!("idle: local_to_idle = {}", local_to_idle);
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
// error: no `local_to_foo` field in `idle::LocalResources`
// _cx.local.local_to_foo += 1;
// error: no `local_to_bar` field in `idle::LocalResources`
// _cx.local.local_to_bar += 1;
loop {
cortex_m::asm::nop();
}
}
// `local_to_foo` can only be accessed from this context
#[task(local = [local_to_foo], priority = 1)]
async fn foo(cx: foo::Context) {
let local_to_foo = cx.local.local_to_foo;
*local_to_foo += 1;
// error: no `local_to_bar` field in `foo::LocalResources`
// cx.local.local_to_bar += 1;
hprintln!("foo: local_to_foo = {}", local_to_foo);
}
// `local_to_bar` can only be accessed from this context
#[task(local = [local_to_bar], priority = 1)]
async fn bar(cx: bar::Context) {
let local_to_bar = cx.local.local_to_bar;
*local_to_bar += 1;
// error: no `local_to_foo` field in `bar::LocalResources`
// cx.local.local_to_foo += 1;
hprintln!("bar: local_to_bar = {}", local_to_bar);
}
}

View File

@@ -0,0 +1,50 @@
//! examples/lock-free.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965)]
mod app {
use cortex_m_semihosting::{debug, hprintln};
use lm3s6965::Interrupt;
#[shared]
struct Shared {
#[lock_free] // <- lock-free shared resource
counter: u64,
}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
rtic::pend(Interrupt::UART0);
(Shared { counter: 0 }, Local {})
}
#[task(binds = UART0, shared = [counter])] // <- same priority
fn foo(c: foo::Context) {
rtic::pend(Interrupt::UART1);
*c.shared.counter += 1; // <- no lock API required
let counter = *c.shared.counter;
hprintln!(" foo = {}", counter);
}
#[task(binds = UART1, shared = [counter])] // <- same priority
fn bar(c: bar::Context) {
rtic::pend(Interrupt::UART0);
*c.shared.counter += 1; // <- no lock API required
let counter = *c.shared.counter;
hprintln!(" bar = {}", counter);
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
}

72
examples/examples/lock.rs Normal file
View File

@@ -0,0 +1,72 @@
//! examples/lock.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [GPIOA, GPIOB, GPIOC])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {
shared: u32,
}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
foo::spawn().unwrap();
(Shared { shared: 0 }, Local {})
}
// when omitted priority is assumed to be `1`
#[task(shared = [shared])]
async fn foo(mut c: foo::Context) {
hprintln!("A");
// the lower priority task requires a critical section to access the data
c.shared.shared.lock(|shared| {
// data can only be modified within this critical section (closure)
*shared += 1;
// bar will *not* run right now due to the critical section
bar::spawn().unwrap();
hprintln!("B - shared = {}", *shared);
// baz does not contend for `shared` so it's allowed to run now
baz::spawn().unwrap();
});
// critical section is over: bar can now start
hprintln!("E");
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
#[task(priority = 2, shared = [shared])]
async fn bar(mut c: bar::Context) {
// the higher priority task does still need a critical section
let shared = c.shared.shared.lock(|shared| {
*shared += 1;
*shared
});
hprintln!("D - shared = {}", shared);
}
#[task(priority = 3)]
async fn baz(_: baz::Context) {
hprintln!("C");
}
}

View File

@@ -0,0 +1,56 @@
//! examples/mutlilock.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [GPIOA])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {
shared1: u32,
shared2: u32,
shared3: u32,
}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
locks::spawn().unwrap();
(
Shared {
shared1: 0,
shared2: 0,
shared3: 0,
},
Local {},
)
}
// when omitted priority is assumed to be `1`
#[task(shared = [shared1, shared2, shared3])]
async fn locks(c: locks::Context) {
let s1 = c.shared.shared1;
let s2 = c.shared.shared2;
let s3 = c.shared.shared3;
(s1, s2, s3).lock(|s1, s2, s3| {
*s1 += 1;
*s2 += 1;
*s3 += 1;
hprintln!("Multiple locks, s1: {}, s2: {}, s3: {}", *s1, *s2, *s3);
});
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
}

View File

@@ -0,0 +1,67 @@
//! `examples/not-sync.rs`
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(missing_docs)]
use core::marker::PhantomData;
use panic_semihosting as _;
/// Not sync
pub struct NotSync {
_0: PhantomData<*const ()>,
data: u32,
}
unsafe impl Send for NotSync {}
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
mod app {
use super::NotSync;
use core::marker::PhantomData;
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {
shared: NotSync,
}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
hprintln!("init");
foo::spawn().unwrap();
bar::spawn().unwrap();
(
Shared {
shared: NotSync {
_0: PhantomData,
data: 13,
},
},
Local {},
)
}
#[idle]
fn idle(_: idle::Context) -> ! {
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
loop {}
}
#[task(shared = [&shared], priority = 1)]
async fn foo(c: foo::Context) {
let shared: &NotSync = c.shared.shared;
hprintln!("foo a {}", shared.data);
}
#[task(shared = [&shared], priority = 1)]
async fn bar(c: bar::Context) {
let shared: &NotSync = c.shared.shared;
hprintln!("bar a {}", shared.data);
}
}

View File

@@ -0,0 +1,43 @@
//! examples/only-shared-access.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [UART0, UART1])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {
key: u32,
}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
foo::spawn().unwrap();
bar::spawn().unwrap();
(Shared { key: 0xdeadbeef }, Local {})
}
#[task(shared = [&key])]
async fn foo(cx: foo::Context) {
let key: &u32 = cx.shared.key;
hprintln!("foo(key = {:#x})", key);
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
#[task(priority = 2, shared = [&key])]
async fn bar(cx: bar::Context) {
hprintln!("bar(key = {:#x})", cx.shared.key);
}
}

View File

@@ -0,0 +1,28 @@
//! examples/peripherals-taken.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965)]
mod app {
use cortex_m_semihosting::debug;
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
assert!(cortex_m::Peripherals::take().is_none());
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
(Shared {}, Local {})
}
}

102
examples/examples/pool.rs Normal file
View File

@@ -0,0 +1,102 @@
//! examples/pool.rs
#![no_main]
#![no_std]
#![deny(warnings)]
use panic_semihosting as _;
use rtic::app;
// thumbv6-none-eabi does not support pool
// This might be better worked around in the build system,
// but for proof of concept, let's try having one example
// being different for different backends
// https://docs.rs/heapless/0.8.0/heapless/pool/index.html#target-support
cfg_if::cfg_if! {
if #[cfg(feature = "thumbv6-backend")] {
// Copy of the smallest.rs example
#[app(device = lm3s6965)]
mod app {
use cortex_m_semihosting::debug;
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
(Shared {}, Local {})
}
}
} else {
// Run actual pool example
use heapless::{
box_pool,
pool::boxed::{Box, BoxBlock},
};
// Declare a pool containing 8-byte memory blocks
box_pool!(P: u8);
const POOL_CAPACITY: usize = 512;
#[app(device = lm3s6965, dispatchers = [SSI0, QEI0])]
mod app {
use crate::{Box, BoxBlock, POOL_CAPACITY};
use cortex_m_semihosting::debug;
use lm3s6965::Interrupt;
// Import the memory pool into scope
use crate::P;
#[shared]
struct Shared {}
#[local]
struct Local {}
const BLOCK: BoxBlock<u8> = BoxBlock::new();
#[init(local = [memory: [BoxBlock<u8>; POOL_CAPACITY] = [BLOCK; POOL_CAPACITY]])]
fn init(cx: init::Context) -> (Shared, Local) {
for block in cx.local.memory {
// Give the 'static memory to the pool
P.manage(block);
}
rtic::pend(Interrupt::I2C0);
(Shared {}, Local {})
}
#[task(binds = I2C0, priority = 2)]
fn i2c0(_: i2c0::Context) {
// Claim 128 u8 blocks
let x = P.alloc(128).unwrap();
// .. send it to the `foo` task
foo::spawn(x).ok().unwrap();
// send another 128 u8 blocks to the task `bar`
bar::spawn(P.alloc(128).unwrap()).ok().unwrap();
}
#[task]
async fn foo(_: foo::Context, _x: Box<P>) {
// explicitly return the block to the pool
drop(_x);
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
#[task(priority = 2)]
async fn bar(_: bar::Context, _x: Box<P>) {
// this is done automatically so we can omit the call to `drop`
// drop(_x);
}
}
}
}

View File

@@ -0,0 +1,48 @@
//! examples/preempt.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
use rtic::app;
#[app(device = lm3s6965, dispatchers = [SSI0, QEI0])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
foo::spawn().unwrap();
(Shared {}, Local {})
}
#[task(priority = 1)]
async fn foo(_: foo::Context) {
hprintln!("foo - start");
baz::spawn().unwrap();
hprintln!("foo - end");
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
#[task(priority = 2)]
async fn bar(_: bar::Context) {
hprintln!(" bar");
}
#[task(priority = 2)]
async fn baz(_: baz::Context) {
hprintln!(" baz - start");
bar::spawn().unwrap();
hprintln!(" baz - end");
}
}

View File

@@ -0,0 +1,86 @@
//! examples/prio-inversion.rs
//!
//! Here we test to make sure we don't have priority inversion.
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
use rtic::app;
// t1 p1 use b, a
// t2 p2 use a
// t3 p3
// t4 p4 use b
//
// so t1 start , take b take a, pend t3
// t3 should not start
// try to see if it starts, IT SHOULD NOT
#[app(device = lm3s6965, dispatchers = [SSI0, QEI0, GPIOA, GPIOB])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {
a: u32,
b: u32,
}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
foo::spawn().unwrap();
(Shared { a: 0, b: 0 }, Local {})
}
#[task(priority = 1, shared = [a, b])]
async fn foo(cx: foo::Context) {
let foo::SharedResources { mut a, mut b, .. } = cx.shared;
hprintln!("foo - start");
// basepri = 0
b.lock(|b| {
// basepri = max(basepri = 0, ceil(b) = 4) = 4
a.lock(|a| {
// basepri = max(basepri = 4, ceil(a) = 2) = 4
hprintln!("pre baz spawn {} {}", a, b);
// This spawn should be blocked as prio(baz) = 3
baz::spawn().unwrap();
hprintln!("post baz spawn {} {}", a, b);
});
// basepri = 4
});
// basepri = 0
hprintln!("foo - end");
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
#[task(priority = 2, shared = [a])]
async fn bar(_: bar::Context) {
hprintln!(" bar");
}
#[task(priority = 3)]
async fn baz(_: baz::Context) {
hprintln!(" baz - start");
hprintln!(" baz - end");
}
#[task(priority = 4, shared = [b])]
async fn pow(_: pow::Context) {
hprintln!(" pow - start");
hprintln!(" pow - end");
}
}

View File

@@ -0,0 +1,49 @@
//! examples/ramfunc.rs
//! TODO: verify that ram-sections are properly used
#![no_main]
#![no_std]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(
device = lm3s6965,
dispatchers = [
UART0,
#[link_section = ".data.UART1"]
UART1
])
]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
foo::spawn().unwrap();
(Shared {}, Local {})
}
#[inline(never)]
#[task]
async fn foo(_: foo::Context) {
hprintln!("foo");
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
// run this task from RAM
#[inline(never)]
#[link_section = ".data.bar"]
#[task(priority = 2)]
async fn bar(_: bar::Context) {
foo::spawn().unwrap();
}
}

View File

@@ -0,0 +1,72 @@
//! examples/resource.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965)]
mod app {
use cortex_m_semihosting::{debug, hprintln};
use lm3s6965::Interrupt;
#[shared]
struct Shared {
// A resource
shared: u32,
}
// Should not collide with the struct above
#[allow(dead_code)]
struct Shared2 {
// A resource
shared: u32,
}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
rtic::pend(Interrupt::UART0);
rtic::pend(Interrupt::UART1);
(Shared { shared: 0 }, Local {})
}
// `shared` cannot be accessed from this context
#[idle]
fn idle(_cx: idle::Context) -> ! {
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
// error: no `shared` field in `idle::Context`
// _cx.shared.shared += 1;
loop {}
}
// `shared` can be accessed from this context
#[task(binds = UART0, shared = [shared])]
fn uart0(mut cx: uart0::Context) {
let shared = cx.shared.shared.lock(|shared| {
*shared += 1;
*shared
});
hprintln!("UART0: shared = {}", shared);
}
// `shared` can be accessed from this context
#[task(binds = UART1, shared = [shared])]
fn uart1(mut cx: uart1::Context) {
let shared = cx.shared.shared.lock(|shared| {
*shared += 1;
*shared
});
hprintln!("UART1: shared = {}", shared);
}
}

View File

@@ -0,0 +1,51 @@
//! examples/late.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965)]
mod app {
use cortex_m_semihosting::{debug, hprintln};
use heapless::spsc::{Consumer, Producer, Queue};
use lm3s6965::Interrupt;
#[shared]
struct Shared {
p: Producer<'static, u32, 5>,
c: Consumer<'static, u32, 5>,
}
#[local]
struct Local {}
#[init(local = [q: Queue<u32, 5> = Queue::new()])]
fn init(cx: init::Context) -> (Shared, Local) {
let (p, c) = cx.local.q.split();
// Initialization of shared resources
(Shared { p, c }, Local {})
}
#[idle(shared = [c])]
fn idle(mut c: idle::Context) -> ! {
loop {
if let Some(byte) = c.shared.c.lock(|c| c.dequeue()) {
hprintln!("received message: {}", byte);
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
} else {
rtic::pend(Interrupt::UART0);
}
}
}
#[task(binds = UART0, shared = [p])]
fn uart0(mut c: uart0::Context) {
c.shared.p.lock(|p| p.enqueue(42).unwrap());
}
}

View File

@@ -0,0 +1,27 @@
//! examples/smallest.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _; // panic handler
use rtic::app;
#[app(device = lm3s6965)]
mod app {
use cortex_m_semihosting::debug;
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
(Shared {}, Local {})
}
}

View File

@@ -0,0 +1,35 @@
//! examples/spawn.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
hprintln!("init");
foo::spawn().unwrap();
(Shared {}, Local {})
}
#[task]
async fn foo(_: foo::Context) {
hprintln!("foo");
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
}

View File

@@ -0,0 +1,34 @@
//! examples/spawn_arguments.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
foo::spawn(1, 1).unwrap();
assert!(foo::spawn(1, 4).is_err()); // The capacity of `foo` is reached
(Shared {}, Local {})
}
#[task]
async fn foo(_c: foo::Context, x: i32, y: u32) {
hprintln!("foo {}, {}", x, y);
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
}

View File

@@ -0,0 +1,39 @@
//! examples/spawn_err.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
hprintln!("init");
foo::spawn().unwrap();
match foo::spawn() {
Ok(_) => {}
Err(()) => hprintln!("Cannot spawn a spawned (running) task!"),
}
(Shared {}, Local {})
}
#[task]
async fn foo(_: foo::Context) {
hprintln!("foo");
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
}

View File

@@ -0,0 +1,42 @@
//! examples/spawn_loop.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
hprintln!("init");
(Shared {}, Local {})
}
#[idle]
fn idle(_: idle::Context) -> ! {
for _ in 0..3 {
foo::spawn().unwrap();
hprintln!("idle");
}
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
loop {}
}
#[task(priority = 1)]
async fn foo(_: foo::Context) {
hprintln!("foo");
}
}

View File

@@ -0,0 +1,67 @@
//! examples/static-resources-in-divergent.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
use rtic_monotonics::systick::prelude::*;
systick_monotonic!(Mono, 100);
#[rtic::app(device = lm3s6965, dispatchers = [UART0])]
mod app {
use super::*;
use cortex_m_semihosting::{debug, hprintln};
use rtic_sync::channel::{Channel, Receiver};
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(cx: init::Context) -> (Shared, Local) {
Mono::start(cx.core.SYST, 12_000_000);
divergent::spawn().ok();
(Shared {}, Local {})
}
#[task(local = [q: Channel<u32, 5> = Channel::new()], priority = 1)]
async fn divergent(cx: divergent::Context) -> ! {
// `q` has `'static` lifetime. You can put references to it in `static` variables,
// structs with references to `q` do not need a generic lifetime parameter, etc.
let (mut tx, rx) = cx.local.q.split();
let mut state = 0;
bar::spawn(rx).unwrap();
loop {
tx.send(state).await.unwrap();
state += 1;
Mono::delay(100.millis()).await;
}
}
#[task(priority = 1)]
async fn bar(_cx: bar::Context, mut rx: Receiver<'static, u32, 5>) -> ! {
loop {
// Lock-free access to the same underlying queue!
if let Some(data) = rx.recv().await.ok() {
hprintln!("received message: {}", data);
if data == 3 {
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
} else {
Mono::delay(100.millis()).await;
}
}
}
}
}

View File

@@ -0,0 +1,60 @@
//! examples/static-resources-in-init.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [UART0])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
use heapless::spsc::{Consumer, Producer, Queue};
#[shared]
struct Shared {}
#[local]
struct Local {
p: Producer<'static, u32, 5>,
c: Consumer<'static, u32, 5>,
}
#[init(local = [q: Queue<u32, 5> = Queue::new()])]
fn init(cx: init::Context) -> (Shared, Local) {
// q has 'static life-time so after the split and return of `init`
// it will continue to exist and be allocated
let (p, c) = cx.local.q.split();
foo::spawn().unwrap();
(Shared {}, Local { p, c })
}
#[idle(local = [c])]
fn idle(c: idle::Context) -> ! {
loop {
// Lock-free access to the same underlying queue!
if let Some(data) = c.local.c.dequeue() {
hprintln!("received message: {}", data);
// Run foo until data
if data == 3 {
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
} else {
foo::spawn().unwrap();
}
}
}
}
#[task(local = [p, state: u32 = 0], priority = 1)]
async fn foo(c: foo::Context) {
*c.local.state += 1;
// Lock-free access to the same underlying queue!
c.local.p.enqueue(*c.local.state).unwrap();
}
}

View File

@@ -0,0 +1,45 @@
//! [compile-pass] Check that `binds` works as advertised
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965)]
mod app {
use cortex_m_semihosting::debug;
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
(Shared {}, Local {})
}
// Cortex-M exception
#[task(binds = SVCall)]
fn foo(c: foo::Context) {
crate::foo_trampoline(c)
}
// LM3S6965 interrupt
#[task(binds = UART0)]
fn bar(c: bar::Context) {
crate::bar_trampoline(c)
}
}
#[allow(dead_code)]
fn foo_trampoline(_: app::foo::Context) {}
#[allow(dead_code)]
fn bar_trampoline(_: app::bar::Context) {}

View File

@@ -0,0 +1,45 @@
//! [compile-pass] check that `#[cfg]` attributes applied on resources work
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
#![allow(unexpected_cfgs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965)]
mod app {
use cortex_m_semihosting::debug;
#[shared]
struct Shared {
// A conditionally compiled resource behind feature_x
#[cfg(feature = "feature_x")]
x: u32,
}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
(
Shared {
#[cfg(feature = "feature_x")]
x: 0,
},
Local {},
)
}
#[idle]
fn idle(_cx: idle::Context) -> ! {
loop {
cortex_m::asm::nop();
}
}
}

View File

@@ -0,0 +1,32 @@
//! examples/t-task-main.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965)]
mod app {
use cortex_m_semihosting::debug;
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
rtic::pend(lm3s6965::Interrupt::UART0);
(Shared {}, Local {})
}
#[task(binds = UART0)]
fn taskmain(_: taskmain::Context) {
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
}

View File

@@ -0,0 +1,33 @@
//! examples/t-idle-main.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965)]
mod app {
use cortex_m_semihosting::debug;
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
(Shared {}, Local {})
}
#[idle]
fn taskmain(_: taskmain::Context) -> ! {
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
loop {
cortex_m::asm::nop();
}
}
}

View File

@@ -0,0 +1,50 @@
//! [compile-pass] shared resources don't need to be `Send` if they are owned by `idle`
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use core::marker::PhantomData;
use panic_semihosting as _;
/// Not send
pub struct NotSend {
_0: PhantomData<*const ()>,
}
#[rtic::app(device = lm3s6965)]
mod app {
use super::NotSend;
use core::marker::PhantomData;
use cortex_m_semihosting::debug;
#[shared]
struct Shared {
x: NotSend,
y: Option<NotSend>,
}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
(
Shared {
x: NotSend { _0: PhantomData },
y: None,
},
Local {},
)
}
#[idle(shared = [x, y])]
fn idle(_: idle::Context) -> ! {
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
loop {
cortex_m::asm::nop();
}
}
}

57
examples/examples/task.rs Normal file
View File

@@ -0,0 +1,57 @@
//! examples/task.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
foo::spawn().unwrap();
(Shared {}, Local {})
}
#[task]
async fn foo(_: foo::Context) {
hprintln!("foo - start");
// spawns `bar` onto the task scheduler
// `foo` and `bar` have the same priority so `bar` will not run until
// after `foo` terminates
bar::spawn().unwrap();
hprintln!("foo - middle");
// spawns `baz` onto the task scheduler
// `baz` has higher priority than `foo` so it immediately preempts `foo`
baz::spawn().unwrap();
hprintln!("foo - end");
}
#[task]
async fn bar(_: bar::Context) {
hprintln!("bar");
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
#[task(priority = 2)]
async fn baz(_: baz::Context) {
hprintln!("baz");
}
}

View File

@@ -0,0 +1,64 @@
//! examples/wait-queue.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [GPIOA])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
use rtic_common::wait_queue::WaitQueue;
use rtic_monotonics::systick::prelude::*;
systick_monotonic!(Mono, 100);
#[shared]
struct Shared {
count: u32,
}
#[local]
struct Local {}
#[init(local = [wait_queue: WaitQueue = WaitQueue::new()])]
fn init(cx: init::Context) -> (Shared, Local) {
Mono::start(cx.core.SYST, 12_000_000);
incrementer::spawn(cx.local.wait_queue).ok().unwrap();
waiter::spawn(cx.local.wait_queue).ok().unwrap();
let count = 0;
(Shared { count }, Local {})
}
#[task(shared = [count])]
async fn incrementer(mut c: incrementer::Context, wait_queue: &'static WaitQueue) {
loop {
hprintln!("Inc");
c.shared.count.lock(|c| *c += 1);
while let Some(waker) = wait_queue.pop() {
waker.wake();
}
Mono::delay(10.millis()).await;
}
}
#[task(shared = [count])]
async fn waiter(mut c: waiter::Context, wait_queue: &'static WaitQueue) {
let value = wait_queue
.wait_until(|| c.shared.count.lock(|c| (*c >= 3).then_some(*c)))
.await;
hprintln!("Got {}", value);
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
}

View File

@@ -0,0 +1,61 @@
//! examples/zero-prio-task.rs
#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]
use core::marker::PhantomData;
use panic_semihosting as _;
/// Does not impl send
pub struct NotSend {
_0: PhantomData<*const ()>,
}
#[rtic::app(device = lm3s6965, peripherals = true)]
mod app {
use super::NotSend;
use core::marker::PhantomData;
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {
x: NotSend,
}
#[local]
struct Local {
y: NotSend,
}
#[init]
fn init(_cx: init::Context) -> (Shared, Local) {
hprintln!("init");
async_task::spawn().unwrap();
async_task2::spawn().unwrap();
(
Shared {
x: NotSend { _0: PhantomData },
},
Local {
y: NotSend { _0: PhantomData },
},
)
}
#[task(priority = 0, shared = [x], local = [y])]
async fn async_task(_: async_task::Context) {
hprintln!("hello from async");
}
#[task(priority = 0, shared = [x])]
async fn async_task2(_: async_task2::Context) {
hprintln!("hello from async2");
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
}