Skip to content

Commit

Permalink
Fix nasa#1, Seconds to Wakeup Count
Browse files Browse the repository at this point in the history
  • Loading branch information
Tvisha Andharia committed Dec 9, 2024
1 parent a752fa3 commit 5000b87
Show file tree
Hide file tree
Showing 30 changed files with 433 additions and 449 deletions.
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
2 changes: 1 addition & 1 deletion config/default_sc_internal_cfg.h
Original file line number Diff line number Diff line change
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
11 changes: 8 additions & 3 deletions config/default_sc_tbldefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,15 @@
typedef uint32 SC_AbsTimeTag_t;

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

/**
* \brief Relative wakeup count
*/
typedef uint32 SC_RelWakeupCount_t;

/**
* \brief ATS Table Entry Header Type
*/
Expand Down Expand Up @@ -97,12 +102,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
57 changes: 29 additions & 28 deletions docs/dox_src/cfs_sc.dox
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,12 @@
/**
\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

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,7 +305,7 @@
\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
Expand Down Expand Up @@ -427,18 +427,19 @@
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.
Expand All @@ -449,9 +450,9 @@
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, 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 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"
Expand Down
4 changes: 2 additions & 2 deletions fsw/src/sc_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ CFE_Status_t SC_AppInit(void)
/* SAD: SC_Process_ATP is 0, within the valid index range of NextCmdTime array, which has 2 elements */
SC_AppData.NextCmdTime[SC_Process_ATP] = SC_MAX_TIME;
/* SAD: SC_Process_RTP is 1, within the valid index range of NextCmdTime array, which has 2 elements */
SC_AppData.NextCmdTime[SC_Process_RTP] = SC_MAX_TIME;
SC_AppData.NextCmdTime[SC_Process_RTP] = SC_MAX_WAKEUP_CNT;

