diff --git a/.vscode/launch.json b/.vscode/launch.json index bf7252e..cfe380f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,6 +12,9 @@ "type": "cortex-debug", "preLaunchTask": "cargo build", "servertype": "openocd", + "preLaunchCommands": [ + "monitor arm semihosting enable", + ], "svdFile": "${workspaceFolder}/bluepill-rs/STM32F103.svd", "configFiles": [ "interface/stlink.cfg", diff --git a/bluepill-rs/Cargo.lock b/bluepill-rs/Cargo.lock index f7102d9..1e37b98 100644 --- a/bluepill-rs/Cargo.lock +++ b/bluepill-rs/Cargo.lock @@ -51,13 +51,12 @@ dependencies = [ "cortex-m", "cortex-m-rt", "cortex-m-rtic", - "defmt", - "defmt-ringbuf", - "defmt-rtt", + "cortex-m-semihosting", "embedded-hal 1.0.0", "heapless 0.8.0", "nb 1.1.0", "panic-halt", + "panic-semihosting", "stm32f1", "stm32f1xx-hal", "systick-monotonic", @@ -111,7 +110,7 @@ checksum = "f0f6f3e36f203cfedbc78b357fb28730aa2c6dc1ab060ee5c2405e843988d3c7" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -139,7 +138,16 @@ dependencies = [ "proc-macro2", "quote", "rtic-syntax", - "syn 1.0.109", + "syn", +] + +[[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]] @@ -148,57 +156,6 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" -[[package]] -name = "defmt" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3939552907426de152b3c2c6f51ed53f98f448babd26f28694c95f5906194595" -dependencies = [ - "bitflags", - "defmt-macros", -] - -[[package]] -name = "defmt-macros" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18bdc7a7b92ac413e19e95240e75d3a73a8d8e78aa24a594c22cbb4d44b4bbda" -dependencies = [ - "defmt-parser", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[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-ringbuf" -version = "0.2.0" -dependencies = [ - "cortex-m", - "critical-section", - "defmt", -] - -[[package]] -name = "defmt-rtt" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "609923761264dd99ed9c7d209718cda4631c5fe84668e0f0960124cbb844c49f" -dependencies = [ - "critical-section", - "defmt", -] - [[package]] name = "embedded-dma" version = "0.2.0" @@ -337,6 +294,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812" +[[package]] +name = "panic-semihosting" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee8a3e1233d9073d76a870223512ce4eeea43c067a94a445c13bd6d792d7b1ab" +dependencies = [ + "cortex-m", + "cortex-m-semihosting", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -346,7 +313,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn 1.0.109", + "syn", "version_check", ] @@ -400,7 +367,7 @@ dependencies = [ "indexmap", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -517,17 +484,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "syn" -version = "2.0.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "systick-monotonic" version = "1.0.1" @@ -539,26 +495,6 @@ dependencies = [ "rtic-monotonic", ] -[[package]] -name = "thiserror" -version = "1.0.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - [[package]] name = "unicode-ident" version = "1.0.12" diff --git a/bluepill-rs/Cargo.toml b/bluepill-rs/Cargo.toml index 7d5892d..5e5d683 100644 --- a/bluepill-rs/Cargo.toml +++ b/bluepill-rs/Cargo.toml @@ -6,8 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -defmt-ringbuf = { path = "../defmt-ringbuf", optional = true } - +# main deps embedded-hal = "1.0.0" stm32f1 = { version = "0.15", features = ["stm32f103", "rt"] } stm32f1xx-hal = { version = "0.10.0", features = ["rt", "stm32f103", "medium"] } @@ -17,9 +16,10 @@ cortex-m-rt = { version = "0.7.1", features = ["device"] } cortex-m-rtic = "1.1.4" systick-monotonic = "1.0.1" -defmt = { version = "0.3", features = ["encoding-rzcobs"] } -defmt-rtt = { version = "0.4", optional = true } +# i2c_slave deps heapless = "0.8.0" # Panic behaviour, see https://crates.io/keywords/panic-impl for alternatives +cortex-m-semihosting = "0.5.0" panic-halt = "0.2.0" +panic-semihosting = "0.6.0" diff --git a/bluepill-rs/src/i2c_reg_slave.rs b/bluepill-rs/src/i2c_reg_slave.rs index 20cfe00..f6592e5 100644 --- a/bluepill-rs/src/i2c_reg_slave.rs +++ b/bluepill-rs/src/i2c_reg_slave.rs @@ -99,7 +99,7 @@ where self.pos = 0; return Ok(Event::Read { reg: self.reg }); } - _ => defmt::unreachable!(), + _ => unreachable!(), }, State::ReceiveReg => match self.i2c_event()? { I2cEvent::Read(value) => { @@ -107,7 +107,7 @@ where self.state = State::ReceivedReg; } I2cEvent::End | I2cEvent::Restart => self.state = State::Idle, - _ => defmt::unreachable!(), + _ => unreachable!(), }, State::ReceivedReg => match self.i2c_event()? { I2cEvent::Read(value) => { @@ -128,7 +128,7 @@ where }); } I2cEvent::Restart => self.state = State::Idle, - _ => defmt::unreachable!(), + _ => unreachable!(), }, State::Receiving => match self.i2c_event()? { I2cEvent::Read(value) => { @@ -143,10 +143,10 @@ where self.state = State::Idle; return Ok(Event::Write { reg: self.reg, - value: Value(defmt::unwrap!(Vec::try_from(&self.buf[..self.pos]))), + value: Value(Vec::try_from(&self.buf[..self.pos]).unwrap()), }); } - _ => defmt::unreachable!(), + _ => unreachable!(), }, State::StartSend => return Ok(Event::Read { reg: self.reg }), State::Sending => { @@ -157,7 +157,7 @@ where self.pos += 1; } I2cEvent::End | I2cEvent::Restart => self.state = State::Idle, - _ => defmt::unreachable!(), + _ => unreachable!(), } } State::Clear => match self.i2c_event()? { @@ -179,7 +179,7 @@ where self.pos = 0; self.state = State::Sending; } else { - defmt::panic!("I2C register slave had no read register event") + panic!("I2C register slave had no read register event") } } } @@ -284,8 +284,8 @@ impl Response { /// /// The length of the value must not exceed `BUFFER`. pub fn set(value: &[u8]) -> Self { - defmt::assert!(value.len() <= BUFFER); - Self(defmt::unwrap!(value.try_into())) + assert!(value.len() <= BUFFER); + Self(value.try_into().unwrap()) } /// Provides an empty register value which will read as all zeros. diff --git a/bluepill-rs/src/i2c_slave.rs b/bluepill-rs/src/i2c_slave.rs index b7f2f4b..3ca2167 100644 --- a/bluepill-rs/src/i2c_slave.rs +++ b/bluepill-rs/src/i2c_slave.rs @@ -199,7 +199,7 @@ where Err(nb::Error::WouldBlock) } } - State::WriteWaiting => defmt::panic!("write event was not handled"), + State::WriteWaiting => panic!("write event was not handled"), State::Receiving => { if sr1.rx_ne().is_not_empty() { let value = self.i2c.dr.read().dr().bits(); diff --git a/bluepill-rs/src/main.rs b/bluepill-rs/src/main.rs index 957221b..e97ac21 100644 --- a/bluepill-rs/src/main.rs +++ b/bluepill-rs/src/main.rs @@ -5,7 +5,8 @@ mod i2c_reg_slave; mod i2c_slave; -use panic_halt as _; +// extern crate panic_halt; +extern crate panic_semihosting; #[rtic::app(device = stm32f1::stm32f103, peripherals = true)] mod app { diff --git a/defmt-ringbuf/Cargo.lock b/defmt-ringbuf/Cargo.lock deleted file mode 100644 index 81871ac..0000000 --- a/defmt-ringbuf/Cargo.lock +++ /dev/null @@ -1,248 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "bare-metal" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" -dependencies = [ - "rustc_version", -] - -[[package]] -name = "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 = "cortex-m" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" -dependencies = [ - "bare-metal", - "bitfield", - "embedded-hal", - "volatile-register", -] - -[[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.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3939552907426de152b3c2c6f51ed53f98f448babd26f28694c95f5906194595" -dependencies = [ - "bitflags", - "defmt-macros", -] - -[[package]] -name = "defmt-macros" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18bdc7a7b92ac413e19e95240e75d3a73a8d8e78aa24a594c22cbb4d44b4bbda" -dependencies = [ - "defmt-parser", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[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-ringbuf" -version = "0.2.0" -dependencies = [ - "cortex-m", - "critical-section", - "defmt", -] - -[[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 = "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 = "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.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver", -] - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "thiserror" -version = "1.0.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[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", -] diff --git a/defmt-ringbuf/Cargo.toml b/defmt-ringbuf/Cargo.toml deleted file mode 100644 index fe5883f..0000000 --- a/defmt-ringbuf/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "defmt-ringbuf" -description = "defmt persistent ring buffer logger" -authors = ["Sebastian Urban "] -categories = ["embedded", "no-std"] -keywords = ["defmt", "defmt-transport"] -readme = "README.md" -repository = "https://github.com/surban/openemc" -license = "MIT OR Apache-2.0" -version = "0.2.0" -edition = "2021" - -[features] -default = ["logger"] -logger = [] - -[dependencies] -defmt = "0.3" -critical-section = "1" -cortex-m = "0.7" diff --git a/defmt-ringbuf/LICENSE-APACHE b/defmt-ringbuf/LICENSE-APACHE deleted file mode 100644 index 11069ed..0000000 --- a/defmt-ringbuf/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - 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. diff --git a/defmt-ringbuf/LICENSE-MIT b/defmt-ringbuf/LICENSE-MIT deleted file mode 100644 index 468cd79..0000000 --- a/defmt-ringbuf/LICENSE-MIT +++ /dev/null @@ -1,23 +0,0 @@ -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/defmt-ringbuf/README.md b/defmt-ringbuf/README.md deleted file mode 100644 index 85dfa8d..0000000 --- a/defmt-ringbuf/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# defmt-ringbuf - -This crate stores [`defmt`] log messages in a simple ring buffer that is persisted across resets. -You still need to read the messages from the buffer and transfer them to a host for formatting. - -[`defmt`]: https://github.com/knurling-rs/defmt - -## License - -Licensed under either of - -- [Apache License, Version 2.0](LICENSE-APACHE) -- [MIT license](LICENSE-MIT) - -at your option. - -## Contribution - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in defmt-ringbuf by you shall be licensed as above, -without any additional terms or conditions. diff --git a/defmt-ringbuf/defmt-ringbuf-test/.cargo/config.toml b/defmt-ringbuf/defmt-ringbuf-test/.cargo/config.toml deleted file mode 100644 index 9b8ae16..0000000 --- a/defmt-ringbuf/defmt-ringbuf-test/.cargo/config.toml +++ /dev/null @@ -1,10 +0,0 @@ -[build] -target = "thumbv7m-none-eabi" -rustflags = [ - "-C", "link-arg=-Tlink.x", - "-C", "link-arg=--nmagic", - "-C", "link-arg=-Tdefmt.x", -] - -[target.'cfg(all(target_arch = "arm", target_os = "none"))'] -runner = "probe-run --chip STM32F103RB" diff --git a/defmt-ringbuf/defmt-ringbuf-test/Cargo.toml b/defmt-ringbuf/defmt-ringbuf-test/Cargo.toml deleted file mode 100644 index 3499dfd..0000000 --- a/defmt-ringbuf/defmt-ringbuf-test/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "defmt-ringbuf-test" -authors = ["Sebastian Urban "] -license = "GPL-3.0" -version = "0.0.0" -publish = false -edition = "2021" - -[dependencies] -defmt-ringbuf = { path = "..", default-features = false } - -cortex-m = { version = "0.7", features = ["critical-section-single-core"] } -cortex-m-rt = { version = "0.7", features = ["device"] } -stm32f1 = { version = "0.15", features = ["stm32f103", "rt"] } -panic-probe = "0.3" -defmt = "0.3" -defmt-rtt = "0.4" - -[profile.release] -opt-level = 'z' -lto = true -debug = 2 diff --git a/defmt-ringbuf/defmt-ringbuf-test/memory.x b/defmt-ringbuf/defmt-ringbuf-test/memory.x deleted file mode 100644 index 74e34b8..0000000 --- a/defmt-ringbuf/defmt-ringbuf-test/memory.x +++ /dev/null @@ -1,5 +0,0 @@ -MEMORY -{ - FLASH : ORIGIN = 0x08000000, LENGTH = 64K - RAM : ORIGIN = 0x20000000, LENGTH = 20K -} \ No newline at end of file diff --git a/defmt-ringbuf/defmt-ringbuf-test/src/main.rs b/defmt-ringbuf/defmt-ringbuf-test/src/main.rs deleted file mode 100644 index 099bc27..0000000 --- a/defmt-ringbuf/defmt-ringbuf-test/src/main.rs +++ /dev/null @@ -1,42 +0,0 @@ -#![no_std] -#![no_main] - -use core::mem; -use cortex_m::{asm::nop, peripheral::SCB}; -use cortex_m_rt::entry; - -use defmt_ringbuf::{RingBuf, RingBuffer}; -use defmt_rtt as _; -use panic_probe as _; -use stm32f1::stm32f103::Peripherals; - -#[no_mangle] -#[used] -#[link_section = ".uninit.BUFFER"] -pub static mut BUFFER: mem::MaybeUninit> = mem::MaybeUninit::uninit(); - -#[entry] -fn main() -> ! { - let _dp = Peripherals::take().unwrap(); - - defmt::info!("Init"); - let buffer = unsafe { RingBuffer::init(&mut BUFFER) }; - - let mut data = [0; 128]; - let (n, lost) = buffer.read(&mut data); - let data = &data[..n]; - defmt::info!("Buffer contents (lost={}): {}", lost, data); - - let mut data = [0; 255]; - for (i, d) in data.iter_mut().enumerate() { - *d = i as u8; - } - buffer.write(&data); - defmt::info!("Wrote {} bytes to buffer", data.len()); - - defmt::info!("Done"); - for _ in 0..1_000_000 { - nop(); - } - SCB::sys_reset(); -} diff --git a/defmt-ringbuf/src/lib.rs b/defmt-ringbuf/src/lib.rs deleted file mode 100644 index 5fcf850..0000000 --- a/defmt-ringbuf/src/lib.rs +++ /dev/null @@ -1,140 +0,0 @@ -//! defmt-ringbuf is a [`defmt`](https://github.com/knurling-rs/defmt) global logger that logs into -//! a persistent ring buffer. -//! -//! The ring buffer is not cleared at startup, i.e. if placed in a static global variable log messages -//! will still be available after a reset. -//! -//! To use this crate, link to it by importing it somewhere in your project. -//! -//! ``` -//! use core::mem::MaybeUninit; -//! use defmt_ringbuf as _; -//! -//! static mut LOG: MaybeUninit> = MaybeUninit::uninit(); -//! -//! #[entry] -//! fn main() -> ! { -//! unsafe { -//! defmt_ringbuf::init(&mut LOG, || ()); -//! } -//! -//! // ... -//! } -//! ``` -//! -//! Call [init] to initialize logging and [read] to read buffered log data. -//! -//! # Critical section implementation -//! -//! This crate uses [`critical-section`](https://github.com/rust-embedded/critical-section) to ensure only one thread -//! is writing to the buffer at a time. You must import a crate that provides a `critical-section` implementation -//! suitable for the current target. See the `critical-section` README for details. -//! -//! For example, for single-core privileged-mode Cortex-M targets, you can add the following to your Cargo.toml. -//! -//! ```toml -//! [dependencies] -//! cortex-m = { version = "0.7.6", features = ["critical-section-single-core"]} -//! ``` - -#![no_std] - -use core::{ - mem::MaybeUninit, - sync::atomic::{AtomicBool, Ordering}, -}; - -mod ring_buffer; - -pub use ring_buffer::{RingBuf, RingBuffer}; - -#[cfg_attr(feature = "logger", defmt::global_logger)] -struct Logger; - -/// Global logger lock. -static TAKEN: AtomicBool = AtomicBool::new(false); - -/// Crticial section. -static mut CS_RESTORE: critical_section::RestoreState = critical_section::RestoreState::invalid(); - -/// Encoder. -static mut ENCODER: defmt::Encoder = defmt::Encoder::new(); - -/// Ring buffer. -static mut RING_BUFFER: Option<&'static mut dyn RingBuf> = None; - -/// Callback when new log data is available. -static mut LOG_AVAILABLE: fn() = || (); - -unsafe impl defmt::Logger for Logger { - fn acquire() { - let restore = unsafe { critical_section::acquire() }; - if TAKEN.load(Ordering::Relaxed) { - panic!("defmt logger taken reentrantly") - } - TAKEN.store(true, Ordering::Relaxed); - unsafe { CS_RESTORE = restore }; - - unsafe { ENCODER.start_frame(do_write) } - } - - unsafe fn flush() { - // Flush is a no-op. - } - - unsafe fn release() { - ENCODER.end_frame(do_write); - - TAKEN.store(false, Ordering::Relaxed); - let restore = CS_RESTORE; - critical_section::release(restore); - } - - unsafe fn write(bytes: &[u8]) { - ENCODER.write(bytes, do_write); - } -} - -fn do_write(data: &[u8]) { - unsafe { - if let Some(buffer) = RING_BUFFER.as_mut() { - buffer.write(data); - LOG_AVAILABLE(); - } - } -} - -/// Initializes logging to a ring buffer. -/// -/// `ring_buffer` specifies the location of the log buffer. -/// It is not cleared if it contains vailid data from the previous boot. -/// -/// `log_available` is called when new log messages are available. -/// -/// This must be called exactly once. -/// Log messages received before initiailization are discarded. -pub unsafe fn init( - ring_buffer: &'static mut MaybeUninit>, - log_available: fn(), -) { - defmt::assert!(RING_BUFFER.is_none()); - - let ring_buffer = RingBuffer::init(ring_buffer); - RING_BUFFER = Some(ring_buffer as &mut dyn RingBuf); - LOG_AVAILABLE = log_available; -} - -/// Reads and removes data from the log buffer. -/// -/// Returns the number of bytes read and whether data was lost. -pub fn read(data: &mut [u8]) -> (usize, bool) { - unsafe { - critical_section::with(|_cs| { - if let Some(buffer) = RING_BUFFER.as_mut() { - buffer.read(data) - } else { - (0, false) - } - }) - } -} diff --git a/defmt-ringbuf/src/ring_buffer.rs b/defmt-ringbuf/src/ring_buffer.rs deleted file mode 100644 index 5059c40..0000000 --- a/defmt-ringbuf/src/ring_buffer.rs +++ /dev/null @@ -1,155 +0,0 @@ -//! Ring buffer. - -use core::{ - mem::MaybeUninit, - ptr::{addr_of, addr_of_mut}, - sync::atomic::{AtomicBool, AtomicU32, AtomicU8, AtomicUsize, Ordering}, -}; - -use cortex_m::Peripherals; - -/// Ring buffer access methods. -pub trait RingBuf { - /// Write into the ring buffer. - fn write(&mut self, data: &[u8]); - - /// Read from the ring buffer. - /// - /// Returns the number of bytes read and whether data was lost. - fn read(&mut self, data: &mut [u8]) -> (usize, bool); -} - -/// Ring buffer. -#[repr(C)] -pub struct RingBuffer { - /// Signature for validity check. - signature: AtomicU32, - /// Read position. - read_pos: AtomicUsize, - /// Write position. - write_pos: AtomicUsize, - /// Unread data overwritten? - overwritten: AtomicBool, - /// Buffer. - buf: [AtomicU8; SIZE], -} - -impl RingBuffer { - /// Signature for validity check. - const SIGNATURE: u32 = 0xb0ffe300; - - /// Initializes the ring buffer, keeping its data if it appears valid. - pub fn init(uninit: &mut MaybeUninit) -> &mut Self { - unsafe { - let mut scb = Peripherals::steal().SCB; - let ptr = uninit.as_mut_ptr(); - - let signature = (addr_of!((*ptr).signature) as *const u32).read_volatile(); - let mut read_pos = (addr_of!((*ptr).read_pos) as *const usize).read_volatile(); - let mut write_pos = (addr_of!((*ptr).write_pos) as *const usize).read_volatile(); - let mut overwritten = (addr_of!((*ptr).overwritten) as *const u8).read_volatile(); - - let valid = signature == Self::SIGNATURE - && read_pos < SIZE - && write_pos < SIZE - && (overwritten == 0 || overwritten == 1); - - if !valid { - addr_of_mut!((*ptr).signature).write_volatile(AtomicU32::new(0)); - scb.clean_dcache_by_ref(&(*ptr).signature); - - read_pos = 0; - write_pos = 0; - overwritten = 0; - } - - for i in 0..SIZE { - let b = if valid { (addr_of!((*ptr).buf[i]) as *const u8).read_volatile() } else { 0 }; - addr_of_mut!((*ptr).buf[i]).write_volatile(AtomicU8::new(b)); - } - scb.clean_dcache_by_slice(&(*ptr).buf); - - addr_of_mut!((*ptr).read_pos).write_volatile(AtomicUsize::new(read_pos)); - scb.clean_dcache_by_ref(&(*ptr).read_pos); - addr_of_mut!((*ptr).write_pos).write_volatile(AtomicUsize::new(write_pos)); - scb.clean_dcache_by_ref(&(*ptr).write_pos); - addr_of_mut!((*ptr).overwritten).write_volatile(AtomicBool::new(overwritten != 0)); - scb.clean_dcache_by_ref(&(*ptr).overwritten); - addr_of_mut!((*ptr).signature).write_volatile(AtomicU32::new(Self::SIGNATURE)); - scb.clean_dcache_by_ref(&(*ptr).signature); - - // SAFETY: all fields have been initialized with either default values or their previous contents. - uninit.assume_init_mut() - } - } -} - -impl RingBuf for RingBuffer { - fn write(&mut self, mut data: &[u8]) { - let mut scb = unsafe { Peripherals::steal().SCB }; - - while !data.is_empty() { - // Split data into part that fits remaining buffer. - let write_pos = self.write_pos.load(Ordering::SeqCst); - let to_end = SIZE - write_pos; - let (part, rest) = data.split_at(to_end.min(data.len())); - data = rest; - - // Calculate write boundaries. - let from = write_pos; - let to = write_pos + part.len(); - - // Update read position if we overwrite unread data. - let read_pos = self.read_pos.load(Ordering::SeqCst); - if from < read_pos && to >= read_pos { - self.overwritten.store(true, Ordering::SeqCst); - - let mut new_read_pos = to + 1; - if new_read_pos >= SIZE { - new_read_pos = 0; - } - self.read_pos.store(new_read_pos, Ordering::SeqCst); - scb.clean_dcache_by_ref(&self.read_pos); - } - - // Copy. - for (dst, src) in self.buf[from..to].iter_mut().zip(part.iter()) { - dst.store(*src, Ordering::SeqCst); - } - scb.clean_dcache_by_slice(&self.buf[from..to]); - - // Update write position. - let new_write_pos = if to == SIZE { 0 } else { to }; - self.write_pos.store(new_write_pos, Ordering::SeqCst); - scb.clean_dcache_by_ref(&self.write_pos); - } - } - - fn read(&mut self, data: &mut [u8]) -> (usize, bool) { - let mut scb = unsafe { Peripherals::steal().SCB }; - - let read_pos = self.read_pos.load(Ordering::SeqCst); - let write_pos = self.write_pos.load(Ordering::SeqCst); - let overwritten = self.overwritten.load(Ordering::SeqCst); - - // Calculate available data. - let avail = if read_pos > write_pos { SIZE - read_pos } else { write_pos - read_pos }; - let n = avail.min(data.len()); - - // Copy. - let from = read_pos; - let to = read_pos + n; - for (dst, src) in data[..n].iter_mut().zip(self.buf[from..to].iter()) { - *dst = src.load(Ordering::SeqCst); - } - - // Update read position and overwritten status. - let new_read_pos = if to == SIZE { 0 } else { to }; - self.read_pos.store(new_read_pos, Ordering::SeqCst); - scb.clean_dcache_by_ref(&self.read_pos); - self.overwritten.store(false, Ordering::SeqCst); - scb.clean_dcache_by_ref(&self.overwritten); - - (n, overwritten) - } -}