ID |
Date |
Author |
Topic |
Subject |
2343
|
14 Feb 2022 |
jago aartsen | Bug Fix | ODBINC/Sequencer Issue | > > I noticed that "Jacob Thorne" in the forum had the same issue as us in Novemeber last
> > year. Indeed we have not installed any later versions of MIDAS since then so we will
> > double check we have the latest version.
>
> As you see from my reply to Jacob, the bug has been fixed in midas since then, so just
> update.
>
> Stefan
We have tried updating using both:
git submodule update --init --recursive
and:
git pull --recurse-submodules
But the error still persists. Is there another way to update which we are missing?
Cheers
Jago |
2342
|
14 Feb 2022 |
Stefan Ritt | Bug Fix | ODBINC/Sequencer Issue | > I noticed that "Jacob Thorne" in the forum had the same issue as us in Novemeber last
> year. Indeed we have not installed any later versions of MIDAS since then so we will
> double check we have the latest version.
As you see from my reply to Jacob, the bug has been fixed in midas since then, so just
update.
Stefan |
2341
|
14 Feb 2022 |
jago aartsen | Bug Fix | ODBINC/Sequencer Issue | > Just post here a minimal script which produces the error, so that I can try myself.
>
> ... and make sure that you have the latest develop version of midas.
>
> Stefan
Here is the simplest script which produces the error:
WAIT seconds, 3
ODBINC /Equipment/ArduinoTestStation/Variables/_S_
I noticed that "Jacob Thorne" in the forum had the same issue as us in Novemeber last
year. Indeed we have not installed any later versions of MIDAS since then so we will
double check we have the latest version.
Jago |
2340
|
14 Feb 2022 |
Stefan Ritt | Bug Fix | ODBINC/Sequencer Issue | Just post here a minimal script which produces the error, so that I can try myself.
... and make sure that you have the latest develop version of midas.
Stefan |
2339
|
14 Feb 2022 |
jago aartsen | Bug Fix | ODBINC/Sequencer Issue | > >
> > [local:mu3eMSci:S]/>cd Equipment/ArduinoTestStation/Variables
> > [local:mu3eMSci:S]Variables>ls -l
> > Key name Type #Val Size Last Opn Mode Value
> > ---------------------------------------------------------------------------
> > _T_ FLOAT 1 4 1h 0 RWD 20.93
> > _F_ FLOAT 1 4 1h 0 RWD 12.8
> > _P_ FLOAT 1 4 1h 0 RWD 56
> > _S_ FLOAT 1 4 1h 0 RWD 5
> > _H_ FLOAT 1 4 60h 0 RWD 44.74
> > _B_ FLOAT 1 4 60h 0 RWD 18.54
> > _A_ FLOAT 1 4 1h 0 RWD 14.41
> > _RH_ FLOAT 1 4 1h 0 RWD 41.81
> > _AT_ FLOAT 1 4 1h 0 RWD 20.46
> > SP INT16 1 2 1h 0 RWD 10
> >
>
> This looks okey, so we still have no explanation for your error. Please post your sequencer
> script?
>
> K.O.
Hey, thanks for getting back to me
We are fairly confident the syntax is correct. Having tried the test script posted by Stefan:
> ODBSET /Equipment/ArduinoTestStation/Variables/_S_, 10
>
> LOOP 10
> WAIT seconds, 3
> ODBINC
The same error is returned:/
We will take another look today.
Jago |
2338
|
14 Feb 2022 |
jago aartsen | Bug Fix | ODBINC/Sequencer Issue | > I tried following script:
>
> ODBSET /Equipment/ArduinoTestStation/Variables/_S_, 10
>
> LOOP 10
> WAIT seconds, 3
> ODBINC /Equipment/ArduinoTestStation/Variables/_S_
> ENDLOOP
>
> and it worked as expected. So I conclude the problem must be in your script. Probably a typo in
> the ODB path pointing to a 32-byte string instead to a 4-byte float.
>
> Stefan
Hi Stefan,
Cheers for the reply. I believe the syntax we are using is correct. I have tried copying the script
you used above and it results in the same error as before. Perhaps something is going wrong
elsewhere - I will take another look today.
Jago |
2337
|
11 Feb 2022 |
Alexey Kalinin | Bug Report | some frontend kicked by cm_periodic_tasks | Thanks for the answer.
As soon as I can(possible in a month) I'll try suggestion below:
> One thing to try is set the write cache size to zero and see if your crash goes away. I see
> some indication of something rotten in the event buffer code if write cache is enabled. This
> is set in ODB "/Eq/XXX/Common/Write Cache Size", set it to zero. (beware recent confusion
> where odb settings have no effect depending on value of "equipment_common_overwrite").
I tried to change this ODB for one of the frontend via mhttpd/browser, and eventually it goes back
to default value (1000 as I remember). but this frontend has the minimum rate 50DWORD/~10sec. and
depending on cashe size it appears in mdump once per 31 events but all aff them . SO its different
story, but m.b. it has the same solution to play with Write Cashe Size.
double free message goes from mserver terminal.
all of the frontends are remote.
I can't exclude crashes of frontend , but when I run ./frontend -i 1(2,3 etc) thet means that I run
one code for all, and only several causes crash.also I found that crash in frontend happened while
it do nothing with collected data (last event reached and new data is not ready), but it tries to
watch for the ODB changes.I mean it crashes iside (while {odb_changes(value in watchdog)}),and I don't
know what else happenned meanwhile with cahed buffer.
Future plans is to use event buider for frontends when data/signals will be perfectly reasonable
i/e/ without broken events. for now i kinda worry about if one of frontends will skip one of the
event inside its buffer.
Thanks for the way to dig into.
A.
> > The problem is that eventually some of frontend closed with message
> > :19:22:31.834 2021/12/02 [rootana,INFO] Client 'Sample Frontend38' on buffer
> > 'SYSMSG' removed by cm_periodic_tasks because process pid 9789 does not exist
>
> This messages means what it says. A client was registered with the SYSMSG buffer and this
> client had pid 9789. At some point some other client (rootana, in this case) checked it and
> process pid 9789 was no longer running. (it then proceeded to remove the registration).
>
> There is 2 possibilities:
> - simplest: your frontend has crashed. best to debug this by running it inside gdb, wait for
> the crash.
> - unlikely: reported pid is bogus, real pid of your frontend is different, the client
> registration in SYSMSG is corrupted. this would indicate massive corruption of midas shared
> memory buffers, not impossible if your frontend misbehaves and writes to random memory
> addresses. ODB has protection against this (normally turned off, easy to enable, set ODB
> "/experiment/protect odb" to yes), shared memory buffers do not have protection against this
> (should be added?).
>
> Do this. When you start your frontend, write down it's pid, when you see the crash message,
> confirm pid number printed is the same. As additional test, run your frontend inside gdb,
> after it crashes, you can print the stack trace, etc.
>
> >
> > in the meantime mserver loggging :
> > mserver started interactively
> > mserver will listen on TCP port 1175
> > double free or corruption (!prev)
> > double free or corruption (!prev)
> > free(): invalid next size (normal)
> > double free or corruption (!prev)
> >
>
> Are these "double free" messages coming from the mserver or from your frontend? (i.e. you run
> them in different terminals, not all in the same terminal?).
>
> If messages are coming from the mserver, this confirms possibility (1),
> except that for frontends connected remotely, the pid is the pid of the mserver,
> and what we see are crashes of mserver, not crashes of your frontend. These are much harder to
> debug.
>
> You will need to enable core dumps (ODB /Experiment/Enable core dumps set to "y"),
> confirm that core dumps work (i.e. "killall -SEGV mserver", observe core files are created
> in the directory where you started the mserver), reproduce the crash, run "gdb mserver
> core.NNNN", run "bt" to print the stack trace, post the stack trace here (or email to me
> directly).
>
> >
> > I can find some correlation between number of events/event size produced by
> > frontend, cause its failed when its become big enough.
> >
>
> There is no limit on event size or event rate in midas, you should not see any crash
> regardless of what you do. (there is a limit of event size, because an event has
> to fit inside an event buffer and event buffer size is limited to 2 GB).
>
> Obviously you hit a bug in mserver that makes it crash. Let's debug it.
>
> One thing to try is set the write cache size to zero and see if your crash goes away. I see
> some indication of something rotten in the event buffer code if write cache is enabled. This
> is set in ODB "/Eq/XXX/Common/Write Cache Size", set it to zero. (beware recent confusion
> where odb settings have no effect depending on value of "equipment_common_overwrite").
>
> >
> > frontend scheme is like this:
> >
>
> Best if you use the tmfe c++ frontend, event data handling is much simpler and we do not
> have to debug the convoluted old code in mfe.c.
>
> K.O.
>
> >
> > poll event time set to 0;
> >
> > poll_event{
> > //if buffer not transferred return (continue cutting the main buffer)
> > //read main buffer from hardware
> > //buffer not transfered
> > }
> >
> > read event{
> > // cut the main buffer to subevents (cut one event from main buffer) return;
> > //if (last subevent) {buffer transfered ;return}
> > }
> >
> > What is strange to me that 2 frontends (1 per remote pc) causing this.
> >
> > Also, I'm executing one FEcode with -i # flag , put setting eventid in
> > frontend_init , and using SYSTEM buffer for all.
> >
> > Is there something I'm missing?
> > Thanks.
> > A. |
2336
|
10 Feb 2022 |
Stefan Ritt | Bug Report | History plots deceiving users into thinking data is still logging | The problem has been fixed on commit 825935dc on Oct. 2021 and runs fine since then at PSI. If TRIUMF people
agree, we can close that issue and proceed.
Stefan |
2335
|
10 Feb 2022 |
Stefan Ritt | Bug Fix | ODBINC/Sequencer Issue | I tried following script:
ODBSET /Equipment/ArduinoTestStation/Variables/_S_, 10
LOOP 10
WAIT seconds, 3
ODBINC /Equipment/ArduinoTestStation/Variables/_S_
ENDLOOP
and it worked as expected. So I conclude the problem must be in your script. Probably a typo in
the ODB path pointing to a 32-byte string instead to a 4-byte float.
Stefan |
2334
|
10 Feb 2022 |
Francesco Renga | Forum | OPC client within MIDAS | Dear all,
I finally succeeded to get a working driver for the communication with an OPC
UA server. It is based on the open62541 library and I use it in combination with the
generic.h driver class. This is still a crude implementation, but let me post it here,
maybe it can be useful to somebody else.
BTW, if there is somebody more skilled than me with OPC UA and MIDAS drivers, who is
willing to give suggestions for improving the implementation, it would be extremely
appreciated.
Best Regards,
Francesco
> Dear all,
> I need to integrate in my MIDAS project the communication with an OPC UA
> server. My plan is to develop an OPC UA client as a "device" in
> midas/drivers/device.
>
> Two questions:
>
> 1) Is anybody aware of some similar effort for some other project, so that I can
> get some example?
>
> 2) What could be the more appropriate driver's class to be used? generic.cxx?
> multi.cxx?
>
> Thank you for your help,
> Francesco |
Attachment 1: opc.cxx
|
/********************************************************************\
Name: opc.cxx
Created by: Francesco Renga
Contents: Device Driver for generic OPC server
$Id: mscbdev.c 3428 2006-12-06 08:49:38Z ritt $
\********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "midas.h"
#include "msystem.h"
#include <open62541/client_config_default.h>
#include <open62541/client_highlevel.h>
#include <open62541/client_subscriptions.h>
#include <open62541/plugin/log_stdout.h>
#ifndef _MSC_VER
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#endif
#include <vector>
using namespace std;
/*---- globals -----------------------------------------------------*/
typedef struct {
char Name[32]; // System Name (duplication)
char ip[32]; // IP# for network access
int nsIndex;
char TagsGuid[64];
} OPC_SETTINGS;
#define OPC_SETTINGS_STR "\
System Name = STRING : [32] gassys\n\
IP = STRING : [32] 172.17.19.70:4870\n\
Namespace Index = INT : 3\n\
Tags Guid = STRING : [64] ecef81d5-c834-4379-ab79-c8fa3133a311\n\
"
typedef struct {
OPC_SETTINGS opc_settings;
UA_Client* client;
int num_channels;
vector<string> channel_name;
vector<int> channel_type;
} OPC_INFO;
/*---- device driver routines --------------------------------------*/
INT opc_init(HNDLE hKey, void **pinfo, INT channels, INT(*bd) (INT cmd, ...))
{
int status, size;
OPC_INFO *info;
HNDLE hDB;
/* allocate info structure */
info = (OPC_INFO *)calloc(1, sizeof(OPC_INFO));
*pinfo = info;
cm_get_experiment_database(&hDB, NULL);
/* create PSI_BEAMBLOCKER settings record */
status = db_create_record(hDB, hKey, "", OPC_SETTINGS_STR);
if (status != DB_SUCCESS)
return FE_ERR_ODB;
size = sizeof(info->opc_settings);
db_get_record(hDB, hKey, &info->opc_settings, &size, 0);
info->client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(info->client));
char address[32];
sprintf(address,"opc.tcp://%s",info->opc_settings.ip);
printf("Connecting to %s...\n",address);
UA_StatusCode retval = UA_Client_connect(info->client, address);
if(retval != UA_STATUSCODE_GOOD) {
UA_Client_delete(info->client);
return FE_ERR_HW;
}
////Scan of variables
UA_BrowseRequest bReq;
UA_BrowseRequest_init(&bReq);
bReq.requestedMaxReferencesPerNode = 0;
bReq.nodesToBrowse = UA_BrowseDescription_new();
bReq.nodesToBrowseSize = 1;
UA_Guid guid1;
UA_Guid_parse(&guid1, UA_STRING(info->opc_settings.TagsGuid));
bReq.nodesToBrowse[0].nodeId = UA_NODEID_GUID(info->opc_settings.nsIndex, guid1);
bReq.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL; /* return everything */
UA_BrowseResponse bResp = UA_Client_Service_browse(info->client, bReq);
for(size_t i = 0; i < bResp.resultsSize; ++i) {
for(size_t j = 0; j < bResp.results[i].referencesSize; ++j) {
UA_ReferenceDescription *ref = &(bResp.results[i].references[j]);
if ((ref->nodeClass == UA_NODECLASS_OBJECT || ref->nodeClass == UA_NODECLASS_VARIABLE||ref->nodeClass == UA_NODECLASS_METHOD)) {
if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_STRING) {
UA_NodeId dataType;
UA_Client_readDataTypeAttribute(info->client, UA_NODEID_STRING(info->opc_settings.nsIndex, ref->nodeId.nodeId.identifier.string.data), &dataType);
(info->channel_type).push_back(dataType.identifier.numeric-1);
(info->channel_name).push_back((char*)(ref->nodeId.nodeId.identifier.string.data));
}
}
}
}
UA_BrowseNextRequest bNextReq;
UA_BrowseNextResponse bNextResp;
UA_BrowseNextRequest_init(&bNextReq);
bNextReq.releaseContinuationPoints = UA_FALSE;
bNextReq.continuationPoints = &bResp.results[0].continuationPoint;
bNextReq.continuationPointsSize = 1;
bool hasRef;
do {
hasRef = false;
bNextResp = UA_Client_Service_browseNext(info->client, bNextReq);
for (size_t i = 0; i < bNextResp.resultsSize; i++) {
for (size_t j = 0; j < bNextResp.results[i].referencesSize; j++) {
hasRef = true;
UA_ReferenceDescription *ref = &(bNextResp.results[i].references[j]);
if ((ref->nodeClass == UA_NODECLASS_OBJECT || ref->nodeClass == UA_NODECLASS_VARIABLE||ref->nodeClass == UA_NODECLASS_METHOD)) {
if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_STRING) {
UA_NodeId dataType;
UA_Client_readDataTypeAttribute(info->client, UA_NODEID_STRING(info->opc_settings.nsIndex, ref->nodeId.nodeId.identifier.string.data), &dataType);
(info->channel_type).push_back(dataType.identifier.numeric-1);
(info->channel_name).push_back((char*)(ref->nodeId.nodeId.identifier.string.data));
}
}
}
}
bNextReq.continuationPoints = &bNextResp.results[0].continuationPoint;
bNextReq.continuationPointsSize = 1;
} while(hasRef);
info->num_channels = info->channel_name.size();
UA_BrowseRequest_deleteMembers(&bReq);
UA_BrowseResponse_deleteMembers(&bResp);
UA_BrowseRequest_clear(&bReq);
UA_BrowseResponse_clear(&bResp);
return FE_SUCCESS;
}
/*----------------------------------------------------------------------------*/
INT opc_exit(OPC_INFO * info)
{
UA_Client_disconnect(info->client);
UA_Client_delete(info->client);
if (info)
free(info);
return FE_SUCCESS;
}
/*----------------------------------------------------------------------------*/
INT opc_get(OPC_INFO * info, INT channel, float *pvalue)
{
////Read value
UA_Variant *val = UA_Variant_new();
UA_StatusCode retval = UA_Client_readValueAttribute(info->client, UA_NODEID_STRING(info->opc_settings.nsIndex, info->channel_name[channel].c_str()), val);
if (retval == UA_STATUSCODE_GOOD && UA_Variant_isScalar(val) &&
val->type == &UA_TYPES[info->channel_type[channel]]
) {
if(info->channel_type[channel] == UA_TYPES_FLOAT){
*pvalue = *(UA_Float*)val->data;
}
else if(info->channel_type[channel] == UA_TYPES_DOUBLE){
*pvalue = *(UA_Double*)val->data;
}
else if(info->channel_type[channel] == UA_TYPES_INT16){
*pvalue = *(UA_Int16*)val->data;
}
else if(info->channel_type[channel] == UA_TYPES_INT32){
*pvalue = *(UA_Int32*)val->data;
}
else if(info->channel_type[channel] == UA_TYPES_INT64){
*pvalue = *(UA_Int64*)val->data;
}
else if(info->channel_type[channel] == UA_TYPES_BOOLEAN){
*pvalue = (*(UA_Boolean*)val->data) ? 1.0 : 0.0;
}
else if(info->channel_type[channel] == UA_TYPES_BYTE){
*pvalue = *(UA_Byte*)val->data;
}
else {
*pvalue = 0.;
}
}
UA_Variant_delete(val);
return FE_SUCCESS;
}
INT opc_set(OPC_INFO * info, INT channel, float value)
{
////Write value
UA_Variant *myVariant = UA_Variant_new();
if(info->channel_type[channel] == UA_TYPES_FLOAT){
UA_Float typevalue = value;
UA_Variant_setScalarCopy(myVariant, &typevalue, &UA_TYPES[info->channel_type[channel]]);
}
else if(info->channel_type[channel] == UA_TYPES_DOUBLE){
UA_Double typevalue = value;
UA_Variant_setScalarCopy(myVariant, &typevalue, &UA_TYPES[info->channel_type[channel]]);
}
else if(info->channel_type[channel] == UA_TYPES_INT16){
UA_Int16 typevalue = value;
UA_Variant_setScalarCopy(myVariant, &typevalue, &UA_TYPES[info->channel_type[channel]]);
}
else if(info->channel_type[channel] == UA_TYPES_INT32){
UA_Int32 typevalue = value;
UA_Variant_setScalarCopy(myVariant, &typevalue, &UA_TYPES[info->channel_type[channel]]);
}
else if(info->channel_type[channel] == UA_TYPES_INT64){
UA_Int64 typevalue = value;
UA_Variant_setScalarCopy(myVariant, &typevalue, &UA_TYPES[info->channel_type[channel]]);
}
else if(info->channel_type[channel] == UA_TYPES_BOOLEAN){
UA_Boolean typevalue = (value != 0) ? true : false;
UA_Variant_setScalarCopy(myVariant, &typevalue, &UA_TYPES[info->channel_type[channel]]);
}
else if(info->channel_type[channel] == UA_TYPES_BYTE){
UA_Byte typevalue = value;
UA_Variant_setScalarCopy(myVariant, &typevalue, &UA_TYPES[info->channel_type[channel]]);
}
else return FE_SUCCESS;
UA_Client_writeValueAttribute(info->client, UA_NODEID_STRING(info->opc_settings.nsIndex, info->channel_name[channel].c_str()), myVariant);
UA_Variant_delete(myVariant);
return FE_SUCCESS;
}
/*---- device driver entry point -----------------------------------*/
... 62 more lines ...
|
Attachment 2: opc.h
|
/********************************************************************\
Name: dd_sy4527.h
Created by: based on null.h / Stefan Ritt
Contents: Device driver function declarations for SY4527 device
$Id$
\********************************************************************/
INT opc(INT cmd, ...);
|
2333
|
09 Feb 2022 |
Konstantin Olchanski | Bug Fix | ODBINC/Sequencer Issue | >
> [local:mu3eMSci:S]/>cd Equipment/ArduinoTestStation/Variables
> [local:mu3eMSci:S]Variables>ls -l
> Key name Type #Val Size Last Opn Mode Value
> ---------------------------------------------------------------------------
> _T_ FLOAT 1 4 1h 0 RWD 20.93
> _F_ FLOAT 1 4 1h 0 RWD 12.8
> _P_ FLOAT 1 4 1h 0 RWD 56
> _S_ FLOAT 1 4 1h 0 RWD 5
> _H_ FLOAT 1 4 60h 0 RWD 44.74
> _B_ FLOAT 1 4 60h 0 RWD 18.54
> _A_ FLOAT 1 4 1h 0 RWD 14.41
> _RH_ FLOAT 1 4 1h 0 RWD 41.81
> _AT_ FLOAT 1 4 1h 0 RWD 20.46
> SP INT16 1 2 1h 0 RWD 10
>
This looks okey, so we still have no explanation for your error. Please post your sequencer
script?
K.O. |
2332
|
09 Feb 2022 |
jago aartsen | Bug Fix | ODBINC/Sequencer Issue | > Please post the output of odbedit "ls -l" for /eq/ar.../variables. (you posted the
> variable name as an image, and I cannot cut-and-paste the odb path!). BTW data size 4 is
> correct, 4 bytes for INT32/UINT32/FLOAT. For DOUBLE it should be 8. For you it prints 32
> and this is wrong, we need to see the output of "ls -l".
> K.O.
Hi,
Thanks for getting back to me regarding this. The output of "ls -l" is:
[local:mu3eMSci:S]/>cd Equipment/ArduinoTestStation/Variables
[local:mu3eMSci:S]Variables>ls -l
Key name Type #Val Size Last Opn Mode Value
---------------------------------------------------------------------------
_T_ FLOAT 1 4 1h 0 RWD 20.93
_F_ FLOAT 1 4 1h 0 RWD 12.8
_P_ FLOAT 1 4 1h 0 RWD 56
_S_ FLOAT 1 4 1h 0 RWD 5
_H_ FLOAT 1 4 60h 0 RWD 44.74
_B_ FLOAT 1 4 60h 0 RWD 18.54
_A_ FLOAT 1 4 1h 0 RWD 14.41
_RH_ FLOAT 1 4 1h 0 RWD 41.81
_AT_ FLOAT 1 4 1h 0 RWD 20.46
SP INT16 1 2 1h 0 RWD 10
Many Thanks
Jago |
2331
|
08 Feb 2022 |
Konstantin Olchanski | Bug Fix | ODBINC/Sequencer Issue | Please post the output of odbedit "ls -l" for /eq/ar.../variables. (you posted the
variable name as an image, and I cannot cut-and-paste the odb path!). BTW data size 4 is
correct, 4 bytes for INT32/UINT32/FLOAT. For DOUBLE it should be 8. For you it prints 32
and this is wrong, we need to see the output of "ls -l".
K.O. |
2330
|
08 Feb 2022 |
jago aartsen | Bug Fix | ODBINC/Sequencer Issue | Hi all,
I am having some issues getting the ODBINC command to work within the MIDAS
sequencer. I am trying to increment one of the ODB values but it is returning a
mismatch data-type size error (see attached image).
All the ODB variables are MIDAS data-type FLOAT and should all be 32-bit values,
but for some reason MIDAS is thinking they are 4-bit values. I have tried creating
new ODB keys of type INT32, UINT32 and DOUBLE but they all give the same error.
If anybody has any suggestions I would really appreciate some help:)
Thanks
|
Attachment 1: mslerror.PNG
|
|
2329
|
07 Feb 2022 |
Konstantin Olchanski | Forum | MidasWiki moved from ladd00 to daq00.triumf.ca and updated to MediaWiki 1.35 | MidasWiki moved from ladd00 (obsolete SL6) to daq00.triumf.ca (Ubuntu LTS 20.04)
and updated from obsolete MediaWiki LTS 1.27.7 to MediaWiki LTS 1.35, supported
until mid-2023, see https://www.mediawiki.org/wiki/Version_lifecycle
Old URL https://midas.triumf.ca and https://midas.triumf.ca/MidasWiki/...
redirect to new URL https://daq00.triumf.ca/MidasWiki/index.php/Main_Page
All old links and bookmarks should continue to work (via redirect).
To report problems with this MediaWiki instance and to request
any changes in configuration or installed extensions, please reply to this
message here.
K.O. |
2328
|
31 Jan 2022 |
Frederik Wauters | Forum | .gz files | > > I adapted our analyzer to compile against the manalyzer included in the midas repo.
> > TMReadEvent: error: short read 0 instead of -1193512213
>
> I think this problem is fixed in the latest version of midasio and manalyzer, but this update
> was not pulled into midas yet. (Canada is in the middle of a covid wave since December).
>
> What happens is you do not have the gzip library installed on your computer and
> your analyzer is built without support for gzip.
>
> The fix is done the hard way, the gzip library is no longer optional, but required.
>
> You do not say what linux you use, so I cannot give exact instructions, but for:
> ubuntu: apt -y install libz-dev
> centos7: installed by default
> centos8: installed by default
> debian11/raspbian: same as ubuntu
>
> K.O.
My libz under ubuntu
-- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.2.11")
-- MIDAS: Found ZLIB version 1.2.11
I got both the manalyzer example and mine going with
* the latest midas dev
* + the latest manalyzer (cf6c233)
* + almost latest midasio (568a617, otherwise I get an linking error
./libmidas.a(midasio.cxx.o): In function `Lz4Error(int)':
midasio.cxx:(.text+0x359): undefined reference to `MLZ4F_getErrorName(unsigned long)'
So this works, I will assume that in the near future this all will come together in the standard midas release.
thanks |
2327
|
29 Jan 2022 |
Isaac Labrie Boulay | Forum | MIDAS and GRIF-16 digitizer (Standalone Mode). | Hi all,
I was sent a version of the frontend for the TIGRESS Detector lab setup so that
I can test detectors using a GRIF-16 digitizer in standalone mode.
I followed the GRIF-16 wiki (https://grsi.wiki.triumf.ca/wiki/GRIF-16#One-
level_operation) to setup the GRIF-16 through the webpage. The digitized data is
supposed to come into my UDP port 8800 but it is never retrieved in the
frontend.
Here's the readout scheme:
// readout sequence ...
// poll_event() true (if still have data in buffer or testmsg() true)
// -> read_trigger_event() -> read_grifc_event() - re-buffers into midas events
// -> grifc_eventread() - returns single grif fragment
// -> grifc_dataread() - returns single net-pkt
Here's poll_event():
INT poll_event(INT source, INT count, BOOL test)
{
int i, have_data=0;
for(i=0; i<count; i++){
if( data_available ){ break; }
have_data = ( testmsg(data_socket, 0) > 0 );
if( have_data && !test ){ break; }
}
return( (have_data || data_available) && !test );
}
This being said, testmsg() always returns empty and "data_available" is only set
to TRUE when there's leftover data after a GRIF-C reading (I'm obviously not
using a GRIF-C).
I know that when GRIF-16 is in standalone mode, MIDAS does not change GRIF-16s
settings based on the ODB, it has to be done through the GRIF-16 webpage. Is the
user frontend code even responsible for the GRIF-16 data readout in standalone
mode? If not, could it just be that my UDP offloader is incorrectly setup?
Here are its current settings:
SETTINGS/UDP
- Offloader: ON
- Dst IP: my IP
- Dst Port: 8800 (DATA_PORT)
SETTINGS/MIDAS
- Use MIDAS: OFF
- MIDAS Hostname: my hostname
- MIDAS IP: same as Dst IP from UDP settings
- Dst Port: 8080 (I'm assuming that this is the mhttpd port)
Again, the frontend runs but I get 0 events. What might I be missing?
Thanks for helping me out!
Isaac |
2326
|
28 Jan 2022 |
Stefan Ritt | Bug Report | Writting MIDAS Events via FPGAs | I finally got the dummy program working. There were several issues:
- event_buffer_size was defined as 10000 * 32 MB = 320 GB, exceeding the RAM of the computer
- SERIAL number starting with 1. Actually in midas, event serial numbers always started with zero, but this was wrong in the documentation at
https://midas.triumf.ca/MidasWiki/index.php/Event_Structure, so I also fixed the documentation
- the event header time stamp must be seconds since 1.1.1970, and thus the function ss_time() should be used to set it
- calling set_equipment_status() for each event slows down the event collection considerably, since this function access the ODB each time
- dma_buf_dummy is defined inside the event loop, so it gets allocated and de-allocated on the stack for each event. Of course this might vanish
when the real FPGA buffer will be used.
- The line pdata+=sizeof(dma_buf_dummy); is wrong. pdata is pointer to uint32_t, but the sizeof() operation returns the size of the
dma_buf_dummy in bytes. Therefore, pdata gets incremented by four times the size of dma_buf_dummy
- Instead the call to std::this_thread::sleep_for(std::chrono::milliseconds(2000)); one can call the standard midas call ss_sleep(2000); which
is a bit shorter
- Finally, sending many events to the ring buffer triggered a bug in the midas ring buffer functions which were lingering there since 2007. I'm
glad that this happened and now could be fixed. Not sure if other experiments where affected in the last decade by that. This could have
manifested itself in lost events or crashing front-ends. Anyhow, now it's fixed. You need to update midas to get the fix.
I attached a working version of the dummy program for your reference. Banks a different but the principle should become clear.
Stefan |
Attachment 1: dummy_fe.cpp
|
/********************************************************************\
Name: dummy_fe.cxx
Created by: Frederik Wauters
Changed by: Marius Koeppel
Contents: Dummy frontend producing stream data
\********************************************************************/
#include <algorithm>
#include <math.h>
#include <random>
#include <stdio.h>
#include <stdlib.h>
#include <bitset>
#include <iostream>
#include <unistd.h>
#include "midas.h"
#include "msystem.h"
#include <chrono>
#include <thread>
#include "mfe.h"
using namespace std;
/*-- Globals -------------------------------------------------------*/
/* The frontend name (client name) as seen by other MIDAS clients */
const char *frontend_name = "Dummy FE SWB";
/* The frontend file name, don't change it */
const char *frontend_file_name = __FILE__;
/* frontend_loop is called periodically if this variable is TRUE */
BOOL frontend_call_loop = FALSE;
/* a frontend status page is displayed with this frequency in ms */
INT display_period = 0;
/* maximum event size produced by this frontend */
INT max_event_size = 1 * (1024 * 1024);// 32MB
/* maximum event size for fragmented events (EQ_FRAGMENTED) */
INT max_event_size_frag = 5 * 1024 * 1024;
/* buffer size to hold events */
INT event_buffer_size = 2 * max_event_size;
/*-- Function declarations -----------------------------------------*/
INT read_stream_thread(void *param);
uint32_t generate_random_pixel_hit_swb(uint32_t time_stamp);
uint32_t generate_random_beam_ref_hit(uint32_t time_stamp, uint32_t chipID);
BOOL equipment_common_overwrite = TRUE;//true is overwriting the common odb
/* DMA Buffer and related */
volatile uint32_t *dma_buf;
#define MUDAQ_DMABUF_DATA_ORDER 25 // 29, 25 for 32 MB
#define MUDAQ_DMABUF_DATA_LEN (1 << MUDAQ_DMABUF_DATA_ORDER)// in bytes
size_t dma_buf_size = MUDAQ_DMABUF_DATA_LEN;
uint32_t dma_buf_nwords = dma_buf_size / sizeof(uint32_t);
/*-- Equipment list ------------------------------------------------*/
EQUIPMENT equipment[] = {
{
"Stream SWB", /* equipment name */
{1, 0, /* event ID, trigger mask */
"SYSTEM", /* event buffer */
EQ_USER, /* equipment type */
0, /* event source */
"MIDAS", /* format */
TRUE, /* enabled */
RO_RUNNING, /* read always and update ODB */
100, /* poll for 100ms */
0, /* stop run after this event limit */
0, /* number of sub events */
0, /* log history every event */
"", "", ""},
NULL, /* readout routine */
},
{""}};
/*-- Dummy routines ------------------------------------------------*/
INT poll_event(INT source, INT count, BOOL test) {
return 1;
};
INT interrupt_configure(INT cmd, INT source, POINTER_T adr) {
return 1;
};
/*-- Frontend Init -------------------------------------------------*/
INT frontend_init() {
// create ring buffer for readout thread
create_event_rb(0);
// create readout thread
ss_thread_create(read_stream_thread, NULL);
return CM_SUCCESS;
}
/*-- Frontend Exit -------------------------------------------------*/
INT frontend_exit() {
return CM_SUCCESS;
}
/*-- Frontend Loop -------------------------------------------------*/
INT frontend_loop() {
return CM_SUCCESS;
}
/*-- Begin of Run --------------------------------------------------*/
INT begin_of_run(INT run_number, char *error) {
return CM_SUCCESS;
}
/*-- End of Run ----------------------------------------------------*/
INT end_of_run(INT run_number, char *error) {
return CM_SUCCESS;
}
/*-- Pause Run -----------------------------------------------------*/
INT pause_run(INT run_number, char *error) {
return CM_SUCCESS;
}
/*-- Resume Run ----------------------------------------------------*/
INT resume_run(INT run_number, char *error) {
return CM_SUCCESS;
}
/*------------------------------------------------------------------*/
uint32_t generate_random_pixel_hit_swb(uint32_t time_stamp) {
uint32_t tot = rand() % 32; // 0 to 31
uint32_t chipID = rand() % 3;// 0 to 2
uint32_t col = rand() % 256; // 0 to 256
uint32_t row = rand() % 250; // 0 to 250
uint32_t hit = (time_stamp << 28) | (chipID << 22) | (row << 14) | (col << 6) | (tot << 1);
// if ( print ) {
// printf("ts:%8.8x,chipID:%8.8x,row:%8.8x,col:%8.8x,tot:%8.8x\n", time_stamp,chipID,row,col,tot);
// printf("hit:%8.8x\n", hit);
// std::cout << std::bitset<32>(hit) << std::endl;
// }
if (((hit >> 22) & 0x3f) > 2)
printf("Hit %8.8x", hit);
if (chipID > 2)
printf("ChipID %8.8x", chipID);
return hit;
}
uint32_t generate_random_beam_ref_hit(uint32_t time_stamp, uint32_t chipID) {
uint32_t fastTS = rand() % 4194303 / 2;// 0 to 4194303
uint32_t hit = (time_stamp << 28) | (chipID << 22) | (fastTS << 1);
if (((hit >> 22) & 0x3f) > 4) {
printf("Hit Ref %8.8x\n", hit);
printf("Ref fast %8.8x\n", fastTS);
printf("ChipID Ref %8.8x\n", chipID);
printf("Time Ref %8.8x\n", time_stamp);
printf("Chip %8.8x\n", ((hit >> 22) & 0x3f));
}
return hit;
}
INT read_stream_thread(void *param) {
uint32_t *pdata;
// init bank structure - 64bit alignment
uint32_t SERIAL = 0;
// tell framework that we are alive
signal_readout_thread_active(0, TRUE);
// obtain ring buffer for inter-thread data exchange
int rbh = get_event_rbh(0);
int status;
int nEvents = 5000;
size_t eventSize = 32; // in 4-byte words
size_t dmaBufSize = nEvents * eventSize * sizeof(uint32_t); // buffer size in bytes
uint32_t * dma_buf_dummy = (uint32_t *) malloc(dmaBufSize);
while (is_readout_thread_enabled()) {
// don't readout events if we are not running
if (!readout_enabled()) {
// do not produce events when run is stopped
ss_sleep(10);// don't eat all CPU
continue;
}
// obtain buffer space with 10 ms timeout
status = rb_get_wp(rbh, (void **) &pdata, 10);
// just try again if buffer has no space
if (status == DB_TIMEOUT)
continue;
if (status != DB_SUCCESS) {
cout << "!DB_SUCCESS" << endl;
break;
}
for (int i = 0; i < nEvents; i++) {
// event header
dma_buf_dummy[ 0 + i * eventSize] = 0x00000001; // Trigger Mask & Event ID
dma_buf_dummy[ 1 + i * eventSize] = SERIAL++; // Serial number
dma_buf_dummy[ 2 + i * eventSize] = ss_time(); // time
dma_buf_dummy[ 3 + i * eventSize] = eventSize * 4 - 4 * 4;// event size
dma_buf_dummy[ 4 + i * eventSize] = eventSize * 4 - 6 * 4;// all bank size
dma_buf_dummy[ 5 + i * eventSize] = 0x31; // flags
// bank PCD0 first FEB
dma_buf_dummy[ 6 + i * eventSize] = 'P' << 0 | 'C' << 8 | 'D' << 16 | '0' << 24;// bank name
dma_buf_dummy[ 7 + i * eventSize] = 0x06; // bank type TID_DWORD
dma_buf_dummy[ 8 + i * eventSize] = 10 * 4; // data size
dma_buf_dummy[ 9 + i * eventSize] = 0x0; // reserved
dma_buf_dummy[10 + i * eventSize] = 0xE80000BC; // preamble
dma_buf_dummy[11 + i * eventSize] = 0x00000000; // TS0
dma_buf_dummy[12 + i * eventSize] = ss_time(); // TS1
dma_buf_dummy[13 + i * eventSize] = 0xFC000000; // sub header
dma_buf_dummy[14 + i * eventSize] = generate_random_pixel_hit_swb(ss_time()); // hit0
dma_buf_dummy[15 + i * eventSize] = generate_random_pixel_hit_swb(ss_time()); // hit1
dma_buf_dummy[16 + i * eventSize] = generate_random_beam_ref_hit(ss_time(), 3);// chip 3 beam ref bits 22:1 -> fast TS
dma_buf_dummy[17 + i * eventSize] = generate_random_beam_ref_hit(ss_time(), 4);// chip 4 sintilator bits 22:1 -> fast TS
dma_buf_dummy[18 + i * eventSize] = 0xFC00009C; // TRAILER
dma_buf_dummy[19 + i * eventSize] = 0xAFFEAFFE; // PADDING
// bank PCD1 second FEB
dma_buf_dummy[20 + i * eventSize] = 'P' << 0 | 'C' << 8 | 'D' << 16 | '1' << 24;// bank name
dma_buf_dummy[21 + i * eventSize] = 0x6; // bank type TID_DWORD
dma_buf_dummy[22 + i * eventSize] = 8 * 4; // data size
dma_buf_dummy[23 + i * eventSize] = 0x0; // reserved
dma_buf_dummy[24 + i * eventSize] = 0xE80001BC; // preamble
dma_buf_dummy[25 + i * eventSize] = 0x00000000; // TS0
dma_buf_dummy[26 + i * eventSize] = ss_time(); // TS1
dma_buf_dummy[27 + i * eventSize] = 0xFC000000; // sub header
dma_buf_dummy[28 + i * eventSize] = generate_random_pixel_hit_swb(ss_time());// hit0
dma_buf_dummy[29 + i * eventSize] = generate_random_pixel_hit_swb(ss_time());// hit1
dma_buf_dummy[30 + i * eventSize] = 0xFC00009C; // TRAILER
dma_buf_dummy[31 + i * eventSize] = 0xAFFEAFFE; // PADDING
}
memcpy(pdata, dma_buf_dummy, dmaBufSize);
// print data
if (true) {
auto *eh = (EVENT_HEADER *) (&pdata[0]);
auto *bh = (BANK_HEADER *) (&pdata[4]);
auto *ba = (BANK32A *) (&pdata[6]);
char bank_name[5];
bank_name[4] = 0;
memcpy(bank_name, (char *) (ba->name), 4);
printf("EID=%4.4x TM=%4.4x SERNO=%8.8x TS=%8.8x EDsiz=%8.8x\n", eh->event_id, eh->trigger_mask, eh->serial_number, eh->time_stamp, eh->data_size);
printf("DAsiz=%8.8x FLAG=%8.8x\n", bh->data_size, bh->flags);
printf("BAname=%s TYP=%8.8x BAsiz=%8.8x BAres=%8.8x\n", bank_name, ba->type, ba->data_size, ba->reserved);
}
rb_increment_wp(rbh, dmaBufSize);// in byte length
ss_sleep(300);// limit data rate
}
free(dma_buf_dummy);
return 0;
}
|
2325
|
26 Jan 2022 |
Marius Koeppel | Bug Report | Writting MIDAS Events via FPGAs |
> If you are connected locally (no mserver), I want to know the value returned by bm_send_event(). Simplest
> if you edit mfe.c and everywhere it calls bm_send_event() and rpc_send_event(), print the returned value.
>
> It would be very interesting to see if bm_send_event() returns 1 (SUCCESS), but the event vanishes
> without a trace.
I checked bm_send_event(rbh, (EVENT_HEADER*)(&pdata[0]), 0, 20); which gives me back 1. I also check the status of rb_increment_wp which is also 1.
> Before you do that, try something simpler:
> Run "mdump -s -d", it will print some event buffer internals.
> Watch to see if any data pointers change when you send your events ("wp", "rp", etc).
"rp" & "wp" are not counting up.
> But there is some funny logic for event_id and trigger_mask and it is worth checking their
> values. For a good test, set event_id=1 and trigger_mask=0x1. There might be trouble if either is set to zero.
Changing both to 0x1 did not change the behavior.
Cheers,
Marius |
2324
|
26 Jan 2022 |
Konstantin Olchanski | Forum | mhttpd error | > > Enable IPv6 y
>
> Probably the IPv6 problem, see here elog:2269
>
> I asked to turn off IPv6 by default, or at least mention this in the documentation,
> but unfortunately nothing happened.
But IPv4 and IPv6 code is completely separate, if IPv6 bind fails, IPv4 should still
work.
This is all very strange.
It does not help that the OP does not say in which way things do not work,
"the server is not accessible from other machines" is not an error message
reported by any browser, and we do not know what URL he is using
to access mhttpd - http: or https:
Also he is enabling the "insecure" port 8081, I am pretty sure the documentation
is pretty clear, either use the secure https port or the insecure port,
but not both at the same time.
In any case, I see current version of mongoose have removed support
for password files, so all this stuff will likely become reworked
and at the end mhttpd will only listen to localhost ports. To make it "accessible
to other machines", one will have to use the apache https proxy. (or mtpcproxy from
midas).
K.O. |
|