Frontend user code

From MidasWiki
Revision as of 17:10, 1 November 2013 by Suz (talk | contribs)
Jump to navigation Jump to search




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
EPICS frontend.c ../midas/examples/epics/ 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).

Include files

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).

Example includes

#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

Global declarations

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 */
/* 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

A discussion of Bank Definitions and Equipment List will be easier to follow if first the sequence of operations is discussed.

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.