--------------------------------------------------------------------------------- FeeServer version 0.9 notes --------------------------------------------------------------------------------- Compilation: ------------ To compile the FeeServer please follow these steps: - change to the dim folder (feeserver/dim) - run ". setup.sh" or "source setup.sh" to prepare your shell (bash) - NEW FEATURE: the FeeServer now allows to print out benchmark timestamps. To enable this feature, you have to comment in the "benchmark = yes" line in the makefile_feeserver.arm (makefile_feeserver.linux). If you specify the environmental variable FEE_BENCHMARK_FILENAME, the timestamps are written to this file, else the benchmark output is sent as log message in the log level MSG_SUCCESS_AUDIT. To use the normal FeeServer make sure this line is outcommented. - if you compile FeeServer for the first time on your system: - run "make -f makefile_dim.arm" to compile the required DIM Library - run "make -f makefile_feeserver.arm" to finally compile FeeServer - NOTE: It is important, that the DIM lib is compiled with the flag NOTHREADS !!! Else the communication can get stuck. The makefiles set this as standart. - to install the feeserver in the run folder, type "make install -f makefile_feeserver.arm". This copies the binary to the run folder, where the start script is located. if you want to clean up your system: - run "make realclean -f makefile_dim.arm" to clean up DIM stuff - run "make clean -f makefile_feeserver.arm" to clean up - to compile everything for standard-linux use "*.linux" makefiles instead of "*.arm" Preparation: ------------ You now compiled the version for ArmLinux, so put the binary wherever you use to execute applications on your board. You must prepare your envirnonment with some variables to run FeeServer. You can either adapt the "setDim.sh" in the dim/run folder (new position, formerly scripts folder!) or you can set these variables by hand (export XY): - DIM_DNS_NODE for the dns for DIM - FEE_SERVER_NAME for the name of the feeserver (as seen in DIM) - FEE_LOG_LEVEL if you want to set a different log level on start up. The loglevel is an integer value and can be any combination of the following: (MSG_INFO=1; MSG_WARNING=2; MSG_ERROR=4; MSG_FAILURE_AUDIT=8; MSG_SUCCESS_AUDIT=16; MSG_DEBUG=32; MSG_ALARM=64) - MSG_ALARM is always on Since version 0.7.7 a new environmental variable has been added: - FEE_LOGWATCHDOG_TIMEOUT variable to set the timeout for the watchdog, checking for replicated log messages (details see below: Changes 0.7.7). If not set, a default value is used. !!! IMPORTANT !!! NOTE: ----------------------- Since version 0.7.0: The environmental variable for the FeeServer name has changed to FEE_SERVER_NAME. Execution: ---------- To execute FeeServer properly please follow these steps: - make sure that the dns for DIM is running on the machine you specified - !!! NEW !!! since version 0.7.0: finally run "sh startFeeServer.sh" This script starts the FeeServer and takes care of various features. NOTE: To have full functionality of the FeeServer you have to use this script!!! Important Notes: ---------------- - make sure that the setup.sh is executed only ONCE per shell! - start the FeeServer only with the startFeeServer.sh script. - interface of FeeServer and CE changed in version 0.7.0 - The service name scheme for CE service has changed: old style: "servername/servicename" -> new style: "servername_servicename" These changes for ACK-, MSG- and Command-channel will follow. - you can extract the documentation of the FeeServer with doxygen, which also gives an detailed description of the interface between FeeServer and CE. CE-issues: --------- Following some notes, which should be take account of. - We included a demo function for initializing an "Item" in our dummy CE. When writing an own CE, it is best copying and using this function in order to get a proper initialized "Item". - Don't use static created "Items", especially don't use static allocated memory for the "Item" names. This would case the clean up to hang and a proper exit would be no longer possible. - Please obey the DCS naming and numbering convention, when naming an "Item". more under: http://alicedcs.web.cern.ch/AliceDCS/ - Provide the "Items" with a default deadband. (Else the deadband will be 0, and the update rate would get to high -> to much traffic). To clarify that, the deadband must not be zero and should be set by the CE. - After the CE has been initialized, let this thread sleep for approx. 2-5 seconds (this gives the FeeServer time start the serving functionality inside the DIM framework). - In "cleanUpCE()", the CE don't need to clean and/or free "Items" and its members. (In fact it must not do it, this would crash the FeeServer during its cleanup.) - Don't call the createLogMessage() function during initializing the CE. (after the above mentioned sleep is fine). This service is only available after the DIM serving functionality has been started. - Be careful with sending log messages, especially in rapidly repeated checks/functions, this can pile up your log file extremely. Even consider carefully the specified log level; MSG_ALARM should be only for events, that could damage or destroy the system/hardware. - If, while testing, certain log messages of the CE don't appear, check the set log levels in FeeServer and InterComLayer. They may have filtered these messages. To set the default log level of the FeeServer, you can also use the environmental variable FEE_LOG_LEVEL before starting the FeeServer. - The CE can now also call a function, which allows for writting out benchmark timestamps. If the environmental variable FEE_BENCHMARK_FILENAME is set, the output goes to this file, else the benchmark timestamp is sent via the log message channel. The signature of the function looks like that: void createBenchmark(char* msg); where msg is a self-choosen text, which should determine the location of the benchmark timestamp. It is prefixed to the timestamp automatically. -------------------------------------------------------------------------------- Changes for version 0.9.0: -------------------------- (formerly version 0.8.2b) - New interface functions for filling Item and IntItem: /** * Function creates an initialized and filled Item. * All "members" are set according to the input parameters and a pointer * to the new created Item is returned. * * @param floatLocation pointer to the actual float value that shall be * published. This location must NOT change after publishing. * @param itemName desired name of the corresponding service * (Null terminated) * @param defDeadband chosen default deadband of the service * * @return pointer to the new Item, if enough memory is available, else * NULL. */ Item* fillItem(float* floatLocation, char* itemName, float defDeadband); /** * Function creates an initialized and filled IntItem. * All "members" are set according to the input parameters and a pointer * to the new created IntItem is returned. * * @param intLocation pointer to the actual int value that shall be * published. This location must NOT change after publishing. * @param itemName desired name of the corresponding service * (Null terminated) * @param defDeadband chosen default deadband of the service * * @return pointer to the new IntItem, if enough memory is available, else * NULL */ IntItem* fillIntItem(int* intLocation, char* itemName, int defDeadband); The returned pointer to Item and IntItem can be directly used for the publish - calls in the initialization of the CE. Memory allocated for the Item and IntItem is exclusively handled by the FeeServer. - Bug fix in float service value monitoring with deadband (floats are now checked really as floats)! - Wrapper function for all interface functions working on Items (float): - FloatItem* createFloatItem(); <- Item* createItem(); - int publishFloat(FloatItem* floatItem); <- int publish(Item* item); - FloatItem* fillFloatItem(...); <- Item* fillItem(...); Main reason for these wrapper is a direct indication which datatype is used (in this case float). - New Memory Management offered for CE: /** * Interface function to allocate memory. The CE can make the FeeServer * allocated and administrade memory for the CE with this function. If the * memory will be lateron used for the acknowledge data, the CE can * indicate that, so the memory already contains a prefix memory block for * the corresponding protocol header. * * @param size the size of the desired memory in bytes * @param type the data type for which memory will be used. * 's', 'i', 'l' - for short, integer, long * 'f', 'd' - for float and double * 'c', 's' - for char and char array (string) * 'x' - for complex * Capital letters are used for unsigned versions. * (in most case setting to 'x' = complex is sufficient). * @param module the name of the module that acquires the memory * (max. 29 chars) * @param prefixPurpose defines the purpose of the memory: if no prefix * memory block is required set to '0', if the memory will be used * for the acknoledge data of an issue-call set to 'A'. * (more might follow) * @param ptr out pointer, which will contain the allocted memory after the * function returns (NOTE: the pointer points to the memory, which * can be used by the calling module, it does NOT point to any * possible memory block for headers or so which might prefixe the * memory). * * @return FEE_OK on success, else an error code is returned: * - FEE_INVALID_PARAM: invalid parameter for size or prefixPurpose * - FEE_FAILED: Unable to create memory block (in most cases * insufficient memory). */ int allocateMemory(unsigned int size, char type, char* module, char prefixPurpose, void** ptr); This function allocates a given size of memory for the CE and allows the FeeServer to take care of its management. If this function is used for the Acknowledge data of an issue call, memory copying for the ACK protocol is avoided. /** * Interface function to free memory allocated by the FeeServer with the * call of allocateMemory(...). With this function the CE can release * memory that is under the management of the FeeServer. * * @param addr the (identifying) address of the memory that shall be freed; * this must be the address returned by 'ptr' of the * allocateMemory() function. * * @return FEE_OK on success, else an error code is returned: * - FEE_NULLPOINTER: addr is a NULL pointer * - FEE_INVALID_PARAM: addr is not in list of managed memory blocks */ int freeMemory(void* addr); This function free a memory block, which is managed by the FeeServer. For identification the address is used. - The start-script now allows to redirect the FeeServer output to the DCS- board syslogger "logger". This is done, if the environment variable "FEE_TO_SYSLOG" is set, else the output is printed on the terminal. - Interface functions for using CharChannels: - Publishing CharChannels: /** * Publishes char items. * Function, called by the Control Engine for each char service the * FeeServer should offer. This must be done before the server starts * serving (call of start()). (is implemented by the FeeServer). * NOTE: THIS FUNCTION IS IN ADDITION TO PUBLISH FLOAT / INT VALUES. * CharItem is very different to Item and IntItem. Instead of a location * pointer, the CharItem owns a function pointer to the corresponding * callback routine: * * void user_routine(long* tag, int** address, int* size); * * This function will be called, when an update of the char service is * triggered. This function has to be implemented by the CE. * * @param tag - The parameter that identifies the service, the tag is * given in the publishChar() call via the CharItem (Set by CE - * member of CharItem). * @param address - Should return the address of the data to be sent to * the FeeClient. * @param size - Should return the size in Bytes of the data to be sent * to the FeeClient. * * @param charItem pointer to the CharItem-struct, containing the name of * the service, an identifying tag and a pointer to a callback * routine, which is called by the DIM framework, when the * corresponding service shall be updated. * * @return FEE_OK, if publishing to server was successful, else an error * code. Possible errors are: * - FEE_WRONG_STATE -> FeeServer is not in state running * - FEE_NULLPOINTER -> given CharItem contains null pointer, * charItem is not published and not stored in list * (but CE can continue). * - FEE_INSUFFICIENT_MEMORY -> insufficient memory on board * - FEE_ITEM_NAME_EXISTS -> item name already exists, item is * not published and not stored in list (but CE can continue) * Note: The name must also be unique against the int and * float items. */ int publishChar(CharItem* charItem); - creating empty CharItem: /** * Function creates an empty, but initialized CharItem. * All "members" are set to 0. For further use it is essential, that these * members are filled with the appropriate values, especially the memory * for the '\0'-terminated name has to be still allocated! * * @return pointer to the new CharItem, if successful, else NULL */ CharItem* createCharItem(); - creating filled CharItem: /** * Function creates an initialized and filled CharItem. * All "members" are set according to the input parameters and a pointer to * the new created CharItem is returned. * * @param funcPointer pointer to the callback routine, that shall be called * by the DIM framework, when the corresponding FeeService is * updated. The callback routine has to be implemented by the CE. * The signature of the callback routine looks like: * * void user_routine(long* tag, int** address, int* size); * [tag - The parameter that identifies the service. The tag * is given to the publishChar() call via the CharItem.] * [address - Should return the address of the (char) data * to be sent to the FeeClient.] * [size - Should return the size of the data to be sent to * the FeeClient in bytes.] * * @param itemName name of the corresponding FeeService (Null terminated) * @param tag the above mentioned tag to identify the service in the * callback routine. * * @return pointer to the new CharItem, if successful, else NULL */ CharItem* fillCharItem(void (*funcPointer)(long*, int**, int*), char* itemName, long tag); - The CharItem looks like the following: /** * Typedef CharItem. * CharItem is a struct, with a function pointer to a callback routine, * that provides the data for the corresponding FeeService; the FeeService * name and a tag which identifies the FeeService. * @ingroup feesrv_core */ typedef struct { /** * struct function pointer -> user_routine for callback in case of * FeeService update. Called by the DIM framework. */ void (*user_routine)(long* tag, int** address, int* size); /** struct value name -> name of char item (service name). */ char* name; /** * struct value tag -> identifies the FeeService; handed to DIM when * registering the service and return by the framework as parameter of * the callback routine. */ long tag; } CharItem; - Interface to CE is now declared as extern "C" (ce_command.h). Open Issues: ------------ - Integration of newest DIM framework version - Interface function that allows the CE to change settings like updateRates or timeouts -------------------------------------------------------------------------------- For questions and remarks please contact: ----------------------------------------- Christian Kofler Sebastian Bablok Bejamin Schockert http://www.ztt.fh-worms.de (download at https://www.ztt.fh-worms.de/download/alice/) --------------------------------------------------------------------------------