Yeah there’s not really much to show?
I schedule a timer (in this case 15 seconds)
static int
doScheduleTimer(
OSUTILS_tTimerPtr theTimer,
const char timerName,
uint16 theTimeoutInMs,
uint8 autoRestart,
void param,
OSUTILS_tTimerFunction theCallbackFunction
)
{
/* Locals */
int theStatus = -1;
/* Create the timer if needed */
if (theTimer == NULL)
theTimer = OSUTILS_TimerCreate(timerName, OSUTILS_ConvertMsToTicks(theTimeoutInMs), autoRestart, param, theCallbackFunction);
/* Sanity check /
if (theTimer != NULL)
{
/ Update the period (This will start the timer, but manually start afterwards just in case) /
if (OSUTILS_TimerChangePeriod(theTimer, OSUTILS_ConvertMsToTicks(theTimeoutInMs)) == 0)
{
if (OSUTILS_TimerStart(theTimer) == 0)
{
/ Successful, update theStatus */
theStatus = 0;
}
}
}
return theStatus;
}
The project here has an abstraction layer, but here is what it is doing:
OSUTILS_tTimerPtr
OSUTILS_TimerCreate(
const char *timerName,
uint32 periodInTicks,
uint8 isAuto,
void * param,
OSUTILS_tTimerFunction timerFunction
)
{
TimerHandle_t timerHandle = NULL;
if (timerName == NULL || timerFunction == NULL) return NULL;
timerHandle = xTimerCreate((const RTOS_CHAR_PTR)timerName, (TickType_t) periodInTicks, (UBaseType_t) isAuto, param, timerFunction);
return (OSUTILS_tTimerPtr) timerHandle;
}
and then starting it:
int
OSUTILS_TimerStart(OSUTILS_tTimerPtr theTimer)
{
BaseType_t retVal;
if (theTimer == NULL) return -1;
retVal = xTimerStart((TimerHandle_t) theTimer, portMAX_DELAY);
return (retVal == pdFALSE) ? -1 : 0;
}
So we start the timers, and I can see based on my logging that the GPIOs are toggling how I want them to according to that time, so I know the timers are working, hitting the callback function, sending the event for the next step in the process.
Now the debug function that I call from my console is just:
static void
doDisplayDeApp(
TCTHACT_tDevID theID
)
{
/* Locals /
static const char trueStr = “TRUE”;
static const char* falseStr = “FALSE”;
static const char* segmentCompleteStr = " segment complete: ";
static const char* timerRunningStr = " timer running: ";
static const char* nextEventStr = "\tNext event to post: ";
/* It shouldn’t be possible to fail this, but just in case /
if (theID < PLATFORM_ID_MAX)
{
/ More locals /
const tHandler theHandler = &(gMyHandlers[theID]);
/* Print the DeApp config, this also gets printed by "thermalctl actuator deapp config <id>" */
doPrintDeAppConfig(theHandler);
/* Print the relevant flags */
CONSOLE_Printn("\r\nDeApp Flags:");
CONSOLE_Printn("DeApp in progress: %s", (theHandler->fFlags & FLAG_DEAPP_IN_PROGRESS) ? trueStr : falseStr);
CONSOLE_Printn("DeApp return%s%s", segmentCompleteStr, (theHandler->fFlags & FLAG_DEAPP_RETURN_COMPLETE) ? trueStr : falseStr);
CONSOLE_Printn("DeApp vacuum%s%s", segmentCompleteStr, (theHandler->fFlags & FLAG_DEAPP_VACUUM_COMPLETE) ? trueStr : falseStr);
CONSOLE_Printn("DeApp purge0%s%s", segmentCompleteStr, (theHandler->fFlags & FLAG_DEAPP_PURGE0_COMPLETE) ? trueStr : falseStr);
CONSOLE_Printn("DeApp purge1%s%s", segmentCompleteStr, (theHandler->fFlags & FLAG_DEAPP_PURGE1_COMPLETE) ? trueStr : falseStr);
/* Print the timer information */
CONSOLE_Printn("\r\nDeApp Timers:");
CONSOLE_Printn("ReturnSv%s %s", timerRunningStr, OSUTILS_TimerIsActive(theHandler->fReturnSvTimer) ? trueStr : falseStr);
CONSOLE_Printn("%s%d", nextEventStr, theHandler->fReturnSvTimerBundle.fEventToPost);
CONSOLE_Printn("VacuumSv%s %s", timerRunningStr, OSUTILS_TimerIsActive(theHandler->fVacuumSvTimer) ? trueStr : falseStr);
CONSOLE_Printn("%s%d", nextEventStr, theHandler->fVacuumSvTimerBundle.fEventToPost);
CONSOLE_Printn("Purge0Sv%s %s", timerRunningStr, OSUTILS_TimerIsActive(theHandler->fPurge0SvTimer) ? trueStr : falseStr);
CONSOLE_Printn("%s%d", nextEventStr, theHandler->fPurge0SvTimerBundle.fEventToPost);
CONSOLE_Printn("Purge1Sv%s %s", timerRunningStr, OSUTILS_TimerIsActive(theHandler->fPurge1SvTimer) ? trueStr : falseStr);
CONSOLE_Printn("%s%d", nextEventStr, theHandler->fPurge1SvTimerBundle.fEventToPost);
CONSOLE_Printn("Disengage%s%s", timerRunningStr, OSUTILS_TimerIsActive(theHandler->fDisengageTimer) ? trueStr : falseStr);
CONSOLE_Printn("%s%d", nextEventStr, theHandler->fDisengageTimerBundle.fEventToPost);
}
return;
}
with OSUTILS_TimerIsActive being:
int
OSUTILS_TimerIsActive(OSUTILS_tTimerPtr theTimer)
{
BaseType_t retVal;
if (theTimer == NULL) return FALSE;
retVal = xTimerIsTimerActive((TimerHandle_t) theTimer);
return (retVal == pdFALSE) ? FALSE : TRUE;
}
And I’ve tried this with calls directly to xTimerIsTimerActive and same thing, it never reports that it is active.
Sorry if the debug prints are a little difficult to read, I have to scrape the walls for bytes in this project. I’ve had to do a release with less than 300 Bytes of flash space free before.
I know that there is no guarantee that xTimerIsTimerActive will immediately report that it is active because it just queues up the timer task, but this is me manually triggering that debug print function repeatedly over 15 seconds and never once seeing it report TRUE, but all the other things, flags, next event to send etc. all do update as expected.
One thing I’m wondering is if calling xTimerStart after xTimerChangePeriod (which itself starts the timer) could be messing up xTimerIsTimerActive? If that was the case that’d be a problem with FreeRTOS