rtic icon indicating copy to clipboard operation
rtic copied to clipboard

Maximum Task Priority

Open noahzarro opened this issue 2 years ago • 5 comments

The book states, that task priorities are in range 1..=(1 << NVIC_PRIO_BITS), where NVIC_PRIO_BITS could be up to 8 bits. The logical priority of the monotonic task however is set to 1 << NVIC_PRIO_BITS. In case of NVIC_PRIO_BITS == 8, this would lead to the logical priority being 256, i.e. 1 unit higher than allowed and an overflow would happen. This would make the timer the least prioritized interrupt.

I think the issue is not very urgent, since (to my limited knowledge) cortex-m devices normally do not offer 8 priority bits. However, I stumbled upon this when I was porting RTIC to the RISC-V processor architecture (with the CLIC extension), that offers 8 priority bits.

Best, Noah

noahzarro avatar Jan 19 '23 15:01 noahzarro

Exciting with RISC-V activities! :)

As you might have noted, in export.rs there's this function:

#[inline]
#[must_use]
pub fn logical2hw(logical: u8, nvic_prio_bits: u8) -> u8 {
    ((1 << nvic_prio_bits) - logical) << (8 - nvic_prio_bits)
}

The logical priorities are not quite the same as the hardware/NVIC priorities, as logical2hw handles the translation.

# Lowest RTIC priority: 1 
> ((1 << 8) - 1) << (8 - 8)

  shift(shift(1, 8) − 1, 8 − 8) = 255

# Highest RTIC priority: (1 << 8) = 256
> ((1 << 8) - (1 << 8)) << (8 - 8)

  shift(shift(1, 8) − shift(1, 8), 8 − 8) = 0

AfoHT avatar Jan 22 '23 00:01 AfoHT

Thanks for finding, but the current system is correct! :)

For RISCV support we are officially adding it to RTIC 2. If you feel like it you're welcome to help out work the design so supporting both arm and RISCV goes smoothly. :)

Plus the codegen is RTIC 2 is much simpler, so adding support should be close to trivial. Ping me on matrix if you want to discuss!

korken89 avatar Jan 22 '23 06:01 korken89

Oh, very cool to hear that a new version is in the pipeline!

Yes, I see the logical to hardware transformation, but that's not what I wanted to say. I probably did not express myself properly :) What I meant was that the highest logical RTIC priority is 256, but the function #[must_use] pub fn logical2hw(logical: u8, nvic_prio_bits: u8) -> u8 takes only an u8 as the logical priority input. But 256 (the maximum logical RTIC priority) does not fit into a u8.

noahzarro avatar Jan 24 '23 12:01 noahzarro

Now I see your point, good catch!

error: this literal must be in the range 1...255
  --> ui/task-priority-too-high.rs:46:37
   |
46 |     #[task(binds = I2C1, priority = 256)]
   |                                     ^^^

Trying to put prio 256 would at least not silently fail/overflow but rather explode and not let the user build :)

It simply does not fit in the u8 and Rust will let us know :heart:

What to do about it... I'm a bit hesitant to just throw in a larger type there, especially as there seems hardware having the use case is RISC-V (which we currently do not support in RTIC v1)

For RTIC v2 this should be kept in mind, so I'll reopen the task as a tracking issue for this :)

AfoHT avatar Jan 25 '23 20:01 AfoHT

Great, this sounds reasonable :)

noahzarro avatar Jan 26 '23 09:01 noahzarro