Back Midas Rome Roody Rootana
  Midas DAQ System, Page 116 of 137  Not logged in ELOG logo
ID Date Authordown Topic Subject
  1523   17 Apr 2019 John M O'DonnellInfoswitch of MIDAS to C++, how much C++?
some semi-random thoughts:

no templates strictly means you can't use std::string, std::vector etc.

printf is in any case part of C++ (#include <cstdio>), but std::ostreams can be faster (for std::cout, endl line causes buffer flushing, whereas "\n" does not flush the buffer but printf
always flushes the buffer), and formatting is possible (though very long winded).  printf does not allow to print things other than simple data, e.g. BANK_HEADER* bh; printf( "%?", *bh);

I've been writing all our DAQ code in C++ for a while now.

> > >
> > > With the removal of the requirement to make it possible to write MIDAS frontends in C, we can switch the MIDAS 
> > > default build to C++ and start using C++ features in the MIDAS API (std::string, std::vector, etc).
> > > 
> 
> C++ is a big animal. Obviously we want to use std::string, std::vector and similar improvements over plain C (we already use "//" for comments).
> 
> But in keeping with the Camel's nose fable (https://en.wikipedia.org/wiki/Camel%27s_nose), there are some parts of C++ we definitely do not want to use in MIDAS. Even the C++ FAQ talks 
> about "evil features", see https://isocpp.org/wiki/faq/big-picture#use-evil-things-sometimes
> 
> Here is my list of things to use and to avoid. Comments on this are very welcome - as everybody's experience with C++ is different (and everybody's experience is very valuable and very 
> welcome).
> 
> - std::string, std:vector, etc are in. I am already using them in the MIDAS API (midas.h)
> - extern "C" is out, everything has to be C++, will remove "extern "C"" from all midas header files.
> - exceptions are out, see https://stackoverflow.com/questions/1736146/why-is-exception-handling-bad
> - std::thread and std::mutex are in, at least for writing new frontends, but see discussion of "cannot use c++11". (maybe replace ss_mutex_xxx() with out own std::mutex look-alike).
> - heavy use of templates and heavy use of argument overloading is out - just by looking at the code, impossible to tell what function will be called
> - "auto" is on probation. I need to know if "auto v=f()" is an integer or a double when I write "auto w=v/2" or "auto w=v/2.0". see 
> https://softwareengineering.stackexchange.com/questions/180216/does-auto-make-c-code-harder-to-understand
> - unreadable gibberish is out (lambdas, etc)
> - C-style malloc()/free() is in. C++ new and delete are okey, but "delete[]" confuses me.
> - C-style printf() is in. C++ cout and "<<" gunk provide no way to easily format the output for easy reading.
> 
> K.O.
  436   18 Feb 2008 Jimmy NgaiBug ReportAnalyzer cannot run as Daemon
Hi All,

I'm testing MIDAS SVN rev-4113 on Scientific Linux 5.1 (i386) and the Analyzer 
can't start as Daemon. What I mean "can't" is that it stops running 
immediately without leaving any error messages. However, it can run offline or 
without becoming a Daemon. I have tested with ROOT 5.14e/5.16/5.18 and 
the "Experiment" example coming with MIDAS and this problem always happens. 
Any ideas?

Best Regards,
Jimmy
  485   05 Jun 2008 Jimmy NgaiForumCAEN VME-USE Bridge with MIDAS
Hi All,

Is there any example code for using MIDAS with the CAEN VME-USB Bridge V1718? 
Thanks.

Regards,
Jimmy
  486   07 Jun 2008 Jimmy NgaiForumCAEN VME-USE Bridge with MIDAS
Hi All,

I am testing the libraries provided by CAEN with the sample softwares in the 
bundle CD. The Windows sample program works fine, but I cannot get started with 
the Linux sample program. When I run CAENVMEDemo in Scientific Linux 5.1, it 
gives me a message "Error opening the device". I have followed the instructions 
in CAENVMElibReadme.txt: 
- compile and load the device driver v1718.ko
- install the library libCAENVME.so

Does anyone have any experience of using V1718 in Scientific Linux? Thanks.

Regards,
Jimmy


> Hi All,
> 
> Is there any example code for using MIDAS with the CAEN VME-USB Bridge V1718? 
> Thanks.
> 
> Regards,
> Jimmy
  493   01 Jul 2008 Jimmy NgaiForumCAEN V792N QDC with MIDAS
Dear All,

I have a problem when testing the V792N 16 CH QDC with the V1718 VME-USB 
Bridge on Scientific Linux 5.1 i386 (kernel 2.6.18-53.1.21.e15).

The problem is that the V792N does not response normally after a few minutes 
of continuous polling and readout of data. It seems like the V792N is hanged 
and a hardware reset of the VME system is required to bring it working again. 
If I do not poll for DREADY first and directly read the Output Buffer 
continuously, the system can work properly.

I have worked on this problem many days but I cannot find any clues to solve 
it. I have tried to use the CAENVMEDemo program (with some modifications) to 
do the same thing (polling and readout) and it works fine. CAEN technical 
support also doesn't know why the VME system is hanged. I think it might be a 
problem of MIDAS itself. I have tried with MIDAS revision 4132 and the trunk 
version, but the problem is still there. Is there any parameter in MIDAS 
(buffer size etc?) which may cause this problem? I have attached my frontend 
code and drivers for your reference.

Thank you for your kind attention.

Best Regards,
Jimmy
Attachment 1: frontend.c
/********************************************************************\

  Name:         frontend.c
  Created by:   Stefan Ritt
  Modified by:  Jimmy Ngai

  Date:         July 1, 2008

  Contents:     Experiment specific readout code (user part) of
                Midas frontend. This example simulates a "trigger
                event" which are filled with VME data. The trigger
                event is filled with two banks(ADC0 and TDC0).

  $Id: frontend.c 4089 2007-11-27 07:28:17Z ritt@PSI.CH $

\********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include "midas.h"
#include "mvmestd.h"
#include "experim.h"

#define HAVE_V792N

/* make frontend functions callable from the C framework */
#ifdef __cplusplus
extern "C" {
#endif

#ifdef HAVE_V792N
#include "vme/v792n.h"
#endif

/*-- Globals -------------------------------------------------------*/

/* The frontend name (client name) as seen by other MIDAS clients   */
char *frontend_name = "Sample Frontend";
/* The frontend file name, don't change it */
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 = 3000;

/* maximum event size produced by this frontend */
INT max_event_size = 10000;

/* 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 = 100 * 10000;

/* Hardware */
MVME_INTERFACE *myvme;

/* VME base address */
DWORD V792N_BASE = 0x32100000;

/* number of channels */
#define N_ADC      16

/*-- Function declarations -----------------------------------------*/

INT frontend_init();
INT frontend_exit();
INT begin_of_run(INT run_number, char *error);
INT end_of_run(INT run_number, char *error);
INT pause_run(INT run_number, char *error);
INT resume_run(INT run_number, char *error);
INT frontend_loop();

INT read_trigger_event(char *pevent, INT off);
INT read_scaler_event(char *pevent, INT off);

/*-- Equipment list ------------------------------------------------*/

EQUIPMENT equipment[] = {

   {"Trigger",               /* equipment name */
    {1, 0,                   /* event ID, trigger mask */
     "SYSTEM",               /* event buffer */
     EQ_POLLED,              /* equipment type */
     LAM_SOURCE(0, 0xFFFFFF),        /* event source crate 0, all stations */
     "MIDAS",                /* format */
     TRUE,                   /* enabled */
     RO_RUNNING,             /* read only when running */
     500,                    /* poll for 500ms */
     0,                      /* stop run after this event limit */
     0,                      /* number of sub events */
     0,                      /* don't log history */
     "", "", "",},
    read_trigger_event,      /* readout routine */
    },

   {""}
};

#ifdef __cplusplus
}
#endif

/********************************************************************\
              Callback routines for system transitions

  These routines are called whenever a system transition like start/
  stop of a run occurs. The routines are called on the following
  occations:

  frontend_init:  When the frontend program is started. This routine
                  should initialize the hardware.

  frontend_exit:  When the frontend program is shut down. Can be used
                  to releas any locked resources like memory, commu-
                  nications ports etc.

  begin_of_run:   When a new run is started. Clear scalers, open
                  rungates, etc.

  end_of_run:     Called on a request to stop a run. Can send
                  end-of-run event and close run gates.

  pause_run:      When a run is paused. Should disable trigger events.

  resume_run:     When a run is resumed. Should enable trigger events.
\********************************************************************/

INT init_vme_modules()
{
#ifdef HAVE_V792N
   v792n_SoftReset(myvme, V792N_BASE);
   v792n_Setup(myvme, V792N_BASE, 3);
//   v792n_Status(myvme, V792N_BASE);
#endif

   return SUCCESS;
}

/*-- Frontend Init -------------------------------------------------*/

INT frontend_init()
{
   int status;

   /* hardware initialization */

   // Open VME interface
   status = mvme_open(&myvme, 0);

   // Set am to A32 non-privileged Data
   mvme_set_am(myvme, MVME_AM_A32_ND);

   // Initialize all VME modules
   init_vme_modules();

   v792n_OfflineSet(myvme, V792N_BASE);
   v792n_DataClear(myvme, V792N_BASE);

   /* print message and return FE_ERR_HW if frontend should not be started */
   if (status != MVME_SUCCESS) {
      cm_msg(MERROR, "frontend_init", "VME interface could not be opened.");
//      return FE_ERR_HW;
   }

   return SUCCESS;
}

/*-- Frontend Exit -------------------------------------------------*/

INT frontend_exit()
{
   // Close VME interface
   mvme_close(myvme);

   return SUCCESS;
}

/*-- Begin of Run --------------------------------------------------*/

INT begin_of_run(INT run_number, char *error)
{
   // Initialize all VME modules
   init_vme_modules();

   v792n_OnlineSet(myvme, V792N_BASE);

   return SUCCESS;
}

/*-- End of Run ----------------------------------------------------*/

INT end_of_run(INT run_number, char *error)
{
   v792n_OfflineSet(myvme, V792N_BASE);
   v792n_DataClear(myvme, V792N_BASE);

   return SUCCESS;
}

/*-- Pause Run -----------------------------------------------------*/

INT pause_run(INT run_number, char *error)
{
   v792n_OfflineSet(myvme, V792N_BASE);

   return SUCCESS;
}

/*-- Resuem Run ----------------------------------------------------*/

INT resume_run(INT run_number, char *error)
{
   v792n_OnlineSet(myvme, V792N_BASE);

   return SUCCESS;
}

/*-- Frontend Loop -------------------------------------------------*/

INT frontend_loop()
{
   /* if frontend_call_loop is true, this routine gets called when
      the frontend is idle or once between every event */
   return SUCCESS;
}

/*------------------------------------------------------------------*/

/********************************************************************\

  Readout routines for different events

\********************************************************************/

/*-- Trigger event routines ----------------------------------------*/

INT poll_event(INT source, INT count, BOOL test)
/* Polling routine for events. Returns TRUE if event
   is available. If test equals TRUE, don't return. The test
   flag is used to time the polling */
{
   int i;
   DWORD lam;

   for (i = 0; i < count; i++) {
      lam = v792n_DataReady(myvme, V792N_BASE);
      if (lam)
         if (!test)
            return TRUE;
   }

   return FALSE;
}

/*-- Interrupt configuration ---------------------------------------*/

INT interrupt_configure(INT cmd, INT source, POINTER_T adr)
{
   switch (cmd) {
   case CMD_INTERRUPT_ENABLE:
      break;
   case CMD_INTERRUPT_DISABLE:
      break;
   case CMD_INTERRUPT_ATTACH:
      break;
   case CMD_INTERRUPT_DETACH:
      break;
   }
   return SUCCESS;
}

/*-- Event readout -------------------------------------------------*/

