Make Priority::get() public.
This will allow to safely get priority of a current task and implement various loggers with lockless queues for each priority level.
Hi, sorry for missing this PR.
Could you show a PoC for this? I'm not sure how making the get function public would help as this is not a part of the context.
Else you can extract the priority from the NVIC, which would not give you a dependency of RTIC.
Hi, I only investigated the possibility of implementing logging functionality through separate queues for each priority level. Didn't had time to implement it yet. There was some discussions in defmt, maybe it's already solved by now. As for the NVIC, one advantage of Priority::get() is that it returns logical priority, not hardware one, or I'm mistaken here?
The hardware and logical priority is a simple conversion function, so in the end you'd get the same. And it's the hardware priority that is important, so that you have one queue per hardware priority in use.
You can check out the conversion function here: https://github.com/rtic-rs/cortex-m-rtic/blob/master/src/export.rs#L190
I'm also using execution priority for lock-free queues for Defmt logging. I certainly would've appreciated RTIC providing a way to get the current priority easily.
Here's the code I use to get the current execution priority:
/// Returns the current execution priority
///
/// **NOTE:** This does not return hardware priority levels but converts them to an easier form.
/// Higher numbers represent higher priorities, starting at zero. The max regular priority is 15,
/// above that is HardFault(16) and NonMaskableInt(17).
pub fn current_priority() -> u8 {
use cortex_m::peripheral::scb::{Exception, SystemHandler, VectActive};
use cortex_m::peripheral::{NVIC, SCB};
// IPSR should be slightly faster than SCB.ICSR
let ipsr: u32;
unsafe {
asm!("mrs {}, IPSR", out(reg) ipsr);
}
let vect_active = VectActive::from(ipsr as u8).unwrap_or(VectActive::ThreadMode);
match vect_active {
VectActive::ThreadMode => 0,
VectActive::Exception(ex) => {
let sysh = match ex {
Exception::MemoryManagement => SystemHandler::MemoryManagement,
Exception::BusFault => SystemHandler::BusFault,
Exception::UsageFault => SystemHandler::UsageFault,
Exception::SVCall => SystemHandler::SVCall,
Exception::DebugMonitor => SystemHandler::DebugMonitor,
Exception::PendSV => SystemHandler::PendSV,
Exception::SysTick => SystemHandler::SysTick,
Exception::HardFault => return 16,
Exception::NonMaskableInt => return 17,
};
16 - (SCB::get_priority(sysh) >> 4)
}
VectActive::Interrupt { irqn } => {
16 - (NVIC::get_priority(InterruptNumber(irqn - 16)) >> 4)
}
}
}
If you can't use inline asm, you can instead read the active vector from SCB.ICSR. You may have to change the shifts based on how many interrupt priority bits your hardware has.