/******************************************************************************* * E.S.O. - VLT project * * "@(#) $Id: tacReadRmnBlock.c 305476 2018-01-19 08:56:18Z rfrahm $" * * who when what * ------- -------- ---------------------------------------------- * gzins 2010-07-27 ported to VLTSW2010 and VxWorks 6.4 * swehner 2008-10-10 creation */ /************************************************************************ * NAME * tacReadRmnBlock - Implemements the standard functions for the * tacReadRmn block and tacReadRfm block. * tacReadRmnBlock - Reads from 1rst generation reflective memory network * tacReadRfmBlock - Reads from 2nd generation reflective memory network * Parameters: * field - token names for the RMN fields to read (up to 10) * Inputs: 0 * Outputs: 1 * output - 1..10 depending on number of field parameters * * * * FILES * * ENVIRONMENT * TAC * * RETURN VALUES * * CAUTIONS * * EXAMPLES * TAC.BLOCK9.TYPE ReadRmn * TAC.BLOCK9.NAME ReadRmn * * SEE ALSO * * BUGS * *------------------------------------------------------------------------ */ #define _POSIX_SOURCE 1 #include "vltPort.h" ATTRIBUTE_UNUSED static const char *rcsId="@(#) $Id: tacReadRmnBlock.c 305476 2018-01-19 08:56:18Z rfrahm $"; /* * System Headers */ #include <taskLib.h> /* taskSpawn, taskDelay, ... */ #include <stdio.h> /* printf ... */ #include <string.h> /* malloc ... */ #include <stdlib.h> /* malloc ... */ #include <logLib.h> #include <math.h> /* * Local Headers */ #include "tacStdBlock.h" #include "tacRmnBlock.h" #include "rmassPublic.h" #include "rmassPrivate.h" /* * Compilation directives */ /* * Constants */ #define tacREAD_RMN_EXPECTED_PARAM 1 #define tacREAD_RMN_DEFAULT_INPUT_NUMBER 0 #define tacREAD_RMN_DEFAULT_OUTPUT_NUMBER tacMAX_DATA_NUMBER #define tacREAD_RMN_FIELD_STRING_LEN 256 #define tacSTRLEN sizeof(double) /* * Types */ /* * Local function declaration */ /* * Global variables */ /* * Function definition */ STATUS tacReadRmnBlockCheckParameter (tacSTDBLOCK* pSelf, /* Reference to the block instance */ tacSTDBLOCK_PARAM* parameter, /* Parameters of the ADDBLCK command */ tacERROR* error) /* Error structure - not a stack */ { tacRMN_LOCAL_PARAMETER* pSelfParam = NULL; pSelfParam = (tacRMN_LOCAL_PARAMETER*) pSelf->parameter; /* field string is built from block params */ if ( tacRmnBlockCheckParameter ( pSelf, parameter, 0, error) != OK ) { return ERROR; } /* useful information on the screen */ printf ("ReadRmn %s: [%s]\n", pSelf->name, pSelfParam->fieldString); return OK; } STATUS tacReadRfmBlockCheckParameter (tacSTDBLOCK* pSelf, /* Reference to the block instance */ tacSTDBLOCK_PARAM* parameter, /* Parameters of the ADDBLCK command */ tacERROR* error) /* Error structure - not a stack */ { tacRMN_LOCAL_PARAMETER* pSelfParam = NULL; pSelfParam = (tacRMN_LOCAL_PARAMETER*) pSelf->parameter; /* field string is built from block params */ if ( tacRmnBlockCheckParameter ( pSelf, parameter, 0, error) != OK ) { return ERROR; } /* useful information on the screen */ printf ("ReadRfm %s: [%s]\n", pSelf->name, pSelfParam->fieldString); return OK; } /* * Constructor Hooks - Called when a block of this type is instanciated (CONFIG or ADDBLCK commands) */ STATUS tacReadRmBlockConstructor (tacSTDBLOCK* pSelf, /* Reference to the block instance */ tacSTDBLOCK_PARAM* parameter, /* Parameters of the ADDBLCK command */ vltLOGICAL isRmn, tacERROR* error) /* Error structure - not a stack */ { tacRMN_LOCAL_PARAMETER* pSelfParam = NULL; /* Check that the expected number of parameters has been received */ if (parameter->number < tacREAD_RMN_EXPECTED_PARAM) { char errorParam[40]; sprintf(errorParam, "Expected at least %d, received %d", tacREAD_RMN_EXPECTED_PARAM, parameter->number); tacRTC_ERR(tacERR_PARAM_NUMBER, errorParam); return ERROR; } /* Allocate and initialize block-specific arrays */ if (tacStdBlockAllocateArrays(pSelf, 0, tacREAD_RMN_DEFAULT_INPUT_NUMBER, tacREAD_RMN_DEFAULT_OUTPUT_NUMBER, error) == ERROR) { return ERROR; } if (tacStdBlockAllocateArrayBySize(pSelf, tacSTDBLOCK_PARAM_ARRAY, sizeof(tacRMN_LOCAL_PARAMETER), error) == ERROR) { tacStdBlockReleaseArray(pSelf, tacSTDBLOCK_INPUT_ARRAY, error); tacStdBlockReleaseArray(pSelf, tacSTDBLOCK_OUTPUT_ARRAY, error); return ERROR; } if ( isRmn ) { if ( tacReadRmnBlockCheckParameter (pSelf, parameter, error) == ERROR) { return ERROR; } } else { if ( tacReadRfmBlockCheckParameter (pSelf, parameter, error) == ERROR) { return ERROR; } } pSelfParam = (tacRMN_LOCAL_PARAMETER*) pSelf->parameter; pSelfParam->handleValid = rmassACCESS_BLOCKED; /* Attach to RMN */ if ( rmassReadAttach (&pSelfParam->handle, pSelfParam->fieldString, &pSelfParam->val[0], &pSelfParam->val[1], &pSelfParam->val[2], &pSelfParam->val[3], &pSelfParam->val[4], &pSelfParam->val[5], &pSelfParam->val[6], &pSelfParam->val[7], &pSelfParam->val[8], &pSelfParam->val[9]) != SUCCESS ) { char errorParam[40]; sprintf(errorParam, "Attach to RMN failed."); tacRTC_ERR(tacERR_INTERNAL, errorParam); return ERROR; } pSelfParam->handleValid = rmassACCESS_FREE; return OK; } STATUS tacReadRmnBlockConstructor (tacSTDBLOCK* pSelf, /* Reference to the block instance */ tacSTDBLOCK_PARAM* parameter, /* Parameters of the ADDBLCK command */ tacERROR* error) /* Error structure - not a stack */ { if ( tacReadRmBlockConstructor (pSelf, parameter, ccsTRUE, error ) == ERROR ) { return ERROR; } return OK; } STATUS tacReadRfmBlockConstructor (tacSTDBLOCK* pSelf, /* Reference to the block instance */ tacSTDBLOCK_PARAM* parameter, /* Parameters of the ADDBLCK command */ tacERROR* error) /* Error structure - not a stack */ { if ( tacReadRmBlockConstructor (pSelf, parameter, ccsFALSE, error ) == ERROR ) { return ERROR; } return OK; } /* * Destructor Hooks - Called when the block is removed from the algorithm (DELBLCK or new CONFIG commands) */ void tacReadRmnBlockDestructor (tacSTDBLOCK* pSelf) /* Reference to the block instance */ { tacRMN_LOCAL_PARAMETER* pSelfParam = NULL; pSelfParam = (tacRMN_LOCAL_PARAMETER*) pSelf->parameter; pSelfParam->handleValid = rmassACCESS_BLOCKED; /* wait until semaphore is acknowledged by realtime algo * or just procede if realtime is not active */ while ((*pSelf->shared).active && pSelfParam->handleValid != rmassACCESS_BLOCK_ACKN) { taskDelay(1); } rmassDetach (&pSelfParam->handle); return; } /* * Change parameters Hooks - Called when modifying the block parameters (MODBLCK command) */ STATUS tacReadRmnBlockSetParameter (tacSTDBLOCK* pSelf, /* Reference to the block instance */ tacSTDBLOCK_PARAM* parameter, /* Parameters of the MODBLCK command */ tacERROR* error) /* Error structure - not a stack */ { tacRMN_LOCAL_PARAMETER* pSelfParam = (tacRMN_LOCAL_PARAMETER*) pSelf->parameter; if ( tacReadRmnBlockCheckParameter (pSelf, parameter, error) == ERROR) { return ERROR; } pSelfParam->handleValid = rmassACCESS_BLOCKED; /* wait until semaphore is acknowledged by realtime algo * or just procede if realtime is not active */ while ((*pSelf->shared).active && pSelfParam->handleValid != rmassACCESS_BLOCK_ACKN) { taskDelay(1); } /* detach RMN handle */ if ( rmassDetach (&pSelfParam->handle) != SUCCESS ) { char errorParam[40]; sprintf(errorParam, "rmassDetach returned error."); tacRTC_ERR(tacERR_INTERNAL, errorParam); return ERROR; } if ( rmassReadAttach (&pSelfParam->handle, pSelfParam->fieldString, &pSelfParam->val[0], &pSelfParam->val[1], &pSelfParam->val[2], &pSelfParam->val[3], &pSelfParam->val[4], &pSelfParam->val[5], &pSelfParam->val[6], &pSelfParam->val[7], &pSelfParam->val[8], &pSelfParam->val[9]) != SUCCESS ) { char errorParam[40]; sprintf(errorParam, "Attach to RMN failed."); tacRTC_ERR(tacERR_INTERNAL, errorParam); return ERROR; } pSelfParam->handleValid = rmassACCESS_FREE; return OK; } STATUS tacReadRfmBlockSetParameter (tacSTDBLOCK* pSelf, /* Reference to the block instance */ tacSTDBLOCK_PARAM* parameter, /* Parameters of the MODBLCK command */ tacERROR* error) /* Error structure - not a stack */ { tacRMN_LOCAL_PARAMETER* pSelfParam = (tacRMN_LOCAL_PARAMETER*) pSelf->parameter; if ( tacReadRfmBlockCheckParameter (pSelf, parameter, error) == ERROR) { return ERROR; } pSelfParam->handleValid = rmassACCESS_BLOCKED; /* wait until semaphore is acknowledged by realtime algo * or just procede if realtime is not active */ while ((*pSelf->shared).active && pSelfParam->handleValid != rmassACCESS_BLOCK_ACKN) { taskDelay(1); } /* detach RMN handle */ if ( rmassDetach (&pSelfParam->handle) != SUCCESS ) { char errorParam[40]; sprintf(errorParam, "rmassDetach returned error."); tacRTC_ERR(tacERR_INTERNAL, errorParam); return ERROR; } if ( rmassReadAttach (&pSelfParam->handle, pSelfParam->fieldString, &pSelfParam->val[0], &pSelfParam->val[1], &pSelfParam->val[2], &pSelfParam->val[3], &pSelfParam->val[4], &pSelfParam->val[5], &pSelfParam->val[6], &pSelfParam->val[7], &pSelfParam->val[8], &pSelfParam->val[9]) != SUCCESS ) { char errorParam[40]; sprintf(errorParam, "Attach to RFM failed."); tacRTC_ERR(tacERR_INTERNAL, errorParam); return ERROR; } pSelfParam->handleValid = rmassACCESS_FREE; return OK; } /* * Algorithm Hooks - Called at each time the TAC algorithm is evaluated (ONLINE state) */ void tacReadRmnBlockAlgorithm (tacSTDBLOCK* pSelf) /* Reference to the block instance */ { tacRMN_LOCAL_PARAMETER* pSelfParam = (tacRMN_LOCAL_PARAMETER*) pSelf->parameter; int i; if ( pSelfParam->handleValid == rmassACCESS_BLOCKED ) { pSelfParam->handleValid = rmassACCESS_BLOCK_ACKN; } if ( pSelfParam->handleValid == rmassACCESS_FREE ) { /* actual RMN read operation */ rmassReadAccessRmn (&pSelfParam->handle); /* Write to outputs */ for (i=0; i < pSelfParam->numFields; i++) { switch (pSelfParam->type[i]) { case rmassTIMESEC: case rmassUINT32: tacStdBlockSetOutput(pSelf, i, (*pSelfParam->val[i]).ui); break; case rmassTIMEUSEC: case rmassINT32: tacStdBlockSetOutput(pSelf, i, (*pSelfParam->val[i]).i); break; case rmassFLOAT: tacStdBlockSetOutput(pSelf, i, (*pSelfParam->val[i]).f); break; default: tacStdBlockSetOutput(pSelf, i, (*pSelfParam->val[i]).d); break; } } /* provide zero values at unsatisfied outputs * I consider this a good thing to do since the block * is always configured */ for (i=pSelfParam->numFields; i < tacREAD_RMN_DEFAULT_OUTPUT_NUMBER; i++) { tacStdBlockSetOutput(pSelf, i, 0.0); } } } void tacReadRfmBlockAlgorithm (tacSTDBLOCK* pSelf) /* Reference to the block instance */ { tacRMN_LOCAL_PARAMETER* pSelfParam = (tacRMN_LOCAL_PARAMETER*) pSelf->parameter; int i; if ( pSelfParam->handleValid == rmassACCESS_BLOCKED ) { pSelfParam->handleValid = rmassACCESS_BLOCK_ACKN; } if ( pSelfParam->handleValid == rmassACCESS_FREE ) { /* actual RMN read operation */ rmassReadAccessRfm (&pSelfParam->handle); /* Write to outputs */ for (i=0; i < pSelfParam->numFields; i++) { switch (pSelfParam->type[i]) { case rmassTIMESEC: case rmassUINT32: tacStdBlockSetOutput(pSelf, i, (*pSelfParam->val[i]).ui); break; case rmassTIMEUSEC: case rmassINT32: tacStdBlockSetOutput(pSelf, i, (*pSelfParam->val[i]).i); break; case rmassFLOAT: tacStdBlockSetOutput(pSelf, i, (*pSelfParam->val[i]).f); break; default: tacStdBlockSetOutput(pSelf, i, (*pSelfParam->val[i]).d); break; } } /* provide zero values at unsatisfied outputs * I consider this a good thing to do since the block * is always configured */ for (i=pSelfParam->numFields; i < tacREAD_RMN_DEFAULT_OUTPUT_NUMBER; i++) { tacStdBlockSetOutput(pSelf, i, 0.0); } } } /* * Show Hooks - Called when the tacRtcTaskShow routine is executed */ void tacReadRmnBlockShow (tacSTDBLOCK* pSelf) /* Reference to the block instance */ { tacRMN_LOCAL_PARAMETER* pSelfParam = (tacRMN_LOCAL_PARAMETER*) pSelf->parameter; /* Print parameter values */ printf(" Attached: %s\n", pSelfParam->fieldString); return; } /***************************************************/ /* The following code is common to all block types */ /* Do not modify without any good reasons */ /***************************************************/ /* * Installation function */ tacSTDBLOCK_TYPE tacReadRmnTypeInfo = { "ReadRmn", &tacReadRmnBlockConstructor, &tacRmBlockGetParameter, &tacReadRmnBlockAlgorithm, &tacReadRmnBlockSetParameter, NULL, NULL, &tacReadRmnBlockDestructor, &tacReadRmnBlockShow }; tacSTDBLOCK_TYPE tacReadRfmTypeInfo = { "ReadRfm", &tacReadRfmBlockConstructor, &tacRmBlockGetParameter, &tacReadRfmBlockAlgorithm, &tacReadRmnBlockSetParameter, NULL, NULL, &tacReadRmnBlockDestructor, &tacReadRmnBlockShow }; STATUS tacReadRmnBlockInitAll (void) { /***************************************************/ /* The following code is common to all block types */ /* Do not modify without any good reasons */ /***************************************************/ /* Install ReadRmn1g Block Hooks */ tacStdBlockInstallNewType(&tacReadRmnTypeInfo); /*****************************/ /* End of common code region */ /*****************************/ /* Perform other library initialization operations */ return OK; } STATUS tacReadRfmBlockInitAll (void) { /***************************************************/ /* The following code is common to all block types */ /* Do not modify without any good reasons */ /***************************************************/ /* Install ReadRmn1g Block Hooks */ tacStdBlockInstallNewType(&tacReadRfmTypeInfo); /*****************************/ /* End of common code region */ /*****************************/ /* Perform other library initialization operations */ return OK; } /*___oOo___*/