PIC32 taskENTER_CRITICAL question

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. Regards Graham

PIC32 taskENTER_CRITICAL question

I’m a bit confused by the question.  A task does not run at an IPL level – interrupt priorities and task priorities are two separate things, and tasks do not run in interrupts.  Also taskENTER_CRITICAL() and taskEXIT_CRITICAL() should not be called from an interrupt service routine. Also check that interrupts that are running with an IPL above that specified by configMAX_SYSCALL_INTERRUPT_PRIORITY do not call FreeRTOS API functions. Regards.

PIC32 taskENTER_CRITICAL question

Yes sorry I used the word ‘task’ in the loosest sense. If an interupt is say at ipl2 and it uses taskENTER_CRITICAL and configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 4 then the result as far as I can see will be 6. i.e. No interrupt other than 7 will pre-empt the interrupt. And as I mentioned, it’s non atomic, which worried me a little. However,  I didn’t know that thsse critical tasks macros shouldn’t be used within an interrupt. I can’t see that entioned in the doc? All my interrupts are running at or below configMAX_SYSCALL_INTERRUPT_PRIORITY and are all called using the FreeRTOS wrapper. I’m not using any xxxISR calls in the interrupts that are giving me problems. As I mentioned I’m  using asm("di") and asm("ei"), running code for days and I’ve had no problems.  Using the critical macros causes _exceptions errors within seconds. But then again, I was using them within interrupts!!  The code is a Circular Buffer implementation that allows seperate tasks (again loose term – could be an intteruot or FreeRTOS task) to read / write, hence the lock required to update the header data. Anyway, my current code is fine  using di/ei and is pretty efficient for a very short lock that I require. Thanks

PIC32 taskENTER_CRITICAL question

…but as Richard said, interrupts must not call taskENTER_CRITICAL(). This goes for all ports.