Commit 3e71ab1d authored by Claes Sjofors's avatar Claes Sjofors

Trend curves, user storage function added

parent a1a1d15d
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,7 @@
#include "rt_cvol.h" #include "rt_cvol.h"
#include "rt_cvolsm.h" #include "rt_cvolsm.h"
#include "rt_cvolcm.h" #include "rt_cvolcm.h"
#include "rt_cbuf.h"
#include "rt_pwr_msg.h" #include "rt_pwr_msg.h"
/* Declare routines used by main. */ /* Declare routines used by main. */
...@@ -100,8 +101,6 @@ static void volumesR (qcom_sGet*); ...@@ -100,8 +101,6 @@ static void volumesR (qcom_sGet*);
static void volumes7 (qcom_sGet*); static void volumes7 (qcom_sGet*);
static void serverConnect (qcom_sGet*); static void serverConnect (qcom_sGet*);
static void fileList (qcom_sGet*); static void fileList (qcom_sGet*);
static void getCircBuffer (qcom_sGet*);
static void updateCircBuffer(qcom_sGet*);
#if 0 #if 0
static void linkEvent (pwr_tUInt32, net_eEvent); static void linkEvent (pwr_tUInt32, net_eEvent);
static void sendIdAck (gdb_sNode*); static void sendIdAck (gdb_sNode*);
...@@ -186,9 +185,9 @@ static void (*fromApplication[net_eMsg_end])(qcom_sGet *) = { ...@@ -186,9 +185,9 @@ static void (*fromApplication[net_eMsg_end])(qcom_sGet *) = {
serverConnect, /* net_eMsg_serverConnect */ serverConnect, /* net_eMsg_serverConnect */
fileList, /* net_eMsg_fileList */ fileList, /* net_eMsg_fileList */
bugError, /* net_eMsg_fileListR, will never reach neth. */ bugError, /* net_eMsg_fileListR, will never reach neth. */
getCircBuffer, /* net_eMsg_getCircBuffer */ cbuf_GetCircBufferMsg, /* net_eMsg_getCircBuffer */
bugError, /* net_eMsg_getCircBufferR, will never reach neth. */ bugError, /* net_eMsg_getCircBufferR, will never reach neth. */
updateCircBuffer, /* net_eMsg_updateCircBuffer */ cbuf_UpdateCircBufferMsg, /* net_eMsg_updateCircBuffer */
bugError, /* net_eMsg_updateCircBufferR, will never reach neth. */ bugError, /* net_eMsg_updateCircBufferR, will never reach neth. */
bugError, /* net_eMsg_ */ bugError, /* net_eMsg_ */
volumes7 volumes7
...@@ -1567,149 +1566,3 @@ fileList ( ...@@ -1567,149 +1566,3 @@ fileList (
net_Reply(&sts, get, &put, 0); net_Reply(&sts, get, &put, 0);
} }
static void
getCircBuffer (
qcom_sGet *get
)
{
net_sGetCircBuffer *mp = get->data;
net_sGetCircBufferR *rmp;
gdb_sNode *np;
pwr_tStatus sts;
pwr_tUInt32 size;
qcom_sPut put;
gdh_sCircBuffInfo info;
gdb_ScopeLock {
np = hash_Search(&sts, gdbroot->nid_ht, &mp->hdr.nid);
} gdb_ScopeUnlock;
if (gdbroot->db->log.b.id) {
errh_Info("Sending 'getCircBuffer' to %s (%s)",
np->name, cdh_NodeIdToString(NULL, np->nid, 0, 0));
}
info.circ_aref = mp->circ_aref;
info.resolution = mp->resolution;
info.samples = mp->samples;
info.bufsize = mp->bufsize;
info.bufp = calloc( 1, info.bufsize);
sts = gdh_GetCircBuffInfo( &info, 1);
if ( EVEN(sts))
size = sizeof(*rmp);
else
size = sizeof(*rmp) + info.bufsize;
size = (size + 3) & ~3; /* Size up to nearest multiple of 4. */
rmp = net_Alloc(&sts, &put, size, net_eMsg_getCircBufferR);
if (rmp == NULL) {
errh_Error("Failed to allocate 'getCircBufferR' to %s (%s)",
np->name, cdh_NodeIdToString(NULL, np->nid, 0, 0));
return;
}
rmp->sts = sts;
if ( EVEN(sts)) {
rmp->sts = sts;
rmp->size = 0;
}
else {
rmp->sts = sts;
rmp->circ_aref = info.circ_aref;
rmp->size = info.size;
rmp->bufsize = info.bufsize;
rmp->first_idx = info.first_idx;
rmp->last_idx = info.last_idx;
rmp->offset = info.offset;
memcpy( rmp->buf, info.bufp, info.bufsize);
free( info.bufp);
}
net_Reply(&sts, get, &put, 0);
}
static void
updateCircBuffer (
qcom_sGet *get
)
{
net_sUpdateCircBuffer *mp = get->data;
net_sUpdateCircBufferR *rmp;
gdb_sNode *np;
pwr_tStatus sts;
pwr_tUInt32 size;
pwr_tUInt32 total_size;
qcom_sPut put;
gdh_sCircBuffInfo info[10];
int i, offs;
gdb_ScopeLock {
np = hash_Search(&sts, gdbroot->nid_ht, &mp->hdr.nid);
} gdb_ScopeUnlock;
if (gdbroot->db->log.b.id) {
errh_Info("Sending 'updateCircBuffer' to %s (%s)",
np->name, cdh_NodeIdToString(NULL, np->nid, 0, 0));
}
if ( mp->info_size >= 10) {
errh_Error("Parameter size error 'updateCircBufferR' to %s (%s)",
np->name, cdh_NodeIdToString(NULL, np->nid, 0, 0));
return;
}
for ( i = 0; i < mp->info_size; i++) {
info[i].circ_aref = mp->circ_aref[i];
info[i].resolution = mp->resolution[i];
info[i].samples = mp->samples[i];
info[i].last_idx = mp->last_idx[i];
info[i].offset = mp->offset[i];
info[i].bufsize = mp->bufsize[i];
info[i].bufp = calloc( 1, info[i].bufsize);
}
sts = gdh_UpdateCircBuffInfo( info, mp->info_size);
if ( EVEN(sts))
size = sizeof(*rmp);
else {
total_size = 0;
for ( i = 0; i < mp->info_size; i++)
total_size += info[i].bufsize;
size = sizeof(*rmp) + total_size;
}
size = (size + 3) & ~3; /* Size up to nearest multiple of 4. */
rmp = net_Alloc(&sts, &put, size, net_eMsg_updateCircBufferR);
if (rmp == NULL) {
errh_Error("Failed to allocate 'updateCircBufferR' to %s (%s)",
np->name, cdh_NodeIdToString(NULL, np->nid, 0, 0));
return;
}
rmp->sts = sts;
if ( EVEN(sts)) {
rmp->sts = sts;
rmp->bsize = 0;
}
else {
rmp->sts = sts;
rmp->info_size = mp->info_size;
rmp->bsize = total_size;
offs = 0;
for ( i = 0; i < mp->info_size; i++) {
rmp->circ_aref[i] = info[i].circ_aref;
rmp->size[i] = info[i].size;
rmp->bufsize[i] = info[i].bufsize;
rmp->first_idx[i] = info[i].first_idx;
rmp->last_idx[i] = info[i].last_idx;
rmp->offset[i] = info[i].offset;
memcpy( rmp->buf + offs, info[i].bufp, info[i].bufsize);
offs += info[i].bufsize;
free( info[i].bufp);
}
}
net_Reply(&sts, get, &put, 0);
}
This diff is collapsed.
/*
* Proview Open Source Process Control.
* Copyright (C) 2005-2012 SSAB EMEA AB.
*
* This file is part of Proview.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Proview. If not, see <http://www.gnu.org/licenses/>
*
* Linking Proview statically or dynamically with other modules is
* making a combined work based on Proview. Thus, the terms and
* conditions of the GNU General Public License cover the whole
* combination.
*
* In addition, as a special exception, the copyright holders of
* Proview give you permission to, from the build function in the
* Proview Configurator, combine Proview with modules generated by the
* Proview PLC Editor to a PLC program, regardless of the license
* terms of these modules. You may copy and distribute the resulting
* combined work under the terms of your choice, provided that every
* copy of the combined work is accompanied by a complete copy of
* the source code of Proview (the version used to produce the
* combined work), being distributed under the terms of the GNU
* General Public License plus this exception.
*/
#ifndef rt_cbuf_h
#define rt_cbuf_h
#if defined __cplusplus
extern "C" {
#endif
/**
* Circular buffer argument structure
*/
typedef struct {
pwr_sAttrRef circ_aref; /**< Attribute reference to circular buffer object */
unsigned int resolution; /**< Resolution of return data */
unsigned int samples; /**< number of data values */
void *bufp; /**< Data buffer that receives the requested information */
unsigned int bufsize; /**< The size in bytes of the data buffer */
unsigned int size; /**< Number of returned values */
unsigned int first_idx; /**< First index, this has to be saved to the next call */
unsigned int last_idx; /**< Last index, this has to be saved to the next call */
unsigned int offset; /**< Index offset to use in the next call */
} cbuf_sCircBuffInfo;
pwr_tStatus cbuf_GetCircBuffInfo( cbuf_sCircBuffInfo *info,
int infosize);
pwr_tStatus cbuf_UpdateCircBuffInfo( cbuf_sCircBuffInfo *info,
int infosize);
void cbuf_GetCircBufferMsg( qcom_sGet *get);
void cbuf_UpdateCircBufferMsg( qcom_sGet *get);
void cbuf_InitBuffer( void *o, pwr_tUInt32 size, pwr_tUInt32 element_size);
void cbuf_AddSample( void *o, void *value);
void cbuf_AddTimeSample( void *o, pwr_tTime *t);
#if defined __cplusplus
}
#endif
#endif
...@@ -72,7 +72,6 @@ ...@@ -72,7 +72,6 @@
#include "rt_subc.h" #include "rt_subc.h"
#include "rt_sanc.h" #include "rt_sanc.h"
#include "rt_dl.h" #include "rt_dl.h"
#include "pwr_baseclasses.h"
#if defined(OS_ELN) #if defined(OS_ELN)
/* For ELN and Lynx , the 'gdh_Lock' code also takes out a mutex lock /* For ELN and Lynx , the 'gdh_Lock' code also takes out a mutex lock
...@@ -5050,377 +5049,3 @@ pwr_tStatus gdh_GetNextSubClass( pwr_tCid cid, pwr_tCid psubcid, pwr_tCid *subci ...@@ -5050,377 +5049,3 @@ pwr_tStatus gdh_GetNextSubClass( pwr_tCid cid, pwr_tCid psubcid, pwr_tCid *subci
return GDH__NOSUCHCLASS; return GDH__NOSUCHCLASS;
} }
pwr_tStatus
gdh_GetCircBuffInfo (
gdh_sCircBuffInfo *info,
int infosize
)
{
pwr_tStatus sts = GDH__SUCCESS;
mvol_sAttribute attribute;
mvol_sAttribute *ap;
pwr_sClass_CircBuffHeader *hp;
char *datap;
int split = 0;
int start_idx;
int first_index, last_index;
int samples;
int j;
memset(&attribute, 0, sizeof(attribute));
gdh_Lock;
for ( j = 0; j < infosize; j++) {
while ( 1) {
ap = vol_ArefToAttribute(&sts, &attribute, &info[j].circ_aref, gdb_mLo_global, vol_mTrans_all);
if (ap == NULL || ap->op == NULL) break;
if ( ap->op->l.flags.b.isCached) {
net_sGetCircBuffer *mp;
qcom_sPut put;
gdb_sVolume *vp;
qcom_sQid tgt;
qcom_sGet get;
net_sGetCircBufferR *rsp;
gdb_sNode *np;
vp = pool_Address(NULL, gdbroot->pool, ap->op->l.vr);
if (vp == NULL) {
sts = GDH__NOSUCHOBJ;
break;
}
mp = net_Alloc(&sts, &put, sizeof(*mp), net_eMsg_getCircBuffer);
if (mp == NULL) break;
mp->circ_aref = info->circ_aref;
mp->resolution = info->resolution;
mp->samples = info->samples;
mp->bufsize = info->bufsize;
np = hash_Search(&sts, gdbroot->nid_ht, &vp->g.nid);
if (np == NULL) break;
tgt = np->handler;
gdb_Unlock;
rsp = net_Request(&sts, &tgt, &put, &get, net_eMsg_getCircBufferR, 0, 0);
gdb_Lock;
if (EVEN(sts))
break;
if (EVEN(rsp->sts)) {
sts = rsp->sts;
net_Free(NULL, rsp);
break;
}
if ( cdh_ObjidIsNotEqual(rsp->circ_aref.Objid, info->circ_aref.Objid)) {
sts = 0;
break;
}
info->size = rsp->size;
info->bufsize = rsp->bufsize;
info->first_idx = rsp->first_idx;
info->last_idx = rsp->last_idx;
info->offset = rsp->offset;
info->bufp = calloc( 1, info->bufsize);
memcpy( info->bufp, rsp->buf, info->bufsize);
net_Free(NULL, rsp);
break;
}
touchObject(ap->op);
samples = info[j].samples;
hp = vol_AttributeToAddress(&sts, ap);
if (hp != NULL) {
if ( hp->FirstIndex == hp->LastIndex)
return 0;
if ( info[j].resolution <= 1) {
if ( samples > hp->Size)
samples = hp->Size;
datap = (char *)hp + pwr_AlignLW(sizeof(pwr_sClass_CircBuffHeader));
first_index = hp->FirstIndex;
last_index = hp->LastIndex;
start_idx = last_index - samples;
if ( first_index < last_index) {
if ( first_index > start_idx)
start_idx = first_index;
}
else {
if ( start_idx < 0) {
split = 1;
start_idx = hp->Size + start_idx;
if ( start_idx < first_index)
start_idx = first_index;
}
}
if ( split) {
memcpy( info[j].bufp, datap + start_idx * hp->ElementSize, (hp->Size - start_idx) * hp->ElementSize);
memcpy( info[j].bufp + (hp->Size - start_idx) * hp->ElementSize, datap, last_index * hp->ElementSize);
info[j].size = hp->Size - start_idx + last_index;
}
else {
memcpy( info[j].bufp, datap + start_idx * hp->ElementSize, (last_index - start_idx) * hp->ElementSize);
info[j].size = last_index - start_idx;
}
info[j].last_idx = last_index;
info[j].first_idx = first_index;
info[j].offset = 0;
}
else {
/* Resolution > 0 */
int elements;
char *dp, *bp;
int i;
int idx, tst_first_idx;
if ( samples > hp->Size / info[j].resolution)
samples = hp->Size / info[j].resolution;
datap = (char *)hp + pwr_AlignLW(sizeof(pwr_sClass_CircBuffHeader));
first_index = hp->FirstIndex;
last_index = hp->LastIndex;
start_idx = last_index - (samples - 1)* info[j].resolution;
tst_first_idx = first_index;
if ( first_index > last_index)
tst_first_idx -= hp->Size;
if ( start_idx < tst_first_idx)
start_idx += (tst_first_idx - start_idx)/ info[j].resolution * info[j].resolution;
elements = (last_index - start_idx) / info[j].resolution + 1;
info[j].size = elements;
info[j].offset = info[j].resolution;
if ( start_idx < 0)
start_idx += hp->Size;
bp = info[j].bufp;
idx = start_idx;
for ( i = 0; i < elements; i++) {
dp = datap + idx * hp->ElementSize;
memcpy( bp, dp, hp->ElementSize);
// printf( "sp1: %d\n", idx);
bp += hp->ElementSize;
idx += info[j].resolution;
if ( idx >= hp->Size)
idx -= hp->Size;
}
info[j].last_idx = last_index;
info[j].first_idx = first_index;
}
sts = GDH__SUCCESS;
}
else
sts = 0;
break;
}
gdh_Unlock;
}
return sts;
}
pwr_tStatus
gdh_UpdateCircBuffInfo (
gdh_sCircBuffInfo *info,
int infosize
)
{
pwr_tStatus sts = GDH__SUCCESS;
mvol_sAttribute attribute;
mvol_sAttribute *ap;
pwr_sClass_CircBuffHeader *hp;
char *datap;
int split = 0;
int start_idx;
int first_index, last_index;
int finish = 0;
int j;
memset(&attribute, 0, sizeof(attribute));
for ( j = 0; j < infosize; j++) {
gdh_Lock;
while ( 1) {
ap = vol_ArefToAttribute(&sts, &attribute, &info[j].circ_aref, gdb_mLo_global, vol_mTrans_all);
if (ap == NULL || ap->op == NULL) break;
if ( ap->op->l.flags.b.isCached) {
net_sUpdateCircBuffer *mp;
qcom_sPut put;
gdb_sVolume *vp;
qcom_sQid tgt;
qcom_sGet get;
net_sUpdateCircBufferR *rsp;
gdb_sNode *np;
int i;
int offs;
vp = pool_Address(NULL, gdbroot->pool, ap->op->l.vr);
if (vp == NULL) {
sts = GDH__NOSUCHOBJ;
break;
}
mp = net_Alloc(&sts, &put, sizeof(*mp), net_eMsg_updateCircBuffer);
if (mp == NULL) break;
mp->info_size = infosize;
if ( mp->info_size > 10)
mp->info_size = 10;
for ( i = 0; i < infosize; i++) {
mp->circ_aref[i] = info[i].circ_aref;
mp->resolution[i] = info[i].resolution;
mp->samples[i] = info[i].samples;
mp->bufsize[i] = info[i].bufsize;
mp->last_idx[i] = info[i].last_idx;
mp->offset[i] = info[i].offset;
}
np = hash_Search(&sts, gdbroot->nid_ht, &vp->g.nid);
if (np == NULL) break;
tgt = np->handler;
gdb_Unlock;
rsp = net_Request(&sts, &tgt, &put, &get, net_eMsg_updateCircBufferR, 0, 0);
gdb_Lock;
if (EVEN(sts))
break;
if (EVEN(rsp->sts)) {
sts = rsp->sts;
net_Free(NULL, rsp);
break;
}
offs = 0;
for ( i = 0; i < rsp->info_size; i++) {
if ( cdh_ObjidIsNotEqual(rsp->circ_aref[i].Objid, info[i].circ_aref.Objid)) {
sts = 0;
break;
}
info[i].size = rsp->size[i];
info[i].bufsize = rsp->bufsize[i];
info[i].first_idx = rsp->first_idx[i];
info[i].last_idx = rsp->last_idx[i];
info[i].offset = rsp->offset[i];
info[i].bufp = calloc( 1, info[i].bufsize);
memcpy( info[i].bufp, rsp->buf + offs, info[i].bufsize);
offs += info[i].bufsize;
}
net_Free(NULL, rsp);
finish = 1;
break;
}
touchObject(ap->op);
hp = vol_AttributeToAddress(&sts, ap);
if (hp != NULL) {
if ( hp->FirstIndex == hp->LastIndex) {
info[j].size = 0;
break;
}
if ( info[j].resolution <= 1) {
datap = (char *)hp + pwr_AlignLW(sizeof(pwr_sClass_CircBuffHeader));
first_index = info[j].last_idx;
last_index = hp->LastIndex;
start_idx = last_index - info[j].samples;
if ( first_index < last_index) {
if ( first_index > start_idx)
start_idx = first_index;
}
else {
if ( start_idx < 0) {
split = 1;
start_idx = hp->Size + start_idx;
if ( start_idx < first_index)
start_idx = first_index;
}
}
if ( split) {
memcpy( info[j].bufp, datap + start_idx * hp->ElementSize, (hp->Size - start_idx) * hp->ElementSize);
memcpy( info[j].bufp + (hp->Size - start_idx) * hp->ElementSize, datap, last_index * hp->ElementSize);
info[j].size = hp->Size - start_idx + last_index;
}
else {
memcpy( info[j].bufp, datap + start_idx * hp->ElementSize, (last_index - start_idx) * hp->ElementSize);
info[j].size = last_index - start_idx;
}
info[j].last_idx = last_index;
info[j].first_idx = first_index;
info[j].offset = 0;
}
else {
/* Resolution > 1 */
int elements;
char *dp;
int i;
int tst_idx;
datap = (char *)hp + pwr_AlignLW(sizeof(pwr_sClass_CircBuffHeader));
first_index = hp->FirstIndex;
last_index = hp->LastIndex;
tst_idx = last_index;
if ( tst_idx < info[j].last_idx)
tst_idx += hp->Size;
start_idx = info[j].last_idx + info[j].offset;
if ( start_idx > tst_idx) {
info[j].size = 0;
break;
}
elements = (tst_idx - start_idx) / info[j].resolution + 1;
info[j].offset = info[j].resolution - (tst_idx - start_idx - (elements - 1) * info[j].resolution);
if ( start_idx >= hp->Size)
start_idx -= hp->Size;
if ( elements > info[j].samples)
elements = info[j].samples;
info[j].size = elements;
for ( i = 0; i < elements; i++) {
dp = datap + start_idx * hp->ElementSize;
memcpy( info[j].bufp + i * hp->ElementSize, dp, hp->ElementSize);
// printf( "%d idx: %d %5.2f el:%d off:%d lidx: prev %d curr %d\n", i, start_idx, *(float *)dp, elements, info[j].offset, info[j].last_idx, last_index);
start_idx += info[j].resolution;
if ( start_idx >= hp->Size)
start_idx -= hp->Size;
}
info[j].last_idx = last_index;
info[j].first_idx = first_index;
}
sts = GDH__SUCCESS;
}
else
sts = 0;
break;
}
gdh_Unlock;
if ( finish)
break;
}
return sts;
}
...@@ -170,21 +170,6 @@ typedef struct { ...@@ -170,21 +170,6 @@ typedef struct {
} gdh_sBitDef; } gdh_sBitDef;
/**
* Circular buffer argument structure
*/
typedef struct {
pwr_sAttrRef circ_aref; /**< Attribute reference to circular buffer object */
unsigned int resolution; /**< Resolution of return data */
unsigned int samples; /**< number of data values */
void *bufp; /**< Data buffer that receives the requested information */
unsigned int bufsize; /**< The size in bytes of the data buffer */
unsigned int size; /**< Number of returned values */
unsigned int first_idx; /**< First index, this has to be saved to the next call */
unsigned int last_idx; /**< Last index, this has to be saved to the next call */
unsigned int offset; /**< Index offset to use in the next call */
} gdh_sCircBuffInfo;
/* GDH entrypoints (as function prototypes). */ /* GDH entrypoints (as function prototypes). */
/** @} */ /** @} */
...@@ -815,18 +800,6 @@ gdh_SetObjectReadOnly( ...@@ -815,18 +800,6 @@ gdh_SetObjectReadOnly(
pwr_tOid oid pwr_tOid oid
); );
pwr_tStatus
gdh_GetCircBuffInfo (
gdh_sCircBuffInfo *info,
int infosize
);
pwr_tStatus
gdh_UpdateCircBuffInfo (
gdh_sCircBuffInfo *info,
int infosize
);
/* Undocumented functions. For internal use only. */ /* Undocumented functions. For internal use only. */
pwr_tStatus pwr_tStatus
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
! combined work), being distributed under the terms of the GNU ! combined work), being distributed under the terms of the GNU
! General Public License plus this exception. ! General Public License plus this exception.
! !
! pwrb_c_circbuff1000.wb_load -- Defines the class CircBuff1000. ! pwrb_c_circbuff1k.wb_load -- Defines the class CircBuff1k.
! !
SObject pwrb:Class SObject pwrb:Class
!/** !/**
...@@ -41,7 +41,7 @@ SObject pwrb:Class ...@@ -41,7 +41,7 @@ SObject pwrb:Class
! @Summary Circular buffer with buffer size 1000 byte ! @Summary Circular buffer with buffer size 1000 byte
! Circular buffer with buffer size 1000 byte. ! Circular buffer with buffer size 1000 byte.
!*/ !*/
Object CircBuff1000 $ClassDef 595 Object CircBuff1k $ClassDef 595
Body SysBody Body SysBody
Attr Editor = pwr_eEditor_AttrEd Attr Editor = pwr_eEditor_AttrEd
Attr Method = pwr_eMethod_Standard Attr Method = pwr_eMethod_Standard
...@@ -49,7 +49,7 @@ SObject pwrb:Class ...@@ -49,7 +49,7 @@ SObject pwrb:Class
EndBody EndBody
Object RtBody $ObjBodyDef 1 Object RtBody $ObjBodyDef 1
Body SysBody Body SysBody
Attr StructName = "CircBuff1000" Attr StructName = "CircBuff1k"
EndBody EndBody
!/** !/**
! Buffer header. ! Buffer header.
...@@ -73,7 +73,7 @@ SObject pwrb:Class ...@@ -73,7 +73,7 @@ SObject pwrb:Class
EndBody EndBody
EndObject EndObject
EndObject EndObject
Object Template CircBuff1000 Object Template CircBuff1k
Body RtBody Body RtBody
Attr Head.Size = 250 Attr Head.Size = 250
Attr Head.ElementSize = 4 Attr Head.ElementSize = 4
......
!
! Proview Open Source Process Control.
! Copyright (C) 2005-2012 SSAB EMEA AB.
!
! This file is part of Proview.
!
! This program is free software; you can redistribute it and/or
! modify it under the terms of the GNU General Public License as
! published by the Free Software Foundation, either version 2 of
! the License, or (at your option) any later version.
!
! This program is distributed in the hope that it will be useful
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with Proview. If not, see <http://www.gnu.org/licenses/>
!
! Linking Proview statically or dynamically with other modules is
! making a combined work based on Proview. Thus, the terms and
! conditions of the GNU General Public License cover the whole
! combination.
!
! In addition, as a special exception, the copyright holders of
! Proview give you permission to, from the build function in the
! Proview Configurator, combine Proview with modules generated by the
! Proview PLC Editor to a PLC program, regardless of the license
! terms of these modules. You may copy and distribute the resulting
! combined work under the terms of your choice, provided that every
! copy of the combined work is accompanied by a complete copy of
! the source code of Proview (the version used to produce the
! combined work), being distributed under the terms of the GNU
! General Public License plus this exception.
!
! pwrb_c_circbuff2k.wb_load -- Defines the class CircBuff2k.
!
SObject pwrb:Class
!/**
! @Version 1.0
! @Summary Circular buffer with buffer size 2000 byte
! Circular buffer with buffer size 2000 byte.
!*/
Object CircBuff2k $ClassDef 600
Body SysBody
Attr Editor = pwr_eEditor_AttrEd
Attr Method = pwr_eMethod_Standard
Attr PopEditor = 1
EndBody
Object RtBody $ObjBodyDef 1
Body SysBody
Attr StructName = "CircBuff2k"
EndBody
!/**
! Buffer header.
!*/
Object Head $Attribute 1
Body SysBody
Attr TypeRef = "pwrb:Class-CircBuffHeader"
Attr Flags |= PWR_MASK_CLASS
EndBody
EndObject
!/**
! Data buffer.
!*/
Object Data $Attribute 2
Body SysBody
Attr TypeRef = "pwrs:Type-$UInt32"
Attr Flags |= PWR_MASK_ARRAY
Attr Flags |= PWR_MASK_STATE
Attr Flags |= PWR_MASK_INVISIBLE
Attr Elements = 500
EndBody
EndObject
EndObject
Object Template CircBuff2k
Body RtBody
Attr Head.Size = 500
Attr Head.ElementSize = 4
EndBody
EndObject
EndObject
EndSObject
...@@ -38,12 +38,11 @@ ...@@ -38,12 +38,11 @@
SObject pwrb:Class SObject pwrb:Class
!/** !/**
! @Version 1.0 ! @Version 1.0
! Stores data for a fast graph à la storage oscilloscope. ! Stores data for a trend graph.
! !
! In one DsFastCurve object, up to 10 attributes can be specified. ! In one DsTrendCurve object, up to 10 attributes can be specified.
! The storage of the attributes will be trigger by the same event, ! The attribute values will be stored with the same frequency, and the
! stored with the same frequency, and the curves will be plotted ! curves will be plotted in the same trend window.
! in the same fastcurve window.
! !
! The names of the attributes is specified the the Attribute array. ! The names of the attributes is specified the the Attribute array.
! For every attribute, a storage area object also has to be specified. ! For every attribute, a storage area object also has to be specified.
...@@ -51,33 +50,57 @@ SObject pwrb:Class ...@@ -51,33 +50,57 @@ SObject pwrb:Class
! objects, for example to store at different frequencies. ! objects, for example to store at different frequencies.
! !
! The sampling rate is specified the the ScanTime attribute. ! The sampling rate is specified the the ScanTime attribute.
! The sampling will start when a trigger event is detected. In some
! cases, when data before the trigger event is valid, the sampling will
! go on even before the trigger event.
! !
! @b Storage arrays ! @b Storage buffers
! Storage arrays has to be supplied by the user, one array for the time axis data, and ! Storage buffers has to be supplied by the user, one buffer for the time axis data, and
! one for each configured attribute. For example, Buff1440, Buff4096 or Buff32k objects ! one for each configured attribute. Object of type CircBuffer has to be used, eg
! can be used for the data storage. These will store up to 360, 1024 resp. 8192 points of ! CircBuff1k, CircBuff2k, CircBuff10k, CircBuff20k, CircBuf100k and CircBuff200k.
! pwr_tFloat32 attributes. ! A CircBuff1k object will for example store 250 samples of size 4 bytes and a
! CircBuff200k 50000.
! !
! @b Data types ! @b Data types
! The datatypes that can be stored is ! The datatypes that can be stored is
! - pwr_tFloat32, pwr_tFloat64 ! - pwr_tFloat32, pwr_tFloat64
! - pwr_tInt32, pwr_tUInt32, pwr_tInt16, pwr_tUInt16, pwr_tInt8, pwr_tUInt8 ! - pwr_tInt32, pwr_tUInt32, pwr_tInt16, pwr_tUInt16, pwr_tInt8, pwr_tUInt8
! !
! The time is stored as pwr_tFloat32. ! The time is stored as one or two UInt32, dependent on the selected TimeResolution.
! The default time is of size 4 bytes where the seconds from epoch is stored. With time
! resolution nanoseconds the size is 8 bytes, and one word with the nanoseconds are added
! for each sample.
! !
! @b Server ! @b Server
! DsTrendCurve objects is handled by the fast server rt_trend. ! DsTrendCurve objects is handled by the fast server rt_trend.
! The base frequency for the fast server process is configured in ! The base frequency for the fast server process is configured in
! the DsTrendConf object. ! the DsTrendConf object.
! !
! @b User storage
! Trend data can be stored by a user defined server, for example by the plc program.
! In this case a number of setting has to be done:
! - Function is set to 1.
! - AttributeType should be set, eg pwrs:Type-$Float32.
! - Attribute should be set to an arbitrary attribute. The only function for the attribute
! is the curve name.
! - ScanTime should be set to the time difference between two samples.
! In the Buffer object, the Size (max number of samples) and ElementSize in bytes should be set.
! To fill in the samples the functions cbuf_AddSample() and cbuf_AddTimeSample() can be used.
! In this example the trend is filled in from a DataArithm where the data buffer is connected
! to Da1 and the time buffer to Da2.
!
! classdef Da1 CircBuff10k;
! classdef Da2 CircBuff20k;
! pwr_tTime time;
!
! time_GetTime(&time);
! cbuf_AddSample(Da1, &A1);
! cbuf_AddTimeSample(Da2, &time);
!
! @b Se also ! @b Se also
! @classlink Buff1440 ssab_buff1440.html ! @classlink CircBuff10k pwrb_circbuff1k.html
! @classlink Buff4096 ssab_buff4096.html ! @classlink CircBuff10k pwrb_circbuff2k.html
! @classlink Buff32k ssab_buff32k.html ! @classlink CircBuff10k pwrb_circbuff10k.html
! @classlink DsFastConf pwrb_dsfastconf.html ! @classlink CircBuff10k pwrb_circbuff20k.html
! @classlink CircBuff10k pwrb_circbuff10k.html
! @classlink DsTrendConf pwrb_dstrendconf.html
!*/ !*/
Object DsTrendCurve $ClassDef 593 Object DsTrendCurve $ClassDef 593
Body SysBody Body SysBody
...@@ -125,6 +148,9 @@ SObject pwrb:Class ...@@ -125,6 +148,9 @@ SObject pwrb:Class
EndBody EndBody
EndObject EndObject
!/** !/**
! The attribute type only has to be set if UserStorage
! is used, where the type is set in the form pwrs:Type-$Float32.
!
! Stores measurants data types. It has to be of any of ! Stores measurants data types. It has to be of any of
! the types pwr_tBoolean, pwr_tFloat32, pwr_tFloat64, ! the types pwr_tBoolean, pwr_tFloat32, pwr_tFloat64,
! pwr_tInt8, pwr_tInt16, pwr_tInt32, pwr_tUInt8, ! pwr_tInt8, pwr_tInt16, pwr_tInt32, pwr_tUInt8,
...@@ -133,8 +159,6 @@ SObject pwrb:Class ...@@ -133,8 +159,6 @@ SObject pwrb:Class
Object AttributeType $Attribute 5 Object AttributeType $Attribute 5
Body SysBody Body SysBody
Attr TypeRef = "pwrs:Type-$TypeId" Attr TypeRef = "pwrs:Type-$TypeId"
Attr Flags |= PWR_MASK_STATE
Attr Flags |= PWR_MASK_INVISIBLE
Attr Flags |= PWR_MASK_ARRAY Attr Flags |= PWR_MASK_ARRAY
Attr Elements = 10 Attr Elements = 10
EndBody EndBody
...@@ -152,11 +176,11 @@ SObject pwrb:Class ...@@ -152,11 +176,11 @@ SObject pwrb:Class
EndBody EndBody
EndObject EndObject
!/** !/**
! @Summary Data buffers. Array attributes that contains the data of the curves. ! @Summary Data buffers. Circular buffer objects that contains the data of the curves.
! Data buffers. Array attributes that contains the data of the curves. ! Circular buffer objects that contains the data of the curves.
! Objects for the databuffers has to be configured by the user. The extent of the ! Objects for the databuffers has to be configured by the user. The extent of the
! buffer attributes should equal or exceed the storeage size, i.e. the size of the ! buffer attributes should equal or exceed the storeage size, i.e. the size of the
! sampled attribute's type multiplied by NoOfPoints. ! sampled attribute's type multiplied by NoOfSample.
!*/ !*/
Object Buffers $Attribute 7 Object Buffers $Attribute 7
Body SysBody Body SysBody
...@@ -166,8 +190,8 @@ SObject pwrb:Class ...@@ -166,8 +190,8 @@ SObject pwrb:Class
EndBody EndBody
EndObject EndObject
!/** !/**
! @Summary Time buffer. An array attribute that contain the time axis data for the curves. ! @Summary Time buffer. A circular buffer object that contain the time axis data for the curves.
! Time buffer. An array attribute that contain the time axis data for the curves. ! Time buffer. A circular buffer object that contain the time axis data for the curves.
! The object for the time buffer has to be configured by the user. The extent of the ! The object for the time buffer has to be configured by the user. The extent of the
! buffer attributes should equal or exceed the storeage size for the time data. ! buffer attributes should equal or exceed the storeage size for the time data.
!*/ !*/
...@@ -178,7 +202,7 @@ SObject pwrb:Class ...@@ -178,7 +202,7 @@ SObject pwrb:Class
EndObject EndObject
!/** !/**
! Resolution of time scale, seconds or nanoseconds. ! Resolution of time scale, seconds or nanoseconds.
! Seconds will require 4 bytes per point, and nanoseconds 8 bytes per point. ! Seconds will require 4 bytes per sample, and nanoseconds 8 bytes per sample.
!*/ !*/
Object TimeResolution $Attribute 16 Object TimeResolution $Attribute 16
Body SysBody Body SysBody
......
...@@ -68,8 +68,18 @@ palette NavigatorPalette ...@@ -68,8 +68,18 @@ palette NavigatorPalette
{ {
class DsFastCurve class DsFastCurve
class DsTrend class DsTrend
class DsTrendCurve
class SevHist class SevHist
class SevHistObject class SevHistObject
menu CircularBuffer
{
class CircBuff1k
class CircBuff2k
class CircBuff10k
class CircBuff20k
class CircBuff100k
class CircBuff200k
}
} }
menu Supervision menu Supervision
{ {
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "pwr.h" #include "pwr.h"
#include "pwr_baseclasses.h" #include "pwr_baseclasses.h"
#include "rt_gdh.h" #include "rt_gdh.h"
#include "rt_cbuf.h"
#include "rt_gdh_msg.h" #include "rt_gdh_msg.h"
#include "co_cdh.h" #include "co_cdh.h"
#include "co_time.h" #include "co_time.h"
...@@ -314,7 +315,7 @@ XttTrend::XttTrend( void *parent_ctx, ...@@ -314,7 +315,7 @@ XttTrend::XttTrend( void *parent_ctx,
cb_info[i].bufsize = cb_info[i].samples * element_size[i]; cb_info[i].bufsize = cb_info[i].samples * element_size[i];
cb_info[i].bufp = (char *) calloc( 1, cb_info[i].bufsize); cb_info[i].bufp = (char *) calloc( 1, cb_info[i].bufsize);
cb_info[i].circ_aref = tcp[tcp_i].Buffers[j]; cb_info[i].circ_aref = tcp[tcp_i].Buffers[j];
*sts = gdh_GetCircBuffInfo( &cb_info[i], 1); *sts = cbuf_GetCircBuffInfo( &cb_info[i], 1);
if ( EVEN(*sts)) if ( EVEN(*sts))
continue; continue;
...@@ -521,7 +522,7 @@ void XttTrend::trend_scan( void *data) ...@@ -521,7 +522,7 @@ void XttTrend::trend_scan( void *data)
pwr_tStatus sts; pwr_tStatus sts;
unsigned int size; unsigned int size;
sts = gdh_UpdateCircBuffInfo( trend->cb_info, trend->trend_cnt); sts = cbuf_UpdateCircBuffInfo( trend->cb_info, trend->trend_cnt);
if ( EVEN(sts)) return; if ( EVEN(sts)) return;
for ( i = 0; i < trend->trend_cnt; i++) { for ( i = 0; i < trend->trend_cnt; i++) {
......
...@@ -47,6 +47,10 @@ ...@@ -47,6 +47,10 @@
# include "ge_curve.h" # include "ge_curve.h"
#endif #endif
#ifndef rt_cbuf_h
# include "rt_cbuf.h"
#endif
#define XTT_TREND_MAX 20 #define XTT_TREND_MAX 20
class CoWow; class CoWow;
...@@ -70,7 +74,7 @@ class XttTrend { ...@@ -70,7 +74,7 @@ class XttTrend {
int max_points; int max_points;
pwr_tTid trend_tid; pwr_tTid trend_tid;
int update_time; int update_time;
gdh_sCircBuffInfo cb_info[XTT_TREND_MAX]; cbuf_sCircBuffInfo cb_info[XTT_TREND_MAX];
CoWowTimer *timerid; CoWowTimer *timerid;
int last_buffer[XTT_TREND_MAX]; int last_buffer[XTT_TREND_MAX];
int last_next_index[XTT_TREND_MAX]; int last_next_index[XTT_TREND_MAX];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment