Merge pull request 'Update STM32F3 example' (#141) from update-stm32f3-example into main
All checks were successful
Rust/sat-rs/pipeline/head This commit looks good

Reviewed-on: #141
This commit is contained in:
Robin Müller 2024-03-22 15:19:58 +01:00
commit a6b57d3eb9
16 changed files with 530 additions and 354 deletions

2
.gitignore vendored
View File

@ -2,5 +2,7 @@ target/
/Cargo.lock
output.log
/.idea/*
!/.idea/runConfigurations

View File

@ -0,0 +1,28 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
# uncomment ONE of these three option to make `cargo run` start a GDB session
# which option to pick depends on your system
# You can also replace openocd.gdb by jlink.gdb when using a J-Link.
# runner = "arm-none-eabi-gdb -q -x openocd.gdb"
# runner = "gdb-multiarch -q -x openocd.gdb"
# runner = "gdb -q -x openocd.gdb"
# runner = "probe-run --chip STM32F303VCTx --connect-under-reset"
rustflags = [
# LLD (shipped with the Rust toolchain) is used as the default linker
"-C", "link-arg=-Tlink.x",
# if you run into problems with LLD switch to the GNU linker by commenting out
# this line
# "-C", "linker=arm-none-eabi-ld",
# if you need to link to pre-compiled C libraries provided by a C toolchain
# use GCC as the linker by commenting out both lines above and then
# uncommenting the three lines below
# "-C", "linker=arm-none-eabi-gcc",
# "-C", "link-arg=-Wl,-Tlink.x",
# "-C", "link-arg=-nostartfiles",
]
[build]
# comment out the following line if you intend to run unit tests on host machine
target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)

View File

@ -1,3 +1,4 @@
/target
/itm.txt
/.cargo/config*
/.vscode

View File

@ -1,3 +0,0 @@
{
"cortex-debug.gdbPath.linux": "gdb-multiarch"
}

View File

@ -13,9 +13,9 @@ dependencies = [
[[package]]
name = "atomic-polyfill"
version = "0.1.11"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28"
checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
dependencies = [
"critical-section",
]
@ -60,15 +60,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b13b4b2ea9ab2ba924063ebb86ad895cb79f4a79bf90f27949eb20c335b30f9"
dependencies = [
"bitflags",
"nb 1.0.0",
"nb 1.1.0",
"vcell",
]
[[package]]
name = "byteorder"
version = "1.4.3"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cast"
@ -87,19 +87,29 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.23"
version = "0.4.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a"
dependencies = [
"num-integer",
"num-traits",
]
[[package]]
name = "cortex-m"
version = "0.7.6"
name = "cobs"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70858629a458fdfd39f9675c4dc309411f2a3f83bede76988d81bf1a0ecee9e0"
checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15"
[[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",
@ -109,9 +119,9 @@ dependencies = [
[[package]]
name = "cortex-m-rt"
version = "0.7.2"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6d3328b8b5534f0c90acd66b68950f2763b37e0173cac4d8b4937c4a80761f9"
checksum = "ee84e813d593101b1723e13ec38b6ab6abbdbaaa4546553f5395ed274079ddb1"
dependencies = [
"cortex-m-rt-macros",
]
@ -124,19 +134,19 @@ checksum = "f0f6f3e36f203cfedbc78b357fb28730aa2c6dc1ab060ee5c2405e843988d3c7"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
name = "cortex-m-rtic"
version = "1.1.3"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6b82f1c39acd6c3a35c2013b6110c20f5bc534522791fabadeed49ccada2dce"
checksum = "d696ae7390bdb9f7978f71ca7144256a2c4616240a6df9002da3c451f9fc8f02"
dependencies = [
"bare-metal 1.0.0",
"cortex-m",
"cortex-m-rtic-macros",
"heapless",
"heapless 0.7.17",
"rtic-core",
"rtic-monotonic",
"version_check",
@ -144,28 +154,43 @@ dependencies = [
[[package]]
name = "cortex-m-rtic-macros"
version = "1.1.5"
version = "1.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e8e9645ef54bec1cf70ac33e9bf9566e6507ab5b41ae6baf3735662194e8607"
checksum = "eefb40b1ca901c759d29526e5c8a0a1b246c20caaa5b4cc5d0f0b94debecd4c7"
dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"rtic-syntax",
"syn",
"syn 1.0.109",
]
[[package]]
name = "critical-section"
version = "1.1.1"
name = "crc"
version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52"
checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe"
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 = "darling"
version = "0.14.2"
version = "0.20.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa"
checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391"
dependencies = [
"darling_core",
"darling_macro",
@ -173,26 +198,37 @@ dependencies = [
[[package]]
name = "darling_core"
version = "0.14.2"
version = "0.20.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f"
checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"syn",
"syn 2.0.53",
]
[[package]]
name = "darling_macro"
version = "0.14.2"
version = "0.20.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e"
checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
dependencies = [
"darling_core",
"quote",
"syn",
"syn 2.0.53",
]
[[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]]
@ -225,23 +261,23 @@ dependencies = [
[[package]]
name = "enumset"
version = "1.0.12"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753"
checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d"
dependencies = [
"enumset_derive",
]
[[package]]
name = "enumset_derive"
version = "0.6.1"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0"
checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af"
dependencies = [
"darling",
"proc-macro2",
"quote",
"syn",
"syn 2.0.53",
]
[[package]]
@ -252,18 +288,18 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "fugit"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ab17bb279def6720d058cb6c052249938e7f99260ab534879281a95367a87e5"
checksum = "17186ad64927d5ac8f02c1e77ccefa08ccd9eaa314d5a4772278aa204a22f7e7"
dependencies = [
"gcd",
]
[[package]]
name = "gcd"
version = "2.2.0"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4b1b088ad0a967aa29540456b82fc8903f854775d33f71e9709c4efb3dfbfd2"
checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a"
[[package]]
name = "generic-array"
@ -276,9 +312,9 @@ dependencies = [
[[package]]
name = "generic-array"
version = "0.14.6"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
@ -293,6 +329,15 @@ 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.12.3"
@ -301,17 +346,27 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "heapless"
version = "0.7.16"
version = "0.7.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743"
checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
dependencies = [
"atomic-polyfill",
"hash32",
"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 = [
"hash32 0.3.1",
"stable_deref_trait",
]
[[package]]
name = "ident_case"
version = "1.0.1"
@ -320,9 +375,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "indexmap"
version = "1.9.2"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"hashbrown",
@ -330,7 +385,8 @@ dependencies = [
[[package]]
name = "itm_logger"
version = "0.1.3-pre.0"
version = "0.1.3-alpha.0"
source = "git+https://github.com/robamu/itm_logger.rs.git?branch=all_features#83ee7a6c57f525a70d0cc5bb7e65826d0ce938a0"
dependencies = [
"cortex-m",
"log",
@ -338,9 +394,9 @@ dependencies = [
[[package]]
name = "lock_api"
version = "0.4.9"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
dependencies = [
"autocfg",
"scopeguard",
@ -348,12 +404,9 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.17"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if",
]
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]]
name = "lsm303dlhc"
@ -372,7 +425,7 @@ version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc4010833aea396656c2f91ee704d51a6f1329ec2ab56ffd00bfd56f7481ea94"
dependencies = [
"generic-array 0.14.6",
"generic-array 0.14.7",
]
[[package]]
@ -381,14 +434,14 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
dependencies = [
"nb 1.0.0",
"nb 1.1.0",
]
[[package]]
name = "nb"
version = "1.0.0"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae"
checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
[[package]]
name = "num"
@ -414,19 +467,18 @@ dependencies = [
[[package]]
name = "num-integer"
version = "0.1.45"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-iter"
version = "0.1.43"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9"
dependencies = [
"autocfg",
"num-integer",
@ -446,13 +498,33 @@ dependencies = [
[[package]]
name = "num-traits"
version = "0.2.15"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
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.53",
]
[[package]]
name = "panic-itm"
version = "0.4.2"
@ -464,9 +536,9 @@ dependencies = [
[[package]]
name = "paste"
version = "1.0.11"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba"
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]]
name = "proc-macro-error"
@ -477,7 +549,7 @@ dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
"version_check",
]
@ -494,27 +566,27 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.49"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.23"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rtcc"
version = "0.3.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3623619ce77c09a7d87cf7c61c5c887b9c7dee8805f66af6c4aa5824be4d9930"
checksum = "f4fbd0d5bed2b76e27a7ef872568b34072c1af94c277cd52c17a89d54673b3fe"
dependencies = [
"chrono",
]
@ -533,14 +605,14 @@ checksum = "fb8b0b822d1a366470b9cea83a1d4e788392db763539dc4ba022bcc787fece82"
[[package]]
name = "rtic-syntax"
version = "1.0.2"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ad3ae243dd8d0a1b064615f664d4fa7e63929939074c564cbe5efdc4c503065"
checksum = "5f5e215601dc467752c2bddc6284a622c6f3d2bab569d992adcd5ab7e4cb9478"
dependencies = [
"indexmap",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -558,31 +630,59 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver 1.0.16",
"semver 1.0.22",
]
[[package]]
name = "sat-rs-example-stm32f-disco"
name = "satrs"
version = "0.2.0-rc.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8cb19cba46a45047ff0879ebfbf9d6ae1c5b2e0e38b2e08760b10a441d4dae6"
dependencies = [
"cobs 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"crc",
"delegate",
"num-traits",
"num_enum",
"paste",
"satrs-shared",
"smallvec",
"spacepackets",
]
[[package]]
name = "satrs-example-stm32f3-disco"
version = "0.1.0"
dependencies = [
"cobs 0.2.3 (git+https://github.com/robamu/cobs.rs.git?branch=all_features)",
"cortex-m",
"cortex-m-rt",
"cortex-m-rtic",
"embedded-hal",
"enumset",
"heapless",
"heapless 0.8.0",
"itm_logger",
"panic-itm",
"satrs",
"stm32f3-discovery",
"stm32f3xx-hal",
"systick-monotonic",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
name = "satrs-shared"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
checksum = "75a402ba556a7f5eef707035b45e64a3259b09674311e98697f3dd0508a1bf51"
dependencies = [
"spacepackets",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "semver"
@ -595,9 +695,9 @@ dependencies = [
[[package]]
name = "semver"
version = "1.0.16"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a"
checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
[[package]]
name = "semver-parser"
@ -607,15 +707,35 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "slice-group-by"
version = "0.3.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03b634d87b960ab1a38c4fe143b508576f075e7c978bfad18217645ebfdfa2ec"
checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7"
[[package]]
name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "spacepackets"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28246ae2451af240c3e3ff3c51363c7b6ad565ca6aa9bad23b8c725687c485e1"
dependencies = [
"chrono",
"crc",
"delegate",
"num-traits",
"num_enum",
"zerocopy",
]
[[package]]
name = "spin"
version = "0.9.4"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
"lock_api",
]
@ -651,7 +771,8 @@ dependencies = [
[[package]]
name = "stm32f3-discovery"
version = "0.8.0-pre.0"
version = "0.8.0-alpha.0"
source = "git+https://github.com/robamu/stm32f3-discovery?branch=all_features#7b1d21b0463331ada405ceed876c93e82b987a9f"
dependencies = [
"accelerometer",
"cortex-m",
@ -663,9 +784,8 @@ dependencies = [
[[package]]
name = "stm32f3xx-hal"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e422c5c044e8f3a068b1e14b83c071449e27c9d4bc0e24f972b552d79f2be03"
version = "0.10.0-alpha.0"
source = "git+https://github.com/robamu/stm32f3xx-hal?branch=all_features#c9b3a4fcaaf48f8264475de2b34387597211478e"
dependencies = [
"bare-metal 1.0.0",
"bxcan",
@ -676,7 +796,7 @@ dependencies = [
"embedded-hal",
"embedded-time",
"enumset",
"nb 1.0.0",
"nb 1.1.0",
"paste",
"rtcc",
"slice-group-by",
@ -696,9 +816,20 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.107"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032"
dependencies = [
"proc-macro2",
"quote",
@ -718,15 +849,15 @@ dependencies = [
[[package]]
name = "typenum"
version = "1.16.0"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "unicode-ident"
version = "1.0.6"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "usb-device"
@ -754,9 +885,30 @@ checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
[[package]]
name = "volatile-register"
version = "0.2.1"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6"
checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc"
dependencies = [
"vcell",
]
[[package]]
name = "zerocopy"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
dependencies = [
"byteorder",
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
]

View File

@ -11,7 +11,7 @@ cortex-m-rt = "0.7"
embedded-hal = "0.2.6"
cortex-m-rtic = "1.0"
enumset = "1.0"
heapless = "0.7"
heapless = "0.8"
systick-monotonic = "1.0"
[dependencies.cobs]
@ -42,9 +42,9 @@ branch = "all_features"
# Can be used in workspace to develop and update BSP
# path = "../stm32f3-discovery"
[dependencies.satrs-core]
git = "https://egit.irs.uni-stuttgart.de/rust/satrs-core.git"
version = "0.1.0-alpha.0"
[dependencies.satrs]
# git = "https://egit.irs.uni-stuttgart.de/rust/satrs-core.git"
version = "0.2.0-rc.0"
default-features = false
# this lets you use `cargo fix`!

View File

@ -11,6 +11,18 @@ used by the [Rust Embedded Book](https://docs.rust-embedded.org/book/intro/hardw
[Rust Discovery](https://docs.rust-embedded.org/discovery/f3discovery/) book as an introduction
to embedded Rust.
If you would like to access the ITM log output, you need to connect the PB3 pin to the CN3 pin
of the SWD header like [shown here](https://docs.rust-embedded.org/discovery/f3discovery/06-hello-world/index.html).
## Pre-Requisites
Make sure the following tools are installed:
1. `openocd`: This is the debug server used to debug the STM32F3. You can install this from
[`xPacks`](https://xpack.github.io/dev-tools/openocd/install/). You can also use the one provided
by a STM32Cube installation.
2. A debugger like `arm-none-eabi-gdb` or `gdb-multiarch`.
## Preparing Rust and the repository
Building an application requires the `thumbv7em-none-eabihf` cross-compiler toolchain.
@ -42,13 +54,25 @@ cargo build
## Flashing and Debugging from the command line
TODO
Make sure you have `openocd` and `itmdump` installed first.
1. Configure a runner inside your `.cargo/config.toml` file by uncommenting an appropriate line
depending on the application you want to use for debugging
2. Start `openocd` inside the project folder. This will start `openocd` with the provided
`openocd.cfg` configuration file.
3. Use `cargo run` to flash and debug the application in your terminal
4. Use `itmdump -F -f itm.txt` to print the logs received from the STM32F3 device. Please note
that the PB3 and CN3 pin of the SWD header need to be connected for this to work.
## 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 `openocd`
and the VS Code [`Cortex-Debug` plugin](https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug).
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.
@ -67,9 +91,23 @@ configuration variables in your `settings.json`:
## Commanding with Python
When the SW is running on the Discovery board, you can command the MCU via a serial interface,
using COBS encoded CCSDS packets.
using COBS encoded PUS packets.
TODO:
- How and where to connect serial interface on the MCU
- How to set up Python venv (or at least strongly recommend it) and install deps
- How to copy `def_tmtc_conf.json` to `tmtc_conf.json` and adapt it for custom serial port
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
```

View File

@ -24,7 +24,9 @@ break main
# # send captured ITM to the file itm.fifo
# # (the microcontroller SWO pin must be connected to the programmer SWO pin)
# # 8000000 must match the core clock frequency
monitor tpiu config internal itm.txt uart off 8000000
# # 2000000 is the frequency of the SWO pin. This was added for newer
# openocd versions like v0.12.0.
monitor tpiu config internal itm.txt uart off 8000000 2000000
# # OR: make the microcontroller SWO pin output compatible with UART (8N1)
# # 8000000 must match the core clock frequency

181
satrs-example-stm32f3-disco/pyclient/main.py Normal file → Executable file
View File

@ -1,39 +1,39 @@
#!/usr/bin/env python3
"""Example client for the sat-rs example application"""
import enum
import struct
import logging
import sys
import time
from typing import Optional, cast
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, PusVerificator
from spacepackets.ecss.pus_17_test import Service17Tm
from spacepackets.ecss.pus_1_verification import UnpackParams, Service1Tm
from tmtccmd import CcsdsTmtcBackend, TcHandlerBase, ProcedureParamsWrapper
from tmtccmd import TcHandlerBase, ProcedureParamsWrapper
from tmtccmd.core.base import BackendRequest
from tmtccmd.core.ccsds_backend import QueueWrapper
from tmtccmd.pus import VerificationWrapper
from tmtccmd.tm import CcsdsTmHandler, SpecificApidHandlerBase
from tmtccmd.com_if import ComInterface
from tmtccmd.tmtc import CcsdsTmHandler, SpecificApidHandlerBase
from tmtccmd.com import ComInterface
from tmtccmd.config import (
CmdTreeNode,
default_json_path,
SetupParams,
TmTcCfgHookBase,
TmtcDefinitionWrapper,
CoreServiceList,
OpCodeEntry,
HookBase,
params_to_procedure_conversion,
)
from tmtccmd.config.com_if import SerialCfgWrapper
from tmtccmd.config.com import SerialCfgWrapper
from tmtccmd.config import PreArgsParsingWrapper, SetupWrapper
from tmtccmd.logging import get_console_logger
from tmtccmd.logging.pus import (
RegularTmtcLogWrapper,
RawTmtcTimedLogWrapper,
TimedLogWhen,
)
from tmtccmd.tc import (
from tmtccmd.tmtc import (
TcQueueEntryType,
ProcedureWrapper,
TcProcedureType,
@ -41,27 +41,28 @@ from tmtccmd.tc import (
SendCbParams,
DefaultPusQueueHelper,
)
from tmtccmd.tm.pus_5_event import Service5Tm
from tmtccmd.pus.s5_fsfw_event import Service5Tm
from tmtccmd.util import FileSeqCountProvider, PusFileSeqCountProvider
from tmtccmd.util.obj_id import ObjectIdDictT
from tmtccmd.util.tmtc_printer import FsfwTmTcPrinter
# from tmtccmd.util.tmtc_printer import FsfwTmTcPrinter
LOGGER = get_console_logger()
_LOGGER = logging.getLogger()
EXAMPLE_PUS_APID = 0x02
class SatRsConfigHook(TmTcCfgHookBase):
class SatRsConfigHook(HookBase):
def __init__(self, json_cfg_path: str):
super().__init__(json_cfg_path=json_cfg_path)
def assign_communication_interface(self, com_if_key: str) -> Optional[ComInterface]:
from tmtccmd.config.com_if import (
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,
@ -76,35 +77,14 @@ class SatRsConfigHook(TmTcCfgHookBase):
cfg.serial_cfg.serial_timeout = 0.5
return create_com_interface_default(cfg)
def get_tmtc_definitions(self) -> TmtcDefinitionWrapper:
from tmtccmd.config.globals import get_default_tmtc_defs
def get_command_definitions(self) -> CmdTreeNode:
"""This function should return the root node of the command definition tree."""
return create_cmd_definition_tree()
defs = get_default_tmtc_defs()
srv_5 = OpCodeEntry()
srv_5.add("0", "Event Test")
defs.add_service(
name=CoreServiceList.SERVICE_5.value,
info="PUS Service 5 Event",
op_code_entry=srv_5,
)
srv_17 = OpCodeEntry()
srv_17.add("0", "Ping Test")
defs.add_service(
name=CoreServiceList.SERVICE_17_ALT,
info="PUS Service 17 Test",
op_code_entry=srv_17,
)
srv_3 = OpCodeEntry()
defs.add_service(
name=CoreServiceList.SERVICE_3,
info="PUS Service 3 Housekeeping",
op_code_entry=srv_3,
)
return defs
def perform_mode_operation(self, tmtc_backend: CcsdsTmtcBackend, mode: int):
LOGGER.info("Mode operation hook was called")
pass
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
@ -112,74 +92,75 @@ class SatRsConfigHook(TmTcCfgHookBase):
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"))
return root_node
class PusHandler(SpecificApidHandlerBase):
def __init__(
self,
file_logger: logging.Logger,
verif_wrapper: VerificationWrapper,
printer: FsfwTmTcPrinter,
raw_logger: RawTmtcTimedLogWrapper,
):
super().__init__(EXAMPLE_PUS_APID, None)
self.printer = printer
self.file_logger = file_logger
self.raw_logger = raw_logger
self.verif_wrapper = verif_wrapper
def handle_tm(self, packet: bytes, _user_args: any):
def handle_tm(self, packet: bytes, _user_args: Any):
time_reader = CdsShortTimestamp.empty()
try:
tm_packet = PusTelemetry.unpack(packet)
pus_tm = PusTelemetry.unpack(packet, time_reader=CdsShortTimestamp.empty())
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}")
_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 = tm_packet.service
dedicated_handler = False
service = pus_tm.service
tm_packet = None
if service == 1:
tm_packet = Service1Tm.unpack(data=packet, params=UnpackParams(1, 2))
tm_packet = Service1Tm.unpack(
data=packet, params=UnpackParams(time_reader, 1, 2)
)
res = self.verif_wrapper.add_tm(tm_packet)
if res is None:
LOGGER.info(
_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(
_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)
dedicated_handler = True
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)
_LOGGER.info("No handling for HK packets implemented")
_LOGGER.info(f"Raw packet: 0x[{packet.hex(sep=',')}]")
pus_tm = PusTelemetry.unpack(packet, CdsShortTimestamp.empty())
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:]
dedicated_handler = True
_LOGGER.info("received JSON string: " + json_str.decode("utf-8"))
if service == 5:
tm_packet = Service5Tm.unpack(packet)
tm_packet = Service5Tm.unpack(packet, time_reader)
if service == 17:
tm_packet = Service17Tm.unpack(packet)
dedicated_handler = True
tm_packet = Service17Tm.unpack(packet, time_reader)
if tm_packet.subservice == 2:
self.printer.file_logger.info("Received Ping Reply TM[17,2]")
LOGGER.info("Received Ping Reply TM[17,2]")
_LOGGER.info("Received Ping Reply TM[17,2]")
else:
self.printer.file_logger.info(
f"Received Test Packet with unknown subservice {tm_packet.subservice}"
)
LOGGER.info(
_LOGGER.info(
f"Received Test Packet with unknown subservice {tm_packet.subservice}"
)
if tm_packet is None:
LOGGER.info(
_LOGGER.info(
f"The service {service} is not implemented in Telemetry Factory"
)
tm_packet = PusTelemetry.unpack(packet)
self.raw_logger.log_tm(tm_packet)
if not dedicated_handler and tm_packet is not None:
self.printer.handle_long_tm_print(packet_if=tm_packet, info_if=tm_packet)
tm_packet = PusTelemetry.unpack(packet, time_reader)
self.raw_logger.log_tm(pus_tm)
def make_addressable_id(target_id: int, unique_id: int) -> bytes:
@ -198,8 +179,11 @@ class TcHandler(TcHandlerBase):
self.seq_count_provider = seq_count_provider
self.verif_wrapper = verif_wrapper
self.queue_helper = DefaultPusQueueHelper(
queue_wrapper=None,
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):
@ -212,31 +196,24 @@ class TcHandler(TcHandlerBase):
)
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}")
_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)
_LOGGER.info(log_entry.log_str)
def queue_finished_cb(self, helper: ProcedureWrapper):
if helper.proc_type == TcProcedureType.DEFAULT:
def_proc = helper.to_def_procedure()
LOGGER.info(
f"Queue handling finished for service {def_proc.service} and "
f"op code {def_proc.op_code}"
)
def queue_finished_cb(self, info: ProcedureWrapper):
if info.proc_type == TcProcedureType.DEFAULT:
def_proc = info.to_def_procedure()
_LOGGER.info(f"Queue handling finished for command {def_proc.cmd_path}")
def feed_cb(self, helper: ProcedureWrapper, wrapper: FeedWrapper):
def feed_cb(self, info: ProcedureWrapper, wrapper: FeedWrapper):
q = self.queue_helper
q.queue_wrapper = wrapper.queue_wrapper
if helper.proc_type == TcProcedureType.DEFAULT:
def_proc = helper.to_def_procedure()
service = def_proc.service
op_code = def_proc.op_code
if (
service == CoreServiceList.SERVICE_17
or service == CoreServiceList.SERVICE_17_ALT
):
if info.proc_type == TcProcedureType.DEFAULT:
def_proc = info.to_def_procedure()
cmd_path = def_proc.cmd_path
if cmd_path == "/ping":
q.add_log_cmd("Sending PUS ping telecommand")
return q.add_pus_tc(PusTelecommand(service=17, subservice=1))
@ -248,25 +225,25 @@ def main():
parser_wrapper.create_default_parent_parser()
parser_wrapper.create_default_parser()
parser_wrapper.add_def_proc_args()
post_args_wrapper = parser_wrapper.parse(hook_obj)
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(params, proc_wrapper)
post_args_wrapper.set_params_without_prompts(proc_wrapper)
else:
post_args_wrapper.set_params_with_prompts(params, proc_wrapper)
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()
printer = FsfwTmTcPrinter(tmtc_logger.logger)
file_logger = tmtc_logger.logger
raw_logger = RawTmtcTimedLogWrapper(when=TimedLogWhen.PER_HOUR, interval=1)
verificator = PusVerificator()
verification_wrapper = VerificationWrapper(verificator, LOGGER, printer.file_logger)
verification_wrapper = VerificationWrapper(verificator, _LOGGER, file_logger)
# Create primary TM handler and add it to the CCSDS Packet Handler
tm_handler = PusHandler(verification_wrapper, printer, raw_logger)
tm_handler = PusHandler(file_logger, verification_wrapper, raw_logger)
ccsds_handler = CcsdsTmHandler(generic_handler=None)
ccsds_handler.add_apid_handler(tm_handler)
@ -288,7 +265,7 @@ def main():
if state.request == BackendRequest.TERMINATION_NO_ERROR:
sys.exit(0)
elif state.request == BackendRequest.DELAY_IDLE:
LOGGER.info("TMTC Client in IDLE mode")
_LOGGER.info("TMTC Client in IDLE mode")
time.sleep(3.0)
elif state.request == BackendRequest.DELAY_LISTENER:
time.sleep(0.8)

View File

@ -1,2 +1,2 @@
tmtccmd == 4.0.0a0
tmtccmd == 8.0.0rc.0
# -e git+https://github.com/robamu-org/tmtccmd.git@main#egg=tmtccmd

View File

@ -4,17 +4,14 @@ extern crate panic_itm;
use rtic::app;
use heapless::{
mpmc::Q16,
pool,
pool::singleton::{Box, Pool},
};
use heapless::{mpmc::Q8, Vec};
#[allow(unused_imports)]
use itm_logger::{debug, info, logger_init, warn};
use satrs_core::spacepackets::{ecss::PusPacket, tm::PusTm};
use satrs_core::{
pus::{EcssTmErrorWithSend, EcssTmSenderCore},
seq_count::SequenceCountProviderCore,
use satrs::seq_count::SequenceCountProviderCore;
use satrs::{
pool::StoreError,
pus::{EcssChannel, EcssTmSenderCore, EcssTmtcError, PusTmWrapper},
spacepackets::{ecss::PusPacket, ecss::WritablePusPacket},
};
use stm32f3xx_hal::dma::dma1;
use stm32f3xx_hal::gpio::{PushPull, AF7, PA2, PA3};
@ -26,8 +23,8 @@ const UART_BAUD: u32 = 115200;
const BLINK_FREQ_MS: u64 = 1000;
const TX_HANDLER_FREQ_MS: u64 = 20;
const MIN_DELAY_BETWEEN_TX_PACKETS_MS: u16 = 5;
const MAX_TC_LEN: usize = 200;
const MAX_TM_LEN: usize = 200;
const MAX_TC_LEN: usize = 128;
const MAX_TM_LEN: usize = 128;
pub const PUS_APID: u16 = 0x02;
type TxType = Tx<USART2, PA2<AF7<PushPull>>>;
@ -51,10 +48,15 @@ static mut DMA_TX_BUF: [u8; TM_BUF_LEN] = [0; TM_BUF_LEN];
// transfer buffer.
static mut DMA_RX_BUF: [u8; TC_BUF_LEN] = [0; TC_BUF_LEN];
static TX_REQUESTS: Q16<(Box<poolmod::TM>, usize)> = Q16::new();
type TmPacket = Vec<u8, MAX_TM_LEN>;
type TcPacket = Vec<u8, MAX_TC_LEN>;
const TC_POOL_SLOTS: usize = 12;
const TM_POOL_SLOTS: usize = 12;
static TM_REQUESTS: Q8<TmPacket> = Q8::new();
const TC_POOL_SLOTS: usize = 8;
const TM_POOL_SLOTS: usize = 8;
use core::cell::RefCell;
use core::sync::atomic::{AtomicU16, Ordering};
pub struct SeqCountProviderAtomicRef {
@ -88,70 +90,56 @@ impl SequenceCountProviderCore<u16> for SeqCountProviderAtomicRef {
static SEQ_COUNT_PROVIDER: SeqCountProviderAtomicRef =
SeqCountProviderAtomicRef::new(Ordering::Relaxed);
// Otherwise, warnings because of heapless pool macro.
#[allow(non_camel_case_types)]
mod poolmod {
use super::*;
// Must hold full TC length including COBS overhead.
pool!(TC: [u8; TC_BUF_LEN]);
// Only encoded at the end, so no need to account for COBS overhead.
pool!(TM: [u8; MAX_TM_LEN]);
}
pub struct TxIdle {
tx: TxType,
dma_channel: dma1::C7,
}
#[derive(Debug)]
pub enum TmStoreError {
StoreFull,
StoreSlotsTooSmall,
}
impl From<TmStoreError> for EcssTmErrorWithSend<TmStoreError> {
fn from(value: TmStoreError) -> Self {
Self::SendError(value)
}
}
pub struct TmSender {
mem_block: Option<Box<poolmod::TM>>,
vec: Option<RefCell<Vec<u8, MAX_TM_LEN>>>,
ctx: &'static str,
}
impl TmSender {
pub fn new(mem_block: Box<poolmod::TM>, ctx: &'static str) -> Self {
pub fn new(tm_packet: TmPacket, ctx: &'static str) -> Self {
Self {
mem_block: Some(mem_block),
vec: Some(RefCell::new(tm_packet)),
ctx,
}
}
}
impl EcssTmSenderCore for TmSender {
type Error = TmStoreError;
impl EcssChannel for TmSender {
fn id(&self) -> satrs::ChannelId {
0
}
}
fn send_tm(
&mut self,
tm: PusTm,
) -> Result<(), satrs_core::pus::EcssTmErrorWithSend<Self::Error>> {
let mem_block = self.mem_block.take();
if mem_block.is_none() {
impl EcssTmSenderCore for TmSender {
fn send_tm(&self, tm: PusTmWrapper) -> Result<(), EcssTmtcError> {
let vec = self.vec.as_ref();
if vec.is_none() {
panic!("send_tm should only be called once");
}
let mut mem_block = mem_block.unwrap();
if tm.len_packed() > MAX_TM_LEN {
return Err(EcssTmErrorWithSend::SendError(
TmStoreError::StoreSlotsTooSmall,
));
let vec_ref = vec.unwrap();
let mut vec = vec_ref.borrow_mut();
match tm {
PusTmWrapper::InStore(addr) => return Err(EcssTmtcError::CantSendAddr(addr)),
PusTmWrapper::Direct(tm) => {
if tm.len_written() > MAX_TM_LEN {
return Err(EcssTmtcError::Store(StoreError::DataTooLarge(
tm.len_written(),
)));
}
vec.resize(tm.len_written(), 0).expect("vec resize failed");
tm.write_to_bytes(vec.as_mut_slice())?;
info!(target: self.ctx, "Sending TM[{},{}] with size {}", tm.service(), tm.subservice(), tm.len_written());
drop(vec);
TM_REQUESTS
.enqueue(vec_ref.take())
.map_err(|_| EcssTmtcError::Store(StoreError::StoreFull(0)))?;
}
}
tm.write_to_bytes(mem_block.as_mut_slice())
.map_err(|e| EcssTmErrorWithSend::EcssTmError(e.into()))?;
info!(target: self.ctx, "Sending TM[{},{}] with size {}", tm.service(), tm.subservice(), tm.len_packed());
TX_REQUESTS
.enqueue((mem_block, tm.len_packed()))
.map_err(|_| TmStoreError::StoreFull)?;
Ok(())
}
}
@ -168,14 +156,11 @@ mod app {
use super::*;
use core::slice::Iter;
use cortex_m::iprintln;
use satrs_core::pus::verification::FailParams;
use satrs_core::pus::verification::VerificationReporterCore;
use satrs_core::spacepackets::{
ecss::EcssEnumU16,
tc::PusTc,
time::cds::P_FIELD_BASE,
tm::{PusTm, PusTmSecondaryHeader},
CcsdsPacket, SpHeader,
use satrs::pus::verification::FailParams;
use satrs::pus::verification::VerificationReporterCore;
use satrs::spacepackets::{
ecss::tc::PusTcReader, ecss::tm::PusTmCreator, ecss::tm::PusTmSecondaryHeader,
ecss::EcssEnumU16, time::cds::P_FIELD_BASE, CcsdsPacket, SpHeader,
};
#[allow(unused_imports)]
use stm32f3_discovery::leds::Direction;
@ -226,9 +211,6 @@ mod app {
"Starting sat-rs demo application for the STM32F3-Discovery"
);
let mut gpioe = cx.device.GPIOE.split(&mut rcc.ahb);
// Assign memory to the pools.
poolmod::TC::grow(cx.local.tc_pool_mem);
poolmod::TM::grow(cx.local.tm_pool_mem);
let verif_reporter = VerificationReporterCore::new(PUS_APID).unwrap();
@ -324,7 +306,7 @@ mod app {
local = []
)]
fn serial_tx_handler(mut cx: serial_tx_handler::Context) {
if let Some((buf, len)) = TX_REQUESTS.dequeue() {
if let Some(vec) = TM_REQUESTS.dequeue() {
cx.shared.tx_transfer.lock(|tx_state| match tx_state {
UartTxState::Idle(tx) => {
//debug!(target: "serial_tx_handler", "bytes: {:x?}", &buf[0..len]);
@ -336,7 +318,7 @@ mod app {
// Should never panic, we accounted for the overhead.
// Write into transfer buffer directly, no need for intermediate
// encoding buffer.
let encoded_len = cobs::encode(&buf[0..len], &mut mut_tx_dma_buf[1..]);
let encoded_len = cobs::encode(&vec[0..vec.len()], &mut mut_tx_dma_buf[1..]);
// 0 end marker
mut_tx_dma_buf[encoded_len + 1] = 0;
//debug!(target: "serial_tx_handler", "Sending {} bytes", encoded_len + 2);
@ -375,14 +357,10 @@ mod app {
verif_reporter
],
)]
fn serial_rx_handler(
cx: serial_rx_handler::Context,
received_packet: Box<poolmod::TC>,
rx_len: usize,
) {
fn serial_rx_handler(cx: serial_rx_handler::Context, received_packet: Vec<u8, MAX_TC_LEN>) {
let tgt: &'static str = "serial_rx_handler";
cx.local.stamp_buf[0] = P_FIELD_BASE;
info!(target: tgt, "Received packet with {} bytes", rx_len);
info!(target: tgt, "Received packet with {} bytes", received_packet.len());
let decode_buf = cx.local.decode_buf;
let packet = received_packet.as_slice();
let mut start_idx = None;
@ -403,7 +381,7 @@ mod app {
match cobs::decode(&received_packet.as_slice()[start_idx..], decode_buf) {
Ok(len) => {
info!(target: tgt, "Decoded packet length: {}", len);
let pus_tc = PusTc::from_bytes(decode_buf);
let pus_tc = PusTcReader::new(decode_buf);
let verif_reporter = cx.local.verif_reporter;
match pus_tc {
Ok((tc, tc_len)) => handle_tc(
@ -429,7 +407,7 @@ mod app {
}
fn handle_tc(
tc: PusTc,
tc: PusTcReader,
tc_len: usize,
verif_reporter: &mut VerificationReporterCore,
src_data_buf: &mut [u8; MAX_TM_LEN],
@ -451,30 +429,25 @@ mod app {
.acceptance_failure(
src_data_buf,
token,
&SEQ_COUNT_PROVIDER,
FailParams::new(stamp_buf, &EcssEnumU16::new(0), None),
SEQ_COUNT_PROVIDER.get(),
0,
FailParams::new(stamp_buf, &EcssEnumU16::new(0), &[]),
)
.unwrap();
let mem_block = poolmod::TM::alloc().unwrap().init([0u8; MAX_TM_LEN]);
let mut sender = TmSender::new(mem_block, tgt);
if let Err(e) =
verif_reporter.send_acceptance_failure(sendable, &SEQ_COUNT_PROVIDER, &mut sender)
{
// let mem_block = poolmod::TM::alloc().unwrap().init([0u8; MAX_TM_LEN]);
let sender = TmSender::new(TmPacket::new(), tgt);
if let Err(e) = verif_reporter.send_acceptance_failure(sendable, &sender) {
warn!(target: tgt, "Sending acceptance failure failed: {:?}", e.0);
};
return;
}
let sendable = verif_reporter
.acceptance_success(src_data_buf, token, &SEQ_COUNT_PROVIDER, stamp_buf)
.acceptance_success(src_data_buf, token, SEQ_COUNT_PROVIDER.get(), 0, stamp_buf)
.unwrap();
let mem_block = poolmod::TM::alloc().unwrap().init([0u8; MAX_TM_LEN]);
let mut sender = TmSender::new(mem_block, tgt);
let accepted_token = match verif_reporter.send_acceptance_success(
sendable,
&SEQ_COUNT_PROVIDER,
&mut sender,
) {
// let mem_block = poolmod::TM::alloc().unwrap().init([0u8; MAX_TM_LEN]);
let sender = TmSender::new(TmPacket::new(), tgt);
let accepted_token = match verif_reporter.send_acceptance_success(sendable, &sender) {
Ok(token) => token,
Err(e) => {
warn!(target: "serial_rx_handler", "Sending acceptance success failed: {:?}", e.0);
@ -485,15 +458,17 @@ mod app {
if tc.service() == 17 {
if tc.subservice() == 1 {
let sendable = verif_reporter
.start_success(src_data_buf, accepted_token, &SEQ_COUNT_PROVIDER, stamp_buf)
.start_success(
src_data_buf,
accepted_token,
SEQ_COUNT_PROVIDER.get(),
0,
stamp_buf,
)
.unwrap();
let mem_block = poolmod::TM::alloc().unwrap().init([0u8; MAX_TM_LEN]);
let mut sender = TmSender::new(mem_block, tgt);
let started_token = match verif_reporter.send_start_success(
sendable,
&SEQ_COUNT_PROVIDER,
&mut sender,
) {
// let mem_block = poolmod::TM::alloc().unwrap().init([0u8; MAX_TM_LEN]);
let sender = TmSender::new(TmPacket::new(), tgt);
let started_token = match verif_reporter.send_start_success(sendable, &sender) {
Ok(token) => token,
Err(e) => {
warn!(target: tgt, "Sending acceptance success failed: {:?}", e.0);
@ -507,24 +482,28 @@ mod app {
let mut sp_header =
SpHeader::tc_unseg(PUS_APID, SEQ_COUNT_PROVIDER.get(), 0).unwrap();
let sec_header = PusTmSecondaryHeader::new_simple(17, 2, stamp_buf);
let ping_reply = PusTm::new(&mut sp_header, sec_header, None, true);
let mut mem_block = poolmod::TM::alloc().unwrap().init([0u8; MAX_TM_LEN]);
let reply_len = ping_reply.write_to_bytes(mem_block.as_mut_slice()).unwrap();
if TX_REQUESTS.enqueue((mem_block, reply_len)).is_err() {
let ping_reply = PusTmCreator::new(&mut sp_header, sec_header, &[], true);
let mut tm_packet = TmPacket::new();
tm_packet.resize(ping_reply.len_written(), 0)
.expect("vec resize failed");
ping_reply.write_to_bytes(&mut tm_packet).unwrap();
if TM_REQUESTS.enqueue(tm_packet).is_err() {
warn!(target: tgt, "TC queue full");
return;
}
SEQ_COUNT_PROVIDER.increment();
let sendable = verif_reporter
.completion_success(src_data_buf, started_token, &SEQ_COUNT_PROVIDER, stamp_buf)
.completion_success(
src_data_buf,
started_token,
SEQ_COUNT_PROVIDER.get(),
0,
stamp_buf,
)
.unwrap();
let mem_block = poolmod::TM::alloc().unwrap().init([0u8; MAX_TM_LEN]);
let mut sender = TmSender::new(mem_block, tgt);
if let Err(e) = verif_reporter.send_step_or_completion_success(
sendable,
&SEQ_COUNT_PROVIDER,
&mut sender,
) {
// let mem_block = poolmod::TM::alloc().unwrap().init([0u8; MAX_TM_LEN]);
let sender = TmSender::new(TmPacket::new(), tgt);
if let Err(e) = verif_reporter.send_step_or_completion_success(sendable, &sender) {
warn!(target: tgt, "Sending completion success failed: {:?}", e.0);
}
} else {
@ -541,17 +520,17 @@ mod app {
let uart_rx_owned = rx_transfer.take().unwrap();
let (buf, c, rx) = uart_rx_owned.stop();
// The received data is transferred to another task now to avoid any processing overhead
// during the interrupt. There are multiple ways to do this, we use a memory pool here
// during the interrupt. There are multiple ways to do this, we use a stack allocaed vector here
// to do this.
let mut mem_block = poolmod::TC::alloc()
.expect("allocating memory block for rx failed")
.init([0u8; TC_BUF_LEN]);
// Copy data into memory pool.
mem_block.copy_from_slice(buf);
let mut tc_packet = TcPacket::new();
tc_packet.resize(buf.len(), 0).expect("vec resize failed");
tc_packet.copy_from_slice(buf);
// Start the next transfer as soon as possible.
*rx_transfer = Some(rx.read_exact(buf, c));
// Only send owning pointer to pool memory and the received packet length.
serial_rx_handler::spawn(mem_block, TC_BUF_LEN)
.expect("spawning rx handler task failed");
// Send the vector to a regular task.
serial_rx_handler::spawn(tc_packet).expect("spawning rx handler task failed");
// If this happens, there is a high chance that the maximum packet length was
// exceeded. Circular mode is not used here, so data might be missed.
warn!(
@ -586,17 +565,16 @@ mod app {
let rx_transfer_owned = rx_transfer.take().unwrap();
let (buf, ch, mut rx, rx_len) = rx_transfer_owned.stop_and_return_received_bytes();
// The received data is transferred to another task now to avoid any processing overhead
// during the interrupt. There are multiple ways to do this, we use a memory pool here
// to do this.
let mut mem_block = poolmod::TC::alloc()
.expect("allocating memory block for rx failed")
.init([0u8; TC_BUF_LEN]);
// Copy data into memory pool.
mem_block[0..rx_len as usize].copy_from_slice(&buf[0..rx_len as usize]);
// during the interrupt. There are multiple ways to do this, we use a stack
// allocated vector to do this.
let mut tc_packet = TcPacket::new();
tc_packet
.resize(rx_len as usize, 0)
.expect("vec resize failed");
tc_packet[0..rx_len as usize].copy_from_slice(&buf[0..rx_len as usize]);
rx.clear_event(RxEvent::Idle);
// Only send owning pointer to pool memory and the received packet length.
serial_rx_handler::spawn(mem_block, rx_len as usize)
.expect("spawning rx handler task failed");
serial_rx_handler::spawn(tc_packet).expect("spawning rx handler task failed");
*rx_transfer = Some(rx.read_exact(buf, ch));
}
});

View File

@ -11,7 +11,8 @@ proc CDSWOConfigure { CDCPUFreqHz CDSWOFreqHz CDSWOOutput } {
# Alternative option: Pipe ITM output into itm.txt file
# tpiu config internal itm.txt uart off $CDCPUFreqHz
# Default option so SWO display of VS code works.
# Default option so SWO display of VS code works. Please note that this might not be required
# anymore starting at openocd v0.12.0
tpiu config internal $CDSWOOutput uart off $CDCPUFreqHz $CDSWOFreqHz
itm port 0 on
}