Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #84, Seconds to Wakeup Count #146

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@
## Introduction

The Stored Command application (SC) is a core Flight System (cFS) application
that is a plug in to the Core Flight Executive (cFE) component of the cFS.
that is a plug in to the Core Flight Executive (cFE) component of the cFS.

The SC application allows a system to be autonomously commanded
using sequences of commands that are loaded to SC. Each command has a time tag
associated with it, permitting the command to be released for distribution at
predetermined times. SC supports both Absolute Time tagged command Sequences
(ATSs) and multiple Relative Time tagged command Sequences (RTSs). The
purpose of ATS commands is to be able to specify commands to be executed at a
specific time. The purpose of Relative Time Sequence commands is to be able
to specify commands to be executed at a relative time.
using sequences of commands that are loaded into SC. Each command has a time tag
or wakeup count associated with it, permitting the command to be released for
distribution at predetermined times or wakeup counts. SC supports both
Absolute Time tagged command Sequences (ATSs) and multiple Relative Time tagged
command Sequences (RTSs). The purpose of ATS commands is to be able to specify
commands to be executed at a specific time. The purpose of Relative Time
Sequence commands is to be able to specify commands to be executed at a
relative wakeup count.

The SC application is written in C and depends on the cFS Operating System
Abstraction Layer (OSAL) and cFE components. There is additional SC application
Expand Down
10 changes: 5 additions & 5 deletions config/default_sc_internal_cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,19 +71,19 @@
#define SC_PLATFORM_ENABLE_HEADER_UPDATE false

/**
* \brief Max number of commands per second
* \brief Max number of commands per wakeup
*
* \par Description:
* Maximum number of commands that can be sent out by SC
* in any given second.
* in any given wakeup cycle.
*
* \par Limits:
* This parameter can't be larger than an unsigned 16 bit
* integer (65535), but should be kepoot relatively small to
* integer (65535), but should be kept relatively small to
* avoid SC hogging the CPU
*
*/
#define SC_MAX_CMDS_PER_SEC 8
#define SC_MAX_CMDS_PER_WAKEUP 8

/**
* \brief Max buffer size for an ATS in uint16s
Expand Down Expand Up @@ -342,7 +342,7 @@
* \brief Defines the TIME SC should use for its commands
*
* \par Description:
* This parameter defines what type of time SC should use for sending uot its commands
* This parameter defines what type of time SC should use for sending out its commands
*
* \par Limits:
* Must be SC_TimeRef_USE_CFE_TIME, SC_TimeRef_USE_TAI, or SC_TimeRef_USE_UTC */
Expand Down
3 changes: 2 additions & 1 deletion config/default_sc_msgdefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ typedef uint8 SC_Process_Enum_t;
#endif

#define SC_MAX_TIME 0xFFFFFFFF /**< \brief Maximum time in SC */
#define SC_MAX_WAKEUP_CNT 0xFFFFFFFF /**< \brief Maximum wakeup count in SC */

/**
* Enumeration for ATS identifiers
Expand Down Expand Up @@ -216,7 +217,7 @@ typedef struct
uint16 AppendLoadCount; /**< \brief Total number of Append ATS table loads */
uint32 AtpCmdNumber; /**< \brief Current command number */
uint32 AtpFreeBytes[SC_NUMBER_OF_ATS]; /**< \brief Free Bytes in each ATS */
uint32 NextRtsTime; /**< \brief Next RTS cmd Absolute Time */
uint32 NextRtsWakeupCnt; /**< \brief Next RTS Command Absolute Wakeup Count */
uint32 NextAtsTime; /**< \brief Next ATS Command Time (seconds) */

uint16 RtsExecutingStatus[(SC_NUMBER_OF_RTS + (SC_NUMBER_OF_RTS_IN_UINT16 - 1)) / SC_NUMBER_OF_RTS_IN_UINT16];
Expand Down
5 changes: 3 additions & 2 deletions config/default_sc_msgids.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

