From 039608987823c78ac986ac7d173c7770a5c9bc59 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Mon, 6 Dec 2021 10:18:19 -0500 Subject: [PATCH] Fix #103, add option to configure base tick rate SCH_LAB was fixed at 1Hz because it bound to the 1Hz tick from CFE_TIME. This creates an OSAL timer instead, which posts a semaphore, and this can serve as a much more flexible time source, with configurable rate. This still binds to 1Hz and the SCH does not start its first message until the first 1Hz is received, thereby keeping some form of 1Hz sync. --- fsw/platform_inc/sch_lab_table.h | 3 +- fsw/src/sch_lab_app.c | 80 ++++++++++++++++++++++++++++++-- fsw/tables/sch_lab_table.c | 3 +- 3 files changed, 79 insertions(+), 7 deletions(-) diff --git a/fsw/platform_inc/sch_lab_table.h b/fsw/platform_inc/sch_lab_table.h index 22e0993..b76cd8d 100644 --- a/fsw/platform_inc/sch_lab_table.h +++ b/fsw/platform_inc/sch_lab_table.h @@ -48,12 +48,13 @@ typedef struct { CFE_SB_MsgId_t MessageID; /* Message ID for the table entry */ - uint32 PacketRate; /* Rate: Send packet every N seconds */ + uint32 PacketRate; /* Rate: Send packet every N ticks */ CFE_MSG_FcnCode_t FcnCode; /* Command/Function code to set */ } SCH_LAB_ScheduleTableEntry_t; typedef struct { + uint32 TickRate; /* Ticks per second to configure for timer (0=default) */ SCH_LAB_ScheduleTableEntry_t Config[SCH_LAB_MAX_SCHEDULE_ENTRIES]; } SCH_LAB_ScheduleTable_t; diff --git a/fsw/src/sch_lab_app.c b/fsw/src/sch_lab_app.c index 2539267..e30879b 100644 --- a/fsw/src/sch_lab_app.c +++ b/fsw/src/sch_lab_app.c @@ -59,6 +59,8 @@ typedef struct typedef struct { SCH_LAB_StateEntry_t State[SCH_LAB_MAX_SCHEDULE_ENTRIES]; + osal_id_t TimerId; + osal_id_t TimingSem; CFE_TBL_Handle_t TblHandle; CFE_SB_PipeId_t CmdPipe; } SCH_LAB_GlobalData_t; @@ -80,8 +82,9 @@ void SCH_Lab_AppMain(void) { int i; uint32 SCH_OneHzPktsRcvd = 0; - uint32 Status = CFE_SUCCESS; - uint32 RunStatus = CFE_ES_RunStatus_APP_RUN; + int32 OsStatus; + CFE_Status_t Status; + uint32 RunStatus = CFE_ES_RunStatus_APP_RUN; SCH_LAB_StateEntry_t *LocalStateEntry; CFE_SB_Buffer_t * SBBufPtr; @@ -99,16 +102,29 @@ void SCH_Lab_AppMain(void) { CFE_ES_PerfLogExit(SCH_MAIN_TASK_PERF_ID); - /* Pend on receipt of 1Hz packet */ - Status = CFE_SB_ReceiveBuffer(&SBBufPtr, SCH_LAB_Global.CmdPipe, CFE_SB_PEND_FOREVER); + /* Pend on timing sem */ + OsStatus = OS_CountSemTake(SCH_LAB_Global.TimingSem); + if (OsStatus == OS_SUCCESS) + { + /* check for arrival of the 1Hz - this should sync counts (TBD) */ + Status = CFE_SB_ReceiveBuffer(&SBBufPtr, SCH_LAB_Global.CmdPipe, CFE_SB_POLL); + } + else + { + Status = CFE_STATUS_EXTERNAL_RESOURCE_FAIL; + } CFE_ES_PerfLogEntry(SCH_MAIN_TASK_PERF_ID); if (Status == CFE_SUCCESS) { SCH_OneHzPktsRcvd++; + } + + if (OsStatus == OS_SUCCESS && SCH_OneHzPktsRcvd > 0) + { /* - ** Process table every second, sending packets that are ready + ** Process table every tick, sending packets that are ready */ LocalStateEntry = SCH_LAB_Global.State; for (i = 0; i < SCH_LAB_MAX_SCHEDULE_ENTRIES; i++) @@ -132,6 +148,11 @@ void SCH_Lab_AppMain(void) } /* end SCH_Lab_AppMain */ +void SCH_LAB_LocalTimerCallback(osal_id_t object_id, void *arg) +{ + OS_CountSemGive(SCH_LAB_Global.TimingSem); +} + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* */ /* SCH_LAB_AppInit() -- initialization */ @@ -141,12 +162,38 @@ int32 SCH_LAB_AppInit(void) { int i; int32 Status; + int32 OsStatus; + uint32 TimerPeriod; + osal_id_t TimeBaseId; SCH_LAB_ScheduleTable_t * ConfigTable; SCH_LAB_ScheduleTableEntry_t *ConfigEntry; SCH_LAB_StateEntry_t * LocalStateEntry; memset(&SCH_LAB_Global, 0, sizeof(SCH_LAB_Global)); + OsStatus = OS_CountSemCreate(&SCH_LAB_Global.TimingSem, "SCH_LAB", 0, 0); + if (OsStatus != OS_SUCCESS) + { + CFE_ES_WriteToSysLog("%s: OS_CountSemCreate failed:RC=%ld\n", __func__, (long)OsStatus); + return CFE_STATUS_EXTERNAL_RESOURCE_FAIL; + } + + /* The underlying timebase object should have been created by the PSP */ + OsStatus = OS_TimeBaseGetIdByName(&TimeBaseId, "cFS-Master"); + if (OsStatus != OS_SUCCESS) + { + CFE_ES_WriteToSysLog("%s: OS_TimeBaseGetIdByName failed:RC=%ld\n", __func__, (long)OsStatus); + return CFE_STATUS_EXTERNAL_RESOURCE_FAIL; + } + + /* Create the timer callback (but not set yet, as that requires the config table) */ + OsStatus = OS_TimerAdd(&SCH_LAB_Global.TimerId, "SCH_LAB", TimeBaseId, SCH_LAB_LocalTimerCallback, NULL); + if (OsStatus != OS_SUCCESS) + { + CFE_ES_WriteToSysLog("%s: OS_TimerAdd failed:RC=%ld\n", __func__, (long)OsStatus); + return CFE_STATUS_EXTERNAL_RESOURCE_FAIL; + } + /* ** Register tables with cFE and load default data */ @@ -203,6 +250,22 @@ int32 SCH_LAB_AppInit(void) ++LocalStateEntry; } + if (ConfigTable->TickRate == 0) + { + /* use default of 1 second */ + CFE_ES_WriteToSysLog("%s: Using default tick rate of 1 second\n", __func__); + TimerPeriod = 1000000; + } + else + { + TimerPeriod = 1000000 / ConfigTable->TickRate; + if ((TimerPeriod * ConfigTable->TickRate) != 1000000) + { + CFE_ES_WriteToSysLog("%s: WARNING: tick rate of %lu is not an integer number of microseconds\n", __func__, + (unsigned long)ConfigTable->TickRate); + } + } + /* ** Release the table */ @@ -225,6 +288,13 @@ int32 SCH_LAB_AppInit(void) OS_printf("SCH Error subscribing to 1hz!\n"); } + /* Set timer period */ + OsStatus = OS_TimerSet(SCH_LAB_Global.TimerId, 1000000, TimerPeriod); + if (OsStatus != OS_SUCCESS) + { + CFE_ES_WriteToSysLog("%s: OS_TimerSet failed:RC=%ld\n", __func__, (long)OsStatus); + } + OS_printf("SCH Lab Initialized.%s\n", SCH_LAB_VERSION_STRING); return (CFE_SUCCESS); diff --git a/fsw/tables/sch_lab_table.c b/fsw/tables/sch_lab_table.c index 90920b8..db4d87c 100644 --- a/fsw/tables/sch_lab_table.c +++ b/fsw/tables/sch_lab_table.c @@ -49,7 +49,8 @@ ** 3. If the table grows too big, increase SCH_LAB_MAX_SCHEDULE_ENTRIES */ -SCH_LAB_ScheduleTable_t SCH_TBL_Structure = {.Config = { +SCH_LAB_ScheduleTable_t SCH_TBL_Structure = {.TickRate = 1, + .Config = { {CFE_SB_MSGID_WRAP_VALUE(CFE_ES_SEND_HK_MID), 4, 0}, {CFE_SB_MSGID_WRAP_VALUE(CFE_EVS_SEND_HK_MID), 4, 0}, {CFE_SB_MSGID_WRAP_VALUE(CFE_TIME_SEND_HK_MID), 4, 0},