xTimerStop() creating issues

Hi,
I have the following code:

In the setup/init function:

//Create Apply Timeout Timer
app_applyData.xTimer_Handle_ApplyTimeout = xTimerCreate("xSoftTmr_ApplyTimeout",
                                                        xPrinterData.uiApplyErrorTimeout,
                                                        pdTRUE,
                                                        ( void * ) 0,
                                                        CBK_SoftTmr_ApplyTimeout);

In the function where I start the timer:

//set timeout time and start timer
xTimerStop(app_applyData.xTimer_Handle_ApplyTimeout, 0);
xTimerChangePeriod(app_applyData.xTimer_Handle_ApplyTimeout, xPrinterData.uiApplyErrorTimeout, 0); //reset time period to 100ms because there is no point in sampling faster  
xTimerStart(app_applyData.xTimer_Handle_ApplyTimeout, 0);

Then is a ISR callback the following code (this is the entire callback):

void CBK_ChangeNotif_ApplicationGap(GPIO_PIN pin, uintptr_t context)
{
    //Check which edge this INT was generated by
    if (APPLIC_GAP_Get() == 0)   
    {
        //INT was generated by falling edge (gap to label transition) 
        _nop();
        //An edge was sensed so stop the timer to prevent timeout
        xTimerStop(app_applyData.xTimer_Handle_ApplyTimeout, 0);

        taskENTER_CRITICAL();

        //set local flag that label edge has been detected
        app_applyData.bLabelEdgeDetected = 1;
        if (app_applyData.bApplyStopByStepCount == 0)
        {
            //clear the flag that the motor is running (because the motor is being stopped)
            app_applyData.bApplyStepperIsRunning = 0;

            //stop motor and timer
            OCMP6_Disable();
            TMR3_Stop ();

            //redundant torque reduction. But placed here too for safety 
            Stepper_Apply_SetTorqueToThird();
        }
        taskEXIT_CRITICAL();

    }
    else    
    {
        //INT was generated by rising edge (label to gap transition) 
        _nop();
    }


    _nop();
}

If I comment out the

xTimerStop(app_applyData.xTimer_Handle_ApplyTimeout, 0);

then the code runs as it should. Otherwise it doesn’t.

And what happens exactly is that none of the other interrupts that occur are serviced after then.

  1. what could cause that?

  2. have a number of software timers. Are there limits to the number of software timers I can create? Do I have to perhaps set some config variable somewhere?

UPDATE
Another thing that occurs if I leave that specific line in while debugging is that the debugger throws an exception and a software breakpoint with no functions shown in the call stack and the only information is a exception code of the MCU core itself. The only information on that code in the silicon manual is Bus Error Exception (instruction fetch). Nothing more. You can see entry/code 6 in table 2.10 on page 42 of the pdf here:
http://hades.mech.northwestern.edu/images/b/b1/PIC32RefManual-Dec2013.pdf
Thank you

Is CBK_ChangeNotif_ApplicationGap an ISR handler? If so, you should use xTimerStopFromISR and taskENTER/EXIT_CRITICAL_FROM_ISR.

Which hardware platform are you using?

Thanks.

Thank you Gaurav,
I am using Microchip’s PIC32MZ series with MPLAB tools.

Yes, it is an ISR. Didn’t notice there was a from ISR version. :roll_eyes: Thank you. :slight_smile:

Do I need to use portEND_SWITCHING_ISR for every function that ends in “fromISR” or just for the TaskNotify ones?

Also, do I need to use the “fromISR” version of functions if I call them from callback functions registered by freeRTOS registering functions such as the freeRTOS Software Timer timeout function? I am asking because I assume they are normal functions so that doesn’t apply but perhaps freeRTOS does something involveing ISR during context switching?

Thank you

It’s your decision. What that macro does is preempt the interrupted task immediately if the action taken in the ISR unblocks a higher pri task (higher pri than the interrupted one) so the unblocked task can proceed faster. If you don’t use it, the task switch does not occur until the next time the sys tick handler enforces a context switch.

Intuitively, it maskes sense to use portEND_SWITCHING_ISR() every time an ISR signals a task that it can now proceed, but again, it’s an implementation decision. In some scenarios it may be undesireable.

The rules are straightforward: You MUST use the xxxFromISR if AND ONLY if the function is called within an ISR context. FreeRTOS software timer timeout functions are by definition executed in the context of the timer TASK, so no …FromISR() there.

One comment on portEND_SWITCHING_ISR(), there generally only needs to be a single instance of this at the end of the ISR, that gathers the results from all the calls in the ISR.

Note that each function that takes the wasWoken flag will only ever set the value, never clear, so they effectively will build an OR of the conditions.

Thank you RAc and Richard :slight_smile: