Table of Contents Previous Chapter ACIS

25.0 Front End Processor Management Classes (36-53217 B)

25.1 Purpose

The purpose of the Front End Processor Management classes, which run on the Back End Processor, are to manage the shared-memory protocol between the Back End Processor and each of the Front End Processors, and to provide general purpose Front End Processor science and diagnostic functions.

This section describes two classes, the FepManager class, and the FepIoManager class.

25.2 Uses

The following lists the primary uses of the Front End Processor Management classes:

  1. Control Power to each of the Front End Processors

  2. Reset, load, and run a program on a Front End Processor

  3. Read a Front End Processor's Memory

  4. Write to a Front End Processor's Memory

  5. Execute a subroutine loaded into a Front End Processor

  6. Configure a Front End Processor for a science run

  7. Start bias calibrations on all configured Front End Processors

  8. Start data processing on all configured Front End Processors and acquire science data from the Front End Processors

  9. Stop bias or data processing on all configured Front End Processors

  10. Disable a Front End Processor for use by science processing

  11. Write a bad pixel code and its parity into the pixel bias map and parity plane

25.3 Organization

Figure 105 illustrates the class relationships used by the Front End Processor Manager, FepManager, and the I/O Management class, FepIoManager.

FIGURE 105. FEP Manager and I/O Manager Classes


FepManager - This class is a subclass of Executive::Task and is responsible for the overall management of the Front End Processors. This class provides functions to power off all Front End's and to run new programs (powerOff, loadRunProgram), to read and write FEP memory and to execute subroutines loaded within a FEP (readMemory, writeMemory, executeMemory), to configure a FEP to prepare for a science run (configureFep), to start FEP bias and data processing operations (invokeBiasProcess, invokeDataProcess), and to acquire data from the running FEPs and to stop current FEP processes (consumeData, terminateProcess). There is only one instance of this class within ACIS, called fepManager.

FepIoManager - This class is responsible for providing access to the Front End Processor's shared-memory Command Mailbox and Science Data Ring Buffer. There is one instance of this class for each Front End Processor in the instrument. This class provides functions, primarily for use by the FepManager, to determine the maximum amount of data that can be sent to the FEP via its command mailbox (getMaxCmdArgs), to determine if the FEP's ring buffer contains any data (hasData), to issue a command to the FEP and wait for its response (issueCmd), to read data from the FEP's ring buffer (readData), and to establish the mailbox and ring buffer addresses used by the program currently running in the FEP (setIoAddresses). Access to instances of this class are performed via an array of pointers, fepIo[]. The array is indexed by the Front End Processor enumeration, FepId.

FepCallback - This class is a subclass of Devices::DevCallback. It is used by the FepManager to obtain control during the processing of Front End Processor Interrupts. Its invoke() member function is responsible for passing control to the FepManager's serviceDevice() function during Front End Processor Interrupt handling. There is one instance of this class within ACIS, called fepCallback.

DevCallback - This abstract class is defined by the Devices class category, and is responsible for defining the common interface to all device interrupt callback classes. It is described in more detail in Section 6.0.

FepDevice - This class is responsible for providing access to the control hardware for each Front End Processor. There is one instance of this class for each Front End Processor in the system. Both the FepManager and FepIoManager classes use this class to query and control the Front End Processor hardware registers. Access to instances of this class are performed via an array of pointers, fepDevice[]. The array is indexed by the Front End Processor enumeration, FepId. This class is defined in more detail in Section 10.0.

TaskManager - This class is defined by the Executive class category and is responsible for managing the overall task scheduling. It is used by the FepManager and FepIoManager classes to obtain access to the currently running task (queryCurrentTask()).

TaskMonitor - This class is defined by the Executive class category, and is a subclass of Task. It is responsible for polling each task in the instrument, and maintaining the watchdog timer. If any task fails to respond in a timely fashion, this task will fail to touch the watchdog, and the instrument will be reset. See Section 15.0 for more detail.

Task - This abstract class is defined by the Executive class category, and responsible for representing a thread of control within the instrument. The FepManager is a subclass, and also contains a pointer to an instance of this class (clientTask). See Section 15.0 for more detail.

Semaphore - This class is defined by the Executive class category. Each FepIoManager instance contains a Semaphore instance (lock) and uses it to arbitrate for access to the Front End Processor's Command Mailbox. See Section 15.0 for more detail.

25.4 Miscellaneous Items

25.4.1 FepManager Auxiliary Service Routine task

The FepManager uses a task to poll for requests and conditions (i.e. this assumes that reaction times are on the order of a half a second) from the Front End Processors. This task consists of a main polling loop, which sleeps for 0.2 second (TBD) on each iteration. From a black-box point of view, the existence of this task is transparent to the client code, and is used only as part of the manager's internal implementation.

25.4.2 FEP Mailbox and Ring-buffers

The software running on each Front Processor establishes a Command Mailbox and a science data ring-buffer in its shared memory space. The mailbox consists of a state variable, a length field, and data. The state variable controls what is currently contain in the mailbox, and which processor has write access to the box. The length field indicates how much data is in the mailbox. The science data ring buffer consists of a series of blocks, where each block consists of thirty two, 32-bit words. The ring buffer uses a shared-memory control structure containing a read index and write index. As the FEP writes blocks into the ring buffer, it advances the write index. As the BEP reads blocks, it advances the read index. When the read and write indices are the equal, the ring buffer is empty. When the write index is equal to the slot just prior to the read index, the ring buffer is full. For a more detailed description of the structure and content of BEP to FEP interface, refer to Section 4.9 and Section 4.10.