#define SC_CMD_MID (0x18A9) /**< \brief Msg ID for cmds to SC */
#define SC_SEND_HK_MID (0x18AA) /**< \brief Msg ID to request SC HK */
#define SC_ONEHZ_WAKEUP_MID (0x18AB) /**< \brief Msg ID to receive the 1Hz */
#define SC_WAKEUP_MID (0x18AB) /**< \brief Msg ID to receive the wakeup command */

/**\}*/

Expand All @@ -46,7 +46,8 @@

/* Compatibility identifiers - in case existing SCH table(s) use the old wakeup MID define */
#ifndef SC_OMIT_DEPRECATED
#define SC_1HZ_WAKEUP_MID SC_ONEHZ_WAKEUP_MID
#define SC_1HZ_WAKEUP_MID SC_WAKEUP_MID
#define SC_ONEHZ_WAKEUP_MID SC_WAKEUP_MID
#endif

#endif
6 changes: 3 additions & 3 deletions config/default_sc_msgstruct.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,14 @@ typedef struct
} SC_SendHkCmd_t;

/**
* \brief 1Hz Wakeup Command
* \brief Wakeup Command
*
* For command details see #SC_ONEHZ_WAKEUP_MID
* For command details see #SC_WAKEUP_MID
*/
typedef struct
{
CFE_MSG_CommandHeader_t CommandHeader; /**< \brief Command Header */
} SC_OneHzWakeupCmd_t;
} SC_WakeupCmd_t;

/**
* \brief No operation Command
Expand Down
8 changes: 4 additions & 4 deletions config/default_sc_tbldefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@
typedef uint32 SC_AbsTimeTag_t;

/**
* \brief Relative time tag for RTC's
* \brief Relative wakeup count
*/
typedef uint32 SC_RelTimeTag_t;
typedef uint32 SC_RelWakeupCount_t;

/**
* \brief ATS Table Entry Header Type
Expand Down Expand Up @@ -97,12 +97,12 @@ typedef struct
*/
typedef struct
{
SC_RelTimeTag_t TimeTag; /**< \brief Relative time tag */
SC_RelWakeupCount_t WakeupCount; /**< \brief Relative wakeup count */

/*
* Note: the command packet data is variable length,
* the command packet header (not shown here),
* comes directly after Time tag.
* comes directly after WakeupCount.
*/
} SC_RtsEntryHeader_t;

