Sie sind auf Seite 1von 10

So you want to code a satellite.

There are a number of steps needed in order for an app to send out a hello world type message to the cfe.

App specific things.


These are things that the app needs to do in order to send out messages.

1. Edit/create header files.


The app header file
app_msg.h
_app_msgids.h
2. Edit/create the c source file
Have an _AppMain function.
Register the app with the cfe.
Create a pipe on the software bus.
Subscribe to messages on the software bus.
Register with the event services
Check for events
Respond to an event with the hello world message.

Build specific things.


These are things that need to be done to configure your app in the build system so it gets compiled and included in the
overall flight software. These steps are detailed in the cFS Deployment Guide. You did read the cFS Deployment Guide
right?

1. Edit the app Makefile.


2. Edit the cFS Makefile
3. Edit the cfs start script

References -=<* Skip this section at your own peril! *>=-.


These are the references used to create the hello app, and that you will be using to create all your apps. The links below
give reasons why you should care about each one, and a brief summary of what each one has in it. Its interesting that
that most important things are at the end of this document.

Core Flight Executive Documentation


The cFE Applicaion Developers Guide.
The cFS Deployment Guide
The app header file

This is just like any other c header file.

Put this in so you dont load the header file more than once.
#ifndef _hello_app_h_
#define _hello_app_h_

These are required so you can get to the cFS functions. You want to use the cfe functions instead of writing your own.
/*
** Required header files.
*/
#include "cfe.h" //the main cfe header. In theory you should only need to load this one.
#include "cfe_error.h" // error handling functions
#include "cfe_evs.h" //the event messaging system
#include "cfe_sb.h" //the software bus system
#include "cfe_es.h" //executive services

set the number of items you can have waiting in your pipe at any one time. Ideally this should be set as low as possible.
Your app should be handing messages in your pipe frequently enough to no need a long queue.
#define HELLO_PIPE_DEPTH

void hello_AppMain(void); the main entry point for your app. Think of this as Main for a regular c program
void hello_AppInit(void); setup everything you need for your app to run
void hello_ProcessCommandPacket(void); what you do when you receive a command from the system
void hello_ProcessGroundCommand(void); what you do when you receive a command from the ground station

although this is not used in the hello app, it should be used on every command you process.
boolean hello_VerifyCmdLength(CFE_SB_MsgPtr_t msg, uint16 ExpectedLength);
The hello_app_msg.h

For the hello app theres one really important line.

#define HELLO_APP_NOOP_CC 0

This sets the command id for the noop command which is being used to generate the hello message to the cFS.
In a real app there will be command ids for every command that can be given to your app. Make sure to name them
something that someone who is only casually familiar with the system can understand.

This is a kind of placeholder for a command header. Since our hello app doesnt use message header data, bu thte
software bus needs to have a header with every message, this will do the trick.

typedef struct
{
uint8 CmdHeader[CFE_SB_CMD_HDR_SIZE];

} HELLO_NoArgsCmd_t;

hello_app_msgids.h
Think of these message ids as ports that you will listen on.
When your app gets registered with the cfe the cfe redirect messages with these ids to your app. This is how the cfe
knows which app to send a command to.

#define HELLO_APP_CMD_MID 0x1701


#define HELLO_APP_SEND_HK_MID 0x1702

Each app needs to define system wide unique ids. Otherwise the cfe will not know which command to send to which app.
(I think it rejects any duplicate ids). Theres a file on the google drive that shows which ids have been used. Update this
doc as soon as you decide which ids you are going to use. That way we can avoid conflicts.
The _AppMain function.
Every c program must have a main function. Every cFS app must also have a main function. Think of the cfe as the
operating system. Just as the operating system needs to know where to start executing your c program, the cfe needs to
know where to start executing your app. Technically speaking you could name this function anything you want. However,
to make it easier to edit, use, and read your code use the following naming convention. %APP_NAME%_AppMain. Youll
use this in the build configuration and the startup scrtipt.

The rest of your functions are not seen by the cFS or the cfe. Keep this in mind when developing your app. Everything
has to start with AppMain.

Register the app with the cfe.


The very fist thing you need to do in your app is register with the cfe. That way the cfe knows your app is running, and
can setup resources for it.
You do this by calling CFE_ES_RegisterApp(); No parameters needed. The cfe does the rest.
If you put this in your init function, make sure this is run before you do anything else. Without doing this your app will not
be able to do any of the other things needed for interacting with the cfe. That includes sending messages like hello.

Create a pipe on the software bus.


This is pretty easy to do.
Just call CFE_SB_CreatePipe(PipeIdPtr , Depth, PipeName). Heres the parameters.

PipeIdPtr A pointer to a variable of type CFE_SB_PipeId_t, Youll need this to setup messaging with the event
which will be filled in with the pipe ID information by service and anywhere you need to check for
the CFE_SB_CreatePipe routine. messages.
Depth The maximum number of messages that will be
allowed on this pipe at one time.
PipeName A string to be used to identify this pipe in error Give it something meaningful like
messages and routing information telemetry. The %APPNAME%_APP_CMD_PIPE
string must be no longer than OS_MAX_API_NAME.
Longer strings will be truncated.

This will return a PipIdPtr pointer that you can use when you have to do things with pipes.
Subscribe to messages on the software bus.
In order to receive messages from the software bus you need to subscribe to them. Subscribing tell the software bus that
you want to get messages as well as what messages you want to get. So that hello command. It might be send from the
ground station, and the cFS might get it, but your app will never know if your app doesnt subscribe to it.

To subscribe call CFE_SB_Subscribe(MsgId, PipeId).


Heres the parameters.
MsgId The message ID of the message to be subscribed to. You should be using one of the defines from
_app_msg.h.
PipeId The pipe ID of the pipe the subscribed message This comes from creating the pipe listed in Create a
should be sent to. pipe on the software bus.

You get back an integer that is actually a status return code. The one your really interested in for the hello app is
CFE_SUCCESS.

Register with the event services


Yeah its a bunch of stuff just to get hello world working. But dont give up. Youre close to almost not quite there.

In order for your app to be able to respond to and send events, which are different to commands, you have register with
the event service. Heres the function call for doing this.
CFE_EVS_Register(Filters, NumFilteredEvents, FilterScheme)

And of course the parameters.


Filters Pointer to an array of event message filters, or NULL if no filtering is desired. The structure of an
event message filter depends on the FilterScheme selected. (see Filter Schemes mentioned
above)
NumFilteredEvents The number of event message filters included in this call. This must be less than or equal to the
maximum number of events allowed per application (CFE_EVS_MAX_EVENT_FILTERS).
FilterScheme The event filtering scheme that this application will use. For the first implementation of the event
services, only filter type CFE_EVS_BINARY_FILTER will be supported.

Although the hello app doesnt use filters they are very very important for an app. You really want to limit the events you
listen for to just the ones you really need. That way your app is not responding and using resources when its not needed.
Check for events

This is really more than one step. Heres the basics.


Your app will be running a loop much like or exactly like this one:

while (CFE_ES_RunLoop(&RunStatus) == TRUE).

Its really just checking to see if your app needs to shutdown. So while the cfe thinks your app should be running, this
while loop will keep running. When the while loop exits you should call CFE_ES_ExitApp(RunStatus); to shutdown your
app. Pretty simple.

In the body of the loop youll be listening for messages and events. The hello app only listens for command messages,
but you could listen for telemetry messages from the system as well.
The function for listening for messages is CFE_SB_RcvMsg().

Heres the parameters youll need.

BufPtr A pointer to a local variable of type CFE_SB_MsgPtr_t. Typically a caller This is where any messages
declares a ptr of type CFE_SB_Msg_t (i.e. CFE_SB_Msg_t *Ptr) then your app receives will be stored.
gives the address of that pointer (&Ptr) as this parmeter. After a successful
receipt of a message, *BufPtr will point to the first byte of the software bus
message header. This should be used as a read-only pointer (in systems
with an MMU, writes to this pointer may cause a memory protection fault).
The *BufPtr is valid only until the next call to CFE_SB_RcvMsg for the
same pipe.
PipeId The pipe ID of the pipe containing the message to be obtained. You created this earlier.
TimeOut The number of milliseconds to wait for a new message if the pipe is empty How long do you want to wait
at the time of the call. This can also be set to CFE_SB_POLL for a non- before looking at the pipe again
blocking receive or CFE_SB_PEND_FOREVER to wait forever for a for another message.
message to arrive.

Youll get back a pointer to the message obtained from the pipe. Which youll need to do something with, because its valid
only until the next call to CFE_SB_RcvMsg for the same pipe.

The TimeOut parameter is very important. In effect your app will pause for this number of milliseconds when you call this
function. This is a good thing. Theres limited resources on a satellite, and it would be bad if your app used more than it
needed. The time out prevents your app from continuously looking at the pipe for messages.
Respond to an event
If youve gotten his far then your ready to actually print hello on the cFS console. YAY!