25.5 Scenarios

25.5.1 Use 1: Power off a FEP

Figure 106 illustrates the sequence of events when a client instructs the FEP Manager to turn off power to a Front End Processor. NOTE: Powering off a FEP destroys any work-in-progress and information contained on that FEP, including the pixel bias map values.

FIGURE 106. Power off FEP


  1. The client instructs the FEP Manager to turn off power to a Front End Processor, using fepManager.powerOff().

  2. fepManager.powerOff() calls disableFep() to take the current FEP out of its list of enabled FEPs.

  3. The loop body then indexes the FEP device pointer, and invokes its fepDevice.powerOff() function to turn off the power to the Front End Processor.

25.5.2 Use 2: Reset, load, and run a program on a Front End Processor

Figure 107 illustrates the actions used to reset a Front End Processor, and to load and run a program on a Front End Processor. In this diagram, fepIo represents instances of the FepIoManager class.

FIGURE 107. Resetting and loading and running a program on a FEP


  1. The client instructs the FEP Manager to reset the FEP, and load and run a program, using fepManager.loadRunProgram().

  2. loadRunProgram() ensures that the FEP has power, using fepDevice.powerOn()

  3. loadRunProgram() ensures the FEP is reset, using fepDevice.holdReset().

  4. loadRunProgram() checks the passed program pointer (not shown). If no program is specified, the FEP is left in a reset state. If a program is specified, then the fepManager extracts the mailbox and ring-buffer addresses from the program header and passes them to the FEP's I/O manager, fepIo.setIoAddresses().

  5. setIoAddresses() then maps the FEP addresses into the shared memory region of the Back End Processor, using fepDevice.mapAddress().

  6. loadRunProgram() then calls loadSections() to copy all code and data sections, mapped to shared memory regions, into the FEP's memory.

  7. loadSections() iterates through each program section, using fepDevice.mapAddress() to determine if a section is mapped to shared memory, and if so, to convert the FEP address into the corresponding BEP's shared memory address. loadSections() and then uses mongoose.copyWords() (not shown) to copy the section's code and/or data directly into the FEP memory.

  8. Once all shared memory sections have been loaded, loadRunProgram() calls fepDevice.releaseReset() to allow the FEP to execute the partially loaded code (NOTE: This assumes that the program contains a section loaded at the Reset Vector). At this point, the fepManager assumes that the code running on the FEP is capable of handling Write Memory, and Execute Memory requests, sent via the FEP's Command MailBox.

  9. loadRunProgram() then calls loadSections() again, this time specifying that it should load only sections which are not located contained in shared memory.

  10. loadSections() iterates through the program sections, using fepDevice.mapAddress() to determine if a section is not contained in shared memory (not shown). It then calls the FepManager's writeMemory() function which uses the Command Mailbox to instruct the FEP to load the contents of these sections into its memory. writeMemory() accesses the FEP's Command Mailbox using the I/O manager's issueCmd() member function.

  11. Once all of the sections have been loaded, loadRunProgram() extracts the start execution address from the program header, and uses executeMemory() to cause the FEP to execute from the start of its completely loaded program. executeMemory() uses the I/O Manager's issueCmd() function to send the request (not shown). At this point, the FEP is up and running the loaded program.

25.5.3 Use 3: Read FEP Memory

Figure 108 illustrates the steps invoked in reading a section of a FEP's memory.

FIGURE 108. Read FEP Memory


  1. client requests the contents of a FEP's memory, issuing fepManager.readMemory(), which blocks until the request is satisfied, or until an error is detected.

  2. readMemory() determines if the requested region is within shared memory using fepDevice.mapAddress(), and if so, passes the supplied address to mongoose.copyWords() (not shown) to copy the region directly out of the FEP, and returns.

  3. If the requested region is not contained within the FEP's shared memory region, readMemory() check that the request does not cross an instruction cache boundary within the FEP, and returns an error of so (not shown). If the requested region does not cross an instruction cache boundary, readMemory() enters a loop to copy the region out in sections, using the FEP's Command Mailbox. The loop uses mongoose.isIcache() (not shown) to determine if the mailbox request is for a read from memory, or a read from instruction cache.The loop then determines the amount of data that can be read by one command, using fepIo.getMaxCmdArgs().

  4. readMemory() issues a request to the I/O manager to read a portion of the memory, using fepIoManager.issueCmd().

  5. issueCmd() attempts to obtain exclusive access to the FEP's Command Mailbox, using waitForLock().

  6. waitForLock() attempts to obtain the semaphore, using lock.waitFor().

  7. waitForLock() ensures that the FEP is powered on, using fepDevice.hasPower()

  8. waitForLock() ensure that the FEP is not in a reset or crashed state using fepDevice.isReset().

  9. If waitForLock() is successful, issueCmd() copies the command information into the FEP's Command Mailbox, and sets its state to indicate that a new message is present (not shown). It then calls waitForReply() to wait until the FEP processes the command.

  10. waitForReply() obtains a pointer to the currently running task, using taskMonitor.queryCurrentTask().

  11. It then enters a polling loop, which terminates when either the FEP's Command Mailbox state no longer indicates that it contains a new message, until the loop's counter expires, or until the FEP loses power (hasPower()) or is reset (isReset()). Upon each iteration, the loop invokes Task::sleep() to allow other tasks to run. Meanwhile, the FEP periodically polls the mailbox. When it sees that a new message is ready, it executes the read-memory command, copying the requested memory region into the mailbox, and setting the box state indicating that a reply is ready (not shown). waitForReply() detects that the reply is ready, copies the FEP supplied memory contents into the caller's data buffer and returns.

  12. Once waitForReply() returns, issueCmd() calls lock.release() to allow other tasks to use the FEP's Command Mailbox.

  13. Upon each issueCmd() iteration, readMemory() calls checkMonitor() to ensure that the Task Monitor does not reset the instrument during a long memory read.

  14. checkMonitor() uses taskManager.queryCurrentTask() to get a pointer to the currently running task.

  15. checkMonitor() then uses Task::requestEvent() to test for a query from the monitor.

  16. If a monitor request is present, checkMonitor() calls taskMonitor.respond() on behalf of the running task.

