From d99fc87ad9096f4acd7d7a6c4cd507473f8ed667 Mon Sep 17 00:00:00 2001 From: brian horakh Date: Sun, 1 Oct 2023 06:45:45 +0000 Subject: [PATCH] wip, hello_world using esp-rs as a package --- examples/esp32c3/Cargo.toml | 131 ++++++++++ examples/esp32c3/README.md | 41 +-- examples/esp32c3/build.rs | 124 +++++++++ .../esp32c3/examples/embassy_hello_world.rs | 56 ++++ examples/esp32c3/ld/bl-esp32c3-memory.x | 33 +++ examples/esp32c3/ld/bl-linkall.x | 14 + examples/esp32c3/ld/bl-riscv-link.x | 112 ++++++++ examples/esp32c3/ld/db-esp32c3-link.x | 14 + examples/esp32c3/ld/db-esp32c3-memory.x | 43 ++++ examples/esp32c3/ld/db-linkall.x | 3 + examples/esp32c3/ld/db-riscv-link.x | 219 ++++++++++++++++ examples/esp32c3/ld/mb-esp32c3-link.x | 45 ++++ examples/esp32c3/ld/mb-esp32c3-memory.x | 65 +++++ examples/esp32c3/ld/mb-linkall.x | 3 + examples/esp32c3/ld/mb-riscv-link.x | 239 ++++++++++++++++++ examples/esp32c3/ld/rom-functions.x | 25 ++ 16 files changed, 1133 insertions(+), 34 deletions(-) create mode 100644 examples/esp32c3/Cargo.toml create mode 100644 examples/esp32c3/build.rs create mode 100644 examples/esp32c3/examples/embassy_hello_world.rs create mode 100644 examples/esp32c3/ld/bl-esp32c3-memory.x create mode 100644 examples/esp32c3/ld/bl-linkall.x create mode 100644 examples/esp32c3/ld/bl-riscv-link.x create mode 100644 examples/esp32c3/ld/db-esp32c3-link.x create mode 100644 examples/esp32c3/ld/db-esp32c3-memory.x create mode 100644 examples/esp32c3/ld/db-linkall.x create mode 100644 examples/esp32c3/ld/db-riscv-link.x create mode 100644 examples/esp32c3/ld/mb-esp32c3-link.x create mode 100644 examples/esp32c3/ld/mb-esp32c3-memory.x create mode 100644 examples/esp32c3/ld/mb-linkall.x create mode 100644 examples/esp32c3/ld/mb-riscv-link.x create mode 100644 examples/esp32c3/ld/rom-functions.x diff --git a/examples/esp32c3/Cargo.toml b/examples/esp32c3/Cargo.toml new file mode 100644 index 00000000..5a596cde --- /dev/null +++ b/examples/esp32c3/Cargo.toml @@ -0,0 +1,131 @@ +[package] +name = "esp32c3-hal" +version = "0.12.0" +authors = [ + "Jesse Braham ", + "BjΓΆrn Quentin ", +] +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"] diff --git a/examples/esp32c3/README.md b/examples/esp32c3/README.md index 57c2dfb3..4677231c 100644 --- a/examples/esp32c3/README.md +++ b/examples/esp32c3/README.md @@ -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: -* 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 +The Cargo.toml file has been modified to use the embassy repo in path ``` -gh repo clone esp-rs/esp-hal 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 -* 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 - +For now +``` +cargo run --example embassy_hello_world --features "default","embassy","embassy-time-timg0" +``` diff --git a/examples/esp32c3/build.rs b/examples/esp32c3/build.rs new file mode 100644 index 00000000..968d07d6 --- /dev/null +++ b/examples/esp32c3/build.rs @@ -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()); +} diff --git a/examples/esp32c3/examples/embassy_hello_world.rs b/examples/esp32c3/examples/embassy_hello_world.rs new file mode 100644 index 00000000..d96aefe7 --- /dev/null +++ b/examples/esp32c3/examples/embassy_hello_world.rs @@ -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(); + }); +} diff --git a/examples/esp32c3/ld/bl-esp32c3-memory.x b/examples/esp32c3/ld/bl-esp32c3-memory.x new file mode 100644 index 00000000..88d2c44f --- /dev/null +++ b/examples/esp32c3/ld/bl-esp32c3-memory.x @@ -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*/ +} diff --git a/examples/esp32c3/ld/bl-linkall.x b/examples/esp32c3/ld/bl-linkall.x new file mode 100644 index 00000000..02895e4f --- /dev/null +++ b/examples/esp32c3/ld/bl-linkall.x @@ -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" diff --git a/examples/esp32c3/ld/bl-riscv-link.x b/examples/esp32c3/ld/bl-riscv-link.x new file mode 100644 index 00000000..1ee26c10 --- /dev/null +++ b/examples/esp32c3/ld/bl-riscv-link.x @@ -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" + diff --git a/examples/esp32c3/ld/db-esp32c3-link.x b/examples/esp32c3/ld/db-esp32c3-link.x new file mode 100644 index 00000000..63ba963a --- /dev/null +++ b/examples/esp32c3/ld/db-esp32c3-link.x @@ -0,0 +1,14 @@ +INCLUDE memory.x + +SECTIONS +{ + .header : AT(0) + { + LONG(0xaedb041d) + LONG(0xaedb041d) + } > IROM +} + +_stext = ORIGIN(IROM) + 8; + +INCLUDE riscv-link.x diff --git a/examples/esp32c3/ld/db-esp32c3-memory.x b/examples/esp32c3/ld/db-esp32c3-memory.x new file mode 100644 index 00000000..e38db1de --- /dev/null +++ b/examples/esp32c3/ld/db-esp32c3-memory.x @@ -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); diff --git a/examples/esp32c3/ld/db-linkall.x b/examples/esp32c3/ld/db-linkall.x new file mode 100644 index 00000000..02bc894c --- /dev/null +++ b/examples/esp32c3/ld/db-linkall.x @@ -0,0 +1,3 @@ +INCLUDE "esp32c3-link.x" +INCLUDE "hal-defaults.x" +INCLUDE "rom-functions.x" diff --git a/examples/esp32c3/ld/db-riscv-link.x b/examples/esp32c3/ld/db-riscv-link.x new file mode 100644 index 00000000..777951ac --- /dev/null +++ b/examples/esp32c3/ld/db-riscv-link.x @@ -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 | */ diff --git a/examples/esp32c3/ld/mb-esp32c3-link.x b/examples/esp32c3/ld/mb-esp32c3-link.x new file mode 100644 index 00000000..0b44b527 --- /dev/null +++ b/examples/esp32c3/ld/mb-esp32c3-link.x @@ -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; diff --git a/examples/esp32c3/ld/mb-esp32c3-memory.x b/examples/esp32c3/ld/mb-esp32c3-memory.x new file mode 100644 index 00000000..8c7ec6bd --- /dev/null +++ b/examples/esp32c3/ld/mb-esp32c3-memory.x @@ -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); diff --git a/examples/esp32c3/ld/mb-linkall.x b/examples/esp32c3/ld/mb-linkall.x new file mode 100644 index 00000000..02bc894c --- /dev/null +++ b/examples/esp32c3/ld/mb-linkall.x @@ -0,0 +1,3 @@ +INCLUDE "esp32c3-link.x" +INCLUDE "hal-defaults.x" +INCLUDE "rom-functions.x" diff --git a/examples/esp32c3/ld/mb-riscv-link.x b/examples/esp32c3/ld/mb-riscv-link.x new file mode 100644 index 00000000..52b1ba73 --- /dev/null +++ b/examples/esp32c3/ld/mb-riscv-link.x @@ -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 | */ diff --git a/examples/esp32c3/ld/rom-functions.x b/examples/esp32c3/ld/rom-functions.x new file mode 100644 index 00000000..cd57ab6a --- /dev/null +++ b/examples/esp32c3/ld/rom-functions.x @@ -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);