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

PSP Integration candidate: Caelum-rc4+dev45 #389

Merged
merged 4 commits into from
Apr 12, 2023
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## Development Build: v1.6.0-rc4+dev72
- adds generic driver interface and Linux sysmon module
- See <https://github.com/nasa/PSP/pull/386>

## Development Build: v1.6.0-rc4+dev67
- Squash constParameter warning in linux cfe_psp_memory.c
- Remove obsolete _USING_RTEMS_INCLUDES_
Expand Down
2 changes: 1 addition & 1 deletion fsw/mcp750-vxworks/inc/psp_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
/*
* Development Build Macro Definitions
*/
#define CFE_PSP_IMPL_BUILD_NUMBER 67
#define CFE_PSP_IMPL_BUILD_NUMBER 72
#define CFE_PSP_IMPL_BUILD_BASELINE "v1.6.0-rc4"

/*
Expand Down
9 changes: 9 additions & 0 deletions fsw/modules/iodriver/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

# Generic I/O device driver interface module
add_psp_module(iodriver src/iodriver.c)

target_include_directories(iodriver PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc)

if (ENABLE_UNIT_TESTS)
add_subdirectory(ut-stubs)
endif (ENABLE_UNIT_TESTS)
71 changes: 71 additions & 0 deletions fsw/modules/iodriver/inc/iodriver_analog_io.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright (c) 2015, United States government as represented by the
* administrator of the National Aeronautics Space Administration.
* All rights reserved. This software was created at NASA Glenn
* Research Center pursuant to government contracts.
*/

/**
* \file
*
* I/O adapter for analog (ADC/DAC) devices
*/

#ifndef CFE_PSP_IODRIVER_ANALOG_IO_H
#define CFE_PSP_IODRIVER_ANALOG_IO_H

/* Include all base definitions */
#include "iodriver_base.h"

/**
* Standardized width of ADC/DAC codes.
*
* This should reflect the highest-precision ADC that the system is expected to use. ADC inputs
* that are less precise than this will be bit-expanded in software such that all processing
* in the upper layers receives consistent data no matter what the actual hardware implements.
* This permits easier swapping between different phsyical hardware types, including those with
* potentially less ADC/DAC precision, while presenting similar values to application code.
*/
#define CFE_PSP_IODRIVER_ADC_BITWIDTH 24

/**
* Type abstraction for expressing analog ADC codes.
*
* This type is an integer type of at least CFE_PSP_IODRIVER_ADC_BITWIDTH in length. It is used
* as a parameter for the Read/Write opcodes on ADC/DAC channels. Normalized (fixed-width) ADC
* codes are used at this layer rather than floating point due to the fact that floats involve a
* lot of extra overhead and some CPUs do not have FP units at all.
*
* If desired on CPUs that are capable of good-performance floating point operations, another
* module/CFS application can convert the ADC codes to real-word floats. This would be done
* outside the I/O driver layer.
*/
typedef int32 CFE_PSP_IODriver_AdcCode_t;

/**
* Complete API container for analog read/write commands.
* This allows reading/writing multiple channels at once with a single entry into the API.
* As each entry into the API needs to acquire a mutex for serialization, this can be much
* more efficient to read channels through this means rather than single channel read/write.
* Set NumChannels to 1 to perform single channel read/write
*/
typedef struct
{
uint16 NumChannels; /**< Number of channels in the i/o structure (length of "samples" array) */
CFE_PSP_IODriver_AdcCode_t *Samples; /**< Array for ADC/DAC samples */
} CFE_PSP_IODriver_AnalogRdWr_t;

/**
* Opcodes specific to analog io (ADC/DAC) devices
*/
enum
{
CFE_PSP_IODriver_ANALOG_IO_NOOP = CFE_PSP_IODriver_ANALOG_IO_CLASS_BASE,

CFE_PSP_IODriver_ANALOG_IO_READ_CHANNELS, /**< CFE_PSP_IODriver_AnalogRdWr_t argument */
CFE_PSP_IODriver_ANALOG_IO_WRITE_CHANNELS, /**< CFE_PSP_IODriver_AnalogRdWr_t argument */

CFE_PSP_IODriver_ANALOG_IO_MAX
};

#endif /* CFE_PSP_IODRIVER_ANALOG_IO_H */
172 changes: 172 additions & 0 deletions fsw/modules/iodriver/inc/iodriver_base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/*
* Copyright (c) 2015, United States government as represented by the
* administrator of the National Aeronautics Space Administration.
* All rights reserved. This software was created at NASA Glenn
* Research Center pursuant to government contracts.
*/

/**
* \file
*
* Generic abstraction API for on-board devices
*
* The design of this interface is similar to the POSIX "ioctl()" in concept -
* A single interface function, with 3 basic arguments:
* - A device/target identifier
* - A command "opcode"
* - A generic argument containing the I/O parameter for that opcode
*
* Note that the last argument may in fact be a structure for opcodes that
* require multiple parameters.
*
* This type of interface makes it fairly simple to swap one hardware device
* for another, as long as they both implement a common set of opcodes, while
* also being extendable/customizable by adding additional opcodes to expose
* device-specific functionality, as long as those extension opcodes do not
* interfere or overlap with the common set.
*/

#ifndef IODRIVER_BASE_H
#define IODRIVER_BASE_H

#include <common_types.h>

/**
* Physical channel location descriptor.
*
* See the CFE_PSP_IODriver_LOOKUP_SUBCHANNEL opcode to determine channel number to set in here,
* as each board may have their own unique channel naming conventions. The integer value that
* goes in this structure may or may not correlate to the physical device labeling.
*/
typedef struct
{
uint32 PspModuleId; /**< Device selection */
uint16 SubsystemId; /**< Instance or subsystem number */
uint16 SubchannelId; /**< Subchannel number - optional, set to 0 for devices that do not have multiple channels */
} CFE_PSP_IODriver_Location_t;

/**
* Wrapper for constant arguments, to avoid a compiler warning
* about arguments differing in const-ness. Use the inline functions to
* pass in an immediate/constant value.
*/
typedef union
{
void * Vptr;
const void *ConstVptr;
const char *ConstStr;
uint32 U32;
} CFE_PSP_IODriver_Arg_t;

static inline CFE_PSP_IODriver_Arg_t CFE_PSP_IODriver_VPARG(void *x)
{
CFE_PSP_IODriver_Arg_t a;
a.Vptr = x;
return a;
}
static inline CFE_PSP_IODriver_Arg_t CFE_PSP_IODriver_CONST_VPARG(const void *x)
{
CFE_PSP_IODriver_Arg_t a;
a.ConstVptr = x;
return a;
}
static inline CFE_PSP_IODriver_Arg_t CFE_PSP_IODriver_CONST_STR(const char *x)
{
CFE_PSP_IODriver_Arg_t a;
a.ConstStr = x;
return a;
}
static inline CFE_PSP_IODriver_Arg_t CFE_PSP_IODriver_U32ARG(uint32 x)
{
CFE_PSP_IODriver_Arg_t a;
a.U32 = x;
return a;
}

/**
* Standardized concept of directionality for any device
*
* Some code may use these enumeration values as a bitmask -
* use care when updating to ensure that the values may be used as bitmasks.
* Specific hardware drivers may or may not implement all modes depending on capabilities.
*/
typedef enum
{
CFE_PSP_IODriver_Direction_DISABLED = 0, /**< Disabled (inactive, tri-state if possible) */
CFE_PSP_IODriver_Direction_INPUT_ONLY = 0x01, /**< Device/channel is configured for input */
CFE_PSP_IODriver_Direction_OUTPUT_ONLY = 0x02, /**< Device/channel is configured for output */
CFE_PSP_IODriver_Direction_INPUT_OUTPUT = 0x03 /**< Input/Output (some HW supports this) */
} CFE_PSP_IODriver_Direction_t;