25.5.4 Use 4: Write FEP Memory

The scenario invoked in writing to the contents of a FEP's memory is very similar to that to Use 3: Read FEP Memory. Instead of calling readMemory(), the client calls fepManager.writeMemory(). writeMemory() then performs similar control operations to readMemory(), except that it uses mongoose.copyWords() to write the contents of FEP shared memory, and issues Write Memory Command Mailbox requests, rather than read requests, for writes to local memory regions.

25.5.5 Use 5: Execute FEP Subroutine

Figure 109 illustrates the steps involved in invoking a subroutine on a FEP.

FIGURE 109. Call FEP Subroutine


  1. client tells the FEP Manager to invoke a subroutine on a particular Front End Processor, using fepManager.executeMemory().

  2. executeMemory() forms and issues the request to the FEP, using fepIo.issueCmd().

  3. issueCmd() attempts to obtain exclusive access to the FEP's Command Mailbox, using waitForLock().

  4. waitForLock() waits for and obtains the mailbox's semaphore, using lock.waitFor().

  5. Once lock.waitFor() returns, waitForLock() tests to ensure that the FEP has power using fepDevice.hasPower().

  6. waitForLock() then checks to make sure the FEP has not been reset, using fepDevice.isReset().

  7. Once the lock to a powered and running FEP is obtained, issueCmd() writes the request to the FEP's Command Mailbox, and sets the mailbox state indicating a new message (not shown). issueCmd() then waits for a response from the FEP using waitForReply().

  8. waitForReply() gets a pointer to the currently running task, using taskManager.queryCurrentTask().

  9. waitForReply() enters a polling loop, testing the mailbox state to detect when a reply has been written by the FEP. The loop terminates when either a response has been written, the FEP is powered off, the FEP is reset, or the loop's iteration counter expires. Within the body of the loop, waitForReply() calls sleep() (for a TBD number of BEP timer ticks) on the current task to allow other processes to run.

  10. Meanwhile, the FEP eventually reads its Command Mailbox and calls the indicated subroutine. Once the subroutine returns, the FEP writes the return value of the function back into the mailbox, and sets its state to indicate that a reply is ready. Back on the BEP, waitForReply() detects the response, and returns to issueCmd(). issueCmd() then releases the mailbox, by calling lock.release(). issueCmd() then returns to the fepManager, which in turn, returns to its client.

25.5.6 Use 6: Configure a FEP for a science run

Figure 110 illustrates the steps used to prepare a Front End Processor to perform bias calibrations, or process CCD data.

FIGURE 110. Configure FEP


  1. client configures a Front End Processor by calling fepManager.configureFep() indicating which CCD's is to be processed by the FEP and passing a parameter block to be used by the FEP.

  2. Prior to setting the FEP's CCD selection in the FEP hardware, fepManager.configureFep() tests that the FEP is powered on, using fepDevice.hasPower().

  3. configureFep() then tells the FEP hardware which CCD to listen to, using fepDevice.selectCcd().

  4. configureFep() then issues a command to the FEP to load the parameter block, using fepIo.issueCmd() (see Use 3: Read FEP Memory, or Use 5: Execute FEP Subroutine for descriptions of the behavior of issueCmd()). If the load is successful, the FEP has registered the parameter block. configureFep() then adds the FEP to its list of enabled Front End Processors. Subsequent calls to invokeBiasProcess(), invokeDataProcess(), terminateProcess(), and readRecord() use this list to determine which FEPs to act on.

25.5.7 Use 7: Start bias calibrations

Figure 111 illustrates the steps used to start a bias calibration on all of the configured Front End Processors (see Use 6: Configure a FEP for a science run).

