This is Unofficial EPICS BASE Doxygen Site
dbnd.c
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2010 Brookhaven National Laboratory.
3 * Copyright (c) 2010 Helmholtz-Zentrum Berlin
4 * für Materialien und Energie GmbH.
5 * Copyright (c) 2014 ITER Organization.
6 * EPICS BASE is distributed subject to a Software License Agreement found
7 * in file LICENSE that is included with this distribution.
8 \*************************************************************************/
9 
10 /*
11  * Author: Ralph Lange <Ralph.Lange@gmx.de>
12  */
13 
14 #include <stdio.h>
15 
16 #include <epicsMath.h>
17 #include <freeList.h>
18 #include <dbConvertFast.h>
19 #include <chfPlugin.h>
20 #include <recGbl.h>
21 #include <epicsExit.h>
22 #include <db_field_log.h>
23 #include <epicsExport.h>
24 
25 typedef struct myStruct {
26  int mode;
27  double cval;
28  double hyst;
29  double last;
30 } myStruct;
31 
32 static void *myStructFreeList;
33 
34 static const
35 chfPluginEnumType modeEnum[] = { {"abs", 0}, {"rel", 1}, {NULL,0} };
36 
37 static const
38 chfPluginArgDef opts[] = {
39  chfDouble (myStruct, cval, "d", 0, 1),
40  chfEnum (myStruct, mode, "m", 0, 1, modeEnum),
41  chfTagDouble (myStruct, cval, "abs", mode, 0, 0, 1),
42  chfTagDouble (myStruct, cval, "rel", mode, 1, 0, 1),
43  chfPluginArgEnd
44 };
45 
46 static void * allocPvt(void)
47 {
48  return freeListCalloc(myStructFreeList);
49 }
50 
51 static void freePvt(void *pvt)
52 {
53  freeListFree(myStructFreeList, pvt);
54 }
55 
56 static int parse_ok(void *pvt)
57 {
58  myStruct *my = (myStruct*) pvt;
59  my->hyst = my->cval;
60  my->last = epicsNAN;
61  return 0;
62 }
63 
64 static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl) {
65  myStruct *my = (myStruct*) pvt;
66  long status;
67  double val;
68  unsigned send = 1;
69 
70  /*
71  * Only scalar values supported - strings, arrays, and conversion errors
72  * are just passed on
73  */
74  if (pfl->type == dbfl_type_val) {
75  DBADDR localAddr = chan->addr; /* Structure copy */
76  localAddr.field_type = pfl->field_type;
77  localAddr.field_size = pfl->field_size;
78  localAddr.no_elements = pfl->no_elements;
79  localAddr.pfield = (char *) &pfl->u.v.field;
80  status = dbFastGetConvertRoutine[pfl->field_type][DBR_DOUBLE]
81  (localAddr.pfield, (void*) &val, &localAddr);
82  if (!status) {
83  send = 0;
84  recGblCheckDeadband(&my->last, val, my->hyst, &send, 1);
85  if (send && my->mode == 1) {
86  my->hyst = val * my->cval/100.;
87  }
88  }
89  }
90  if (!send) {
91  db_delete_field_log(pfl);
92  return NULL;
93  } else return pfl;
94 }
95 
96 static void channelRegisterPre(dbChannel *chan, void *pvt,
97  chPostEventFunc **cb_out, void **arg_out, db_field_log *probe)
98 {
99  *cb_out = filter;
100  *arg_out = pvt;
101 }
102 
103 static void channel_report(dbChannel *chan, void *pvt, int level, const unsigned short indent)
104 {
105  myStruct *my = (myStruct*) pvt;
106  printf("%*sDeadband (dbnd): mode=%s, delta=%g%s\n", indent, "",
107  chfPluginEnumString(modeEnum, my->mode, "n/a"), my->cval,
108  my->mode == 1 ? "%" : "");
109 }
110 
111 static chfPluginIf pif = {
112  allocPvt,
113  freePvt,
114 
115  NULL, /* parse_error, */
116  parse_ok,
117 
118  NULL, /* channel_open, */
119  channelRegisterPre,
120  NULL, /* channelRegisterPost, */
121  channel_report,
122  NULL /* channel_close */
123 };
124 
125 static void dbndShutdown(void* ignore)
126 {
127  if(myStructFreeList)
128  freeListCleanup(myStructFreeList);
129  myStructFreeList = NULL;
130 }
131 
132 static void dbndInitialize(void)
133 {
134  if (!myStructFreeList)
135  freeListInitPvt(&myStructFreeList, sizeof(myStruct), 64);
136 
137  chfPluginRegister("dbnd", &pif, opts);
138  epicsAtExit(dbndShutdown, NULL);
139 }
140 
141 epicsExportRegistrar(dbndInitialize);
LIBCOM_API void *epicsStdCall freeListCalloc(void *pvt)
Definition: freeListLib.c:60
Definition: arr.c:26
struct myStruct myStruct
pvd::Status status
double hyst
Definition: dbnd.c:28
double cval
Definition: dbnd.c:27
#define printf
Definition: epicsStdio.h:41
#define NULL
Definition: catime.c:38
LIBCOM_API void epicsStdCall freeListInitPvt(void **ppvt, int size, int nmalloc)
Definition: freeListLib.c:44
int mode
Definition: dbnd.c:26
LIBCOM_API void epicsStdCall freeListCleanup(void *pvt)
Definition: freeListLib.c:152
double last
Definition: dbnd.c:29
LIBCOM_API void epicsStdCall freeListFree(void *pvt, void *pmem)
Definition: freeListLib.c:131
#define DBR_DOUBLE
Definition: db_access.h:76
Extended replacement for the Posix exit and atexit routines.
float epicsNAN
Definition: epicsMath.cpp:35
#define epicsAtExit(F, A)
Convenience macro to register a function and context value to be run when the process exits...
Definition: epicsExit.h:70
epicsExportRegistrar(dbndInitialize)
Exporting IOC objects.