cancel
Showing results for 
Search instead for 
Did you mean: 

Questions on NVIC

autukuri
Associate II
Posted on July 30, 2008 at 20:53

Questions on NVIC

8 REPLIES 8
autukuri
Associate II
Posted on May 17, 2011 at 12:40

I have a simple question on NVIC. I was having a little difficulty understanding the difference between preemptionpriority and subpriority for an IRQ channel.

I am assuming that preemptionpriority is the actual priority (0-16, with 0 being the highest priority). So, IRQ 0 would preempt all others and 1 would preempt 2-16.

I am also assuming that the subpriority is a priority within the group of same preemptionpriority. So, subpriority 0 would be higher than subpriority 1 given the same preemption?

Is this correct? My IRQs are not behaving the way they should, and I am trying to figure out the bug. Thanks in advance.

lanchon
Associate II
Posted on May 17, 2011 at 12:40

only 4 bits total determine both pri and subpri per source. the allocation of those 4 bits to mean pri or subpri is configurable. for instance you could have 4 bits (16 levels) of pri and 0 bits (1 level) of subpri (no subpris), or 1 bit (2 levels) of pri and 3 bits (8 level) of subpri.

within a pri level, subpris order pending interrupts but do not interrupt each other.

autukuri
Associate II
Posted on May 17, 2011 at 12:40

Thanks. Here is what I am coding. I have 3 interrupts:

Timer2: Preemption: 0, Priority: 0

USB: Preemption: 1, Priority: 0

DMA: Preemption: 2, Priority: 0

I want the timer to turn on\off Hardware port, so I want the timing to be exact. So, I made it have preemption 0, so it should interrupt everything else. But, the timer loop is still inconsistent. Sometime it take 8us, sometime 16us. If I turn off the USB and DMA, it is exactly 8us all the time. So, is there something wrong in my logic?

joseph239955
Associate II
Posted on May 17, 2011 at 12:40

Did you setup the priority group setting? It is in NVIC Application Interrupt and Reset Control Register (0xE000ED0C).

This setting defines how the priority level register is divided into preempt priority and sub-priority.

In addition, what are the read back values of the priority registers?

(so that you can confirm that the levels are programmed correctly).

I assumed you will get:

Timer2 : 0x00

USB : 0x10

DMA : 0x20

Note: On STM32, the priority level registers only have bit 7 to bit 4. Bit 3 to bit 0 are always 0.

autukuri
Associate II
Posted on May 17, 2011 at 12:40

I set the priority as:

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

Once I called NVIC_Init with all the interrupts, I am trying to read back the priority registers:

myvar = NVIC->IPR[(DMA1_Channel1_IRQChannel >> 02)].

Is this correct? It looks like the library code is truncating the two LSB of the IRQ channel values. I definitely dont see USB:0x10.

autukuri
Associate II
Posted on May 17, 2011 at 12:40

Ok, figured out how the NVIC registers should be set up. Each IRQ is 8 bits, and they are packed into 32 bit registers of course. And the preemption is written into the high bits backwards, which was my confusion.

So, I have set the GroupPriority to be 2, and the IPR registers are configured properly so:

Timer = 0

USB = 1

DMA = 2.

I still have the timer interrupt being triggered with varying delays and the problem disappears if I comment out the other interrupts.

joseph239955
Associate II
Posted on May 17, 2011 at 12:40

Would it be possible that the other interrupt service routine set the PRIMASK or FAULTMASK (exception masking registers) for timing critical task, so your timer exception is delayed?

[ This message was edited by: joseph.yiu on 30-07-2008 23:15 ]

picguy
Associate II
Posted on May 17, 2011 at 12:40

I had much the same ptoblem until I did this:

; the std Cortex SVC is set to the lowest priority

; Needed because we spend much time in our SVC handler

; aka tack scheduler

ldr r0,=0xE000ED18

movs r1,#0xFF ;absoulte min priority

strb r1,[r0,#11-4] ;lower pri of SVC (makes svc code interruptable)

;-4 because the table starts at exception 4

My little OS gains entry from various SVCs. I loop in my SVC handler until some task is ready to run. But SVC had max priority and no ISR would run. The above code drops SVC priority as low as it will go.