FIGURE 111. Start FEP Bias Calibrations


  1. Upon each iteration of its main loop, the FEP Manager's main task loop (goTaskEntry) suspends execution using sleep(), allowing other tasks to run. Periodically, the task wakes up and checks for taskMonitor queries, FEP crashes, bias completions or data availability.

  2. client informs the FEP Manager which task to notify, and with which events, when a bias calibration completes, when data becomes available, and if all of the configured FEPs should crash, using fepManager.registerClient().

  3. client tells the FEP Manager to start bias calibrations on all of the configured FEPs, using invokeBiasProcess().

  4. fepManager.invokeBiasProcess() loops through each configured FEP, using fepIo.issueCmd() to tell the FEP to start its bias calibration (see Use 3: Read FEP Memory, or Use 5: Execute FEP Subroutine for descriptions of the behavior of issueCmd()).

  5. client then starts the DEA sequencer, recording the microsecond science time stamp associated with the start of the sequence (not shown). client then suspends until the bias calibration on all of the configured FEPs complete, until an error occurs, or until commanded to abort the current process, using waitForEvent().

  6. Periodically, the fepManager task wakes up from its sleep and responds to any queries from the taskMonitor, using checkMonitor(). checkMonitor() responds to a pending query using taskMonitor.respond().

  7. The fepManager task then detects that a bias computation is progress, and polls the active FEPs using pollBiasComplete().

  8. pollBiasComplete() iterates through each enabled FEP, calling checkReset() to ensure that the FEP still has power and is not reset.

  9. checkReset() uses fepDevice.hasPower(), and fepDevice.isReset() to ensure that the specified FEP is on and running. If a FEP is off-line, checkReset() takes the FEP out of the enabled list and pending bias list using disableFep() (not shown).

  10. If the current FEP is on-line and is not yet in the bias completion list, pollBiasComplete() uses queryFepStatus() to query the current state of the FEP. (NOTE: A single FEP can hold up the start of data processing by computing bias "forever")

  11. queryFepStatus() uses fepIo.issueCmd() to issue the query to the FEP, and retrieve the response. If the FEP's bias is complete, pollBiasComplete() adds the FEP to the completion list.

  12. The fepManager task continues through its polling loop, repeatedly calling pollBiasComplete(). Once pollBiasComplete() indicates that all on-line FEPs have completed their bias calculations, the fepManager task notifies the client that the bias maps are complete, using clientTask->notify().

25.5.8 Use 8: Start data processing and consume data

Figure 112 illustrates the steps involved in starting science data processing on each of the configured Front End Processors (see Use 6: Configure a FEP for a science run).

FIGURE 112. Start FEP Data Processing


  1. Upon each iteration of its main loop, the FEP Manager's main task loop (goTaskEntry) suspends execution using sleep(), allowing other tasks to run. Periodically, the task wakes up and checks for task monitor queries, FEP crashes, bias completions or data availability.

  2. client informs the FEP Manager which task to notify, and with which events, when a bias calibration completes, when data becomes available, and if all of the configured FEPs should crash, using fepManager.registerClient().

  3. client tells the FEP Manager to start data processing on all of the configured FEPs, using invokeDataProcess(), passing the command code indicating which science mode to run.

  4. fepManager.invokeDataProcess() loops through each configured FEP, using fepIo.issueCmd() to tell the FEP to start its data processing activities (see Use 3: Read FEP Memory, or Use 5: Execute FEP Subroutine for descriptions of the behavior of issueCmd()).

  5. client then starts the DEA sequencer, recording the microsecond science time stamp associated with the start of the sequence (not shown). client then suspends until data arrives, until an error occurs, or until commanded to abort the current process, using waitForEvent(). At this point, the CCDs start producing image data, and the FEPs start processing the received exposures. As a FEP produces data, it stores the data into its ring buffer.

  6. Periodically goTaskEntry() wakes up from its call to sleep(), and responds to any taskMonitor queries using checkMonitor().

  7. The task then detects that a run is in progress, and checks if a FEP has any data in its ring-buffer, using pollDataReady().

  8. pollDataReady() iterates through each enabled FEP, calling checkReset() to ensure that the FEP still has power and is not reset.

  9. checkReset() uses fepDevice.hasPower(), and fepDevice.isReset() to ensure that the specified FEP is on and running. If a FEP is off-line, checkReset() takes the FEP out of the enabled list using disableFep() (not shown).

  10. If the current FEP is on-line, pollDataReady() uses fepIo.hasData() to check if the FEP has data in its ring buffer. If so, pollDataReady() stops checking the remaining FEPs and returns to its caller.

  11. If a FEP has data in its ring-buffer, goTaskEntry() notifies the installed client task (clientTask) with the registered "data available" event, using clientTask>notify().

  12. client wakes up from its call to waitForEvent() and calls fepManager.readRecord() to consume one science data record from one of the enabled FEPs.

  13. fepManager.readRecord() iterates through each enabled FEP, calling fepIo.readRecord(). Once a fepIo.readRecord() indicates that a record has been read from its ring buffer, fepManager.readRecord() returns to its caller with the ring buffer data record, which FEP produced it, and which CCD the FEP is processing. The client then processes the record.

25.5.9 Use 9: Stop bias or data processing

Figure 113 illustrates the steps used to stop bias or science data processing on the configured Front End Processors. NOTE: Stopping science data processing is a normal part of performing a run, whereas, stopping a bias calibration process should only be used for error processing or under abnormal conditions.

FIGURE 113. Stop FEP Bias or Data Processing


  1. client issues a request to stop the current operation (i.e. bias or data processing) using fepManager.terminateProcess().

  2. terminateProcess() iterates through each configured Front End Processor, calling fepIo.issueCmd() to form and issue a "terminate" command via a FEP's Command Mailbox (see Use 3: Read FEP Memory or Use 5: Execute FEP Subroutine for a detailed description of issueCmd(). Once issueCmd() returns, the FEP software has received and acknowledged the command. At this point, the FEP completes its current operation (bias phase, or exposure) and returns to its top level control loop. If the FEPs were processing bias, the client is responsible for continuing to wait for indication that the bias completed (see Use 7: Start bias calibrations). If it was processing data, the client must continue to consume data from the FEPs until all of the FEPs have completed their exposures (i.e. client receives "end of exposure records", and the subsequent call to readRecord() indicate that there is no more data in the ring buffers).

25.5.10 Use 10: Disable FEP

