Frontend user code
This section describes the features of the user-written part of a Frontend, referred to here as frontend.c. To make a custom frontend, users will usually modify one of the templates provided in the MIDAS package for their particular hardware and other requirements. A partial list of the templates provided is shown below:
|Hardware||Filename||Directory (MIDAS package)||Purpose||Language|
|VME||fevmemodules.c||../midas/examples/Triumf/c/||Access to VME modules||C|
|VME||fevme.cxx||../midas/examples/Triumf/c++/||Access to VME modules||C++|
|CAMAC||frontend.c||../midas/examples/experiment/||Access to CAMAC modules||C|
|RS485 bus||mscb_fe.c||../midas/examples/slowcont/||Slow controls||C|
The features of a typical frontend program are best explained by reference to examples of the user code provided in the Midas Package.
Frontend code sections
The following sections refer to the templates for user frontend code found in the MIDAS packages (see Introduction).
The following example (from template frontend file fevmemodules.c - see Introduction) shows the standard include files needed for VME access with VMIC. The user may add any other include files as needed. In this case, header files for several device drivers have also been added. The optional include file "experim.h" is often included. This is a special include file for ease of communication between the C code and the ODB, and is generated by the user (see experim.h).
#include <stdio.h> // C standard headers #include <stdlib.h> #include "midas.h" // MIDAS include file #include "mvmestd.h" // VME header file #include "vmicvme.h" // VMIC header file #include "vmeio.h" // optional hardware header files #include "v1190B.h" #include "v792.h" #include "vf48.h" #include "v1729.h" #include "experim.h" // user-created with odbedit make command
The following example (from template frontend file fevmemodules.c - see Introduction) shows the global declaration. The declarations are system wide. Some may be changed to suit the user, but none should not be removed.
- This value can be modified to reflect the purpose of the code
- If set to TRUE, the function frontend_loop() runs after every equipment loop. If FALSE, frontend_loop() does not run. The user can add suitable code to this routine if desired (e.g. to check for a condition).
- The time interval (defined in milliseconds) between the refresh of a frontend status display. The value of zero disables the display. If the frontend is started in the background with the display enabled, the stdout should be redirected to the null device to prevent the process from hanging.
- specifies the maximum size (in bytes) of the expected event.
- specifies the maximum size (in bytes) of the buffer to be allocated by the system.
Example global declaration
/* The frontend name (client name) as seen by other MIDAS clients */ char *frontend_name = "fevmemodules"; /* 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 = 000; // /* maximum event size produced by this frontend */ INT max_event_size = 200000; // /* 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 = 10 * 100000;
Global User Declarations
After the global declarations, the user may add his or her own declarations. The following example (from template frontend file fevmemodules.c - see Introduction) defines various VME hardware parameters.
Example hardware declarations
/* Hardware */ MVME_INTERFACE *myvme; // /* VME base addresses */ DWORD VMEIO_BASE = 0x780000; DWORD VTDC0_BASE = 0xF10000; ....... /* Globals */ #define N_ADC 100 #define N_TDC 100 #define N_PTS 5000
System Function Prototypes
These prototypes declare the pre-defined system functions which should be present.
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();
User Function Prototypes
Following the previous group is a second group of prototypes, which define the user functions that run when the defined equipments are triggered. In this example, two equipments will be defined, so there are two prototypes. The user functions will be described in detail in the following sections.
INT read_trigger_event(char *pevent, INT off); INT read_scaler_event(char *pevent, INT off);
If using an interrupt, callback function prototypes are also included
extern void interrupt_routine(void); void register_cnaf_callback(int debug);
Bank Definition and Equipment List
Sequence of Operations in the frontend
The following table shows the sequence of operations of the Frontend System functions. These subroutines must be present in frontend.c, but the contents are coded by the user. These functions are called by mfe.c at the appropriate time. The System Transition functions are associated with a particular Run Transition as shown below:
|System Function||System Transition Function||Associated Transition||Action|
|frontend_init()||Runs once after system initialization, before Equipment registration.|
|begin_of_run()||TR_START||Runs after system statistics reset at each begin-of-run request.|
|pause_run()||TR_PAUSE||Runs at each pause-run request.|
|resume_run()||TR_RESUME||Runs at each resume-run request.|
|end_of_run()||TR_STOP||Runs at each end-of-run request.|
|frontend_exit()||Runs once before any Slow Control Equipment exit|
Each defined Equipment has the option to force itself to run at individual transition times (see Equipment ReadOn Flag), so that its equipment function will be called on a certain transition (or combination of transitions).
The system transition functions all run prior to the equipment functions. This gives the system the chance to take basic action on the transition request (e.g. enable/disable interrupt) before the equipment runs. All the transition routines run with a Transition Sequence number of 500 (the default). This allows users to add additional functions in the frontend that will run before or after any of the transitions (such as a prestart() or a poststop() function). See Run Transition Priority for more information.