The hello app doesnt distinguish between a system message and a ground station message, but your app will. So, for
your app youll setup a function to decipher what kind of message you received and call the appropriate function to handle
that message. For example one handler for ground station messages, one for housekeeping, and one for system
messages. Youll most likely need more handlers than that.

To print hello, you call CFE_EVS_SendEvent(EventID, EventType, Spec)

And just like the other functions, heres the parameters.


EventID A numeric literal used to uniquely identify an application event. The EventID is defined and supplied by the
application sending the event.
EventType A numeric literal used to classify an event, one of:
CFE_EVS_CRITICAL
CFE_EVS_ERROR
CFE_EVS_INFORMATION
CFE_EVS_DEBUG
Spec A pointer to a null terminated text string describing the output format for the event. This is the same type of
format string used for the ANSI printf function. Nominally the post-conversion string is limited to 80
characters, but this limit is configurable through the parameter CFE_EVS_MAX_MESSAGE_LENGTH.
Characters beyond the limit will be truncated. Do not use floating point conversions (f, e, E, g, and G) in
the format string unless your application will be running in a system that supports floating point arithmetic.
Do not use non-printable characters (\t, \n, etc.) in the format string; they will mess up the formatting when
the events are displayed on the ground system.

For a return value youll get a status code that you can use to determine if the event was sucessful.

If everything went right, youll be looking at your message displayed on the ground station.
The App Makefile

In the for_build directory there should be one file called Makefile. Your going to need to change this file. Not that linux
and c are both case sensitive so this file must have a capital M.

The relevant sections for apps are:

APPTARGET
This one is very important. The make system uses this to know what to compile. It must be set to the same name as the
directory in APPS for your app.

ENTRY_PT
This tells the system which function will be used to start you app. It should be set to %APP_NAME%_AppMain.

OBJS
Used by the compiler to set the name obj files to link. Give this the name of your app just in case some debugging needs
to happen at the build system level. If all goes well, you shouldnt need to do anything with obj files.

Heres the top part of the Makefile for hello.

###############################################################################
# File: CFS Application Makefile
#
# $Id: Makefile 1.8 2009/07/09 12:25:54EDT rmcgraw Exp $
#
# $Log: Makefile $
# Revision 1.8 2009/07/09 12:25:54EDT rmcgraw
# DCR8291:1 Changed CFE_MISSION_INC to CFS_MISSION_INC and added log
#
###############################################################################
# Changed by Lance Tokuno for hello app
#
# Subsystem produced by this makefile.
#
APPTARGET = hello

#
# Entry Point for task
#
ENTRY_PT = hello_AppMain

#
# Object files required to build subsystem.
#
OBJS = hello.o
The cFS Makefile

This can be found in the build directory in the directory named for the current cpu you are programming to. This might be
PC-LINUX, or cpu1, or some other designation.

You need to add your app to the list of app in the THE_APPS variable. The easy way to do this is to use
THE_APPS += YOUR_APP_NAME. The app name used should be the same one you used for APPTARGET in the app
Makefile.

The Startup Script.


It would be good if the cfe started you app when it was run. To do this you have to edit the cfe start script. The start script
is in the build/%CPU_NAME%/exe. The filename is cfe_es_startup.scr. The instructions for what you need to change are
in the file itself. Just follow those instructions.

For Path/Filename used the same value as you did for OBJS in the app Makefile but change the .o to .so.

For Entry Point, use the same value you used for ENTRY_PT in the app Makefile. This needs to be the name of your main
function.

For CFE_NAME give the name of your app. This should be the same as the directory name.

For priority you can use any value you like until priorities are decided on for the whole system. Try something 90 or
above.

The rest of the values can be copied from the other apps listed in the file.
8192, 0x0, 0
for Stack Size, Load Address, and Exception Action.
Core Flight Executive Documentation / aka The cFE Users Guide
This is the go to book for making apps. It describes in great detail all the things the cFE allows you to do, and has a
reference for every cfe function. Its in html format. You should at least read the sections on each of the services, even if
you dont look at all the functions. This will give you a much better idea of how the system works in the context of apps
you will write.

The cFE Applicaion Developers Guide.


This is handy for getting into the cfe. If you want to know what the cfe is doing and why this book probably has the
answer. It also has sections on each cfe service, and covers the basic concepts of the entire system.

The cFS Deployment Guide


This covers how to get the cFS system up and running on a computer. Its helpful for app development as it shows a bit
about the build system and how to make apps work with it. It also has standard directory locations and what they are
used for, as well as instructions for building / compiling the system (with your apps included).

Das könnte Ihnen auch gefallen