In order to tell the FEP Manager to stop using a previously configured Front End Processor, the client calls fepManager.disableFep(). This takes the FEP out of the list of enabled FEPs, and subsequent calls to invokeBiasProcess(), invokeDataProcess(), terminateProcess(), and readRecord() no longer use the indicated FEP. In order to start using the FEP again, the client must call fepManager.configureFep().

25.5.11 Use 11: Write a bad pixel code into the pixel bias map and adjust its parity

In order to support the use of the FEP bias map to flag bad pixels, the FEP supports loading of bad pixel code directly into the FEP's pixel map (located in shared memory), and set the corresponding parity bit accordingly. To use this feature, the client calls fepManager.loadBadPixel(), specifying the FEP to address, and passing the pixel row and column of the bad pixel. loadBadPixel() then passes a PIXEL_BAD code to fepIo->writeBiasValue(). writeBiasValue() then computes the bias map address to write to and writes the code into the map. It then computes the parity of the passed code, and sets or clears the corresponding parity plane bit.


25.6 Class FepManager

Documentation:
This class is responsible for managing the Front End Processor devices.
Export Control:
Public
Cardinality:
1

Hierarchy:

Superclasses:

Task

Implementation Uses:

FepDevice fepDevice[6]
FepIoManager fepIo[6]
TaskManager taskManager
TaskMonitor taskMonitor

Public Interface:

Operations:

FepManager()
configureFep()
disableFep()
executeMemory()
goTaskEntry()
invokeBiasProcess()
invokeDataProcess()
loadRunProgram()
powerOff()
queryFepStatus()
readMemory()
readRecord()
registerClient()
terminateProcess()
writeMemory()

Protected Interface:

Operations:

checkMonitor()
checkReset()
loadSections()
pollBiasComplete()
pollDataReady()

Private Interface:

Has-A Relationships:


unsigned enabledFeps: This variable contains the list of FEPs currently configured to perform science operations. Bit 0 corresponds to FEP 0, bit 1 corresponds to FEP 1 and so on. If a bit is 1, then configureFep() has been called for the corresponding FEP, and the FEP has not been reset, powered off, or crashed. If a bit is 0, then the FEP was not configured, has crashed, or been powered off.

unsigned expReadyFeps: This variable contains the list of FEPs which have requested permission to proceed to the next exposure. Bit 0 corresponds to FEP 0, bit 1 to FEP 1 and so on. If a bit is 1, the corresponding FEP has issued a request since the last reply was issued by the BEP. If a bit is 0, the FEP is not yet ready to process another exposure.

unsigned biasReadyFeps: This variable indicates the list of FEPs who have completed their bias calibrations. Bit 0 corresponds to FEP 0, bit 1 to FEP 1, and so on. If a FEP has completed its bias, the corresponding bit in this value is 1. If not, the bit is 0.

unsigned crashedFeps: This variable contains a list of FEPs which caused an interrupt, and were in a reset state (i.e. their watchdog reset went off). Bit 0 corresponds to FEP 0, bit 1 to FEP 1 and so on. If a bit is 1, then the corresponding FEP has reset. If the bit is 0, the FEP has not autonomously reset (yet).

Task* clientTask: This is a pointer to the task using the FepManager to perform science operations. This variable is assigned using registerClient().

unsigned clientEvBiasRdy: This is the event mask that the client task wants when all enabled FEPs have completed their bias calibrations. This value is assigned by registerClient().

unsigned clientEvDataRdy: This is the event set that the client task wants if any of the enabled FEPs have new data in their ring-buffers. This value is assigned by registerClient().

unsigned clientEvCrash: This variable contains the event mask that the client task wants if all of the enabled FEPs have watchdog reset. This variable is assigned by registerClient().

FepId nxtFep: This variable indicates which FEP should be checked next by readRecord(). This variable is used to perform round-robin polling of each FEP's ring-buffer.
Concurrency:
Active
Persistence:
Persistent

25.6.1 FepManager()

Public member of:
FepManager

Arguments:

unsigned taskid
Documentation:
This constructor initializes the FepManager instance, passing taskid to the parent Task constructor, zeroing its FEP lists, and client information, and registering the FEP interrupt callback instance, fepCallback, with the FepIntrDevice.
Concurrency:
Sequential

25.6.2 checkMonitor()

Protected member of:
FepManager
Return Class:
void
Documentation:
This function responds to taskMonitor queries on behalf of the currently running task. It gets the current task, using taskManager.queryCurrentTask(), and then calls requestEvent() on that task for the query from the monitor. If the event is present, this function calls taskMonitor.respond(), to acknowledge the query.
Concurrency:
Guarded

25.6.3 checkReset()

Protected member of:
FepManager
Return Class:
Boolean

Arguments:

FepId fepid
Documentation:
This function tests the FEP's, fepid, power and reset lines. If either the power is off, or if the FEP is held in a reset state, this function adds the FEP to the manager's crashed list, crashedFeps, and removes the FEP from the manager's enabled and ready lists (enabledFeps, expReadyFeps) by calling disableFep(). The function then returns BoolTrue. If the FEP has power and is not reset, this function returns BoolFalse.
Concurrency:
Guarded

25.6.4 configureFep()

Public member of:
FepManager
Return Class:
Boolean

Arguments:

FepId fepid
CcdId ccdselect
unsigned* pbaddr
unsigned pblen
Documentation:
This function configures the Front End Processor indicated by fepid, and adds the FEP to the manager's list of enabled Front End Processors, enabledFeps. ccdselect is the CCD assigned to the configured FEP. pbaddr is a pointer to a FEP parameter block, and pblen is the number of words in the parameter block. This function loads the parameter block into the FEP via its Command Mailbox. If successful, this function returns BoolTrue. If the FEP is reset, powered off, or has a problem with a parameter, this function returns BoolFalse, and the FEP is not added to the enabled list.
Concurrency:
Guarded

25.6.5 disableFep()

Public member of:
FepManager
Return Class:
void

Arguments:

FepId fepid
Documentation:
This function causes the FEP Manager to remove the Front End Processor, specified by fepid, from its enabled, bias ready, and data ready lists (enabledFeps, biasReadyFeps, expReadyFeps), and resulting in the FEP no longer reading data from its ring-buffer. Subsequent calls to invokeBiasProcess, invokeDataProcess, and terminateProcess commands have no effect on the specified FEP. In order to re-enable use of the FEP, the client must call configureFep() to re-add the FEP to the manager's enabled list.
Concurrency:
Synchronous

25.6.6 executeMemory()

Public member of:
FepManager
Return Class:
Boolean

Arguments:

FepId fepid
unsigned (*)(...) fepaddr
const unsigned* args
unsigned argcnt
unsigned* result
Documentation:
This function tells the FepManager to command the Front End Processor, specified by fepid, to execute a subroutine, located at fepaddr. The subroutine will be passed at least argcnt words, whose values are contained in the buffer pointed to by args. Since, in C and C++, the caller maintains the argument stack, the implementation may pass more arguments than specified by the called function. The additional arguments are ignored by the called function. The value returned by the called subroutine will be stored in result. If the call is successful, this function returns BoolTrue, and result will contain the value returned by the subroutine. If an error is encountered, such as the indicated FEP is no power, or is in a reset state, this function returns BoolFalse, indicating that the call was not made.
Concurrency:
Synchronous

25.6.7 goTaskEntry()

Public member of:
FepManager
Return Class:
void
Documentation:
This function is the main loop of the FEP Manager task. This loop is responsible for handling low-priority requests from one or more of the FEPs. This function consists of an infinite loop, which sleeps for 0.1 second on each iteration, after which it tests for event notifications from serviceDevice() and from the taskMonitor using requestEvent(). If the taskMonitor queries the manager, this function responds to the query. If serviceDevice() notifies the task that a FEP has crashed or that an FEP has requested service, this function checks the list of enabled FEPs. If the last enabled FEP has crashed, and a client task has been registered, this function notifies the task that there are no remaining enabled FEPs. If a FEP has requested service, this function tests each of the enabled FEPs output mailboxes and ring buffers, and notifies the registered client task if all enabled FEPs have completed their bias calibrations, or if any of the enabled FEPs have data ready in their ring buffers.
Concurrency:
Synchronous

25.6.8 invokeBiasProcess()

Public member of:
FepManager
Return Class:
Boolean
Documentation:
This function instructs the FEP Manager to tell each of the configured Front End Processors (see configureFep()) to start computing bias map values from their respective CCDs. This function returns BoolTrue if successful, and BoolFalse if an error is encountered.
Concurrency:
Guarded

25.6.9 invokeDataProcess()

Public member of:
FepManager
Return Class:
Boolean

Arguments:

int requestType
int acktype
Documentation:
This function tells each of the configured Front End Processors (see configureFep()) to start processing data according to the request code, specified by requestType. If successful, and all of the FEPs respond with acktype, this function will return BoolTrue. If an error is encountered, this function returns BoolFalse. NOTE: This function is provided as a means by which new science modes can be added without having to directly modify the FepManager.
Concurrency:
Guarded

25.6.10 loadRunProgram()

Public member of:
FepManager
Return Class:
Boolean

Arguments:

FepId fepid
const FepProgram* program
Documentation:
This function enables power to the Front End Processor, indicated by fepid, sleeps for 1 timer tick (100ms), loads the code and data referenced by program, and starts the FEP running the loaded program. If the indicated FEP is already powered on, its reset line is asserted prior to the load attempt. This function returns BoolTrue if program was loaded successfully, and BoolFalse if an error is encountered during the load.
Semantics:
Make sure power is on using fepDevice.powerOn(), sleep for 1 tick, and reset the processor using fepDevice.holdReset(). Extract the mailbox and ring buffer addresses from the program header and inform the I/O manager, fepIo.setIoAddresses(). Then call loadSections() to load sections into shared memory. If successful, release the reset line (using fepDevice.releaseReset()) to cause the FEP to execute its bootstrap loader code. Then use loadSections() to load the remaining sections via the command mailbox (serviced by the bootstrap loader code). Given that the command mailbox requires handshaking from the FEP, no explicit delays need to be inserted prior to this activity. Once all of the code is loaded, extract the start address and use executeMemory() to launch the completely loaded program.
Postconditions:
If successful, program is loaded into the indicated FEP's memory, and the FEP is running.
Concurrency:
Guarded

25.6.11 loadSections()

Protected member of:
FepManager
Return Class:
Boolean

Arguments:

FepId fepid
const FepSection* sections
unsigned sectioncnt
Boolean sharedOnly
Documentation:
This function loads the code/data sections into the Front End Processor indicated by fepid. The argument sections points to the sections to load, and sectioncnt is the number of sections being pointed to. If sharedOnly is BoolTrue, only sections which appear in shared memory are loaded. If sharedOnly is BoolFalse, then this function uses the command mailbox to load sections into non-shared memory areas of the FEP.
Concurrency:
Guarded