#ifdef HAVE_V792N
INT read_v792n(INT base, const char *bk_name, char *pevent, INT n_chn)
{
   INT i;
   INT nentry = 0, counter;
   DWORD data[V792N_MAX_CHANNELS+2];
   WORD *pdata;

   // Event counter
//   v792n_EvtCntRead(myvme, base, &counter);

   // Read event
   v792n_EventRead(myvme, base, data, &nentry);

   // Clear ADC
//   v792n_DataClear(myvme, base);

   // Create ADC bank
   bk_create(pevent, bk_name, TID_WORD, &pdata);

   for (i = 0; i < n_chn; i++)
      pdata[i] = 0;

   for (i = 0; i < nentry; i++) {
... 27 more lines ...
Attachment 2: v1718.c
/********************************************************************

  Name:         v1718.c
  Created by:   Jimmy Ngai

  Contents:     Midas VME standard (MVMESTD) layer for CAEN V1718
                VME-USB2.0 Bridge using CAENVMElib Linux library

  Based on sis3100.c by Stefan Ritt

  $Id: $

\********************************************************************/

#ifdef __linux__
#ifndef OS_LINUX
#define OS_LINUX
#endif
#endif

#ifdef OS_LINUX

#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>

#include "CAENVMElib.h"

#endif // OS_LINUX

#include "mvmestd.h"

/*------------------------------------------------------------------*/

int mvme_open(MVME_INTERFACE **vme, int idx)
{
   *vme = (MVME_INTERFACE *) malloc(sizeof(MVME_INTERFACE));
   if (*vme == NULL)
      return MVME_NO_MEM;

   memset(*vme, 0, sizeof(MVME_INTERFACE));

   /* open VME */
   if (CAENVME_Init(cvV1718, 0, idx, &(*vme)->handle) != cvSuccess)
      return MVME_NO_INTERFACE;

   /* default values */
   (*vme)->am        = MVME_AM_DEFAULT;
   (*vme)->dmode     = MVME_DMODE_D32;
   (*vme)->blt_mode  = MVME_BLT_NONE;
   (*vme)->table     = NULL; // not used

   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_close(MVME_INTERFACE *vme)
{
   CAENVME_End(vme->handle);

   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_sysreset(MVME_INTERFACE *vme)
{
   CAENVME_SystemReset(vme->handle);

   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_write(MVME_INTERFACE *vme, mvme_addr_t vme_addr, void *src, mvme_size_t n_bytes)
{
   mvme_size_t n;
   DWORD data;
   int status=0;
   int hvme;
   hvme = vme->handle;

   if (n_bytes <= 4) {
      data = n = 0;
      memcpy(&data, src, n_bytes);

      /* D8 */
      if (vme->dmode == MVME_DMODE_D8)
         status = CAENVME_WriteCycle(hvme, vme_addr, &data, vme->am, cvD8);
      /* D16 */
      else if (vme->dmode == MVME_DMODE_D16)
         status = CAENVME_WriteCycle(hvme, vme_addr, &data, vme->am, cvD16);
      /* D32 */
      else if (vme->dmode == MVME_DMODE_D32)
         status = CAENVME_WriteCycle(hvme, vme_addr, &data, vme->am, cvD32);
      
      if (status == cvSuccess)
         n = n_bytes;
      else
         n = 0;
   } else {

      /* D32 BLT */
      if (vme->blt_mode == MVME_BLT_BLT32)
         status |= CAENVME_BLTWriteCycle(hvme, vme_addr, src, n_bytes, vme->am, cvD32, &n);
      /* D64 MBLT */
      else if (vme->blt_mode == MVME_BLT_MBLT64)
         status |= CAENVME_MBLTWriteCycle(hvme, vme_addr, src, n_bytes, vme->am, &n);

      if (status != cvSuccess)
         n = 0;
   }

   return n;
}

/*------------------------------------------------------------------*/

int mvme_write_value(MVME_INTERFACE *vme, mvme_addr_t vme_addr, unsigned int value)
{
   mvme_size_t n;
   int status=0;
   int hvme;
   hvme = vme->handle;

   if (vme->dmode == MVME_DMODE_D8)
      n = 1;
   else if (vme->dmode == MVME_DMODE_D16)
      n = 2;
   else
      n = 4;

   /* D8 */
   if (vme->dmode == MVME_DMODE_D8)
      status = CAENVME_WriteCycle(hvme, vme_addr, &value, vme->am, cvD8);
   /* D16 */
   else if (vme->dmode == MVME_DMODE_D16)
      status = CAENVME_WriteCycle(hvme, vme_addr, &value, vme->am, cvD16);
   /* D32 */
   else if (vme->dmode == MVME_DMODE_D32)
      status = CAENVME_WriteCycle(hvme, vme_addr, &value, vme->am, cvD32);

   if (status != cvSuccess)
      n = 0;

   return n;
}

/*------------------------------------------------------------------*/

int mvme_read(MVME_INTERFACE *vme, void *dst, mvme_addr_t vme_addr, mvme_size_t n_bytes)
{
   mvme_size_t i, n;
   DWORD data;
   int status=0, cfifo;
   int hvme;
   hvme = vme->handle;

   if (n_bytes <= 4) {
      data = 0;

      /* D8 */
      if (vme->dmode == MVME_DMODE_D8)
         status = CAENVME_ReadCycle(hvme, vme_addr, &data, vme->am, cvD8);
      /* D16 */
      else if (vme->dmode == MVME_DMODE_D16)
         status = CAENVME_ReadCycle(hvme, vme_addr, &data, vme->am, cvD16);
      /* D32 */
      else if (vme->dmode == MVME_DMODE_D32)
         status = CAENVME_ReadCycle(hvme, vme_addr, &data, vme->am, cvD32);
      
      memcpy(dst, &data, n_bytes);
      if (status == cvSuccess)
         n = n_bytes;
      else
         n = 0;

   } else {

      n = 0;

      /* normal I/O */
      if (vme->blt_mode == MVME_BLT_NONE) {
         for (i=0 ; i<n_bytes ; i++)
            status = CAENVME_ReadCycle(hvme, vme_addr, dst+i, vme->am, cvD8);
         n = n_bytes;
      /* D32 BLT */
      } else if (vme->blt_mode == MVME_BLT_BLT32)
         status |= CAENVME_BLTReadCycle(hvme, vme_addr, dst, n_bytes, vme->am, cvD32, &n);
      /* D32 FIFO BLT */
      else if (vme->blt_mode == MVME_BLT_BLT32FIFO) {
         CAENVME_GetFIFOMode(hvme, &cfifo);
         status = CAENVME_SetFIFOMode(hvme, 1);
         status |= CAENVME_BLTReadCycle(hvme, vme_addr, dst, n_bytes, vme->am, cvD32, &n);
         CAENVME_SetFIFOMode(hvme, cfifo);
      /* D64 MBLT */
      } else if (vme->blt_mode == MVME_BLT_MBLT64)
         status |= CAENVME_MBLTReadCycle(hvme, vme_addr, dst, n_bytes, vme->am, &n);
      /* D64 FIFO MBLT */
      else if (vme->blt_mode == MVME_BLT_MBLT64FIFO) {
         CAENVME_GetFIFOMode(hvme, &cfifo);
         status = CAENVME_SetFIFOMode(hvme, 1);
         status |= CAENVME_MBLTReadCycle(hvme, vme_addr, dst, n_bytes, vme->am, &n);
         CAENVME_SetFIFOMode(hvme, cfifo);
      }

      if (status != cvSuccess)
         n = 0;
   }

   return n;
}

/*------------------------------------------------------------------*/

unsigned int mvme_read_value(MVME_INTERFACE *vme, mvme_addr_t vme_addr)
{
   unsigned int data;
   int status=0;
   int hvme;
   hvme = vme->handle;

   data = 0;

   /* D8 */
   if (vme->dmode == MVME_DMODE_D8)
      status = CAENVME_ReadCycle(hvme, vme_addr, &data, vme->am, cvD8);
   /* D16 */
   else if (vme->dmode == MVME_DMODE_D16)
      status = CAENVME_ReadCycle(hvme, vme_addr, &data, vme->am, cvD16);
   /* D32 */
   else if (vme->dmode == MVME_DMODE_D32)
      status = CAENVME_ReadCycle(hvme, vme_addr, &data, vme->am, cvD32);

   return data;
}

/*------------------------------------------------------------------*/

int mvme_set_am(MVME_INTERFACE *vme, int am)
{
   vme->am = am;
   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_get_am(MVME_INTERFACE *vme, int *am)
{
   *am = vme->am;
   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_set_dmode(MVME_INTERFACE *vme, int dmode)
{
   vme->dmode = dmode;
   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_get_dmode(MVME_INTERFACE *vme, int *dmode)
{
   *dmode = vme->dmode;
   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_set_blt(MVME_INTERFACE *vme, int mode)
{
   vme->blt_mode = mode;
   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_get_blt(MVME_INTERFACE *vme, int *mode)
{
   *mode = vme->blt_mode;
   return MVME_SUCCESS;
}
Attachment 3: v792n.h
/*********************************************************************

  Name:         v792n.h
  Created by:   Jimmy Ngai

  Contents:     V792N 16ch. QDC include

  Based on v792.h by Pierre-Andre Amaudruz

  $Id: $
*********************************************************************/
#ifndef  V792N_INCLUDE_H
#define  V792N_INCLUDE_H

#include <stdio.h>
#include <string.h>
#include "mvmestd.h"

#ifdef __cplusplus
extern "C" {
#endif

#define  V792N_MAX_CHANNELS       (DWORD) 16
#define  V792N_REG_BASE           (DWORD) (0x1000)
#define  V792N_FIRM_REV           (DWORD) (0x1000)
#define  V792N_GEO_ADDR_RW        (DWORD) (0x1002)
#define  V792N_MCST_CBLT_RW       (DWORD) (0x1004)
#define  V792N_BIT_SET1_RW        (DWORD) (0x1006)
#define  V792N_BIT_CLEAR1_WO      (DWORD) (0x1008)
#define  V792N_SOFT_RESET         (DWORD) (0x1<<7)
#define  V792N_INT_LEVEL_WO       (DWORD) (0x100A)
#define  V792N_INT_VECTOR_WO      (DWORD) (0x100C)
#define  V792N_CSR1_RO            (DWORD) (0x100E)
#define  V792N_CR1_RW             (DWORD) (0x1010)
#define  V792N_ADER_H_RW          (DWORD) (0x1012)
#define  V792N_ADER_L_RW          (DWORD) (0x1014)
#define  V792N_SINGLE_RST_WO      (DWORD) (0x1016)
#define  V792N_MCST_CBLT_CTRL_RW  (DWORD) (0x101A)
#define  V792N_EVTRIG_REG_RW      (DWORD) (0x1020)
#define  V792N_CSR2_RO            (DWORD) (0x1022)
#define  V792N_EVT_CNT_L_RO       (DWORD) (0x1024)
#define  V792N_EVT_CNT_H_RO       (DWORD) (0x1026)
#define  V792N_INCR_EVT_WO        (DWORD) (0x1028)
#define  V792N_INCR_OFFSET_WO     (DWORD) (0x102A)
#define  V792N_LD_TEST_RW         (DWORD) (0x102C)
#define  V792N_DELAY_CLEAR_RW     (DWORD) (0x102E)
#define  V792N_FCLR_WIN_RW        (DWORD) (0x102E)
#define  V792N_BIT_SET2_RW        (DWORD) (0x1032)
#define  V792N_BIT_CLEAR2_WO      (DWORD) (0x1034)
#define  V792N_W_MEM_TEST_WO      (DWORD) (0x1036)
#define  V792N_MEM_TEST_WORD_H_WO (DWORD) (0x1038)
#define  V792N_MEM_TEST_WORD_L_WO (DWORD) (0x103A)
#define  V792N_CRATE_SEL_RW       (DWORD) (0x103C)
#define  V792N_TEST_EVENT_WO      (DWORD) (0x103E)
#define  V792N_EVT_CNT_RST_WO     (DWORD) (0x1040)
#define  V792N_IPED_RW            (DWORD) (0x1060)
#define  V792N_R_MEM_TEST_WO      (DWORD) (0x1064)
#define  V792N_SWCOMM_WO          (DWORD) (0x1068)
#define  V792N_SLIDECONST_RW      (DWORD) (0x106A)
#define  V792N_AAD_RO             (DWORD) (0x1070)
#define  V792N_BAD_RO             (DWORD) (0x1072)
#define  V792N_THRES_BASE         (DWORD) (0x1080)

WORD v792n_Read16(MVME_INTERFACE *mvme, DWORD base, int offset);
void v792n_Write16(MVME_INTERFACE *mvme, DWORD base, int offset, WORD value);
DWORD v792n_Read32(MVME_INTERFACE *mvme, DWORD base, int offset);
void v792n_Write32(MVME_INTERFACE *mvme, DWORD base, int offset, DWORD value);

int  v792n_DataReady(MVME_INTERFACE *mvme, DWORD base);
int  v792n_isEvtReady(MVME_INTERFACE *mvme, DWORD base);
int  v792n_isBusy(MVME_INTERFACE *mvme, DWORD base);
int  v792n_EventRead(MVME_INTERFACE *mvme, DWORD base, DWORD *pdest, int *nentry);
int  v792n_DataRead(MVME_INTERFACE *mvme, DWORD base, DWORD *pdest, int *nentry);
void v792n_DataClear(MVME_INTERFACE *mvme, DWORD base);
void v792n_EvtCntRead(MVME_INTERFACE *mvme, DWORD base, DWORD *evtcnt);
void v792n_EvtCntReset(MVME_INTERFACE *mvme, DWORD base);
void v792n_IntSet(MVME_INTERFACE *mvme, DWORD base, int level, int vector);
void v792n_IntEnable(MVME_INTERFACE *mvme, DWORD base, int level);
void v792n_IntDisable(MVME_INTERFACE *mvme, DWORD base);
void v792n_EvtTriggerSet(MVME_INTERFACE *mvme, DWORD base, int count);
void v792n_SingleShotReset(MVME_INTERFACE *mvme, DWORD base);
void v792n_SoftReset(MVME_INTERFACE *mvme, DWORD base);
void v792n_Trigger(MVME_INTERFACE *mvme, DWORD base);
int  v792n_ThresholdRead(MVME_INTERFACE *mvme, DWORD base, WORD *threshold);
int  v792n_ThresholdWrite(MVME_INTERFACE *mvme, DWORD base, WORD *threshold);
int  v792n_CSR1Read(MVME_INTERFACE *mvme, DWORD base);
int  v792n_CSR2Read(MVME_INTERFACE *mvme, DWORD base);
int  v792n_BitSet2Read(MVME_INTERFACE *mvme, DWORD base);
void v792n_BitSet2Set(MVME_INTERFACE *mvme, DWORD base, WORD pat);
void v792n_BitSet2Clear(MVME_INTERFACE *mvme, DWORD base, WORD pat);
WORD v792n_ControlRegister1Read(MVME_INTERFACE *mvme, DWORD base);
void v792n_ControlRegister1Write(MVME_INTERFACE *mvme, DWORD base, WORD pat);
void v792n_OnlineSet(MVME_INTERFACE *mvme, DWORD base);
void v792n_OfflineSet(MVME_INTERFACE *mvme, DWORD base);
void v792n_BlkEndEnable(MVME_INTERFACE *mvme, DWORD base);
void v792n_OverRangeEnable(MVME_INTERFACE *mvme, DWORD base);
void v792n_OverRangeDisable(MVME_INTERFACE *mvme, DWORD base);
void v792n_LowThEnable(MVME_INTERFACE *mvme, DWORD base);
void v792n_LowThDisable(MVME_INTERFACE *mvme, DWORD base);
void v792n_EmptyEnable(MVME_INTERFACE *mvme, DWORD base);
void v792n_CrateSet(MVME_INTERFACE *mvme, DWORD base, DWORD *evtcnt);
void v792n_DelayClearSet(MVME_INTERFACE *mvme, DWORD base, int delay);
int  v792n_Setup(MVME_INTERFACE *mvme, DWORD base, int mode);
void v792n_Status(MVME_INTERFACE *mvme, DWORD base);
int  v792n_isPresent(MVME_INTERFACE *mvme, DWORD base);

  enum v792n_DataType {
    v792n_typeMeasurement=0,
    v792n_typeHeader     =2,
    v792n_typeFooter     =4,
    v792n_typeFiller     =6
  };

  typedef union {
    DWORD raw;
    struct v792n_Entry {
      unsigned adc:12; // bit0 here
      unsigned ov:1;
      unsigned un:1;
      unsigned _pad_1:3;
      unsigned channel:4;
      unsigned _pad_2:3;
      unsigned type:3;
      unsigned geo:5;
    } data ;
    struct v792n_Header {
      unsigned _pad_1:8; // bit0 here
      unsigned cnt:6;
      unsigned _pad_2:2;
      unsigned crate:8;
      unsigned type:3;
      unsigned geo:5;
    } header;
    struct v792n_Footer {
      unsigned evtCnt:24; // bit0 here
      unsigned type:3;
      unsigned geo:5;
    } footer;
  } v792n_Data;

  typedef union {
    DWORD raw;
    struct {
      unsigned DataReady:1; // bit0 here
      unsigned GlobalDataReady:1;
      unsigned Busy:1;
      unsigned GlobalBusy:1;
      unsigned Amnesia:1;
      unsigned Purge:1;
      unsigned TermOn:1;
      unsigned TermOff:1;
      unsigned EventReady:1; //bit 8 here
    };
  } v792n_StatusRegister1;
  typedef union {
    DWORD raw;
    struct {
      unsigned _pad_1:1; // bit0 here
      unsigned BufferEmpty:1;
      unsigned BufferFull:1;
      unsigned _pad_2:1;
      unsigned PB:4;
      //unsigned DSEL0:1;
      //unsigned DSEL1:1;
      //unsigned CSEL0:1;
      //unsigned CSEL1:1;
    };
  } v792n_StatusRegister2;
  typedef union {
    DWORD raw;
    struct {
      unsigned _pad_1:2;
      unsigned BlkEnd:1;
      unsigned _pad_2:1;
      unsigned ProgReset:1;
      unsigned BErr:1;
      unsigned Align64:1;
    };
  } v792n_ControlRegister1;
  typedef union {
    DWORD raw;
    struct {
      unsigned MemTest:1;
      unsigned OffLine:1;
      unsigned ClearData:1;
      unsigned OverRange:1;
      unsigned LowThresh:1;
      unsigned _pad_1:1;//bit5
      unsigned TestAcq:1;
      unsigned SLDEnable:1;
      unsigned StepTH:1;
      unsigned _pad_2:2;//bits 9-10
      unsigned AutoIncr:1;
      unsigned EmptyProg:1;
      unsigned SlideSubEnable:1;
      unsigned AllTrg:1;
    };
  } v792n_BitSet2Register;

  void v792n_printEntry(const v792n_Data* v);

#ifdef __cplusplus
}
#endif

#endif // V792N_INCLUDE_H

/* emacs
 * Local Variables:
 * mode:C
 * mode:font-lock
 * tab-width: 8
 * c-basic-offset: 2
 * End:
 */
Attachment 4: v792n.c
/*********************************************************************

  Name:         v792n.c
  Created by:   Jimmy Ngai

  Contents:     V792N 16ch. QDC

  Based on v792.c by Pierre-Andre Amaudruz
                
  $Id: $
*********************************************************************/
#include <stdio.h>
#include <string.h>
#include <signal.h>
#if defined(OS_LINUX)
#include <unistd.h>
#endif
#include "v792n.h"

WORD v792n_Read16(MVME_INTERFACE *mvme, DWORD base, int offset)
{
  int cmode;
  WORD data;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  data = mvme_read_value(mvme, base+offset);
  mvme_set_dmode(mvme, cmode);
  return data;
}

void v792n_Write16(MVME_INTERFACE *mvme, DWORD base, int offset, WORD value)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+offset, value);
  mvme_set_dmode(mvme, cmode);
}

DWORD v792n_Read32(MVME_INTERFACE *mvme, DWORD base, int offset)
{
  int cmode;
  DWORD data;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D32);
  data = mvme_read_value(mvme, base+offset);
  mvme_set_dmode(mvme, cmode);
  return data;
}

void v792n_Write32(MVME_INTERFACE *mvme, DWORD base, int offset, DWORD value)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D32);
  mvme_write_value(mvme, base+offset, value);
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
int v792n_DataReady(MVME_INTERFACE *mvme, DWORD base)
{
  int data_ready, cmode;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  data_ready = mvme_read_value(mvme, base+V792N_CSR1_RO) & 0x1;
  mvme_set_dmode(mvme, cmode);
  return data_ready;
}

/*****************************************************************/
int v792n_isEvtReady(MVME_INTERFACE *mvme, DWORD base)
{
  int csr;
  csr = v792n_CSR1Read(mvme, base);
  return (csr & 0x100);
}

/*****************************************************************/
int v792n_isBusy(MVME_INTERFACE *mvme, DWORD base)
{
  int status, busy, timeout, cmode;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  timeout = 1000;
  do {
    status = mvme_read_value(mvme, base+V792N_CSR1_RO);
    busy = status & 0x4;
    timeout--;
  } while (busy || timeout);
  mvme_set_dmode(mvme, cmode);
  return (busy != 0 ? 1 : 0);
}

/*****************************************************************/
/*
Read single event, return event length (number of entries)
Uses single vme access! (1us/D32)
*/
int v792n_EventRead(MVME_INTERFACE *mvme, DWORD base, DWORD *pdest, int *nentry)
{
#define USE_BLT_READ_2

#ifdef USE_SINGLE_READ
  DWORD hdata;
  int   cmode;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D32);

  *nentry = 0;
  if (v792n_DataReady(mvme, base)) {
    do {
      hdata = mvme_read_value(mvme, base);
    } while (!(hdata & 0x02000000)); // skip up to the header

    pdest[*nentry] = hdata;
    *nentry += 1;
    do {
      pdest[*nentry] = mvme_read_value(mvme, base);
      *nentry += 1;
    } while (!(pdest[*nentry-1] & 0x04000000)); // copy until the trailer

    nentry--;
  }

  mvme_set_dmode(mvme, cmode);
#endif // USE_SINGLE_READ

#ifdef USE_BLT_READ_1
  DWORD hdata, data[V792N_MAX_CHANNELS+2];
  int   cam, cmode, cnt, i;

  mvme_get_am(mvme, &cam);
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D32);

  *nentry = 0;
  if (v792n_DataReady(mvme, base)) {
    do {
      hdata = mvme_read_value(mvme, base);
    } while (!(hdata & 0x02000000)); // skip up to the header

    mvme_set_am(mvme, MVME_AM_A32_NB);
    mvme->blt_mode = MVME_BLT_BLT32;
    cnt = (hdata >> 8) & 0x3F;

    mvme_read(mvme, data, base, (cnt+1)*4);
    pdest[0] = hdata;
    for (i=1;i<=cnt+1;i++)
      pdest[i] = data[i-1];

    *nentry = cnt + 2;
  }

  mvme_set_am(mvme, cam);
  mvme_set_dmode(mvme, cmode);
#endif // USE_BLT_READ_1

#ifdef USE_BLT_READ_2
  DWORD hdata;
  int   cam, cmode, cnt;

  mvme_get_am(mvme, &cam);
  mvme_get_dmode(mvme, &cmode);

  *nentry = 0;
//  if (v792n_DataReady(mvme, base)) {
    mvme_set_am(mvme, MVME_AM_A32_NB);
    mvme->blt_mode = MVME_BLT_BLT32;
    mvme_read(mvme, pdest, base, (V792N_MAX_CHANNELS+2)*4);
    cnt = (pdest[0] >> 8) & 0x3F;
    *nentry = cnt + 2;
//  }

  mvme_set_am(mvme, cam);
  mvme_set_dmode(mvme, cmode);
#endif //USE_BLT_READ_2

  return *nentry;
}

/*****************************************************************/
/*
Read nentry of data from the data buffer. Will use the DMA engine
if size is larger than 127 bytes.
*/
int v792n_DataRead(MVME_INTERFACE *mvme, DWORD base, DWORD *pdest, int *nentry)
{
  int  cmode;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D32);
//  *nentry = 128;
  if (v792n_DataReady(mvme, base)) {
    mvme_read(mvme, pdest, base, *nentry*4);
  }
  mvme_set_dmode(mvme, cmode);
  return *nentry;
}

/*****************************************************************/
void v792n_DataClear(MVME_INTERFACE *mvme, DWORD base)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_BIT_SET2_RW, 0x4);
  mvme_write_value(mvme, base+V792N_BIT_CLEAR2_WO, 0x4);
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_EvtCntRead(MVME_INTERFACE *mvme, DWORD base, DWORD *evtcnt)
{
  int cmode;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  *evtcnt  = mvme_read_value(mvme, base+V792N_EVT_CNT_L_RO);
  *evtcnt += (mvme_read_value(mvme, base+V792N_EVT_CNT_H_RO) << 16);
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_EvtCntReset(MVME_INTERFACE *mvme, DWORD base)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_EVT_CNT_RST_WO, 1);
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_IntSet(MVME_INTERFACE *mvme, DWORD base, int level, int vector)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_INT_VECTOR_WO, (vector & 0xFF));
  mvme_write_value(mvme, base+V792N_INT_LEVEL_WO, (level & 0x7));
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_IntEnable(MVME_INTERFACE *mvme, DWORD base, int level)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_EVTRIG_REG_RW, (level & 0x1F));
  /* Use the trigger buffer for int enable/disable
  mvme_write_value(mvme, base+V792N_INT_LEVEL_WO, (level & 0x7));
  */
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_IntDisable(MVME_INTERFACE *mvme, DWORD base)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_EVTRIG_REG_RW, 0);
  /* Use the trigger buffer for int enable/disable
     Setting a level 0 reboot the VMIC !
  mvme_write_value(mvme, base+V792N_INT_LEVEL_WO, 0);
  */
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_EvtTriggerSet(MVME_INTERFACE *mvme, DWORD base, int count)
{
  int cmode;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_EVTRIG_REG_RW, (count & 0x1F));
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_SingleShotReset(MVME_INTERFACE *mvme, DWORD base)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_SINGLE_RST_WO, 1);
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_SoftReset(MVME_INTERFACE *mvme, DWORD base)
{
... 407 more lines ...
  528   20 Nov 2008 Jimmy NgaiInfoRecommended platform for running MIDAS
Dear All,

Is there any recommended platforms for running MIDAS? Have anyone encountered 
problems when running MIDAS on Scientific Linux?

Thanks.

Jimmy
  530   26 Nov 2008 Jimmy NgaiInfoSend email alert in alarm system
Dear All,

We have a temperature/humidity sensor in MIDAS now and will add a liquid level 
sensor to MIDAS soon. We want the operators to get alerted ASAP when the 
laboratory environment or the liquid level reached some critical levels. Can 
MIDAS send email alerts or SMS alerts to cell phones when the alarms are 
triggered? If yes, how can I config it?

Many thanks!

Best Regards,
Jimmy
  541   12 Dec 2008 Jimmy NgaiInfoCustom page which executes custom function
Dear All,

How can I add a button at the top of the "Status" webpage which will show a 
page similar to the "CNAF" one after I click on it? and how can I make a 
custom page similar to "CNAF" which allow me to call some custom funtions? I 
want to make a page which is particularly for doing calibration.

Thank you for your attention!

Best Regards,
Jimmy Ngai
  565   17 Apr 2009 Jimmy NgaiForumMIDAS mhttpd custom page questions
Dear All,

I have created a custom page (please see the attachment) and imported into 
MIDAS with key name "Control panel&" (without the ""). I have the following 
two questions:

1) I display the status of the run with <odb src="/Runinfo/State">, but it 
returns numbers which is not user friendly. How can I make something 
like "Running" with green background and "Stopped" with red background in the 
default status page?

