W. Grandegger, E. Pasqualucci, I. Sfiligoi

Methods and Rules for KLOE Level-1 Software Development

The purpose of this document is to define rules and methods for level-1 software development.

The strategy to build the test tools for the KLOE readout system is based on the integration of different libraries, each of them written to access a given module. In order to allow an easy integration, each developer has to follow some simple rules regarding software portability, use of common tools and libraries, general programming criteria, naming conventions, and documentation.

As for the general rules of the KLOE online software, the rules and methods described here should be regarded as a starting point for discussion. So, if some rule will be added or modified, according to developers' experience, this document will be updated accordingly. The updated topics will be marked with (updated) .

Table of contents


Packages and general rules

While in a second step all the software will be included in a single package, each developer has to create his own package in order to develop the software related to a board, following the naming conventions described in the following.

All the rules contained in the general document about the online software development hold if not otherwise specified.

It is mandatory to use packman to configure and maintain the software. Once a version of a package will be released, it will be freezed and integrated in the level-1 general package and a new version will be created as developing area.

Each version of a package must be certified both by the responsible of the related board and by the responsible of software integration.


Software portability and supported OS (updated)

The KLOE DAQ and online environment is a distributed heterogeneous UNIX environment. Various UNIX operating systems, mainly HP-UX, OSF/1, LynxOS, are in use on different hardware platforms including VME processor boards. All the level-1 software must support almost these three OS.

Some general criteria have to be followed to build multi-platform code with only one set of source files:

Furthermore, all the released tools, such as the TL compiler to produce graphic interfaces and the source2html or c2html tool to produce updated documentation in HTML format should be used.


Naming conventions

Some naming conventions have to be adopted to avoid entry point duplication and to build easy-to-read software. These conventions applies to:

Almost one include files must be provided, named package.h or package_public.h, containing:

Another include file can be provided if encapsulated type definitions are needed. This file will be called package_private.h.


Operations on registers

Simple operations on registers (such as read, write or modify operations) should be implemented using macros and an easy-to-learn naming scheme:

	#define package_operation_register-name
For instance, to read the register called pippo in the adc, in the public include file you will have:
        #define ADC_PIPPO_OFFSET    0x32

        #define adc_get_pippo (id, val_pippo) \
                               VmeRead(id.cid, ADC_PIPPO,\
                               (char *) &val_pippo,\
                               sizeof (val_pippo))

NOTE: In general, working with macros helps to have compact and efficient code, avoiding overload. A macro can easily implement low-level operations. Furthermore, writing a macro for each register allows the user to work easily, calling the appropriate procedures for each operation on the hardware.


Bit and mask manipulation

To implement operations on bits or bit fields similar criteria should be used. A basic macro should be provided to implement each operation for each bit field; bit and field manipulation can be performed by using the utility bits, included in the common package. For instance, to set the flag called MYFLG in the ADC register PIPPO:

	#include "bits.h"

        #define ADC_PIPPO_OFFSET   0x20

        #define ADC_MYFLG          4

        #define adc_set_myflg (id, value) \
                              {char rval;\
                               VmeRead (id.cid, ADC_PIPPO,\
                                        &rval, sizeof (char));\
                               bits_set_bit (rval, ADC_MYFLG,\
                                             value);\
                               VmeWrite (id.cid, ADC_PIPPO,\
                                         &rval, sizeof (char));}

NOTE: It is possible to manage bit fields (see bits documentation). Use macros to manage single fields; use functions to perform complex operation, such as modifying two fields in the same register. This will avoid overload due to unuseful VME accesses when calling two `set' macros.


Error management


Some other useful criteria (updated)