Skip to content

Commit 60a5f65

Browse files
authored
Merge pull request #586 from nasa/integration-candidate
Integration Candidate - 2020-04-01
2 parents 62252d1 + c7a3ce2 commit 60a5f65

17 files changed

+1079
-421
lines changed

.travis.yml

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1+
os: linux
12
dist: bionic
2-
sudo: required
3-
language:
4-
- c
3+
language: c
54
compiler:
65
- gcc
76
addons:

README.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
Travis-CI: [![Build Status](https://travis-ci.com/nasa/cFE.svg)](https://travis-ci.com/nasa/cFE)
2+
13
# Core Flight System : Framework : Core Flight Executive
24

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

79
## Version Notes
810

11+
- 6.7.12: DEVELOPMENT
12+
- Cmd code (and checksum) are always in the same place (matches GSFC spec for command secondary header)
13+
- 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.
14+
- Minor other updates (see https://github.com/nasa/cFE/pull/586)
915
- 6.7.11: DEVELOPMENT
1016
- Improve documentation
1117
- Update makefile to report branch coverage
@@ -41,7 +47,7 @@ This is a collection of services and associated framework to be located in the `
4147
- 6.7.3: DEVELOPMENT
4248
- Minor updates (see https://github.com/nasa/cFE/pull/413)
4349
- 6.7.2: DEVELOPMENT
44-
- Minor bugs and enhancements (see https://github.com/nasa/cFE/pull/388)
50+
- Minor bugs and enhancements (see https://github.com/nasa/cFE/pull/388)
4551
- 6.7.1: DEVELOPMENT
4652
- Minor bug fixes (see https://github.com/nasa/cFE/pull/378)
4753
- Fix strlen in CFE_ES_TaskInit https://github.com/nasa/cFE/pull/23

docs/cFE Application Developers Guide.md

+5-37
Original file line numberDiff line numberDiff line change
@@ -836,44 +836,12 @@ to the OSAL Library API).
836836

837837
#### 5.8 Interrupt Handling
838838

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

842-
```
843-
OS_IntAttachHandler( uint32 InterruptNumber, void *InterruptHandler, int32 Param );
844-
```
845-
846-
The possible values of InterruptNumber are defined in hardware-specific
847-
header files (osplatform.h and osprocessor.h). The InterruptHandler is a
848-
function that will be called when the interrupt is detected and should
849-
have a prototype that looks like the following:
850-
851-
```
852-
void InterruptHandler( void );
853-
```
854-
855-
The Param is a value that may be passed to the interrupt handler in some
856-
operating systems; it is currently not used and should be set to 0.
857-
858-
The interrupt handler must not invoke any cFE or OS API function calls
859-
that could cause it to block.
860-
861-
The following functions can be used to enable and disable all
862-
interrupts. These should be used only when servicing a hardware device.
863-
For protecting a software variable against modification by several
864-
applications, one should use a mutex instead.
865-
866-
```
867-
status = OS_IntEnableAll();
868-
status = OS_IntDisableAll();
869-
```
870-
871-
There are similar functions for enabling/disabling specific interrupts.
872-
These are OS_IntEnable and OS_IntDisable. These functions require an
873-
interrupt number to identify the interrupt to be enabled or disabled.
874-
875-
To acknowledge the interrupt has been serviced, the interrupt service
876-
routine must call OS_IntAck.
842+
No longer supporting abstracted interrupt handling API from OSAL. Could
843+
consider at the PSP layer as future work but current dependencies should
844+
revert to native interrupt handling.
877845

878846
#### 5.9 Exceptions
879847

+250
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
/*
2+
** GSC-18128-1, "Core Flight Executive Version 6.7"
3+
**
4+
** Copyright (c) 2006-2019 United States Government as represented by
5+
** the Administrator of the National Aeronautics and Space Administration.
6+
** All Rights Reserved.
7+
**
8+
** Licensed under the Apache License, Version 2.0 (the "License");
9+
** you may not use this file except in compliance with the License.
10+
** You may obtain a copy of the License at
11+
**
12+
** http://www.apache.org/licenses/LICENSE-2.0
13+
**
14+
** Unless required by applicable law or agreed to in writing, software
15+
** distributed under the License is distributed on an "AS IS" BASIS,
16+
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
** See the License for the specific language governing permissions and
18+
** limitations under the License.
19+
*/
20+
21+
/*
22+
** File: cfe_es_backgroundtask.c
23+
**
24+
** Purpose: This file contains the implementation of the ES "background task"
25+
**
26+
** This task sits idle most of the time, but is woken by the ES application
27+
** for various maintenance duties that may take time to execute, such as
28+
** writing status/log files.
29+
**
30+
*/
31+
32+
/*
33+
** Include Section
34+
*/
35+
36+
#include <string.h>
37+
38+
#include "osapi.h"
39+
#include "private/cfe_private.h"
40+
#include "cfe_es_perf.h"
41+
#include "cfe_es_global.h"
42+
#include "cfe_es_task.h"
43+
44+
#define CFE_ES_BACKGROUND_SEM_NAME "ES_BackgroundSem"
45+
#define CFE_ES_BACKGROUND_CHILD_NAME "ES_BackgroundTask"
46+
#define CFE_ES_BACKGROUND_CHILD_STACK_PTR NULL
47+
#define CFE_ES_BACKGROUND_CHILD_STACK_SIZE CFE_PLATFORM_ES_PERF_CHILD_STACK_SIZE
48+
#define CFE_ES_BACKGROUND_CHILD_PRIORITY CFE_PLATFORM_ES_PERF_CHILD_PRIORITY
49+
#define CFE_ES_BACKGROUND_CHILD_FLAGS 0
50+
#define CFE_ES_BACKGROUND_MAX_IDLE_DELAY 30000 /* 30 seconds */
51+
52+
53+
typedef struct
54+
{
55+
bool (*RunFunc)(uint32 ElapsedTime, void *Arg);
56+
void *JobArg;
57+
uint32 ActivePeriod; /**< max wait/delay time between calls when job is active */
58+
uint32 IdlePeriod; /**< max wait/delay time between calls when job is idle */
59+
} CFE_ES_BackgroundJobEntry_t;
60+
61+
/*
62+
* List of "background jobs"
63+
*
64+
* This is just a list of functions to periodically call from the context of the background task,
65+
* and can be added/extended as needed.
66+
*
67+
* Each Job function returns a boolean, and should return "true" if it is active, or "false" if it is idle.
68+
*
69+
* This uses "cooperative multitasking" -- the function should do some limited work, then return to the
70+
* background task. It will be called again after a delay period to do more work.
71+
*/
72+
const CFE_ES_BackgroundJobEntry_t CFE_ES_BACKGROUND_JOB_TABLE[] =
73+
{
74+
{ /* Performance Log Data Dump to file */
75+
.RunFunc = CFE_ES_RunPerfLogDump,
76+
.JobArg = &CFE_ES_TaskData.BackgroundPerfDumpState,
77+
.ActivePeriod = CFE_PLATFORM_ES_PERF_CHILD_MS_DELAY,
78+
.IdlePeriod = CFE_PLATFORM_ES_PERF_CHILD_MS_DELAY * 1000
79+
}
80+
};
81+
82+
#define CFE_ES_BACKGROUND_NUM_JOBS (sizeof(CFE_ES_BACKGROUND_JOB_TABLE) / sizeof(CFE_ES_BACKGROUND_JOB_TABLE[0]))
83+
84+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
85+
/* Name: CFE_ES_BackgroundTask */
86+
/* */
87+
/* Purpose: A helper task for low priority routines that may take time to */
88+
/* execute, such as writing log files. */
89+
/* */
90+
/* Assumptions and Notes: This is started from the ES initialization, and */
91+
/* pends on a semaphore until a work request comes in. This is intended to */
92+
/* avoid the need to create a child task "on demand" when work items arrive, */
93+
/* which is a form of dynamic allocation. */
94+
/* */
95+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
96+
void CFE_ES_BackgroundTask(void)
97+
{
98+
int32 status;
99+
uint32 JobTotal;
100+
uint32 NumJobsRunning;
101+
uint32 NextDelay;
102+
uint32 ElapsedTime;
103+
OS_time_t CurrTime;
104+
OS_time_t LastTime;
105+
const CFE_ES_BackgroundJobEntry_t *JobPtr;
106+
107+
status = CFE_ES_RegisterChildTask();
108+
if (status != CFE_SUCCESS)
109+
{
110+
/* should never occur */
111+
CFE_ES_WriteToSysLog("CFE_ES: Background Task Failed to register: %08lx\n", (unsigned long)status);
112+
return;
113+
}
114+
115+
CFE_PSP_GetTime(&LastTime);
116+
117+
while (true)
118+
{
119+
/*
120+
* compute the elapsed time (difference) between last
121+
* execution and now, in microseconds.
122+
*
123+
* Note this calculation is done as a uint32 which will overflow
124+
* after about 35 minutes, but the max delays ensure that this
125+
* executes at least every few seconds, so that should never happen.
126+
*/
127+
CFE_PSP_GetTime(&CurrTime);
128+
ElapsedTime = 1000000 * (CurrTime.seconds - LastTime.seconds);
129+
ElapsedTime += CurrTime.microsecs;
130+
ElapsedTime -= LastTime.microsecs;
131+
LastTime = CurrTime;
132+
133+
/*
134+
* convert to milliseconds.
135+
* we do not really need high precision
136+
* for background task timings
137+
*/
138+
ElapsedTime /= 1000;
139+
140+
NextDelay = CFE_ES_BACKGROUND_MAX_IDLE_DELAY; /* default; will be adjusted based on active jobs */
141+
JobPtr = CFE_ES_BACKGROUND_JOB_TABLE;
142+
JobTotal = CFE_ES_BACKGROUND_NUM_JOBS;
143+
NumJobsRunning = 0;
144+
145+
while (JobTotal > 0)
146+
{
147+
/*
148+
* call the background job -
149+
* if it returns "true" that means it is active,
150+
* if it returns "false" that means it is idle
151+
*/
152+
if (JobPtr->RunFunc != NULL && JobPtr->RunFunc(ElapsedTime, JobPtr->JobArg))
153+
{
154+
++NumJobsRunning;
155+
156+
if (JobPtr->ActivePeriod != 0 && NextDelay > JobPtr->ActivePeriod)
157+
{
158+
/* next delay is based on this active job wait time */
159+
NextDelay = JobPtr->ActivePeriod;
160+
}
161+
}
162+
else if (JobPtr->IdlePeriod != 0 && NextDelay > JobPtr->IdlePeriod)
163+
{
164+
/* next delay is based on this idle job wait time */
165+
NextDelay = JobPtr->IdlePeriod;
166+
}
167+
--JobTotal;
168+
++JobPtr;
169+
}
170+
171+
CFE_ES_Global.BackgroundTask.NumJobsRunning = NumJobsRunning;
172+
173+
status = OS_BinSemTimedWait(CFE_ES_Global.BackgroundTask.WorkSem, NextDelay);
174+
if (status != OS_SUCCESS && status != OS_SEM_TIMEOUT)
175+
{
176+
/* should never occur */
177+
CFE_ES_WriteToSysLog("CFE_ES: Failed to take background sem: %08lx\n", (unsigned long)status);
178+
break;
179+
}
180+
181+
}
182+
}
183+
184+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
185+
/* Name: CFE_ES_BackgroundInit */
186+
/* */
187+
/* Purpose: Initialize the background task */
188+
/* */
189+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
190+
int32 CFE_ES_BackgroundInit(void)
191+
{
192+
int32 status;
193+
194+
status = OS_BinSemCreate(&CFE_ES_Global.BackgroundTask.WorkSem, CFE_ES_BACKGROUND_SEM_NAME, 0, 0);
195+
if (status != OS_SUCCESS)
196+
{
197+
CFE_ES_WriteToSysLog("CFE_ES: Failed to create background sem: %08lx\n", (unsigned long)status);
198+
return status;
199+
}
200+
201+
/* Spawn a task to write the performance data to a file */
202+
status = CFE_ES_CreateChildTask(&CFE_ES_Global.BackgroundTask.TaskID,
203+
CFE_ES_BACKGROUND_CHILD_NAME,
204+
CFE_ES_BackgroundTask,
205+
CFE_ES_BACKGROUND_CHILD_STACK_PTR,
206+
CFE_ES_BACKGROUND_CHILD_STACK_SIZE,
207+
CFE_ES_BACKGROUND_CHILD_PRIORITY,
208+
CFE_ES_BACKGROUND_CHILD_FLAGS);
209+
210+
if (status != OS_SUCCESS)
211+
{
212+
CFE_ES_WriteToSysLog("CFE_ES: Failed to create background task: %08lx\n", (unsigned long)status);
213+
return status;
214+
}
215+
216+
return CFE_SUCCESS;
217+
}
218+
219+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
220+
/* Name: CFE_ES_BackgroundCleanup */
221+
/* */
222+
/* Purpose: Exit/Stop the background task */
223+
/* */
224+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
225+
void CFE_ES_BackgroundCleanup(void)
226+
{
227+
CFE_ES_DeleteChildTask(CFE_ES_Global.BackgroundTask.TaskID);
228+
OS_BinSemDelete(CFE_ES_Global.BackgroundTask.WorkSem);
229+
230+
CFE_ES_Global.BackgroundTask.TaskID = 0;
231+
CFE_ES_Global.BackgroundTask.WorkSem = 0;
232+
}
233+
234+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
235+
/* Name: CFE_ES_BackgroundWakeup */
236+
/* */
237+
/* Purpose: Wake up the background task */
238+
/* Notifies the background task to perform an extra poll for new work */
239+
/* */
240+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
241+
void CFE_ES_BackgroundWakeup(void)
242+
{
243+
/* wake up the background task by giving the sem.
244+
* This is "informational" and not strictly required,
245+
* but it will make the task immediately wake up and check for new
246+
* work if it was idle. */
247+
OS_BinSemGive(CFE_ES_Global.BackgroundTask.WorkSem);
248+
}
249+
250+

0 commit comments

Comments
 (0)