wip, hello_world using esp-rs as a package
This commit is contained in:
parent
730fe627ff
commit
d99fc87ad9
131
examples/esp32c3/Cargo.toml
Normal file
131
examples/esp32c3/Cargo.toml
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
[package]
|
||||||
|
name = "esp32c3-hal"
|
||||||
|
version = "0.12.0"
|
||||||
|
authors = [
|
||||||
|
"Jesse Braham <jesse@beta7.io>",
|
||||||
|
"Björn Quentin <bjoern.quentin@mobile-j.de>",
|
||||||
|
]
|
||||||
|
edition = "2021"
|
||||||
|
rust-version = "1.67.0"
|
||||||
|
description = "HAL for ESP32-C3 microcontrollers"
|
||||||
|
repository = "https://github.com/esp-rs/esp-hal"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
|
keywords = [
|
||||||
|
"embedded",
|
||||||
|
"embedded-hal",
|
||||||
|
"esp",
|
||||||
|
"esp32c3",
|
||||||
|
"no-std",
|
||||||
|
]
|
||||||
|
categories = [
|
||||||
|
"embedded",
|
||||||
|
"hardware-support",
|
||||||
|
"no-std",
|
||||||
|
]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
cfg-if = "1.0.0"
|
||||||
|
esp-hal-common = { version = "0.12.0", features = ["esp-riscv-rt","esp32c3"], git="https://github.com/esp-rs/esp-hal" }
|
||||||
|
embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-1_000_000"], optional = true }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
aes = "0.8.3"
|
||||||
|
critical-section = "1.1.2"
|
||||||
|
crypto-bigint = { version = "0.5.3", default-features = false }
|
||||||
|
embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] }
|
||||||
|
embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly","integrated-timers","arch-riscv32","executor-thread"] }
|
||||||
|
embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
|
||||||
|
embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
|
||||||
|
|
||||||
|
embedded-can = "0.4.1"
|
||||||
|
embedded-graphics = "0.8.1"
|
||||||
|
embedded-hal = { version = "0.2.7", features = ["unproven"] }
|
||||||
|
embedded-hal-1 = { version = "=1.0.0-rc.1", package = "embedded-hal" }
|
||||||
|
embedded-hal-async = "=1.0.0-rc.1"
|
||||||
|
embedded-io-async = "0.5.0"
|
||||||
|
esp-backtrace = { version = "0.8.0", features = ["esp32c3", "panic-handler", "exception-handler", "print-uart"] }
|
||||||
|
esp-hal-smartled = { version = "0.5.0", features = ["esp32c3"], git="https://github.com/esp-rs/esp-hal" }
|
||||||
|
esp-println = { version = "0.6.0", features = ["esp32c3", "log"] }
|
||||||
|
heapless = "0.7.16"
|
||||||
|
hmac = { version = "0.12.1", default-features = false }
|
||||||
|
lis3dh-async = "0.8.0"
|
||||||
|
sha2 = { version = "0.10.7", default-features = false }
|
||||||
|
#smart-leds = "0.3.0"
|
||||||
|
#ssd1306 = "0.8.1"
|
||||||
|
static_cell = { version = "1.2.0", features = ["nightly"] }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["rt", "vectored", "esp-hal-common/rv-zero-rtc-bss"]
|
||||||
|
async = ["esp-hal-common/async"]
|
||||||
|
debug = ["esp-hal-common/debug"]
|
||||||
|
defmt = ["esp-hal-common/defmt"]
|
||||||
|
direct-boot = ["esp-hal-common/rv-init-data", "esp-hal-common/rv-init-rtc-data"]
|
||||||
|
direct-vectoring = ["esp-hal-common/direct-vectoring"]
|
||||||
|
eh1 = ["esp-hal-common/eh1"]
|
||||||
|
interrupt-preemption = ["esp-hal-common/interrupt-preemption"]
|
||||||
|
log = ["esp-hal-common/log"]
|
||||||
|
mcu-boot = []
|
||||||
|
rt = []
|
||||||
|
ufmt = ["esp-hal-common/ufmt"]
|
||||||
|
vectored = ["esp-hal-common/vectored"]
|
||||||
|
|
||||||
|
# Embassy support
|
||||||
|
embassy = ["esp-hal-common/embassy"]
|
||||||
|
embassy-time-systick = ["esp-hal-common/embassy-time-systick", "embassy-time/tick-hz-16_000_000"]
|
||||||
|
embassy-time-timg0 = ["esp-hal-common/embassy-time-timg0", "embassy-time/tick-hz-1_000_000"]
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = true
|
||||||
|
|
||||||
|
# [[example]]
|
||||||
|
# name = "spi_eh1_loopback"
|
||||||
|
# required-features = ["eh1"]
|
||||||
|
|
||||||
|
# [[example]]
|
||||||
|
# name = "spi_eh1_device_loopback"
|
||||||
|
# required-features = ["eh1"]
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "embassy_hello_world"
|
||||||
|
required-features = ["embassy"]
|
||||||
|
|
||||||
|
# [[example]]
|
||||||
|
# name = "embassy_wait"
|
||||||
|
# required-features = ["embassy", "async"]
|
||||||
|
|
||||||
|
# [[example]]
|
||||||
|
# name = "interrupt_preemption"
|
||||||
|
# required-features = ["interrupt-preemption"]
|
||||||
|
|
||||||
|
# [[example]]
|
||||||
|
# name = "embassy_spi"
|
||||||
|
# required-features = ["embassy", "async"]
|
||||||
|
|
||||||
|
# [[example]]
|
||||||
|
# name = "embassy_serial"
|
||||||
|
# required-features = ["embassy", "async"]
|
||||||
|
|
||||||
|
# [[example]]
|
||||||
|
# name = "embassy_i2c"
|
||||||
|
# required-features = ["embassy", "async"]
|
||||||
|
|
||||||
|
# [[example]]
|
||||||
|
# name = "embassy_rmt_tx"
|
||||||
|
# required-features = ["embassy", "async"]
|
||||||
|
|
||||||
|
# [[example]]
|
||||||
|
# name = "embassy_rmt_rx"
|
||||||
|
# required-features = ["embassy", "async"]
|
||||||
|
|
||||||
|
# [[example]]
|
||||||
|
# name = "embassy_i2s_sound"
|
||||||
|
# required-features = ["embassy", "async"]
|
||||||
|
|
||||||
|
# [[example]]
|
||||||
|
# name = "embassy_i2s_read"
|
||||||
|
# required-features = ["embassy", "async"]
|
||||||
|
|
||||||
|
# [[example]]
|
||||||
|
# name = "direct-vectoring"
|
||||||
|
# required-features = ["direct-vectoring"]
|
@ -1,42 +1,15 @@
|
|||||||
# esp32-c3 example
|
# 👋🏻
|
||||||
|
|
||||||
this is an WIP signpost, to inform & guide to better examples.
|
This code was borrowed from [esp32c3-hal](https://github.com/esp-rs/esp-hal/tree/main/esp32c3-hal)
|
||||||
|
|
||||||
👋🏻 I'm concurrently proposing basic signpost for README-embassy.md this is in conjunction with my proposed uplift:
|
The Cargo.toml file has been modified to use the embassy repo in path
|
||||||
* https://github.com/esp-rs/esp-hal/pull/834
|
|
||||||
* https://github.com/drogue-iot/drogue-device/pull/388
|
|
||||||
|
|
||||||
## The Basics:
|
|
||||||
* embassy-rs uses esp-rs/esp-hal
|
|
||||||
* esp-hal: Hardware Abstraction Layer crates for the ESP32, ESP32-C2/C3/C6, ESP32-H2, and ESP32-S2/S3 from Espressif.
|
|
||||||
* The Minimum Supported Rust Version is 1.67.0 for all packages.
|
|
||||||
* 🔗 https://docs.rs/esp32c3-hal/latest/esp32c3_hal/
|
|
||||||
|
|
||||||
## Quickstart:
|
|
||||||
https://github.com/esp-rs/esp-hal/blob/main/esp32c3-hal/examples/embassy_hello_world.rs
|
|
||||||
|
|
||||||
```
|
```
|
||||||
gh repo clone esp-rs/esp-hal
|
|
||||||
rustup target add riscv32imc-unknown-none-elf
|
rustup target add riscv32imc-unknown-none-elf
|
||||||
# when targeting RISC-V arch. necessary to set:
|
|
||||||
RUSTC_BOOTSTRAP=1
|
|
||||||
cd esp-hal/esp32c3-hal
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🥰 more github.com/esp-rs/esp-hal/esp32c3-hal/examples
|
For now
|
||||||
* embassy_hello_world.rs
|
|
||||||
* embassy_i2s_read.rs
|
|
||||||
* embassy_rmt_rx.rs
|
|
||||||
* embassy_serial.rs
|
|
||||||
* embassy_wait.rs
|
|
||||||
* embassy_i2c.rs
|
|
||||||
* embassy_i2s_sound.rs
|
|
||||||
* embassy_rmt_tx.rs
|
|
||||||
* embassy_spi.rs
|
|
||||||
|
|
||||||
## coming soon:
|
|
||||||
* embassy_blink (esp32 c3 & s2)
|
|
||||||
* drogue-iot example with esp32
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
cargo run --example embassy_hello_world --features "default","embassy","embassy-time-timg0"
|
||||||
|
```
|
||||||
|
124
examples/esp32c3/build.rs
Normal file
124
examples/esp32c3/build.rs
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
use std::{env, fs::File, io::Write, path::PathBuf};
|
||||||
|
|
||||||
|
// Thanks to kennytm and TheDan64 for the assert_used_features macro.
|
||||||
|
// Source:
|
||||||
|
// https://github.com/TheDan64/inkwell/blob/36c3b106e61b1b45295a35f94023d93d9328c76f/src/lib.rs#L81-L110
|
||||||
|
macro_rules! assert_unique_features {
|
||||||
|
() => {};
|
||||||
|
($first:tt $(,$rest:tt)*) => {
|
||||||
|
$(
|
||||||
|
#[cfg(all(feature = $first, feature = $rest))]
|
||||||
|
compile_error!(concat!("Features \"", $first, "\" and \"", $rest, "\" cannot be used together"));
|
||||||
|
)*
|
||||||
|
assert_unique_features!($($rest),*);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_unique_features! {"mcu-boot", "direct-boot"}
|
||||||
|
|
||||||
|
#[cfg(feature = "direct-boot")]
|
||||||
|
fn main() {
|
||||||
|
// Put the linker script somewhere the linker can find it
|
||||||
|
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||||
|
|
||||||
|
File::create(out.join("memory.x"))
|
||||||
|
.unwrap()
|
||||||
|
.write_all(include_bytes!("ld/db-esp32c3-memory.x"))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
File::create(out.join("esp32c3-link.x"))
|
||||||
|
.unwrap()
|
||||||
|
.write_all(include_bytes!("ld/db-esp32c3-link.x"))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
File::create(out.join("riscv-link.x"))
|
||||||
|
.unwrap()
|
||||||
|
.write_all(include_bytes!("ld/db-riscv-link.x"))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
File::create(out.join("linkall.x"))
|
||||||
|
.unwrap()
|
||||||
|
.write_all(include_bytes!("ld/db-linkall.x"))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("cargo:rustc-link-search={}", out.display());
|
||||||
|
|
||||||
|
// Only re-run the build script when memory.x is changed,
|
||||||
|
// instead of when any part of the source code changes.
|
||||||
|
println!("cargo:rerun-if-changed=ld/memory.x");
|
||||||
|
|
||||||
|
add_defaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(feature = "mcu-boot", feature = "direct-boot")))]
|
||||||
|
fn main() {
|
||||||
|
// Put the linker script somewhere the linker can find it
|
||||||
|
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||||
|
File::create(out.join("memory.x"))
|
||||||
|
.unwrap()
|
||||||
|
.write_all(include_bytes!("ld/bl-esp32c3-memory.x"))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
File::create(out.join("bl-riscv-link.x"))
|
||||||
|
.unwrap()
|
||||||
|
.write_all(include_bytes!("ld/bl-riscv-link.x"))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
File::create(out.join("linkall.x"))
|
||||||
|
.unwrap()
|
||||||
|
.write_all(include_bytes!("ld/bl-linkall.x"))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("cargo:rustc-link-search={}", out.display());
|
||||||
|
|
||||||
|
// Only re-run the build script when memory.x is changed,
|
||||||
|
// instead of when any part of the source code changes.
|
||||||
|
println!("cargo:rerun-if-changed=ld/memory.x");
|
||||||
|
|
||||||
|
add_defaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "mcu-boot")]
|
||||||
|
fn main() {
|
||||||
|
// Put the linker script somewhere the linker can find it
|
||||||
|
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||||
|
|
||||||
|
File::create(out.join("memory.x"))
|
||||||
|
.unwrap()
|
||||||
|
.write_all(include_bytes!("ld/mb-esp32c3-memory.x"))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
File::create(out.join("esp32c3-link.x"))
|
||||||
|
.unwrap()
|
||||||
|
.write_all(include_bytes!("ld/mb-esp32c3-link.x"))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
File::create(out.join("riscv-link.x"))
|
||||||
|
.unwrap()
|
||||||
|
.write_all(include_bytes!("ld/mb-riscv-link.x"))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
File::create(out.join("linkall.x"))
|
||||||
|
.unwrap()
|
||||||
|
.write_all(include_bytes!("ld/mb-linkall.x"))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("cargo:rustc-link-search={}", out.display());
|
||||||
|
|
||||||
|
// Only re-run the build script when memory.x is changed,
|
||||||
|
// instead of when any part of the source code changes.
|
||||||
|
println!("cargo:rerun-if-changed=ld/memory.x");
|
||||||
|
|
||||||
|
add_defaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_defaults() {
|
||||||
|
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||||
|
|
||||||
|
File::create(out.join("rom-functions.x"))
|
||||||
|
.unwrap()
|
||||||
|
.write_all(include_bytes!("ld/rom-functions.x"))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("cargo:rustc-link-search={}", out.display());
|
||||||
|
}
|
56
examples/esp32c3/examples/embassy_hello_world.rs
Normal file
56
examples/esp32c3/examples/embassy_hello_world.rs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
//! embassy hello world
|
||||||
|
//!
|
||||||
|
//! This is an example of running the embassy executor with multiple tasks
|
||||||
|
//! concurrently.
|
||||||
|
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
use embassy_executor::Executor;
|
||||||
|
use embassy_time::{Duration, Timer};
|
||||||
|
use esp32c3_hal::{clock::ClockControl, embassy, peripherals::Peripherals, prelude::*};
|
||||||
|
use esp_backtrace as _;
|
||||||
|
use static_cell::make_static;
|
||||||
|
|
||||||
|
#[embassy_executor::task]
|
||||||
|
async fn run1() {
|
||||||
|
loop {
|
||||||
|
esp_println::println!("Hello world from embassy using esp-hal-async!");
|
||||||
|
Timer::after(Duration::from_millis(1_000)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[embassy_executor::task]
|
||||||
|
async fn run2() {
|
||||||
|
loop {
|
||||||
|
esp_println::println!("Bing!");
|
||||||
|
Timer::after(Duration::from_millis(5_000)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[entry]
|
||||||
|
fn main() -> ! {
|
||||||
|
esp_println::println!("Init!");
|
||||||
|
let peripherals = Peripherals::take();
|
||||||
|
let system = peripherals.SYSTEM.split();
|
||||||
|
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||||
|
|
||||||
|
#[cfg(feature = "embassy-time-systick")]
|
||||||
|
embassy::init(
|
||||||
|
&clocks,
|
||||||
|
esp32c3_hal::systimer::SystemTimer::new(peripherals.SYSTIMER),
|
||||||
|
);
|
||||||
|
|
||||||
|
#[cfg(feature = "embassy-time-timg0")]
|
||||||
|
embassy::init(
|
||||||
|
&clocks,
|
||||||
|
esp32c3_hal::timer::TimerGroup::new(peripherals.TIMG0, &clocks).timer0,
|
||||||
|
);
|
||||||
|
|
||||||
|
let executor = make_static!(Executor::new());
|
||||||
|
executor.run(|spawner| {
|
||||||
|
spawner.spawn(run1()).ok();
|
||||||
|
spawner.spawn(run2()).ok();
|
||||||
|
});
|
||||||
|
}
|
33
examples/esp32c3/ld/bl-esp32c3-memory.x
Normal file
33
examples/esp32c3/ld/bl-esp32c3-memory.x
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
https://github.com/espressif/esptool/blob/ed64d20b051d05f3f522bacc6a786098b562d4b8/esptool/targets/esp32c3.py#L78-L90
|
||||||
|
MEMORY_MAP = [[0x00000000, 0x00010000, "PADDING"],
|
||||||
|
[0x3C000000, 0x3C800000, "DROM"],
|
||||||
|
[0x3FC80000, 0x3FCE0000, "DRAM"],
|
||||||
|
[0x3FC88000, 0x3FD00000, "BYTE_ACCESSIBLE"],
|
||||||
|
[0x3FF00000, 0x3FF20000, "DROM_MASK"],
|
||||||
|
[0x40000000, 0x40060000, "IROM_MASK"],
|
||||||
|
[0x42000000, 0x42800000, "IROM"],
|
||||||
|
[0x4037C000, 0x403E0000, "IRAM"],
|
||||||
|
[0x50000000, 0x50002000, "RTC_IRAM"],
|
||||||
|
[0x50000000, 0x50002000, "RTC_DRAM"],
|
||||||
|
[0x600FE000, 0x60100000, "MEM_INTERNAL2"]]
|
||||||
|
*/
|
||||||
|
/* 400K of on soc RAM, 16K reserved for cache */
|
||||||
|
ICACHE : ORIGIN = 0x4037C000, LENGTH = 0x4000
|
||||||
|
/* Instruction RAM */
|
||||||
|
IRAM : ORIGIN = 0x4037C000 + 0x4000, LENGTH = 400K - 0x4000
|
||||||
|
/* Data RAM */
|
||||||
|
DRAM : ORIGIN = 0x3FC80000, LENGTH = 0x50000
|
||||||
|
|
||||||
|
|
||||||
|
/* External flash */
|
||||||
|
/* Instruction ROM */
|
||||||
|
IROM : ORIGIN = 0x42000000 + 0x20, LENGTH = 0x400000 - 0x20
|
||||||
|
/* Data ROM */
|
||||||
|
DROM : ORIGIN = 0x3C000000, LENGTH = 0x400000
|
||||||
|
|
||||||
|
/* RTC fast memory (executable). Persists over deep sleep. */
|
||||||
|
RTC_FAST : ORIGIN = 0x50000000, LENGTH = 0x2000 /*- ESP_BOOTLOADER_RESERVE_RTC*/
|
||||||
|
}
|
14
examples/esp32c3/ld/bl-linkall.x
Normal file
14
examples/esp32c3/ld/bl-linkall.x
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
INCLUDE "memory.x"
|
||||||
|
|
||||||
|
REGION_ALIAS("ROTEXT", IROM);
|
||||||
|
REGION_ALIAS("RODATA", DROM);
|
||||||
|
|
||||||
|
REGION_ALIAS("RWDATA", DRAM);
|
||||||
|
REGION_ALIAS("RWTEXT", IRAM);
|
||||||
|
|
||||||
|
REGION_ALIAS("RTC_FAST_RWTEXT", RTC_FAST);
|
||||||
|
REGION_ALIAS("RTC_FAST_RWDATA", RTC_FAST);
|
||||||
|
|
||||||
|
INCLUDE "bl-riscv-link.x"
|
||||||
|
INCLUDE "hal-defaults.x"
|
||||||
|
INCLUDE "rom-functions.x"
|
112
examples/esp32c3/ld/bl-riscv-link.x
Normal file
112
examples/esp32c3/ld/bl-riscv-link.x
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
PROVIDE(_stext = ORIGIN(ROTEXT));
|
||||||
|
PROVIDE(_stack_start = ORIGIN(RWDATA) + LENGTH(RWDATA));
|
||||||
|
PROVIDE(_max_hart_id = 0);
|
||||||
|
|
||||||
|
PROVIDE(UserSoft = DefaultHandler);
|
||||||
|
PROVIDE(SupervisorSoft = DefaultHandler);
|
||||||
|
PROVIDE(MachineSoft = DefaultHandler);
|
||||||
|
PROVIDE(UserTimer = DefaultHandler);
|
||||||
|
PROVIDE(SupervisorTimer = DefaultHandler);
|
||||||
|
PROVIDE(MachineTimer = DefaultHandler);
|
||||||
|
PROVIDE(UserExternal = DefaultHandler);
|
||||||
|
PROVIDE(SupervisorExternal = DefaultHandler);
|
||||||
|
PROVIDE(MachineExternal = DefaultHandler);
|
||||||
|
|
||||||
|
PROVIDE(DefaultHandler = DefaultInterruptHandler);
|
||||||
|
PROVIDE(ExceptionHandler = DefaultExceptionHandler);
|
||||||
|
|
||||||
|
PROVIDE(__post_init = default_post_init);
|
||||||
|
|
||||||
|
/* A PAC/HAL defined routine that should initialize custom interrupt controller if needed. */
|
||||||
|
PROVIDE(_setup_interrupts = default_setup_interrupts);
|
||||||
|
|
||||||
|
/* # Multi-processing hook function
|
||||||
|
fn _mp_hook() -> bool;
|
||||||
|
|
||||||
|
This function is called from all the harts and must return true only for one hart,
|
||||||
|
which will perform memory initialization. For other harts it must return false
|
||||||
|
and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt).
|
||||||
|
*/
|
||||||
|
PROVIDE(_mp_hook = default_mp_hook);
|
||||||
|
|
||||||
|
/* # Start trap function override
|
||||||
|
By default uses the riscv crates default trap handler
|
||||||
|
but by providing the `_start_trap` symbol external crates can override.
|
||||||
|
*/
|
||||||
|
PROVIDE(_start_trap = default_start_trap);
|
||||||
|
|
||||||
|
/* esp32c3 fixups */
|
||||||
|
SECTIONS {
|
||||||
|
.text.dummy (NOLOAD) :
|
||||||
|
{
|
||||||
|
/* This section is intended to make _stext address work */
|
||||||
|
. = ABSOLUTE(_stext);
|
||||||
|
} > ROTEXT
|
||||||
|
}
|
||||||
|
INSERT BEFORE .text_init;
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
/* These symbols/functions need to be near eachother, group them together at the start of text */
|
||||||
|
.text_init _stext : ALIGN(4)
|
||||||
|
{
|
||||||
|
KEEP(*(.init));
|
||||||
|
KEEP(*(.init.rust));
|
||||||
|
KEEP(*(.text.abort));
|
||||||
|
} > ROTEXT
|
||||||
|
}
|
||||||
|
INSERT BEFORE .text;
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
.trap : ALIGN(4)
|
||||||
|
{
|
||||||
|
KEEP(*(.trap));
|
||||||
|
*(.trap.*);
|
||||||
|
} > RWTEXT
|
||||||
|
}
|
||||||
|
INSERT BEFORE .rwtext;
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
/**
|
||||||
|
* This dummy section represents the .text section but in rodata.
|
||||||
|
* Thus, it must have its alignement and (at least) its size.
|
||||||
|
*/
|
||||||
|
.text_dummy (NOLOAD):
|
||||||
|
{
|
||||||
|
/* Start at the same alignement constraint than .text */
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* Create an empty gap as big as .text section */
|
||||||
|
. = . + SIZEOF(.text) + SIZEOF(.text_init);
|
||||||
|
/* Prepare the alignement of the section above. Few bytes (0x20) must be
|
||||||
|
* added for the mapping header. */
|
||||||
|
. = ALIGN(0x10000) + 0x20;
|
||||||
|
} > RODATA
|
||||||
|
}
|
||||||
|
INSERT BEFORE .rodata;
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
/* similar as text_dummy */
|
||||||
|
.rwdata_dummy (NOLOAD) : {
|
||||||
|
. = ALIGN(ALIGNOF(.rwtext));
|
||||||
|
. = . + SIZEOF(.rwtext);
|
||||||
|
. = . + SIZEOF(.rwtext.wifi);
|
||||||
|
. = . + SIZEOF(.trap);
|
||||||
|
} > RWDATA
|
||||||
|
}
|
||||||
|
INSERT BEFORE .data;
|
||||||
|
|
||||||
|
/* Must be called __global_pointer$ for linker relaxations to work. */
|
||||||
|
PROVIDE(__global_pointer$ = _data_start + 0x800);
|
||||||
|
/* end of esp32c3 fixups */
|
||||||
|
|
||||||
|
/* Shared sections - ordering matters */
|
||||||
|
INCLUDE "text.x"
|
||||||
|
INCLUDE "rodata.x"
|
||||||
|
INCLUDE "rwtext.x"
|
||||||
|
INCLUDE "rwdata.x"
|
||||||
|
INCLUDE "rtc_fast.x"
|
||||||
|
/* End of Shared sections */
|
||||||
|
|
||||||
|
INCLUDE "debug.x"
|
||||||
|
|
14
examples/esp32c3/ld/db-esp32c3-link.x
Normal file
14
examples/esp32c3/ld/db-esp32c3-link.x
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
INCLUDE memory.x
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.header : AT(0)
|
||||||
|
{
|
||||||
|
LONG(0xaedb041d)
|
||||||
|
LONG(0xaedb041d)
|
||||||
|
} > IROM
|
||||||
|
}
|
||||||
|
|
||||||
|
_stext = ORIGIN(IROM) + 8;
|
||||||
|
|
||||||
|
INCLUDE riscv-link.x
|
43
examples/esp32c3/ld/db-esp32c3-memory.x
Normal file
43
examples/esp32c3/ld/db-esp32c3-memory.x
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
https://github.com/espressif/esptool/blob/ed64d20b051d05f3f522bacc6a786098b562d4b8/esptool/targets/esp32c3.py#L78-L90
|
||||||
|
MEMORY_MAP = [[0x00000000, 0x00010000, "PADDING"],
|
||||||
|
[0x3C000000, 0x3C800000, "DROM"],
|
||||||
|
[0x3FC80000, 0x3FCE0000, "DRAM"],
|
||||||
|
[0x3FC88000, 0x3FD00000, "BYTE_ACCESSIBLE"],
|
||||||
|
[0x3FF00000, 0x3FF20000, "DROM_MASK"],
|
||||||
|
[0x40000000, 0x40060000, "IROM_MASK"],
|
||||||
|
[0x42000000, 0x42800000, "IROM"],
|
||||||
|
[0x4037C000, 0x403E0000, "IRAM"],
|
||||||
|
[0x50000000, 0x50002000, "RTC_IRAM"],
|
||||||
|
[0x50000000, 0x50002000, "RTC_DRAM"],
|
||||||
|
[0x600FE000, 0x60100000, "MEM_INTERNAL2"]]
|
||||||
|
*/
|
||||||
|
/* 400K of on soc RAM, 16K reserved for cache */
|
||||||
|
ICACHE : ORIGIN = 0x4037C000, LENGTH = 0x4000
|
||||||
|
/* Instruction RAM */
|
||||||
|
IRAM : ORIGIN = 0x4037C000 + 0x4000, LENGTH = 400K - 0x4000
|
||||||
|
/* Data RAM */
|
||||||
|
DRAM : ORIGIN = 0x3FC80000, LENGTH = 0x50000
|
||||||
|
|
||||||
|
|
||||||
|
/* External flash */
|
||||||
|
/* Instruction ROM */
|
||||||
|
IROM : ORIGIN = 0x42000000, LENGTH = 0x400000
|
||||||
|
/* Data ROM */
|
||||||
|
DROM : ORIGIN = 0x3C000000, LENGTH = 0x400000
|
||||||
|
|
||||||
|
/* RTC fast memory (executable). Persists over deep sleep. */
|
||||||
|
RTC_FAST : ORIGIN = 0x50000000, LENGTH = 0x2000 /*- ESP_BOOTLOADER_RESERVE_RTC*/
|
||||||
|
}
|
||||||
|
|
||||||
|
REGION_ALIAS("REGION_TEXT", IROM);
|
||||||
|
REGION_ALIAS("REGION_RODATA", DROM);
|
||||||
|
|
||||||
|
REGION_ALIAS("REGION_DATA", DRAM);
|
||||||
|
REGION_ALIAS("REGION_BSS", DRAM);
|
||||||
|
REGION_ALIAS("REGION_STACK", DRAM);
|
||||||
|
|
||||||
|
REGION_ALIAS("REGION_RWTEXT", IRAM);
|
||||||
|
REGION_ALIAS("REGION_RTC_FAST", RTC_FAST);
|
3
examples/esp32c3/ld/db-linkall.x
Normal file
3
examples/esp32c3/ld/db-linkall.x
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
INCLUDE "esp32c3-link.x"
|
||||||
|
INCLUDE "hal-defaults.x"
|
||||||
|
INCLUDE "rom-functions.x"
|
219
examples/esp32c3/ld/db-riscv-link.x
Normal file
219
examples/esp32c3/ld/db-riscv-link.x
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
PROVIDE(_stext = ORIGIN(REGION_TEXT));
|
||||||
|
PROVIDE(_stack_start = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK));
|
||||||
|
PROVIDE(_max_hart_id = 0);
|
||||||
|
|
||||||
|
PROVIDE(UserSoft = DefaultHandler);
|
||||||
|
PROVIDE(SupervisorSoft = DefaultHandler);
|
||||||
|
PROVIDE(MachineSoft = DefaultHandler);
|
||||||
|
PROVIDE(UserTimer = DefaultHandler);
|
||||||
|
PROVIDE(SupervisorTimer = DefaultHandler);
|
||||||
|
PROVIDE(MachineTimer = DefaultHandler);
|
||||||
|
PROVIDE(UserExternal = DefaultHandler);
|
||||||
|
PROVIDE(SupervisorExternal = DefaultHandler);
|
||||||
|
PROVIDE(MachineExternal = DefaultHandler);
|
||||||
|
|
||||||
|
PROVIDE(DefaultHandler = DefaultInterruptHandler);
|
||||||
|
PROVIDE(ExceptionHandler = DefaultExceptionHandler);
|
||||||
|
|
||||||
|
PROVIDE(__post_init = default_post_init);
|
||||||
|
|
||||||
|
/* A PAC/HAL defined routine that should initialize custom interrupt controller if needed. */
|
||||||
|
PROVIDE(_setup_interrupts = default_setup_interrupts);
|
||||||
|
|
||||||
|
/* # Multi-processing hook function
|
||||||
|
fn _mp_hook() -> bool;
|
||||||
|
|
||||||
|
This function is called from all the harts and must return true only for one hart,
|
||||||
|
which will perform memory initialization. For other harts it must return false
|
||||||
|
and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt).
|
||||||
|
*/
|
||||||
|
PROVIDE(_mp_hook = default_mp_hook);
|
||||||
|
|
||||||
|
/* # Start trap function override
|
||||||
|
By default uses the riscv crates default trap handler
|
||||||
|
but by providing the `_start_trap` symbol external crates can override.
|
||||||
|
*/
|
||||||
|
PROVIDE(_start_trap = default_start_trap);
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text.dummy (NOLOAD) :
|
||||||
|
{
|
||||||
|
/* This section is intended to make _stext address work */
|
||||||
|
. = ABSOLUTE(_stext);
|
||||||
|
} > REGION_TEXT
|
||||||
|
|
||||||
|
.text _stext :
|
||||||
|
{
|
||||||
|
/* Put reset handler first in .text section so it ends up as the entry */
|
||||||
|
/* point of the program. */
|
||||||
|
KEEP(*(.init));
|
||||||
|
KEEP(*(.init.rust));
|
||||||
|
KEEP(*(.text.abort));
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
*(.text .text.*);
|
||||||
|
_etext = .;
|
||||||
|
} > REGION_TEXT
|
||||||
|
|
||||||
|
_text_size = _etext - _stext + 8;
|
||||||
|
.rodata ORIGIN(DROM) + _text_size : AT(_text_size)
|
||||||
|
{
|
||||||
|
_srodata = .;
|
||||||
|
*(.srodata .srodata.*);
|
||||||
|
*(.rodata .rodata.*);
|
||||||
|
|
||||||
|
/* 4-byte align the end (VMA) of this section.
|
||||||
|
This is required by LLD to ensure the LMA of the following .data
|
||||||
|
section will have the correct alignment. */
|
||||||
|
. = ALIGN(4);
|
||||||
|
_erodata = .;
|
||||||
|
} > REGION_RODATA
|
||||||
|
|
||||||
|
_rodata_size = _erodata - _srodata + 8;
|
||||||
|
.data ORIGIN(DRAM) : AT(_text_size + _rodata_size)
|
||||||
|
{
|
||||||
|
_data_start = .;
|
||||||
|
/* Must be called __global_pointer$ for linker relaxations to work. */
|
||||||
|
PROVIDE(__global_pointer$ = . + 0x800);
|
||||||
|
*(.sdata .sdata.* .sdata2 .sdata2.*);
|
||||||
|
*(.data .data.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
_data_end = .;
|
||||||
|
} > REGION_DATA
|
||||||
|
|
||||||
|
_data_size = _data_end - _data_start + 8;
|
||||||
|
.rwtext ORIGIN(REGION_RWTEXT) + _data_size : AT(_text_size + _rodata_size + _data_size){
|
||||||
|
_srwtext = .;
|
||||||
|
KEEP(*(.trap));
|
||||||
|
*(.trap.*);
|
||||||
|
*(.rwtext);
|
||||||
|
. = ALIGN(4);
|
||||||
|
_erwtext = .;
|
||||||
|
} > REGION_RWTEXT
|
||||||
|
_rwtext_size = _erwtext - _srwtext + 8;
|
||||||
|
|
||||||
|
.rwtext.dummy (NOLOAD):
|
||||||
|
{
|
||||||
|
/* This section is required to skip .rwtext area because REGION_RWTEXT
|
||||||
|
* and REGION_BSS reflect the same address space on different buses.
|
||||||
|
*/
|
||||||
|
. = ORIGIN(REGION_DATA) + _rwtext_size + 8 + SIZEOF(.data);
|
||||||
|
} > REGION_DATA
|
||||||
|
|
||||||
|
.bss (NOLOAD) :
|
||||||
|
{
|
||||||
|
_bss_start = .;
|
||||||
|
*(.sbss .sbss.* .bss .bss.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
_bss_end = .;
|
||||||
|
} > REGION_BSS
|
||||||
|
|
||||||
|
/* ### .uninit */
|
||||||
|
.uninit (NOLOAD) : ALIGN(4)
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__suninit = .;
|
||||||
|
*(.uninit .uninit.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
__euninit = .;
|
||||||
|
} > REGION_BSS
|
||||||
|
|
||||||
|
/* fictitious region that represents the memory available for the stack */
|
||||||
|
.stack (NOLOAD) :
|
||||||
|
{
|
||||||
|
_estack = .;
|
||||||
|
. = ABSOLUTE(_stack_start);
|
||||||
|
_sstack = .;
|
||||||
|
} > REGION_STACK
|
||||||
|
|
||||||
|
.rtc_fast.text : AT(_text_size + _rodata_size + _data_size + _rwtext_size) {
|
||||||
|
_srtc_fast_text = .;
|
||||||
|
*(.rtc_fast.literal .rtc_fast.text .rtc_fast.literal.* .rtc_fast.text.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_ertc_fast_text = .;
|
||||||
|
} > REGION_RTC_FAST
|
||||||
|
_fast_text_size = _ertc_fast_text - _srtc_fast_text + 8;
|
||||||
|
|
||||||
|
.rtc_fast.data : AT(_text_size + _rodata_size + _data_size + _rwtext_size + _fast_text_size)
|
||||||
|
{
|
||||||
|
_rtc_fast_data_start = ABSOLUTE(.);
|
||||||
|
*(.rtc_fast.data .rtc_fast.data.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_rtc_fast_data_end = ABSOLUTE(.);
|
||||||
|
} > REGION_RTC_FAST
|
||||||
|
_rtc_fast_data_size = _rtc_fast_data_end - _rtc_fast_data_start + 8;
|
||||||
|
|
||||||
|
.rtc_fast.bss (NOLOAD) : ALIGN(4)
|
||||||
|
{
|
||||||
|
_rtc_fast_bss_start = ABSOLUTE(.);
|
||||||
|
*(.rtc_fast.bss .rtc_fast.bss.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_rtc_fast_bss_end = ABSOLUTE(.);
|
||||||
|
} > REGION_RTC_FAST
|
||||||
|
|
||||||
|
.rtc_fast.noinit (NOLOAD) : ALIGN(4)
|
||||||
|
{
|
||||||
|
*(.rtc_fast.noinit .rtc_fast.noinit.*)
|
||||||
|
} > REGION_RTC_FAST
|
||||||
|
|
||||||
|
/* fake output .got section */
|
||||||
|
/* Dynamic relocations are unsupported. This section is only used to detect
|
||||||
|
relocatable code in the input files and raise an error if relocatable code
|
||||||
|
is found */
|
||||||
|
.got (INFO) :
|
||||||
|
{
|
||||||
|
KEEP(*(.got .got.*));
|
||||||
|
}
|
||||||
|
|
||||||
|
.eh_frame (INFO) : { KEEP(*(.eh_frame)) }
|
||||||
|
.eh_frame_hdr (INFO) : { *(.eh_frame_hdr) }
|
||||||
|
}
|
||||||
|
|
||||||
|
PROVIDE(_sidata = _erodata + 8);
|
||||||
|
PROVIDE(_irwtext = ORIGIN(DROM) + _text_size + _rodata_size + _data_size);
|
||||||
|
PROVIDE(_irtc_fast_text = ORIGIN(DROM) + _text_size + _rodata_size + _data_size + _rwtext_size);
|
||||||
|
PROVIDE(_irtc_fast_data = ORIGIN(DROM) + _text_size + _rodata_size + _data_size + _rwtext_size + _fast_text_size);
|
||||||
|
|
||||||
|
/* Do not exceed this mark in the error messages above | */
|
||||||
|
ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, "
|
||||||
|
ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(ORIGIN(REGION_RODATA) % 4 == 0, "
|
||||||
|
ERROR(riscv-rt): the start of the REGION_RODATA must be 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(ORIGIN(REGION_DATA) % 4 == 0, "
|
||||||
|
ERROR(riscv-rt): the start of the REGION_DATA must be 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, "
|
||||||
|
ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(ORIGIN(REGION_STACK) % 4 == 0, "
|
||||||
|
ERROR(riscv-rt): the start of the REGION_STACK must be 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(_stext % 4 == 0, "
|
||||||
|
ERROR(riscv-rt): `_stext` must be 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(_data_start % 4 == 0 && _data_end % 4 == 0, "
|
||||||
|
BUG(riscv-rt): .data is not 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(_sidata % 4 == 0, "
|
||||||
|
BUG(riscv-rt): the LMA of .data is not 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(_bss_start % 4 == 0 && _bss_end % 4 == 0, "
|
||||||
|
BUG(riscv-rt): .bss is not 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(_stext + SIZEOF(.text) < ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT), "
|
||||||
|
ERROR(riscv-rt): The .text section must be placed inside the REGION_TEXT region.
|
||||||
|
Set _stext to an address smaller than 'ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT)'");
|
||||||
|
|
||||||
|
ASSERT(SIZEOF(.got) == 0, "
|
||||||
|
.got section detected in the input files. Dynamic relocations are not
|
||||||
|
supported. If you are linking to C code compiled using the `gcc` crate
|
||||||
|
then modify your build script to compile the C code _without_ the
|
||||||
|
-fPIC flag. See the documentation of the `gcc::Config.fpic` method for
|
||||||
|
details.");
|
||||||
|
|
||||||
|
/* Do not exceed this mark in the error messages above | */
|
45
examples/esp32c3/ld/mb-esp32c3-link.x
Normal file
45
examples/esp32c3/ld/mb-esp32c3-link.x
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
INCLUDE memory.x
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.metadata :
|
||||||
|
{
|
||||||
|
/* Magic for load header */
|
||||||
|
|
||||||
|
LONG(0xace637d3)
|
||||||
|
|
||||||
|
/* Application entry point address */
|
||||||
|
|
||||||
|
KEEP(*(.entry_addr))
|
||||||
|
|
||||||
|
/* IRAM metadata:
|
||||||
|
* - Destination address (VMA) for IRAM region
|
||||||
|
* - Flash offset (LMA) for start of IRAM region
|
||||||
|
* - Size of IRAM region
|
||||||
|
*/
|
||||||
|
|
||||||
|
LONG(ADDR(.rwtext))
|
||||||
|
LONG(LOADADDR(.rwtext))
|
||||||
|
LONG(SIZEOF(.rwtext))
|
||||||
|
|
||||||
|
/* DRAM metadata:
|
||||||
|
* - Destination address (VMA) for DRAM region
|
||||||
|
* - Flash offset (LMA) for start of DRAM region
|
||||||
|
* - Size of DRAM region
|
||||||
|
*/
|
||||||
|
|
||||||
|
LONG(ADDR(.data))
|
||||||
|
LONG(LOADADDR(.data))
|
||||||
|
LONG(SIZEOF(.data))
|
||||||
|
} > metadata
|
||||||
|
}
|
||||||
|
|
||||||
|
INCLUDE riscv-link.x
|
||||||
|
|
||||||
|
_image_drom_vma = ADDR(.rodata);
|
||||||
|
_image_drom_lma = LOADADDR(.rodata);
|
||||||
|
_image_drom_size = LOADADDR(.rodata) + SIZEOF(.rodata) - _image_drom_lma;
|
||||||
|
|
||||||
|
_image_irom_vma = ADDR(.text);
|
||||||
|
_image_irom_lma = LOADADDR(.text);
|
||||||
|
_image_irom_size = LOADADDR(.text) + SIZEOF(.text) - _image_irom_lma;
|
65
examples/esp32c3/ld/mb-esp32c3-memory.x
Normal file
65
examples/esp32c3/ld/mb-esp32c3-memory.x
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
https://github.com/espressif/esptool/blob/ed64d20b051d05f3f522bacc6a786098b562d4b8/esptool/targets/esp32c3.py#L78-L90
|
||||||
|
MEMORY_MAP = [[0x00000000, 0x00010000, "PADDING"],
|
||||||
|
[0x3C000000, 0x3C800000, "DROM"],
|
||||||
|
[0x3FC80000, 0x3FCE0000, "DRAM"],
|
||||||
|
[0x3FC88000, 0x3FD00000, "BYTE_ACCESSIBLE"],
|
||||||
|
[0x3FF00000, 0x3FF20000, "DROM_MASK"],
|
||||||
|
[0x40000000, 0x40060000, "IROM_MASK"],
|
||||||
|
[0x42000000, 0x42800000, "IROM"],
|
||||||
|
[0x4037C000, 0x403E0000, "IRAM"],
|
||||||
|
[0x50000000, 0x50002000, "RTC_IRAM"],
|
||||||
|
[0x50000000, 0x50002000, "RTC_DRAM"],
|
||||||
|
[0x600FE000, 0x60100000, "MEM_INTERNAL2"]]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The origin values for "metadata" and "ROM" memory regions are the actual
|
||||||
|
* load addresses.
|
||||||
|
*
|
||||||
|
* NOTE: The memory region starting from 0x0 with 0x20 length is reserved
|
||||||
|
* for the MCUboot header, which will be prepended to the binary file by
|
||||||
|
* the "imgtool" during the signing of firmware image.
|
||||||
|
*/
|
||||||
|
metadata : ORIGIN = 0x20, LENGTH = 0x20
|
||||||
|
ROM : ORIGIN = 0x40, LENGTH = 0x400000 - 0x40
|
||||||
|
|
||||||
|
/* 400K of on soc RAM, 16K reserved for cache */
|
||||||
|
ICACHE : ORIGIN = 0x4037C000, LENGTH = 0x4000
|
||||||
|
/* Instruction RAM */
|
||||||
|
IRAM : ORIGIN = 0x4037C000 + 0x4000, LENGTH = 400K - 0x4000
|
||||||
|
/* Data RAM */
|
||||||
|
DRAM : ORIGIN = 0x3FC80000, LENGTH = 0x50000
|
||||||
|
|
||||||
|
/* External flash */
|
||||||
|
/* Instruction ROM */
|
||||||
|
IROM : ORIGIN = 0x42000000, LENGTH = 0x400000
|
||||||
|
/* Data ROM */
|
||||||
|
/* The DROM segment origin is offset by 0x40 for mirroring the actual ROM
|
||||||
|
* image layout:
|
||||||
|
* 0x0 - 0x1F : MCUboot header
|
||||||
|
* 0x20 - 0x3F : Application image metadata section
|
||||||
|
* 0x40 onwards: ROM code and data
|
||||||
|
* This is required to meet the following constraint from the external
|
||||||
|
* flash MMU:
|
||||||
|
* VMA % 64KB == LMA % 64KB
|
||||||
|
* i.e. the lower 16 bits of both the virtual address (address seen by the
|
||||||
|
* CPU) and the load address (physical address of the external flash) must
|
||||||
|
* be equal.
|
||||||
|
*/
|
||||||
|
DROM : ORIGIN = 0x3C000000 + 0x40, LENGTH = 0x400000 - 0x40
|
||||||
|
|
||||||
|
/* RTC fast memory (executable). Persists over deep sleep. */
|
||||||
|
RTC_FAST : ORIGIN = 0x50000000, LENGTH = 0x2000 /*- ESP_BOOTLOADER_RESERVE_RTC*/
|
||||||
|
}
|
||||||
|
|
||||||
|
REGION_ALIAS("REGION_TEXT", IROM);
|
||||||
|
REGION_ALIAS("REGION_RODATA", DROM);
|
||||||
|
|
||||||
|
REGION_ALIAS("REGION_DATA", DRAM);
|
||||||
|
REGION_ALIAS("REGION_BSS", DRAM);
|
||||||
|
REGION_ALIAS("REGION_STACK", DRAM);
|
||||||
|
|
||||||
|
REGION_ALIAS("REGION_RWTEXT", IRAM);
|
||||||
|
REGION_ALIAS("REGION_RTC_FAST", RTC_FAST);
|
3
examples/esp32c3/ld/mb-linkall.x
Normal file
3
examples/esp32c3/ld/mb-linkall.x
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
INCLUDE "esp32c3-link.x"
|
||||||
|
INCLUDE "hal-defaults.x"
|
||||||
|
INCLUDE "rom-functions.x"
|
239
examples/esp32c3/ld/mb-riscv-link.x
Normal file
239
examples/esp32c3/ld/mb-riscv-link.x
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
PROVIDE(_stack_start = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK));
|
||||||
|
PROVIDE(_max_hart_id = 0);
|
||||||
|
|
||||||
|
PROVIDE(UserSoft = DefaultHandler);
|
||||||
|
PROVIDE(SupervisorSoft = DefaultHandler);
|
||||||
|
PROVIDE(MachineSoft = DefaultHandler);
|
||||||
|
PROVIDE(UserTimer = DefaultHandler);
|
||||||
|
PROVIDE(SupervisorTimer = DefaultHandler);
|
||||||
|
PROVIDE(MachineTimer = DefaultHandler);
|
||||||
|
PROVIDE(UserExternal = DefaultHandler);
|
||||||
|
PROVIDE(SupervisorExternal = DefaultHandler);
|
||||||
|
PROVIDE(MachineExternal = DefaultHandler);
|
||||||
|
|
||||||
|
PROVIDE(DefaultHandler = DefaultInterruptHandler);
|
||||||
|
PROVIDE(ExceptionHandler = DefaultExceptionHandler);
|
||||||
|
|
||||||
|
PROVIDE(__post_init = default_post_init);
|
||||||
|
|
||||||
|
/* A PAC/HAL defined routine that should initialize custom interrupt controller if needed. */
|
||||||
|
PROVIDE(_setup_interrupts = default_setup_interrupts);
|
||||||
|
|
||||||
|
/* # Multi-processing hook function
|
||||||
|
fn _mp_hook() -> bool;
|
||||||
|
|
||||||
|
This function is called from all the harts and must return true only for one hart,
|
||||||
|
which will perform memory initialization. For other harts it must return false
|
||||||
|
and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt).
|
||||||
|
*/
|
||||||
|
PROVIDE(_mp_hook = default_mp_hook);
|
||||||
|
|
||||||
|
/* # Start trap function override
|
||||||
|
By default uses the riscv crates default trap handler
|
||||||
|
but by providing the `_start_trap` symbol external crates can override.
|
||||||
|
*/
|
||||||
|
PROVIDE(_start_trap = default_start_trap);
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.rodata :
|
||||||
|
{
|
||||||
|
_srodata = .;
|
||||||
|
*(.srodata .srodata.*);
|
||||||
|
*(EXCLUDE_FILE (*libriscv-*.rlib:riscv.*) .rodata);
|
||||||
|
*(EXCLUDE_FILE (*libriscv-*.rlib:riscv.*) .rodata.*);
|
||||||
|
*(EXCLUDE_FILE (*libesp_riscv_rt-*.rlib:esp-riscv-rt.*) .rodata);
|
||||||
|
*(EXCLUDE_FILE (*libesp_riscv_rt-*.rlib:esp-riscv-rt.*) .rodata.*);
|
||||||
|
|
||||||
|
/* 4-byte align the end (VMA) of this section.
|
||||||
|
This is required by LLD to ensure the LMA of the following .data
|
||||||
|
section will have the correct alignment. */
|
||||||
|
. = ALIGN(4);
|
||||||
|
_erodata = .;
|
||||||
|
} > REGION_RODATA AT>ROM
|
||||||
|
|
||||||
|
.rwtext :
|
||||||
|
{
|
||||||
|
_srwtext = .;
|
||||||
|
/* Put reset handler first in .rwtext section so it ends up as the entry */
|
||||||
|
/* point of the program. */
|
||||||
|
KEEP(*(.init));
|
||||||
|
KEEP(*(.init.rust));
|
||||||
|
KEEP(*(.text.abort));
|
||||||
|
KEEP(*(.trap));
|
||||||
|
*(.trap.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
*libriscv-*.rlib:riscv.*(.literal .text .literal.* .text.*);
|
||||||
|
*libesp_riscv_rt-*.rlib:esp-riscv-rt.*(.literal .text .literal.* .text.*);
|
||||||
|
*(.rwtext);
|
||||||
|
. = ALIGN(4);
|
||||||
|
_erwtext = .;
|
||||||
|
} > REGION_RWTEXT AT>ROM
|
||||||
|
|
||||||
|
.rwtext.dummy (NOLOAD):
|
||||||
|
{
|
||||||
|
/* This section is required to skip .rwtext area because REGION_RWTEXT
|
||||||
|
* and REGION_BSS reflect the same address space on different buses.
|
||||||
|
*/
|
||||||
|
|
||||||
|
. = ORIGIN(REGION_BSS) + _erwtext - _srwtext;
|
||||||
|
} > REGION_BSS
|
||||||
|
|
||||||
|
.bss (NOLOAD) :
|
||||||
|
{
|
||||||
|
_bss_start = .;
|
||||||
|
*(.sbss .sbss.* .bss .bss.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
_bss_end = .;
|
||||||
|
} > REGION_BSS
|
||||||
|
|
||||||
|
.uninit (NOLOAD) : ALIGN(4)
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__suninit = .;
|
||||||
|
*(.uninit .uninit.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
__euninit = .;
|
||||||
|
} > REGION_BSS
|
||||||
|
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
_data_start = .;
|
||||||
|
/* Must be called __global_pointer$ for linker relaxations to work. */
|
||||||
|
PROVIDE(__global_pointer$ = . + 0x800);
|
||||||
|
*(.sdata .sdata.* .sdata2 .sdata2.*);
|
||||||
|
*(.data .data.*);
|
||||||
|
*libriscv-*.rlib:riscv.*(.rodata .rodata.*);
|
||||||
|
*libesp_riscv_rt-*.rlib:esp-riscv-rt.*(.rodata .rodata.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
_data_end = .;
|
||||||
|
} > REGION_DATA AT>ROM
|
||||||
|
|
||||||
|
/* fictitious region that represents the memory available for the stack */
|
||||||
|
.stack (NOLOAD) :
|
||||||
|
{
|
||||||
|
_estack = .;
|
||||||
|
. = ABSOLUTE(_stack_start);
|
||||||
|
_sstack = .;
|
||||||
|
} > REGION_STACK
|
||||||
|
|
||||||
|
.rtc_fast.text :
|
||||||
|
{
|
||||||
|
_srtc_fast_text = .;
|
||||||
|
*(.rtc_fast.literal .rtc_fast.text .rtc_fast.literal.* .rtc_fast.text.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_ertc_fast_text = .;
|
||||||
|
} > REGION_RTC_FAST AT>ROM
|
||||||
|
|
||||||
|
.rtc_fast.data :
|
||||||
|
{
|
||||||
|
_rtc_fast_data_start = ABSOLUTE(.);
|
||||||
|
*(.rtc_fast.data .rtc_fast.data.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_rtc_fast_data_end = ABSOLUTE(.);
|
||||||
|
} > REGION_RTC_FAST AT>ROM
|
||||||
|
|
||||||
|
.rtc_fast.bss (NOLOAD) : ALIGN(4)
|
||||||
|
{
|
||||||
|
_rtc_fast_bss_start = ABSOLUTE(.);
|
||||||
|
*(.rtc_fast.bss .rtc_fast.bss.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_rtc_fast_bss_end = ABSOLUTE(.);
|
||||||
|
} > REGION_RTC_FAST
|
||||||
|
|
||||||
|
.rtc_fast.noinit (NOLOAD) : ALIGN(4)
|
||||||
|
{
|
||||||
|
*(.rtc_fast.noinit .rtc_fast.noinit.*)
|
||||||
|
} > REGION_RTC_FAST
|
||||||
|
|
||||||
|
/* The alignment of the "text" output section is forced to
|
||||||
|
* 0x00010000 (64KB) to ensure that it will be allocated at the beginning
|
||||||
|
* of the next available Flash block.
|
||||||
|
* This is required to meet the following constraint from the external
|
||||||
|
* flash MMU:
|
||||||
|
* VMA % 64KB == LMA % 64KB
|
||||||
|
* i.e. the lower 16 bits of both the virtual address (address seen by the
|
||||||
|
* CPU) and the load address (physical address of the external flash) must
|
||||||
|
* be equal.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.text.dummy (NOLOAD) : ALIGN(0x10000)
|
||||||
|
{
|
||||||
|
/* This section is required to skip .rodata area because REGION_TEXT
|
||||||
|
* and REGION_RODATA reflect the same address space on different buses.
|
||||||
|
*/
|
||||||
|
|
||||||
|
. += SIZEOF(.rodata);
|
||||||
|
} > REGION_TEXT
|
||||||
|
|
||||||
|
.text : ALIGN(0x10000)
|
||||||
|
{
|
||||||
|
_stext = .;
|
||||||
|
*(EXCLUDE_FILE (*libriscv-*.rlib:riscv.*) .text)
|
||||||
|
*(EXCLUDE_FILE (*libriscv-*.rlib:riscv.*) .text.*)
|
||||||
|
*(EXCLUDE_FILE (*libesp_riscv_rt-*.rlib:esp-riscv-rt.*) .text)
|
||||||
|
*(EXCLUDE_FILE (*libesp_riscv_rt-*.rlib:esp-riscv-rt.*) .text.*)
|
||||||
|
_etext = .;
|
||||||
|
} > REGION_TEXT AT>ROM
|
||||||
|
|
||||||
|
/* fake output .got section */
|
||||||
|
/* Dynamic relocations are unsupported. This section is only used to detect
|
||||||
|
relocatable code in the input files and raise an error if relocatable code
|
||||||
|
is found */
|
||||||
|
.got (INFO) :
|
||||||
|
{
|
||||||
|
KEEP(*(.got .got.*));
|
||||||
|
}
|
||||||
|
|
||||||
|
.eh_frame (INFO) : { KEEP(*(.eh_frame)) }
|
||||||
|
.eh_frame_hdr (INFO) : { *(.eh_frame_hdr) }
|
||||||
|
}
|
||||||
|
|
||||||
|
PROVIDE(_sidata = _erodata + 8);
|
||||||
|
PROVIDE(_irwtext = ORIGIN(DROM) + _text_size + _rodata_size + _data_size);
|
||||||
|
PROVIDE(_irtc_fast_text = ORIGIN(DROM) + _text_size + _rodata_size + _data_size + _rwtext_size);
|
||||||
|
PROVIDE(_irtc_fast_data = ORIGIN(DROM) + _text_size + _rodata_size + _data_size + _rwtext_size + _fast_text_size);
|
||||||
|
|
||||||
|
/* Do not exceed this mark in the error messages above | */
|
||||||
|
ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, "
|
||||||
|
ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(ORIGIN(REGION_RODATA) % 4 == 0, "
|
||||||
|
ERROR(riscv-rt): the start of the REGION_RODATA must be 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(ORIGIN(REGION_DATA) % 4 == 0, "
|
||||||
|
ERROR(riscv-rt): the start of the REGION_DATA must be 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, "
|
||||||
|
ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(ORIGIN(REGION_STACK) % 4 == 0, "
|
||||||
|
ERROR(riscv-rt): the start of the REGION_STACK must be 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(_stext % 4 == 0, "
|
||||||
|
ERROR(riscv-rt): `_stext` must be 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(_data_start % 4 == 0 && _data_end % 4 == 0, "
|
||||||
|
BUG(riscv-rt): .data is not 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(_sidata % 4 == 0, "
|
||||||
|
BUG(riscv-rt): the LMA of .data is not 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(_bss_start % 4 == 0 && _bss_end % 4 == 0, "
|
||||||
|
BUG(riscv-rt): .bss is not 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(_stext + SIZEOF(.text) < ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT), "
|
||||||
|
ERROR(riscv-rt): The .text section must be placed inside the REGION_TEXT region.
|
||||||
|
Set _stext to an address smaller than 'ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT)'");
|
||||||
|
|
||||||
|
ASSERT(SIZEOF(.got) == 0, "
|
||||||
|
.got section detected in the input files. Dynamic relocations are not
|
||||||
|
supported. If you are linking to C code compiled using the `gcc` crate
|
||||||
|
then modify your build script to compile the C code _without_ the
|
||||||
|
-fPIC flag. See the documentation of the `gcc::Config.fpic` method for
|
||||||
|
details.");
|
||||||
|
|
||||||
|
/* Do not exceed this mark in the error messages above | */
|
25
examples/esp32c3/ld/rom-functions.x
Normal file
25
examples/esp32c3/ld/rom-functions.x
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
ets_printf = 0x40000040;
|
||||||
|
PROVIDE(esp_rom_printf = ets_printf);
|
||||||
|
PROVIDE(cache_invalidate_icache_all = 0x400004d8);
|
||||||
|
PROVIDE(cache_suspend_icache = 0x40000524);
|
||||||
|
PROVIDE(cache_resume_icache = 0x40000528);
|
||||||
|
PROVIDE(cache_ibus_mmu_set = 0x40000560);
|
||||||
|
PROVIDE(cache_dbus_mmu_set = 0x40000564);
|
||||||
|
PROVIDE(ets_delay_us = 0x40000050);
|
||||||
|
PROVIDE(ets_update_cpu_frequency_rom = 0x40000588);
|
||||||
|
PROVIDE(rom_i2c_writeReg = 0x4000195c);
|
||||||
|
PROVIDE(rom_i2c_writeReg_Mask = 0x40001960);
|
||||||
|
PROVIDE(rtc_get_reset_reason = 0x40000018);
|
||||||
|
PROVIDE(software_reset = 0x40000090);
|
||||||
|
PROVIDE(software_reset_cpu = 0x40000094);
|
||||||
|
|
||||||
|
PROVIDE(esp_rom_crc32_be = 0x4000062c);
|
||||||
|
PROVIDE(esp_rom_crc16_be = 0x40000634);
|
||||||
|
PROVIDE(esp_rom_crc8_be = 0x4000063c);
|
||||||
|
PROVIDE(esp_rom_crc32_le = 0x40000628);
|
||||||
|
PROVIDE(esp_rom_crc16_le = 0x40000630);
|
||||||
|
PROVIDE(esp_rom_crc8_le = 0x40000638);
|
||||||
|
|
||||||
|
PROVIDE(esp_rom_md5_init = 0x40000614);
|
||||||
|
PROVIDE(esp_rom_md5_update = 0x40000618);
|
||||||
|
PROVIDE(esp_rom_md5_final = 0x4000061c);
|
Loading…
Reference in New Issue
Block a user