25.6.12 powerOff()

Public member of:
FepManager
Return Class:
void

Arguments:

FepId fepid
Documentation:
This functions turns the power off to the Front End Processor indicated by fepid, and takes the FEP out of the current list of enabled FEPs. In order to restart a powered-off FEP, use loadRunProgram().
Concurrency:
Guarded

25.6.13 pollBiasComplete()

Protected member of:
FepManager
Return Class:
Boolean
Documentation:
This function queries the status of each active FEP to determine if their respective biases have completed. If so, the function returns BoolTrue. If one or more of the FEPs are continuing their bias computations, the function returns BoolFalse.
Concurrency:
Guarded

25.6.14 pollDataReady()

Protected member of:
FepManager
Return Class:
Boolean
Documentation:
This function checks each enabled FEP's ring buffer. If any enabled FEP has data in its ring buffer, the function returns BoolTrue, otherwise it returns BoolFalse.
Concurrency:
Guarded

25.6.15 queryFepStatus()

Public member of:
FepManager
Return Class:
Boolean

Arguments:

FepId fepid
Boolean& biasReady
unsigned*& biasbase
unsigned*& paritybase
Documentation:
This function issues a query to the FEP to obtain its current status. fepid specifies which FEP to query. On return, biasReady will contain BoolTrue if the bias map has been computed and is ready for use and BoolFalse if the bias map has not been computed, or is in the process of being computed. biasbase will contain a pointer to the bias map memory buffer within the FEP shared memory (mapped to BEP address space), and paritybase will point to the bias map parity plane within the FEP shared memory (again, mapped to BEP address space). If the query succeeds, the function returns BoolTrue. If the query fails, the function returns BoolFalse.
Concurrency:
Synchronous

25.6.16 readMemory()

Public member of:
FepManager
Return Class:
Boolean

Arguments:

FepId fepid
FepAddr fepaddr
unsigned* dstbuf
unsigned wordcnt
Documentation:
This function instructs the FEP Manager to read wordcnt 32-bit words from fepaddr on the FEP Device indicated by fepid. The read data is stored in dstbuf. This function returns BoolTrue if the read is successful, and BoolFalse if an error is encountered.
Concurrency:
Synchronous

25.6.17 readRecord()

Public member of:
FepManager
Return Class:
Boolean

Arguments:

RINGREC& blockout
FepId& fepout
CcdId& ccdout
Documentation:
This function consumes one block from one of the active Front End Processors ring buffers. If a block is available from one of the FEPs, this function copies the data into the passed output array, blockout, stores the id of the FEP producing the block into fepout, and stores the id of the CCD which produced the data into ccdout. It then returns BoolTrue. If no active FEP has data available, the function returns BoolFalse.
Concurrency:
Guarded

25.6.18 registerClient()

Public member of:
FepManager
Return Class:
void

Arguments:

Task* client
unsigned evbias
unsigned evdata
unsigned everr
Documentation:
This function registers a client task using the FepManager. client points to the task to notify under various conditions. evbias is the event mask to use when a bias calibration completes on all enabled FEPs. evdata is the event mask to use when data is available on any of the enabled FEPs. everr is the event mask to use if all enabled FEPs watchdog reset.
Concurrency:
Guarded

25.6.19 terminateProcess()

Public member of:
FepManager
Return Class:
Boolean

Arguments:

Boolean abortFlag
Documentation:
This function instructs each of the configured Front End Processors (see configureFep()) to terminate their current science operations. If abortFlag is BoolFalse, the FEP is asked to complete its current data set before stopping. If abortFlag is BoolTrue, the FEPs are asked to stop immediately. This function returns BoolTrue is the request is successful, and BoolFalse if an error is encountered.
Concurrency:
Guarded

25.6.20 writeMemory()

Public member of:
FepManager
Return Class:
Boolean

Arguments:

FepId fepid
FepAddr fepaddr
const unsigned* srcbuf
unsigned wordcnt
Documentation:
This function instructs the FEP Manager to write wordcnt 32-bit words from srcaddr to fepaddr on the Front End Processor indicated by fepid. If successful, this function returns BoolTrue. If an error is encountered, this function returns BoolFalse. NOTE: Although fepaddr is written to on the FEP, it is treated as read-only address while being used by the BEP.
Concurrency:
Synchronous

25.7 Class FepIoManager

Documentation:
This class is responsible for managing a Front End Processor's command and request mailboxes, and its ring buffer.
Export Control:
Public
Cardinality:
6

Hierarchy:

Superclasses:

none

Implementation Uses:

FepDevice fepDevice[]
TaskManager taskManager
Task

Public Interface:

Operations:

FepIoManager()
getMaxCmdArgs()
hasData()
issueCmd()
readRecord()
setBiasMapInfo()
setIoAddresses()
waitForLock()
waitForReply()
writeBiasValue()

Private Interface:

Has-A Relationships:


Semaphore lock: This semaphore instance is used to arbitrate access to the FEP's command mailbox.

const unsigned lock_timeout: This read-only field contains the number of BEP timer ticks (1/10 second) used to wait for access to the FEP's command mailbox.

const unsigned reply_timeout: This read-only field contains the approximate number of BEP timer ticks (1/10 second) used to wait for a reply to a command written to the FEP's command mailbox.

const FepId fepId: This field contains the identifier of the Front End Processor managed by this FepIoManager instance. This field is read-only, and is assigned during construction of the class instance.

CMD_MBOX* cmdBox: This field points to the Front End Processor's command mailbox, located in the FEP's shared memory area.

