hackndev / zinc

The bare metal stack for rust
zinc.rs
Apache License 2.0
1k stars 100 forks source link

ISR vectors not linked when NOTHING from zinc crate is used. #295

Open mcoffin opened 9 years ago

mcoffin commented 9 years ago

If an application uses nothing from the zinc crate, then the ISR vectors will not be linked, despite the KEEP directive in the linker script.

mcoffin commented 9 years ago

For app that uncovered this, see app_empty from mcoffin@b9a9d4fdfdd7df09ffa0513ea54784acca283dd0

bharrisau commented 9 years ago

I'd prefer to move ISR vectors to PT and zinc_main macros. We currently simplify things by saying all k20 have the same ISRs, but they really don't. Even in the same speed grade the peripherals change.

I'll do up a JSON device and board definition for a Teensy and see how that feels. The makefile or build.rs would ideally also use that info when creating the linker script, as we again just simplify and overestimate the number of vendor ISRs (for the size of vector flash).

For app that uncovered this, see app_empty from mcoffin@b9a9d4f https://github.com/mcoffin/zinc/commit/b9a9d4fdfdd7df09ffa0513ea54784acca283dd0

— Reply to this email directly or view it on GitHub https://github.com/hackndev/zinc/issues/295#issuecomment-107338127.

mcoffin commented 9 years ago

I'd prefer to move ISR vectors to PT and zinc_main macros

:+1:

mcoffin commented 9 years ago

@bharrisau Actually, neither of those macros are a good fit. platformtree can't be used in non-platformtree examples and the zinc_main annotation cannot be used from within platformtree as it's entire purpose is to define a dummy #[start] implementation for those who aren't using platformtree.

If we're going to take the macro-based approach instead of the linker-based approach, then what we really want is a new crate level attribute, zinc_board added to macro_zinc once #288 gets reviewed and lands. This crate-level attribute would emit the ISR vectors. For example, non-platformtree examples could have #![zinc_board="some_board"] and then platformtree examples could just emit that exact same attribute as an item from the platformtree! macro. That way there's no repetition of code.

To be honest, this should really come after some kind of comprehensive "board abstraction" RFC because the second you try to implement that attribute, you're going to run in to the exact same problem that the current platformtree does in that you need a significant amount of macro code for every single board (well for platformtree it's for every platform, but still the same basic problem).

mcoffin commented 9 years ago

One way we could solve that problem is by doing something like the following hack...

quote_item!(cx, include!("path/to/platform/board_isr.rs"));

That way it at least appears as if you're writing native code and not macro code for every board.

farcaller commented 9 years ago

We can also make a little dedicated macro to just build the isr table.

mcoffin commented 9 years ago

Well, that's what zinc_board would be. Maybe a better name would be zinc_isr. The advantage of being a crate-level attribute is being able to enforce invoking it only at the crate level (and I guess, at least to me, it feels more idiomatic).

mokus0 commented 9 years ago

I saw this as well, in both the empty and blink_stm32f4 examples. After a while banging my head against the linker script trying to figure out why the heck KEEP wasn't keeping it, I finally thought to look at the linker input (zinc's rlib) and found that ISRVectors was being put in .rodata rather than .isr_vector. Turns out this was a known issue (https://github.com/rust-lang/rust/issues/27467) in rustc, resolved a few days ago. Pulled a new rustc nightly, and it was magically fixed.