Advanced Distributed Systems module at HSLU
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

103 lines
3.2 KiB

/**
* \file
* \brief Implementation of generic triggers.
* \author Erich Styger, erich.styger@hslu.ch
* \license SPDX-License-Identifier: BSD-3-Clause
* This module implements a trigger module.
* Triggers are special events which are triggered in a given time in the future
*/
#include "platform.h"
#include "Trigger.h"
#include "McuCriticalSection.h"
#include <stddef.h> /* for NULL */
/*! \brief Descriptor for a trigger. */
typedef struct TRG_TriggerDesc {
TRG_TriggerTime ticks; /*!< tick count until trigger */
TRG_Callback callback; /*!< callback function */
TRG_CallBackDataPtr data; /*!< additional data pointer for callback */
} TRG_TriggerDesc;
static TRG_TriggerDesc TRG_Triggers[TRG_NOF_TRIGGERS]; /*!< Array of triggers */
uint8_t TRG_SetTrigger(TRG_TriggerKind trigger, TRG_TriggerTime ticks, TRG_Callback callback, TRG_CallBackDataPtr data) {
McuCriticalSection_CriticalVariable()
McuCriticalSection_EnterCritical();
TRG_Triggers[trigger].ticks = ticks;
TRG_Triggers[trigger].callback = callback;
TRG_Triggers[trigger].data = data;
McuCriticalSection_ExitCritical();
return ERR_OK;
}
uint8_t TRG_StopTrigger(TRG_TriggerKind trigger) {
McuCriticalSection_CriticalVariable()
McuCriticalSection_EnterCritical();
TRG_Triggers[trigger].ticks = 0;
TRG_Triggers[trigger].callback = NULL;
TRG_Triggers[trigger].data = NULL;
McuCriticalSection_ExitCritical();
return ERR_OK;
}
/*!
* \brief Goes through the list of triggers and returns TRUE in case we have to call a callback.
* \return Returns TRUE if we have called a callback.
*/
static bool CheckCallbacks(void) {
TRG_TriggerKind i;
TRG_Callback callback;
TRG_CallBackDataPtr data;
bool calledCallBack = FALSE;
McuCriticalSection_CriticalVariable()
for(i=(TRG_TriggerKind)0;i<TRG_NOF_TRIGGERS;i++) {
McuCriticalSection_EnterCritical();
if (TRG_Triggers[i].ticks==0 && TRG_Triggers[i].callback != NULL) { /* trigger! */
callback = TRG_Triggers[i].callback; /* get a copy */
data = TRG_Triggers[i].data; /* get backup of data, as we overwrite it below */
/* reset trigger structure, as callback might setup this trigger again */
TRG_Triggers[i].callback = NULL; /* NULL callback prevents that we are called again */
McuCriticalSection_ExitCritical();
callback(data);
calledCallBack = TRUE; /* callback may have set a trigger at the current time: rescan trigger list */
} else {
McuCriticalSection_ExitCritical();
}
} /* for */
return calledCallBack;
}
void TRG_AddTick(void) {
TRG_TriggerKind i;
uint8_t res;
McuCriticalSection_CriticalVariable()
McuCriticalSection_EnterCritical();
for(i=(TRG_TriggerKind)0;i<TRG_NOF_TRIGGERS;i++) {
if (TRG_Triggers[i].ticks!=0) { /* prevent underflow */
TRG_Triggers[i].ticks--;
}
} /* for */
McuCriticalSection_ExitCritical();
do {
res = CheckCallbacks(); /* while there are callbacks, re-iterate */
} while(res);
}
void TRG_Deinit(void) {
/* nothing to do */
}
void TRG_Init(void) {
TRG_TriggerKind i;
for(i=(TRG_TriggerKind)0;i<TRG_NOF_TRIGGERS;i++) {
TRG_Triggers[i].ticks = 0;
TRG_Triggers[i].callback = NULL;
TRG_Triggers[i].data = NULL;
}
}