mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-27 12:20:56 +00:00
Backtrace tweaks (#4012)
* Disallow multiple halt methods * Warn for nonsense config * Use DRAM range from metadata
This commit is contained in:
parent
af1956d477
commit
55d8228987
@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- `exception-handler` now panics. (#3838)
|
||||
- Only halt cores in panics when `halt-cores` feature is enabled. (#4010)
|
||||
- It is no longer possible to select multiple halt method features (`halt-cores`, `custom-halt`, `semihosting`) (#4012)
|
||||
|
||||
### Fixed
|
||||
|
||||
|
@ -23,6 +23,7 @@ cfg-if = "1.0.0"
|
||||
critical-section = "1.1.2"
|
||||
defmt = { version = "1", optional = true }
|
||||
esp-config = { version = "0.5.0", path = "../esp-config" }
|
||||
esp-metadata-generated = { version = "0.1.0", path = "../esp-metadata-generated" }
|
||||
esp-println = { version = "0.15.0", optional = true, default-features = false, path = "../esp-println" }
|
||||
heapless = "0.8"
|
||||
semihosting = { version = "0.1.20", optional = true }
|
||||
@ -34,13 +35,13 @@ esp-config = { version = "0.5.0", path = "../esp-config", features = ["build"]
|
||||
[features]
|
||||
default = ["colors"]
|
||||
|
||||
esp32 = ["esp-println?/esp32", "semihosting?/openocd-semihosting", "print-float-registers"]
|
||||
esp32c2 = ["esp-println?/esp32c2"]
|
||||
esp32c3 = ["esp-println?/esp32c3"]
|
||||
esp32c6 = ["esp-println?/esp32c6"]
|
||||
esp32h2 = ["esp-println?/esp32h2"]
|
||||
esp32s2 = ["esp-println?/esp32s2", "semihosting?/openocd-semihosting"]
|
||||
esp32s3 = ["esp-println?/esp32s3", "semihosting?/openocd-semihosting", "print-float-registers"]
|
||||
esp32 = ["esp-println?/esp32", "esp-metadata-generated/esp32", "semihosting?/openocd-semihosting", "print-float-registers"]
|
||||
esp32c2 = ["esp-println?/esp32c2", "esp-metadata-generated/esp32c2"]
|
||||
esp32c3 = ["esp-println?/esp32c3", "esp-metadata-generated/esp32c3"]
|
||||
esp32c6 = ["esp-println?/esp32c6", "esp-metadata-generated/esp32c6"]
|
||||
esp32h2 = ["esp-println?/esp32h2", "esp-metadata-generated/esp32h2"]
|
||||
esp32s2 = ["esp-println?/esp32s2", "esp-metadata-generated/esp32s2", "semihosting?/openocd-semihosting"]
|
||||
esp32s3 = ["esp-println?/esp32s3", "esp-metadata-generated/esp32s3", "semihosting?/openocd-semihosting", "print-float-registers"]
|
||||
|
||||
## Use `esp-println`
|
||||
println = ["dep:esp-println"]
|
||||
@ -60,6 +61,8 @@ custom-halt = []
|
||||
custom-pre-backtrace = []
|
||||
## Halt both CPUs on ESP32 / ESP32-S3 instead of doing a `loop {}` in case of a panic
|
||||
halt-cores = []
|
||||
## Exit with a semihosting call in case of a panic
|
||||
semihosting = ["dep:semihosting"]
|
||||
## Include a panic handler
|
||||
panic-handler = []
|
||||
|
||||
|
@ -1,5 +1,16 @@
|
||||
use esp_config::generate_config_from_yaml_definition;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! assert_unique_features {
|
||||
($($feature:literal),+ $(,)?) => {
|
||||
assert!(
|
||||
(0 $(+ cfg!(feature = $feature) as usize)+ ) <= 1,
|
||||
"At most one of the following features must be enabled: {}",
|
||||
[$($feature),+].join(", ")
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! assert_unique_used_features {
|
||||
($($feature:literal),+ $(,)?) => {
|
||||
@ -15,8 +26,17 @@ fn main() {
|
||||
// Ensure that exactly a backend is selected:
|
||||
assert_unique_used_features!("defmt", "println");
|
||||
|
||||
if cfg!(feature = "custom-halt") && cfg!(feature = "halt-cores") {
|
||||
panic!("Only one of `custom-halt` and `halt-cores` can be enabled");
|
||||
// Ensure that there aren't multiple halt methods selected:
|
||||
assert_unique_features!("custom-halt", "halt-cores", "semihosting");
|
||||
|
||||
if !cfg!(feature = "panic-handler")
|
||||
&& cfg!(any(
|
||||
feature = "custom-halt",
|
||||
feature = "halt-cores",
|
||||
feature = "semihosting"
|
||||
))
|
||||
{
|
||||
print_warning("A halt method is selected, but esp-backtrace is not the panic handler.")
|
||||
}
|
||||
|
||||
// emit config
|
||||
@ -25,3 +45,7 @@ fn main() {
|
||||
.expect("Failed to read esp_config.yml for esp-backtrace");
|
||||
generate_config_from_yaml_definition(&cfg_yaml, true, true, None).unwrap();
|
||||
}
|
||||
|
||||
fn print_warning(message: impl core::fmt::Display) {
|
||||
println!("cargo:warning={message}");
|
||||
}
|
||||
|
@ -25,6 +25,9 @@
|
||||
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")]
|
||||
#![no_std]
|
||||
|
||||
#[macro_use]
|
||||
extern crate esp_metadata_generated;
|
||||
|
||||
#[cfg(feature = "defmt")]
|
||||
use defmt as _;
|
||||
#[cfg(feature = "println")]
|
||||
@ -120,67 +123,17 @@ fn panic_handler(info: &core::panic::PanicInfo) -> ! {
|
||||
abort();
|
||||
}
|
||||
|
||||
// Ensure that the address is in DRAM and that it is 16-byte aligned.
|
||||
// Ensure that the address is in DRAM.
|
||||
//
|
||||
// Based loosely on the `esp_stack_ptr_in_dram` function from
|
||||
// `components/esp_hw_support/include/esp_memory_utils.h` in ESP-IDF.
|
||||
//
|
||||
// Address ranges can be found in `components/soc/$CHIP/include/soc/soc.h` as
|
||||
// `SOC_DRAM_LOW` and `SOC_DRAM_HIGH`.
|
||||
// Address ranges can be found in `esp-metadata/devices/$CHIP.toml` in the `device` table.
|
||||
fn is_valid_ram_address(address: u32) -> bool {
|
||||
if (address & 0xF) != 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
#[cfg(feature = "esp32")]
|
||||
if !(0x3FFA_E000..=0x4000_0000).contains(&address) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#[cfg(feature = "esp32c2")]
|
||||
if !(0x3FCA_0000..=0x3FCE_0000).contains(&address) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#[cfg(feature = "esp32c3")]
|
||||
if !(0x3FC8_0000..=0x3FCE_0000).contains(&address) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#[cfg(feature = "esp32c6")]
|
||||
if !(0x4080_0000..=0x4088_0000).contains(&address) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#[cfg(feature = "esp32h2")]
|
||||
if !(0x4080_0000..=0x4085_0000).contains(&address) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#[cfg(feature = "esp32s2")]
|
||||
if !(0x3FFB_0000..=0x4000_0000).contains(&address) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#[cfg(feature = "esp32s3")]
|
||||
if !(0x3FC8_8000..=0x3FD0_0000).contains(&address) {
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
memory_range!("DRAM").contains(&address)
|
||||
}
|
||||
|
||||
#[cfg(feature = "halt-cores")]
|
||||
fn halt() -> ! {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "custom-halt")] {
|
||||
// call custom code
|
||||
unsafe extern "Rust" {
|
||||
fn custom_halt() -> !;
|
||||
}
|
||||
unsafe { custom_halt() }
|
||||
} else if #[cfg(any(feature = "esp32", feature = "esp32s3"))] {
|
||||
// multi-core
|
||||
fn halt() {
|
||||
#[cfg(any(feature = "esp32", feature = "esp32s3"))]
|
||||
{
|
||||
#[cfg(feature = "esp32")]
|
||||
mod registers {
|
||||
pub(crate) const OPTIONS0: u32 = 0x3ff48000;
|
||||
@ -212,9 +165,6 @@ fn halt() -> ! {
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[cfg(feature = "panic-handler")]
|
||||
@ -236,13 +186,20 @@ fn abort() -> ! {
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "semihosting")] {
|
||||
critical_section::with(|_| {
|
||||
semihosting::process::abort();
|
||||
});
|
||||
} else if #[cfg(feature = "halt-cores")] {
|
||||
halt();
|
||||
} else {
|
||||
critical_section::with(|_| {
|
||||
loop {}
|
||||
})
|
||||
} else if #[cfg(feature = "custom-halt")] {
|
||||
// call custom code
|
||||
unsafe extern "Rust" {
|
||||
fn custom_halt() -> !;
|
||||
}
|
||||
unsafe { custom_halt() }
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
critical_section::with(|_| loop {})
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user