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 #171, use OSAL timebase for CFE timers #286

Merged
Merged
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
7 changes: 7 additions & 0 deletions fsw/inc/cfe_psp.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,13 @@
#define CFE_PSP_MISSION_REV (GLOBAL_PSP_CONFIGDATA.PSP_VersionInfo.MissionRev)
#define CFE_PSP_VERSION (GLOBAL_PSP_CONFIGDATA.PSP_VersionInfo.VersionString)

/**
* \brief The name of the software/RTOS timebase for general system timers.
*
* This name may be referred to by CFE TIME and/or SCH when setting up its own timers.
*/
#define CFE_PSP_SOFT_TIMEBASE_NAME "cFS-Master"

/*
** Type Definitions
*/
Expand Down
10 changes: 10 additions & 0 deletions fsw/mcp750-vxworks/inc/cfe_psp_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@
*/
#define CFE_PSP_MAX_EXCEPTION_ENTRIES 4

/*
* The tick period that will be configured in the RTOS for the simulated
* time base, in microseconds. This in turn is used to drive the 1hz clock
* and other functions.
*
* On the MCP750 the sysClockRate runs at 60Hz so this is the same period
* that the cFE software timebase will be configured at.
*/
#define CFE_PSP_SOFT_TIMEBASE_PERIOD 16666

/*
** Typedef for the layout of the vxWorks boot record structure
**
Expand Down
3 changes: 2 additions & 1 deletion fsw/mcp750-vxworks/psp_module_list.cmake
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# This is a list of modules that is included as a fixed/base set
# This is a list of modules that is included as a fixed/base set
# when this PSP is selected. They must exist under fsw/modules

soft_timebase
eeprom_direct
28 changes: 0 additions & 28 deletions fsw/mcp750-vxworks/src/cfe_psp_start.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ IMPORT void sysPciWrite32(UINT32, UINT32);

#define CFE_PSP_MAIN_FUNCTION (*GLOBAL_CONFIGDATA.CfeConfig->SystemMain)
#define CFE_PSP_NONVOL_STARTUP_FILE (GLOBAL_CONFIGDATA.CfeConfig->NonvolStartupFile)
#define CFE_PSP_1HZ_FUNCTION (*GLOBAL_CONFIGDATA.CfeConfig->System1HzISR)

/******************************************************************************
** Function: OS_Application_Startup()
Expand Down Expand Up @@ -232,30 +231,3 @@ void OS_Application_Startup(void)
*/
CFE_PSP_MAIN_FUNCTION(reset_type, reset_subtype, 1, CFE_PSP_NONVOL_STARTUP_FILE);
}

/******************************************************************************
** Function: OS_Application_Run()
**
** Purpose:
** Idle Loop entry point from OSAL BSP.
**
** Arguments:
** (none)
**
** Return:
** (none)
*/
void OS_Application_Run(void)
{
int TicksPerSecond;

/*
** Main loop for default task and simulated 1hz
*/
for (;;)
{
TicksPerSecond = sysClkRateGet();
(void)taskDelay(TicksPerSecond);
CFE_PSP_1HZ_FUNCTION();
}
}
3 changes: 3 additions & 0 deletions fsw/modules/soft_timebase/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

# Create the module
add_psp_module(soft_timebase cfe_psp_soft_timebase.c)
82 changes: 82 additions & 0 deletions fsw/modules/soft_timebase/cfe_psp_soft_timebase.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
** GSC-18128-1, "Core Flight Executive Version 6.7"
**
** Copyright (c) 2006-2019 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 cfe_psp_soft_timebase.c
*
* A PSP module that instantiates an RTOS-backed OSAL timebase to provide
* various timing services. This in turn may be used to drive CFE TIME 1Hz
* signal, the CFS SCH major/minor frame sync and other periodic services
* in CFE.
*
* This module can be used on systems which do not have a hardware
* source for the 1Hz signal or timing info (i.e. simulation, test
* and debug platforms, etc).
*/

#include "cfe_psp.h"
#include "cfe_psp_module.h"
#include "cfe_psp_config.h"

CFE_PSP_MODULE_DECLARE_SIMPLE(soft_timebase);

/*
* Global state data for this module (not exposed publicly)
*/
static struct
{
osal_id_t sys_timebase_id;
} PSP_SoftTimebase_Global;