RINGBUF* ringBuf: This field points the Front End Processor's ring-buffer structure, located in the FEP's shared memory area.

unsigned* biasMap: This is a pointer to the bias map memory for the FEP.

unsigned* parityPlane: This is a pointer to the bias map parity error plane in the FEP's shared memory.
Concurrency:
Guarded
Persistence:
Persistent

25.7.1 FepIoManager()

Public member of:
FepIoManager

Arguments:

FepId fepid
unsigned semid
Documentation:
This constructor creates an I/O manager instance associated with the Front End Processor specified by fepid. semid is the RTX semaphore identifier to use with the command mailbox's Semaphore, lock.
Concurrency:
Sequential

25.7.2 getMaxCmdArgs()

Public member of:
FepIoManager
Return Class:
unsigned
Documentation:
This function returns the maximum number of arguments that can be passed or returned in the FEP's mailbox.
Concurrency:
Synchronous

25.7.3 hasData()

Public member of:
FepIoManager
Return Class:
Boolean
Documentation:
This function determines if there is any data in the FEP's ring buffer. It returns BoolTrue if there is data ready, and BoolFalse if there is no data in the ring buffer.
Concurrency:
Synchronous

25.7.4 issueCmd()

Public member of:
FepIoManager
Return Class:
Boolean

Arguments:

int cmdtype
const unsigned* info
unsigned infocnt
const unsigned* args
unsigned argcnt
int replytype
unsigned* replybuf
unsigned replycnt
Documentation:
This function issues a command to the FEP command mailbox and waits for a reply. cmdtype is the command type to use. If not 0, info is a pointer to a command-specific information data structure, and infocnt is the number of 32-bit words in the structure. If not 0, args is a pointer to an array of 32-bit argument words, and argcnt is the number of words in the array. replytype is the expected command response type. If not 0, replybuf is a pointer to where the function will store reply data, and replycnt is the maximum number of words that can be stored into replybuf. If successful, this function returns BoolTrue. If an error is encountered, or a reply doesn't match replytype, this function returns BoolFalse.
Semantics:
Call waitForLock() to obtain exclusive access to the command mailbox. If successful, store cmdtype into the mailbox. If info is not zero, copy the data structure to the mailbox and set the length. If args is not zero, append args to the mailbox and extend the length. Then set the mailbox state to indicate a new message. Call waitForReply() to obtain the response to the command. Once a reply is received (or an error occurs) release the lock semaphore, using lock.release().
Concurrency:
Synchronous

25.7.5 readRecord()

Public member of:
FepIoManager
Return Class:
Boolean

Arguments:

RINGREC& dstblock
Documentation:
This function reads one data record block from the FEP's ring buffer into dstblock. If a block was available, it copies the block into dstblock, advances the read pointer in the ring buffer and returns BoolTrue. If no data is available in the ring buffer, the function returns BoolFalse.
Concurrency:
Guarded

25.7.6 setBiasMapInfo()

Public member of:
FepIoManager
Return Class:
void

Arguments:

unsigned* mapaddr
unsigned* parityaddr
Documentation:
This function sets the bias map address, biasaddr, and bias map parity error plane address, parityaddr.
Concurrency:
Guarded

25.7.7 setIoAddresses()

Public member of:
FepIoManager
Return Class:
Boolean

Arguments:

FepAddr inbox
FepAddr ringbuf
Documentation:
This function sets the mailbox and ring buffer addresses of this FEP instance. inbox is the FEP address of the FEP's command mailbox, ringbuf is the FEP's address of its ring-buffer. If all of the addresses fit into the FEPs shared memory space, this function returns BoolTrue. If one or more of the addresses are not within shared memory, this function returns BoolFalse.
Concurrency:
Guarded

25.7.8 waitForLock()

Public member of:
FepIoManager
Return Class:
Boolean
Documentation:
This function attempts to obtain exclusive access to the instance's semaphore, using lock.waitFor(). If successful, and the processor has power and is not reset (fepDevice[fepId]->hasPower(), fepDevice[fepId]>isReset()) this function returns BoolTrue. If it times out, or the processor is disabled, this function returns BoolFalse.
Concurrency:
Synchronous

25.7.9 waitForReply()

Public member of:
FepIoManager
Return Class:
Boolean

Arguments:

int replytype
unsigned* dstbuf
unsigned dstcnt
Documentation:
This function polls the command mailbox until a reply is written by the FEP. If successful the function returns BoolTrue, and if dstbuf is not 0, this function copies at most dstcnt words from the reply buffer to dstbuf. If dstbuf is 0, no reply data is copied. If the reply times out, or if an error is encountered, this function returns BoolFalse.
Semantics:
Query taskManager for current task. Enter loop which terminates when the command mailbox state is no longer indicates a new message, or when the loop iterates reply_timeout times, or if the FEP loses power or is reset. On each iteration, call sleep() on the current task for 1 tick. Once the loop completes, test the mailbox state, and replytype. If all is well, and dstbuf is not zero, copy the reply data to dstbuf. Once the copy is complete, set the mailbox state to indicate that the box is available for use.
Concurrency:
Guarded

25.7.10 writeBiasValue()

Public member of:
FepIoManager
Return Class:
void

Arguments:

unsigned row
unsigned col
unsigned short value
Documentation:
This function writes value to the bias map location indexed by row and col, and adjusts the corresponding parity bit accordingly.
Concurrency:
Guarded
 

Table of Contents Next Chapter