Skip to content

Commit 80a3e48

Browse files
committed
Re-arranged memory.
BIOS is at the top of the 256 KB block of RAM. Application is at the bottom. Core 0 and Core 1 stacks get the upper two 4KB blocks.
1 parent 014e757 commit 80a3e48

File tree

5 files changed

+342
-112
lines changed

5 files changed

+342
-112
lines changed

Cargo.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ version = "0.2.0"
1111
# Useful Cortex-M specific functions (e.g. SysTick)
1212
cortex-m = "0.7"
1313
# The Raspberry Pi Pico HAL
14-
pico = { git = "https://github.com/rp-rs/rp-hal.git" }
14+
rp-pico = "0.3"
1515
# Cortex-M run-time (or start-up) code
1616
cortex-m-rt = "0.7"
1717
# The BIOS API we export to the OS
@@ -28,12 +28,12 @@ defmt = "0.3"
2828
defmt-rtt = "0.3"
2929
# Send panics to the debugger
3030
panic-probe = "0.2"
31-
# Fetches the BIOS version from git
31+
# Fetches git hashes from git at compile time
3232
git-version = "0.3"
33-
# RP2040 PIO driver
34-
pio = { git = "https://github.com/rp-rs/pio-rs.git", branch = "main" }
35-
# RP2040 PIO driver macros
36-
pio-proc = { git = "https://github.com/rp-rs/pio-rs.git", branch = "main" }
33+
# RP2040 PIO assembler
34+
pio = "0.2"
35+
# Macros for RP2040 PIO assembler
36+
pio-proc = "0.2"
3737

