Table of Contents Previous Chapter
The purpose of the Telemetry Management system is to build and send a time-ordered list of telemetry packets to the instrument's telemetry hardware.
Figure 66 illustrates the top-level classes and their relationships involved in processing telemetry.
FIGURE 66. Telemetry Management Class Relationships
TlmManager - The TlmManager class is responsible for maintaining a queue of telemetry packets (see TlmQueue and TlmPkt) to feed to the telemetry device (Devices::TlmDevice).
TlmPkt - The TlmPkt class is responsible for managing the raw telemetry buffer located in Single Event Upset (SEU) vulnerable RAM, and for maintaining a small amount of critical packet header information within SEU immune RAM. This class serves as the container for telemetry information within the ACIS software.
TlmAllocator - The TlmAllocator class acts as a memory manager for a group of telemetry packet buffer types. It maintains a collection of equally sized TlmPkt instances. The allocator class uses the TlmPool class to obtain a set of TlmPkt instances during start-up, and then uses a TlmQueue to manage these instances at run-time.
TlmQueue - The TlmQueue class is a subclass of Executive::Queue. It serves as a type-safe interface to a Queue instance which maintains an first-in/first-out list of pointers to TlmPkt instances. This class is used by the TlmAllocator to maintain its list of free telemetry packets. It is also used by the TlmManager to maintain a list of active telemetry packets awaiting transfer out of the instrument.
TlmPool - The TlmPool class is a subclass of Executive::MemoryPool. It serves as a type-safe interface to a MemoryPool instance which contains the memory buffers used for TlmPkt instances. This class is used by the TlmAllocator during start-up to reserve memory for a set of TlmPkt buffers. The intent of this class is to provide the ability to patch the number or size of TlmPkts within a given pool instance, if the unlikely need arises after launch.
TlmForm -The TlmForm class is used as a base-class for the different telemetry packet formats. It and its subclasses are responsible for providing the interface functions needed to allocate telemetry packets, format the contents of the packets, and post the packets to the TlmManager for transfer out of the instrument. By convention, the name of all subclasses of TlmForm shall be prefixed with the abbreviation, "Tf" (i.e. a command echo telemetry format class would be called Tf_Command_Echo).
TlmDevice - The Devices::TlmDevice is responsible for commanding the hardware to transfer a telemetry packet. It is a subclass of Devices::IntrDevice, and is provided by the Devices class category. It is described in Section 9.0 .
TlmCallback - The TlmCallback class is a subclass of Devices::IntrCallback. It is used by the TlmManager to obtain control during telemetry interrupt processing.
TlmFatal - The TlmFatal class is responsible for formatting fatal error messages. Due to the special nature of fatal error messages, this class is implemented independently of the telemetry format class, TlmForm.
The hardware requires that all telemetry transfers must be from uncached RAM, must be less than or equal to 8192 bytes in size, must be aligned to a 4-byte boundary, and must not cross an 8192 byte boundary. In ACIS, this memory is vulnerable to Single-Event Upsets (SEU). In order to minimize the possibility of an upset corrupting crucial buffer management information, or important packet header information, the ACIS software maintains this information in its data cache space, which uses SEU immune RAM. This information is contained within a TlmPkt class instance. Each TlmPkt instance has a pointer to a packet transfer buffer within uncached RAM. In general, memory for TlmPkt instances are reserved using TlmPool instances (which use Nucleus RTX Memory Partitions), and lists of TlmPkt's are maintained using TlmQueue instances (which use Nucleus RTX Queues).
During operation, all telemetry information except for the packet headers is written directly into a packet's transfer buffer by a TlmForm instance (or by a user of TlmForm). Except for the telemetry packet header, once a packet has been formatted and posted, no further modifications to a telemetry packet are needed. Telemetry buffer management and formatting are treated as two different activities. The TlmPkt class is used for buffer management, and the TlmForm subclasses are used for formatting the buffer contents. Only TlmPkt instances need to be dynamically allocated and released at run-time.
The ACIS produces telemetry packets asynchronously to the spacecraft telemetry frames, and these packets can appear anywhere within the telemetry frame science data sections allocated for ACIS by the spacecraft. Each packet consists of a series of 32-bit words. In order to allow the ground software to easily locate the start of an ACIS telemetry packet within the science stream, ACIS provides a synchronization word at the start of each packet. Gaps between ACIS packets are filled using a hardware generated fill pattern (see Section 9.4 ). Within the instrument software, the format of this header is managed by the TlmPkt class. Table 21 illustrates the format of the ACIS telemetry packet header.
TABLE 21. Telemetry Packet Header
----------------------------------------------------------------------------------------- Word Bits Field Description Min. Value Max Value----------------------------------------------------------------------------------------- 0 0:31 Packet This field contains a constant 32-bit 0x4329da2c N/A Synch. synch. pattern, used to locate the start of a telemetry packet within a spacecraft minor frame. 1 0:9 Packet This field contains the total number 2 1023 Length of 32-bit words in the packet, including the Packet Synch. 1 10:15 Packet This field identifies the type of data 0 63 Format contained in the body of the packet. Tag 1 16:31 Packet This field contains an telemetry 0 65,535 Sequence packet counter, which increments Number for each packet sent by ACIS 2:Packet - Data The remainder of the packet con - - Length - 1 tains format tag-specific data. -----------------------------------------------------------------------------------------
Within the ACIS software, each packet data format is represented by some subclass of TlmForm. These subclasses inherit directly from TlmForm, or inherit from some intermediate abstract class which provides fields common to a set of different formats.
The formats of each packet type are defined by the Instrument Program and Command List (IP&CL) structure tables (see TBD). These format tables are converted into classes either by hand, or using a conversion program. Each generated class is a subclass of TlmForm, and uses the TlmForm member functions putField and appendField to write bit-fields into the telemetry packet buffer. The total number of words in a telemetry packet is calculated by each subclass member function getWordCount.
In order to reduce the number and size of gaps between telemetry packets when there are a set of packets ready to be sent, the Telemetry Device states that the time between the end of one telemetry transfer, and the start of the next start take less than 0.5 milliseconds (see Section 9.0 ). In order to avoid possible long delays due to context switching, the Telemetry Manager performs back-to-back telemetry transfers using the TlmDevice's callback instance. When a telemetry transfer completes, the TlmDevice's interrupt handler is invoked. This handler then invokes the installed callback, which in turn, calls the TlmManager's serviceDevice() member function. During this interrupt callback processing, serviceDevice() then obtains the next packet from the telemetry queue, and starts the next transfer. If the total time spent handling a telemetry interrupt using a non-empty telemetry queue is less than 0.5 milliseconds (assuming no higher priority interrupts occur and that interrupts are in an enabled state when telemetry transfer completes), no gaps will occur between adjacent, prepared telemetry packets.
Within ACIS, memory for all telemetry buffers and control structures (TlmPkt) are reserved (via Nucleus RTX memory partitions), allocated and initialized during system initialization and start-up. Once running, groups consisting of equally sized telemetry packet buffers are maintained by TlmAllocator instances. Any given TlmForm uses a single TlmAllocator to obtain packet buffers, and each TlmPkt has a pointer back to its owning TlmAllocator instance.
Figure 67 illustrates the allocation of telemetry buffers and control structures during the system initialization process.
FIGURE 67. System Initialization Telemetry Packet Allocation
Once the allocator has been constructed, its freeQueue will contain a pointer to each telemetry packet instance maintained by the allocator. Each instance can support a telemetry packet up to the size specified as part to the allocator's constructor.
From the client's point of view, all telemetry packet acquisition, formatting and posting is accomplished using subclasses of TlmForm. TlmForm maintains a pointer to the telemetry packet currently being formatted. Upon construction, this pointer is 0, and the client must invoke TlmForm::waitForBuffer() to obtain a telemetry packet. In order to give client code a certain degree of flexibility, this is NOT done automatically by TlmForm's constructor. Once the packet is posted to the telemetry manager, TlmForm zeros this pointer to prevent further modifications of the packet's contents, and the client code must call TlmForm::waitForBuffer() to obtain another packet. If a TlmForm instance is destroyed prior to posting an allocated telemetry packet, its destructor invokes the packet's TlmPkt::release() function to ensure that it is not lost. Figure 68 illustrates the overall life-cycle of a TlmForm instance, and its formatted telemetry packet.
FIGURE 68. Telemetry formatting, buffering and transfer
The TlmManager class provides the ability to jam a fatal error message into the telemetry stream. It assumes that, when doing this, all interrupts have been disabled by the client. Figure 69 illustrates the overall fatal error message scenario.
FIGURE 69. Sending a Fatal Error Message
Hierarchy:
Superclasses:
none
Public Uses:
TlmPkt
Implementation Uses:
TlmDevice tlmDevice
Public Interface:
Operations:
TlmManager() post() sendPanic() serviceDevice()
Private Interface:
Has-A Relationships:
Arguments:
unsigned queueId
unsigned maxpkts
Documentation:
This constructor initializes the telemetry queue, using the passed Nucleus RTX queueId. The maximum number of telemetry packets supported by the instrument is specified by maxpkts. This function also zeros the current transfer packet pointer, indicating that no transfers are underway.
Arguments:
TlmPkt* pkt
Documentation:
This function places the referenced telemetry packet, pkt, onto the manager's telemetry queue. Once all previously posted packets have been transferred, the referenced packet will be transferred out of the instrument. Once its transfer is complete, its release() member function will be invoked.
Arguments:
TlmPkt* pkt
Documentation:
This function "jams" a telemetry packet into the telemetry stream.
Arguments:
IntrDevice* devptr
Documentation:
This function is invoked by the telemetry callback instance once a telemetry transfer has been completed. This function invokes the just completed packet's release() member function. It then attempts to dequeue another packet from the sendQueue and start its transfer.
Hierarchy:
Superclasses:
Queue
Public Uses:
TlmPkt
Public Interface:
Operations:
TlmQueue() enqueuePkt() requestPkt() waitForPkt()
Arguments:
unsigned queueId
unsigned nitems
Documentation:
This constructor initializes the queue of telemetry packet pointers. queueId is the Nucleus RTX queue identifier used for the particular instance being initialized. nitems is the number of packet pointers which can be contained in this queue (used for sanity checking against the RTX queue instance). This function invokes the parent constructor, Queue::Queue(), using the number of words in a telemetry packet pointer as the element size within the queue (queueId and nitems are passed unmodified).
Arguments:
TlmPkt* pkt
Documentation:
This function enqueues a pointer, pkt, to a telemetry packet onto this queue, using its parent's Queue::enqueue() function.
Arguments:
unsigned timeout
Documentation:
This function waits for and dequeues a packet from the queue, using its parent's Queue::waitForItem() function. If no packets are ready, this function waits no longer than timeout timer ticks (1/10 second) for one to be enqueued. If timeout expires, this function returns 0.
Hierarchy:
Superclasses:
none
Public Interface:
Operations:
TlmPkt() prepareForXfr() release() setFormatTag() setSequence()
Protected Interface:
Operations:
getBufferAddress() getBufferLength() setPacketLength()
Has-A Relationships:
Private Interface:
Has-A Relationships:
Arguments:
TlmAllocator* allocator
unsigned* buffer
unsigned wordcnt
Documentation:
This constructor sets up the non-volatile state of a telemetry packet instance, assigning its read-only owner, bufAddr, and bufLength values to the corresponding passed arguments, and zeroing pktLength, pktSeq and pktFormat. owner and buffer must not be 0, and wordcnt must be greater than or equal to 2.
Arguments:
unsigned datacnt
Documentation:
This function is used to inform the packet of the amount of information written to its packet buffer. A pointer to the buffer is provided by getBufferAddress(). The argument datacnt reflects the number of 32-bit words written into the entire packet buffer. datacnt must not exceed the value returned by getBufferLength(). This function stores the passed datacnt into pktLength.
Arguments:
TlmFormatTag tag
Documentation:
This function sets the format tag of the telemetry packet instance, by copying tag into pktFormat.
Arguments:
unsigned*& xfraddr
unsigned& xfrlen
Documentation:
This function prepares a telemetry buffer to be transferred to the telemetry interface hardware. Upon return, xfraddr will contain the address of the buffer to transfer, and xfrlen will contain the number of 32-bit words to transfer. NOTE: Given the volatile nature of the telemetry transfer buffer, this function should be called just prior to instructing the telemetry hardware to transfer the buffer.
Arguments:
unsigned sequence
Documentation:
This function sets the sequence number within the packet by copying sequence to pktSeq.
Hierarchy:
Superclasses:
none
Public Uses:
TlmPkt
Public Interface:
Operations:
TlmAllocator() releasePkt() requestPkt() waitForPkt()
Private Interface:
Has-A Relationships:
Arguments:
unsigned poolId
unsigned queueId
unsigned wordcnt
unsigned npkts
Documentation:
This constructor initializes its memory pool, instancePool, and free packet list, freeQueue, using poolId and queueId, and allocates sections of the raw telemetry buffer, placing references to the allocated packet instances into its freeQueue.
Arguments:
TlmPkt* pkt
Documentation:
This function releases a telemetry packet back into the freeQueue, using freeQueue.enqueuePkt().
Arguments:
unsigned timeout
Documentation:
This function attempts to dequeue a telemetry packet from its freeQueue. If timeout expires before a packet becomes available, the function returns 0. If a packet is obtained, it returns a pointer to the constructed packet. This function uses freeQueue.waitForPkt() to wait for and dequeue the packet pointer.
Hierarchy:
Superclasses:
MemoryPool
Public Uses:
TlmPkt
Public Interface:
Operations:
TlmPool() allocatePkt()
Arguments:
unsigned poolId
unsigned instanceSize
unsigned nbufs
Documentation:
This constructor initializes a pool of buffers to be used to reserve space for telemetry packet instances. poolId is the Nucleus RTX partition identifier, instanceSize and nbufs are used to sanity check the RTX pool capabilities and are respectively the size of the buffered class instance and number of instances.
Hierarchy:
Superclasses:
none
Implementation Uses:
TlmManager tlmManager
Public Interface:
Operations:
TlmForm() ~TlmForm() hasBuffer() post() requestBuffer() waitForBuffer()
Protected Interface:
Operations:
appendField() getBufLength() getBufPtr() getWordCount() putField()
Private Interface:
Has-A Relationships:
TlmForm
Arguments:
TlmAllocator* pktsrc
TlmFormatTag tag
Documentation:
This constructor initializes the top-level state of the formatter, by setting the read-only allocator instance from pktsrc, and by zeroing the current packet pointer. tag is the telemetry packet format tag to use for packets written by this formatter instance.
TlmForm
TlmForm
void
Arguments:
unsigned value
unsigned bitoffset
unsigned bitwidth
unsigned bitmask
unsigned index
unsigned arraywidth
Documentation:
This inline function appends a field into the end of a telemetry packet buffer. This function can potentially be more heavily optimized than putField() because it does not need to preserve values stored beyond the current field. This function is intended to be expanded within subclass field writer functions, and be heavily optimized by the compiler. value contains the item to store into the buffer, bitoffset is the starting bit position of the field within the telemetry packet. If the field is within a structure, the bitoffset is the bit-position of the first field within the first array element. bitwidth is the number of bits within the field. bitmask is a right-justified mask of the field, where 1's correspond to the bits within the field and 0's correspond to other fields. If the field is within an array, index is the array element to access, and arraywidth is the number of bits within 1 array element.
TlmForm
unsigned
TlmForm
unsigned*
TlmForm
unsigned
TlmForm
Boolean
TlmForm
void
TlmForm
void
Arguments:
unsigned value
unsigned bitoffset
unsigned bitwidth
unsigned bitmask
unsigned index
unsigned arraywidth
Documentation:
This inline function writes a field into the telemetry packet buffer. This function is intended to be expanded within subclass field writer functions, and be heavily optimized by the compiler. value contains the item to store into the buffer, bitoffset is the starting bit position of the field within the telemetry packet. If the field is within a structure, the bitoffset is the bit-position of the first field within the first array element. bitwidth is the number of bits within the field. bitmask is a right-justified mask of the field, where 1's correspond to the bits within the field and 0's correspond to other fields. If the field is within an array, index is the array element to access, and arraywidth is the number of bits within 1 array element.
TlmForm
Boolean
TlmForm
Boolean
Arguments:
unsigned timeout
Documentation:
This function uses its allocator to wait for and allocate a telemetry packet. If timeout is reached, this function returns BoolFalse. If a packet was obtained, it returns BoolTrue.
Hierarchy:
Superclasses:
DevCallback
Implementation Uses:
TlmManager tlmManager
Public Interface:
Operations:
invoke()
Arguments:
IntrDevice* devptr
Documentation:
This function is called by the telemetry device during its interrupt processing. This function invokes the tlmManager.serviceDevice() function to handle the end of a telemetry packet transfer.
Hierarchy:
Superclasses:
none
Implementation Uses:
TlmManager
Public Interface:
Operations:
TlmFatal() sendMessage()
Private Interface:
Has-A Relationships:
Arguments:
FatalCode code
unsigned arg
Documentation:
This function stores the passed fatal message code and argument into the fatal message telemetry packet, and instructs the Telemetry Manager to transfer the packet out of the instrument. code indicates which fatal message is to be sent, and arg is the optional argument of the message.