/**
* Some common values for the device command codes
* These are some VERY basic ops that many devices may support in some way.
* Any opcode that is not implemented should return CFE_PSP_ERROR_NOT_IMPLEMENTED
*
* Negative return values indicate an error of some type, while return values >= 0 indicate success
*/
enum
{
CFE_PSP_IODriver_NOOP = 0, /**< Reserved, do nothing */

/* Start/stop opcodes */
CFE_PSP_IODriver_SET_RUNNING = 1, /**< uint32 argument, 0=stop 1=start device */
CFE_PSP_IODriver_GET_RUNNING = 2, /**< no argument, returns positive nonzero (true) if running and zero (false) if
stopped, negative on error */

/* Configuration opcodes */
CFE_PSP_IODriver_SET_CONFIGURATION = 3, /**< const string argument (device-dependent content) */
CFE_PSP_IODriver_GET_CONFIGURATION = 4, /**< void * argument (device-dependent content) */

/* Sub-channel configuration/mapping opcodes */
CFE_PSP_IODriver_LOOKUP_SUBSYSTEM = 5, /**< const char * argument, looks up ChannelName and returns positive value
for subsystem ID, negative value for error */
CFE_PSP_IODriver_LOOKUP_SUBCHANNEL = 6, /**< const char * argument, looks up ChannelName and returns positive value
for subchannel ID, negative value for error */
CFE_PSP_IODriver_SET_DIRECTION = 7, /**< U32 (CFE_PSP_IODriver_Direction_t) argument as input */
CFE_PSP_IODriver_QUERY_DIRECTION = 8, /**< U32 (CFE_PSP_IODriver_Direction_t) argument as output */

/*
* Placeholders for opcodes that could be implemented across a class of devices.
* For instance, all ADC/DAC devices should implement a common set of read/write opcodes
* so that devices can be interchanged without affecting higher-level software
*/
CFE_PSP_IODriver_ANALOG_IO_CLASS_BASE = 0x00010000, /**< Opcodes for typical adc/dac devices */
CFE_PSP_IODriver_DISCRETE_IO_CLASS_BASE = 0x00020000, /**< Opcodes for discrete IO (digital logic) devices */
CFE_PSP_IODriver_PACKET_IO_CLASS_BASE = 0x00030000, /**< Opcodes for packet/datagram-oriented devices */
CFE_PSP_IODriver_MEMORY_IO_CLASS_BASE = 0x00040000, /**< Opcodes for memory/register oriented devices */
CFE_PSP_IODriver_STREAM_IO_CLASS_BASE = 0x00050000, /**< Opcodes for data stream oriented devices */

/**
* Placeholder for extended opcodes that may be very specific to a single device/device type.
* This allows the same API call (CFE_PSP_DeviceCommandFunc_t) but
*/
CFE_PSP_IODriver_EXTENDED_BASE = 0x7FFF0000

};

/* ------------------------------------------------------------- */
/**
* @brief Find an IO device module ID by name
*
* @param DriverName the device name to find
* @param PspModuleId location to store the module ID, if found
*
* @retval #CFE_PSP_SUCCESS if found, or error code if not found
*/
int32 CFE_PSP_IODriver_FindByName(const char *DriverName, uint32 *PspModuleId);

/* ------------------------------------------------------------- */
/**
* @brief Issue a request to an IO device module
*
* @param Location Aggregate location identifier
* @param CommandCode Request identifier
* @param Arg Request Argument
*
* @retval #CFE_PSP_SUCCESS if successful, or error code if not successful
*/
int32 CFE_PSP_IODriver_Command(const CFE_PSP_IODriver_Location_t *Location, uint32 CommandCode,
CFE_PSP_IODriver_Arg_t Arg);

#endif /* IODRIVER_BASE_H */
64 changes: 64 additions & 0 deletions fsw/modules/iodriver/inc/iodriver_discrete_io.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2015, United States government as represented by the
* administrator of the National Aeronautics Space Administration.
* All rights reserved. This software was created at NASA Glenn
* Research Center pursuant to government contracts.
*/

/**
* \file
*
* I/O adapter for discrete (digitial gpio) interfaces
*/

#ifndef CFE_PSP_IODRIVER_DISCRETE_IO_H
#define CFE_PSP_IODRIVER_DISCRETE_IO_H

