mirror of
https://github.com/apache/nuttx.git
synced 2026-08-29 05:10:44 +00:00
arch/arm/src/rp23xx: fix NVIC priority init missing IRQs 12-51
At system startup, the NVIC was configured for proper default priority only for the first three IPR registers, even though the loop was executed 13 times - due to a gotcha on what the `NVIC_IRQ_PRIORITY(i)` macro returns. IRQs 12-51 stayed at the reset priority of 0 - highest in the system; so any peripherals issuing those interrupts will shoot through critical sections that rely on BASEPRI = NVIC_SYSH_PRIORITY_DEFAULT (0x80). This can corrupt the TCB ready-to-run list and semaphore wait queues; this is hard to reproduce (e.g. in ostest) because it requires a peripheral ISR to land inside a critical section, but the failure modes range from hangs to wild pointer crashes once it does. In my case I had SPI and I2C peripherals that were issuing IRQs and were preempting scheduler and semaphore list operations, causing corruption. Step the loop by four and bound it with RP23XX_IRQ_NEXTINT so every IPR covering IRQs 0..51 is written once with DEFPRIORITY32. Signed-off-by: Daniel Fanache <dan@rts.ro>
This commit is contained in:
parent
f5689656c6
commit
ed5a661da8
1 changed files with 7 additions and 2 deletions
|
|
@ -280,9 +280,14 @@ void up_irqinitialize(void)
|
|||
arm_ramvec_initialize();
|
||||
#endif
|
||||
|
||||
/* Now set all of the interrupt lines to the default priority */
|
||||
/* Set all of the interrupt lines to the default priority.
|
||||
* NVIC_IRQ_PRIORITY(n) maps IRQ number n to its IPR register via
|
||||
* (n >> 2); each 32-bit IPR covers four IRQs. Step by four and bound
|
||||
* the loop by RP23XX_IRQ_NEXTINT so that every IPR (covering IRQs
|
||||
* 0..51) is written exactly once.
|
||||
*/
|
||||
|
||||
for (i = 0; i < 12; i++)
|
||||
for (i = 0; i < RP23XX_IRQ_NEXTINT; i += 4)
|
||||
{
|
||||
regaddr = NVIC_IRQ_PRIORITY(i);
|
||||
putreg32(DEFPRIORITY32, regaddr);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue