Age | Commit message (Collapse) | Author | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
closes #59
|
|
safe `&'static mut` references through a runtime checked macro
runtime checked implementation of japaric/cortex-m-rtfm#59 that doesn't depend on RTFM macros
TODO
- [ ] bikeshed macro syntax
|
|
|
|
revise peripheral API
This PR changes the signature of many of the high level methods available on peripherals like
`NVIC::get_priority`. Additionally some instance methods have been turned into static methods. The
following guidelines have been used to apply the changes:
- If the method body contains a single, atomic read operation with *no* side effects (e.g. the read
operation clears one of the bits of the register): the signature changed to make the method
static, i.e. `&self` was removed from the signature.
- If the method involves writing to or a RMW operation on a register: the signature changed to take
the singleton by `&mut self` reference.
- If the method involves only read operations where at least one of them modifies the value
of a register: the signature changed to take the singleton by `&mut self` reference.
The rationale for this last guideline is that using `&self`, instead of `&mut self`, lets the user
(unintentionally) break abstractions in the presence of generators. Example below:
``` rust
let peripherals = Peripherals::take().unwrap();
let syst = &peripherals.SYST;
// tasks
let mut a = || {
loop {
// yielding "busy wait"
while !a.has_wrapped() {
yield;
}
// do stuff
}
};
let mut b = || {
// ..
// *NOTE* the problem is in the line below: this `is_counter_enabled` method reads the CSR
// register and that read operation clears the COUNTFLAG bit of the register (if set), which is
// the bit the `has_wrapped` method checks for.
if syst.is_counter_enabled() {
// ..
}
// ..
};
```
One more guideline was considered but the required conditions didn't apply to any of the existing
methods:
- If the method involves only non side effectful, non necessarily atomic read operations: the
signature of the method should remain as `&self`.
The rationale for this guideline is that a static method (no `self` argument) wouldn't be
appropriate because that can result in a torn read if the read operation can be preempted by some
context that modifies the register.
In any case, this last guideline doesn't seem to apply well to the peripherals structs exposed by
this crate because they *deref* to a `RegisterBlock` that allows mutation through a `&self`
reference. When these two properties (the guideline and `Deref<Target=RegisterBlock>`) are mixed
the user can potentially break abstractions using generators (as shown in the `syst` example).
cc @hannobraun
closes #67
|
|
|
|
|
|
add a Cargo feature, cm7-r0p1, to fix a Cortex-M7 BASEPRI erratum
see japaric/cortex-m-rtfm#53 for background information
|
|
this prevents people from overlapping non-atomic write operations on the same stimulus port when
working with generators (cooperative tasks).
For example, with this change the following code won't compile
``` rust
let stim = &mut ITM.stim[0];
let a = || {
loop {
// ..
for byte in b"Hello, world!".iter() {
while !stim.is_fifo_ready() { yield }
stim.write_u8(*byte);
}
// ..
}
};
let b = || {
loop {
// ..
for byte in b"The quick brown fox jumps over the lazy dog".iter() {
while !stim.is_fifo_ready() { yield }
stim.write_u8(*byte);
}
// ..
}
};
```
A possible fix for the above code is to use different stimulus ports in each task (generator).
|
|
|
|
closes #67
|
|
|
|
|
|
|
|
closes #44
|
|
On ARMv6-M, anything but world-aligned access to the IPR registers will
lead to unpredictable results.
Fixes #61.
|
|
According to the ARMv7-M Technical Reference Manual[1], there are 124
IPR registers available on ARMv7-M, and 16 of all others. I don't know
where the original numbers came from, since on ARMv6-M, there are only 8
IPR registers available, and 1 of each of the others.[2]
This commit removes some test cases that were checking the address of
the last register. Since the last register has changed, those are no
longer applicable. I decided to remove instead of update them, since
they only really test the length of each register type, which is obvious
enough from the code.
[1]: https://silver.arm.com/download/ARM_and_AMBA_Architecture/AR580-DA-70000-r0p0-05rel0/DDI0403E_B_armv7m_arm.pdf
[2]: https://silver.arm.com/download/ARM_and_AMBA_Architecture/AR585-DA-70000-r0p0-00rel0/DDI0419C_arm_architecture_v6m_reference_manual.pdf
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
closes #50
|
|
the functionality is not fundamental and can be easily added to a program by
directly depending on cortex-m-semihosting
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[breaking-change]
|
|
this is mainly to avoid adding custom cfg logic to svd2rust generated crates
where all the core peripherals are re-exported. (I'd rather not have to teach
svd2rust how to generate a build script)
|
|
|
|
closes #49
|
|
don't expose registers clidr, ctr, ccsidr, csselr to ARMv6-M targets
as these are only available on ARMv7-M devices
|
|
|
|
|