2) When I click either Start/Stop/Pause/Resume, it can performs the right 
things, but afterward it jumps to the page "http://domain.name:8081/CS/" which 
shows "Invalid custom page: NULL path". How can I make it returns to the 
correct page "http://domain.name:8081/CS/Control%20panel"?

Thank you for your attention.

Best Regards,
Jimmy
Attachment 1: control_panel.html
  566   20 Apr 2009 Jimmy NgaiForumMIDAS mhttpd custom page questions
Dear All,

I have one more question. I use <odb src="odb field" edit=1> to display an 
editable ODB value, but how can I show this value in hexadecimal?

Thanks.

Best Regards,
Jimmy


> Dear All,
> 
> I have created a custom page (please see the attachment) and imported into 
> MIDAS with key name "Control panel&" (without the ""). I have the following 
> two questions:
> 
> 1) I display the status of the run with <odb src="/Runinfo/State">, but it 
> returns numbers which is not user friendly. How can I make something 
> like "Running" with green background and "Stopped" with red background in the 
> default status page?
> 
> 2) When I click either Start/Stop/Pause/Resume, it can performs the right 
> things, but afterward it jumps to the page "http://domain.name:8081/CS/" which 
> shows "Invalid custom page: NULL path". How can I make it returns to the 
> correct page "http://domain.name:8081/CS/Control%20panel"?
> 
> Thank you for your attention.
> 
> Best Regards,
> Jimmy
  594   15 Jun 2009 Jimmy NgaiForumTime limit of each run
