6个版本
0.2.1 | 2020年3月2日 |
---|---|
0.2.0 | 2020年3月2日 |
0.1.3 | 2020年1月14日 |
0.1.2 | 2019年11月21日 |
#1761 在 嵌入式开发
每月33次下载
22KB
133 行
Cortex-M中断移动
这是移动到中断上下文的最佳选择。
示例
请查看app-examples
文件夹中的完整示例。
目标
这里的目的是替换可能需要整个临界区的互斥锁的使用,而是将数据“移动”到中断上下文中。
这意味着我们不需要临界区来访问它,只需要我们处于移动数据的那个中断中。
这是如何工作的
#![no_std]
#![no_main]
// Panic provider crate
use panic_halt as _;
// CMIM items
use cmim::{
Move,
Context,
Exception,
};
// Used to set the program entry point
use cortex_m_rt::{entry, exception};
use embedded_hal::timer::Cancel;
// Provides definitions for our development board
use dwm1001::{
cortex_m::peripheral::syst::SystClkSource::Core,
nrf52832_hal::{
nrf52832_pac::{interrupt, Interrupt, TIMER1, UARTE0},
prelude::*,
Timer, Uarte,
},
DWM1001,
};
static TIMER_1_DATA: Move<Timer1Data, Interrupt> = Move::new_uninitialized(Context::Interrupt(Interrupt::TIMER1));
static SYSTICK_DATA: Move<SysTickData, Interrupt> = Move::new_uninitialized(Context::Exception(Exception::SysTick));
struct Timer1Data {
uart: Uarte<UARTE0>,
timer: Timer<TIMER1>,
led: dwm1001::Led,
toggle: bool,
}
struct SysTickData {
led: dwm1001::Led,
toggle: bool,
}
#[entry]
fn main() -> ! {
if let Some(mut board) = DWM1001::take() {
let mut timer = board.TIMER0.constrain();
let mut _rng = board.RNG.constrain();
let mut itimer = board.TIMER1.constrain();
itimer.start(1_000_000u32);
itimer.enable_interrupt(&mut board.NVIC);
// Core clock is 64MHz, blink at 16Hz
board.SYST.set_clock_source(Core);
board.SYST.set_reload(4_000_000 - 1);
board.SYST.enable_counter();
board.SYST.enable_interrupt();
TIMER_1_DATA
.try_move(Timer1Data {
uart: board.uart,
timer: itimer,
led: board.leds.D9,
toggle: false,
})
.ok();
SYSTICK_DATA
.try_move(SysTickData {
led: board.leds.D12,
toggle: false,
})
.ok();
let mut toggle = false;
loop {
// board.leds.D9 - Top LED GREEN
// board.leds.D12 - Top LED RED
// board.leds.D11 - Bottom LED RED
// board.leds.D10 - Bottom LED BLUE
if toggle {
board.leds.D10.enable();
} else {
board.leds.D10.disable();
}
toggle = !toggle;
timer.delay(250_000);
}
}
loop {
continue;
}
}
#[exception]
fn SysTick() {
SYSTICK_DATA
.try_lock(|data| {
// Blink the LED
if data.toggle {
data.led.enable();
} else {
data.led.disable();
}
data.toggle = !data.toggle;
})
.ok();
}
#[interrupt]
fn TIMER1() {
TIMER_1_DATA
.try_lock(|data| {
// Start the timer again first for accuracy
data.timer.cancel().unwrap();
data.timer.start(1_000_000u32);
// Write message to UART. The NRF UART requires data
// to be in RAM, not flash.
const MSG_BYTES: &[u8] = "Blink!\r\n".as_bytes();
let mut buf = [0u8; MSG_BYTES.len()];
buf.copy_from_slice(MSG_BYTES);
data.uart.write(&buf).unwrap();
// Blink the LED
if data.toggle {
data.led.enable();
} else {
data.led.disable();
}
data.toggle = !data.toggle;
})
.ok();
}
许可证
以下任一许可证下授权:
-
Apache License,版本2.0 (LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
-
MIT许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任选其一。
贡献
除非你明确声明,否则根据Apache-2.0许可证定义的,你提交给作品以供包含的任何贡献将如上所述双许可,不附加任何额外条款或条件。
依赖项
~1MB
~12K SLoC