I’m using taskENTER_CRITICAL and taskLEAVE_CRITCAL but have been having problems on PIC32.
I have two questions:-
i) ulStatus = _CP0_GET_STATUS();
ulStatus |= ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT );
_CP0_SET_STATUS( ulStatus );
is used to take the CP0 status register and modify the IPL bits with configMAX_SYSCALL_INTERRUPT_PRIORITY.
Maybe I’m wrong, but if my task is at ipl2 and MAX_SYSCALL is at ipl4 this will result in a new value of 6. As the PIC32 doc says that… “This field is the encoded (0…63) value of the current IPL.” e.g. the task in example above with ipl2 executing a crit sec will write ipl6 to status. No interrupt <=6 will preempt this crit sec when the intent was for interrupts <=4.
ii) It appears taskENTER_CRITICAL and taskLEAVE_CRITCAL are non-atomic. It would appear possible for another process to preempt/interleave and affect the STATUS register bits and then return to have _CP0_SET_STATUS write incorrect bits back from the saved ulStatus. e.g. bit 0. Is this likely to cause problems?
I have been getting problems ( processor exceptions of differing types) using the above macro’s when locking a int variable prior to incrementing whereas using asm(“di”) asm(“ei”) seems to fix the problem.