Dear All,

Can one set a time limit for each run? I can only find event limit in ODB. 
Thanks.

Jimmy
  624   01 Sep 2009 Jimmy NgaiForumTimeout during run transition
Dear All,

I'm using SL5 and MIDAS rev 4528. Occasionally, when I stop a run in odbedit, 
a timeout would occur: 
[midas.c:9496:rpc_client_call,ERROR] rpc timeout after 121 sec, routine 
= "rc_transition", host = "computerB", connection closed
Error: Unknown error 504 from client 'Frontend' on host computerB

This error seems to be random without any reason or pattern. After this error 
occurs, I cannot start or stop any run. Sometime restarting MIDAS can bring 
the system working again, but sometime not.

Another transition timeout occurs after I change any ODB value using the web 
interface:
[midas.c:8291:rpc_client_connect,ERROR] timeout on receive remote computer 
info: 
[midas.c:3642:cm_transition,ERROR] cannot connect to client "Frontend" on host 
computerB, port 36255, status 503
Error: Cannot connect to client 'Frontend'

This error is reproducible: start run -> change ODB value within webpage -> 
stop run -> timeout!

Any idea?

Thanks,
Jimmy
  642   09 Sep 2009 Jimmy NgaiForumRetrieve start/stop time in offline
Hi All,

