Hi,
The code halts in both the hardware running standalone and in debug mode. I am trying to figure out if it is related to a software timer below which is about debouncing of a switch.
UPDATE: the exception that occurs:
- happens either when exiting CBK_ChangeNotif_ProdTrigger() or after executing taskEXIT_CRITICAL() which is just the previous line. Or perhaps after starting the timer because it never gets to the timer callback function.
- the exception is a interrupt vector exception and seems to point to a memory address that does not appear in the disassembly listing (i.e. there’s nothing there)
Here is what I do…
During initialization I create the timer which I assume persists forever because I never delete it (only stop it and restart it). I also check that it is is created by checking the handle:
app_applyData.xTimer_Handle_ApplyDebounce = xTimerCreate("xSoftTmr_ApplyDebounce",
BTN_DEBOUNCE_MS_INITIAL_DEBOUNCE,
pdFALSE,
( void * ) 0,
CBK_SoftTmr_ApplyDebounce);
if (app_applyData.xTimer_Handle_ApplyDebounce == NULL)
{
ErrorMessage();
While(1);
}
The timer is started only when a switch is sensed by this INT callback function:
void CBK_ChangeNotif_ProdTrigger(GPIO_PIN pin, uintptr_t context)
{
BaseType_t xHigherPriorityTaskWoken;
xHigherPriorityTaskWoken = pdFALSE;
taskENTER_CRITICAL();
uint32_t tmpDebounceState = app_applyData.ui32ProdTrigState;
if ((tmpDebounceState == PROD_TRIG_STATE_STANDBY) && //In in standby and
(PROD_TRIG_Get() == PROD_TRIG_PRESSED)) //and button is pressed
{
PROD_TRIG_InterruptDisable(); //disable this int
xTimerStop(app_applyData.xTimer_Handle_ApplyDebounce, 0);
xTimerChangePeriod(app_applyData.xTimer_Handle_ApplyDebounce, BTN_DEBOUNCE_MS_INITIAL_DEBOUNCE, 0); //reset time period to initial debounce
xTimerReset(app_applyData.xTimer_Handle_ApplyDebounce, 0);
//start debouncing (timer) - after the debounce happened then will also send the message to the apply
xTimerReset(app_applyData.xTimer_Handle_ApplyDebounce, 0); //reset just in case
xTimerStart(app_applyData.xTimer_Handle_ApplyDebounce, 0);
app_applyData.ui32ProdTrigState = PROD_TRIG_STATE_PROD_DETECTED;
}
if ((tmpDebounceState == BTN_DEBOUNCE_STATE_PROD_PRESENT) && //State is "pressed"
(PROD_TRIG_Get() == PROD_TRIG_RELEASED)) //and button is released
{
PROD_TRIG_InterruptDisable(); //disable this int
//start debouncing (timer) - after the debounce happened then will also send the message to the apply
xTimerStop(app_applyData.xTimer_Handle_ApplyDebounce, 0);
xTimerChangePeriod(app_applyData.xTimer_Handle_ApplyDebounce, BTN_DEBOUNCE_MS_INITIAL_DEBOUNCE, 0); //reset time period to initial debounce
xTimerReset(app_applyData.xTimer_Handle_ApplyDebounce, 0);
xTimerStart(app_applyData.xTimer_Handle_ApplyDebounce, 0);
app_applyData.ui32ProdTrigState = BTN_DEBOUNCE_STATE_RELEASE_DETECTED;
}
taskEXIT_CRITICAL();
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
The callback is
void CBK_SoftTmr_ApplyDebounce(TimerHandle_t pxExpiredTimer)
{
_nop();
switch(app_applyData.ui32ProdTrigState)
{
case PROD_TRIG_STATE_STANDBY:
{
break;
}
case PROD_TRIG_STATE_PROD_DETECTED:
{//here the initial debouncing has elapsed
//check if the button is still pressed
_nop();
if (PROD_TRIG_Get() == PROD_TRIG_PRESSED)
{//if still pressed...
//so ONLY if stepper is not running then send message
if (! app_applyData.bApplyStepperIsRunning) //only if previous cycle is complete then send message
{
xTaskNotify(xAPP_APPLY_Tasks, NOTIF__APPLY__PRODUCT_SENSED, eSetBits);
}
app_applyData.ui32ProdTrigState = BTN_DEBOUNCE_STATE_PROD_PRESENT;
}
else
{//if released
//go back to standby state
app_applyData.ui32ProdTrigState = PROD_TRIG_STATE_STANDBY;
}
//in both cases re-enable prod trigger int
PROD_TRIG_InterruptEnable();
break;
}
case BTN_DEBOUNCE_STATE_PROD_PRESENT:
{
break;
}
case BTN_DEBOUNCE_STATE_RELEASE_DETECTED:
{//here the initial debouncing has elapsed
_nop();
//check if the button is still released
if (PROD_TRIG_Get() == PROD_TRIG_RELEASED)
{
app_applyData.ui32ProdTrigState = PROD_TRIG_STATE_STANDBY;
}
else
{//if released
//go back to standby state
app_applyData.ui32ProdTrigState = BTN_DEBOUNCE_STATE_PROD_PRESENT;
}
//in both cases re-enable prod trigger int
PROD_TRIG_InterruptEnable();
break;
}
default:
{
while(1);
// send debug error...
break;
}
}
}
And through the code I use the following functions
xTimerStop(app_applyData.xTimer_Handle_ApplyDebounce, 0);
xTimerChangePeriod(app_applyData.xTimer_Handle_ApplyDebounce, BTN_DEBOUNCE_MS_INITIAL_DEBOUNCE, 0); //reset time period to initial debounce
xTimerReset(app_applyData.xTimer_Handle_ApplyDebounce, 0);
xTimerStart(app_applyData.xTimer_Handle_ApplyDebounce, 0);
Few questions:
- am I doing anything wrong in the above code?
- is there any advantage in creating the timer statically?
- being set to “single shot” it does not need any particular attention, correct? It still persists forever in memory and it just calls the callback after it is started and the timeout is expired. Correct?
Thank you