PIC32 interrupt issue xQueueSendToBackFromISR

Hello. I have a huge problem with my touch screen driver which is interrupt driven under FreeRtos. I hope someone can help me.
Here is my code (sorry for a mess)
void vCNInterruptHandler( void );
extern void __attribute__( (interrupt(ipl3), vector(_CHANGE_NOTICE_VECTOR))) vCNInterruptWrapper( void );
extern xQueueHandle hTouchMsgQueue;
void TouchStandby( void )
{
    IEC1bits.CNIE = 0;
    // Set Yadc and Xadc pins as digital inputs
    AD1PCFG |= 0xC000;
    // Set X axis tied to GND: 
    // X- as HiZ with PD (hardwired)
    TRIS_XNEG = 1;      // HiZ  
    // X+ as Gnd without PU
    LAT_XPOS(0);
  TRIS_XPOS(0);         // Gnd
  
  // Set Y axis tied to VCC ( close to Vcc because of hardwired PD on RB15. It couses current flow! )
    // Y+ as HiZ with PU enabled     
  TRIS_YPOS(1);     // HiZ  
    // Y- as HiZ with CN interrupt enabled. PD is present (hardwired)
    TRIS_YNEG = 1;      // INT

    RtosDelayMs(1);
    CNEN = 0x1000;
    // Clear mismatch condition
    BYTE dummyRead = PORTB;
    // Clear CN interrutp flag
    IFS1bits.CNIF = 0;
    // Enable interrupt
    IEC1bits.CNIE = 1;
}   
void TouchWakeup( void )
{
    // Set Yadc and Xadc pins as analog inputs
    AD1PCFG &= 0x3FFF;
}   
volatile BYTE smTouchDetection = touchStandby;
void TouchInterruptInit( void )
{
    WORD dummyRead;

    // Enable CN12 interrupt
    CNEN = 0x1000;
    // Enable CN module and set halt in idle mode
    CNCON = 0xA000; 
    // Interrupt priority 2, subpriority 1
    IPC6 = 0x000900000;
    // Clear mismatch condition
    dummyRead = PORTB;
    // Clear CN interrutp flag
    IFS1bits.CNIF = 0;
    // Enable CN interrupt
    //IEC1bits.CNIE = 1;

}   
  enum{
        touchUnpressed = 0,
        touchPressed = 1
    };

volatile BYTE touchMsgCnt = 0;
// CN12 = RB15
void vCNInterruptHandler( void )
{  
  static isrTest = 0;
  signed portBASE_TYPE xHigherPriorityTaskWoken;     
    xHigherPriorityTaskWoken = pdFALSE;

    isrTest++;
    if( isrTest > 1 ){
        Nop();
    }   
    WORD dummyRead;
    // Clear mismatch
    dummyRead = PORTB;
  // Clear CN interrutp flag
    IFS1bits.CNIF = 0;


    if( !_RB15 ) {
        // Disable CN interrupt until int source is handled
        IEC1bits.CNIE = 0;
     // CNEN = 0x0000;
        // Inform touchTask about touch screen being pressed
        BYTE touchMsg;
        touchMsg = touchPressed;
    if( xQueueSendToBackFromISR( hTouchMsgQueue, &touchMsg, &xHigherPriorityTaskWoken ) )
    {
        touchMsgCnt++;
      }       
  }
    if( isrTest > 1 ){
        Nop();
    }   

    isrTest = 0;

    portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); // If necessary change context to task with higher priority

}
volatile BYTE touchDebug = 0; 
void TouchTask(void *pVoid) {

    volatile int touchPressed = 0;
    BYTE touchMessage;
    //TouchStandby();
    RtosDelayMs(100);
    TouchInterruptInit();
    while (TRUE) {
        touchDebug = 0;
        switch( smTouchDetection ) {
            case touchStandby:
                touchDebug = 1;
                LockSD();
                touchDebug = 2;
                TouchStandby();
                touchDebug = 3;
                UnlockSD();
                touchDebug = 4;
                // Block until touch screen is pressed. Detection done in CN interrupt handler
                if( !xQueueReceive( hTouchMsgQueue, &touchMessage, 100000 ) )
                {
                    //Timeout
                    if( touchMsgCnt > 0 ){
                        Nop();
                    }
                    else
                        break;
                }               
                touchMsgCnt--;
                touchDebug = 5;
                TouchWakeup();
                touchDebug = 8;
                smTouchDetection = touchDetect;
                touchDebug = 9;
                //RtosDelayMs(25);
            //break;

            case touchDetect:
                touchDebug = 10;
                LockSD();
                touchDebug = 11;
                touchPressed = TouchDetectPosition();
                touchDebug = 12;                
                UnlockSD();
                touchDebug = 13;
                if( touchPressed ) {
                    touchDebug = 14;
                    RtosDelayMs(25);
                    touchDebug = 15;
                }   
                else{
                    touchDebug = 16;
                    // Touch is depressed. Return to standby state
                    smTouchDetection = touchStandby;
                    touchDebug = 17;
                }       
            break;  
        }       
#ifdef WIN32
        Sleep(1);
#endif
    touchDebug = 18;
    taskYIELD();
    //tuchDebug = 19;
    }
} //void TouchTask(void *pVoid) {
ISR.S:
#include <p32xxxx.h>
#include <sys/asm.h>
#include "libs/FreeRTOS/ISR_Support.h"
    .set    nomips16
    .set    noreorder

    .extern vCNInterruptHandler
    .extern xISRStackTop
    .global vCNInterruptWrapper
    .set        noreorder
    .set        noat
    .ent        vCNInterruptWrapper