I set "/Analyzer/ODB Load" to true and analyzed a run in offline mode. After
that, I found the start time and stop time in /RunInfo did not reflect the
correct time as in online. How do I retrieve the correct start/stop time from
the ODB in offline mode?

Thanks!

Jimmy
  669   06 Nov 2009 Jimmy NgaiForumRun multiple frontend on the same host
Dear All,

I want to run two frontend programs (one for trigger and one for slow control)
concurrently on the same computer, but I failed. The second frontend said: 

Semaphore already present
 There is another process using the semaphore.
 Or a process using the semaphore exited abnormally.
 In That case try to manually release the semaphore with:
   ipcrm sem XXX.

The two frontends are connected to the same experiment. Is there any way I can
overcome this problem?

Thanks!

Jimmy
  687   07 Dec 2009 Jimmy NgaiForumRun multiple frontend on the same host
Dear Stefan,

Thanks for the reply. I have tried your patch and it didn't solve my problem. Maybe I 
have not written my question clearly. The two frontends could run on the same computer 
if I use the remote method, i.e. by setting up the mserver and connect to the 
experiment by specifying "-h localhost", also the frontend programs need to be put in 
different directory. What I want to know is whether I can simply start multiple 
frontends in the same directory without setting up the mserver etc. I noticed that 
there are several *.SHM files, I'm not familiar with semaphore, but I guess they are 
the key to the problem. Please correct me if I misunderstood something.

