[PREVIOUS] [NEXT] [CONTENTS] ACIS Users Guide, Rev. A [AXAF]

3.8 Calling Subroutines

ACIS provides mechanisms for the maintainer to directly call C, C++ or assembler subroutines in both the BEP and the FEPs.

NOTE: In general, calling code directly within ACIS can crash the software. These types of commands are intended to be built by the ACIS software maintenance team.

3.8.1 Calling BEP subroutines

Description

ACIS implements commanded function calls on the BEP using the Memory Server task. The maintainer prepares an "Execute BEP" command packet, specifying the address of the function to call, and a list of zero to up to 20, 32-bit arguments to pass to the called subroutine.

Upon receipt of the command, the Memory Server task calls the subroutine indirectly via a pointer, always passing 20 arguments. The values specified in the command packet will appear in order at the beginning of the argument list, and the remaining passed arguments will contain unpredictable values. In C and C++, one can always pass more arguments to a subroutine than the subroutine demands (NOTE: This may or may not be allowed for certain assembly language subroutines. If needed, the maintainer can load a translation subroutine using "Write BEP" (see Section 3.7.2), which deals with the extra arguments and invokes the target routine).

The called subroutine runs under the Memory Server task, which will be blocked until the called routine returns. Attempts to execute subsequent Memory Server commands, such as another execute command or a read or write command, while the called subroutine has control, will be rejected with a CMDRESULT_BUSY reply in their respective Command Echoes.

Once the called subroutine returns, the Memory Server task records the return value in a "BEP Execute Reply" telemetry packet. For the C and C++ compilers used for the Mongoose, this value is always in the same CPU register. If the function does not return any value, the recorded reply value will be meaningless. The maintainer should be aware of what the return value, if any, means, and therefore should know how to deal with it.

The constraints for execute memory commands are as follows:

Commands

Command to execute a routine on a BEP:

executeBep: CMDOP_EXEC_BEP
{
  functionAddress     = address of subroutine            
  functionArguments[] = up to 20 arguments to pass to 
routine
}

For example, the maintainer has a diagnostic program to run on FEP_2, and wants to load it using the FepManager's "loadRunProgram" member function, located at 0x8008939c. The first argument to the loadRunProgram is the address of the fepManager object (in C++, the first argument of all non-static member functions is a pointer to the object), which is 0x80003da4. The second argument is the FEP Id, which, for FEP_2, has a value of 2, and the third is a pointer to the FepProgram to load. Assume that the program has already been loaded into RAM using a series "Write BEP" commands, at location 0x80030000. The command to call the subroutine is:

executeBep: CMDOP_EXEC_BEP
{
  functionAddress     = 0x8008939c  - &FepManager::loadRunProgram
  functionArguments[] =
  {
    0x80003da4,                     - &fepManager
    2,                              - FEP_2
    0x80030000                      - address of pre-loaded FEP load image
  }
}

Science Telemetry

The command echo from an "Execute BEP" command is:

commandEcho: TTAG_CMD_ECHO
{
  arrival    = time command arrived (BEP 10Hz Ticks)
  result     = CMDRESULT_OK (other values indicate an error)

  executeBep: CMDOP_EXEC_BEP
  {
    functionAddress
    functionArguments[]  
  }
}

If an error is encountered, such as specifying an invalid address, the Command Echo "result" field will contain CMDRESULT_BAD_ARGUMENT, and the function will not be called.

If the Memory Server task is in the process of executing an earlier write or execute command, the Command Echo "result" field will contain CMDRESULT_BUSY, and the function will not be called.

If the Memory Server task is in the process of performing an earlier memory read or dump, the Command Echo "result" field will contain CMDRESULT_CLOBBERED, the read operation will be aborted, and the function will be called.

When the called function returns, the Memory Server task will produce a "BEP Execute Reply" telemetry packet:

bepExecuteReply: TTAG_EXEC_BEP
{
  commandId       = id of command containing call
  bepTickCounter  = BEP 10Hz tick counter at the time of the call
  functionAddress = address of the function which was called
  returnedValue   = 32-bit value returned by the called function. (NOTE:
                    This field is meaningless if the function is "void")
}

Warnings

  1. Calls to the wrong locations or with the wrong arguments can crash the software

    It is assumed that the maintainers know what they are calling and why

  2. Aborts earlier read

    If, when the command is received, the Memory Server task is executing an earlier read command, such as a dump of the Huffman Tables, the earlier read will be aborted, possibly causing incomplete information to be telemetered. The execute will then commence.

  3. Routines must return within 7 minutes or manage task monitor requests

    Within the ACIS software, there is a Task Monitor task which issues an event to each task in sequence. The target task must then respond to the Task Monitor. Once the targeted task responds, the Task Monitor "touches" the hardware watchdog timer, sleeps, for about 1 second, and then moves on to the next task. If a task does not respond within about 8 minutes, the hardware watchdog timer will expire and reset the BEP. Since subroutines invoked by the "Execute BEP" command run under the Memory Server task, they must either return to the calling Memory Server code within about 7 minutes, so the Memory Server code can respond to the Task Monitor, or must themselves respond to the Task Monitor queries. If not, the called routine will starve the watchdog timer, and cause the BEP to reset.

3.8.1 Call FEP subroutines

Description

ACIS implements commanded function calls on the FEP using the Memory Server task, in cooperation with software already running on the targeted FEP. The maintainer prepares an "Execute FEP" command packet, specifying which FEP to use, the address in FEP memory space of the function to call, and a list of zero to up to 20, 32-bit arguments to pass to the called subroutine.

Upon receipt of the command, the Memory Server task calls a routine which forms and issues a request to the FEP software, via the BEP to FEP mailbox, and waits for a reply. The FEP software then calls the subroutine indirectly via a pointer, always passing 20 arguments. The values specified in the command packet will appear in order at the head of the argument list, and the remaining passed arguments will contain unpredictable values. In C and C++, one can always pass more arguments to a subroutine than the subroutine demands (NOTE: This may or may not be allowed for certain assembly language subroutines. If needed, the maintainer can load a translation subroutine using "Write FEP" (see Section 3.7.2), which deals with the extra arguments and invokes the target routine).

The dispatch of the request to the FEP runs under the Memory Server task, which will be blocked until the FEP replies to the request, or until the BEP times out waiting for the reply. The called routine on the FEP must return within 10 seconds to avoid a time-out (NOTE: The FEP routine will continue to run after the time-out has expired. The BEP will reset and re-load the FEP if it remains non-responsive during the setup stage of the next science run). Attempts to execute subsequent Memory Server commands, such as another execute command or a read or write command, while the called subroutine has control, will be rejected with a CMDRESULT_BUSY reply in their respective Command Echoes.

Once the called subroutine returns on the FEP, the FEP software packages the returned value in its reply to the BEP. The Memory Server task records the returned value in a "FEP Execute Reply" telemetry packet. For the C compilers used for the Mongoose, this value is always in the same CPU register. If the function does not return any value, the recorded reply value will be meaningless. The maintainer should be aware of what the return value, if any, means, and therefore should know how to deal with it.

The constraints for execute FEP memory commands are as follows:

Commands

Command to execute a routine on a FEP:

executeFep: CMDOP_EXEC_FEP
{
  fepId               = FEP_0..FEP_5  - FEP to use
  functionAddress     = address       - address of subroutine            
  functionArguments[] =               - up to 20 arguments to pass 
to routine
}

Science Telemetry

The command echo from an "Execute FEP" command is:

commandEcho: TTAG_CMD_ECHO
{
  arrival      = time command arrived (BEP 10Hz Ticks)
  result       = CMDRESULT_OK (other values indicate an error)

  executeFep: CMDOP_EXEC_FEP
  {
    fepId
    functionAddress
    functionArguments[]  
  }
}

If an error is encountered, such as specifying an invalid address, the Command Echo "result" field will contain CMDRESULT_BAD_ARGUMENT, and the function will not be called.

If the Memory Server task is in the process of executing an earlier write or execute command, the Command Echo "result" field will contain CMDRESULT_BUSY, and the function will not be called.

If the Memory Server task is in the process of performing an earlier memory read or dump, the Command Echo "result" field will contain CMDRESULT_CLOBBERED, the read operation will be aborted, and the function will be called.

When the called function returns, the Memory Server task will produce a "FEP Execute Reply" telemetry packet:

fepExecuteReply: TTAG_EXEC_FEP
{
  commandId       = id of command containing call
  fepId           = id of FEP used
  bepTickCounter  = BEP 10Hz tick counter at the time of the call
  functionAddress = address of the function which was called
  returnedValue   = 32-bit value returned by the called function. (NOTE:
                    This field is meaningless if the function is "void")
}

NOTE: If the called subroutine does not return within 10 seconds, the BEP will not issue the "FEP Execute Reply" telemetry packet. The FEP routine may continue to execute until the BEP attempts to setup for a subsequent science run. If the FEP remains non-responsive at this point, the BEP will reset and re-load the FEP.

Warnings

  1. Calls to the wrong locations or with the wrong arguments can crash the FEP

    It is assumed that the maintainers know what they are calling and why

  2. Aborts earlier read

    If, when the command is received, the Memory Server task is executing an earlier read command, such as a dump of the Huffman Tables, the earlier read will be aborted, possibly causing incomplete information to be telemetered. The execute will then commence.

  3. FEP routines must return within 7 minutes or manage the FEP watchdog timer

    Software running on the FEP is jointly responsible for maintaining the watchdog timer. This timer will expire and reset the FEP if it is not reset at least once every 8 minutes. All called subroutines on the FEP must either return within 7 minutes, or must touch the watchdog timer themselves.

  4. FEP routines must return within 10 seconds to avoid reply time-out on the BEP

    The BEP maintains a 10 second time-out when waiting for replies from the FEP. If the subroutine on the FEP does not return within 10 seconds, the BEP will not issue a "FEP Execute Reply" telemetry packet.


[PREVIOUS] [NEXT] [CONTENTS]
James E. Francis
Last modified: Wed Jan 12 10:40:15 EST