vCNInterruptWrapper:
    portSAVE_CONTEXT
    jal vCNInterruptHandler
    nop
    portRESTORE_CONTEXT
    .end        vCNInterruptWrapper
Some stuff from FreeRtosConfig.h:
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 0
#define INCLUDE_xTaskResumeFromISR 1
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 0x03
#define configKERNEL_INTERRUPT_PRIORITY 0x01 And last but not least problem description:
TouchTask block(should do this indefinitely but I used 10s for debuf purpose) until touch is detected by change notice interrupt. Interrupt sends message “touchPressed” if CN12 is pushed. Message from queue is received by touchTask and detection is procced. Everything works great until I start pushing touch screen rapidly. Then touch task hangs.
I was able to determine that:
1.CN interrupt detects push and sends message into hTouchMsgQueue. It returns with xHigherPriorityTaskWoken = pdTrue.
2. The touch task never unblocks even with xTicksToWait definied (as it is in code above) and message being queued.
I read about interrupt priority issues but I made everything (or rather I hope) according to FreeRtos manuall scheme. I tried to comment out portEND_SWITCHING_ISR but problem still exists.

PIC32 interrupt issue xQueueSendToBackFromISR

From reading the code, it looks like the interrupt has a priority of 2, and the max syscall priority is 3, so on a PIC32 device that is ok. Are you able to determine what the TouchTask is doing?  What is it executing.  This sort of thing can sometimes happen when the peripheral drivers (in this case I presume this is the TouchDetectPosition(), and the lock/unlock SD functions, etc.) contain polling loops in them, and the loop exit condition never occurs leaving the task just spinning on the same code continuously.  (I had the same thing recently myself with a USB CDC driver – when I hammered it by automatically sending it lots of characters in quick succession it ended up getting stuck in a loop that was polling for a bit change that never changed). Which IDE are you using?  If MPLAB 8 then Microchip provide a FreeRTOS plug-in that will at least tell you the state of the task (running/blocked/etc.).  If using MPLAB X then there is also a plug-in but I’m not sure of its status at the moment (a recent support request was having a problem using it).  If you don’t have the plug-in then I can tell you how to determine the state using the debugger – but that involves following a pointer chain so is not very user friendly. The trace tool offers another option to see what is actually running if you have the possibility to add in the trace recorder code and obtain the tool. Does xQueueSendToBackFromISR() ever return pdFALSE? 
How big is the queue?
Is it correct that the break statement is commented out in the switch statement of your task? Regards.

PIC32 interrupt issue xQueueSendToBackFromISR

Thanks for quick respond.
The last line executed by TouchTask is xQueueReceive( hTouchMsgQueue, &touchMessage, 100000 ) . The touchDebug variable has value of 4 and touchMsgCnt = 1. The LockSD and UnlockSD are just mutexes that secure the  SPI4 peripherial. The commented break is just to speed up touch detection a little.  For xQueueSendToBackFromISR()  I decided to disable CN interrupt each time touch screen is pressed, procced with touch detection and then reenable interrupt. I think it is more safe right now but I have also tried approch without disabling it. I was able to spot that CN ISR was preempting it self! (is it normal?) Preemption occurs during xQueueSendToBackFromISR() ( line 919 of queue.c ). That time is return with pdFalse. This is wired because it happensa also when the CN12 interrupt is masked (CNEN = 0! ) 
But for now lest return to problem with touch task queue.
I am using MPLAB8 and all task in RtosViewer are suspended. I tried to see if other task that are working in time dependant manner (like networkTask, lcdTask etc ). are working correctly. It turned out that only one task is running and there is no task switch. The vPortIncrementTick is executed so tick interrupt is working fine. I really don’t have any idea what to check next:/

PIC32 interrupt issue xQueueSendToBackFromISR