void soft_timebase_Init(uint32 PspModuleId)
{
int32 status;

memset(&PSP_SoftTimebase_Global, 0, sizeof(PSP_SoftTimebase_Global));

/* Set up the OSAL timebase using the well-known name */
status = OS_TimeBaseCreate(&PSP_SoftTimebase_Global.sys_timebase_id, CFE_PSP_SOFT_TIMEBASE_NAME, NULL);
if (status == OS_SUCCESS)
{
/* Set the timebase to trigger with desired resolution */
status = OS_TimeBaseSet(PSP_SoftTimebase_Global.sys_timebase_id, CFE_PSP_SOFT_TIMEBASE_PERIOD,
CFE_PSP_SOFT_TIMEBASE_PERIOD);
}

/*
* The only way this can fail is through a misconfiguration or API incompatibility -
* if it fails, it means all timing related functions are likely to be broken,
* CFE TIME may not work correctly, and background jobs will not run.
*
* Might even be worth a CFE_PSP_Panic(), but it still may be possible
* to boot CFE and (maybe) save the system by uploading a file with the bug fixed.
*/
if (status != OS_SUCCESS)
{
printf("CFE_PSP: *** Failed to configure software timebase \'%s\', status = %d! ***\n",
CFE_PSP_SOFT_TIMEBASE_NAME, (int)status);
}
else
{
/* Inform the user that this module is in use */
printf("CFE_PSP: Instantiated software timebase \'%s\' running at %lu usec\n", CFE_PSP_SOFT_TIMEBASE_NAME,
(unsigned long)CFE_PSP_SOFT_TIMEBASE_PERIOD);
}
}
13 changes: 13 additions & 0 deletions fsw/pc-linux/inc/cfe_psp_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,19 @@
/* use the "USR1" signal to wake the idle thread when an exception occurs */
#define CFE_PSP_EXCEPTION_EVENT_SIGNAL SIGUSR1

/*
* The tick period that will be configured in the RTOS for the simulated
* time base, in microseconds. This in turn is used to drive the 1hz clock
* and other functions.
*
* To minimize jitter in the resulting callbacks, it should be an even
* divisor of 1000000 usec.
*
* Note - 10ms/100Hz is chosen to also allow this same timebase to be
* used to drive the CFS SCH minor frame callbacks in its default config.
*/
#define CFE_PSP_SOFT_TIMEBASE_PERIOD 10000

/*
** Global variables
*/
Expand Down
3 changes: 2 additions & 1 deletion fsw/pc-linux/psp_module_list.cmake
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# This is a list of modules that is included as a fixed/base set
# This is a list of modules that is included as a fixed/base set
# when this PSP is selected. They must exist under fsw/modules

soft_timebase
eeprom_mmap_file
142 changes: 0 additions & 142 deletions fsw/pc-linux/src/cfe_psp_start.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,8 @@ typedef struct
/*
** Prototypes for this module
*/
void CFE_PSP_TimerHandler(int signum);
void CFE_PSP_DisplayUsage(char *Name);
void CFE_PSP_ProcessArgumentDefaults(CFE_PSP_CommandData_t *CommandDataDefault);
void CFE_PSP_SetupLocal1Hz(void);

/*
** Global variables
Expand Down Expand Up @@ -212,8 +210,6 @@ void OS_Application_Startup(void)
{
uint32 reset_type;
uint32 reset_subtype;
int32 time_status;
osal_id_t sys_timebase_id;
osal_id_t fs_id;
int opt = 0;
int longIndex = 0;
Expand Down Expand Up @@ -342,41 +338,6 @@ void OS_Application_Startup(void)
memset(&CFE_PSP_IdleTaskState, 0, sizeof(CFE_PSP_IdleTaskState));
CFE_PSP_IdleTaskState.ThreadID = pthread_self();

/*
** Set up the timebase, if OSAL supports it
** Done here so that the modules can also use it, if desired
**
** This is a clock named "cFS-Master" that will serve to drive
** all time-related CFE functions including the 1Hz signal.
**
** Note the timebase is only prepared here; the application is
** not ready to receive a callback yet, as it hasn't been started.
** CFE TIME registers its own callback when it is ready to do so.
*/
time_status = OS_TimeBaseCreate(&sys_timebase_id, "cFS-Master", NULL);
if (time_status == OS_SUCCESS)
{
/*
* Set the clock to trigger with 50ms resolution - slow enough that
* it will not hog CPU resources but fast enough to have sufficient resolution
* for most general timing purposes.
* (It may be better to move this to the mission config file)
*/
time_status = OS_TimeBaseSet(sys_timebase_id, 50000, 50000);
}
else
{
/*
* Cannot create a timebase in OSAL.
*
* Note: Most likely this is due to building with
* the old/classic POSIX OSAL which does not support this.
*
* See below for workaround.
*/
sys_timebase_id = OS_OBJECT_ID_UNDEFINED;
}

