Verified Commit c6e5161f authored by Paul Szczepanek's avatar Paul Szczepanek Committed by Vincent Coubard
Browse files

Fix iot timer implementation using CMSIS



Adds limitation of timers needing to have same periodicity as first timeout
Signed-off-by: default avatarPaul Szczepanek <paul.szczepanek@arm.com>
Signed-off-by: Vincent Coubard's avatarVincent Coubard <vincent.coubard@arm.com>
parent 3b1bd48f
......@@ -54,9 +54,15 @@ typedef struct threadInfo {
osThreadId_t threadId; /**< Thread ID. */
} threadInfo_t;
typedef void ( * callback_t )( void * );
/**
* @brief Represents an #IotTimer_t on AFR systems.
*/
typedef osTimerId_t _IotSystemTimer_t;
typedef struct _IotSystemTimer_t {
osTimerId_t timerId;
callback_t callback;
void *callbackArg;
} _IotSystemTimer_t;
#endif /* ifndef _IOT_PLATFORM_TYPES_POSIX_H_ */
......@@ -72,14 +72,8 @@ bool IotClock_GetTimestring(char *pBuffer,
uint64_t milliSeconds = IotClock_GetTimeMs();
int timestringLength = 0;
if( pBuffer == NULL )
{
return false;
}
if( pTimestringLength == NULL )
{
return false;
}
configASSERT( pBuffer != NULL );
configASSERT( pTimestringLength != NULL );
/* Convert the localTime struct to a string. */
timestringLength = snprintf( pBuffer, bufferSize, "%llu", milliSeconds );
......@@ -100,10 +94,35 @@ bool IotClock_GetTimestring(char *pBuffer,
uint64_t IotClock_GetTimeMs( void )
{
uint32_t tickCount = OS_Tick_GetCount();
static uint32_t lastCount;
static uint64_t overflows = 0;
/* This is called by the scheduler but also by the logger so we need a mutex. */
/* We can do the creation here since this is guaranteed to be first called by the scheduler. */
static mutex_id = 0;
if (!mutex_id)
{
mutex_id = osMutexNew(NULL);
}
osMutexAcquire(mutex_id, 0);
uint32_t tickCount = osKernelGetTickCount();
if ( tickCount < lastCount )
{
overflows++;
}
lastCount = tickCount;
osMutexRelease(mutex_id);
uint64_t tickResult = tickCount;
tickResult = tickResult + overflows * UINT32_MAX;
/* Return the ticks converted to Milliseconds */
return tickCount * _MILLISECONDS_PER_TICK;
return ( tickResult * _MILLISECONDS_PER_TICK );
}
/*-----------------------------------------------------------*/
......@@ -118,54 +137,47 @@ bool IotClock_TimerCreate( IotTimer_t * pNewTimer,
IotThreadRoutine_t expirationRoutine,
void * pArgument )
{
_IotSystemTimer_t * pxTimer = ( _IotSystemTimer_t * ) pNewTimer;
osTimerId_t timerId = NULL;
if( pNewTimer == NULL )
{
return false;
}
if( expirationRoutine == NULL )
{
return false;
}
configASSERT( pNewTimer != NULL );
configASSERT( expirationRoutine != NULL );
IotLogDebug( "Creating new timer %p.", pNewTimer );
osTimerAttr_t timerAttr = { "timer", 0, NULL, 0 };
timerId = osTimerNew( expirationRoutine, osTimerOnce, &pArgument, &timerAttr );
if( timerId == NULL )
{
IotLogError( "Failed to create timer %p.", pNewTimer );
}
IotLogDebug( "Delaying creation of timer %p.", pxTimer );
/* Set the timer expiration routine, argument and period */
* pNewTimer = timerId;
pNewTimer->timerId = 0;
pNewTimer->callback = expirationRoutine;
pNewTimer->callbackArg = pArgument;
return true;
}
/*-----------------------------------------------------------*/
void IotClock_TimerDestroy( IotTimer_t * pTimer )
static osTimerId_t SafeTimerDelete(osTimerId_t timerId)
{
_IotSystemTimer_t * pTimerInfo = ( _IotSystemTimer_t * ) pTimer;
if( timerId != 0 )
{
if( osTimerDelete( timerId ) != osOK )
{
IotLogError( "Failed to delete timer %p.", pTimer );
}
else
{
timerId = 0;
}
}
return timerId;
}
if( pTimerInfo == NULL )
void IotClock_TimerDestroy( IotTimer_t * pTimer )
{
if( pTimer == NULL )
{
IotLogError( "Timer doesn't exist. Can't destroy it." );
}
IotLogDebug( "Destroying timer %p.", pTimer );
if( osTimerIsRunning( * pTimerInfo ) == 1 )
{
if( osTimerDelete( * pTimerInfo ) != osOK )
{
IotLogError( "Failed to delete timer %p.", pTimer );
};
}
pTimer->timerId = SafeTimerDelete( pTimer->timerId );
}
/*-----------------------------------------------------------*/
......@@ -174,27 +186,29 @@ bool IotClock_TimerArm( IotTimer_t * pTimer,
uint32_t relativeTimeoutMs,
uint32_t periodMs )
{
_IotSystemTimer_t * pTimerInfo = ( _IotSystemTimer_t * ) pTimer;
_IotSystemTimer_t * pNewTimerInfo;
if ( pTimerInfo == NULL ) {
if ( pTimer == NULL || pTimer->timerId == 0 ) {
IotLogError( "Timer doesn't exist. Can't Arm it." );
}
if( relativeTimeoutMs == periodMs )
{
IotLogDebug("Arming timer %p with period %llu.", pTimer, periodMs);
pTimer->timerId = SafeTimerDelete( pTimer->timerId );
osTimerType_t timer_type = ( 0 == periodMs ) ? osTimerOnce : osTimerPeriodic;
pTimer->timerId = osTimerNew( pTimer->callback, timer_type, pTimer->callbackArg, NULL );
osTimerStart( * pTimerInfo, pdMS_TO_TICKS( periodMs ) );
if( pTimer->timerId == NULL )
{
IotLogError( "Failed to create timer %p.", pTimer );
}
else
{
IotLogDebug( "Arming timer %p with timeout %llu and period %llu.", pTimer, relativeTimeoutMs, periodMs );
void *timerCallbackArg = { pTimer, periodMs, periodMs };
IotClock_TimerCreate( pNewTimerInfo, IotClock_TimerArm, timerCallbackArg );
IotLogDebug("Arming timer %p with timeout %llu.", pTimer, relativeTimeoutMs);
if (relativeTimeoutMs != periodMs)
{
IotLogError( "Requested periodicity %llu couldn't be set. Period must be the same as first timeout.", relativeTimeoutMs );
}
osTimerStart( pNewTimerInfo, pdMS_TO_TICKS( relativeTimeoutMs ) );
osTimerStart( pTimer->timerId, pdMS_TO_TICKS( relativeTimeoutMs ) );
}
return true;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment