Merge pull request 'Update embedded examples' (#194) from update-embedded-examples into main
All checks were successful
Rust/sat-rs/pipeline/head This commit looks good
All checks were successful
Rust/sat-rs/pipeline/head This commit looks good
Reviewed-on: #194
This commit is contained in:
commit
a819feeaa2
@ -9,6 +9,7 @@ members = [
|
||||
]
|
||||
|
||||
exclude = [
|
||||
"satrs-example-stm32f3-disco",
|
||||
"embedded-examples/stm32f3-disco-rtic",
|
||||
"embedded-examples/stm32h7-rtic",
|
||||
]
|
||||
|
||||
|
11
README.md
11
README.md
@ -39,14 +39,19 @@ This project currently contains following crates:
|
||||
on a host computer or on any system with a standard runtime like a Raspberry Pi.
|
||||
* [`satrs-mib`](https://egit.irs.uni-stuttgart.de/rust/sat-rs/src/branch/main/satrs-mib):
|
||||
Components to build a mission information base from the on-board software directly.
|
||||
* [`satrs-example-stm32f3-disco`](https://egit.irs.uni-stuttgart.de/rust/sat-rs/src/branch/main/satrs-example-stm32f3-disco):
|
||||
* [`satrs-stm32f3-disco-rtic`](https://egit.irs.uni-stuttgart.de/rust/sat-rs/src/branch/main/embedded-examples/satrs-stm32f3-disco-rtic):
|
||||
Example of a simple example using low-level sat-rs components on a bare-metal system
|
||||
with constrained resources.
|
||||
with constrained resources. This example uses the [RTIC](https://github.com/rtic-rs/rtic)
|
||||
framework on the STM32F3-Discovery device.
|
||||
* [`satrs-stm32h-nucleo-rtic`](https://egit.irs.uni-stuttgart.de/rust/sat-rs/src/branch/main/embedded-examples/satrs-stm32h7-nucleo-rtic):
|
||||
Example of a simple example using sat-rs components on a bare-metal system
|
||||
with constrained resources. This example uses the [RTIC](https://github.com/rtic-rs/rtic)
|
||||
framework on the STM32H743ZIT device.
|
||||
|
||||
Each project has its own `CHANGELOG.md`.
|
||||
|
||||
# Related projects
|
||||
|
||||
|
||||
In addition to the crates in this repository, the sat-rs project also maintains other libraries.
|
||||
|
||||
* [`spacepackets`](https://egit.irs.uni-stuttgart.de/rust/spacepackets): Basic ECSS and CCSDS
|
||||
|
@ -22,9 +22,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.2.0"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[package]]
|
||||
name = "bare-metal"
|
||||
@ -88,13 +88,19 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.37"
|
||||
version = "0.4.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e"
|
||||
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cobs"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15"
|
||||
|
||||
[[package]]
|
||||
name = "cobs"
|
||||
version = "0.2.3"
|
||||
@ -115,9 +121,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cortex-m-rt"
|
||||
version = "0.7.3"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee84e813d593101b1723e13ec38b6ab6abbdbaaa4546553f5395ed274079ddb1"
|
||||
checksum = "2722f5b7d6ea8583cffa4d247044e280ccbb9fe501bed56552e2ba48b02d5f3d"
|
||||
dependencies = [
|
||||
"cortex-m-rt-macros",
|
||||
]
|
||||
@ -144,9 +150,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crc"
|
||||
version = "3.0.1"
|
||||
version = "3.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe"
|
||||
checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636"
|
||||
dependencies = [
|
||||
"crc-catalog",
|
||||
]
|
||||
@ -165,9 +171,9 @@ checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.20.8"
|
||||
version = "0.20.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391"
|
||||
checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
@ -175,33 +181,33 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.20.8"
|
||||
version = "0.20.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f"
|
||||
checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.20.8"
|
||||
version = "0.20.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
|
||||
checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "defmt"
|
||||
version = "0.3.6"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3939552907426de152b3c2c6f51ed53f98f448babd26f28694c95f5906194595"
|
||||
checksum = "a99dd22262668b887121d4672af5a64b238f026099f1a2a1b322066c9ecfe9e0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"defmt-macros",
|
||||
@ -219,15 +225,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "defmt-macros"
|
||||
version = "0.3.7"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18bdc7a7b92ac413e19e95240e75d3a73a8d8e78aa24a594c22cbb4d44b4bbda"
|
||||
checksum = "e3a9f309eff1f79b3ebdf252954d90ae440599c26c2c553fe87a2d17195f2dcb"
|
||||
dependencies = [
|
||||
"defmt-parser",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -259,7 +265,7 @@ checksum = "984bc6eca246389726ac2826acc2488ca0fe5fcd6b8d9b48797021951d76a125"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -273,6 +279,17 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive-new"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d150dea618e920167e5973d70ae6ece4385b7164e0d799fe7c122dd0a5d912ad"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embedded-dma"
|
||||
version = "0.2.0"
|
||||
@ -325,7 +342,7 @@ dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -409,9 +426,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.3"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
|
||||
[[package]]
|
||||
name = "heapless"
|
||||
@ -507,9 +524,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.44"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9"
|
||||
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
@ -529,9 +546,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.18"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
@ -553,14 +570,14 @@ checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "panic-probe"
|
||||
version = "0.3.1"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa6fa5645ef5a760cd340eaa92af9c1ce131c8c09e7f8926d8a24b59d26652b9"
|
||||
checksum = "4047d9235d1423d66cc97da7d07eddb54d4f154d6c13805c6d0793956f4f25b0"
|
||||
dependencies = [
|
||||
"cortex-m",
|
||||
"defmt",
|
||||
@ -568,9 +585,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.14"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
@ -610,18 +627,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.79"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
|
||||
checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.35"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@ -674,7 +691,7 @@ dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -717,16 +734,20 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver 1.0.22",
|
||||
"semver 1.0.23",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "satrs"
|
||||
version = "0.2.0-rc.0"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "866fcae3b683ccc37b5ad77982483a0ee01d5dc408dea5aad2117ad404b60fe1"
|
||||
dependencies = [
|
||||
"cobs",
|
||||
"cobs 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crc",
|
||||
"defmt",
|
||||
"delegate",
|
||||
"derive-new",
|
||||
"num-traits",
|
||||
"num_enum",
|
||||
"paste",
|
||||
@ -736,10 +757,19 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "satrs-example-stm32f3-disco"
|
||||
name = "satrs-shared"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6042477018c2d43fffccaaa5099bc299a58485139b4d31c5b276889311e474f1"
|
||||
dependencies = [
|
||||
"spacepackets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "satrs-stm32f3-disco-rtic"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cobs",
|
||||
"cobs 0.2.3 (git+https://github.com/robamu/cobs.rs.git?branch=all_features)",
|
||||
"cortex-m",
|
||||
"cortex-m-rt",
|
||||
"cortex-m-semihosting",
|
||||
@ -757,13 +787,6 @@ dependencies = [
|
||||
"stm32f3xx-hal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "satrs-shared"
|
||||
version = "0.1.3"
|
||||
dependencies = [
|
||||
"spacepackets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
@ -775,9 +798,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.22"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
|
||||
checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
@ -799,9 +822,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "spacepackets"
|
||||
version = "0.11.0-rc.2"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2cfd5f9a4c7f10714d21f9bc61f2d176cb7ae092cdd687e7ade2d4e6f7d7125"
|
||||
checksum = "e85574d113a06312010c0ba51aadccd4ba2806231ebe9a49fc6473d0534d8696"
|
||||
dependencies = [
|
||||
"crc",
|
||||
"defmt",
|
||||
@ -899,9 +922,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.58"
|
||||
version = "2.0.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
|
||||
checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -910,22 +933,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.58"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
|
||||
checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.58"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
|
||||
checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -975,9 +998,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.32"
|
||||
version = "0.7.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
|
||||
checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"zerocopy-derive",
|
||||
@ -985,11 +1008,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.32"
|
||||
version = "0.7.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
||||
checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.65",
|
||||
]
|
@ -1,8 +1,8 @@
|
||||
[package]
|
||||
name = "satrs-example-stm32f3-disco"
|
||||
name = "satrs-stm32f3-disco-rtic"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
default-run = "satrs-example-stm32f3-disco"
|
||||
default-run = "satrs-stm32f3-disco-rtic"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
@ -46,7 +46,8 @@ branch = "complete-dma-update-hal"
|
||||
# path = "../stm32f3-discovery"
|
||||
|
||||
[dependencies.satrs]
|
||||
path = "../satrs"
|
||||
# path = "satrs"
|
||||
version = "0.2"
|
||||
default-features = false
|
||||
features = ["defmt"]
|
||||
|
@ -1,10 +1,10 @@
|
||||
sat-rs example for the STM32F3-Discovery board
|
||||
=======
|
||||
|
||||
This example application shows how the [sat-rs framework](https://egit.irs.uni-stuttgart.de/rust/satrs-launchpad)
|
||||
This example application shows how the [sat-rs library](https://egit.irs.uni-stuttgart.de/rust/sat-rs)
|
||||
can be used on an embedded target.
|
||||
It also shows how a relatively simple OBSW could be built when no standard runtime is available.
|
||||
It uses [RTIC](https://rtic.rs/1/book/en/) as the concurrency framework and the
|
||||
It uses [RTIC](https://rtic.rs/2/book/en/) as the concurrency framework and the
|
||||
[defmt](https://defmt.ferrous-systems.com/) framework for logging.
|
||||
|
||||
The STM32F3-Discovery device was picked because it is a cheap Cortex-M4 based device which is also
|
@ -9,7 +9,7 @@ from prompt_toolkit.history import FileHistory, History
|
||||
from spacepackets.ecss.tm import CdsShortTimestamp
|
||||
|
||||
import tmtccmd
|
||||
from spacepackets.ecss import PusTelemetry, PusTelecommand, PusVerificator
|
||||
from spacepackets.ecss import PusTelemetry, PusTelecommand, PusTm, PusVerificator
|
||||
from spacepackets.ecss.pus_17_test import Service17Tm
|
||||
from spacepackets.ecss.pus_1_verification import UnpackParams, Service1Tm
|
||||
|
||||
@ -43,7 +43,7 @@ from tmtccmd.tmtc import (
|
||||
DefaultPusQueueHelper,
|
||||
)
|
||||
from tmtccmd.pus.s5_fsfw_event import Service5Tm
|
||||
from tmtccmd.util import FileSeqCountProvider, PusFileSeqCountProvider
|
||||
from spacepackets.seqcount import FileSeqCountProvider, PusFileSeqCountProvider
|
||||
from tmtccmd.util.obj_id import ObjectIdDictT
|
||||
|
||||
_LOGGER = logging.getLogger()
|
||||
@ -53,7 +53,7 @@ EXAMPLE_PUS_APID = 0x02
|
||||
|
||||
class SatRsConfigHook(HookBase):
|
||||
def __init__(self, json_cfg_path: str):
|
||||
super().__init__(json_cfg_path=json_cfg_path)
|
||||
super().__init__(json_cfg_path)
|
||||
|
||||
def get_communication_interface(self, com_if_key: str) -> Optional[ComInterface]:
|
||||
from tmtccmd.config.com import (
|
||||
@ -111,9 +111,10 @@ class PusHandler(SpecificApidHandlerBase):
|
||||
self.verif_wrapper = verif_wrapper
|
||||
|
||||
def handle_tm(self, packet: bytes, _user_args: Any):
|
||||
time_reader = CdsShortTimestamp.empty()
|
||||
try:
|
||||
pus_tm = PusTelemetry.unpack(packet, time_reader=CdsShortTimestamp.empty())
|
||||
pus_tm = PusTm.unpack(
|
||||
packet, timestamp_len=CdsShortTimestamp.TIMESTAMP_SIZE
|
||||
)
|
||||
except ValueError as e:
|
||||
_LOGGER.warning("Could not generate PUS TM object from raw data")
|
||||
_LOGGER.warning(f"Raw Packet: [{packet.hex(sep=',')}], REPR: {packet!r}")
|
||||
@ -122,7 +123,7 @@ class PusHandler(SpecificApidHandlerBase):
|
||||
tm_packet = None
|
||||
if service == 1:
|
||||
tm_packet = Service1Tm.unpack(
|
||||
data=packet, params=UnpackParams(time_reader, 1, 2)
|
||||
data=packet, params=UnpackParams(CdsShortTimestamp.TIMESTAMP_SIZE, 1, 2)
|
||||
)
|
||||
res = self.verif_wrapper.add_tm(tm_packet)
|
||||
if res is None:
|
||||
@ -139,16 +140,16 @@ class PusHandler(SpecificApidHandlerBase):
|
||||
if service == 3:
|
||||
_LOGGER.info("No handling for HK packets implemented")
|
||||
_LOGGER.info(f"Raw packet: 0x[{packet.hex(sep=',')}]")
|
||||
pus_tm = PusTelemetry.unpack(packet, CdsShortTimestamp.empty())
|
||||
pus_tm = PusTelemetry.unpack(packet, CdsShortTimestamp.TIMESTAMP_SIZE)
|
||||
if pus_tm.subservice == 25:
|
||||
if len(pus_tm.source_data) < 8:
|
||||
raise ValueError("No addressable ID in HK packet")
|
||||
json_str = pus_tm.source_data[8:]
|
||||
_LOGGER.info("received JSON string: " + json_str.decode("utf-8"))
|
||||
if service == 5:
|
||||
tm_packet = Service5Tm.unpack(packet, time_reader)
|
||||
tm_packet = Service5Tm.unpack(packet, CdsShortTimestamp.TIMESTAMP_SIZE)
|
||||
if service == 17:
|
||||
tm_packet = Service17Tm.unpack(packet, time_reader)
|
||||
tm_packet = Service17Tm.unpack(packet, CdsShortTimestamp.TIMESTAMP_SIZE)
|
||||
if tm_packet.subservice == 2:
|
||||
_LOGGER.info("Received Ping Reply TM[17,2]")
|
||||
else:
|
||||
@ -159,7 +160,7 @@ class PusHandler(SpecificApidHandlerBase):
|
||||
_LOGGER.info(
|
||||
f"The service {service} is not implemented in Telemetry Factory"
|
||||
)
|
||||
tm_packet = PusTelemetry.unpack(packet, time_reader)
|
||||
tm_packet = PusTelemetry.unpack(packet, CdsShortTimestamp.TIMESTAMP_SIZE)
|
||||
self.raw_logger.log_tm(pus_tm)
|
||||
|
||||
|
||||
@ -203,15 +204,15 @@ class TcHandler(TcHandlerBase):
|
||||
_LOGGER.info(log_entry.log_str)
|
||||
|
||||
def queue_finished_cb(self, info: ProcedureWrapper):
|
||||
if info.proc_type == TcProcedureType.DEFAULT:
|
||||
def_proc = info.to_def_procedure()
|
||||
if info.proc_type == TcProcedureType.TREE_COMMANDING:
|
||||
def_proc = info.to_tree_commanding_procedure()
|
||||
_LOGGER.info(f"Queue handling finished for command {def_proc.cmd_path}")
|
||||
|
||||
def feed_cb(self, info: ProcedureWrapper, wrapper: FeedWrapper):
|
||||
q = self.queue_helper
|
||||
q.queue_wrapper = wrapper.queue_wrapper
|
||||
if info.proc_type == TcProcedureType.DEFAULT:
|
||||
def_proc = info.to_def_procedure()
|
||||
if info.proc_type == TcProcedureType.TREE_COMMANDING:
|
||||
def_proc = info.to_tree_commanding_procedure()
|
||||
cmd_path = def_proc.cmd_path
|
||||
if cmd_path == "/ping":
|
||||
q.add_log_cmd("Sending PUS ping telecommand")
|
@ -1,2 +1,2 @@
|
||||
tmtccmd == 8.0.0rc.0
|
||||
tmtccmd == 8.0.1
|
||||
# -e git+https://github.com/robamu-org/tmtccmd.git@main#egg=tmtccmd
|
@ -1,6 +1,6 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
use satrs_example_stm32f3_disco as _;
|
||||
use satrs_stm32f3_disco_rtic as _;
|
||||
|
||||
use stm32f3_discovery::leds::Leds;
|
||||
use stm32f3_discovery::stm32f3xx_hal::delay::Delay;
|
@ -9,7 +9,7 @@ use satrs::spacepackets::ecss::EcssEnumU16;
|
||||
use satrs::spacepackets::CcsdsPacket;
|
||||
use satrs::spacepackets::{ByteConversionError, SpHeader};
|
||||
// global logger + panicking-behavior + memory layout
|
||||
use satrs_example_stm32f3_disco as _;
|
||||
use satrs_stm32f3_disco_rtic as _;
|
||||
|
||||
use rtic::app;
|
||||
|
@ -12,11 +12,11 @@
|
||||
"chip": "STM32F303VCTx",
|
||||
"coreConfigs": [
|
||||
{
|
||||
"programBinary": "${workspaceFolder}/target/thumbv7em-none-eabihf/debug/satrs-example-stm32f3-disco",
|
||||
"programBinary": "${workspaceFolder}/target/thumbv7em-none-eabihf/debug/satrs-stm32f3-disco-rtic",
|
||||
"rttEnabled": true,
|
||||
"svdFile": "STM32F303.svd"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
29
embedded-examples/stm32h7-nucleo-rtic/.cargo/def_config.toml
Normal file
29
embedded-examples/stm32h7-nucleo-rtic/.cargo/def_config.toml
Normal file
@ -0,0 +1,29 @@
|
||||
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
|
||||
runner = "probe-rs run --chip STM32H743ZITx"
|
||||
# runner = ["probe-rs", "run", "--chip", "$CHIP", "--log-format", "{L} {s}"]
|
||||
|
||||
rustflags = [
|
||||
"-C", "linker=flip-link",
|
||||
"-C", "link-arg=-Tlink.x",
|
||||
"-C", "link-arg=-Tdefmt.x",
|
||||
# This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
|
||||
# See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
|
||||
"-C", "link-arg=--nmagic",
|
||||
# Can be useful for debugging.
|
||||
# "-Clink-args=-Map=app.map"
|
||||
]
|
||||
|
||||
[build]
|
||||
# (`thumbv6m-*` is compatible with all ARM Cortex-M chips but using the right
|
||||
# target improves performance)
|
||||
# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
|
||||
# target = "thumbv7m-none-eabi" # Cortex-M3
|
||||
# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU)
|
||||
target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)
|
||||
|
||||
[alias]
|
||||
rb = "run --bin"
|
||||
rrb = "run --release --bin"
|
||||
|
||||
[env]
|
||||
DEFMT_LOG = "info"
|
4
embedded-examples/stm32h7-nucleo-rtic/.gitignore
vendored
Normal file
4
embedded-examples/stm32h7-nucleo-rtic/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/target
|
||||
/.cargo/config*
|
||||
/.vscode
|
||||
/app.map
|
881
embedded-examples/stm32h7-nucleo-rtic/Cargo.lock
generated
Normal file
881
embedded-examples/stm32h7-nucleo-rtic/Cargo.lock
generated
Normal file
@ -0,0 +1,881 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "atomic-polyfill"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
|
||||
dependencies = [
|
||||
"critical-section",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[package]]
|
||||
name = "bare-metal"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
|
||||
dependencies = [
|
||||
"rustc_version 0.2.3",
|
||||
]
|
||||
|
||||
[[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 = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cast"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cobs"
|
||||
version = "0.2.3"
|
||||
source = "git+https://github.com/robamu/cobs.rs.git?branch=all_features#c70a7f30fd00a7cbdb7666dec12b437977385d40"
|
||||
|
||||
[[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.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2722f5b7d6ea8583cffa4d247044e280ccbb9fe501bed56552e2ba48b02d5f3d"
|
||||
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 = "crc"
|
||||
version = "3.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636"
|
||||
dependencies = [
|
||||
"crc-catalog",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc-catalog"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
|
||||
|
||||
[[package]]
|
||||
name = "critical-section"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
|
||||
|
||||
[[package]]
|
||||
name = "defmt"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a99dd22262668b887121d4672af5a64b238f026099f1a2a1b322066c9ecfe9e0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"defmt-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "defmt-brtt"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2f0ac3635d0c89d12b8101fcb44a7625f5f030a1c0491124b74467eb5a58a78"
|
||||
dependencies = [
|
||||
"critical-section",
|
||||
"defmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "defmt-macros"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3a9f309eff1f79b3ebdf252954d90ae440599c26c2c553fe87a2d17195f2dcb"
|
||||
dependencies = [
|
||||
"defmt-parser",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "defmt-parser"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff4a5fefe330e8d7f31b16a318f9ce81000d8e35e69b93eae154d16d2278f70f"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "defmt-test"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "290966e8c38f94b11884877242de876280d0eab934900e9642d58868e77c5df1"
|
||||
dependencies = [
|
||||
"cortex-m-rt",
|
||||
"cortex-m-semihosting",
|
||||
"defmt",
|
||||
"defmt-test-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "defmt-test-macros"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "984bc6eca246389726ac2826acc2488ca0fe5fcd6b8d9b48797021951d76a125"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "delegate"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee5df75c70b95bd3aacc8e2fd098797692fb1d54121019c4de481e42f04c8a1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive-new"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d150dea618e920167e5973d70ae6ece4385b7164e0d799fe7c122dd0a5d912ad"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embedded-alloc"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddae17915accbac2cfbc64ea0ae6e3b330e6ea124ba108dada63646fd3c6f815"
|
||||
dependencies = [
|
||||
"critical-section",
|
||||
"linked_list_allocator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embedded-dma"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "994f7e5b5cb23521c22304927195f236813053eb9c065dd2226a32ba64695446"
|
||||
dependencies = [
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[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"
|
||||
dependencies = [
|
||||
"defmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embedded-hal-async"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884"
|
||||
dependencies = [
|
||||
"defmt",
|
||||
"embedded-hal 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embedded-hal-bus"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57b4e6ede84339ebdb418cd986e6320a34b017cdf99b5cc3efceec6450b06886"
|
||||
dependencies = [
|
||||
"critical-section",
|
||||
"defmt",
|
||||
"embedded-hal 1.0.0",
|
||||
"embedded-hal-async",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embedded-storage"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032"
|
||||
|
||||
[[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-core"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
||||
|
||||
[[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-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 = "hash32"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[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.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
|
||||
[[package]]
|
||||
name = "heapless"
|
||||
version = "0.7.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
|
||||
dependencies = [
|
||||
"atomic-polyfill",
|
||||
"hash32 0.2.1",
|
||||
"rustc_version 0.4.0",
|
||||
"spin",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heapless"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad"
|
||||
dependencies = [
|
||||
"defmt",
|
||||
"hash32 0.3.1",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked_list_allocator"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "managed"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d"
|
||||
|
||||
[[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 = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845"
|
||||
dependencies = [
|
||||
"num_enum_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum_derive"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "panic-probe"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4047d9235d1423d66cc97da7d07eddb54d4f154d6c13805c6d0793956f4f25b0"
|
||||
dependencies = [
|
||||
"cortex-m",
|
||||
"defmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
||||
|
||||
[[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"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rtic"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c443db16326376bdd64377da268f6616d5f804aba8ce799bac7d1f7f244e9d51"
|
||||
dependencies = [
|
||||
"atomic-polyfill",
|
||||
"bare-metal 1.0.0",
|
||||
"cortex-m",
|
||||
"critical-section",
|
||||
"rtic-core",
|
||||
"rtic-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rtic-common"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0786b50b81ef9d2a944a000f60405bb28bf30cd45da2d182f3fe636b2321f35c"
|
||||
dependencies = [
|
||||
"critical-section",
|
||||
]
|
||||
|
||||
[[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.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54053598ea24b1b74937724e366558412a1777eb2680b91ef646db540982789a"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rtic-monotonics"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "058c2397dbd5bb4c5650a0e368c3920953e458805ff5097a0511b8147b3619d7"
|
||||
dependencies = [
|
||||
"atomic-polyfill",
|
||||
"cfg-if",
|
||||
"cortex-m",
|
||||
"embedded-hal 1.0.0",
|
||||
"fugit",
|
||||
"rtic-time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rtic-sync"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49b1200137ccb2bf272a1801fa6e27264535facd356cb2c1d5bc8e12aa211bad"
|
||||
dependencies = [
|
||||
"critical-section",
|
||||
"defmt",
|
||||
"embedded-hal 1.0.0",
|
||||
"embedded-hal-async",
|
||||
"embedded-hal-bus",
|
||||
"heapless 0.8.0",
|
||||
"portable-atomic",
|
||||
"rtic-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rtic-time"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75b232e7aebc045cfea81cdd164bc2727a10aca9a4568d406d0a5661cdfd0f19"
|
||||
dependencies = [
|
||||
"critical-section",
|
||||
"futures-util",
|
||||
"rtic-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
dependencies = [
|
||||
"semver 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver 1.0.23",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "satrs"
|
||||
version = "0.2.1"
|
||||
dependencies = [
|
||||
"cobs",
|
||||
"crc",
|
||||
"defmt",
|
||||
"delegate",
|
||||
"derive-new",
|
||||
"heapless 0.7.17",
|
||||
"num-traits",
|
||||
"num_enum",
|
||||
"paste",
|
||||
"satrs-shared",
|
||||
"smallvec",
|
||||
"spacepackets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "satrs-shared"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6042477018c2d43fffccaaa5099bc299a58485139b4d31c5b276889311e474f1"
|
||||
dependencies = [
|
||||
"spacepackets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "satrs-stm32h7-nucleo-rtic"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cortex-m",
|
||||
"cortex-m-rt",
|
||||
"cortex-m-semihosting",
|
||||
"defmt",
|
||||
"defmt-brtt",
|
||||
"defmt-test",
|
||||
"embedded-alloc",
|
||||
"panic-probe",
|
||||
"rtic",
|
||||
"rtic-monotonics",
|
||||
"rtic-sync",
|
||||
"satrs",
|
||||
"smoltcp",
|
||||
"stm32h7xx-hal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[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"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "smoltcp"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a1a996951e50b5971a2c8c0fa05a381480d70a933064245c4a223ddc87ccc97"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"byteorder",
|
||||
"cfg-if",
|
||||
"defmt",
|
||||
"heapless 0.8.0",
|
||||
"managed",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spacepackets"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e85574d113a06312010c0ba51aadccd4ba2806231ebe9a49fc6473d0534d8696"
|
||||
dependencies = [
|
||||
"crc",
|
||||
"defmt",
|
||||
"delegate",
|
||||
"num-traits",
|
||||
"num_enum",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "stm32h7"
|
||||
version = "0.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "362f288cd8341e9209587b889c385f323e82fc237b60c272868965bb879bb9b1"
|
||||
dependencies = [
|
||||
"bare-metal 1.0.0",
|
||||
"cortex-m",
|
||||
"cortex-m-rt",
|
||||
"vcell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stm32h7xx-hal"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3bd869329be25440b24e2b3583a1c016151b4a54bc36d96d82af7fcd9d010b98"
|
||||
dependencies = [
|
||||
"bare-metal 1.0.0",
|
||||
"cast",
|
||||
"cortex-m",
|
||||
"embedded-dma",
|
||||
"embedded-hal 0.2.7",
|
||||
"embedded-storage",
|
||||
"fugit",
|
||||
"nb 1.1.0",
|
||||
"paste",
|
||||
"smoltcp",
|
||||
"stm32h7",
|
||||
"void",
|
||||
]
|
||||
|
||||
[[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.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ad3dee41f36859875573074334c200d1add8e4a87bb37113ebd31d926b7b11f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "vcell"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[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 = "zerocopy"
|
||||
version = "0.7.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
]
|
85
embedded-examples/stm32h7-nucleo-rtic/Cargo.toml
Normal file
85
embedded-examples/stm32h7-nucleo-rtic/Cargo.toml
Normal file
@ -0,0 +1,85 @@
|
||||
[package]
|
||||
authors = ["Robin Mueller <robin.mueller.m@gmail.com>"]
|
||||
name = "satrs-stm32h7-nucleo-rtic"
|
||||
edition = "2021"
|
||||
version = "0.1.0"
|
||||
default-run = "satrs-stm32h7-nucleo-rtic"
|
||||
|
||||
[lib]
|
||||
harness = false
|
||||
|
||||
# needed for each integration test
|
||||
[[test]]
|
||||
name = "integration"
|
||||
harness = false
|
||||
|
||||
[dependencies]
|
||||
cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
|
||||
cortex-m-rt = "0.7"
|
||||
defmt = "0.3"
|
||||
defmt-brtt = { version = "0.1", default-features = false, features = ["rtt"] }
|
||||
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
||||
cortex-m-semihosting = "0.5.0"
|
||||
stm32h7xx-hal = { version="0.16", features= ["stm32h743v", "ethernet"] }
|
||||
embedded-alloc = "0.5"
|
||||
rtic-sync = { version = "1", features = ["defmt-03"] }
|
||||
|
||||
[dependencies.smoltcp]
|
||||
version = "0.11.0"
|
||||
default-features = false
|
||||
features = ["medium-ethernet", "proto-ipv4", "socket-raw", "socket-dhcpv4", "socket-udp", "defmt"]
|
||||
|
||||
[dependencies.rtic]
|
||||
version = "2"
|
||||
features = ["thumbv7-backend"]
|
||||
|
||||
[dependencies.rtic-monotonics]
|
||||
version = "1"
|
||||
features = ["cortex-m-systick"]
|
||||
|
||||
[dependencies.satrs]
|
||||
path = "../../satrs"
|
||||
version = "0.2"
|
||||
default-features = false
|
||||
features = ["defmt", "heapless"]
|
||||
|
||||
[dev-dependencies]
|
||||
defmt-test = "0.3"
|
||||
|
||||
# cargo build/run
|
||||
[profile.dev]
|
||||
codegen-units = 1
|
||||
debug = 2
|
||||
debug-assertions = true # <-
|
||||
incremental = false
|
||||
opt-level = 's' # <-
|
||||
overflow-checks = true # <-
|
||||
|
||||
# cargo test
|
||||
[profile.test]
|
||||
codegen-units = 1
|
||||
debug = 2
|
||||
debug-assertions = true # <-
|
||||
incremental = false
|
||||
opt-level = 3 # <-
|
||||
overflow-checks = true # <-
|
||||
|
||||
# cargo build/run --release
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
debug = 2
|
||||
debug-assertions = false # <-
|
||||
incremental = false
|
||||
lto = 'fat'
|
||||
opt-level = 3 # <-
|
||||
overflow-checks = false # <-
|
||||
|
||||
# cargo test --release
|
||||
[profile.bench]
|
||||
codegen-units = 1
|
||||
debug = 2
|
||||
debug-assertions = false # <-
|
||||
incremental = false
|
||||
lto = 'fat'
|
||||
opt-level = 3 # <-
|
||||
overflow-checks = false # <-
|
201
embedded-examples/stm32h7-nucleo-rtic/LICENSE-APACHE
Normal file
201
embedded-examples/stm32h7-nucleo-rtic/LICENSE-APACHE
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
118
embedded-examples/stm32h7-nucleo-rtic/README.md
Normal file
118
embedded-examples/stm32h7-nucleo-rtic/README.md
Normal file
@ -0,0 +1,118 @@
|
||||
sat-rs example for the STM32F3-Discovery board
|
||||
=======
|
||||
|
||||
This example application shows how the [sat-rs library](https://egit.irs.uni-stuttgart.de/rust/sat-rs)
|
||||
can be used on an embedded target.
|
||||
It also shows how a relatively simple OBSW could be built when no standard runtime is available.
|
||||
It uses [RTIC](https://rtic.rs/2/book/en/) as the concurrency framework and the
|
||||
[defmt](https://defmt.ferrous-systems.com/) framework for logging.
|
||||
|
||||
The STM32H743ZIT device was picked because it is one of the more powerful Cortex-M based devices
|
||||
available for STM with which also has a little bit more RAM available and also allows commanding
|
||||
via TCP/IP.
|
||||
|
||||
## Pre-Requisites
|
||||
|
||||
Make sure the following tools are installed:
|
||||
|
||||
1. [`probe-rs`](https://probe.rs/): Application used to flash and debug the MCU.
|
||||
2. Optional and recommended: [VS Code](https://code.visualstudio.com/) with
|
||||
[probe-rs plugin](https://marketplace.visualstudio.com/items?itemName=probe-rs.probe-rs-debugger)
|
||||
for debugging.
|
||||
|
||||
## Preparing Rust and the repository
|
||||
|
||||
Building an application requires the `thumbv7em-none-eabihf` cross-compiler toolchain.
|
||||
If you have not installed it yet, you can do so with
|
||||
|
||||
```sh
|
||||
rustup target add thumbv7em-none-eabihf
|
||||
```
|
||||
|
||||
A default `.cargo` config file is provided for this project, but needs to be copied to have
|
||||
the correct name. This is so that the config file can be updated or edited for custom needs
|
||||
without being tracked by git.
|
||||
|
||||
```sh
|
||||
cp def_config.toml config.toml
|
||||
```
|
||||
|
||||
The configuration file will also set the target so it does not always have to be specified with
|
||||
the `--target` argument.
|
||||
|
||||
## Building
|
||||
|
||||
After that, assuming that you have a `.cargo/config.toml` setting the correct build target,
|
||||
you can simply build the application with
|
||||
|
||||
```sh
|
||||
cargo build
|
||||
```
|
||||
|
||||
## Flashing from the command line
|
||||
|
||||
You can flash the application from the command line using `probe-rs`:
|
||||
|
||||
```sh
|
||||
probe-rs run --chip STM32H743ZITx
|
||||
```
|
||||
|
||||
## Debugging with VS Code
|
||||
|
||||
The STM32F3-Discovery comes with an on-board ST-Link so all that is required to flash and debug
|
||||
the board is a Mini-USB cable. The code in this repository was debugged using [`probe-rs`](https://probe.rs/docs/tools/debuggerA)
|
||||
and the VS Code [`probe-rs` plugin](https://marketplace.visualstudio.com/items?itemName=probe-rs.probe-rs-debugger).
|
||||
Make sure to install this plugin first.
|
||||
|
||||
Sample configuration files are provided inside the `vscode` folder.
|
||||
Use `cp vscode .vscode -r` to use them for your project.
|
||||
|
||||
Some sample configuration files for VS Code were provided as well. You can simply use `Run` and `Debug`
|
||||
to automatically rebuild and flash your application.
|
||||
|
||||
The `tasks.json` and `launch.json` files are generic and you can use them immediately by opening
|
||||
the folder in VS code or adding it to a workspace.
|
||||
|
||||
## Commanding with Python
|
||||
|
||||
When the SW is running on the Discovery board, you can command the MCU via a serial interface,
|
||||
using COBS encoded PUS packets.
|
||||
|
||||
It is recommended to use a virtual environment to do this. To set up one in the command line,
|
||||
you can use `python3 -m venv venv` on Unix systems or `py -m venv venv` on Windows systems.
|
||||
After doing this, you can check the [venv tutorial](https://docs.python.org/3/tutorial/venv.html)
|
||||
on how to activate the environment and then use the following command to install the required
|
||||
dependency:
|
||||
|
||||
```sh
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
The packets are exchanged using a dedicated serial interface. You can use any generic USB-to-UART
|
||||
converter device with the TX pin connected to the PA3 pin and the RX pin connected to the PA2 pin.
|
||||
|
||||
A default configuration file for the python application is provided and can be used by running
|
||||
|
||||
```sh
|
||||
cp def_tmtc_conf.json tmtc_conf.json
|
||||
```
|
||||
|
||||
After that, you can for example send a ping to the MCU using the following command
|
||||
|
||||
```sh
|
||||
./main.py -p /ping
|
||||
```
|
||||
|
||||
You can configure the blinky frequency using
|
||||
|
||||
```sh
|
||||
./main.py -p /change_blink_freq
|
||||
```
|
||||
|
||||
All these commands will package a PUS telecommand which will be sent to the MCU using the COBS
|
||||
format as the packet framing format.
|
||||
|
||||
## Resources
|
||||
|
||||
- [STM32H743ZI Ethernet link checker example](https://github.com/stm32-rs/stm32h7xx-hal/blob/master/examples/ethernet-nucleo-h743zi2.rs)
|
||||
- [smoltcp DHCP client](https://github.com/smoltcp-rs/smoltcp/blob/main/examples/dhcp_client.rs)
|
107782
embedded-examples/stm32h7-nucleo-rtic/STM32H743.svd
Normal file
107782
embedded-examples/stm32h7-nucleo-rtic/STM32H743.svd
Normal file
File diff suppressed because it is too large
Load Diff
BIN
embedded-examples/stm32h7-nucleo-rtic/docs/stm32h743bi.pdf
Normal file
BIN
embedded-examples/stm32h7-nucleo-rtic/docs/stm32h743bi.pdf
Normal file
Binary file not shown.
Binary file not shown.
119
embedded-examples/stm32h7-nucleo-rtic/memory.x
Normal file
119
embedded-examples/stm32h7-nucleo-rtic/memory.x
Normal file
@ -0,0 +1,119 @@
|
||||
/* Taken from https://github.com/stm32-rs/stm32h7xx-hal/pull/299, adapted slightly to work with */
|
||||
/* flip-link */
|
||||
MEMORY
|
||||
{
|
||||
/* This file is intended for parts in the STM32H743/743v/753/753v families (RM0433), */
|
||||
/* with the exception of the STM32H742/742v parts which have a different RAM layout. */
|
||||
/* - FLASH and RAM are mandatory memory sections. */
|
||||
/* - The sum of all non-FLASH sections must add to 1060K total device RAM. */
|
||||
/* - The FLASH section size must match your device, see table below. */
|
||||
|
||||
/* FLASH */
|
||||
/* Flash is divided in two independent banks (except 750xB). */
|
||||
/* Select the appropriate FLASH size for your device. */
|
||||
/* - STM32H750xB 128K (only FLASH1) */
|
||||
/* - STM32H750xB 1M (512K + 512K) */
|
||||
/* - STM32H743xI/753xI 2M ( 1M + 1M) */
|
||||
FLASH1 : ORIGIN = 0x08000000, LENGTH = 1M
|
||||
FLASH2 : ORIGIN = 0x08100000, LENGTH = 1M
|
||||
|
||||
/* Data TCM */
|
||||
/* - Two contiguous 64KB RAMs. */
|
||||
/* - Used for interrupt handlers, stacks and general RAM. */
|
||||
/* - Zero wait-states. */
|
||||
/* - The DTCM is taken as the origin of the base ram. (See below.) */
|
||||
/* This is also where the interrupt table and such will live, */
|
||||
/* which is required for deterministic performance. */
|
||||
/* Need a region called RAM */
|
||||
/* DTCM : ORIGIN = 0x20000000, LENGTH = 128K */
|
||||
RAM : ORIGIN = 0x20000000, LENGTH = 128K
|
||||
|
||||
/* Instruction TCM */
|
||||
/* - Used for latency-critical interrupt handlers etc. */
|
||||
/* - Zero wait-states. */
|
||||
ITCM : ORIGIN = 0x00000000, LENGTH = 64K
|
||||
|
||||
/* AXI SRAM */
|
||||
/* - AXISRAM is in D1 and accessible by all system masters except BDMA. */
|
||||
/* - Suitable for application data not stored in DTCM. */
|
||||
/* - Zero wait-states. */
|
||||
AXISRAM : ORIGIN = 0x24000000, LENGTH = 512K
|
||||
|
||||
/* AHB SRAM */
|
||||
/* - SRAM1-3 are in D2 and accessible by all system masters except BDMA. */
|
||||
/* Suitable for use as DMA buffers. */
|
||||
/* - SRAM4 is in D3 and additionally accessible by the BDMA. Used for BDMA */
|
||||
/* buffers, for storing application data in lower-power modes. */
|
||||
/* - Zero wait-states. */
|
||||
SRAM1 : ORIGIN = 0x30000000, LENGTH = 128K
|
||||
SRAM2 : ORIGIN = 0x30020000, LENGTH = 128K
|
||||
SRAM3 : ORIGIN = 0x30040000, LENGTH = 32K
|
||||
SRAM4 : ORIGIN = 0x38000000, LENGTH = 64K
|
||||
|
||||
/* Backup SRAM */
|
||||
BSRAM : ORIGIN = 0x38800000, LENGTH = 4K
|
||||
}
|
||||
|
||||
/*
|
||||
/* Assign the memory regions defined above for use. */
|
||||
/*
|
||||
|
||||
/* Provide the mandatory FLASH and RAM definitions for cortex-m-rt's linker script. */
|
||||
/* These do not work with flip-link */
|
||||
REGION_ALIAS(FLASH, FLASH1);
|
||||
/* REGION_ALIAS(RAM, DTCM); */
|
||||
|
||||
/* The location of the stack can be overridden using the `_stack_start` symbol. */
|
||||
/* - Set the stack location at the end of RAM, using all remaining space. */
|
||||
_stack_start = ORIGIN(RAM) + LENGTH(RAM);
|
||||
|
||||
/* The location of the .text section can be overridden using the */
|
||||
/* `_stext` symbol. By default it will place after .vector_table. */
|
||||
/* _stext = ORIGIN(FLASH) + 0x40c; */
|
||||
|
||||
/* Define sections for placing symbols into the extra memory regions above. */
|
||||
/* This makes them accessible from code. */
|
||||
/* - ITCM, DTCM and AXISRAM connect to a 64-bit wide bus -> align to 8 bytes. */
|
||||
/* - All other memories connect to a 32-bit wide bus -> align to 4 bytes. */
|
||||
SECTIONS {
|
||||
.flash2 (NOLOAD) : ALIGN(4) {
|
||||
*(.flash2 .flash2.*);
|
||||
. = ALIGN(4);
|
||||
} > FLASH2
|
||||
|
||||
.itcm (NOLOAD) : ALIGN(8) {
|
||||
*(.itcm .itcm.*);
|
||||
. = ALIGN(8);
|
||||
} > ITCM
|
||||
|
||||
.axisram (NOLOAD) : ALIGN(8) {
|
||||
*(.axisram .axisram.*);
|
||||
. = ALIGN(8);
|
||||
} > AXISRAM
|
||||
|
||||
.sram1 (NOLOAD) : ALIGN(8) {
|
||||
*(.sram1 .sram1.*);
|
||||
. = ALIGN(4);
|
||||
} > SRAM1
|
||||
|
||||
.sram2 (NOLOAD) : ALIGN(8) {
|
||||
*(.sram2 .sram2.*);
|
||||
. = ALIGN(4);
|
||||
} > SRAM2
|
||||
|
||||
.sram3 (NOLOAD) : ALIGN(4) {
|
||||
*(.sram3 .sram3.*);
|
||||
. = ALIGN(4);
|
||||
} > SRAM3
|
||||
|
||||
.sram4 (NOLOAD) : ALIGN(4) {
|
||||
*(.sram4 .sram4.*);
|
||||
. = ALIGN(4);
|
||||
} > SRAM4
|
||||
|
||||
.bsram (NOLOAD) : ALIGN(4) {
|
||||
*(.bsram .bsram.*);
|
||||
. = ALIGN(4);
|
||||
} > BSRAM
|
||||
|
||||
};
|
8
embedded-examples/stm32h7-nucleo-rtic/pyclient/.gitignore
vendored
Normal file
8
embedded-examples/stm32h7-nucleo-rtic/pyclient/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
/venv
|
||||
/.tmtc-history.txt
|
||||
/log
|
||||
/.idea/*
|
||||
!/.idea/runConfigurations
|
||||
|
||||
/seqcnt.txt
|
||||
/tmtc_conf.json
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
"com_if": "udp",
|
||||
"tcpip_udp_port": 7301
|
||||
}
|
305
embedded-examples/stm32h7-nucleo-rtic/pyclient/main.py
Executable file
305
embedded-examples/stm32h7-nucleo-rtic/pyclient/main.py
Executable file
@ -0,0 +1,305 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Example client for the sat-rs example application"""
|
||||
import struct
|
||||
import logging
|
||||
import sys
|
||||
import time
|
||||
from typing import Any, Optional, cast
|
||||
from prompt_toolkit.history import FileHistory, History
|
||||
from spacepackets.ecss.tm import CdsShortTimestamp
|
||||
|
||||
import tmtccmd
|
||||
from spacepackets.ecss import PusTelemetry, PusTelecommand, PusTm, PusVerificator
|
||||
from spacepackets.ecss.pus_17_test import Service17Tm
|
||||
from spacepackets.ecss.pus_1_verification import UnpackParams, Service1Tm
|
||||
|
||||
from tmtccmd import TcHandlerBase, ProcedureParamsWrapper
|
||||
from tmtccmd.core.base import BackendRequest
|
||||
from tmtccmd.core.ccsds_backend import QueueWrapper
|
||||
from tmtccmd.logging import add_colorlog_console_logger
|
||||
from tmtccmd.pus import VerificationWrapper
|
||||
from tmtccmd.tmtc import CcsdsTmHandler, SpecificApidHandlerBase
|
||||
from tmtccmd.com import ComInterface
|
||||
from tmtccmd.config import (
|
||||
CmdTreeNode,
|
||||
default_json_path,
|
||||
SetupParams,
|
||||
HookBase,
|
||||
params_to_procedure_conversion,
|
||||
)
|
||||
from tmtccmd.config.com import SerialCfgWrapper
|
||||
from tmtccmd.config import PreArgsParsingWrapper, SetupWrapper
|
||||
from tmtccmd.logging.pus import (
|
||||
RegularTmtcLogWrapper,
|
||||
RawTmtcTimedLogWrapper,
|
||||
TimedLogWhen,
|
||||
)
|
||||
from tmtccmd.tmtc import (
|
||||
TcQueueEntryType,
|
||||
ProcedureWrapper,
|
||||
TcProcedureType,
|
||||
FeedWrapper,
|
||||
SendCbParams,
|
||||
DefaultPusQueueHelper,
|
||||
)
|
||||
from tmtccmd.pus.s5_fsfw_event import Service5Tm
|
||||
from spacepackets.seqcount import FileSeqCountProvider, PusFileSeqCountProvider
|
||||
from tmtccmd.util.obj_id import ObjectIdDictT
|
||||
|
||||
_LOGGER = logging.getLogger()
|
||||
|
||||
EXAMPLE_PUS_APID = 0x02
|
||||
|
||||
|
||||
class SatRsConfigHook(HookBase):
|
||||
def __init__(self, json_cfg_path: str):
|
||||
super().__init__(json_cfg_path)
|
||||
|
||||
def get_communication_interface(self, com_if_key: str) -> Optional[ComInterface]:
|
||||
from tmtccmd.config.com import (
|
||||
create_com_interface_default,
|
||||
create_com_interface_cfg_default,
|
||||
)
|
||||
|
||||
assert self.cfg_path is not None
|
||||
cfg = create_com_interface_cfg_default(
|
||||
com_if_key=com_if_key,
|
||||
json_cfg_path=self.cfg_path,
|
||||
space_packet_ids=None,
|
||||
)
|
||||
if cfg is None:
|
||||
raise ValueError(
|
||||
f"No valid configuration could be retrieved for the COM IF with key {com_if_key}"
|
||||
)
|
||||
if cfg.com_if_key == "serial_cobs":
|
||||
cfg = cast(SerialCfgWrapper, cfg)
|
||||
cfg.serial_cfg.serial_timeout = 0.5
|
||||
return create_com_interface_default(cfg)
|
||||
|
||||
def get_command_definitions(self) -> CmdTreeNode:
|
||||
"""This function should return the root node of the command definition tree."""
|
||||
return create_cmd_definition_tree()
|
||||
|
||||
def get_cmd_history(self) -> Optional[History]:
|
||||
"""Optionlly return a history class for the past command paths which will be used
|
||||
when prompting a command path from the user in CLI mode."""
|
||||
return FileHistory(".tmtc-history.txt")
|
||||
|
||||
def get_object_ids(self) -> ObjectIdDictT:
|
||||
from tmtccmd.config.objects import get_core_object_ids
|
||||
|
||||
return get_core_object_ids()
|
||||
|
||||
|
||||
def create_cmd_definition_tree() -> CmdTreeNode:
|
||||
root_node = CmdTreeNode.root_node()
|
||||
root_node.add_child(CmdTreeNode("ping", "Send PUS ping TC"))
|
||||
root_node.add_child(CmdTreeNode("change_blink_freq", "Change blink frequency"))
|
||||
return root_node
|
||||
|
||||
|
||||
class PusHandler(SpecificApidHandlerBase):
|
||||
def __init__(
|
||||
self,
|
||||
file_logger: logging.Logger,
|
||||
verif_wrapper: VerificationWrapper,
|
||||
raw_logger: RawTmtcTimedLogWrapper,
|
||||
):
|
||||
super().__init__(EXAMPLE_PUS_APID, None)
|
||||
self.file_logger = file_logger
|
||||
self.raw_logger = raw_logger
|
||||
self.verif_wrapper = verif_wrapper
|
||||
|
||||
def handle_tm(self, packet: bytes, _user_args: Any):
|
||||
try:
|
||||
pus_tm = PusTm.unpack(
|
||||
packet, timestamp_len=CdsShortTimestamp.TIMESTAMP_SIZE
|
||||
)
|
||||
except ValueError as e:
|
||||
_LOGGER.warning("Could not generate PUS TM object from raw data")
|
||||
_LOGGER.warning(f"Raw Packet: [{packet.hex(sep=',')}], REPR: {packet!r}")
|
||||
raise e
|
||||
service = pus_tm.service
|
||||
tm_packet = None
|
||||
if service == 1:
|
||||
tm_packet = Service1Tm.unpack(
|
||||
data=packet, params=UnpackParams(CdsShortTimestamp.TIMESTAMP_SIZE, 1, 2)
|
||||
)
|
||||
res = self.verif_wrapper.add_tm(tm_packet)
|
||||
if res is None:
|
||||
_LOGGER.info(
|
||||
f"Received Verification TM[{tm_packet.service}, {tm_packet.subservice}] "
|
||||
f"with Request ID {tm_packet.tc_req_id.as_u32():#08x}"
|
||||
)
|
||||
_LOGGER.warning(
|
||||
f"No matching telecommand found for {tm_packet.tc_req_id}"
|
||||
)
|
||||
else:
|
||||
self.verif_wrapper.log_to_console(tm_packet, res)
|
||||
self.verif_wrapper.log_to_file(tm_packet, res)
|
||||
if service == 3:
|
||||
_LOGGER.info("No handling for HK packets implemented")
|
||||
_LOGGER.info(f"Raw packet: 0x[{packet.hex(sep=',')}]")
|
||||
pus_tm = PusTelemetry.unpack(packet, CdsShortTimestamp.TIMESTAMP_SIZE)
|
||||
if pus_tm.subservice == 25:
|
||||
if len(pus_tm.source_data) < 8:
|
||||
raise ValueError("No addressable ID in HK packet")
|
||||
json_str = pus_tm.source_data[8:]
|
||||
_LOGGER.info("received JSON string: " + json_str.decode("utf-8"))
|
||||
if service == 5:
|
||||
tm_packet = Service5Tm.unpack(packet, CdsShortTimestamp.TIMESTAMP_SIZE)
|
||||
if service == 17:
|
||||
tm_packet = Service17Tm.unpack(packet, CdsShortTimestamp.TIMESTAMP_SIZE)
|
||||
if tm_packet.subservice == 2:
|
||||
_LOGGER.info("Received Ping Reply TM[17,2]")
|
||||
else:
|
||||
_LOGGER.info(
|
||||
f"Received Test Packet with unknown subservice {tm_packet.subservice}"
|
||||
)
|
||||
if tm_packet is None:
|
||||
_LOGGER.info(
|
||||
f"The service {service} is not implemented in Telemetry Factory"
|
||||
)
|
||||
tm_packet = PusTelemetry.unpack(packet, CdsShortTimestamp.TIMESTAMP_SIZE)
|
||||
self.raw_logger.log_tm(pus_tm)
|
||||
|
||||
|
||||
def make_addressable_id(target_id: int, unique_id: int) -> bytes:
|
||||
byte_string = bytearray(struct.pack("!I", target_id))
|
||||
byte_string.extend(struct.pack("!I", unique_id))
|
||||
return byte_string
|
||||
|
||||
|
||||
class TcHandler(TcHandlerBase):
|
||||
def __init__(
|
||||
self,
|
||||
seq_count_provider: FileSeqCountProvider,
|
||||
verif_wrapper: VerificationWrapper,
|
||||
):
|
||||
super(TcHandler, self).__init__()
|
||||
self.seq_count_provider = seq_count_provider
|
||||
self.verif_wrapper = verif_wrapper
|
||||
self.queue_helper = DefaultPusQueueHelper(
|
||||
queue_wrapper=QueueWrapper.empty(),
|
||||
tc_sched_timestamp_len=7,
|
||||
seq_cnt_provider=seq_count_provider,
|
||||
pus_verificator=verif_wrapper.pus_verificator,
|
||||
default_pus_apid=EXAMPLE_PUS_APID,
|
||||
)
|
||||
|
||||
def send_cb(self, send_params: SendCbParams):
|
||||
entry_helper = send_params.entry
|
||||
if entry_helper.is_tc:
|
||||
if entry_helper.entry_type == TcQueueEntryType.PUS_TC:
|
||||
pus_tc_wrapper = entry_helper.to_pus_tc_entry()
|
||||
pus_tc_wrapper.pus_tc.seq_count = (
|
||||
self.seq_count_provider.get_and_increment()
|
||||
)
|
||||
self.verif_wrapper.add_tc(pus_tc_wrapper.pus_tc)
|
||||
raw_tc = pus_tc_wrapper.pus_tc.pack()
|
||||
_LOGGER.info(f"Sending {pus_tc_wrapper.pus_tc}")
|
||||
send_params.com_if.send(raw_tc)
|
||||
elif entry_helper.entry_type == TcQueueEntryType.LOG:
|
||||
log_entry = entry_helper.to_log_entry()
|
||||
_LOGGER.info(log_entry.log_str)
|
||||
|
||||
def queue_finished_cb(self, info: ProcedureWrapper):
|
||||
if info.proc_type == TcProcedureType.TREE_COMMANDING:
|
||||
def_proc = info.to_tree_commanding_procedure()
|
||||
_LOGGER.info(f"Queue handling finished for command {def_proc.cmd_path}")
|
||||
|
||||
def feed_cb(self, info: ProcedureWrapper, wrapper: FeedWrapper):
|
||||
q = self.queue_helper
|
||||
q.queue_wrapper = wrapper.queue_wrapper
|
||||
if info.proc_type == TcProcedureType.TREE_COMMANDING:
|
||||
def_proc = info.to_tree_commanding_procedure()
|
||||
cmd_path = def_proc.cmd_path
|
||||
if cmd_path == "/ping":
|
||||
q.add_log_cmd("Sending PUS ping telecommand")
|
||||
q.add_pus_tc(PusTelecommand(service=17, subservice=1))
|
||||
if cmd_path == "/change_blink_freq":
|
||||
self.create_change_blink_freq_command(q)
|
||||
|
||||
def create_change_blink_freq_command(self, q: DefaultPusQueueHelper):
|
||||
q.add_log_cmd("Changing blink frequency")
|
||||
while True:
|
||||
blink_freq = int(
|
||||
input(
|
||||
"Please specify new blink frequency in ms. Valid Range [2..10000]: "
|
||||
)
|
||||
)
|
||||
if blink_freq < 2 or blink_freq > 10000:
|
||||
print(
|
||||
"Invalid blink frequency. Please specify a value between 2 and 10000."
|
||||
)
|
||||
continue
|
||||
break
|
||||
app_data = struct.pack("!I", blink_freq)
|
||||
q.add_pus_tc(PusTelecommand(service=8, subservice=1, app_data=app_data))
|
||||
|
||||
|
||||
def main():
|
||||
add_colorlog_console_logger(_LOGGER)
|
||||
tmtccmd.init_printout(False)
|
||||
hook_obj = SatRsConfigHook(json_cfg_path=default_json_path())
|
||||
parser_wrapper = PreArgsParsingWrapper()
|
||||
parser_wrapper.create_default_parent_parser()
|
||||
parser_wrapper.create_default_parser()
|
||||
parser_wrapper.add_def_proc_args()
|
||||
params = SetupParams()
|
||||
post_args_wrapper = parser_wrapper.parse(hook_obj, params)
|
||||
proc_wrapper = ProcedureParamsWrapper()
|
||||
if post_args_wrapper.use_gui:
|
||||
post_args_wrapper.set_params_without_prompts(proc_wrapper)
|
||||
else:
|
||||
post_args_wrapper.set_params_with_prompts(proc_wrapper)
|
||||
params.apid = EXAMPLE_PUS_APID
|
||||
setup_args = SetupWrapper(
|
||||
hook_obj=hook_obj, setup_params=params, proc_param_wrapper=proc_wrapper
|
||||
)
|
||||
# Create console logger helper and file loggers
|
||||
tmtc_logger = RegularTmtcLogWrapper()
|
||||
file_logger = tmtc_logger.logger
|
||||
raw_logger = RawTmtcTimedLogWrapper(when=TimedLogWhen.PER_HOUR, interval=1)
|
||||
verificator = PusVerificator()
|
||||
verification_wrapper = VerificationWrapper(verificator, _LOGGER, file_logger)
|
||||
# Create primary TM handler and add it to the CCSDS Packet Handler
|
||||
tm_handler = PusHandler(file_logger, verification_wrapper, raw_logger)
|
||||
ccsds_handler = CcsdsTmHandler(generic_handler=None)
|
||||
ccsds_handler.add_apid_handler(tm_handler)
|
||||
|
||||
# Create TC handler
|
||||
seq_count_provider = PusFileSeqCountProvider()
|
||||
tc_handler = TcHandler(seq_count_provider, verification_wrapper)
|
||||
tmtccmd.setup(setup_args=setup_args)
|
||||
init_proc = params_to_procedure_conversion(setup_args.proc_param_wrapper)
|
||||
tmtc_backend = tmtccmd.create_default_tmtc_backend(
|
||||
setup_wrapper=setup_args,
|
||||
tm_handler=ccsds_handler,
|
||||
tc_handler=tc_handler,
|
||||
init_procedure=init_proc,
|
||||
)
|
||||
tmtccmd.start(tmtc_backend=tmtc_backend, hook_obj=hook_obj)
|
||||
try:
|
||||
while True:
|
||||
state = tmtc_backend.periodic_op(None)
|
||||
if state.request == BackendRequest.TERMINATION_NO_ERROR:
|
||||
sys.exit(0)
|
||||
elif state.request == BackendRequest.DELAY_IDLE:
|
||||
_LOGGER.info("TMTC Client in IDLE mode")
|
||||
time.sleep(3.0)
|
||||
elif state.request == BackendRequest.DELAY_LISTENER:
|
||||
time.sleep(0.8)
|
||||
elif state.request == BackendRequest.DELAY_CUSTOM:
|
||||
if state.next_delay.total_seconds() <= 0.4:
|
||||
time.sleep(state.next_delay.total_seconds())
|
||||
else:
|
||||
time.sleep(0.4)
|
||||
elif state.request == BackendRequest.CALL_NEXT:
|
||||
pass
|
||||
except KeyboardInterrupt:
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -0,0 +1,2 @@
|
||||
tmtccmd == 8.0.1
|
||||
# -e git+https://github.com/robamu-org/tmtccmd.git@main#egg=tmtccmd
|
55
embedded-examples/stm32h7-nucleo-rtic/src/bin/blinky.rs
Normal file
55
embedded-examples/stm32h7-nucleo-rtic/src/bin/blinky.rs
Normal file
@ -0,0 +1,55 @@
|
||||
//! Blinks an LED
|
||||
//!
|
||||
//! This assumes that LD2 (blue) is connected to pb7 and LD3 (red) is connected
|
||||
//! to pb14. This assumption is true for the nucleo-h743zi board.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
use satrs_stm32h7_nucleo_rtic as _;
|
||||
|
||||
use stm32h7xx_hal::{block, prelude::*, timer::Timer};
|
||||
|
||||
use cortex_m_rt::entry;
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
defmt::println!("starting stm32h7 blinky example");
|
||||
|
||||
// Get access to the device specific peripherals from the peripheral access crate
|
||||
let dp = stm32h7xx_hal::stm32::Peripherals::take().unwrap();
|
||||
|
||||
// Take ownership over the RCC devices and convert them into the corresponding HAL structs
|
||||
let rcc = dp.RCC.constrain();
|
||||
|
||||
let pwr = dp.PWR.constrain();
|
||||
let pwrcfg = pwr.freeze();
|
||||
|
||||
// Freeze the configuration of all the clocks in the system and
|
||||
// retrieve the Core Clock Distribution and Reset (CCDR) object
|
||||
let rcc = rcc.use_hse(8.MHz()).bypass_hse();
|
||||
let ccdr = rcc.freeze(pwrcfg, &dp.SYSCFG);
|
||||
|
||||
// Acquire the GPIOB peripheral
|
||||
let gpiob = dp.GPIOB.split(ccdr.peripheral.GPIOB);
|
||||
|
||||
// Configure gpio B pin 0 as a push-pull output.
|
||||
let mut ld1 = gpiob.pb0.into_push_pull_output();
|
||||
|
||||
// Configure gpio B pin 7 as a push-pull output.
|
||||
let mut ld2 = gpiob.pb7.into_push_pull_output();
|
||||
|
||||
// Configure gpio B pin 14 as a push-pull output.
|
||||
let mut ld3 = gpiob.pb14.into_push_pull_output();
|
||||
|
||||
// Configure the timer to trigger an update every second
|
||||
let mut timer = Timer::tim1(dp.TIM1, ccdr.peripheral.TIM1, &ccdr.clocks);
|
||||
timer.start(1.Hz());
|
||||
|
||||
// Wait for the timer to trigger an update and change the state of the LED
|
||||
loop {
|
||||
ld1.toggle();
|
||||
ld2.toggle();
|
||||
ld3.toggle();
|
||||
block!(timer.wait()).unwrap();
|
||||
}
|
||||
}
|
11
embedded-examples/stm32h7-nucleo-rtic/src/bin/hello.rs
Normal file
11
embedded-examples/stm32h7-nucleo-rtic/src/bin/hello.rs
Normal file
@ -0,0 +1,11 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
use satrs_stm32h7_nucleo_rtic as _; // global logger + panicking-behavior + memory layout
|
||||
|
||||
#[cortex_m_rt::entry]
|
||||
fn main() -> ! {
|
||||
defmt::println!("Hello, world!");
|
||||
|
||||
satrs_stm32h7_nucleo_rtic::exit()
|
||||
}
|
52
embedded-examples/stm32h7-nucleo-rtic/src/lib.rs
Normal file
52
embedded-examples/stm32h7-nucleo-rtic/src/lib.rs
Normal file
@ -0,0 +1,52 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
use cortex_m_semihosting::debug;
|
||||
|
||||
use defmt_brtt as _; // global logger
|
||||
|
||||
// TODO(5) adjust HAL import
|
||||
use stm32h7xx_hal as _; // memory layout
|
||||
|
||||
use panic_probe as _;
|
||||
|
||||
// same panicking *behavior* as `panic-probe` but doesn't print a panic message
|
||||
// this prevents the panic message being printed *twice* when `defmt::panic` is invoked
|
||||
#[defmt::panic_handler]
|
||||
fn panic() -> ! {
|
||||
cortex_m::asm::udf()
|
||||
}
|
||||
|
||||
/// Terminates the application and makes a semihosting-capable debug tool exit
|
||||
/// with status code 0.
|
||||
pub fn exit() -> ! {
|
||||
loop {
|
||||
debug::exit(debug::EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
/// Hardfault handler.
|
||||
///
|
||||
/// Terminates the application and makes a semihosting-capable debug tool exit
|
||||
/// with an error. This seems better than the default, which is to spin in a
|
||||
/// loop.
|
||||
#[cortex_m_rt::exception]
|
||||
unsafe fn HardFault(_frame: &cortex_m_rt::ExceptionFrame) -> ! {
|
||||
loop {
|
||||
debug::exit(debug::EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
// defmt-test 0.3.0 has the limitation that this `#[tests]` attribute can only be used
|
||||
// once within a crate. the module can be in any file but there can only be at most
|
||||
// one `#[tests]` module in this library crate
|
||||
#[cfg(test)]
|
||||
#[defmt_test::tests]
|
||||
mod unit_tests {
|
||||
use defmt::assert;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
assert!(true)
|
||||
}
|
||||
}
|
528
embedded-examples/stm32h7-nucleo-rtic/src/main.rs
Normal file
528
embedded-examples/stm32h7-nucleo-rtic/src/main.rs
Normal file
@ -0,0 +1,528 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
extern crate alloc;
|
||||
|
||||
use rtic::app;
|
||||
use rtic_monotonics::systick::Systick;
|
||||
use rtic_monotonics::Monotonic;
|
||||
use satrs::pool::{PoolAddr, PoolProvider, StaticHeaplessMemoryPool};
|
||||
use satrs::static_subpool;
|
||||
// global logger + panicking-behavior + memory layout
|
||||
use satrs_stm32h7_nucleo_rtic as _;
|
||||
use smoltcp::socket::udp::UdpMetadata;
|
||||
use smoltcp::socket::{dhcpv4, udp};
|
||||
|
||||
use core::mem::MaybeUninit;
|
||||
use embedded_alloc::Heap;
|
||||
use smoltcp::iface::{Config, Interface, SocketHandle, SocketSet, SocketStorage};
|
||||
use smoltcp::wire::{HardwareAddress, IpAddress, IpCidr};
|
||||
use stm32h7xx_hal::ethernet;
|
||||
|
||||
const DEFAULT_BLINK_FREQ_MS: u32 = 1000;
|
||||
const PORT: u16 = 7301;
|
||||
|
||||
const HEAP_SIZE: usize = 131_072;
|
||||
|
||||
const TC_SOURCE_CHANNEL_DEPTH: usize = 16;
|
||||
pub type SharedPool = StaticHeaplessMemoryPool<3>;
|
||||
pub type TcSourceChannel = rtic_sync::channel::Channel<PoolAddr, TC_SOURCE_CHANNEL_DEPTH>;
|
||||
pub type TcSourceTx = rtic_sync::channel::Sender<'static, PoolAddr, TC_SOURCE_CHANNEL_DEPTH>;
|
||||
pub type TcSourceRx = rtic_sync::channel::Receiver<'static, PoolAddr, TC_SOURCE_CHANNEL_DEPTH>;
|
||||
|
||||
#[global_allocator]
|
||||
static HEAP: Heap = Heap::empty();
|
||||
|
||||
// We place the memory pool buffers inside the larger AXISRAM.
|
||||
pub const SUBPOOL_SMALL_NUM_BLOCKS: u16 = 32;
|
||||
pub const SUBPOOL_SMALL_BLOCK_SIZE: usize = 32;
|
||||
pub const SUBPOOL_MEDIUM_NUM_BLOCKS: u16 = 16;
|
||||
pub const SUBPOOL_MEDIUM_BLOCK_SIZE: usize = 128;
|
||||
pub const SUBPOOL_LARGE_NUM_BLOCKS: u16 = 8;
|
||||
pub const SUBPOOL_LARGE_BLOCK_SIZE: usize = 2048;
|
||||
|
||||
// This data will be held by Net through a mutable reference
|
||||
pub struct NetStorageStatic<'a> {
|
||||
socket_storage: [SocketStorage<'a>; 8],
|
||||
}
|
||||
// MaybeUninit allows us write code that is correct even if STORE is not
|
||||
// initialised by the runtime
|
||||
static mut STORE: MaybeUninit<NetStorageStatic> = MaybeUninit::uninit();
|
||||
|
||||
static mut UDP_RX_META: [udp::PacketMetadata; 12] = [udp::PacketMetadata::EMPTY; 12];
|
||||
static mut UDP_RX: [u8; 2048] = [0; 2048];
|
||||
static mut UDP_TX_META: [udp::PacketMetadata; 12] = [udp::PacketMetadata::EMPTY; 12];
|
||||
static mut UDP_TX: [u8; 2048] = [0; 2048];
|
||||
|
||||
/// Locally administered MAC address
|
||||
const MAC_ADDRESS: [u8; 6] = [0x02, 0x00, 0x11, 0x22, 0x33, 0x44];
|
||||
|
||||
pub struct Net {
|
||||
iface: Interface,
|
||||
ethdev: ethernet::EthernetDMA<4, 4>,
|
||||
dhcp_handle: SocketHandle,
|
||||
}
|
||||
|
||||
impl Net {
|
||||
pub fn new(
|
||||
sockets: &mut SocketSet<'static>,
|
||||
mut ethdev: ethernet::EthernetDMA<4, 4>,
|
||||
ethernet_addr: HardwareAddress,
|
||||
) -> Self {
|
||||
let config = Config::new(ethernet_addr);
|
||||
let mut iface = Interface::new(
|
||||
config,
|
||||
&mut ethdev,
|
||||
smoltcp::time::Instant::from_millis((Systick::now() - Systick::ZERO).to_millis()),
|
||||
);
|
||||
// Create sockets
|
||||
let dhcp_socket = dhcpv4::Socket::new();
|
||||
iface.update_ip_addrs(|addrs| {
|
||||
let _ = addrs.push(IpCidr::new(IpAddress::v4(192, 168, 1, 99), 0));
|
||||
});
|
||||
|
||||
let dhcp_handle = sockets.add(dhcp_socket);
|
||||
Net {
|
||||
iface,
|
||||
ethdev,
|
||||
dhcp_handle,
|
||||
}
|
||||
}
|
||||
|
||||
/// Polls on the ethernet interface. You should refer to the smoltcp
|
||||
/// documentation for poll() to understand how to call poll efficiently
|
||||
pub fn poll<'a>(&mut self, sockets: &'a mut SocketSet) -> bool {
|
||||
let uptime = Systick::now() - Systick::ZERO;
|
||||
let timestamp = smoltcp::time::Instant::from_millis(uptime.to_millis());
|
||||
|
||||
self.iface.poll(timestamp, &mut self.ethdev, sockets)
|
||||
}
|
||||
|
||||
pub fn poll_dhcp<'a>(&mut self, sockets: &'a mut SocketSet) -> Option<dhcpv4::Event<'a>> {
|
||||
let opt_event = sockets.get_mut::<dhcpv4::Socket>(self.dhcp_handle).poll();
|
||||
if let Some(event) = &opt_event {
|
||||
match event {
|
||||
dhcpv4::Event::Deconfigured => {
|
||||
defmt::info!("DHCP lost configuration");
|
||||
self.iface.update_ip_addrs(|addrs| addrs.clear());
|
||||
self.iface.routes_mut().remove_default_ipv4_route();
|
||||
}
|
||||
dhcpv4::Event::Configured(config) => {
|
||||
defmt::info!("DHCP configuration acquired");
|
||||
defmt::info!("IP address: {}", config.address);
|
||||
self.iface.update_ip_addrs(|addrs| {
|
||||
addrs.clear();
|
||||
addrs.push(IpCidr::Ipv4(config.address)).unwrap();
|
||||
});
|
||||
|
||||
if let Some(router) = config.router {
|
||||
defmt::debug!("Default gateway: {}", router);
|
||||
self.iface
|
||||
.routes_mut()
|
||||
.add_default_ipv4_route(router)
|
||||
.unwrap();
|
||||
} else {
|
||||
defmt::debug!("Default gateway: None");
|
||||
self.iface.routes_mut().remove_default_ipv4_route();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
opt_event
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UdpNet {
|
||||
udp_handle: SocketHandle,
|
||||
last_client: Option<UdpMetadata>,
|
||||
tc_source_tx: TcSourceTx,
|
||||
}
|
||||
|
||||
impl UdpNet {
|
||||
pub fn new<'sockets>(sockets: &mut SocketSet<'sockets>, tc_source_tx: TcSourceTx) -> Self {
|
||||
// SAFETY: The RX and TX buffers are passed here and not used anywhere else.
|
||||
let udp_rx_buffer =
|
||||
smoltcp::socket::udp::PacketBuffer::new(unsafe { &mut UDP_RX_META[..] }, unsafe {
|
||||
&mut UDP_RX[..]
|
||||
});
|
||||
let udp_tx_buffer =
|
||||
smoltcp::socket::udp::PacketBuffer::new(unsafe { &mut UDP_TX_META[..] }, unsafe {
|
||||
&mut UDP_TX[..]
|
||||
});
|
||||
let udp_socket = smoltcp::socket::udp::Socket::new(udp_rx_buffer, udp_tx_buffer);
|
||||
|
||||
let udp_handle = sockets.add(udp_socket);
|
||||
Self {
|
||||
udp_handle,
|
||||
last_client: None,
|
||||
tc_source_tx,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn poll<'sockets>(
|
||||
&mut self,
|
||||
sockets: &'sockets mut SocketSet,
|
||||
shared_pool: &mut SharedPool,
|
||||
) {
|
||||
let socket = sockets.get_mut::<udp::Socket>(self.udp_handle);
|
||||
if !socket.is_open() {
|
||||
if let Err(e) = socket.bind(PORT) {
|
||||
defmt::warn!("binding UDP socket failed: {}", e);
|
||||
}
|
||||
}
|
||||
loop {
|
||||
match socket.recv() {
|
||||
Ok((data, client)) => {
|
||||
match shared_pool.add(data) {
|
||||
Ok(store_addr) => {
|
||||
if let Err(e) = self.tc_source_tx.try_send(store_addr) {
|
||||
defmt::warn!("TC source channel is full: {}", e);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
defmt::warn!("could not add UDP packet to shared pool: {}", e);
|
||||
}
|
||||
}
|
||||
self.last_client = Some(client);
|
||||
// TODO: Implement packet wiretapping.
|
||||
}
|
||||
Err(e) => match e {
|
||||
udp::RecvError::Exhausted => {
|
||||
break;
|
||||
}
|
||||
udp::RecvError::Truncated => {
|
||||
defmt::warn!("UDP packet was truncacted");
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[app(device = stm32h7xx_hal::stm32, peripherals = true)]
|
||||
mod app {
|
||||
use core::ptr::addr_of_mut;
|
||||
|
||||
use super::*;
|
||||
use rtic_monotonics::systick::fugit::MillisDurationU32;
|
||||
use rtic_monotonics::systick::Systick;
|
||||
use satrs::spacepackets::ecss::tc::PusTcReader;
|
||||
use stm32h7xx_hal::ethernet::{EthernetMAC, PHY};
|
||||
use stm32h7xx_hal::gpio::{Output, Pin};
|
||||
use stm32h7xx_hal::prelude::*;
|
||||
use stm32h7xx_hal::stm32::Interrupt;
|
||||
|
||||
struct BlinkyLeds {
|
||||
led1: Pin<'B', 7, Output>,
|
||||
led2: Pin<'B', 14, Output>,
|
||||
}
|
||||
|
||||
#[local]
|
||||
struct Local {
|
||||
leds: BlinkyLeds,
|
||||
link_led: Pin<'B', 0, Output>,
|
||||
net: Net,
|
||||
udp: UdpNet,
|
||||
tc_source_rx: TcSourceRx,
|
||||
phy: ethernet::phy::LAN8742A<EthernetMAC>,
|
||||
}
|
||||
|
||||
#[shared]
|
||||
struct Shared {
|
||||
blink_freq: MillisDurationU32,
|
||||
eth_link_up: bool,
|
||||
sockets: SocketSet<'static>,
|
||||
shared_pool: SharedPool,
|
||||
}
|
||||
|
||||
#[init]
|
||||
fn init(mut cx: init::Context) -> (Shared, Local) {
|
||||
defmt::println!("Starting sat-rs demo application for the STM32H743ZIT");
|
||||
|
||||
let pwr = cx.device.PWR.constrain();
|
||||
let pwrcfg = pwr.freeze();
|
||||
|
||||
let rcc = cx.device.RCC.constrain();
|
||||
// Try to keep the clock configuration similar to one used in STM examples:
|
||||
// https://github.com/STMicroelectronics/STM32CubeH7/blob/master/Projects/NUCLEO-H743ZI/Examples/GPIO/GPIO_EXTI/Src/main.c
|
||||
let ccdr = rcc
|
||||
.sys_ck(400.MHz())
|
||||
.hclk(200.MHz())
|
||||
.use_hse(8.MHz())
|
||||
.bypass_hse()
|
||||
.pclk1(100.MHz())
|
||||
.pclk2(100.MHz())
|
||||
.pclk3(100.MHz())
|
||||
.pclk4(100.MHz())
|
||||
.freeze(pwrcfg, &cx.device.SYSCFG);
|
||||
|
||||
// Initialize the systick interrupt & obtain the token to prove that we did
|
||||
let systick_mono_token = rtic_monotonics::create_systick_token!();
|
||||
Systick::start(
|
||||
cx.core.SYST,
|
||||
ccdr.clocks.sys_ck().to_Hz(),
|
||||
systick_mono_token,
|
||||
);
|
||||
|
||||
// Those are used in the smoltcp of the stm32h7xx-hal , I am not fully sure what they are
|
||||
// good for.
|
||||
cx.core.SCB.enable_icache();
|
||||
cx.core.DWT.enable_cycle_counter();
|
||||
|
||||
let gpioa = cx.device.GPIOA.split(ccdr.peripheral.GPIOA);
|
||||
let gpiob = cx.device.GPIOB.split(ccdr.peripheral.GPIOB);
|
||||
let gpioc = cx.device.GPIOC.split(ccdr.peripheral.GPIOC);
|
||||
let gpiog = cx.device.GPIOG.split(ccdr.peripheral.GPIOG);
|
||||
|
||||
let link_led = gpiob.pb0.into_push_pull_output();
|
||||
let mut led1 = gpiob.pb7.into_push_pull_output();
|
||||
let mut led2 = gpiob.pb14.into_push_pull_output();
|
||||
|
||||
// Criss-cross pattern looks cooler.
|
||||
led1.set_high();
|
||||
led2.set_low();
|
||||
let leds = BlinkyLeds { led1, led2 };
|
||||
|
||||
let rmii_ref_clk = gpioa.pa1.into_alternate::<11>();
|
||||
let rmii_mdio = gpioa.pa2.into_alternate::<11>();
|
||||
let rmii_mdc = gpioc.pc1.into_alternate::<11>();
|
||||
let rmii_crs_dv = gpioa.pa7.into_alternate::<11>();
|
||||
let rmii_rxd0 = gpioc.pc4.into_alternate::<11>();
|
||||
let rmii_rxd1 = gpioc.pc5.into_alternate::<11>();
|
||||
let rmii_tx_en = gpiog.pg11.into_alternate::<11>();
|
||||
let rmii_txd0 = gpiog.pg13.into_alternate::<11>();
|
||||
let rmii_txd1 = gpiob.pb13.into_alternate::<11>();
|
||||
|
||||
let mac_addr = smoltcp::wire::EthernetAddress::from_bytes(&MAC_ADDRESS);
|
||||
|
||||
/// Ethernet descriptor rings are a global singleton
|
||||
#[link_section = ".sram3.eth"]
|
||||
static mut DES_RING: MaybeUninit<ethernet::DesRing<4, 4>> = MaybeUninit::uninit();
|
||||
|
||||
let (eth_dma, eth_mac) = ethernet::new(
|
||||
cx.device.ETHERNET_MAC,
|
||||
cx.device.ETHERNET_MTL,
|
||||
cx.device.ETHERNET_DMA,
|
||||
(
|
||||
rmii_ref_clk,
|
||||
rmii_mdio,
|
||||
rmii_mdc,
|
||||
rmii_crs_dv,
|
||||
rmii_rxd0,
|
||||
rmii_rxd1,
|
||||
rmii_tx_en,
|
||||
rmii_txd0,
|
||||
rmii_txd1,
|
||||
),
|
||||
// SAFETY: We do not move the returned DMA struct across thread boundaries, so this
|
||||
// should be safe according to the docs.
|
||||
unsafe { DES_RING.assume_init_mut() },
|
||||
mac_addr,
|
||||
ccdr.peripheral.ETH1MAC,
|
||||
&ccdr.clocks,
|
||||
);
|
||||
// Initialise ethernet PHY...
|
||||
let mut lan8742a = ethernet::phy::LAN8742A::new(eth_mac.set_phy_addr(0));
|
||||
lan8742a.phy_reset();
|
||||
lan8742a.phy_init();
|
||||
|
||||
unsafe {
|
||||
ethernet::enable_interrupt();
|
||||
cx.core.NVIC.set_priority(Interrupt::ETH, 196); // Mid prio
|
||||
cortex_m::peripheral::NVIC::unmask(Interrupt::ETH);
|
||||
}
|
||||
|
||||
// unsafe: mutable reference to static storage, we only do this once
|
||||
let store = unsafe {
|
||||
let store_ptr = STORE.as_mut_ptr();
|
||||
|
||||
// Initialise the socket_storage field. Using `write` instead of
|
||||
// assignment via `=` to not call `drop` on the old, uninitialised
|
||||
// value
|
||||
addr_of_mut!((*store_ptr).socket_storage).write([SocketStorage::EMPTY; 8]);
|
||||
|
||||
// Now that all fields are initialised we can safely use
|
||||
// assume_init_mut to return a mutable reference to STORE
|
||||
STORE.assume_init_mut()
|
||||
};
|
||||
|
||||
let (tc_source_tx, tc_source_rx) =
|
||||
rtic_sync::make_channel!(PoolAddr, TC_SOURCE_CHANNEL_DEPTH);
|
||||
|
||||
let mut sockets = SocketSet::new(&mut store.socket_storage[..]);
|
||||
let net = Net::new(&mut sockets, eth_dma, mac_addr.into());
|
||||
let udp = UdpNet::new(&mut sockets, tc_source_tx);
|
||||
|
||||
let mut shared_pool: SharedPool = StaticHeaplessMemoryPool::new(true);
|
||||
static_subpool!(
|
||||
SUBPOOL_SMALL,
|
||||
SUBPOOL_SMALL_SIZES,
|
||||
SUBPOOL_SMALL_NUM_BLOCKS as usize,
|
||||
SUBPOOL_SMALL_BLOCK_SIZE,
|
||||
link_section = ".axisram"
|
||||
);
|
||||
static_subpool!(
|
||||
SUBPOOL_MEDIUM,
|
||||
SUBPOOL_MEDIUM_SIZES,
|
||||
SUBPOOL_MEDIUM_NUM_BLOCKS as usize,
|
||||
SUBPOOL_MEDIUM_BLOCK_SIZE,
|
||||
link_section = ".axisram"
|
||||
);
|
||||
static_subpool!(
|
||||
SUBPOOL_LARGE,
|
||||
SUBPOOL_LARGE_SIZES,
|
||||
SUBPOOL_LARGE_NUM_BLOCKS as usize,
|
||||
SUBPOOL_LARGE_BLOCK_SIZE,
|
||||
link_section = ".axisram"
|
||||
);
|
||||
|
||||
shared_pool
|
||||
.grow(
|
||||
unsafe { SUBPOOL_SMALL.assume_init_mut() },
|
||||
unsafe { SUBPOOL_SMALL_SIZES.assume_init_mut() },
|
||||
SUBPOOL_SMALL_NUM_BLOCKS,
|
||||
true,
|
||||
)
|
||||
.expect("growing heapless memory pool failed");
|
||||
shared_pool
|
||||
.grow(
|
||||
unsafe { SUBPOOL_MEDIUM.assume_init_mut() },
|
||||
unsafe { SUBPOOL_MEDIUM_SIZES.assume_init_mut() },
|
||||
SUBPOOL_MEDIUM_NUM_BLOCKS,
|
||||
true,
|
||||
)
|
||||
.expect("growing heapless memory pool failed");
|
||||
shared_pool
|
||||
.grow(
|
||||
unsafe { SUBPOOL_LARGE.assume_init_mut() },
|
||||
unsafe { SUBPOOL_LARGE_SIZES.assume_init_mut() },
|
||||
SUBPOOL_LARGE_NUM_BLOCKS,
|
||||
true,
|
||||
)
|
||||
.expect("growing heapless memory pool failed");
|
||||
|
||||
// Set up global allocator. Use AXISRAM for the heap.
|
||||
#[link_section = ".axisram"]
|
||||
static mut HEAP_MEM: [MaybeUninit<u8>; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE];
|
||||
unsafe { HEAP.init(HEAP_MEM.as_ptr() as usize, HEAP_SIZE) }
|
||||
|
||||
eth_link_check::spawn().expect("eth link check failed");
|
||||
blinky::spawn().expect("spawning blink task failed");
|
||||
udp_task::spawn().expect("spawning UDP task failed");
|
||||
tc_source_task::spawn().expect("spawning TC source task failed");
|
||||
|
||||
(
|
||||
Shared {
|
||||
blink_freq: MillisDurationU32::from_ticks(DEFAULT_BLINK_FREQ_MS),
|
||||
eth_link_up: false,
|
||||
sockets,
|
||||
shared_pool,
|
||||
},
|
||||
Local {
|
||||
link_led,
|
||||
leds,
|
||||
net,
|
||||
udp,
|
||||
tc_source_rx,
|
||||
phy: lan8742a,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[task(local = [leds], shared=[blink_freq])]
|
||||
async fn blinky(mut cx: blinky::Context) {
|
||||
let leds = cx.local.leds;
|
||||
loop {
|
||||
leds.led1.toggle();
|
||||
leds.led2.toggle();
|
||||
let current_blink_freq = cx.shared.blink_freq.lock(|current| *current);
|
||||
Systick::delay(current_blink_freq).await;
|
||||
}
|
||||
}
|
||||
|
||||
/// This task checks for the network link.
|
||||
#[task(local=[link_led, phy], shared=[eth_link_up])]
|
||||
async fn eth_link_check(mut cx: eth_link_check::Context) {
|
||||
let phy = cx.local.phy;
|
||||
let link_led = cx.local.link_led;
|
||||
loop {
|
||||
let link_was_up = cx.shared.eth_link_up.lock(|link_up| *link_up);
|
||||
if phy.poll_link() {
|
||||
if !link_was_up {
|
||||
link_led.set_high();
|
||||
cx.shared.eth_link_up.lock(|link_up| *link_up = true);
|
||||
defmt::info!("Ethernet link up");
|
||||
}
|
||||
} else if link_was_up {
|
||||
link_led.set_low();
|
||||
cx.shared.eth_link_up.lock(|link_up| *link_up = false);
|
||||
defmt::info!("Ethernet link down");
|
||||
}
|
||||
Systick::delay(100.millis()).await;
|
||||
}
|
||||
}
|
||||
|
||||
#[task(binds=ETH, local=[net], shared=[sockets])]
|
||||
fn eth_isr(mut cx: eth_isr::Context) {
|
||||
// SAFETY: We do not write the register mentioned inside the docs anywhere else.
|
||||
unsafe {
|
||||
ethernet::interrupt_handler();
|
||||
}
|
||||
// Check and process ETH frames and DHCP. UDP is checked in a different task.
|
||||
cx.shared.sockets.lock(|sockets| {
|
||||
cx.local.net.poll(sockets);
|
||||
cx.local.net.poll_dhcp(sockets);
|
||||
});
|
||||
}
|
||||
|
||||
/// This task routes UDP packets.
|
||||
#[task(local=[udp], shared=[sockets, shared_pool])]
|
||||
async fn udp_task(mut cx: udp_task::Context) {
|
||||
loop {
|
||||
cx.shared.sockets.lock(|sockets| {
|
||||
cx.shared.shared_pool.lock(|pool| {
|
||||
cx.local.udp.poll(sockets, pool);
|
||||
})
|
||||
});
|
||||
Systick::delay(40.millis()).await;
|
||||
}
|
||||
}
|
||||
|
||||
/// This task handles all the incoming telecommands.
|
||||
#[task(local=[read_buf: [u8; 1024] = [0; 1024], tc_source_rx], shared=[shared_pool])]
|
||||
async fn tc_source_task(mut cx: tc_source_task::Context) {
|
||||
loop {
|
||||
let recv_result = cx.local.tc_source_rx.recv().await;
|
||||
match recv_result {
|
||||
Ok(pool_addr) => {
|
||||
cx.shared.shared_pool.lock(|pool| {
|
||||
match pool.read(&pool_addr, cx.local.read_buf.as_mut()) {
|
||||
Ok(packet_len) => {
|
||||
defmt::info!("received {} bytes in the TC source task", packet_len);
|
||||
match PusTcReader::new(&cx.local.read_buf[0..packet_len]) {
|
||||
Ok((packet, _tc_len)) => {
|
||||
// TODO: Handle packet here or dispatch to dedicated PUS
|
||||
// handler? Dispatching could simplify some things and make
|
||||
// the software more scalable..
|
||||
defmt::info!("received PUS packet: {}", packet);
|
||||
}
|
||||
Err(e) => {
|
||||
defmt::info!("invalid TC format, not a PUS packet: {}", e);
|
||||
}
|
||||
}
|
||||
if let Err(e) = pool.delete(pool_addr) {
|
||||
defmt::warn!("deleting TC data failed: {}", e);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
defmt::warn!("TC packet read failed: {}", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
Err(e) => {
|
||||
defmt::warn!("TC source reception error: {}", e);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
16
embedded-examples/stm32h7-nucleo-rtic/tests/integration.rs
Normal file
16
embedded-examples/stm32h7-nucleo-rtic/tests/integration.rs
Normal file
@ -0,0 +1,16 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use stm32h7_testapp as _; // memory layout + panic handler
|
||||
|
||||
// See https://crates.io/crates/defmt-test/0.3.0 for more documentation (e.g. about the 'state'
|
||||
// feature)
|
||||
#[defmt_test::tests]
|
||||
mod tests {
|
||||
use defmt::assert;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
assert!(true)
|
||||
}
|
||||
}
|
2
embedded-examples/stm32h7-nucleo-rtic/vscode/.gitignore
vendored
Normal file
2
embedded-examples/stm32h7-nucleo-rtic/vscode/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/settings.json
|
||||
/.cortex-debug.*
|
12
embedded-examples/stm32h7-nucleo-rtic/vscode/extensions.json
Normal file
12
embedded-examples/stm32h7-nucleo-rtic/vscode/extensions.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
|
||||
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
|
||||
|
||||
// List of extensions which should be recommended for users of this workspace.
|
||||
"recommendations": [
|
||||
"rust-lang.rust",
|
||||
"probe-rs.probe-rs-debugger"
|
||||
],
|
||||
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
|
||||
"unwantedRecommendations": []
|
||||
}
|
22
embedded-examples/stm32h7-nucleo-rtic/vscode/launch.json
Normal file
22
embedded-examples/stm32h7-nucleo-rtic/vscode/launch.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"preLaunchTask": "${defaultBuildTask}",
|
||||
"type": "probe-rs-debug",
|
||||
"request": "launch",
|
||||
"name": "probe-rs Debugging ",
|
||||
"flashingConfig": {
|
||||
"flashingEnabled": true
|
||||
},
|
||||
"chip": "STM32H743ZITx",
|
||||
"coreConfigs": [
|
||||
{
|
||||
"programBinary": "${workspaceFolder}/target/thumbv7em-none-eabihf/debug/satrs-stm32h7-nucleo-rtic",
|
||||
"rttEnabled": true,
|
||||
"svdFile": "STM32H743.svd"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
20
embedded-examples/stm32h7-nucleo-rtic/vscode/tasks.json
Normal file
20
embedded-examples/stm32h7-nucleo-rtic/vscode/tasks.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "cargo build",
|
||||
"type": "shell",
|
||||
"command": "~/.cargo/bin/cargo", // note: full path to the cargo
|
||||
"args": [
|
||||
"build"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
|
||||
]
|
||||
}
|
@ -396,6 +396,9 @@ pub mod alloc_mod {
|
||||
#[derive(Debug)]
|
||||
pub struct PusScheduler {
|
||||
// TODO: Use MonotonicTime from tai-time crate instead of UnixTime and cache leap seconds.
|
||||
// TODO: Introduce optional limit of commands stored in the TC map. If a limit is set,
|
||||
// there will be a check for each insertion whether the map is full, making the memory
|
||||
// usage of the scheduler more deterministic.
|
||||
tc_map: BTreeMap<UnixTime, Vec<TcInfo>>,
|
||||
pub(crate) current_time: UnixTime,
|
||||
time_margin: Duration,
|
||||
|
Loading…
Reference in New Issue
Block a user