Table of Contents Previous Chapter ACIS

27.0 Memory Server (36-53219 A)

27.1 Purpose

The MemoryServer responds to commands to read, write, and execute code in memory.

27.2 Uses

The MemoryServer will support requests to telemeter a copy of any portion of the memory's contents, to replace a section of the memories contents, or to execute the code stored in Instruction Cache or general purpose memory.

Specifically, it provides the following features:

  1. Provides rapid acceptance of client requests through public routines

  2. Waits responding to client requests and monitors' query

  3. Reads memory of the BEP, FEP, PRAM, and SRAM

  4. Writes memory of the BEP, FEP, PRAM, and SRAM

  5. Executes appropriate BEP or FEP memory

  6. Read and telemeter (i.e. dump) multi-packet configuration information (such as the Bad Pixel Map)

27.3 Organization

Figure 122 illustrates the relationships between the classes used by the MemoryServer, with public methods of interest listed; while Figure 2 shows the telemetry packet classes.

FIGURE 122. MemoryServer Class Relationships


The MemoryServer uses the Executive and Protocols class categories.

MemoryServer - This class is a subclass of Executive::Task. It is responsible for providing reads, writes, and executes of memory directly from the request.

TfReadBep - TfReadFep - TfReadSram - TfReadPram - TfExecBep - TfExecFep - This set of classes, Figure 123, encapsulates the representation of a telemetry packet. It is a subclass of Protocols::TfCmdResponse, which in turn, is a subclass of TlmForm.

FIGURE 123. MemoryServer Telemetry Packet Classes


Mongoose - This set of utility tools is available to all classes. The functions specific to the MemoryServer deal with reading and writing I_Cache.

SwHousekeeper - This class (not shown) is a subclass of Executive::Task. It is responsible for delivering housekeeping data telemetry packets (faults, status, etc.) supplied to it by the various functions.

TaskMonitor - This class (not shown) is a subclass of Executive::Task. It interrogates each thread in turn, verifying that it is functioning. Failure to respond will cause a watchdog reset when the watchdog counter reaches zero. The maximum time is less than eight minutes (TBD).

notify and waitForEvent - are functions of Executive::Task. They provide the connectivity between the client's request and the thread's main process.

Semaphore - This class is a member of Executive. It provides the gating method used to process commands serially.

FepManager - This class is a member of Protocols. It is responsible for the read, write, and execute interaction with the FEPs.

DeaManager - This class is a member of Protocols. It is responsible for the read, and write interaction with the DEAs.

27.4 Scenarios

27.4.1 Operational Overview

The MemoryServer has been designed to quickly acquire a client's request directive, and then release the client to its normal duty. The request will be fulfilled, eventually, by the MemoryServer task. All tasks must be able to respond to the task wellness monitor.

The MemoryServer is implemented by providing a set of public functions, callable by the client. Each of the set supports a specific type of request. It is the purpose of each function to verify arguments, to obtain a control semaphore which will insure serial execution of requests, and to quickly acquire buffered input data. The function will then notify the MemoryServer task, running autonomously, that a request is pending. Control is returned to the client.

When the MemoryServer task, goTaskEntry(), receives the notification of a pending request, it independently activates the private function responsible for fulfillment of that type of request. The fulfilling function, either directly or assisted by services provided by specialized managers, will complete the request. The function will then return to the MemoryServer task which releases the control semaphore, permitting additional requests to be initiated.

The acquiring public functions and their corresponding fulfilling private functions are: executeBep - exeBep, executeFep - exeFep, readBep - rdBep, readFep - rdFep, readPram - rdPram, readSram - rdSram, writeBep - wrtBep, writeFep - wrtFep, writePram - wrtPram, writeSram - wrtSram.

Between requests and during the request fulfillment period, the process must punctually respond to the task wellness monitor. Failure to do so will keep the monitor from resetting the watchdog.

27.4.2 Use 1:: Provides rapid acceptance of client requests through public routines

As illustrated in Figure 124, any client requesting a memory service will call one of the public routines with the arguments and data which specifies that request. The intent is to quickly initiate the request and return.

FIGURE 124. Public Function Delivers a Request


  1. The client requests a memory service via a public function e.g. readBep(). Each service provides for verification of the arguments as necessary.

  2. Then attempts to obtain control of the MemoryServer task using getSemaphore(). If the semaphore is already in use, the function returns BUSY. Upon obtaining the semaphore, the arguments and associated data are stored.

  3. Finally, notify() is called to alert the fulfillment control task goTaskEntry(). The public function returns control to the client reporting the request as DELIVERED.

27.4.3 Use 2:: Waits responding to client requests and monitors' query

The MemoryServer task is omnipresent. It only functions when requested to do so by its public functions or by the monitor. Refer to Figure 125

FIGURE 125. Event handling by the MemoryServer


  1. When there are no pending requests, the main MemoryServer process thread, goTaskEntry(), waits, idling in waitForEvent(), for a valid request from its public functions or for a query from the taskMonitor().

  2. Meanwhile, the taskMonitor() is using Task::notify() to send a EV_TASKQUERY to each active task to verify its viability.

  3. On receipt of an event, goTaskEntry() uses TaskMonitor::respond() to answer the taskMonitor().

  4. When an event is received from a Client driven MemoryServer public function requesting a memory service, goTaskEntry() directs the request to the proper subfunction for processing. Should this request fulfilling subfunction be delayed by the unavailability of packets to deliver requested data, it lingers for a specified period in waitForBuffer().

  5. Each time it obtains a packet buffer and between lingerings, as necessary, the subfunction uses the non-blocking requestEvent() to monitor taskMonitor() queries. When a query does arrive, it uses respond() to send a reply to the taskMonitor().

  6. Upon the functions return, the main process, goTaskEvent() calls semaphore::release() to free the semaphore and then resumes its waiting.

27.4.4 Use 3:: Read memory of the BEP, FEP, PRAM, and SRAM

The read requests will identify the target process memory, the memory location to begin the read and the amount of data to be delivered. A request to deliver an extensive amount of data will require an appreciable number of packet loads. With a limited supply of MemoryServer packets and possible contention for delivery services, this request may dribble data packets over an extended period.

27.4.4.1 Read Back End Processor memory

