From 8753a09a4c69d775cead1f1febafa5c44ac5a936 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Fri, 16 Jun 2023 16:05:04 -0400 Subject: [PATCH 1/7] Fix #2379, implement SB bulk transfer test Add a functional test that moves a large number of messages across the bus as fast as possible (i.e. with no delay). The process is timed, thus offering some metric as to the single thread/single core performance of the software bus implementation underneath. Note that due to vast differences between hardware, results should only be compared between successive runs on the exact same hardware, such as before and after a change was made. --- modules/cfe_assert/inc/cfe_assert.h | 28 ++++ modules/cfe_assert/src/cfe_assert_runner.c | 7 +- modules/cfe_testcase/CMakeLists.txt | 3 +- modules/cfe_testcase/src/cfe_test.c | 1 + modules/cfe_testcase/src/cfe_test.h | 1 + .../cfe_testcase/src/sb_performance_test.c | 147 ++++++++++++++++++ 6 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 modules/cfe_testcase/src/sb_performance_test.c diff --git a/modules/cfe_assert/inc/cfe_assert.h b/modules/cfe_assert/inc/cfe_assert.h index 082b0872e..a464432ac 100644 --- a/modules/cfe_assert/inc/cfe_assert.h +++ b/modules/cfe_assert/inc/cfe_assert.h @@ -163,6 +163,23 @@ typedef void (*CFE_Assert_StatusCallback_t)(uint8 MessageType, const char *Prefi */ #define CFE_Assert_STATUS_STORE(FN) CFE_Assert_Status_Store(FN, __FILE__, __LINE__, #FN) +/** +** \brief Check if the stored status matches a possible value +** +** Allows the caller to check the value from a previous invocation of CFE_Assert_STATUS_STORE() +** without directly asserting on the value or changing test state. +** +** This may be useful in situations where a large volume of tests are being performed, such as +** during performance or load testing, where reporting all "PASS" cases may add signficant +** extra CPU usage and log volume, interfering with the result. This macro can be followed +** or combined with CFE_Assert_STATUS_MAY_BE / CFE_Assert_STATUS_MUST_BE to do actual reporting. + +** \sa #CFE_Assert_STATUS_STORE, #CFE_Assert_STATUS_MAY_BE, #CFE_Assert_STATUS_MUST_BE +** +** \returns Actual CFE_Status_t value from the call +*/ +#define CFE_Assert_STATUS_SILENTCHECK(expected) CFE_Assert_Status_SilentCheck(expected) + /*****************************************************************************/ /** ** \brief Retroactively check for an acceptable status value from CFE_Assert_STATUS_STORE @@ -357,6 +374,17 @@ bool CFE_Assert_StatusCheck(CFE_Status_t Status, bool ExpectSuccess, UtAssert_Ca */ CFE_Status_t CFE_Assert_Status_Store(CFE_Status_t Status, const char *File, uint32 Line, const char *Text); +/** +** \brief Helper function to silently check status of a previously stored result +** +** \par Description +** This helper function will check the status previously stored to a +** temporary holding area, but does not assert on it. +** +** \returns true if status code matched, false if it did not match. +*/ +bool CFE_Assert_Status_SilentCheck(CFE_Status_t Status); + /** ** \brief Helper function for nominal CFE calls with deferred check ** diff --git a/modules/cfe_assert/src/cfe_assert_runner.c b/modules/cfe_assert/src/cfe_assert_runner.c index 5c5216d23..74a0b53a7 100644 --- a/modules/cfe_assert/src/cfe_assert_runner.c +++ b/modules/cfe_assert/src/cfe_assert_runner.c @@ -111,6 +111,11 @@ CFE_Status_t CFE_Assert_Status_Store(CFE_Status_t Status, const char *File, uint return Status; } +bool CFE_Assert_Status_SilentCheck(CFE_Status_t Status) +{ + return (Status == CFE_Assert_Global.StoredStatus); +} + bool CFE_Assert_Status_DeferredCheck(CFE_Status_t Status, UtAssert_CaseType_t CaseType, const char *File, uint32 Line, const char *Text) { @@ -125,7 +130,7 @@ bool CFE_Assert_Status_DeferredCheck(CFE_Status_t Status, UtAssert_CaseType_t Ca } else { - Result = (Status == CFE_Assert_Global.StoredStatus); + Result = CFE_Assert_Status_SilentCheck(Status); if (Result) { /* no extra tag added to "true" conditions */ diff --git a/modules/cfe_testcase/CMakeLists.txt b/modules/cfe_testcase/CMakeLists.txt index bed726c1a..6c83749ca 100644 --- a/modules/cfe_testcase/CMakeLists.txt +++ b/modules/cfe_testcase/CMakeLists.txt @@ -2,7 +2,7 @@ include_directories(inc) # Filenames based on doxygen groups. # Create the app module -add_cfe_app(cfe_testcase +add_cfe_app(cfe_testcase src/cfe_test.c src/cfe_test_table.c src/es_application_control_test.c @@ -23,6 +23,7 @@ add_cfe_app(cfe_testcase src/message_id_test.c src/msg_api_test.c src/resource_id_misc_test.c + src/sb_performance_test.c src/sb_pipe_mang_test.c src/sb_sendrecv_test.c src/sb_subscription_test.c diff --git a/modules/cfe_testcase/src/cfe_test.c b/modules/cfe_testcase/src/cfe_test.c index 9a655f0ea..388a289bf 100644 --- a/modules/cfe_testcase/src/cfe_test.c +++ b/modules/cfe_testcase/src/cfe_test.c @@ -78,6 +78,7 @@ void CFE_TestMain(void) SBPipeMangSetup(); SBSendRecvTestSetup(); SBSubscriptionTestSetup(); + SBPerformanceTestSetup(); TBLContentAccessTestSetup(); TBLContentMangTestSetup(); TBLInformationTestSetup(); diff --git a/modules/cfe_testcase/src/cfe_test.h b/modules/cfe_testcase/src/cfe_test.h index 1bd1c4e65..c31e83a5a 100644 --- a/modules/cfe_testcase/src/cfe_test.h +++ b/modules/cfe_testcase/src/cfe_test.h @@ -89,6 +89,7 @@ void FSUtilTestSetup(void); void MessageIdTestSetup(void); void MsgApiTestSetup(void); void ResourceIdMiscTestSetup(void); +void SBPerformanceTestSetup(void); void SBPipeMangSetup(void); void SBSendRecvTestSetup(void); void SBSubscriptionTestSetup(void); diff --git a/modules/cfe_testcase/src/sb_performance_test.c b/modules/cfe_testcase/src/sb_performance_test.c new file mode 100644 index 000000000..e56b1e09d --- /dev/null +++ b/modules/cfe_testcase/src/sb_performance_test.c @@ -0,0 +1,147 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * @file + * + * Functional test of SB transmit/receive API performance + * + * The intent of this test is to perform a set of SB message transfers + * at a sufficiently high rate / volume such that the performance of + * the implementation can be characterized. Note that this + * cannot (currently) measure the performance directly, it merely implements a + * scenario that allows the performance to be measured by an external test + * harness. + */ + +#include "cfe_test.h" +#include "cfe_msgids.h" +#include "cfe_test_msgids.h" + +/* A simple command message */ +typedef struct +{ + CFE_MSG_CommandHeader_t CommandHeader; + uint32 CmdPayload; +} CFE_FT_TestCmdMessage_t; + +/* A simple telemetry message */ +typedef struct +{ + CFE_MSG_TelemetryHeader_t TelemetryHeader; + uint32 TlmPayload; +} CFE_FT_TestTlmMessage_t; + +/* + * This test procedure should be agnostic to specific MID values, but it should + * not overlap/interfere with real MIDs used by other apps. + */ +static const CFE_SB_MsgId_t CFE_FT_CMD_MSGID = CFE_SB_MSGID_WRAP_VALUE(CFE_TEST_CMD_MID); +static const CFE_SB_MsgId_t CFE_FT_TLM_MSGID = CFE_SB_MSGID_WRAP_VALUE(CFE_TEST_HK_TLM_MID); + +void TestBulkTransmitRecv(void) +{ + CFE_SB_PipeId_t PipeId1 = CFE_SB_INVALID_PIPE; + CFE_SB_PipeId_t PipeId2 = CFE_SB_INVALID_PIPE; + CFE_FT_TestCmdMessage_t CmdMsg; + CFE_FT_TestTlmMessage_t TlmMsg; + CFE_SB_Buffer_t * MsgBuf; + const CFE_FT_TestCmdMessage_t *CmdPtr; + const CFE_FT_TestTlmMessage_t *TlmPtr; + uint32 SendCount; + OS_time_t StartTime; + OS_time_t ElapsedTime; + + memset(&CmdMsg, 0, sizeof(CmdMsg)); + memset(&TlmMsg, 0, sizeof(TlmMsg)); + + UtPrintf("Testing: Bulk SB Transmit/Receive"); + CFE_PSP_GetTime(&StartTime); + + /* Setup, create a pipe and subscribe (one cmd, one tlm) */ + UtAssert_INT32_EQ(CFE_SB_CreatePipe(&PipeId1, 5, "TestPipe1"), CFE_SUCCESS); + UtAssert_INT32_EQ(CFE_SB_CreatePipe(&PipeId2, 5, "TestPipe2"), CFE_SUCCESS); + UtAssert_INT32_EQ(CFE_SB_SubscribeEx(CFE_FT_CMD_MSGID, PipeId1, CFE_SB_DEFAULT_QOS, 3), CFE_SUCCESS); + UtAssert_INT32_EQ(CFE_SB_SubscribeEx(CFE_FT_TLM_MSGID, PipeId2, CFE_SB_DEFAULT_QOS, 3), CFE_SUCCESS); + + /* Initialize the message content */ + UtAssert_INT32_EQ(CFE_MSG_Init(CFE_MSG_PTR(CmdMsg.CommandHeader), CFE_FT_CMD_MSGID, sizeof(CmdMsg)), CFE_SUCCESS); + UtAssert_INT32_EQ(CFE_MSG_Init(CFE_MSG_PTR(TlmMsg.TelemetryHeader), CFE_FT_TLM_MSGID, sizeof(TlmMsg)), CFE_SUCCESS); + + for (SendCount = 0; SendCount < 1000000; ++SendCount) + { + CmdMsg.CmdPayload = SendCount; + TlmMsg.TlmPayload = ~SendCount; + + /* In order to not "flood" with test results, this should be silent unless a failure occurs */ + CFE_Assert_STATUS_STORE(CFE_SB_TransmitMsg(CFE_MSG_PTR(CmdMsg.CommandHeader), true)); + if (!CFE_Assert_STATUS_SILENTCHECK(CFE_SUCCESS)) + { + break; + } + + CFE_Assert_STATUS_STORE(CFE_SB_TransmitMsg(CFE_MSG_PTR(TlmMsg.TelemetryHeader), true)); + if (!CFE_Assert_STATUS_SILENTCHECK(CFE_SUCCESS)) + { + break; + } + + CFE_Assert_STATUS_STORE(CFE_SB_ReceiveBuffer(&MsgBuf, PipeId1, CFE_SB_POLL)); + if (!CFE_Assert_STATUS_SILENTCHECK(CFE_SUCCESS)) + { + break; + } + + /* As above, to avoid flooding of test cases, only report mismatch here */ + CmdPtr = (const void *)MsgBuf; + if (CmdPtr->CmdPayload != CmdMsg.CmdPayload) + { + UtAssert_UINT32_EQ(CmdPtr->CmdPayload, CmdMsg.CmdPayload); + break; + } + + CFE_Assert_STATUS_STORE(CFE_SB_ReceiveBuffer(&MsgBuf, PipeId2, CFE_SB_POLL)); + if (!CFE_Assert_STATUS_SILENTCHECK(CFE_SUCCESS)) + { + break; + } + + TlmPtr = (const void *)MsgBuf; + if (TlmPtr->TlmPayload != TlmMsg.TlmPayload) + { + UtAssert_UINT32_EQ(TlmPtr->TlmPayload, TlmMsg.TlmPayload); + break; + } + + /* report progress periodically */ + if ((SendCount % 50000) == 0) + { + UtPrintf("Success after %lu messages", (unsigned long)SendCount); + } + } + + CFE_PSP_GetTime(&ElapsedTime); + ElapsedTime = OS_TimeSubtract(ElapsedTime, StartTime); + + UtAssert_MIR("Elapsed time for SB bulk message test: %lu usec", OS_TimeGetTotalMicroseconds(ElapsedTime)); +} + +void SBPerformanceTestSetup(void) +{ + UtTest_Add(TestBulkTransmitRecv, NULL, NULL, "Test Bulk SB Transmit/Receive"); +} From 126e23d27c1d7b363f4768b652631e318e57d61b Mon Sep 17 00:00:00 2001 From: Jacob Hageman Date: Mon, 17 Jul 2023 14:54:12 +0000 Subject: [PATCH 2/7] Fix #1991, TriggerMode unsigned compare with 0 --- modules/es/fsw/src/cfe_es_perf.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/es/fsw/src/cfe_es_perf.c b/modules/es/fsw/src/cfe_es_perf.c index c6a86ad76..62233a6fa 100644 --- a/modules/es/fsw/src/cfe_es_perf.c +++ b/modules/es/fsw/src/cfe_es_perf.c @@ -155,8 +155,7 @@ int32 CFE_ES_StartPerfDataCmd(const CFE_ES_StartPerfDataCmd_t *data) PerfDumpState->PendingState == CFE_ES_PerfDumpState_IDLE) { /* Make sure Trigger Mode is valid */ - /* cppcheck-suppress unsignedPositive */ - if ((CmdPtr->TriggerMode >= CFE_ES_PERF_TRIGGER_START) && (CmdPtr->TriggerMode < CFE_ES_PERF_MAX_MODES)) + if (CmdPtr->TriggerMode < CFE_ES_PERF_MAX_MODES) { CFE_ES_Global.TaskData.CommandCounter++; From 5843440428738191fddc96b5c59a0b54cd08625d Mon Sep 17 00:00:00 2001 From: Jacob Hageman Date: Mon, 17 Jul 2023 15:30:54 +0000 Subject: [PATCH 3/7] Fix #2334, Uninitialized PktTime in EVS_SendViaPorts --- modules/evs/fsw/src/cfe_evs_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/evs/fsw/src/cfe_evs_utils.c b/modules/evs/fsw/src/cfe_evs_utils.c index bf6057b05..f6fcc3260 100644 --- a/modules/evs/fsw/src/cfe_evs_utils.c +++ b/modules/evs/fsw/src/cfe_evs_utils.c @@ -540,7 +540,7 @@ void EVS_SendViaPorts(CFE_EVS_LongEventTlm_t *EVS_PktPtr) { char PortMessage[CFE_EVS_MAX_PORT_MSG_LENGTH]; char TimeBuffer[CFE_TIME_PRINTED_STRING_SIZE]; - CFE_TIME_SysTime_t PktTime; + CFE_TIME_SysTime_t PktTime = {0}; CFE_MSG_GetMsgTime(CFE_MSG_PTR(EVS_PktPtr->TelemetryHeader), &PktTime); CFE_TIME_Print(TimeBuffer, PktTime); From 2afb1342256a16eded511c765d5aa055f0cc975f Mon Sep 17 00:00:00 2001 From: Jacob Hageman Date: Mon, 17 Jul 2023 15:41:23 +0000 Subject: [PATCH 4/7] Fix #2402, Uninitialized ExceptionTaskID in CFE_ES_RunExceptionScan --- modules/es/fsw/src/cfe_es_erlog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/es/fsw/src/cfe_es_erlog.c b/modules/es/fsw/src/cfe_es_erlog.c index 35e437288..e65163a1c 100644 --- a/modules/es/fsw/src/cfe_es_erlog.c +++ b/modules/es/fsw/src/cfe_es_erlog.c @@ -274,7 +274,7 @@ bool CFE_ES_RunExceptionScan(uint32 ElapsedTime, void *Arg) uint32 PspContextId; char ReasonString[CFE_ES_ERLOG_DESCRIPTION_MAX_LENGTH]; CFE_ES_TaskInfo_t EsTaskInfo; - osal_id_t ExceptionTaskID; + osal_id_t ExceptionTaskID = OS_OBJECT_ID_UNDEFINED; uint32 ResetType; CFE_ES_LogEntryType_Enum_t LogType; CFE_ES_AppRecord_t * AppRecPtr; From 9579423ed8c7f3a471d090d73dcf3b5bef3d2c3f Mon Sep 17 00:00:00 2001 From: dzbaker Date: Tue, 8 Aug 2023 11:15:15 -0400 Subject: [PATCH 5/7] Fix #2419, Fixes errors in IC Bundle workflow file --- .github/workflows/icbundle.yml | 5 ++--- CHANGELOG.md | 10 +--------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/.github/workflows/icbundle.yml b/.github/workflows/icbundle.yml index c943edd86..460cff552 100644 --- a/.github/workflows/icbundle.yml +++ b/.github/workflows/icbundle.yml @@ -58,11 +58,10 @@ jobs: see_entry="${see_entry}"$' ' done changelog_entry="${changelog_entry}\n${see_entry}\n" - echo "s|# Changelog|$changelog_entry|" - sed -ir "s|Changelog|$changelog_entry|" CHANGELOG.md + sed -ir "s|# Changelog|$changelog_entry|" CHANGELOG.md buildnumber_entry=$'#define CFE_BUILD_NUMBER '${rev_num}$' /**< @brief Development: Number of development git commits since CFE_BUILD_BASELINE */' - sed -ir "s|define CFE_BUILD_NUMBER.*|$buildnumber_entry|" modules/core_api/fsw/inc/cfe_version.h + sed -ir "s|#define CFE_BUILD_NUMBER.*|$buildnumber_entry|" modules/core_api/fsw/inc/cfe_version.h - name: Commit and Push Updates to IC Branch env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 712ec25fe..e164788c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -102,15 +102,7 @@ - See ## Development Build: v7.0.0-rc4+dev197 -- Remove # Changelog - -## Development Build: v7.0.0-rc4+dev342 -- 'Fix #2368, cFE Functional Test 23' -- 'Fix #1407, Add error report on EVS failure during log header write' -- 'Fix #1515, Remove unnecessary memset from CFE_TBL_LoadFromFile' -- See: - in Doxygen Config -- See +- Remove Changelog in Doxygen Config ## Development Build: v7.0.0-rc4+dev193 - Remove redundant/inconsistent comments (/* end of function */, /* end if */ etc.) and clean up empty lines. From eda9fc5a13d07d8a2a187c60a6a74842e8f66193 Mon Sep 17 00:00:00 2001 From: Dylan Date: Fri, 1 Sep 2023 07:47:58 -0400 Subject: [PATCH 6/7] Updating documentation and version numbers for v7.0.0-rc4+dev370 --- CHANGELOG.md | 8 ++++++++ modules/core_api/fsw/inc/cfe_version.h | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 300b0aa03..3ce8c38fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## Development Build: v7.0.0-rc4+dev384 +- Uninitialized PktTime in EVS_SendViaPorts +- Uninitialized ExceptionTaskID in CFE_ES_RunExceptionScan +- implement SB bulk transfer test +- TriggerMode unsigned compare with 0 +- Fixes errors in IC Bundle workflow file +- See: , , , , and + ## Development Build: v7.0.0-rc4+dev370 - 'Fix #2430, reinstate example header files.' - See: diff --git a/modules/core_api/fsw/inc/cfe_version.h b/modules/core_api/fsw/inc/cfe_version.h index 4052751d4..25dea4790 100644 --- a/modules/core_api/fsw/inc/cfe_version.h +++ b/modules/core_api/fsw/inc/cfe_version.h @@ -26,7 +26,7 @@ #define CFE_VERSION_H /* Development Build Macro Definitions */ -#define CFE_BUILD_NUMBER 370 /**< @brief Development: Number of development git commits since CFE_BUILD_BASELINE */ +#define CFE_BUILD_NUMBER 384 /**< @brief Development: Number of development git commits since CFE_BUILD_BASELINE */ #define CFE_BUILD_BASELINE "v7.0.0-rc4" /**< @brief Development: Reference git tag for build number */ /* See \ref cfsversions for definitions */ From 14c3daa6cb5acda9a5ade92a89a512734da8668c Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Fri, 1 Sep 2023 10:16:29 -0400 Subject: [PATCH 7/7] HotFix #2438, add required cast to printf output --- modules/cfe_testcase/src/sb_performance_test.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/cfe_testcase/src/sb_performance_test.c b/modules/cfe_testcase/src/sb_performance_test.c index e56b1e09d..25f86ef44 100644 --- a/modules/cfe_testcase/src/sb_performance_test.c +++ b/modules/cfe_testcase/src/sb_performance_test.c @@ -138,7 +138,8 @@ void TestBulkTransmitRecv(void) CFE_PSP_GetTime(&ElapsedTime); ElapsedTime = OS_TimeSubtract(ElapsedTime, StartTime); - UtAssert_MIR("Elapsed time for SB bulk message test: %lu usec", OS_TimeGetTotalMicroseconds(ElapsedTime)); + UtAssert_MIR("Elapsed time for SB bulk message test: %lu usec", + (unsigned long)OS_TimeGetTotalMicroseconds(ElapsedTime)); } void SBPerformanceTestSetup(void)