ID |
Date |
Author |
Topic |
Subject |
986
|
17 Mar 2014 |
Stefan Ritt | Info | Windows support droped? | > The Windows executables are no longer included in the midas git repository. Old versions are still available in
> the git repository - they got pulled in during conversion from svn.
>
> One reason for removing them is that neither myself, nor Pierre, nor Stefan have ready access to a Windows
> development environment and we cannot keep Windows binaries up to date. Theoretically we can setup a
> Windows machine just for compiling MIDAS, but then there is a question of which Windows we should use and
> how much priority we should put into it. I do not think there is any demand for MIDAS on Windows at TRIUMF.
I double checked and can confirm that the executables in GIT are very old. So I tried to compile the current version for Windows. I found that I had to change lots
of places (basically all the new files written by KO) to make it work again, so it took me half a day, but now should be fine.
I'm not sure if it's a good idea to keep .exe files in GIT, maybe we should remove it some day, but for the moment I updated the executables to the current
version. Feedback welcome.
/Stefan |
991
|
16 Apr 2014 |
Stefan Ritt | Forum | C++11 error | > I am having some trouble creating a frontend that interacts with some libraries that use C++11.
>
> The flag I added to my MIDAS Makefile to get the C++11 part of the code to work is -std=c++0x. This
> causes an error in the equipment description in the frontend code.
>
> The error I get is:
>
> frontend.cpp:149: error: narrowing conversion of ‘-0x00000000000000001’ from ‘int’ to ‘WORD’ inside {
> }
>
> This corresponds to the following in the MIDAS frontend code.
>
> EQUIPMENT equipment[] = {
> {
> "MWPC", /* equipment name */
> {1, TRIGGER_ALL, /* event ID, trigger mask */
> "BUF2", /* event buffer */
> EQ_POLLED | EQ_EB, /* equipment type */
> LAM_SOURCE(0, 0xFFFFFF), /* event source crate 0, all stations */
> "MIDAS", /* format */
> TRUE, /* enabled */
> RO_RUNNING, /* read only when running */
> 1, /* poll for 1ms */
> 0, /* stop run after this event limit */
> 0, /* number of sub events */
> 0, /* don't log history */
> "", "", "",},
> read_trigger_event, /* readout routine */
> },
>
> {""}
> }; <- this is line 149
> #ifdef __cplusplus
> }
> #endif
>
> Do you know a way to make this compatible with C++11?
>
> Thanks!
Is this maybe related to the LAM_SOURCE(0, 0xFFFFFFFF) where 0xFFFFFFFF is -1. I guess you are not using CAMAC, so just replace the
LAM_SOURCE(...) with zero and try again.
/Stefan |
993
|
17 Apr 2014 |
Stefan Ritt | Forum | C++11 error | > Thanks for the suggestion. It looks like it is instead the TRIGGER_ALL that is causing the problem. TRIGGER_ALL is defined as -1 in midas.h. If I replace TRIGGER_ALL with 0 in the
> frontend, it compiles, but if I use -1, I get the same error. I do not think that I want my trigger mask set to 0. Do you have a suggestion of how to get around this?
Ok, then it's clear. The trigger mask inside the EQUIPMENT_INFO is defined as 16-bit unsigned int (WORD). So the -1 gets expanded into a 64-bit signed int, then the compiler complains about truncating this to 16-bit.
Just try instead TRIGGER_ALL to write
(WORD)(-1)
or even
0xFFFF
that should do the job. Basically you want all 16 bits to be "1" if yo do not use this feature.
Best regards,
Stefan |
1000
|
26 May 2014 |
Stefan Ritt | Suggestion | "Edit-on-end" would be nice | We have similar demands, and we solve it in the following:
We use a run database. In the simplest case, this can be a text file which gets written at the end of the file. The
mlogger has a built in SQL interface, so one can keep that table even inside a SQL interface. The per-run-
information then contains the run number, start/stop time, number of events, some run parameters and a "junk"
flag. So if a run has a problem, one can set the junk flag by accessing the database (or text file) and setting this
flag. In many cases you see that a run had a problem not at the end of the run, but a bit later. You mayby realize
that the last two or three runs had the problem. With the run database approach, you can flag any run as "junk"
later, which we need often, An edit-on-end would not make this possible.
So technically putting and edit-on-end is not a problem, but your life might be much easier if you use a run
database as outlined above.
Best regards,
Stefan |
1007
|
12 Jun 2014 |
Stefan Ritt | Suggestion | Saving ODB values in a sequencer script | > I have a possibly simple feature request for the MIDAS sequencer. It would be
> helpful to be able to save an ODB key's value to a variable, for later use, and
> would be the analogue of the ODBSET command. I had in mind an application where
> a user wants to temporarily change some settings in the ODB, then restore the
> ODB to its original values. Maybe something like on ODBRead command:
I implemented your request, committed the changed to GIT and updated the documentation. Now you can run
things like:
ODBSET /System/tmp/test 1234
ODBGET /System/tmp/test v
MESSAGE $v
(first you must create the key in the ODB manually).
Best regards,
Stefan |
1025
|
14 Oct 2014 |
Stefan Ritt | Bug Report | Hostile network scans against MIDAS RPC ports | Doing this through the ODB seems ok to me. If the ODB cannot be accessed, you can fall back to no protection.
At PSI we fortunately do not have these network scans because PSI uses a institute-wide firewall. So you can connect from outside PSI to inside PSI only
on certain well-defined ports (like SSH to certain machines). You can do the same in Alpha. Use one computer as a router with two network cards, where
the DAQ network runs on the second card as a private network. Then program the routing tables in that gateway such that only certain ports can be
accessed from outside, like port 8080 to mhttpd. This way you block all except the things which are needed.
/Stefan |
1026
|
15 Oct 2014 |
Stefan Ritt | Bug Report | Problem in mfe multithread equipments | You are absolutely correct, the code is certainly wrong. It looks to me like the
while (rbh)
was put in there for some testing, and I forgot to remove it. The only thing I could imagine is that we want to have a while loop there for performance reason. Like
readout_start = ss_millitime();
while (ss_millitime - readout_start < (DWORD) eq_info->period) {
read event
return 0 if no event found
}
You find this code also in the check_polled_events() routine. It ensures that the routine does not return after every single event, but after the period defined in the
equipment (which is usually 100 ms for polled events). This way the code is more efficiently, since we do not check for RPC calls between every event, but just 10 times
per second. This way you can shovel more events through the system, while still being responsive to run stops.
I don't have any hardware right now to test this, so please put my code above into the routine and commit it if it works.
I notice also a difference in both codes concerning the read buffer handles. The old code uses rbh2, while the new (wrong) code uses rbh. In your case probably both
handles are the same, so it works, but in other experiments, which might use several ring buffers, it will fail. So please use rbh instead rbh2.
Let me know if it works for you, and if you see any difference in speed between the versions with and without the while loop (actually you will see this only if your trigger
rate maxes out the DAQ).
Cheers,
Stefan |
1027
|
15 Oct 2014 |
Stefan Ritt | Bug Report | Problem in mfe multithread equipments | Please disregard my previous posting, you don't need the while loop, since it's already in the scheduler (around lines 2160 under /*---- send interrupt events ----*/).
But now I remember the rationale behind it. The loop over the rb[i] is because in MEG I have n calibration threads, each one running on a separate CPU core. So the receive_trigger_event() routine has to collect events from all the
threads, each of them having one ring buffer. In the process of implementing EQ_USER, I changed this somehow, and apparently broke the code by making the while() loop looping forever if the event rate is over 100 Hz.
So for the moment please remove the while loop completely, and I will worry later of putting it back correctly when MEG will start again next year.
/Stefan |
1028
|
15 Oct 2014 |
Stefan Ritt | Bug Report | Problem with EQ_USER | Sure, each thread needs its own ring buffer for writing.
So I see that we need back the multiple-ring-buffer-readout-scheme even before MEG will start. So what you need is something like
for (i=0 ; rb[i] != 0 ; i++) {
read event from rb[i];
}
as it was before. What I do not like is that rb is a global variable, we should better use the encapsulation functions and extend get_event_rb() to
get_event_rb(i) so you can have n ring buffers.
Give me one day, I will extend the current code to make it work again and to implement N threads.
Cheers,
Stefan |
1029
|
16 Oct 2014 |
Stefan Ritt | Bug Report | Problem with EQ_USER | I restructured the front-end code to enable multiple readout threads for EQ_USER equipment. Last summer I was definitively interrupted during
that work and left it in an half finished state, sorry for that.
The way it works now is illustrated in mtfe.c. You create N ring buffers and N threads via
for (int i=0 ; i<N ; i++) {
create_event_rb(i);
ss_thread_create(trigger_thread, (void*)(PTYPE)i);
}
then each readout thread accesses its own readout buffer
thread(...)
{
index = (int)(PTYPE)param;
signal_readout_thread_active(index, TRUE);
rbh = get_event_rbh(index);
while (is_readout_thread_enabled()) {
... read event and put it into ring buffer ...
}
signal_readout_thread_active(index, FALSE);
}
The is_readout_thread_enabled() and signal_readout_thread_active() are used by the framework to shut down gracefully threads correct at the end
of the program. This way each thread can close any hardware correctly.
Note that no other thread management is done by the framework. In the old days with interrupt equipment, the framework disabled interrupts
when reading out periodic events, since that was necessary when using a single CAMAC crate for ADCs and scalers. This is obsolete now and not
needed any longer. It is now the responsibility of the user code to resolve hardware access conflicts between different threads (like using a local
mutex to access the same hardware). There is also no "readout when running" handling. If events should not be read out when the run is stopped,
the readout thread has to check to run status, or better the EOR routine should disable the hardware trigger and the BOR routine should re-enable
it. The readout threads will then poll for new events and just go to sleep if nothing is there.
I testes the mtfe.c program with 100 Hz and 1 MHz event rate on a dummy experiment (no hardware access) and it worked without problem.
Let me know if there is any issue left over.
/Stefan |
1030
|
16 Oct 2014 |
Stefan Ritt | Bug Report | Problem in mfe multithread equipments | > while (1)
> wait 10 ms for an event
> process event, loop back
> if there is no event, exit
> }
This code has been rewritten now and should work for event rates >100 Hz.
/Stefan |
1032
|
16 Oct 2014 |
Stefan Ritt | Bug Report | Hostile network scans against MIDAS RPC ports | > Sometimes we have very small MIDAS installations, i.e. just one machine by itself, and such setups should be secure/secured easily -
> too much work to setup an external firewall box just for one machine and OS-level firewall rules sometimes conflict
> with some OS services (i.e. NIS) (I am still waiting for the "NIS to LDAP migration for dummies" guide).
I fully agree with you. So if you find time to implement this, I will be more than happy.
/Stefan |
1034
|
24 Oct 2014 |
Stefan Ritt | Forum | Running a frontend on Arduino Yun | > Hello,
>
> I'm currently trying to create a midas bank for basic temperature reading from the Arduino Yun, but when creating a bank the frontend crashed with a segfault, my
> code currently looks like this:
>
> INT read_event(char *pevent, INT off)
> {
> WORD *data;
> //printf("before init\n");
> bk_init(pevent);
> //printf("after init\n");
> bk_create(pevent, "TEM0", TID_WORD, data); // <= we are dieing at this line
> //printf("after create\n");
>
> bk_close(pevent, data);
>
> return bk_size(pevent);
> }
>
> Does anyone have an Idea how to tackle this problem down? running a debugger is a little bit tricky on a this processor..
>
> Thanks!
Two bugs:
bk_create(pevent, "TEMO0", TID_WORD, &data);
note the "&" in front of data. Then you have to increment the pointer for each byte you add to the bank:
*data = <temp>;
data++;
bk_close(pevent, data);
this way the bk_close() function know how much data you added to the bank.
Cheers,
Stefan |
1036
|
02 Nov 2014 |
Stefan Ritt | Forum | Running a frontend on Arduino Yun | > With the correct definition, you should get a compile error (type mismatch).
>
> With the wrong current definition, you should have gotten a warning about "use of uninitialized variable 'data'", but some compilers with some settings do not generate this warning.
I redefined the definition of the bk_create function to contain a void **pdate pointer, but that did not really help. Now I get a compiler error:
"Incompatible pointer type passing 'DWORD **' to parameter of type 'void **', so I need an explicit cast each time
bk_create(... (void **)&pdata);
But I think this is better than what we had before so I leave it. Please note that all front-ends using bk_create need to be modified accordingly to suppress this warning.
/Stefan |
1037
|
06 Nov 2014 |
Stefan Ritt | Forum | Weird problem on new installation |
Razvan Stefan Gornea wrote: | In my case I have the following structure in ODB right before the framework calls frontend_init():
/Equipment/CAEN_V1740 [CLOSE]
/Equipment/CAEN_V1740/Variables [CLOSE]
/Equipment/CAEN_V1740/Common [OPEN]
/Equipment/CAEN_V1740/Statistics [OPEN]
/Equipmemt/CANE_V1740/Settings [CLOSE]
|
Sorry my late reply, but I could only find today to have a look at this.
It is absolutely ok to have the Common and Statistics subtrees in the ODB open. So if anybody modifies anything in the Common tree for example, the frontend gets notified directly via the hot link mechanism. Having a subtree "open" however means that the structure of that tree may not be changed, since it's directly mapped onto a fixed C structure. If you create a subtree via the db_create_record() function, you modify the structure of that tree, and thus it may not be open by other clients.
Your problem can be fixed if you create the /Equipment/CAEN_V1740/Settings tree (which is not open), instead the full /Equipment/CAEN_V1740 tree, which contains the open Common and Statistics subtrees.
Best regards,
Stefan |
1044
|
03 Mar 2015 |
Stefan Ritt | Forum | Starting program from custom page | > I am trying to start a program (fronend) from a custom page. What is the best
> way to do that? Would ODBRpc() do this? if so can anyone give me an example of
> how to do this. Thanks.
You have a look at the documentation:
http://ladd00.triumf.ca/~daqweb/doc/midas-old/html/RC_mhttpd_defining_script_buttons.html
Cheers,
Stefan |
1046
|
03 Mar 2015 |
Stefan Ritt | Forum | Starting program from custom page | > Hi Stefan, thanks for the quick reply. I guess my question was not clear enough.
>
> My aim is to create a button which mimics the "Start/Stop" button functionality in the
> "Programs" page where we start all the front-ends for the various equipment. The idea is that
> the user will use a simple interface in a custom page (not the status page) which sets up the
> equipment needed for a specific type of measurement.
All functions in midas are controlled through special URLs. So the URL
http://<host:port>/?cmd=Start&value=10
will start run #10. Similarly with ?cmd=Stop. Now all you need is to set up a custom button, and use the
OnClick="" JavaScript method to fire off an Ajax request with the above URL.
To send an Ajax request, you can use the function XMLHttpRequestGeneric which ships as part of midas in the
mhttpd.js file. Then the code would be
<input type="button" onclick="start()">
and in your JavaScript code:
...
function start()
{
var request = XMLHttpRequestGeneric();
url = '?cmd=Start&value=10';
request.open('GET', url, false);
request.send(null);
}
...
Cheers,
Stefan |
1053
|
13 May 2015 |
Stefan Ritt | Forum | Check if Client is running from Javascript |
Andreas Suter wrote: | Is there currently an easy way to check from javascript if a midas client is
running? I mean an equivalent to cm_exist.
Sometimes this would be very useful in custom pages. |
Sounds like a good idea. We will add it this summer. |
1058
|
14 May 2015 |
Stefan Ritt | Suggestion | checksums for midas data files | > Any thoughts on this?
We use binary midas files now for ~20 years and never felt the necessity to put any checksums or even encryption on these files. The reason for that is the following: Data on
modern hard disks is already protected by CRC code or even ERC on the lower level, so it's very unlikely that single bytes change. If something happens, then it's a
corruption of the file system, so a few sectors of a file are missing or wrong. In that case a CRC won't help you much, just tells you that the files are corrupt. But you see that
also in the midas event structure. Each event has a header with the size of the event, so you can follow the file event by event. If something is missing, the next event header
is no event header but something in the middle of the date, and you recognise this immediately since the header does not make any send (date is off by many years, event ID
is arbitrary, event size is very different). So this redundancy in the midas event structure helps you to identify any corrupt files as good in my opinion as a CRC code will. I
would not want to waste a single CPU cycle on lengthy CRC or even SHA algorithms, unless I see single bytes change inside events. But in this case this can even happen at
the network level between frontend and backends. So we should add the CRC/SHA code at the frontend level. This could increase the dead time of the experiment which is
bad. And what about VME transfer? While hard disks and Ethernet networks have already built-in CRC checks, VME transfer doesn't. So how can you be sure that no bits
get corrupt between your ADC and your frontend computer?
If people insist of having CRC or SHA protection/encryption for some reason I do not understand yet, we should make this optional, so that I can turn it off, since I don't
need it.
/Stefan |
1065
|
10 Jun 2015 |
Stefan Ritt | Forum | Midas-MSCB SCS2000 integration | > If anyone has any ideas or has had previous work with the SCS2000 and knows how to read back the
> internal values please let me know.
The current MIDAS distribution contains a file /midas/examples/slowcont/mscb_fe.c which contains example code of how to read some MSCB devices.
/Stefan |
|