Figure 126 illustrates the process by describing the steps needed to deliver a copy of the Back End Processors' memory

FIGURE 126. Process a read BEP request


  1. Upon being alerted by notify(), sent by the client through the public function readBep (not shown), the main process thread, goTaskEvent(), handles the request by directing the BEP reader service function, rdBep(), to process the request.

  2. The rdBep() function uses isIcache() to test for an I_Cache read request so it may invoke the appropriate reading method.

  3. It then enters a loop which uses the constructor to obtains a telemetry packet instance.

  4. It calls the MemoryServer function waitGetPacket() to supply a packet buffer.

  5. The routine checks the monitor (above) and uses the TfReadBep parent function TlmForm::waitForBuffer() which may linger for a stated period. It will return having succeeded in getting a buffer, or will cycle to try again.

  6. rdBep() uses the forms' getBufferInfo() to determine the location of the buffer and its length.

  7. Then it uses the forms' setCmdId() to install the command identifier into the packet buffer.

  8. The forms' setTimeStamp() is used to provide a timing reference.

  9. The address of the first word to be read and stored into the buffer is installed using the forms' setMemAddr(). The memory location of each packets' contents are thus identified.

  10. Having determined the amount of data to be loaded in the current packet buffer, the forms setReadLength() installs this information.

  11. rdBep() will call icacheRead() to have a copy of data in the I cache inserted into the buffer or else it will load the buffer directly itself.

  12. A call to the forms' post() will forward the packet for delivery. rdBep() calculates the amount of data remaining to be processed. If the request has not been completed, it cycles to the top of the loop to obtain, load and deliver another packet.

  13. When the request is completed, control is returned to the main process where the semaphore is made available to the next request using semaphore::release().
27.4.4.2 Read Front End Processor memory

Assistance from the FEP manager is required to deliver a memory copy from one of the FEPs. The BEP manages the packets needed to fulfill the request and will designate the packet buffer address to begin data storage. It, will specify which FEP memory is to be read, where to begin and how much may be stored in the buffer. Figure 127 illustrates this shared activity.

FIGURE 127. Process a read FEP request


  1. A request to read FEP data follows about the same scenario as in read BEP data. goTaskEntry() will call rdFep() to obtain a packet, will establish load points, and will install the specific header information.

  2. The form's setFepId() is added to the heading to identify the intended FEP.

  3. Provided with a target FEP identity, the address to be read from, a buffer address to load the data into and the amount to be loaded; the FepManager::readMemory() will be used to fill the buffer. It handles reads to I_cache, D_Cache or bulk memory.

  4. Should the FepManager encounter a difficulty in delivering the requested data, it will return a Boolean value indicating the futility of continuing. rdFep() will use SwHouskeeper::report() to record the incident, will release() the packet buffer and return. Upon leaving scope, the packet instance is eliminated.

  5. The forms' post() is used to instigate delivery of the packet. rdFep() determines when the request has been completed. It will continue to obtain a packet, load the header, and pass its buffer address and other arguments to readMemory() until the request has been completed. When the request is completed, control is returned to the main process where the semaphore is made available to the next request using semaphore::release() (not shown).
27.4.4.3 Read from DEA Sequencer RAM

The DEA manager will support requests to deliver a copy of SRAM memory from one of the DEA CCD boards. The BEP will provide the packets needed to fulfill the request and will designate the packet storage buffer address. It will specify which DEA CCD board memory is to be read, where to begin and how much may be stored in the buffer. Figure 128 illustrates this shared activity.

FIGURE 128. Process a read SRAM request


  1. When a read from SRAM is requested, goTaskEvent() will pass responsibility to rdSram(). Again, a similar scenario is followed. A packet is obtained, the header information loaded, and the responsibility for loading the data is passed to the DeaManager.

  2. The calls to obtain a packet and to load the header have the same name as previous read memory requests. The DEA unit identifier is installed by the forms' setBoardId().

  3. The starting location of the data to be read into the packet buffer is installed using the forms' setIndex().

  4. The DeaManager::readSram() is provided with the proper request to fill the buffer provided, and returns when the data has been installed.

  5. Should the DeaManager encounter a difficulty in delivering the requested data, it will return an indication of the futility of continuing. rdSram() will use SwHouskeeper::report() to record the failure, will release() the packet buffer and return.

  6. The forms' post() initiates delivery of the packet. rdSram() determines when the request has been completed. It will continue to obtain a packet, load the header, and pass its buffer address and other parameters to readSram() until the request has been complete. When the request is completed, control is returned to the main process where the semaphore is made available to the next request using semaphore::release() (not shown).
27.4.4.4 Read DEA Program RAM

The DEA manager will support requests to deliver a copy of PRAM memory from one of the DEA CCD boards. The memory service will provide the packets needed to fulfill the request and will designate the packet location to begin loading data. It will specify which DEA CCD board memory is to be read, where to begin and how much may be stored in the buffer. Figure 129 illustrates these actions.

FIGURE 129. Process a read PRAM request.


  1. When a read from PRAM is requested, rdPram() is called. The scenario, again is similar; the calls to obtain a packet, and to load the header have the same names as in prior read requests.

  2. The DeaManager::readPram() is called with appropriate arguments to have the provided packet buffer loaded.

  3. If the DeaManager can not fulfill the request to deliver the data, it will return an indication of the failure. rdPram() will use SwHouskeeper::report() to record the condition, will release() the packet buffer and return.

  4. The forms' post() is used to initiate delivery of the packet. rdPram() determines when the request has been completed. It will continue to obtain a packet, load the header, and pass its buffer address and other parameters to readSram() until the request has been fulfilled. When the request is completed, control is returned to the main process where the semaphore is made available to the next request using semaphore::release() (not shown).

27.4.5 Use 4:: Write memory of the BEP, FEP, PRAM, and SRAM

As with the read memory scenario, each of the write requests will: verify arguments, obtain the control semaphore, and notify the main process thread. This task, goTaskEntry(), passes control to the designated function. The request may be handled directly, or may be handed to the respective interfacing manager which assists by fulfilling the request. The size of each write is restricted by the assumption that it could have been contained within a 128 word command packet. However; there is no restriction to the number of sequential writes commanded, nor to the client requesting the service. The write requests do not generate telemetry packets initiated by the MemoryServer.