Best Regards,
Jimmy


> > Dear All,
> > 
> > I want to run two frontend programs (one for trigger and one for slow control)
> > concurrently on the same computer, but I failed. The second frontend said: 
> > 
> > Semaphore already present
> >  There is another process using the semaphore.
> >  Or a process using the semaphore exited abnormally.
> >  In That case try to manually release the semaphore with:
> >    ipcrm sem XXX.
> > 
> > The two frontends are connected to the same experiment. Is there any way I can
> > overcome this problem?
> 
> That might be related to the RPC mutex, which gets created system wide now. I 
> modified this in midas.c rev. 4628, so there will be one mutex per process. Can you 
> try that temporary patch and tell me if it works for you?
  689   12 Dec 2009 Jimmy NgaiForumRun multiple frontend on the same host
Dear Stefan,

I followed your suggestion to try the sample front-ends from the distribution and 
they work fine. They also work fine with any one of my front-ends. Only my two 
front-ends cannot run concurrently in the same directory. I later found that the 
problem is in the CAEN HV wrapper library. The problem arises when the front-ends 
are both linked to that library and it is solved now.

Thanks & Best Regards,
Jimmy


> Hi Jimmy,
> 
> ok, now I understand. Well, I don't see your problem. I just tried with the 
> current SVN 
> version to start
> 
> midas/examples/experiment/frontend
> midas/examples/slowcont/scfe
> 
> in the same directory (without "-h localhost") and it works just fine (see 
> attachemnt). I even started them from the same directory. Yes there are *.SHM 
> files and they correspond to shared memory, but both front-ends use this shared 
> memory together (that's why it's called 'shared').
> 
> Your error message 'Semaphore already present' is strange. The string is not 
> contained in any midas program, so it must come from somewhere else. Do you 
> maybe try to access the same hardware with the two front-end programs?
> 
> I would propose you do the following: Use the two front-ends from the 
> distribution (see above). They do not access any hardware. See if you can run 
> them with the current SVN version of midas. If not, report back to me.
> 
> Best regards,
> 
>   Stefan
> 
> 
> > Dear Stefan,
> > 
> > Thanks for the reply. I have tried your patch and it didn't solve my problem. 
> Maybe I 
> > have not written my question clearly. The two frontends could run on the same 
> computer 
> > if I use the remote method, i.e. by setting up the mserver and connect to the 
> > experiment by specifying "-h localhost", also the frontend programs need to be 
> put in 
> > different directory. What I want to know is whether I can simply start 
> multiple 
> > frontends in the same directory without setting up the mserver etc. I noticed 
> that 
> > there are several *.SHM files, I'm not familiar with semaphore, but I guess 
> they are 
> > the key to the problem. Please correct me if I misunderstood something.
> > 
> > Best Regards,
> > Jimmy
> > 
> > 
> > > > Dear All,
> > > > 
> > > > I want to run two frontend programs (one for trigger and one for slow 
> control)
> > > > concurrently on the same computer, but I failed. The second frontend said: 
> > > > 
> > > > Semaphore already present
> > > >  There is another process using the semaphore.
> > > >  Or a process using the semaphore exited abnormally.
> > > >  In That case try to manually release the semaphore with:
> > > >    ipcrm sem XXX.
> > > > 
> > > > The two frontends are connected to the same experiment. Is there any way I 
> can
> > > > overcome this problem?
> > > 
> > > That might be related to the RPC mutex, which gets created system wide now. 
> I 
> > > modified this in midas.c rev. 4628, so there will be one mutex per process. 
> Can you 
> > > try that temporary patch and tell me if it works for you?
  698   22 Apr 2010 Jimmy NgaiForumHow to stop a run with a timer?