3838
[features]
3939
default = [

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,18 +47,18 @@ The Neotron BIOS uses the [defmt](https://crates.io/crates/defmt) crate to provi
4747

4848
2. Flash your *Debugger* Pico with https://github.com/majbthrd/DapperMime firmware (e.g. by copying the UF2 file to the USB Mass Storage device)
4949

50-
3. On your PC, install *probe-rs-rp* from the RP2040-specific [probe-run](https://github.com/knurling-rs/probe-run) fork at https://github.com/rp-rs/probe-run.
50+
3. On your PC, install [*probe-rs*](https://github.com/knurling-rs/probe-run), the programming tool from [Ferrous System's](https://www.ferrous-systems.com) [Knurling Project](https://github.com/knurling).
5151

5252
```console
53-
user@host ~ $ cargo install probe-rs-rp
53+
user@host ~ $ cargo install probe-rs
5454
```
5555

5656
4. Power on your Neotron Pico.
5757

58-
5. Build and load the Neotron BIOS, and view the debug output stream, with `cargo run`:
58+
5. Build and load the Neotron BIOS, and view the debug output stream, with `cargo run --release`:
5959

6060
```console
61-
user@host ~/neotron-pico-bios $ cargo run --release
61+
user@host ~/neotron-pico-bios $ DEFMT_LOG=debug cargo run --release
6262
Compiling neotron-pico-bios v0.1.0 (/home/jonathan/Documents/neotron/neotron-pico-bios)
6363
Finished release [optimized + debuginfo] target(s) in 0.76s
6464
Running `probe-run-rp --chip RP2040 target/thumbv6m-none-eabi/release/neotron-pico-bios`
@@ -75,6 +75,8 @@ user@host ~/neotron-pico-bios $ cargo run --release
7575
└─ neotron_pico_bios::__cortex_m_rt_main @ src/main.rs:128
7676
```
7777

78+
You should see your Neotron Pico boot, both over RTT in the `probe-run` output, and also on the VGA output.
79+
7880
## Changelog
7981

8082
See [CHANGELOG.md](./CHANGELOG.md)

memory.x

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,46 @@ MEMORY {
2121
/*
2222
* This is the remainder of the 2048 KiB flash chip.
2323
*/
24-
FLASH_OS: ORIGIN = 0x10020000, LENGTH = 2048K - 128K
24+
FLASH_OS : ORIGIN = 0x10020000, LENGTH = 2048K - 128K
2525
/*
26-
* This is the internal SRAM in the RP2040.
26+
* This is the bottom of the four striped banks of SRAM in the RP2040.
2727
*/
28-
RAM : ORIGIN = 0x20000000, LENGTH = 256K
28+
RAM_OS : ORIGIN = 0x20000000, LENGTH = 0x3C000
29+
/*
30+
* This is the top of the four striped banks of SRAM in the RP2040.
31+
*/
32+
RAM : ORIGIN = 0x2003C000, LENGTH = 16K
33+
/*
34+
* This is the fifth bank, a 4KB block. We use this for Core 0 Stack.
35+
*/
36+
RAM_CORE0_STACK : ORIGIN = 0x20040000, LENGTH = 4K
37+
/*
38+
* This is the sixth bank, a 4KB block. We use this for Core 1 Stack.
39+
*/
40+
RAM_CORE1_STACK : ORIGIN = 0x20041000, LENGTH = 4K
2941
}
30-
/* This is where the call stack will be allocated. */
31-
/* The stack is of the full descending type. */
32-
/* You may want to use this variable to locate the call stack and static
33-
variables in different memory regions. Below is shown the default value */
34-
_stack_start = ORIGIN(RAM) + LENGTH(RAM);
42+
43+
/*
44+
* This is where the call stack for Core 0 will be located. The stack is of
45+
* the full descending type. You may want to use this variable to locate the
46+
* call stack and static variables in different memory regions. Below is
47+
* shown the default value
48+
*/
49+
_stack_start = ORIGIN(RAM_CORE0_STACK) + LENGTH(RAM_CORE0_STACK);
50+
51+
/*
52+
* This is where the call stack for Core 1 will be located.
53+
*/
54+
_core1_stack_bottom = ORIGIN(RAM_CORE1_STACK);
55+
_core1_stack_len = LENGTH(RAM_CORE1_STACK);
3556

3657
/*
3758
* Export some symbols to tell the BIOS where it might find the OS.
3859
*/
3960
_flash_os_start = ORIGIN(FLASH_OS);
4061
_flash_os_len = LENGTH(FLASH_OS);
62+
_ram_os_start = ORIGIN(RAM_OS);
63+
_ram_os_len = LENGTH(RAM_OS);
4164

4265
SECTIONS {
4366
/* ### RP2040 Boot loader */

src/main.rs

Lines changed: 61 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ pub mod vga;
4444
// -----------------------------------------------------------------------------
4545

4646
use cortex_m_rt::entry;
47-
use defmt::*;
47+
use defmt::info;
4848
use defmt_rtt as _;
4949
use embedded_hal::digital::v2::OutputPin;
5050
use embedded_time::rate::*;
5151
use git_version::git_version;
5252
use panic_probe as _;
53-
use pico::{
53+
use rp_pico::{
5454
self,
5555
hal::{
5656
self,
@@ -68,16 +68,6 @@ use pico::{
6868
// Static and Const Data
6969
// -----------------------------------------------------------------------------
7070

71-
/// This is the standard RP2040 bootloader. It must be stored in the first 256
72-
/// bytes of the external SPI Flash chip. It will map the external SPI flash
73-
/// chip to address `0x1000_0000` and jump to an Interrupt Vector Table at
74-
/// address `0x1000_0100` (i.e. immediately after the bootloader).
75-
///
76-
/// See `memory.x` for a definition of the `.boot2` section.
77-
#[link_section = ".boot2"]
78-
#[used]
79-
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080;
80-
8171
/// BIOS version
8272
const GIT_VERSION: &str = git_version!();
8373

@@ -88,7 +78,10 @@ static TEXT_CONSOLE: vga::TextConsole = vga::TextConsole::new();
8878
// Functions
8979
// -----------------------------------------------------------------------------
9080

91-
/// Prints to the screen
81+
/// Prints to the screen.
82+
///
83+
/// This function is NOT interrupt safe. Only call from the main thread, on
84+
/// core 1.
9285
#[macro_export]
9386
macro_rules! print {
9487
($($arg:tt)*) => {
@@ -99,7 +92,10 @@ macro_rules! print {
9992
};
10093
}
10194

102-
/// Prints to the screen and puts a new-line on the end
95+
/// Prints to the screen and puts a new-line on the end.
96+
///
97+
/// This function is NOT interrupt safe. Only call from the main thread, on
98+
/// core 1.
10399
#[macro_export]
104100
macro_rules! println {
105101
() => (print!("\n"));
@@ -136,12 +132,12 @@ fn main() -> ! {
136132

137133
// Run at 126 MHz SYS_PLL, 48 MHz, USB_PLL
138134

139-
let xosc = hal::xosc::setup_xosc_blocking(pac.XOSC, pico::XOSC_CRYSTAL_FREQ.Hz())
135+
let xosc = hal::xosc::setup_xosc_blocking(pac.XOSC, rp_pico::XOSC_CRYSTAL_FREQ.Hz())
140136
.map_err(|_x| false)
141137
.unwrap();
142138

143139
// Configure watchdog tick generation to tick over every microsecond
144-
watchdog.enable_tick_generation((pico::XOSC_CRYSTAL_FREQ / 1_000_000) as u8);
140+
watchdog.enable_tick_generation((rp_pico::XOSC_CRYSTAL_FREQ / 1_000_000) as u8);
145141

146142
let mut clocks = hal::clocks::ClocksManager::new(pac.CLOCKS);
147143

@@ -183,7 +179,7 @@ fn main() -> ! {
183179
let mut sio = hal::sio::Sio::new(pac.SIO);
184180

185181
// Configure and grab all the RP2040 pins the Pico exposes.
186-
let pins = pico::Pins::new(
182+
let pins = rp_pico::Pins::new(
187183
pac.IO_BANK0,
188184
pac.PADS_BANK0,
189185
sio.gpio_bank0,
@@ -223,11 +219,57 @@ fn main() -> ! {
223219

224220
TEXT_CONSOLE.set_text_buffer(unsafe { &mut vga::CHAR_ARRAY });
225221

226-
info!("VGA intialised");
222+
for _col in 0..vga::NUM_TEXT_ROWS {
223+
println!();
224+
}
225+
226+
TEXT_CONSOLE.move_to(0, 0);
227+
228+
println!("Neotron Pico BIOS, for the Raspberry Pi RP2040");
229+
println!("Copyright © Jonathan 'theJPster' Pallant and the Neotron Developers, 2021");
230+
println!("Version {}", GIT_VERSION);
231+
println!();
232+
println!("This program is free software: you can redistribute it and/or modify");
233+
println!("it under the terms of the GNU General Public License as published by");
234+
println!("the Free Software Foundation, either version 3 of the License, or");
235+
println!("(at your option) any later version.");
236+
println!();
237+
println!("This program is distributed in the hope that it will be useful,");
238+
println!("but WITHOUT ANY WARRANTY; without even the implied warranty of");
239+
println!("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the");
240+
println!("GNU General Public License for more details.");
241+
println!();
242+
println!("You should have received a copy of the GNU General Public License");
243+
println!("along with this program. If not, see https://www.gnu.org/licenses/.");
244+
println!();
245+
println!("Searching for Neotron OS...");
246+
247+
extern "C" {
248+
static mut _flash_os_start: u32;
249+
static mut _flash_os_len: u32;
250+
static mut _ram_os_start: u32;
251+
static mut _ram_os_len: u32;
252+
}
253+
254+
let flash_os_start = unsafe {
255+
&mut _flash_os_start as *mut u32 as usize
256+
};
257+
let flash_os_len = unsafe {
258+
&mut _flash_os_len as *mut u32 as usize
259+
};
260+
let ram_os_start = unsafe {
261+
&mut _ram_os_start as *mut u32 as usize
262+
};
263+
let ram_os_len = unsafe {
264+
&mut _ram_os_len as *mut u32 as usize
265+
};
266+
267+
println!("OS Flash is {:08x}, {} bytes", flash_os_start, flash_os_len);
268+
println!("OS RAM is {:08x}, {} bytes", ram_os_start, ram_os_len);
227269

228270
let mut x: u32 = 0;
229271
loop {
230-
println!("x = {}", x);
272+
print!("\rx = {}", x);
231273
x = x.wrapping_add(1);
232274
}
233275
}

0 commit comments

Comments
 (0)