Closed
Description
I'm trying to add an interrupt handler to TIMER1_COMPA
to flash PB5. Here's what I tried:
#[no_mangle]
pub unsafe extern "avr-interrupt" fn __vector_11() {
volatile_store(PORTB, volatile_load(PORTB) ^ MASK);
}
simavr
reports that the generated executable goes wrong after running the handler twice:
CORE: *** Invalid read address PC=0136 SP=2022 O=901f Address 2023 out of ram (08ff)
avr_sadly_crashed
Standalone, full test case:
#![feature(no_core)]
#![feature(lang_items)]
#![feature(fundamental)]
#![feature(intrinsics)]
#![feature(optin_builtin_traits)]
#![feature(asm)]
#![feature(abi_avr_interrupt)]
#![no_core]
#![no_main]
mod clone {
use marker::Sized;
pub trait Clone : Sized {
fn clone(&self) -> Self;
#[inline(always)]
fn clone_from(&mut self, source: &Self) {
*self = source.clone()
}
}
}
mod marker {
use clone::Clone;
#[lang = "sized"]
#[fundamental]
pub trait Sized {}
#[lang = "copy"]
pub trait Copy : Clone {}
#[lang = "freeze"]
unsafe trait Freeze {}
unsafe impl Freeze for .. {}
}
mod ops {
#[lang = "bitor"]
pub trait BitOr {
fn bitor(self, rhs: Self) -> Self;
}
impl BitOr for u8 {
#[inline]
fn bitor(self, rhs: u8) -> u8 { self | rhs }
}
#[lang = "bitxor"]
pub trait BitXor {
fn bitxor(self, rhs: Self) -> Self;
}
impl BitXor for u8 {
#[inline]
fn bitxor(self, other: u8) -> u8 { self ^ other }
}
}
mod intrinsics {
extern "rust-intrinsic" {
pub fn volatile_load<T>(src: *const T) -> T;
pub fn volatile_store<T>(dst: *mut T, val: T);
}
}
use intrinsics::{volatile_load, volatile_store};
mod avr {
pub const DDRB: *mut u8 = 0x24 as *mut u8;
pub const PORTB: *mut u8 = 0x25 as *mut u8;
pub const TCCR1B: *mut u8 = 0x81 as *mut u8;
pub const TIMSK1: *mut u8 = 0x6f as *mut u8;
pub const OCR1A: *mut u16 = 0x88 as *mut u16;
}
use avr::*;
const MASK: u8 = 0b_0010_0000;
#[no_mangle]
pub extern fn main() {
unsafe {
volatile_store(DDRB, volatile_load(DDRB) | MASK);
// Configure timer 1 for CTC mode, with divider of 64
volatile_store(TCCR1B, volatile_load(TCCR1B) | 0b_0000_1101);
// Timer frequency
volatile_store(OCR1A, 62500);
// Enable CTC interrupt
volatile_store(TIMSK1, volatile_load(TIMSK1) | 0b_0000_0010);
// Good to go!
asm!("SEI");
loop {}
}
}
#[no_mangle]
pub unsafe extern "avr-interrupt" fn __vector_11() {
volatile_store(PORTB, volatile_load(PORTB) ^ MASK);
}