Skip to content

Commit

Permalink
WIP nasa#1009 - doc update
Browse files Browse the repository at this point in the history
  • Loading branch information
skliper committed Nov 18, 2020
1 parent 36ce14d commit ec0dc36
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 74 deletions.
103 changes: 50 additions & 53 deletions docs/cFE Application Developers Guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -1080,21 +1080,17 @@ void SAMPLE_TaskMain(void)
/*
** Wait for the next Software Bus message
*/
Status = CFE_SB_RcvMsg( &SAMPLE_TaskData.MsgPtr,
SAMPLE_TaskData.CmdPipe,
CFE_SB_PEND_FOREVER );
Status = CFE_SB_RcvMsg(&SBBufPtr, SAMPLE_TaskData.CmdPipe, CFE_SB_PEND_FOREVER);
if (Status == CFE_SUCCESS)
{
/*
** Process Software Bus message
*/
SAMPLE_TaskPipe(CFE_TBL_TaskData.MsgPtr);
SAMPLE_TaskPipe(SBBufPtr);
/* Update Critical Data Store */
CFE_ES_CopyToCDS(SAMPLE_TaskData.MyCDSHandle,
&SAMPLE_MyCDSDataType_t);
CFE_ES_CopyToCDS(SAMPLE_TaskData.MyCDSHandle, &SAMPLE_MyCDSDataType_t);
}
}
CFE_EVS_SendEvent(CFE_TBL_EXIT_ERR_EID, CFE_EVS_ERROR,
Expand Down Expand Up @@ -1216,7 +1212,7 @@ FILE: xx_app.c
void XX_AppMain(void)
{
uint32 RunStatus = CFE_ES_RunStatus_APP_RUN;
CFE_MSG_Message_t *MsgPtr;
CFE_SB_Buffer_t *SBBufPtr;
int32 Result = CFE_SUCCESS;
/* Register application */
Expand Down Expand Up @@ -1250,15 +1246,15 @@ void XX_AppMain(void)
CFE_ES_PerfLogExit(XX_APPMAIN_PERF_ID);
/* Wait for the next Software Bus message */
Result = CFE_SB_RcvMsg(&MsgPtr, XX_GlobalData.CmdPipe, CFE_SB_PEND_FOREVER);
Result = CFE_SB_RcvMsg(&SBBufPtr, XX_GlobalData.CmdPipe, CFE_SB_PEND_FOREVER);
/* Performance Log (start time counter) */
CFE_ES_PerfLogEntry(XX_APPMAIN_PERF_ID);
if (Result == CFE_SUCCESS)
{
/* Process Software Bus message */
XX_ProcessPkt(MsgPtr);
XX_ProcessPkt(SBBufPtr);
}
else
{
Expand Down Expand Up @@ -1714,14 +1710,14 @@ functions are only applicable to a specific header type. Additional
information on modifying specific header types is provided in the following
subsections.

| **SB Message Header Field** | **API for Modifying the Header Field** | **Applicability** |
| ---------------------------:| --------------------------------------:| -------------------:|
| Message ID | CFE_MSG_SetMsgId | Command & Telemetry |
| Total Message Length | CFE_MSG_SetSize | Command & Telemetry |
| Command Code | CFE_MSG_SetFcnCode | Command Only |
| Checksum | CFE_MSG_GenerateChecksum | Command Only |
| Time | CFE_SB_TimeStampMsg | Telemetry Only |
| Time | CFE_MSG_SetMsgTime | Telemetry Only |
| **SB Message Header Field** | **API for Modifying the Header Field** |
| ---------------------------:| --------------------------------------:|
| Message ID | CFE_MSG_SetMsgId |
| Total Message Length | CFE_MSG_SetSize |
| Command Code | CFE_MSG_SetFcnCode |
| Checksum | CFE_MSG_GenerateChecksum |
| Time | CFE_SB_TimeStampMsg |
| Time | CFE_MSG_SetMsgTime |

Applications shall always use these functions to manipulate the
Message Header. The structure of the Message Header may change from
Expand Down Expand Up @@ -1760,12 +1756,12 @@ Applications are portable to future missions. The following table
identifies the fields of the Message Header and the appropriate API
for extracting that field from the header:

| **SB Message Header Field** | **API for Reading the Header Field** | **Applicability** |
|:----------------------------|:-------------------------------------|:--------------------|
| Message ID | CFE_MSG_GetMsgId | Command & Telemetry |
| Message Time | CFE_MSG_GetTime | Imp. Dependent |
| Total Message Length | CFE_MSG_GetSize | Command & Telemetry |
| Command Code | CFE_MSG_GetFcnCode | Command Only |
| **SB Message Header Field** | **API for Reading the Header Field** |
|:----------------------------|:-------------------------------------|
| Message ID | CFE_MSG_GetMsgId |
| Message Time | CFE_MSG_GetTime |
| Total Message Length | CFE_MSG_GetSize |
| Command Code | CFE_MSG_GetFcnCode |

There are other APIs based on selected implementation. The full list is
available in the user's guide.
Expand All @@ -1783,9 +1779,8 @@ The preference is to use the actual packet structure when available.
#### 6.6 Sending Software Bus Messages

After an SB message has been created (see Section 6.5) and its contents
have been set to the appropriate values, the application can call
CFE_SB_SendMsg() to send the message on the SB. An example of this is
shown below:
have been set to the appropriate values, the application can then
send the message on the SB. An example of this is shown below:

```
FILE: sample_app.c
Expand All @@ -1795,17 +1790,17 @@ SAMPLE_AppData_t SAMPLE_AppData; /* Instantiate Task Data */
...
{
...
/*
** Get command execution counters and put them into housekeeping SB Message
*/
SAMPLE_AppData.HkPacket.CmdCounter = SAMPLE_AppData.CmdCounter;
SAMPLE_AppData.HkPacket.ErrCounter = SAMPLE_AppData.ErrCounter;
/*
** Get command execution counters...
*/
SAMPLE_APP_Data.HkTlm.Payload.CommandErrorCounter = SAMPLE_APP_Data.ErrCounter;
SAMPLE_APP_Data.HkTlm.Payload.CommandCounter = SAMPLE_APP_Data.CmdCounter;
/*
** Send housekeeping SB Message after time tagging it with current time
*/
CFE_SB_TimeStampMsg((CFE_MSG_Message_t *) &SAMPLE_AppData.HkPacket);
CFE_SB_SendMsg((CFE_MSG_Message_t *) &SAMPLE_AppData.HkPacket);
/*
** Send housekeeping telemetry packet...
*/
CFE_SB_TimeStampMsg(&SAMPLE_APP_Data.HkTlm.TlmHeader.Msg);
CFE_SB_TransmitMsg(&SAMPLE_APP_Data.HkTlm.TlmHeader.Msg, true);
...
}
```
Expand All @@ -1821,7 +1816,6 @@ FILE: sample_app.h
typedef struct
{
...
CFE_MSG_Message_t *MsgPtr;
CFE_SB_PipeId_t CmdPipe;
...
} SAMPLE_AppData_t;
Expand All @@ -1830,13 +1824,15 @@ typedef struct
FILE: sample_app.c
{
...
CFE_SB_Buffer_t *SBBufPtr;
...
while (TRUE)
{
/*
** Wait for the next Software Bus message...
*/
SB_Status = CFE_SB_RcvMsg(&SAMPLE_AppData.MsgPtr,
SB_Status = CFE_SB_RcvMsg(&SBBufPtr,
SAMPLE_AppData.CmdPipe,
CFE_SB_PEND_FOREVER);
Expand All @@ -1845,15 +1841,15 @@ FILE: sample_app.c
/*
** Process Software Bus message...
*/
SAMPLE_AppPipe(SAMPLE_AppData.MsgPtr);
SAMPLE_AppPipe(SBBufPtr);
}
}
}
```

In the above example, the Application will pend on the
SAMPLE_AppData.CmdPipe until an SB Message arrives. A pointer to the next SB
Message in the Pipe will be returned in SAMPLE_AppData.MsgPtr.
message in the Pipe will be returned in SBBufPtr.

Alternatively, the Application could have chosen to pend with a timeout (by
providing a numerical argument in place of CFE_SB_PEND_FOREVER) or to quickly
Expand Down Expand Up @@ -1920,7 +1916,7 @@ FILE: sample_app.h
*/
typedef struct
{
uint8 TlmHeader[CFE_SB_TLM_HDR_SIZE];
CFE_MSG_CommandHeader_t TlmHeader;
/*
** Task command interface counters...
Expand All @@ -1929,14 +1925,17 @@ typedef struct
} SAMPLE_BigPkt_t;
/* Define Msg Length for SAMPLE’s Big Pkt */
#define SAMPLE_BIGPKT_MSGLEN sizeof(SAMPLE_BigPkt_t)
typedef union
{
CFE_SB_Buffer_t SBBuf;
SAMPLE_BigPkt_t Pkt;
} SAMPLE_BigPkt_Buffer_t;
...
typedef struct
{
...
...
SAMPLE_BigPkt_t *BigPktPtr; /* Declare instance of Big Packet */
SAMPLE_BigPkt_Buffer_t *BigPktBuf; /* Declare instance of Big Packet */
...
} SAMPLE_AppData_t;
Expand All @@ -1949,10 +1948,8 @@ SAMPLE_AppData_t SAMPLE_AppData; /* Instantiate Task Data */
/*
** Get a SB Message block of memory and initialize it
*/
SAMPLE_AppData.BigPktPtr = (SAMPLE_BigPkt_t *)CFE_SB_ZeroCopyGetPtr(SAMPLE_BIGPKT_MSGLEN);
CFE_MSG_Init((CFE_MSG_Message_t *) SAMPLE_AppData.BigPktPtr,
SAMPLE_BIG_TLM_MID,
SAMPLE_BIGPKT_MSGLEN);
SAMPLE_AppData.BigPktBuf = (SAMPLE_BigPkt_Buffer_t *)CFE_SB_ZeroCopyGetPtr(sizeof(SAMPLE_BigPkt_t);
CFE_MSG_Init(SAMPLE_AppData.BigPktBuf->Pkt.TlmHeader.Msg, SAMPLE_BIG_TLM_MID, sizeof(SAMPLE_BigPkt_t);
/*
** ...Fill Packet with Data...
Expand All @@ -1961,9 +1958,9 @@ SAMPLE_AppData_t SAMPLE_AppData; /* Instantiate Task Data */
/*
** Send SB Message after time tagging it with current time
*/
CFE_SB_TimeStampMsg((CFE_MSG_Message_t *) SAMPLE_AppData.BigPktPtr);
CFE_SB_ZeroCopySend((CFE_MSG_Message_t *) SAMPLE_AppData.BigPktPtr);
/* SAMPLE_AppData.BigPktPtr is no longer a valid pointer */
CFE_SB_TimeStampMsg(&SAMPLE_AppData.BigPktBuf->Pkt.TlmHeader.Msg);
CFE_SB_ZeroCopySend(SAMPLE_AppData.BigPktBuf);
/* SAMPLE_AppData.BigPktBuf is no longer a valid pointer */
...
}
```
Expand Down
42 changes: 21 additions & 21 deletions docs/src/cfe_sb.dox
Original file line number Diff line number Diff line change
Expand Up @@ -292,20 +292,21 @@

The sequence counter for command messages is not altered by the software bus.

For telemetry messages sent with the #CFE_SB_SendMsg API, the software bus populates the packet sequence
header field for all messages. The first time a telemetry message is sent with a new Message ID,
the sequence counter field in the header is set to a value of one. For subsequent
sends of a message, the sequence counter is incremented by one regardless of the number of
destinations for the packet. After a rollover condition the sequence counter will be a
value of zero for one instance. The sequence counter is incremented in the #CFE_SB_SendMsg
API after all the checks have passed prior to the actual sending of the message. This
includes the parameter checks and the memory allocation check.
Note: The count is incremented regardless of whether there are any subscribers.

For telemetry messages sent with the #CFE_SB_PassMsg API the sequence counter is not incremented.
This method of message delivery is recommended for situations
where the sender did not generate the packet, such as a network interface application
passing a packet from a remote system to the local software bus.
For a telemetry message, the behavior is controlled via input parameters or API selection
when sending the command. When enabled, the software bus will populate the packet sequence
counter using an internal counter that gets intialized upon the first subscription to the
message (first message will have a packet sequence counter value of 1). From that point on
each send request will increment the counter by one, regardless of the number of destinations
or if there is an active subscription.

After a rollover condition the sequence counter will be a value of zero for one instance.
The sequence counter is incremented after all the checks have passed prior to the actual
sending of the message. This includes the parameter checks and the memory allocation check.

When disabled, the original message will not be altered. This method of message delivery
is recommended for situations where the sender did not generate the packet,
such as a network interface application passing a packet from a remote system to the local
software bus.

Next: \ref cfesbugmsgpipeerr <BR>
Prev: \ref cfesbugrouting <BR>
Expand Down Expand Up @@ -369,15 +370,14 @@

There is one case in which events are filtered by the software bus instead of event services.
This occurs when the software bus needs to suppress events so that a fatal recursive event
condition does not transpire. Because the #CFE_SB_SendMsg API is a library function that
calls #CFE_EVS_SendEvent, and #CFE_EVS_SendEvent is a library function that calls #CFE_SB_SendMsg,
condition does not transpire. Because error cases encountered when sending a message generate
an event, and events cause a message to be sent
a calling sequence could cause a stack overflow if the recursion is not properly terminated.
The cFE software bus detects this condition and properly terminates the recursion. This is
done by using a set of flags (one flag per event in the Send API) which determine whether
an API has relinquished its stack. If the #CFE_SB_SendMsg needs to send an event that may
cause recursion, the flag is set and the event is sent. #CFE_EVS_SendEvent then calls #CFE_SB_SendMsg
in the same thread. If the second call to #CFE_SB_SendMsg needs to send that same event again,
it finds that the flag is set and the #CFE_EVS_SendEvent call is bypassed, terminating the
an API has relinquished its stack. If the software bus needs to send an event that may
cause recursion, the flag is set and the event is sent. If sending the event would cause
the same event again, the event call will be bypassed, terminating the
recursion. The result is that the user will see only one event instead of the many events
that would normally occur without the protection. The heritage software bus did not have
this condition because it stored events in the software bus event log and another thread
Expand Down Expand Up @@ -508,7 +508,7 @@
How many copies of the message are performed in a typical message delivery?
</B><TR><TD WIDTH="5%"> &nbsp; <TD WIDTH="95%">
There is a single copy of the message performed during a typical delivery.
During the #CFE_SB_SendMsg API, the software bus copies the message from the
When transmitting a message, the software bus copies the message from the
callers memory space to the software bus memory space. The #CFE_SB_RcvMsg API
gives the user a pointer to the message in the software bus memory space. This
is equivalent to the copy mode send and pointer mode receive in the heritage
Expand Down

0 comments on commit ec0dc36

Please sign in to comment.