Expand Down
130 changes: 65 additions & 65 deletions docs/dox_src/cfs_sc.dox
Original file line number Diff line number Diff line change
Expand Up @@ -107,20 +107,20 @@
/**
\page cfsscovr CFS Stored Command Overview

The CFS Stored Command appliaction allows the spacecraft to be commanded
The CFS Stored Command application allows the spacecraft to be commanded
using sequences of commands that are loaded from the ground. Each
command has a time tag associated with it, permitting the command to be
released for distribution at predetermined times. SC supports both Absolute
Time tagged command Sequences (ATSs) and multiple Relative Time tagged
command Sequences (RTSs).
command has a time tag or wakeup count associated with it, permitting the command to be
released for distribution at predetermined times or wakeup counts. SC supports both Absolute
Time tagged command Sequences (ATSs) and multiple Relative Time tagged command Sequences (RTSs),
where RTSs use wakeup counts instead of time tags.

\section SC Design Overview

The CFS Stored Command application is driven off of the 1Hz packet from the
Scheduler Application. When the 1Hz is received, SC looks to see if there are
The CFS Stored Command application is driven off of the wakeup command packet from the
Scheduler Application. When the wakeup command is received, SC looks to see if there are
stored commands to execute (in the ATS and the RTS's). If there are commands
to be executed in this second, SC will execute them up until
#SC_MAX_CMDS_PER_SEC commands are executed. SC is also driven off of the
to be executed in this wakeup, SC will execute them up until
#SC_MAX_CMDS_PER_WAKEUP commands are executed. SC is also driven off of the
housekeeping request packet from the Scheduler Application. When SC receives
the HK request, it processes the request, sends out the housekeeping packet,
and looks for table updates to the load/dump tables that SC maintains. SC is
Expand Down Expand Up @@ -243,7 +243,7 @@
<H2>Relative Time Processor (RTP)</H2>

When the sequence is started, the RTP reads the delay of the first command.
After the amount of seconds listed in the delay, the RTP will fetch the
After the amount of wakeup counts listed in the delay, the RTP will fetch the
command, check the checksum of the command, and send the command out to the
data system. The RTP will then fetch the next command in the sequence and
determine when this command needs to execute.
Expand Down Expand Up @@ -273,12 +273,12 @@
a priority associated with it. The priority is assigned by the buffer number.
In other words, RTS buffer 1 has the highest priority and the last RTS buffer
has the lowest priority. This priority only comes into play when there is more
than one RTS that has commands to be executed in the SAME SECOND. For example,
if RTS 1 has a command to go out at 12:00:01 and RTS 50 has 8 commands to go
out at 12:00:00, all 8 commands from RTS 50 will be executed before RTS 1
executes it's command. However, if the 8 commands from RTS 50 are scheduled to
go out at 12:00:01, then the command from RTS 1 will be sent first, followed
by 7 commands from RTS 50. At 12:00:02, the 8th command from RTS 50 will be
than one RTS that has commands to be executed on the same wakeup count. For example,
if RTS 1 has a command to go out on the 103rd wakeup of SC and RTS 50 has 8 commands to go
out on the 102nd wakeup, all 8 commands from RTS 50 will be executed before RTS 1
executes its command. However, if the 8 commands from RTS 50 are scheduled to
go out on the 103rd wakeup, then the command from RTS 1 will be sent first, followed
by 7 commands from RTS 50. On the 104th wakeup, the 8th command from RTS 50 will be
sent.

<H2>RTP Error Handling</H2>
Expand All @@ -305,12 +305,12 @@
\page cfsscdg CFS Stored Command Deployment Guide

While the SC application does not require a great deal of work for platform
deployment, the following are some general guidlines.
deployment, the following are some general guidelines.

CFS Stored Command requires that two message ID's be put in the CFS Scheduler
table for proper operation. Those message ID's are #SC_SEND_HK_MID, which
should be sent out at the housekeeping request interval, and
#SC_ONEHZ_WAKEUP_MID, which needs to be sent out every second.
#SC_WAKEUP_MID.

CFS Stored Command generates telemetry when it receives the housekeeping
request. Its telemetry message ID is #SC_HK_TLM_MID.
Expand Down Expand Up @@ -427,35 +427,34 @@
two hours. If SC is conifured to use TAI time, and the ATS is started, and the
leap seconds are changed, SC time will not be affected.

The effect of adjusting time on Relative Time Sequences is a little more
complicated. As mentioned in the Scheduling section, the next RTS command for
each sequence actually has an absolute time associated with it. With this
absolute time, it is possible for SC to know when to send out each RTS
command. From the Absolute time a delay time is computed, which is used to
tell SC how long to delay. When time is adjusted on an RTS, the command that
is currently waiting to execute gets "thrown off". Depending on the time
adjustment, the command could go out sooner or later than expected. Once the
"current" command is out, however, the remaining commands in the sequence will
execute as scheduled because they are relative to the previous command.

The point of this discussion is that SC will not react well to time changes.
RTSs, on the other hand, use wakeup counts instead of time tags, meaning
commands are scheduled based on the number of wakeups since the previous
command. Each command in an RTS is associated with a relative wakeup count,
and this value determines when the command will execute relative to the last
executed command. For example, if a command is scheduled to execute after 2
wakeups, the system will calculate the absolute wakeup count by adding 2 to
the current absolute wakeup count. The command will execute at that absolute
wakeup count, regardless of any adjustments to the system time. This means
that time shifts are not expected to affect the time at which the commands
are executed, since they are based on wakeup counts rather than specific
time values.

Despite this, time adjustments can introduce risks or unintended behaviors.
It is recommended that SC be idle during large time adjustments (1 second or
greater). Small adjustments can be tolerated if there is not an exact second
tolerance for every command being executed.

<H2>Over-scheduling the Stored Command Application</H2>

Another way to stress SC is to send out many commands in one second from many
sequences. The time tags for both ATS commands and RTS commands have one
second resolution. However, there is a way to send multiple commands in one
second. For ATS commands, set the time tags to the same second. For RTS
commands, set the delays to zero. As noted earlier, SC will send out the
commands as fast as possible up to a certain number of commands per second.
With this in mind, it is possible to pack the ATSs and a few RTSs with
commands that want to go out in the same second. When all of these sequences
are run, SC will get behind in sending out the commands. SC will keep going
until all of the commands are executed, but do not expect "to the second"
execution accuracy.
Another way to stress SC is to send out many commands in one wakeup cycle
from many sequences. For ATS commands, set the time tags to the same second.
For RTS commands, set the relative wakeup counts to zero. As noted earlier,
SC will send out the commands as fast as possible up to a certain number of
commands per wakeup. With this in mind, it is possible to pack the ATSs and
a few RTSs with commands that want to go out in the same wakeup. When all of
these sequences are run, SC will get behind in sending out the commands. SC
will keep going until all of the commands are executed, but do not expect
"to the second" execution accuracy.

<H2>Unsorted ATS Loads</H2>

Expand All @@ -477,30 +476,31 @@
the switch command could be sent. Figure 4.6 shows the overlapping buffer
concept with the ATSs. As mentioned earlier, the ATP can execute commands
with the same time tag. Because the resolution of the time tag only goes
down to one second, in order to execute more than one command in one second,
the commands should have the same time tag. Now suppose that the ATP receives
the command to Switch ATSs while one ATS is in the middle of sending 8
commands out with the same time tag, and only 5 of these commands were
sent out before the buffer is switched (assuming a switch command coming
from the ground, not the internal switch command). At first glance this
seems to work because the other ATS buffer has an overlap with the same 8
commands that want to go out in one second. This is where a problem occurs:
when the new ATS is started, the ATP will walk down the list of commands
until it finds a command with a time tag that is greater than or equal to
the current time tag. Because the resolution of the time tags only goes
down to a second, the ATP will execute all 8 commands in that one second,
causing 5 of the eight commands to be sent out twice. In order to solve the
problem of the ATS Switch sending out duplicate commands, the Switch ATS
command received from the ground causes a wait condition until it is "safe"
to switch the ATS buffer. So, when the Switch ATS command is received by the
ATP, the command is validated and then a SWITCH_PEND flag is set. When it
becomes safe for the ATS to switch (i.e. at a 1 second boundary in UTC Time),
the switch will be serviced. This method assures that sending the Switch ATS
command from the ground will not cause any duplicate commands to be sent
out to the data system, nor any missed commands. Note that all of this
switch logic only comes into use when there are multiple commands per second.
The safe switch will wait until all commands during the current second have
been sent out, then it will switch. If there are no commands with the same
down to one second, in order to have more than one command go out in the
same second, the commands should have the same time tag. Now suppose that
the ATP receives the command to Switch ATSs while one ATS is in the middle
of sending 8 commands out with the same time tag, and only 5 of these
commands were sent out before the buffer is switched (assuming a switch
command coming from the ground, not the internal switch command). At first
glance this seems to work because the other ATS buffer has an overlap with
the same 8 commands that want to go out in one second. This is where a
problem occurs: when the new ATS is started, the ATP will walk down the
list of commands until it finds a command with a time tag that is greater
than or equal to the current time tag. Because the resolution of the time
tags only goes down to a second, the ATP will execute all 8 commands in
that one second, causing 5 of the eight commands to be sent out twice.
In order to solve the problem of the ATS Switch sending out duplicate
commands, the Switch ATS command received from the ground causes a wait
condition until it is "safe" to switch the ATS buffer. So, when the
Switch ATS command is received by the ATP, the command is validated and
then a SWITCH_PEND flag is set. When it becomes safe for the ATS to
switch (i.e. at a 1 second boundary in UTC Time), the switch will be
serviced. This method assures that sending the Switch ATS command from
the ground will not cause any duplicate commands to be sent out to the
data system, nor any missed commands. Note that all of this switch logic
only comes into use when there are multiple commands per second. The safe
switch will wait until all commands during the current second have been
sent out, then it will switch. If there are no commands with the same
time tag in the overlap region (including the switch command) this logic
does not get used. In either case, the switch can be performed without
sending any duplicate commands to be sent out. There are certain conditions
Expand Down
Loading