/*
** Set up the virtual FS mapping for the "/cf" directory
** On this platform it is just a local/relative dir of the same name.
Expand Down Expand Up @@ -453,15 +414,6 @@ void OS_Application_Startup(void)
** Call cFE entry point.
*/
CFE_PSP_MAIN_FUNCTION(reset_type, reset_subtype, 1, CFE_PSP_NONVOL_STARTUP_FILE);

/*
* Backward compatibility for old OSAL.
*/
if (!OS_ObjectIdDefined(sys_timebase_id) || time_status != OS_SUCCESS)
{
OS_printf("CFE_PSP: WARNING - Compatibility mode - using local 1Hz Interrupt\n");
CFE_PSP_SetupLocal1Hz();
}
}

void OS_Application_Run(void)
Expand Down Expand Up @@ -522,31 +474,6 @@ void OS_Application_Run(void)
OS_DeleteAllObjects();
}

/******************************************************************************
** Function: CFE_PSP_TimerHandler()
**
** Purpose:
** 1hz "isr" routine for linux/OSX
** This timer handler will execute 4 times a second.
**
** Arguments:
** (none)
**
** Return:
** (none)
*/
void CFE_PSP_TimerHandler(int signum)
{
/*
** call the CFE_TIME 1hz ISR
*/
if ((TimerCounter % 4) == 0)
CFE_PSP_1HZ_FUNCTION();

/* update timer counter */
TimerCounter++;
}

/******************************************************************************
** Function: CFE_PSP_DisplayUsage
**
Expand Down Expand Up @@ -639,72 +566,3 @@ void CFE_PSP_ProcessArgumentDefaults(CFE_PSP_CommandData_t *CommandDataDefault)
CommandDataDefault->GotCpuName = 1;
}
}

/******************************************************************************
** Function: CFE_PSP_SetupLocal1Hz
**
** Purpose:
** This is a backward-compatible timer setup that is invoked when
** there is a failure to set up the timebase in OSAL. It is basically
** the old way of doing things.
**
** IMPORTANT: Note this is technically incorrect as it gives the
** callback directly in the context of the signal handler. It is
** against spec to use most OSAL functions within a signal.
**
** This is included merely to mimic the previous system behavior. It
** should be removed in a future version of the PSP.
**
**
** Arguments:
** (none)
**
** Return:
** (none)
**
*/

void CFE_PSP_SetupLocal1Hz(void)
{
struct sigaction sa;
struct itimerval timer;
int ret;

/*
** Init timer counter
*/
TimerCounter = 0;

/*
** Install timer_handler as the signal handler for SIGALRM.
*/
memset(&sa, 0, sizeof(sa));
sa.sa_handler = &CFE_PSP_TimerHandler;

/*
** Configure the timer to expire after 250ms
**
** (this is historical; the actual callback is invoked
** only on every 4th timer tick. previous versions of the
** PSP did it this way, so this is preserved here).
*/
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 250000;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 250000;

ret = sigaction(SIGALRM, &sa, NULL);

if (ret < 0)
{
OS_printf("CFE_PSP: sigaction() error %d: %s \n", ret, strerror(errno));
}
else
{
ret = setitimer(ITIMER_REAL, &timer, NULL);
if (ret < 0)
{
OS_printf("CFE_PSP: setitimer() error %d: %s \n", ret, strerror(errno));
}
}
}
13 changes: 13 additions & 0 deletions fsw/pc-rtems/inc/cfe_psp_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,19 @@
*/
#define CFE_PSP_MAX_EXCEPTION_ENTRIES 1

/*
* The tick period that will be configured in the RTOS for the simulated
* time base, in microseconds. This in turn is used to drive the 1hz clock
* and other functions.
*
* To minimize jitter in the resulting callbacks, it should be an even
* divisor of 1000000 usec.
*
* Note - 10ms/100Hz is chosen to also allow this same timebase to be
* used to drive the CFS SCH minor frame callbacks in its default config.
*/
#define CFE_PSP_SOFT_TIMEBASE_PERIOD 10000

/*
** Typedef for the layout of the header in the reserved memory block
*/
Expand Down
Loading