Section 27.4.2 describes the client request of a service by selecting the MemoryServer public procedure which specifies the service desired, delivering the location to be targeted, and the relevant data needed to fulfill the task. The public function has stored the data to be copied into a private buffer.

27.4.5.1 Write data to Back End Processor memory

Figure 130 illustrates the process of fulfillment by describing the steps needed to over-write a section of the Back End Processors' memory.

FIGURE 130. Process a write BEP request


  1. Upon being alerted by notify(), sent by the client through the public functions, the main process thread, goTaskEvent(), handles the request by directing the BEP writing service function, wrtBep(), to process the request.

  2. The wrtBep() function uses isIcache() to test for an I_Cache write request so it may invoke the appropriate copying method.

  3. wrtBep() will call icachewrite() to write data in to the I cache or else it will overwrite the memory directly itself.

  4. With the request completed, control is returned to the main process, goTaskEntry() which will use semaphore::release() to free the semaphore and will return to wait for another request.
27.4.5.2 Write data to Front End Processor memory

Assistance from the FEP manager is required to copy data into the memory of one of the FEPs. The FEP manager will provide the copying service, whether to I_Cache, D_cache or bulk memory. The memory service will provide the address of the data and specify the location to be targeted. This is illustrated in Figure 131

FIGURE 131. Process a write FEP request


  1. A request to read FEP data follows about the same scenario as read BEP, above. goTaskEntry() calls wrtFep() to manage the data copy to the FEP memory.

  2. Provided with a target FEP identity, the buffer address that data is to be read from, the destination address that data is to be copied into and the amount to be copied; the wrtFep() will use FepManager::writeMemory() to fulfill the request.

  3. Should the FepManager encounter a difficulty in delivering the requested data, it will return a Boolean value indicating a failure to complete its mission. wrtFep() will use SwHouskeeper::report() to record the incident and return.

  4. goTaskEntry() will release() the semaphore and then wait for the next event notification to arrive.
27.4.5.3 Write data to DEA Sequencer RAM

The DEA manager will support requests to copy data into SRAM of one of the DEA CCD boards. The memory service will designate the buffer location from which to begin copying data. It will specify which DEA CCD board memory, data is to be written, where to begin and how much of SRAM is to be over-written. Figure 132 illustrates this scenario.

FIGURE 132. Process a write SRAM request


  1. When a write to SRAM is requested, goTaskEntry() calls wrtSram() to manage the data copy to the DEA SRAM.

  2. The DeaManager::writeSram() is called with appropriate arguments to have the designated DEA CCD board SRAM location loaded with the supplied data.

  3. If the DeaManager can not fulfill the request to over-write the memory, it will return an indication of the failure. wrtSram() will use SwHouskeeper::report() to record the condition and return.

  4. goTaskEntry() will use semaphore::release() to free the semaphore and then will wait for the next event notification to arrive.
27.4.5.4 Write data to DEA Program RAM

The DEA manager will support requests to copy data into PRAM of one of the DEA CCD boards. The memory service will designate the buffer location from which to begin copying data. It will specify which DEA CCD board memory is to be written to, where to begin and how much of PRAM is to be over-written. Figure 133 illustrates this scenario.

FIGURE 133. Process a write PRAM request


  1. When a write to PRAM is requested, goTaskEntry() calls wrtPram() to manage the data copy to the DEA PRAM.

  2. The DeaManager::writePram() is called with appropriate arguments to have the designated DEA CCD board PRAM location loaded with the supplied data.

  3. If the DeaManager can not fulfill the request to over-write the memory, it will return an indication of the failure. wrtPram() will use SwHouskeeper::report() to record the condition and return.

  4. goTaskEntry() will use semaphore::release() to free the semaphore and then wait for the next event.

27.4.6 Use 5:: Execute appropriate BEP or FEP memory

      The execute functions public interface checks the input, screening out attempts to execute in D_Cache. It obtains the control semaphore, stores the arguments and the target location, then notifies the main process which will invoke the private method used to fulfill the request. 

Note: the routine servicing this request will initiate execution of the target code as a subroutine. Either the MemoryServer function or its surrogate will become the executing thread; unless the process it activates is initiated as an independent thread which allows its initiator to return. Either way, if the execution time approaches the watchdog duration, the executing procedure must be able to handle the taskMonitor() interrogations. Another approach would be to have the task touch() the watchdog directly.

27.4.6.1 Execute code in Back End Processor memory

The public execute BEP function provides for (up to) twenty arguments with which to begin execution at the I_Cache or bulk memory address provided. When the executing process returns, the private fulfilling function, will include a one word (32bit) result in its telemetry buffer. Refer to Figure 134.

FIGURE 134. Process an execute BEP request


  1. Upon being alerted by notify(), sent by the client through the public function, the main process, goTaskEvent(), handles the request by directing the BEP execute service function, exeBep(), to process the request.

  2. It uses the form TfExecBep constructor to obtain a telemetry packet instance.

  3. It calls the MemoryServer function waitGetPacket() to supply a packet buffer.

  4. The subroutine checks whether the monitor has requested a response and uses waitForBuffer() which will linger for a stated period, before returning having succeeded or cycling to try again.

  5. exeBep() uses the forms' getBufferInfo() to determine the location of the packet buffer and its length.

  6. Then it uses the forms' setCmdId() to install the command identifier into the packet buffer.

  7. The forms' setTimeStamp() is used to provide a timing reference.

  8. exeBep() will call the memory location as an executable function (*target_address)(...) delivering the maximum number of arguments. The function, will only use the number it expects.

  9. After the targeted process returns, exeBep() will call to the forms' setReturnValue() to have data returned by the function inserted into the buffer.

  10. A call to the forms' post() will forward the packet for delivery.

  11. When the request is completed, control is returned to the main process where the semaphore is made available to the next request using semaphore::release() (not shown). goTaskEntry() will then wait for the next event.
27.4.6.2 Execute code in Front End Processor memory