/**
* Type abstraction for expressing digital logic levels.
*
* This value will be filled starting with the LSB. A typical GPIO logic channel is 1 bit, so
* only the LSB is signficiant and the other bits are not used.
*
* This allows single channels up to 8 bits wide, but multiple "channels" could be concatenated
* using a multi-read/write opcode to allow atomic access to any number of bits.
*/
typedef uint8 CFE_PSP_IODriver_GpioLevel_t;

/**
* Enumerated names for typical digital 1-bit logic channel states.
*
* For convenience / code readability.
*/
enum
{
CFE_PSP_IODriver_GPIO_LOGIC_LOW = 0,
CFE_PSP_IODriver_GPIO_LOGIC_HIGH = 1
};

/**
* Complete API container for gpio read/write commands.
* This allows reading/writing multiple channels at once with a single entry into the API.
* As each entry into the API needs to acquire a mutex for serialization, this can be much
* more efficient to read channels through this means rather than single channel read/write.
*/
typedef struct
{
uint16 NumChannels; /**< Number of channels in the i/o structure (length of "samples" array) */
CFE_PSP_IODriver_GpioLevel_t *Samples; /**< Array for digital logic levels */
} CFE_PSP_IODriver_GpioRdWr_t;

/**
* Opcodes specific to digital GPIO devices
*/
enum
{
CFE_PSP_IODriver_DISCRETE_IO_NOOP = CFE_PSP_IODriver_DISCRETE_IO_CLASS_BASE,

CFE_PSP_IODriver_DISCRETE_IO_READ_CHANNELS, /**< CFE_PSP_IODriver_GpioRdWr_t argument */
CFE_PSP_IODriver_DISCRETE_IO_WRITE_CHANNELS, /**< CFE_PSP_IODriver_GpioRdWr_t argument */

CFE_PSP_IODriver_DISCRETE_IO_MAX
};

#endif /* CFE_PSP_IODRIVER_DISCRETE_IO_H */
55 changes: 55 additions & 0 deletions fsw/modules/iodriver/inc/iodriver_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2015, United States government as represented by the
* administrator of the National Aeronautics Space Administration.
* All rights reserved. This software was created at NASA Glenn
* Research Center pursuant to government contracts.
*/

/**
* \file iodriver_impl.h
*
* Created on: Oct 5, 2015
* Created by: [email protected]
*
*/

#ifndef IODRIVER_IMPL_H
#define IODRIVER_IMPL_H

#ifndef _CFE_PSP_MODULE_
#error "Do not include this file from outside the PSP"
#endif

#include "cfe_psp_module.h"
#include "iodriver_base.h"

/**
* Macro to declare the global object for an IO device driver
*/
#define CFE_PSP_MODULE_DECLARE_IODEVICEDRIVER(name) \
static void name##_Init(uint32 PspModuleId); \
CFE_PSP_ModuleApi_t CFE_PSP_##name##_API = { \
.ModuleType = CFE_PSP_MODULE_TYPE_DEVICEDRIVER, \
.OperationFlags = 0, \
.Init = name##_Init, \
.ExtendedApi = &name##_DevApi, \
}

/**
* Prototype for a basic device command function
* Implemented as a single API call with an extendible command code for device-specific ops. This allows
* a common API to be used while still allowing full freedom to handle many different device types.
*/
typedef int32 (*CFE_PSP_IODriver_ApiFunc_t)(uint32 CommandCode, uint16 Instance, uint16 SubChannel,
CFE_PSP_IODriver_Arg_t arg);

typedef const struct
{
CFE_PSP_IODriver_ApiFunc_t DeviceCommand;
CFE_PSP_IODriver_ApiFunc_t DeviceMutex;
} CFE_PSP_IODriver_API_t;

osal_id_t CFE_PSP_IODriver_GetMutex(uint32 PspModuleId, int32 DeviceHash);
int32 CFE_PSP_IODriver_HashMutex(int32 StartHash, int32 Datum);

#endif /* IODRIVER_IMPL_H */
Loading