README for Knob Controller Software The knob controller software handles communication with the hardware knob boxes. Each instance can support a single 'line', always identified as line 0, which can support up to 16 knob boxes. Each box has 4 knobs. ================================================================= Configuration: EPICS databases, knobCtrlApp/Db: - Instantiate one instance of knobCtrlBox.db for each box. Example: # Macros: # LOCA: Physical box location. For Accelerator Control Room, use ACR0 # BOX: Box number to be used in PV names, user interfaces # Combination of LOCA and BOX must be unique globally # INST: Box instance, between 1 and 15. # Matches box hardware address and is index into box data structures. # #===================================================================== # file knobCtrlBox.db{ pattern { LOCA, BOX, INST } { ACR0, 1, 1 } { ACR0, 2, 2 } { ACR0, 3, 3 } { ACR0, 4, 4 } { ACR0, 5, 5 } { ACR0, 6, 6 } { ACR0, 7, 7 } { ACR0, 8, 8 } { ACR0, 9, 9 } { ACR0, 10, 10 } { ACR0, 11, 11 } { ACR0, 12, 12 } { ACR0, 13, 13 } { ACR0, 14, 14 } { ACR0, 15, 15 } } ----------------------------------------------------------------- st.cmd: - Load EPICS Knob User database, for example SIOC-ACR0-KN00.db: dbLoadRecords("db/SIOC-ACR0-KN00") -Initialize knob controller software before iocInit. Example for development system: # Initalize knob box controller software # knobInit(boxcb, usercb, line) # boxcb - Name of callbacks for comm with boxes # usercb - Name of callbacks for comm with users # line - Comm handle for line (typically terminal server node name) # knobCtrlInit( "knobCtrlBoxCommTcpCb", "knobCtrlUserCommUdpCb", "ts-b34-nw15") ================================================================= Source code description: ----------------------------------------------------------------- Main program files: knobCtrlApp/src/knobCtrl.c/.h knobCommonApp/src/knobCtrlDef.h Main program to handle communication with hardware knob boxes. Tasks: - Initiate communication with clients who wish to control devices with knobs. As we are the server and support multiple dynamic clients, we just create a means to receive requests. Once a request is actually received, we save information about the client. - Initiate communication with knobs. - Await messages from clients who wish to control devices with knobs. - Execute requests from clients: attach device, detach device, update knob legend, etc. - Poll knobs for latest turns count. - Each knob can be 'owned' by a different user (i.e. control system). When a knob is attached, that user's info is saved. Only that user will be allowed to update the knob legend or detach the knob. Another user can take control simply by attaching. We send a message to the user that was deposed (not all users support this message; those who do not should discard it.) Program flow: - After initialization, the main processing threads are created: - One thread is used to listen for and process messages from users. It loops infinitely doing this. - Each knob box also has a thread to handle processing of that box. It loops infinitely, requesting turns counts for attached knobs and writing new legend updates. Data structures (see knobCommonApp/src/knobCtrlDef.h): - knob_ts contains knob data. One per knob. - box_ts contains box data. One per box. - line_ts contains line data. One per line. - ctrlglobal_ts is top-level struct that contains all of the above Callbacks (see knobCommonApp/src/knobCtrlUserDef.h and knobCtrlBoxDef.h): - kusercb_ts is the callback structure used for communication with knob users. It is required and must be passed as argument to knobCtrlInit. - knobcb_ts is the callback structure used for communication with knob boxes. It is required and must be passed as argument to knobCtrlInit. (Byte order is handled here. For communication with knobs, we do not need to worry about byte order because the data is sent in a serial byte stream and the value of each byte is defined in the message protocol. For communication with clients, byte order may be an issue because messages may be sent over the network to hosts with different endianness and we have several multi-byte integers embedded in our message protocol. Use callbacks to handle this.) ----------------------------------------------------------------- Communication with knob users: knobCtrlApp/src/knobCtrlUserComm.c/.h knobCommonApp/src/knobCtrlUserDef.h Tasks: - Initialize means to listen for requests from clients - Use callbacks to receive/send messages supported by our msg protocol: attach, detach, etc. ----------------------------------------------------------------- Communication with knob boxes: knobCtrlApp/src/knobCtrlComm.c/.h knobCommonApp/src/knobCtrlUserDef.h Tasks: - Intialize communication with knobs - Use callbacks to receive send messages supported by our msg protocol: request turns, update legend, etc. ----------------------------------------------------------------- Callbacks for communication with knob users - UDP knobCtrlUserUdp/knobCtrlUserUdp.c Implements kusercb_ts to communicate with users via UDP. See knobCommonApp/src/knobCtrlUserDef.h for functional description of callbacks Default UDP port number is 2001. (Historical and is used by VMS COWs.) User can override at startup before knobCtrlInit by calling iocsh routine. See knobCtrlUserUdp.c. Tasks: - Initialize UDP server - Initialize data structures - Copy/compare knob user socket info - Send UDP messages - Receive UDP messages ----------------------------------------------------------------- Callbacks for communication with knob boxes - TCP knobCtrlBoxTcp/knobCtrlBoxTcp.c Implements knobcb_ts to communicate with knob boxes via TCP. See knobCommonApp/src/knobCtrlBoxDef.h for functional description of callbacks Tasks: - Initialize TCP clients - Initialize data structures - Send TCP messages - Receive TCP messages ----------------------------------------------------------------- =================================================================