Skip to content

Commit

Permalink
Merge pull request #586 from nasa/integration-candidate
Browse files Browse the repository at this point in the history
Integration Candidate - 2020-04-01
  • Loading branch information
astrogeco authored Apr 9, 2020
2 parents 62252d1 + c7a3ce2 commit 60a5f65
Show file tree
Hide file tree
Showing 17 changed files with 1,079 additions and 421 deletions.
5 changes: 2 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
os: linux
dist: bionic
sudo: required
language:
- c
language: c
compiler:
- gcc
addons:
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Travis-CI: [![Build Status](https://travis-ci.com/nasa/cFE.svg)](https://travis-ci.com/nasa/cFE)

# Core Flight System : Framework : Core Flight Executive

This repository contains NASA's Core Flight Executive (cFE), which is a framework component of the Core Flight System.
Expand All @@ -6,6 +8,10 @@ This is a collection of services and associated framework to be located in the `

## Version Notes

- 6.7.12: DEVELOPMENT
- Cmd code (and checksum) are always in the same place (matches GSFC spec for command secondary header)
- No impact to behavior. Previously the perf log dump file frequently contained errors due to out of order or otherwise corrupted entries, which is now fixed.
- Minor other updates (see https://github.com/nasa/cFE/pull/586)
- 6.7.11: DEVELOPMENT
- Improve documentation
- Update makefile to report branch coverage
Expand Down Expand Up @@ -41,7 +47,7 @@ This is a collection of services and associated framework to be located in the `
- 6.7.3: DEVELOPMENT
- Minor updates (see https://github.com/nasa/cFE/pull/413)
- 6.7.2: DEVELOPMENT
- Minor bugs and enhancements (see https://github.com/nasa/cFE/pull/388)
- Minor bugs and enhancements (see https://github.com/nasa/cFE/pull/388)
- 6.7.1: DEVELOPMENT
- Minor bug fixes (see https://github.com/nasa/cFE/pull/378)
- Fix strlen in CFE_ES_TaskInit https://github.com/nasa/cFE/pull/23
Expand Down
42 changes: 5 additions & 37 deletions docs/cFE Application Developers Guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -836,44 +836,12 @@ to the OSAL Library API).

#### 5.8 Interrupt Handling

The following function specifies a handler for an interrupt. This is
called in the initialization function for an interrupt handler.
OSAL interrupt handling functions have been deprecated due to
platform dependencies, incomplete testing, and incomplete implementaion

```
OS_IntAttachHandler( uint32 InterruptNumber, void *InterruptHandler, int32 Param );
```

The possible values of InterruptNumber are defined in hardware-specific
header files (osplatform.h and osprocessor.h). The InterruptHandler is a
function that will be called when the interrupt is detected and should
have a prototype that looks like the following:

```
void InterruptHandler( void );
```

The Param is a value that may be passed to the interrupt handler in some
operating systems; it is currently not used and should be set to 0.

The interrupt handler must not invoke any cFE or OS API function calls
that could cause it to block.

The following functions can be used to enable and disable all
interrupts. These should be used only when servicing a hardware device.
For protecting a software variable against modification by several
applications, one should use a mutex instead.

```
status = OS_IntEnableAll();
status = OS_IntDisableAll();
```

There are similar functions for enabling/disabling specific interrupts.
These are OS_IntEnable and OS_IntDisable. These functions require an
interrupt number to identify the interrupt to be enabled or disabled.

To acknowledge the interrupt has been serviced, the interrupt service
routine must call OS_IntAck.
No longer supporting abstracted interrupt handling API from OSAL. Could
consider at the PSP layer as future work but current dependencies should
revert to native interrupt handling.

#### 5.9 Exceptions

Expand Down
250 changes: 250 additions & 0 deletions fsw/cfe-core/src/es/cfe_es_backgroundtask.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
/*
** 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_es_backgroundtask.c
**
** Purpose: This file contains the implementation of the ES "background task"
**
** This task sits idle most of the time, but is woken by the ES application
** for various maintenance duties that may take time to execute, such as
** writing status/log files.
**
*/

/*
** Include Section
*/

#include <string.h>

#include "osapi.h"
#include "private/cfe_private.h"
#include "cfe_es_perf.h"
#include "cfe_es_global.h"
#include "cfe_es_task.h"

#define CFE_ES_BACKGROUND_SEM_NAME "ES_BackgroundSem"
#define CFE_ES_BACKGROUND_CHILD_NAME "ES_BackgroundTask"
#define CFE_ES_BACKGROUND_CHILD_STACK_PTR NULL
#define CFE_ES_BACKGROUND_CHILD_STACK_SIZE CFE_PLATFORM_ES_PERF_CHILD_STACK_SIZE
#define CFE_ES_BACKGROUND_CHILD_PRIORITY CFE_PLATFORM_ES_PERF_CHILD_PRIORITY
#define CFE_ES_BACKGROUND_CHILD_FLAGS 0
#define CFE_ES_BACKGROUND_MAX_IDLE_DELAY 30000 /* 30 seconds */


typedef struct
{
bool (*RunFunc)(uint32 ElapsedTime, void *Arg);
void *JobArg;
uint32 ActivePeriod; /**< max wait/delay time between calls when job is active */
uint32 IdlePeriod; /**< max wait/delay time between calls when job is idle */
} CFE_ES_BackgroundJobEntry_t;

/*
* List of "background jobs"
*
* This is just a list of functions to periodically call from the context of the background task,
* and can be added/extended as needed.
*
* Each Job function returns a boolean, and should return "true" if it is active, or "false" if it is idle.
*
* This uses "cooperative multitasking" -- the function should do some limited work, then return to the
* background task. It will be called again after a delay period to do more work.
*/
const CFE_ES_BackgroundJobEntry_t CFE_ES_BACKGROUND_JOB_TABLE[] =
{
{ /* Performance Log Data Dump to file */
.RunFunc = CFE_ES_RunPerfLogDump,
.JobArg = &CFE_ES_TaskData.BackgroundPerfDumpState,
.ActivePeriod = CFE_PLATFORM_ES_PERF_CHILD_MS_DELAY,
.IdlePeriod = CFE_PLATFORM_ES_PERF_CHILD_MS_DELAY * 1000
}
};

#define CFE_ES_BACKGROUND_NUM_JOBS (sizeof(CFE_ES_BACKGROUND_JOB_TABLE) / sizeof(CFE_ES_BACKGROUND_JOB_TABLE[0]))

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Name: CFE_ES_BackgroundTask */
/* */
/* Purpose: A helper task for low priority routines that may take time to */
/* execute, such as writing log files. */
/* */
/* Assumptions and Notes: This is started from the ES initialization, and */
/* pends on a semaphore until a work request comes in. This is intended to */
/* avoid the need to create a child task "on demand" when work items arrive, */
/* which is a form of dynamic allocation. */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void CFE_ES_BackgroundTask(void)
{
int32 status;
uint32 JobTotal;
uint32 NumJobsRunning;
uint32 NextDelay;
uint32 ElapsedTime;
OS_time_t CurrTime;
OS_time_t LastTime;
const CFE_ES_BackgroundJobEntry_t *JobPtr;

status = CFE_ES_RegisterChildTask();
if (status != CFE_SUCCESS)
{
/* should never occur */
CFE_ES_WriteToSysLog("CFE_ES: Background Task Failed to register: %08lx\n", (unsigned long)status);
return;
}

CFE_PSP_GetTime(&LastTime);

while (true)
{
/*
* compute the elapsed time (difference) between last
* execution and now, in microseconds.
*
* Note this calculation is done as a uint32 which will overflow
* after about 35 minutes, but the max delays ensure that this
* executes at least every few seconds, so that should never happen.
*/
CFE_PSP_GetTime(&CurrTime);
ElapsedTime = 1000000 * (CurrTime.seconds - LastTime.seconds);
ElapsedTime += CurrTime.microsecs;
ElapsedTime -= LastTime.microsecs;
LastTime = CurrTime;

/*
* convert to milliseconds.
* we do not really need high precision
* for background task timings
*/
ElapsedTime /= 1000;

NextDelay = CFE_ES_BACKGROUND_MAX_IDLE_DELAY; /* default; will be adjusted based on active jobs */
JobPtr = CFE_ES_BACKGROUND_JOB_TABLE;
JobTotal = CFE_ES_BACKGROUND_NUM_JOBS;
NumJobsRunning = 0;

while (JobTotal > 0)
{
/*
* call the background job -
* if it returns "true" that means it is active,
* if it returns "false" that means it is idle
*/
if (JobPtr->RunFunc != NULL && JobPtr->RunFunc(ElapsedTime, JobPtr->JobArg))
{
++NumJobsRunning;

if (JobPtr->ActivePeriod != 0 && NextDelay > JobPtr->ActivePeriod)
{
/* next delay is based on this active job wait time */
NextDelay = JobPtr->ActivePeriod;
}
}
else if (JobPtr->IdlePeriod != 0 && NextDelay > JobPtr->IdlePeriod)
{
/* next delay is based on this idle job wait time */
NextDelay = JobPtr->IdlePeriod;
}
--JobTotal;
++JobPtr;
}

CFE_ES_Global.BackgroundTask.NumJobsRunning = NumJobsRunning;

status = OS_BinSemTimedWait(CFE_ES_Global.BackgroundTask.WorkSem, NextDelay);
if (status != OS_SUCCESS && status != OS_SEM_TIMEOUT)
{
/* should never occur */
CFE_ES_WriteToSysLog("CFE_ES: Failed to take background sem: %08lx\n", (unsigned long)status);
break;
}

}
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Name: CFE_ES_BackgroundInit */
/* */
/* Purpose: Initialize the background task */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int32 CFE_ES_BackgroundInit(void)
{
int32 status;

status = OS_BinSemCreate(&CFE_ES_Global.BackgroundTask.WorkSem, CFE_ES_BACKGROUND_SEM_NAME, 0, 0);
if (status != OS_SUCCESS)
{
CFE_ES_WriteToSysLog("CFE_ES: Failed to create background sem: %08lx\n", (unsigned long)status);
return status;
}

/* Spawn a task to write the performance data to a file */
status = CFE_ES_CreateChildTask(&CFE_ES_Global.BackgroundTask.TaskID,
CFE_ES_BACKGROUND_CHILD_NAME,
CFE_ES_BackgroundTask,
CFE_ES_BACKGROUND_CHILD_STACK_PTR,
CFE_ES_BACKGROUND_CHILD_STACK_SIZE,
CFE_ES_BACKGROUND_CHILD_PRIORITY,
CFE_ES_BACKGROUND_CHILD_FLAGS);

if (status != OS_SUCCESS)
{
CFE_ES_WriteToSysLog("CFE_ES: Failed to create background task: %08lx\n", (unsigned long)status);
return status;
}

return CFE_SUCCESS;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Name: CFE_ES_BackgroundCleanup */
/* */
/* Purpose: Exit/Stop the background task */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void CFE_ES_BackgroundCleanup(void)
{
CFE_ES_DeleteChildTask(CFE_ES_Global.BackgroundTask.TaskID);
OS_BinSemDelete(CFE_ES_Global.BackgroundTask.WorkSem);

CFE_ES_Global.BackgroundTask.TaskID = 0;
CFE_ES_Global.BackgroundTask.WorkSem = 0;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Name: CFE_ES_BackgroundWakeup */
/* */
/* Purpose: Wake up the background task */
/* Notifies the background task to perform an extra poll for new work */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void CFE_ES_BackgroundWakeup(void)
{
/* wake up the background task by giving the sem.
* This is "informational" and not strictly required,
* but it will make the task immediately wake up and check for new
* work if it was idle. */
OS_BinSemGive(CFE_ES_Global.BackgroundTask.WorkSem);
}


Loading

0 comments on commit 60a5f65

Please sign in to comment.