This is the code for a gensub record (asub record are said to be 100% compatible
with gensub)
Here is the code for a simple status code translation
Note that the asub and gensub have input and output records
In the example below:
1/ read the input (status code)
2/ write output (status string)
record(genSub, "$(deviceName)$(_)StsGS") {
field(DESC, "Status Translator")
field(SCAN, "Passive")
field(SCAN, "1 second")
field(INAM, "")
field(SNAM, "SNOVA_funcTranslateStatusCodes")
#field(SNAM, "SNOVA_funcIdle")
field(EFLG, "ON CHANGE")
#--- input
field(INPA, "$(deviceName)$(_)Main$(_)StsLI")
field(FTA, "LONG")
field(UFA, "")
field(NOA, "1")
field(INPB, "$(deviceName)$(_)HighVltg$(_)StsLI")
field(FTB, "LONG")
field(UFB, "")
field(NOB, "1")
field(INPC, "$(deviceName)$(_)Flmnt$(_)StsLI")
field(FTC, "LONG")
field(UFC, "")
field(NOC, "1")
field(INPD, "$(deviceName)$(_)Cmnctn$(_)StsLI")
field(FTD, "LONG")
field(UFD, "")
field(NOD, "1")
field(INPE, "$(deviceName)$(_)Reset$(_)StsLI")
field(FTE, "LONG")
field(UFE, "")
field(NOE, "1")
field(INPF, "$(deviceName)$(_)Mode$(_)StsLI")
field(FTF, "LONG")
field(UFF, "")
field(NOF, "1")
#gensub counter
field(INPU, "$(deviceName)$(_)StsGS NPP NMS")
field(FTU, "LONG")
field(NOU, "1")
field(UFU, "")
#--- ouput
field(OUTA, "$(deviceName)$(_)Main$(_)StsSI PP")
field(FTVA, "STRING")
field(NOVA, "40")
field(OUTB, "$(deviceName)$(_)HighVltg$(_)StsSI PP")
field(FTVB, "STRING")
field(NOVB, "40")
field(OUTC, "$(deviceName)$(_)Flmnt$(_)StsSI PP")
field(FTVC, "STRING")
field(NOVC, "40")
field(OUTD, "$(deviceName)$(_)Cmnctn$(_)StsSI PP")
field(FTVD, "STRING")
field(NOVD, "40")
field(OUTE, "$(deviceName)$(_)Reset$(_)StsSI PP")
field(FTVE, "STRING")
field(NOVE, "40")
field(OUTF, "$(deviceName)$(_)Mode$(_)StsSI PP")
field(FTVF, "STRING")
field(NOVF, "40")
field(OUTG, "$(deviceName)$(_)WrnngBI PP")
field(FTVG, "SHORT")
field(NOVG, "1")
field(OUTH, "$(deviceName)$(_)AlarmBI PP")
field(FTVH, "SHORT")
field(NOVH, "1")
}
#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "dbCommon.h"
#include "dbDefs.h"
#include "dbEvent.h"
#include "epicsExport.h"
#include "genSubRecord.h"
#include "recSup.h"
#include "registryFunction.h"
#define SUCCESS 0
#define ERROR -1
#define BUFLEN 40
int SNOVA_funcTranslateStatusCodes_LOG=1;
epicsExportAddress(int, SNOVA_funcTranslateStatusCodes_LOG);
/*----------------------------------------------------------------------*/
static int funcLog(int logLevel, const char *format, ...) {
va_list args;
if ( (SNOVA_funcTranslateStatusCodes_LOG % logLevel ) == 0 ) {
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
}
return(SUCCESS);
}
/*----------------------------------------------------------------------*/
static int translateMainStatus(long mainStatusLI, char *p_mainStatusSI) {
switch(mainStatusLI) {
case 1: strncpy(p_mainStatusSI,"HV-TankOpen interlock",40); break;
case 2: strncpy(p_mainStatusSI,"HV-Temp interlock",40); break;
case 3: strncpy(p_mainStatusSI,"HV-Oil level interlock",40); break;
case 4: strncpy(p_mainStatusSI,"HV-Pressure interlock",40); break;
case 5: strncpy(p_mainStatusSI,"HV-DCPS interlock",40); break;
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17: strncpy(p_mainStatusSI,"HV-IGBT interlock",40); break;
case 18: strncpy(p_mainStatusSI,"HV-Voltage interlock",40); break;
case 19: strncpy(p_mainStatusSI,"HV-Spark interlock",40); break;
case 20: strncpy(p_mainStatusSI,"HV-Power exceeded interlock",40); break;
case 21: strncpy(p_mainStatusSI,"HV-DcReset interlock",40); break;
case 22: strncpy(p_mainStatusSI,"Communication interlock",40); break;
case 23: strncpy(p_mainStatusSI,"Spark interlock",40); break;
case 24: strncpy(p_mainStatusSI,"Power exceeded interlock",40); break;
case 25: strncpy(p_mainStatusSI,"SafetyBus interlock",40); break;
case 26: strncpy(p_mainStatusSI,"Waterflow interlock",40); break;
case 27:
case 99: strncpy(p_mainStatusSI,"HV-Spare",40); break;
case 100: strncpy(p_mainStatusSI,"Temp interlock",40); break;
case 101: strncpy(p_mainStatusSI,"LoOil interlock",40); break;
case 102: strncpy(p_mainStatusSI,"HiOil interlock",40); break;
case 103: strncpy(p_mainStatusSI,"FilVolt interlock",40); break;
case 104: strncpy(p_mainStatusSI,"FilCurr interlock",40); break;
case 105: strncpy(p_mainStatusSI,"Waterflow interlock",40); break;
case 106:
case 199: strncpy(p_mainStatusSI,"Spare",40); break;
case 1000: strncpy(p_mainStatusSI,"Off",40); break;
case 2000: strncpy(p_mainStatusSI,"Cooling down...",40); break;
case 7000: strncpy(p_mainStatusSI,"Warming up...",40); break;
case 7001: strncpy(p_mainStatusSI,"Warm",40); break;
case 8000: strncpy(p_mainStatusSI,"HV On",40); break;
case 8001: strncpy(p_mainStatusSI,"HV Trig",40); break;
default: strncpy(p_mainStatusSI,"Unknown status",40); break;
}
return(SUCCESS);
}
/*----------------------------------------------------------------------*/
static int translateHighVoltageStatus(
long highVoltageStatusLI, char *p_highVoltageStatusSI) {
switch(highVoltageStatusLI) {
case 1: strncpy(p_highVoltageStatusSI,"OilTemp interlock",40); break;
case 2: strncpy(p_highVoltageStatusSI,"LoOilLevel interlock",40); break;
case 3: strncpy(p_highVoltageStatusSI,"HiOilLevel interlock",40); break;
case 4: strncpy(p_highVoltageStatusSI,"Dcps interlock",40); break;
case 5: strncpy(p_highVoltageStatusSI,"DcpsVoltage interlock",40); break;
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17: strncpy(p_highVoltageStatusSI,"Lgbt interlock",40); break;
case 18: strncpy(p_highVoltageStatusSI,"Load Current interlock",40); break;
case 19: strncpy(p_highVoltageStatusSI,"Load Voltage interlock",40); break;
case 20: strncpy(p_highVoltageStatusSI,"DcResetCurr interlock",40); break;
case 21: strncpy(p_highVoltageStatusSI,"DcResetVltg interlock",40); break;
case 22: strncpy(p_highVoltageStatusSI,"Communication interlock",40); break;
case 23: strncpy(p_highVoltageStatusSI,"Spark interlock",40); break;
case 24: strncpy(p_highVoltageStatusSI,"Power exceed interlock",40); break;
case 25: strncpy(p_highVoltageStatusSI,"SafetyBus interlock",40); break;
case 26: strncpy(p_highVoltageStatusSI,"Waterflow interlock",40); break;
case 27:
case 98: strncpy(p_highVoltageStatusSI,"Spare",40); break;
case 1000: strncpy(p_highVoltageStatusSI,"Off",40); break;
case 1001: strncpy(p_highVoltageStatusSI,"HV-Cnd",40); break;
case 2000: strncpy(p_highVoltageStatusSI,"Off requested",40); break;
case 7000: strncpy(p_highVoltageStatusSI,"On requested",40); break;
case 7001: strncpy(p_highVoltageStatusSI,"Ramp up HV",40); break;
case 8000: strncpy(p_highVoltageStatusSI,"HV on",40); break;
case 8001: strncpy(p_highVoltageStatusSI,"HV trig",40); break;
default: strncpy(p_highVoltageStatusSI,"Unknown",40);
}
return(SUCCESS);
}
/*----------------------------------------------------------------------*/
static int translateFilamentStatus(long filamentStatusLI, char
*p_filamentStatusSI) {
switch(filamentStatusLI) {
case 100: strncpy(p_filamentStatusSI,"Temp interlock",40); break;
case 101: strncpy(p_filamentStatusSI,"LoOil interlock",40); break;
case 102: strncpy(p_filamentStatusSI,"HiOil interlock",40); break;
case 103: strncpy(p_filamentStatusSI,"FilVolt interlock",40); break;
case 104: strncpy(p_filamentStatusSI,"FilCurr interlock",40); break;
case 105: strncpy(p_filamentStatusSI,"Waterflow interlock",40); break;
case 106:
case 198: strncpy(p_filamentStatusSI,"Spare",40); break;
case 199: strncpy(p_filamentStatusSI,"Fault",40); break;
case 1000: strncpy(p_filamentStatusSI,"Off",40); break;
case 1001: strncpy(p_filamentStatusSI,"FilPs-Cnd",40); break;
case 2000: strncpy(p_filamentStatusSI,"Off requested",40); break;
case 7000: strncpy(p_filamentStatusSI,"On requested",40); break;
case 7001: strncpy(p_filamentStatusSI,"Preheating (0min)",40); break;
case 7002: strncpy(p_filamentStatusSI,"Preheating (1min)",40); break;
case 7003: strncpy(p_filamentStatusSI,"Preheating (2min)",40); break;
case 7004: strncpy(p_filamentStatusSI,"Preheating (3min)",40); break;
case 7005: strncpy(p_filamentStatusSI,"Preheating (4min)",40); break;
case 7006: strncpy(p_filamentStatusSI,"Preheating (5min)",40); break;
case 7007: strncpy(p_filamentStatusSI,"Preheating (6min)",40); break;
case 7008: strncpy(p_filamentStatusSI,"Preheating (7min)",40); break;
case 7009: strncpy(p_filamentStatusSI,"Preheating (8min)",40); break;
case 7010: strncpy(p_filamentStatusSI,"Preheating (9min)",40); break;
case 7011: strncpy(p_filamentStatusSI,"Preheating (10min)",40); break;
case 7012: strncpy(p_filamentStatusSI,"Preheating (11min)",40); break;
case 7013: strncpy(p_filamentStatusSI,"Preheating (12min)",40); break;
case 7014: strncpy(p_filamentStatusSI,"Preheating (13min)",40); break;
case 7015: strncpy(p_filamentStatusSI,"Preheating (14min)",40); break;
case 7016: strncpy(p_filamentStatusSI,"Preheating (15min)",40); break;
case 8000: strncpy(p_filamentStatusSI,"On",40); break;
default: strncpy(p_filamentStatusSI,"Unknown Filament",40);
}
return(SUCCESS);
}
/*----------------------------------------------------------------------*/
static int translateCommunicationStatus(long communicationStatusLI, char
*p_communicationStatusSI) {
switch(communicationStatusLI) {
case 1: strncpy(p_communicationStatusSI,"Communication interlock",40); break;
case 1000: strncpy(p_communicationStatusSI,"Off",40); break;
case 8000: strncpy(p_communicationStatusSI,"Ok",40); break;
case 8001: strncpy(p_communicationStatusSI,"One missed reply",40); break;
case 8002: strncpy(p_communicationStatusSI,"Two missed reply",40); break;
case 8003: strncpy(p_communicationStatusSI,"Three missed reply",40); break;
case 8004: strncpy(p_communicationStatusSI,"Four missed reply",40); break;
default: strncpy(p_communicationStatusSI,"Unknown Com",40);
}
return(SUCCESS);
}
/*----------------------------------------------------------------------*/
static int translateResetStatus(long resetStatusLI, char *p_resetStatusSI) {
switch(resetStatusLI) {
case 1000: strncpy(p_resetStatusSI,"Off",40); break;
case 7000: strncpy(p_resetStatusSI,"Reset requested",40); break;
case 8000: strncpy(p_resetStatusSI,"Resetting",40); break;
default: strncpy(p_resetStatusSI,"Unknown Reset",40);
}
return(SUCCESS);
}
/*----------------------------------------------------------------------*/
static int translateModeStatus(long modeStatusLI, char *p_modeStatusSI) {
switch(modeStatusLI) {
case 0: strncpy(p_modeStatusSI,"Off",40); break;
case 1: strncpy(p_modeStatusSI,"Status 1",40); break;
case 2: strncpy(p_modeStatusSI,"Status 2",40); break;
case 3: strncpy(p_modeStatusSI,"Status 3",40); break;
case 4: strncpy(p_modeStatusSI,"Ready",40); break;
default: strncpy(p_modeStatusSI,"Unknown Mode",40);
}
return(SUCCESS);
}
/*----------------------------------------------------------------------*/
static long SNOVA_funcTranslateStatusCodes( struct genSubRecord *p_gensub ) {
long mainStatusLI;
long highVoltageStatusLI;
long filamentStatusLI;
long communicationStatusLI;
long resetStatusLI;
long modeStatusLI;
char p_mainStatusSI[BUFLEN];
char p_highVoltageStatusSI[BUFLEN];
char p_filamentStatusSI[BUFLEN];
char p_communicationStatusSI[BUFLEN];
char p_resetStatusSI[BUFLEN];
char p_modeStatusSI[BUFLEN];
long *p_counter;
short alarmBI;
short warningBI;
funcLog( 3, __FILE__ "[%d] --> %s (%s)\n",
__LINE__, __func__, p_gensub->name);
mainStatusLI=*(long *)p_gensub->a;
translateMainStatus(mainStatusLI,p_mainStatusSI);
memcpy(p_gensub->vala, p_mainStatusSI, BUFLEN*sizeof(char));
highVoltageStatusLI=*(long *)p_gensub->b;
translateHighVoltageStatus(highVoltageStatusLI,p_highVoltageStatusSI);
memcpy(p_gensub->valb, p_highVoltageStatusSI, BUFLEN*sizeof(char));
filamentStatusLI=*(long *)p_gensub->c;
translateFilamentStatus(filamentStatusLI,p_filamentStatusSI);
memcpy(p_gensub->valc, p_filamentStatusSI, BUFLEN*sizeof(char));
communicationStatusLI=*(long *)p_gensub->d;
translateCommunicationStatus(communicationStatusLI,p_communicationStatusSI);
memcpy(p_gensub->vald, p_communicationStatusSI, BUFLEN*sizeof(char));
resetStatusLI=*(long *)p_gensub->e;
translateResetStatus(resetStatusLI,p_resetStatusSI);
memcpy(p_gensub->vale, p_resetStatusSI, BUFLEN*sizeof(char));
modeStatusLI=*(long *)p_gensub->f;
translateModeStatus(modeStatusLI,p_modeStatusSI);
memcpy(p_gensub->valf, p_modeStatusSI, BUFLEN*sizeof(char));
alarmBI=0;
warningBI=0;
if (mainStatusLI<200) {
alarmBI=0;
warningBI=1;
}
memcpy(p_gensub->valg, &warningBI, sizeof(short));
memcpy(p_gensub->valh, &alarmBI, sizeof(short));
funcLog( 5, __FILE__ "[%d] %s\n", __LINE__, p_gensub->name);
funcLog( 5, __FILE__ "[%d] mainStatusSI = >%s< (%d)\n",
__LINE__, p_gensub->vala, mainStatusLI);
funcLog( 5, __FILE__ "[%d] highVoltageStatusSI = >%s< (%d)\n",
__LINE__, p_gensub->valb, highVoltageStatusLI);
funcLog( 5, __FILE__ "[%d] filamentStatusSI = >%s< (%d)\n",
__LINE__, p_gensub->valc, filamentStatusLI);
funcLog( 5, __FILE__ "[%d] communicationStatusSI= >%s< (%d)\n",
__LINE__, p_gensub->vald, communicationStatusLI);
funcLog( 5, __FILE__ "[%d] resetStatusSI = >%s< (%d)\n",
__LINE__, p_gensub->vale, resetStatusLI);
funcLog( 5, __FILE__ "[%d] modeStatusSI = >%s< (%d)\n",
__LINE__, p_gensub->valf, modeStatusLI);
funcLog( 5, __FILE__ "[%d] warningBI = %d (%d,%d)\n",
__LINE__, *(short *)p_gensub->valg, warningBI, mainStatusLI);
funcLog( 5, __FILE__ "[%d] alarmBI = %d (%d,%d)\n",
__LINE__, *(short *)p_gensub->valh, alarmBI, mainStatusLI);
p_counter=(long *)p_gensub->u;
*p_counter=*p_counter+1;
funcLog( 3, __FILE__ "[%d] <-- %s (%ld)\n",
__LINE__, __func__, *p_counter);
return(*p_counter);
}
epicsRegisterFunction(SNOVA_funcTranslateStatusCodes);
> Date: Wed, 16 Oct 2013 18:16:44 +0800
> From: [email protected]
> To: [email protected]
> Subject: how to put value to other record in subroutine record
>
> hi, all:
>
> if I want to change another record's value in a subroutine record's process
function, can I call dbPutField() or other functions? can anyone show me some
examples?
> thanks a lot in advance.
>
>
> --------------
> Best wishes
> Geyang 2013-10-16
>