Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add global HSEM object and shared memory sample #6

Merged
merged 3 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .zed/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
"allTargets": false,
"targets": "thumbv7em-none-eabihf"
},
"linkedProjects": [
"./core0/Cargo.toml",
"./core1/Cargo.toml",
"./stm32h7hal-ext/Cargo.toml"
],
"inlayHints": {
"maxLength": null,
"lifetimeElisionHints": {
Expand Down
37 changes: 37 additions & 0 deletions .zed/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Static tasks configuration.
[
{
"label": "Build Core 0",
"command": "cargo build",
//"args": ["build"],
// Env overrides for the command, will be appended to the terminal's environment from the settings.
// "env": { "foo": "bar" },
// Current working directory to spawn the command into, defaults to current project root.
"cwd": "$ZED_WORKTREE_ROOT/core0",
// Whether to use a new terminal tab or reuse the existing one to spawn the process, defaults to `false`.
"use_new_terminal": false,
// Whether to allow multiple instances of the same task to be run, or rather wait for the existing ones to finish, defaults to `false`.
"allow_concurrent_runs": false
// What to do with the terminal pane and tab, after the command was started:
// * `always` — always show the terminal pane, add and focus the corresponding task's tab in it (default)
// * `never` — avoid changing current terminal pane focus, but still add/reuse the task's tab there
//"reveal": "always"
},
{
"label": "Build Core 1",
"command": "cargo build",
//"args": ["build"],
// Env overrides for the command, will be appended to the terminal's environment from the settings.
// "env": { "foo": "bar" },
// Current working directory to spawn the command into, defaults to current project root.
"cwd": "$ZED_WORKTREE_ROOT/core1",
// Whether to use a new terminal tab or reuse the existing one to spawn the process, defaults to `false`.
"use_new_terminal": false,
// Whether to allow multiple instances of the same task to be run, or rather wait for the existing ones to finish, defaults to `false`.
"allow_concurrent_runs": false
// What to do with the terminal pane and tab, after the command was started:
// * `always` — always show the terminal pane, add and focus the corresponding task's tab in it (default)
// * `never` — avoid changing current terminal pane focus, but still add/reuse the task's tab there
//"reveal": "always"
}
]
29 changes: 17 additions & 12 deletions core0/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions core0/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ embedded-storage = "0.3.1"
static_cell = "2"
chrono = { version = "^0.4", default-features = false }
stm32h7hal-ext = { version = "0.1.0", path = "../stm32h7hal-ext" }
shared = { version = "0.1.0", path = "../shared" }

# [patch."https://github.com/esrlabs/embassy"]
# embassy-stm32 = { path = "../../embassy/embassy-stm32" }
# embassy-sync = { path = "../../embassy/embassy-sync" }
Expand Down
4 changes: 2 additions & 2 deletions core0/memory.x
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ SECTIONS {
*(.sram3 .sram3.*);
. = ALIGN(4);
} > SRAM3
.sram4 (NOLOAD) : ALIGN(4) {
*(.sram4 .sram4.*);
.shared (NOLOAD) : ALIGN(4) {
*(.sram4 .sram4.* .shared .shared.*);
. = ALIGN(4);
} > SRAM4
.bsram (NOLOAD) : ALIGN(4) {
Expand Down
70 changes: 62 additions & 8 deletions core0/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![no_std]
#![no_main]

#![feature(sync_unsafe_cell)]
use core::cell::SyncUnsafeCell;
use cortex_m::peripheral::NVIC;
use defmt::*;
use embassy_executor::Spawner;
Expand All @@ -9,20 +10,32 @@ use hal::{
bind_interrupts,
gpio::{Level, Output, Speed},
hsem::{HardwareSemaphore, InterruptHandler},
peripherals, Config,
peripherals::{self, HSEM},
Config,
};
use {
defmt_rtt as _, embassy_stm32 as hal, panic_probe as _, shared as _, stm32h7hal_ext as hal_ext,
};
use {defmt_rtt as _, embassy_stm32 as hal, panic_probe as _, stm32h7hal_ext as hal_ext};

bind_interrupts!(
struct Irqs {
HSEM1 => InterruptHandler<peripherals::HSEM>;
}
);

// SAFETY: This is safe because all access to the HSEM registers are atomic
static HSEM_INSTANCE: SyncUnsafeCell<Option<HardwareSemaphore<'static, HSEM>>> =
SyncUnsafeCell::new(None);

#[embassy_executor::main]
async fn main(_spawner: Spawner) {
info!("Core0: STM32H755 Embassy HSEM Test.");

unsafe {
for i in 0..10 {
shared::MAILBOX[i] = 0;
}
}
// Wait for Core1 to be finished with its init
// tasks and in Stop mode
hal_ext::wait_for_core1();
Expand Down Expand Up @@ -68,29 +81,35 @@ async fn main(_spawner: Spawner) {
let mut led_green = Output::new(p.PB0, Level::Low, Speed::Low);
let mut led_red = Output::new(p.PB14, Level::Low, Speed::Low);

let mut hsem = HardwareSemaphore::new(p.HSEM, Irqs);
let hsem = HardwareSemaphore::new(p.HSEM, Irqs);

// initialize global HSEM instance
unsafe { *HSEM_INSTANCE.get() = Some(hsem) };

unsafe { NVIC::unmask(embassy_stm32::pac::Interrupt::HSEM1) };
// Take the semaphore for waking Core1 (CM4)
if let Err(_err) = hsem.one_step_lock(0) {
if !get_global_hsem().one_step_lock(0) {
info!("Error taking semaphore 0");
} else {
info!("Semaphore 0 taken");
}

let mut core_1_blink_delay = 500;
set_core1_blink_delay(core_1_blink_delay).await;

// Wake Core1 (CM4)
hsem.unlock(0, 0);
get_global_hsem().unlock(0, 0);
info!("Core1 (CM4) woken");
led_green.set_high();
Timer::after_millis(250).await;
led_green.set_low();

info!("Waiting for Sem 1");
let _ = hsem.wait_unlocked(1).await;
let _ = get_global_hsem().wait_unlocked(1).await;
led_green.set_high();
led_red.set_high();
info!("Waiting for Sem 2");
let _ = hsem.wait_unlocked(2).await;
let _ = get_global_hsem().wait_unlocked(2).await;
led_red.set_low();
led_green.set_low();

Expand All @@ -102,5 +121,40 @@ async fn main(_spawner: Spawner) {
led_red.set_high();
Timer::after_millis(500).await;
led_red.set_low();
info!("Set Core 1 blink delay {}", core_1_blink_delay);
set_core1_blink_delay(core_1_blink_delay).await;
if core_1_blink_delay < 100 {
core_1_blink_delay = 500;
}
core_1_blink_delay -= 50;
}
}

async fn set_core1_blink_delay(freq: u32) {
let mut retry = 10;
while !get_global_hsem().lock(5).await && retry > 0 {
Timer::after_micros(50).await;
retry -= 1;
}
if retry > 0 {
//let mut mailbox = *shared::MAILBOX.get() as [u32; 10];
unsafe {
shared::MAILBOX[0] = freq;
};

get_global_hsem().unlock(5, 0);
} else {
// Core1 has asquired the semaphore and is
// not releasing it - crashed?
defmt::panic!("Failed to asquire semaphore 1");
}
}

fn get_global_hsem() -> &'static mut HardwareSemaphore<'static, HSEM> {
unsafe {
match *HSEM_INSTANCE.get() {
Some(ref mut obj) => obj,
None => defmt::panic!("HardwareSemaphore was not initialized"),
}
}
}
Loading
Loading