The scenario for executing in FEP is similar to that for BEP. This request, however, uses the assistance of the FEP manager to take the arguments and initiate the execution. The public execute FEP function acquires the arguments to begins execution at the I_Cache or bulk memory address provided. The private fulfilling function, will include a one word (32bit) result in its telemetry buffer. Figure 135 illustrates this scenario.

FIGURE 135. Process an execute FEP request


  1. Upon being alerted by notify(), sent by the client through the public function, the main process, goTaskEvent(), handles the request by directing the FEP execute service function, exeFep(), to process the request.

  2. It uses the form TfExecFep constructor to obtain a telemetry packet instance, then, as with exeBep(), it calls the MemoryServer function waitGetPacket() to supply a packet buffer. The subroutine checks the monitor, as described in Section 27.4.3 , and uses waitGetPacket() which will linger for a stated period, before returning having succeeded or cycling to try again. Having obtained one, exeFep() uses the forms' getBufferInfo() to determine the location of the packet buffer and its length.

  3. Then it uses the forms' setCmdId() to install the command identifier, setTimeStamp() to provide a timing reference, and setFepId() to identify the targeted FEP.

  4. exeFep() will call the fepManager::executeMemory() specifying which FEP's memory to target, the memory location to begin execution, and the buffer location of the arguments to be used. When the result is returned, exeFep() will call the forms' setReturnValue() to have data word returned by the function inserted into the buffer.

  5. A call to the forms' post() will forward the packet for delivery.

  6. If the DeaManager can not fulfill the request to over-write the memory, it will return
    an indication of the failure. exeFep() will use SwHouskeeper::report() to record the condition and return.

  7. goTaskEntry() will use semaphore::release() to free the semaphore and then will wait for the next event to arrive.
27.4.6.3 Execute code in memory - Caveat

Note: that the routine servicing this request will initiate execution of the target code as a subroutine. It will become the executing thread; unless the process it activates is initiated as an independent thread which allows its initiator to return. Either way, if the execution time approaches the watchdog duration, the executing procedure must be able to handle the taskMonitor() interrogations. Another approach might be to touch() the watchdog directly.

27.4.7 Use 6: Read and telemetry configuration information

This feature is implemented using the Read Back End Memory feature (see Section 27.4.4 ). In addition to specifying the address and length of the region of memory to telemeter, the caller passes the telemetry format tag to use with the telemetered memory. This allows the ground to easily identify the region of memory, and structure of the information being sent, without resorting to looking up the address of the region being dumped.

27.5 Class MemoryServer

Documentation:
The MemoryServer is responsible for accomplishing direct reads, writes, and execution of memory requested by explicit commands. The operations use a semaphore in performing their functions which guarantees serial execution of the commands. Requests received while an operation is in progress, are rejected and the public function returns "CMDRESULT_BUSY".
Export Control:
Public
Cardinality:
1

Hierarchy:

Superclasses:

Task

Public Interface:

Operations:

MemoryServer()
executeBep()
executeFep()
goTaskEntry()
readBep()
readFep()
readPram()
readSram()
writeBep()
writeFep()
writePram()
writeSram()

Private Interface:

Has-A Relationships:


The rqst.... variables will contain the information which is being passed from the commanding function to the task servicing the request.

const unsigned* rqstAddrR:: Target Address provided by the current request. This is the BEP or FEP address from which to begin reading.

unsigned* rqstAddrW:: Target Address provided by the current
request. This is the BEP or FEP address to which to begin writing.

unsigned(*rqstExeAddr)(...) Address provided by the request. This is the BEP or FEP address at which to begin executing code.

unsigned rqstIndex:: Requested target index. This is the DEA index, location, from which to begin reading or to which to begin writing

unsigned rqstCnt:: Requested word or argument count. This is the number of items to be read or to be written; or the number of arguments being provided for execution of code.

FepId rqstFepId:: Requested hardware identifier. It is used to identify FEP to which the request is directed.

DeaCcdBdId rqstDeaId:: Requested hardware identifier. It is used to identify FEP to which the request is directed.

unsigned rqstCmdId:: Requests' command identification number.

unsigned rqstMemBuf[]:: The memory buffer which holds the data which will be used in fulfilling write or execute commands directed to the BEP or FEP.

DeaPramWord rqstPramBuf[]:: The memory buffer for use by write PRAM commands.

DeaSramWord rqstSramBuf[]:: The memory buffer for use by write SRAM commands.

void (*memFuncPtr)():: Denotes the MemoryServer service routine requested; rdBep(), wrtSram(), exeFep(), etc.

Semaphore lock:: Specifies the MemoryServer semaphore handle. The single semaphore insures serial processing of requests.

TlmFormatTag rqstRdBepTag:: This is the telemetry format tag to use when performing the current Back End Read Memory request.

Operations:

crossIBound()
exeBep()
exeFep()
getSemaphore()
rdBep()
rdFep()
rdPram()
rdSram()
waitGetPacket()
wrtBep()
wrtFep()
wrtPram()
wrtSram()
Concurrency:
Active
Persistence:
Persistent

27.5.1 MemoryServer()

Private member of:
MemoryServer

Arguments:

unsigned taskId
unsigned lockId
Documentation:
This constructor initializes the MemoryServer instance. taskId is this task's identifier and lockId is the semaphore used by this task. MemoryServer initializes the global variables. Refer to the private interface listing in section 27.5 "Class MemoryServer".
Concurrency:
Sequential

27.5.2 crossIBound()

Private member of:
MemoryServer
Return Class:
CmdResult

Arguments:

const unsigned* addr
unsigned wordCnt
Documentation:
crossIBound performs the checks to validate legal BEP & FEP addressing.
Semantics:
crossIBound checks the requested read/write range to insure that it does not cross into, or out of the I_cache boundary. The request must be totally within a memory area (I_Cache being between D_Cache and bulk memory). This function also checks that the address is on a word boundary.
Concurrency:
Guarded

27.5.3 exeBep()