I’ve forgot to add my hTouchQueueMsg initialization: hTouchMsgQueue = xQueueCreate( 1, 1 );

PIC32 interrupt issue xQueueSendToBackFromISR

Because of the way FreeRTOS handles indefinite waits a task that makes a blocking call with a block time of portMAX_DELAY will show as being Suspended when it is actually Blocked. I don’t see TouchTask() ever using portMAX_DELAY or actually being suspended, but you say the viewer shows it as Suspended?

PIC32 interrupt issue xQueueSendToBackFromISR

No it is my mistake. I checked RtosViewer once again and IDLE is in ready state TmrSvc Unkcnown 6 more tasks are Suspended (blocked indefinite, waiting for message in queue/ semaphore ) but there are many tasks missing in the list. However before this error shows (before touch screen stops responding and task switch stop working) all of them are present. Is it possible to determine what exactly touchTask is doing? I know that last command is xQueueReceive();

PIC32 interrupt issue xQueueSendToBackFromISR

So it looks likely there is some corruption of the kernel data somewhere. Before I walk through manually tracking the stat of the task, a couple of quick questions: 1) Do you have stack overflow checking switched on?
2) What is the priority of the touch task?
3) When the error occurs, what is the value of the uxTopReadyPriority variable in tasks.c?
4) If you are using FreeRTOS V7.3.0, what is configUSE_PORT_OPTIMISED_TASK_SELECTION set to (if it is not defined then I will look up the default). Regards.

PIC32 interrupt issue xQueueSendToBackFromISR

Here it goes:
1)  I have
#define configCHECK_FOR_STACK_OVERFLOW 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1 But neither my constructor task that monitors every tasks thru uxTaskGetStackHighWaterMark nor vApplicationStackOverflowHook() indicates any stack problems.
2) touch task has priority 2 (as most tasks in project)
3) uxTopReadyPriority = 2 (when screen freezes )
4) I have FreeRTOS V7.3.0 with onfigUSE_PORT_OPTIMISED_TASK_SELECTION set to default (not definied at all)

PIC32 interrupt issue xQueueSendToBackFromISR

Small update but maybe helpful.
If I change lines:
                if( !xQueueReceive( hTouchMsgQueue, &touchMessage, 100000 ) )
                {
                    //Timeout
                    if( touchMsgCnt > 0 ){
                        Nop();
                    }
                    else
                        break;
                }       
to only:
xQueueReceive( hTouchMsgQueue, &touchMessage, portMAX_DELAY );
Symptoms are the same for touchTask but other tasks are switching normally. What is more every task is present in RtosViewer list (including those in block state as well) expect touchTask.
Let me know if I can be of any more help

PIC32 interrupt issue xQueueSendToBackFromISR

One last update for today. I’ve modified taskTocuh. It is a little less efective (checking Queue every 50ms) but right now it seems to work without a problem. Here it is:
void TouchTask(void *pVoid) {

    volatile int touchPressed = 0;
    BYTE touchMessage;
    RtosDelayMs(100);
    TouchInterruptInit();
    while (TRUE) {
        switch( smTouchDetection ) {
            case touchStandby:
                LockSD();
                TouchStandby();
                UnlockSD();
                smTouchDetection = touchCheck;

                break;

                case touchCheck:
                // Block until touch screen is pressed. Detection done in CN interrupt handler
                RtosDelayMs(50);
                if( !xQueueReceive( hTouchMsgQueue, &touchMessage, 0 ) )
                {
                    break;
                }                   
                touchMsgCnt--;
                TouchWakeup();
                smTouchDetection = touchDetect;

            case touchDetect:
                LockSD();
                touchPressed = TouchDetectPosition();               
                UnlockSD();
                if( touchPressed ) {
                    RtosDelayMs(25);
                }   
                else{
                    // Touch is depressed. Return to standby state
                    smTouchDetection = touchStandby;
                }       
            break;  
        }       
#ifdef WIN32
        Sleep(1);
#endif
    taskYIELD();
    }
} //void TouchTask(void *pVoid) {
I’ve noticed that when the xTickToWait time in xQueueReceive call is small (I’ve tried up to 100ticks=10ms ) every think works correctly. This could point to a reson why longer blocking/suspending of touchTask currupts some data (etc.:xEventList? xSuspendedTaskList?)

PIC32 interrupt issue xQueueSendToBackFromISR

Lately I was able to finally solve the problem from my first post. I had Read-Modify-Write hazard when clearing/setting interrupt flag for CN peripherial. I used IEC1bits.CNIE and IFS1bits.CNIE commands which are not atomic operations. After changing these to atomic opeartions (IEC1SET IEC1CLR IFS1SET IFS1CLR ) everything works flawless. I hope someone will find it usefull in the future.