/* Initialize the SC housekeeping packet */
CFE_MSG_Init(CFE_MSG_PTR(SC_OperData.HkPacket.TelemetryHeader), CFE_SB_ValueToMsgId(SC_HK_TLM_MID),
Expand Down Expand Up @@ -287,7 +287,7 @@ CFE_Status_t SC_InitTables(void)
{
RtsInfoPtr = SC_GetRtsInfoObject(SC_RTS_IDX_C(i));

RtsInfoPtr->NextCommandTime = SC_MAX_TIME;
RtsInfoPtr->NextCommandTgtWakeup = SC_MAX_WAKEUP_CNT;
RtsInfoPtr->NextCommandPtr = SC_ENTRY_OFFSET_FIRST;
RtsInfoPtr->RtsStatus = SC_Status_EMPTY;
RtsInfoPtr->DisabledFlag = true;
Expand Down
25 changes: 13 additions & 12 deletions fsw/src/sc_app.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ typedef struct
*/
typedef struct
{
SC_Status_Enum_t RtsStatus; /**< \brief status of the RTS */
bool DisabledFlag; /**< \brief disabled/enabled flag */
uint8 CmdCtr; /**< \brief Cmds executed in current rts */
uint8 CmdErrCtr; /**< \brief errs in current RTS */
SC_AbsTimeTag_t NextCommandTime; /**< \brief next command time for RTS */
SC_EntryOffset_t NextCommandPtr; /**< \brief where next rts cmd is */
uint16 UseCtr; /**< \brief how many times RTS is run */
SC_Status_Enum_t RtsStatus; /**< \brief status of the RTS */
bool DisabledFlag; /**< \brief disabled/enabled flag */
uint8 CmdCtr; /**< \brief Cmds executed in current rts */
uint8 CmdErrCtr; /**< \brief errs in current RTS */
uint32 NextCommandTgtWakeup; /**< \brief target wakeup count for next RTS command */
SC_EntryOffset_t NextCommandPtr; /**< \brief where next rts cmd is */
uint16 UseCtr; /**< \brief how many times RTS is run */
} SC_RtsInfoEntry_t;

/**
Expand Down Expand Up @@ -368,11 +368,12 @@ typedef struct

bool EnableHeaderUpdate; /**< \brief whether to update headers in outgoing messages */

SC_Process_Enum_t NextProcNumber; /**< \brief the next command processor number */
SC_AbsTimeTag_t NextCmdTime[2]; /**< \brief The overall next command time 0 - ATP, 1- RTP*/
SC_AbsTimeTag_t CurrentTime; /**< \brief this is the current time for SC */
SC_RtsNum_t AutoStartRTS; /**< \brief Start selected auto-exec RTS after init */
uint16 AppendWordCount; /**< \brief Size of cmd entries in current Append ATS table */
SC_Process_Enum_t NextProcNumber; /**< \brief the next command processor number */
uint32 NextCmdTime[2]; /**< \brief The overall next command time for ATP (0) and command wakeup count for RTP (1) */
SC_AbsTimeTag_t CurrentTime; /**< \brief this is the current time for SC */
uint32 CurrentWakeupCount; /**< \brief this is the current wakeup count for SC */
SC_RtsNum_t AutoStartRTS; /**< \brief Start selected auto-exec RTS after init */
uint16 AppendWordCount; /**< \brief Size of cmd entries in current Append ATS table */
} SC_AppData_t;

/************************************************************************
Expand Down
17 changes: 10 additions & 7 deletions fsw/src/sc_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ void SC_ProcessRtpCommand(void)

/*
** The following conditions must be met before a RTS command is executed:
** 1.) The next command time must be <= the current time
** 1.) The next command wakeup count must be <= the current wakeup count
** 2.) The next processor number must be SC_Process_RTP
** 3.) The RTS number in the RTP control block must be valid and
** 4.) the RTS must be EXECUTING
Expand All @@ -312,8 +312,8 @@ void SC_ProcessRtpCommand(void)

RtsInfoPtr = SC_GetRtsInfoObject(RtsIndex);

if ((SC_AppData.NextCmdTime[SC_AppData.NextProcNumber] <= SC_AppData.CurrentTime) &&
(SC_AppData.NextProcNumber == SC_Process_RTP) && (RtsInfoPtr->RtsStatus == SC_Status_EXECUTING))
if ((SC_AppData.NextProcNumber == SC_Process_RTP) &&
(SC_AppData.NextCmdTime[SC_Process_RTP] <= SC_AppData.CurrentWakeupCount) && (RtsInfoPtr->RtsStatus == SC_Status_EXECUTING))
{
/*
** Count the command for the rate limiter
Expand Down Expand Up @@ -443,9 +443,9 @@ void SC_SendHkPacket(void)
** Fill out the RTP control block information
*/

SC_OperData.HkPacket.Payload.NumRtsActive = SC_OperData.RtsCtrlBlckAddr->NumRtsActive;
SC_OperData.HkPacket.Payload.RtsNum = SC_OperData.RtsCtrlBlckAddr->CurrRtsNum;
SC_OperData.HkPacket.Payload.NextRtsTime = SC_AppData.NextCmdTime[SC_Process_RTP];
SC_OperData.HkPacket.Payload.NumRtsActive = SC_OperData.RtsCtrlBlckAddr->NumRtsActive;
SC_OperData.HkPacket.Payload.RtsNum = SC_OperData.RtsCtrlBlckAddr->CurrRtsNum;
SC_OperData.HkPacket.Payload.NextRtsWakeupCnt = SC_AppData.NextCmdTime[SC_Process_RTP];

/*
** Fill out the RTS status bit mask
Expand Down Expand Up @@ -538,6 +538,7 @@ void SC_ResetCountersCmd(const SC_ResetCountersCmd_t *Cmd)
void SC_OneHzWakeupCmd(const SC_OneHzWakeupCmd_t *Cmd)
{
bool IsThereAnotherCommandToExecute = false;
SC_AppData.CurrentWakeupCount++;

/*
* Time to execute a command in the SC memory
Expand Down Expand Up @@ -565,8 +566,10 @@ void SC_OneHzWakeupCmd(const SC_OneHzWakeupCmd_t *Cmd)
}

SC_UpdateNextTime();

if ((SC_AppData.NextProcNumber == SC_Process_NONE) ||
(SC_AppData.NextCmdTime[SC_AppData.NextProcNumber] > SC_AppData.CurrentTime))
((SC_AppData.NextProcNumber == SC_Process_ATP) && (SC_AppData.NextCmdTime[SC_Process_ATP] > SC_AppData.CurrentTime)) ||
((SC_AppData.NextProcNumber == SC_Process_RTP) && (SC_AppData.NextCmdTime[SC_Process_RTP] > SC_AppData.CurrentWakeupCount)))
{
SC_OperData.NumCmdsSec = 0;
IsThereAnotherCommandToExecute = false;
Expand Down
14 changes: 7 additions & 7 deletions fsw/src/sc_loads.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,12 +377,12 @@ void SC_LoadRts(SC_RtsIndex_t RtsIndex)
/* Clear out the RTS info table */
RtsInfoPtr = SC_GetRtsInfoObject(RtsIndex);

RtsInfoPtr->RtsStatus = SC_Status_LOADED;
RtsInfoPtr->UseCtr = 0;
RtsInfoPtr->CmdCtr = 0;
RtsInfoPtr->CmdErrCtr = 0;
RtsInfoPtr->NextCommandTime = 0;
RtsInfoPtr->NextCommandPtr = SC_ENTRY_OFFSET_FIRST;
RtsInfoPtr->RtsStatus = SC_Status_LOADED;
RtsInfoPtr->UseCtr = 0;
RtsInfoPtr->CmdCtr = 0;
RtsInfoPtr->CmdErrCtr = 0;
RtsInfoPtr->NextCommandTgtWakeup = 0;
RtsInfoPtr->NextCommandPtr = SC_ENTRY_OFFSET_FIRST;

/* Make sure the RTS is disabled */
RtsInfoPtr->DisabledFlag = true;
Expand Down Expand Up @@ -449,7 +449,7 @@ bool SC_ParseRts(uint32 Buffer32[])

if (!CFE_SB_IsValidMsgId(MessageID))
{
if (EntryPtr->Header.TimeTag == 0)
if (EntryPtr->Header.WakeupCount == 0)
{
Done = true; /* assumed end of file */
}
Expand Down
14 changes: 7 additions & 7 deletions fsw/src/sc_rtsrq.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ void SC_StartRtsCmd(const SC_StartRtsCmd_t *Cmd)
RtsInfoPtr->UseCtr++;

/*
** Get the absolute time for the RTSs next_cmd_time
** using the current time and the relative time tag.
** Get the absolute wakeup count for the RTS's next_command_tgt_wakeup
** using the current wakeup count and the relative wakeup count.
*/
RtsInfoPtr->NextCommandTime = SC_ComputeAbsTime(RtsEntryPtr->TimeTag);
RtsInfoPtr->NextCommandTgtWakeup = SC_ComputeAbsWakeup(RtsEntryPtr->WakeupCount);

/*
** Last, Increment some global counters associated with the
Expand Down Expand Up @@ -203,9 +203,9 @@ void SC_StartRtsGrpCmd(const SC_StartRtsGrpCmd_t *Cmd)
RtsInfoPtr->NextCommandPtr = SC_ENTRY_OFFSET_FIRST;
RtsInfoPtr->UseCtr++;

/* get absolute time for 1st cmd in the RTS */
RtsInfoPtr->NextCommandTime =
SC_ComputeAbsTime(SC_GetRtsEntryAtOffset(RtsIndex, SC_ENTRY_OFFSET_FIRST)->Header.TimeTag);
/* get absolute wakeup count for 1st cmd in the RTS */
RtsInfoPtr->NextCommandTgtWakeup =
SC_ComputeAbsWakeup(SC_GetRtsEntryAtOffset(RtsIndex, SC_ENTRY_OFFSET_FIRST)->Header.WakeupCount);

/* maintain counters associated with starting RTS */
SC_OperData.RtsCtrlBlckAddr->NumRtsActive++;
Expand Down Expand Up @@ -547,7 +547,7 @@ void SC_KillRts(SC_RtsIndex_t RtsIndex)
** Stop the RTS from executing
*/
RtsInfoPtr->RtsStatus = SC_Status_LOADED;
RtsInfoPtr->NextCommandTime = SC_MAX_TIME;
RtsInfoPtr->NextCommandTgtWakeup = SC_MAX_WAKEUP_CNT;

/*
** Note: the rest of the fields are left alone
Expand Down
Loading

0 comments on commit 5000b87

Please sign in to comment.