Private member of:
MemoryServer
Return Class:
void
Documentation:
exeBep initiates execution at the address provided with the arguments provided and returns the resultant value.
Semantics:
exeBep will obtain a TfExecBep telemetry packet instance, and will use waitGetPacket to obtain a telemetry packet. It will use TfExecBep::getReadBuffer to obtain the packet storage location and its length. exeFep stores: the command identity from rqstCmdId into the buffer using TfCmdResponse::setCmdId, the BEP tick count from SystemClock::currentTime into the buffer using TfCmdResponse::setTimestamp. It then references the specified number of arguments (stored in rqstMemBuf), and begins execution at the memory location provided in rqstExeAddr. The code is executed as a subroutine of the memory server thread. When execution completes, it will install the return value into the telemetry buffer using TfExecBep::setReturnValue, then hand the packet off to the telemetry manager using TlmForms::post.
Note: if the execution time approaches the watchdog interval, provision must be made by the user, to have the executing process handle the taskMonitor interrogations.
Concurrency:
Guarded

27.5.4 executeBep()

Public member of:
MemoryServer
Return Class:
CmdResult

Arguments:

unsigned cmdIdent
unsigned(*execAddr)(...) 
const unsigned* argBuff
unsigned argCount
Documentation:
executeBep instructs the MemoryServer to store the accompanying arguments, and to initiate execution at the address provided.
Preconditions:
The address to execute must not be within D_Cache.
Semantics:
executeBep verifies that the address is not in D_Cache, and that the number of arguments is within bounds, else softwareHousekeeping is called and the status CMDRESULT_BAD_ARGUMENT is returned. executeBep attempts to acquire the MemoryServer semaphore. If it fails to acquire, the status CMDRESULT_BUSY is returned.
Having acquired the semaphore, the command data are stored: the command identifier; cmdIdent to rqstCmdId, the code address to begin execution; execAddr to rqstExecAddr, the number of arguments to copy; argCount to rqstCnt, and the arguments to be provided are copied from argBuff into rqstMemBuf. The address of the fulfilling function exeBep is stored in memFunsPtr. The MemoryServer event is set to notify goTaskEntry(), and the status CMDRESULT_OK is returned.
Postconditions:
The arguments and the location to be executed have been made available and the thread notified.
Concurrency:
Synchronous

27.5.5 exeFep()

Private member of:
MemoryServer
Return Class:
void
Documentation:
exeFep initiates execution by the Front End Process Manager, fepManager, on the designated FEP at the memory address provided, and with the arguments provided. Then it telemeters the returned result.
Semantics:
exeFep will obtain a TfExecFep telemetry packet instance, and will use waitGetPacket to obtain a telemetry packet. It will use TfExecFep::getReadBuffer to obtain the packet storage location and its length. exeFep stores: the command identity from rqstCmdId into the buffer using TfCmdResponse::setCmdId; the BEP tick count from SystemClock::currentTime into the buffer using TfCmdResponse::setTimestamp; the FEP identity into the buffer using TfReadFep::setFepIdentity. It then provides a pointer to the arguments (stored in rqstMemBuf), and directs the FEP manager to execute the code at the memory location provided in rqstExeAddr by calling fepManager::executeMemory. If the fepManager could not fulfill the request, notification is made by sending a SwHouskeeper::report; the packet will be released back to the pool from TlmForms::~TlmForm when control passes from the scope of exeFep. With this request completed, exeFep will install the return value into the telemetry buffer using TfExecFep::setReturnValue, then it will hand the packet off to the telemetry manager using TlmForms::post.
Note: if the execution time approaches the watchdog interval, the provision must be made by the user, to have the executing process handle the taskMonitor interrogations.
Concurrency:
Guarded

27.5.6 executeFep()

Public member of:
MemoryServer
Return Class:
CmdResult

Arguments:

unsigned cmdIdent
FepId identFep
unsigned(*execAddr)(...)
const unsigned* argBuff
unsigned argCount
Documentation:
executeFep instructs the MemoryServer to take the accompanying arguments, and initiate execution on the designated FEP at the address provided.
Preconditions:
The address to execute must not be within D_Cache.
Semantics:
executeBep verifies that the address is not in D_Cache, that the target address is on a word boundary, and the number of arguments is within bounds, else SwHousekeeper is called and the status CMDRESULT_BAD_ARGUMENT is returned. executeBep attempts to acquire the MemoryServer semaphore. If it fails to acquire, the status CMDRESULT_BUSY is returned
Having acquired the semaphore, the command data are stored: the command identifier; cmdIdent to rqstCmdId, the code address to begin execution; execAddr to rqstExecAddr, the number of arguments to copy; argCount to rqstCnt, and the arguments to be provided are copied from argBuff into rqstMemBuf. The address of the fulfilling function exeFep is stored in memFunsPtr. The MemoryServer event is set to notify goTaskEntry(), and the status CMDRESULT_OK is returned.
Postconditions:
The arguments and the location to be executed have been made available and the thread notified.
Concurrency:
Synchronous

27.5.7 goTaskEntry()

Public member of:
MemoryServer
Return Class:
void
Documentation:
goTaskEntry is initialized as the MemoryServer thread, and leaves the process waiting for its events. When alerted, it invokes the appropriate fulfilling function or taskMonitor response. On the functions return, it releases the semaphore and returns to waiting for an event.
Semantics:
The process waits FOREVER for its event, EV_REQUEST_SERVICE, or for the taskMonitor query, EV_TASKQUERY; to which it replies using taskMonitor::respond. When its event is received, it consumes the event, verifies and then invokes the appropriate function, which was designated during execution of the public function. On the subroutines' return; goTaskEntry releases the semaphore, invalidates the function address, and cycles to wait for an event.
Postconditions:
The process is waiting FOREVER for one of its events or for the taskMonitor query request.
Concurrency:
Sequential

27.5.8 getSemaphore()

Private member of:
MemoryServer
Return Class:
CmdResult
Documentation:
getSemaphore attempts to obtain the MemoryServer semaphore which is required before executing the requested service.

Semantics:

getSemaphore uses the Semaphore::request function when attempting to obtain the semaphore; succeeding it returns CMDRESULT_OK, else it returns CMDRESULT_BUSY.
Concurrency:
Guarded

27.5.9 readBep()

Public member of:
MemoryServer
Return Class:
CmdResult

Arguments:

unsigned cmdIdent
Const unsigned* addr
unsigned readCount
TlmFormatTag tag
Documentation:
readBep() posts a request to the MemoryServer main thread goTaskEntry() to initiate a memory read from the Back End Processor memory at the address provided. The service will use rdBep() to deliver the number of words requested.
Semantics:
The target area specifications are verified using crossIBound(), else the status DATA_ERROR is returned. The MemoryServer semaphore must be acquired or the status CMDRESULT_BUSY is returned. Having acquired the semaphore, the command data are stored: the command identifier; cmdIdent to rqstCmdId, the address to begin reading from; addr to rqstAddrR, and the number of 32 bit words to read and deliver; readCount to rqstCnt. The address of the fulfilling function rdBep() is stored in memFuncPtr. The telemetry format tag to use when sending the region, tag, is stored in rqstRdBepTag. The MemoryServer event is set to notify the autonomous task goTaskEntry(), and the delivered status CMDRESULT_OK is returned.
Postconditions:
The beginning location and the amount of data to be delivered have been made available in global variables and the thread notified. The total amount of memory to be read will be delivered in one or more packets.
Concurrency:
Synchronous

27.5.10 readFep()

Public member of:
MemoryServer

Return Class:

CmdResult

Arguments:

unsigned cmdIdent
FepId identFep
const unsigned* addr
unsigned readCount
Documentation:
readFep instructs the MemoryServer to initiate a memory read of a number of words by the specified Front End Processor at the address provided.
Preconditions:
Memory to be read must not cross the D_Cache / I_Cache boundary, nor the I_Cache / Bulk boundary.
Semantics:
The target area specification are verified using crossIbound. Any error conditions are passed to softwareHousekeeping, and the status CMDRESULT_BAD_ARGUMENT is returned.
The memoryServer semaphore must be acquired or the status CMDRESULT_BUSY is returned. Having acquired the semaphore, the command data are stored: the command identifier; cmdIdent to rqstCmdId, the FEP from which the memory is to be read; identFep to rqstFepId, the address to begin reading from; addr to rqstAddrR, and the number of 32 bit words to read and deliver; readCount to rqstCnt. The address of the fulfilling function rdFep() is stored in memFuncPtr. The MemoryServer event is set to notify the autonomous task goTaskEntry(), and the delivered status CMDRESULT_OK is returned.
Postconditions:
The beginning location and the amount of data to be delivered have been made available and the task notified.
Concurrency:
Synchronous

27.5.11 readPram()

Public member of:
MemoryServer
Return Class:
CmdResult

Arguments:

unsigned cmdIdent
DeaCcdBdId identPram
unsigned index
unsigned readCount
Documentation:
readPram instructs the MemoryServer to initiate a memory read of a specified number of words from the identified DEA board PRAM by the DEA manager, deaManager.
Semantics:
The validity of the arguments having been checked beforehand, readPram attempts to acquire the MemoryServer semaphore. If it fails to acquire, the return status CMDRESULT_BUSY is returned.
Having acquired the semaphore, the command data are stored: the command identifier; cmdIdent to rqstCmdId, the DEA from which the memory is to be read; identPram to rqstDeaId, the index to begin reading from; index to rqstIndex, and the number of PRAM words to read and deliver; readCount to rqstCnt. The address of the fulfilling function rdPram() is stored in memFuncPtr. The MemoryServer event is set to notify the autonomous task goTaskEntry(), and the delivered status CMDRESULT_OK is returned.
Postconditions:
The beginning location and the amount of data to be delivered have been made available and the thread notified.
Concurrency:
Synchronous

27.5.12 readSram()

Public member of:
MemoryServer
Return Class:
CmdResult

Arguments:

unsigned cmdIdent
DeaCcdBdId identSram
unsigned index
unsigned readCount
Documentation:
readSram instructs the MemoryServer to initiate a memory read of a specified number of words from the identified DEA board SRAM by the DEA manager, deaManager.
Semantics:

The validity of the arguments having been checked beforehand, readSram attempts to acquire the MemoryServer semaphore. If it fails to acquire, the return status CMDRESULT_BUSY is returned.
Having acquired the semaphore, the command data are stored: the command identifier; cmdIdent to rqstCmdId, the DEA from which the memory is to be read; identSram to rqstDeaId, the index to begin reading from; index to rqstIndex, and the number of SRAM words to read and deliver; readCount to rqstCnt. The address of the fulfilling function rdSram() is stored in memFuncPtr. The MemoryServer event is set to notify the autonomous task goTaskEntry(), and the delivered status CMDRESULT_OK is returned.
Postconditions:
The beginning location and the amount of data to be delivered have been made available and the thread has been notified.
Concurrency:
Synchronous

27.5.13 rdBep()

Private member of:
MemoryServer
Return Class:
void
Documentation:
rdBep reads BEP memory and loads it into telemetry buffers.
Semantics:
rdBep determines if the address from which to read data is in I_cache using mongoose::isIcache. It then enters a loop, obtains a TfReadBep telemetry packet instance, and uses waitGetPacket which returns when the packet buffer is available. rdBep uses getReadBuffer to obtain the packet storage location and its length. rdBep stores: the command identity from rqstCmdId into the buffer using TfCmdResponse::setCmdId, the BEP tick count from SystemClock::currentTime into the buffer using TfCmdResponse::setTimestamp, copies the target address which begins this read, and the length of data to be read, into the buffer using TfReadBep::setMemAddr and TfReadBep::setReadLength, respectively. It reads the memory, writing it into the buffer directly or by using the I_Cache read memory utility Mongoose::icacheRead. rdBep uses TlmForms::post to hand the packet off to the telemetry manager. Having adjusted the address for the amount of memory copied, it decrements that amount from the requested length. This cycle continues until the request has been fulfilled.
Concurrency:
Guarded

27.5.14 rdFep()