Hi Exaos,

This may help: https://ladd00.triumf.ca/elog/Midas/645

You need to set the following keys:
/Logger/Run duration
/Logger/Auto restart
/Logger/Auto restart delay

Regards,
Jimmy


> I want to let the run stop and start periodically. But I looked through the ODB
> and didn't find anything may help. I also checked the FAQ online and didn't find
> answer either. Who can help me? Thank you.
  699   22 Apr 2010 Jimmy NgaiForumCustomized "Start" page
Dear All,

After clicking the "Start" button, there is a page for the operator to change some 
ODB values. I have created "/Experiment/Edit on start" and added some links there. 
If the link is pointed to a boolean type key, a check box will appear in the 
"Start" page, which is great. But how about if I want to have some radio buttons 
or pull-down menus for the operator to select among different calibration sources 
or running modes?

Thanks,

Jimmy
  706   24 Jun 2010 Jimmy NgaiForumError connecting to back-end computer
Dear All,

This is my first time running an experiment on separate computers. I followed 
the documentation (https://midas.psi.ch/htmldoc/quickstart.html) to setup the 
files:
/etc/services
/etc/xinetd.d/midas
/etc/ld.so.conf
/etc/exptab

but when I started the frontend program in the front-end computer I got the 
following error (computerB is my back-end): 

[midas.c:8623:rpc_server_connect,ERROR] mserver subprocess could not be started 
(check path)
[mfe.c:2573:mainFE,ERROR] Cannot connect to experiment '' on host 'computerB', 
status 503

In both front-end and back-end computers only a file '.SYSMSG.SHM' was created 
after the attempt. If I start the frontend program somewhere in the back-end 
computer by connecting to 'localhost', seven .SHM files are created in the 
experiment directory together with a .RPC.SHM in the directory where I run the 
frontend program.

Is that I misconfigure something? I cannot find a solution...

Thanks.

Best Regards,
Jimmy
  708   27 Jun 2010 Jimmy NgaiForumError connecting to back-end computer
> Hi, there. I have not recently run mserver through inetd, and we usually do not do
> that at TRIUMF. We do this:
> 
> a) on the main computer: start mserver: "mserver -p 7070 -D" (note - use non-default
> port - can use different ports for different experiments)
> b) on remote computer: "odbedit -h main:7070" ("main" is the hostname of your main
> computer). Use same "-h" switch for all other programs, including the frontends.
> 
> This works well when all computers are on the same network, but if you have some
> midas clients running on private networks you may get into trouble when they try to
> connect to each other and fail because network routing is funny.

Hi K.O.,

Thanks for your reply. I have tried your way but I got the same error: 

[midas.c:8623:rpc_server_connect,ERROR] mserver subprocess could not be started 
(check path)

My front-end and back-end computers are on the same network connected by a router. I 
have allowed port 7070 in the firewall and done the port forwarding in the router (for 
connecting from outside the network). From the error message it seems that some 
processes can not be started automatically. Could it be related to some security 
settings such as the SELinux?

Best Regards,
Jimmy
ELOG V3.1.4-2e1708b5