126 lines
3.5 KiB
C
126 lines
3.5 KiB
C
/*************************************************************************\
|
|
* Copyright (c) 2023 Paul Scherrer Institute
|
|
* ecmc is distributed subject to a Software License Agreement found
|
|
* in file LICENSE that is included with this distribution.
|
|
*
|
|
* ecmcPluginSafety.c
|
|
*
|
|
* Created on: jan 29, 2024
|
|
* Author: anderssandstrom
|
|
*
|
|
* Instructions:
|
|
* - IMPORTANT: Add "USR_CFLAGS +=-DECMC_PLUGIN_MODULE_NAME=${MODULE}" to GNUMakefile
|
|
* - All functions and ecmcPluginData struct must be declared static
|
|
\*************************************************************************/
|
|
|
|
// Needed to get headers in ecmc right...
|
|
#define ECMC_IS_PLUGIN
|
|
#define ECMC_PLUGIN_VERSION 1
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif // ifdef __cplusplus
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "ecmcPluginDefs.h"
|
|
#include "ecmcSafetyPlgDefs.h"
|
|
#include "ecmcSafetyPlgWrap.h"
|
|
|
|
static int lastEcmcError = 0;
|
|
static int alreadyLoaded = 0;
|
|
static int destructs_ = 0;
|
|
|
|
/** Optional.
|
|
* Will be called once after successful load into ecmc.
|
|
* Return value other than 0 will be considered error.
|
|
* configStr can be used for configuration parameters.
|
|
**/
|
|
static int construct(char *configStr)
|
|
{
|
|
|
|
if(alreadyLoaded) {
|
|
return ECMC_PLUGIN_ALREADY_LOADED_ERROR_CODE;
|
|
}
|
|
|
|
alreadyLoaded = 1;
|
|
|
|
return setCfgString(configStr);
|
|
}
|
|
|
|
/** Optional function.
|
|
* Will be called once at unload.
|
|
**/
|
|
static void safetyDestruct(void)
|
|
{
|
|
destructs_ = 1;
|
|
deleteAllSafetyGroups();
|
|
}
|
|
|
|
/** Optional function.
|
|
* Will be called each realtime cycle if defined
|
|
* ecmcError: Error code of ecmc. Makes it possible for
|
|
* this plugin to react on ecmc errors
|
|
* Return value other than 0 will be considered to be an error code in ecmc.
|
|
**/
|
|
static int safetyRealtime(int ecmcError)
|
|
{
|
|
if(destructs_) return 0;
|
|
|
|
executeSafetyGroups();
|
|
lastEcmcError = ecmcError;
|
|
return 0;
|
|
}
|
|
|
|
/** Link to data source here since all sources should be available at this stage
|
|
* (for example ecmc PLC variables are defined only at enter of realtime)
|
|
**/
|
|
static int safetyEnterRT(){
|
|
return validate();
|
|
}
|
|
|
|
/** Optional function.
|
|
* Will be called once just before leaving realtime mode
|
|
* Return value other than 0 will be considered error.
|
|
**/
|
|
static int safetyExitRT(void){
|
|
return 0;
|
|
}
|
|
|
|
// Register data for plugin so ecmc know what to use
|
|
static struct ecmcPluginData pluginDataDef = {
|
|
// Allways use ECMC_PLUG_VERSION_MAGIC
|
|
.ifVersion = ECMC_PLUG_VERSION_MAGIC,
|
|
// Name
|
|
.name = "ecmc_plugin_safety",
|
|
// Description
|
|
.desc = "Safety plugin.",
|
|
// Option description
|
|
.optionDesc = "\n "ECMC_PLUGIN_DBG_PRINT_OPTION_CMD"<1/0> : Enables/disables printouts from plugin, default = disabled.\n"
|
|
,
|
|
// Plugin version
|
|
.version = ECMC_PLUGIN_VERSION,
|
|
// Optional construct func, called once at load. NULL if not defined.
|
|
.constructFnc = construct,
|
|
// Optional destruct func, called once at unload. NULL if not defined.
|
|
.destructFnc = safetyDestruct,
|
|
// Optional func that will be called each rt cycle. NULL if not defined.
|
|
.realtimeFnc = safetyRealtime,
|
|
// Optional func that will be called once just before enter realtime mode
|
|
.realtimeEnterFnc = safetyEnterRT,
|
|
// Optional func that will be called once just before exit realtime mode
|
|
.realtimeExitFnc = safetyExitRT,
|
|
// PLC funcs
|
|
.funcs[0] = {0}, // last element set all to zero..
|
|
// PLC consts
|
|
.consts[0] = {0}, // last element set all to zero..
|
|
};
|
|
|
|
ecmc_plugin_register(pluginDataDef);
|
|
|
|
# ifdef __cplusplus
|
|
}
|
|
# endif // ifdef __cplusplus
|