Private member of:
MemoryServer
Return Class:
void
Documentation:
rdFep oversees reading of FEP memory by the FEP manager and provides and forwards telemetry buffers.
Semantics:
rdFep enters a loop, obtains a TfReadFep telemetry packet instance, and uses waitGetPacket to request a telemetry packet buffer, returning when one is available. rdFep uses TfReadFep::getReadBuffer to obtain the packet storage location and its length. rdFep stores: the command identity from rqstCmdId into the buffer using TfCmdResponse::setCmdId; the BEP tick count from SystemClock::currentTime into the buffer using TfCmdResponse::setTimestamp; the FEP identity into the buffer using TfReadFep::setFepIdentity; and copies the target address which begins this read, and the length of data to be read, into the buffer using TfReadFep::setMemAddr and TfReadFep::setReadLength, respectively. It determines the length of data to be loaded into the packet buffer and calls the Front End Processor Manager requesting that memory be copied from the designated FEPs' specified address to the telemetry buffer address using fepManager::readMemory. When the manager returns, if it could not fulfill the request, notification is made by sending a SwHouskeeper::report; the packet will be released back to the pool from TlmForms::~TlmForm when control passes from control of the loop in which it was invoked. With this request completed, rdFep will hand the packet to the telemetry manager using TlmForms::post, decrement the length of memory to be read, and increment the address. This cycle continues until all of the request has been fulfilled.
Concurrency:
Guarded

27.5.15 rdPram()

Private member of:
MemoryServer
Return Class:
void
Documentation:
rdPram initiates a memory read by the Detector Electronics Assembly Manager, deaManager, from the designated DEA at the index provided, and telemeters the returned result.
Semantics:
rdPram begins a loop, obtains a TfReadPram telemetry packet instance, passing rqstRdBepTag as the tag to use for packets formatted by the instance, and uses waitGetPacket to request a telemetry packet buffer, returning when one is available. rdPram uses TfReadPram::getReadBuffer to obtain the packet storage location and its length. rdPram stores: the command identity from rqstCmdId into the buffer using TfCmdResponse::setCmdId; the BEP tick count from SystemClock::currentTime into the buffer using TfCmdResponse::setTimestamp; and the DEA identity into the buffer using TfReadPram::setBoardId. It determines the length of data to be loaded into the packet buffer then copies the target index at which this read begins, and the length of data to be read, into the buffer using TfReadPram::setIndex and TfReadPram::setReadCount, respectively. rdPram calls the Detector Electronics Assembly Manager requesting that memory be copied from the designated DEA boards' specified index to the telemetry buffer address using deaManager::readPram. When the manager returns, if it could not fulfill the request, notification is made by sending a SwHouskeeper::report; the packet buffer will be released back to the pool from TlmForms::~TlmForm when control passes from the scope of the loop in which it was invoked. With this request completed, rdPram will hand the packet to the telemetry manager using TlmForms::post, decrement the count of PRAM words to be read, and increment the index from which to read. This cycle continues until the request has been fulfilled.
Concurrency:
Guarded

27.5.16 rdSram()

Private member of:
MemoryServer
Return Class:
void
Documentation:
rdSram initiates a memory read by the Detector Electronics Assembly Manager, deaManager, from the designated DEA board at the index provided, and telemeters the returned result. rdSram provides the packet buffers and posts them when filled.
Semantics:
rdSram begins a loop, obtains a TfReadSram telemetry packet instance, and uses waitGetPacket to request a telemetry packet buffer, returning when one is available. rdSram uses TfReadSram::getReadBuffer to obtain the packet storage location and its length. rdSram stores: the command identity from rqstCmdId into the buffer using TfCmdResponse::setCmdId; the BEP tick count from SystemClock::currentTime into the buffer using TfCmdResponse::setTimestamp; and the DEA identity into the buffer using TfReadSram::setBoardId. It determines the length of data to be loaded into the packet buffer then copies the target index at which this read begins, and the length of data to be read, into the buffer using TfReadSram::setIndex and TfReadSram::setReadCount, respectively. rdSram calls the Detector Electronics Assembly Manager requesting that memory be copied from the designated DEA boards' specified index to the telemetry buffer address using deaManager::readSram. When the manager returns, if it could not fulfill the request, notification is made by sending a SwHouskeeper::report; the packet buffer will be released back to the pool from TlmForms::~TlmForm when control passes from the scope of the loop in which it was invoked. With this request completed, rdSram will hand the packet to the telemetry manager using TlmForms::post, decrement the count of SRAM words to be read, and increment the index from which to read. This cycle continues until the request has been fulfilled.
Concurrency:
Guarded

27.5.17 waitGetPacket()

Private member of:
MemoryServer
Return Class:
void

Arguments:

TlmForm &pkt
Documentation:
waitGetReply waits for a packet to become available while insuring that taskMonitor queries are acknowledged.

Semantics:

waitGetPacket begins with a loop that checks the taskMonitor EV_TASKQUERY event and responds if it is set. It then waits using TlmForm::waitForBuffer for a period specified by GET_PKT_TIME_OUT, for a packet buffer to become available. When one is available, it returns and pkt has a buffer. If the wait times out before a packet is available, it cycles, checking taskMonitor query and waiting again for a packet to become available. waitGetPacket does not return without a packet.
Postconditions:
A packet instance with generic header and memory buffer is available to be filled with the requested data.
Concurrency:
Guarded

27.5.18 writeBep()

Public member of:
MemoryServer
Return Class:
CmdResult

Arguments:

unsigned cmdIdent
unsigned* addr
const unsigned* srcBuff
unsigned writeCount
 
Documentation:
writeBep instructs the MemoryServer to initiate a memory write of the associated data to the Back End Processor address provided.
Preconditions:
Memory to be written must be wholly within D_Cache or within I_Cache or within Bulk. It may not cross the I_Cache boundary.
Semantics:
The target area specifications are verified using crossIBound, else the status CMDRESULT_BAD_ARGUMENT is returned. writeBep confirms that the amount of data to be written will fit in the private buffer, else it returns CMDRESULT_BAD_ARGUMENT. It attempts to acquire the MemoryServer semaphore. If it fails to acquire, the return status CMDRESULT_BUSY is returned.
Having acquired the semaphore, the command data are stored: the command identifier; cmdIdent to rqstCmdId, the address at which to begin writing; addr to rqstAddrW, and the number of 32 bit words to write and deliver; writeCount to rqstCnt. The address of the fulfilling function wrtBep() is stored in memFuncPtr. The MemoryServer event is set to notify the autonomous task goTaskEntry(), and the delivered status CMDRESULT_OK is returned.
Postconditions:
The total data to be written and its location have been made available and the thread notified.
Concurrency:
Synchronous

27.5.19 writeFep()

Public member of:
MemoryServer
Return Class:
CmdResult

Arguments:

unsigned cmdIdent
FepId identFep
unsigned* addr
const unsigned* srcBuff
unsigned writeCount
Documentation:
writeFep instructs the MemoryServer to initiate a memory write of the associated data into the specified Front End Processor memory at the address provided.
Memory to be written must be within D_Cache or within I_Cache or within Bulk. It must not cross the I_Cache boundary
Semantics:
The target area specifications are verified using crossIBound, and writeBep confirms that the amount of data to be written will fit in the private buffer, else it returns CMDRESULT_BAD_ARGUMENT. It attempts to acquire the MemoryServer semaphore. If it fails to acquire, the return status CMDRESULT_BUSY is returned.
Having acquired the semaphore, the command data are stored: the command identifier; cmdIdent to rqstCmdId, the FEP who's memory is to be overwritten; identFep to rqstFepId the address at which to begin writing; addr to rqstAddrW, and the number of 32 bit words to write and deliver; writeCount to rqstCnt, and the data to be written is copied from srcBuff into rqstMemBuf. The address of the fulfilling function wrtFep() is stored in memFuncPtr. The MemoryServer event is set to notify goTaskEntry(), and the delivered status CMDRESULT_OK is returned.
Postconditions:


The total data to be written and its location have been made available and the thread notified.
Concurrency:
Synchronous

27.5.20 writePram()

Public member of:
MemoryServer
Return Class:
CmdResult

Arguments:

unsigned cmdIdent
DeaCcdBdId identPram
unsigned index
const DeaPramWord* srcBuff
unsigned writeCount
Documentation:
writePram instructs the MemoryServer to initiate a memory write of the associated data to the identified DEA board PRAM by the DEA manager.
Semantics:
The length of data to be written is checked against the local buffer size. If the data exceeds the buffer size, softwareHousekeeping is called and the status CMDRESULT_BAD_ARGUMENT is returned. writeSram attempts to acquire the MemoryServer semaphore. If it fails to acquire, the status CMDRESULT_BUSY is returned.
Having acquired the semaphore, the command data are stored: the command identifier; cmdIdent to rqstCmdId, the DEA who's memory is to be overwritten; identPram to rqstDeaId the index at which to begin writing; index to rqstIndex, and the number of PRAM words to write and deliver; writeCount to rqstCnt, and the data to be written is copied from srcBuff into rqstPramBuf. The address of the fulfilling function wrtPram() is stored in memFuncPtr. The MemoryServer event is set to notify goTaskEntry(), and the status CMDRESULT_OK is returned.
Postconditions:
The total data to be written and its location have been made available and the thread notified.
Concurrency:
Synchronous

27.5.21 writeSram()

Public member of:
MemoryServer
Return Class:
CmdResult

Arguments:

unsigned cmdIdent
DeaCcdBdId identSram
unsigned index
const DeaSramWord* srcBuff
unsigned writeCount
Documentation:
writeSram instructs the MemoryServer to initiate a memory write of the associated data to the identified DEA board SRAM by the DEA manager.
Semantics:
The length of data to be written is checked against the local buffer size. If the data exceeds the buffer size, softwareHousekeeping is called and the status CMDRESULT_BAD_ARGUMENT is returned. writeSram attempts to acquire the MemoryServer semaphore. If it fails to acquire, the status CMDRESULT_BUSY is returned.
Having acquired the semaphore, the command data are stored: the command identifier; cmdIdent to rqstCmdId, the DEA who's memory is to be overwritten; identSram to rqstDeaId the index at which to begin writing; index to rqstIndex, and the number of SRAM words to write and deliver; writeCount to rqstCnt, and the data to be written is copied from srcBuff into rqstSramBuf. The address of the fulfilling function wrtSram() is stored in memFuncPtr. The MemoryServer event is set to notify goTaskEntry(), and the delivered status CMDRESULT_OK is returned.
Postconditions:


The total data to be written and its location have been made available and the thread notified.
Concurrency:
Synchronous

27.5.22 wrtBep()

Private member of:
MemoryServer
Return Class:
void
Documentation:
wrtBep writes data into BEP memory.
Semantics:
wrtBep determines if the address from which to read data is in I_Cache using mongoose::isIcache, writes the data provided (previously stored in rqstMemBuf) into memory beginning at the address specified in rqstAddrW either directly or by using the I_Cache read memory utility mongoose::icacheWrite. The maximum data length is limited to the maximum command packet data space. There is no telemetered response.
Concurrency:
Guarded

27.5.23 wrtFep()

Private member of:
MemoryServer
Return Class:
void
Documentation:
wrtFep over sees data write by the designated FEP into memory.
Semantics:
wrtFep calls the Front End Processor Manager requesting a write by the designated FEP of the referenced data (stored in rqstMemBuf) beginning at the specified address using fepManager::writeMemory. When the manager returns, if the FEP manager could not fulfill the request, notification is made by sending a SwHouskeeper::report. When the manager returns, if it could not fulfill the request, notification is made by sending a SwHouskeeper::report. Then this process returns.
Concurrency:
Guarded

27.5.24 wrtPram()

Private member of:
MemoryServer
Return Class:
void
Documentation:
wrtPram oversees write of the provided data by the Detector Electronics Assembly Manager, deaManager, to the specified DEA subsection PRAM at the index provided.
Semantics:
wrtPram calls the Detector Electronics Assembly Manager requesting a write of PRAM words contained in rqstPramBuf to the designated DEA board PRAM index. When the manager returns, if it could not fulfill the request, notification is made by sending a SwHouskeeper::report. Then this process returns.
Concurrency:
Guarded

27.5.25 wrtSram()

Private member of:
MemoryServer
Return Class:
void
Documentation:
wrtSram oversees write of the provided data by the Detector Electronics Assembly Manager, deaManager, to the specified DEA subsection SRAM at the index provided.
Semantics:
wrtSram calls the Detector Electronics Assembly Manager requesting a write of SRAM words contained in rqstSramBuf to the designated DEA board SRAM index. When the manager returns, if it could not fulfill the request, notification is made by sending a SwHouskeeper::report. Then this process returns.
Concurrency:
Guarded
 

Table of Contents Next Chapter