-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Include reference implementation for concepts mentioned in Porting Guide #1487
Comments
I support this idea because it will make it easier for stakeholders to estimate the ROM costing associated with porting FPrime to a specific unsupported hardware platform and operating system. This is a major issue on my side to convince our working groups in adopting the framework. |
@pelmini look here too. These are some other ideas on stuff to include. |
We need to add this to system reference. |
F-Prime-Reference-Implementations.txt F Prime Reference Implementations1. CMake Toolchain and Platform FilesExample Toolchain File (arm-cortex-toolchain.cmake)set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)
# Specify the cross compiler
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
# Search for programs only in host directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# Compiler flags
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mcpu=cortex-m4 -mthumb")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=cortex-m4 -mthumb") Example Platform File (stm32-platform.cmake)include(${CMAKE_CURRENT_LIST_DIR}/arm-cortex-toolchain.cmake)
# Platform-specific definitions
add_definitions(-DSTM32F4)
add_definitions(-DHSE_VALUE=8000000)
# Platform-specific compiler flags
set(PLATFORM_C_FLAGS
"-mcpu=cortex-m4 \
-mfloat-abi=hard \
-mfpu=fpv4-sp-d16"
)
set(PLATFORM_CXX_FLAGS "${PLATFORM_C_FLAGS}")
# Link flags including startup and linker script
set(PLATFORM_LINKER_FLAGS
"-T${CMAKE_SOURCE_DIR}/platform/stm32/linker/STM32F407VGTx_FLASH.ld \
-mcpu=cortex-m4 \
-mfloat-abi=hard \
-mfpu=fpv4-sp-d16 \
-specs=nano.specs"
) 2. Fw::Types ConfigurationExample Types Configuration (FpConfig.hpp)#ifndef FP_CONFIG_HPP
#define FP_CONFIG_HPP
// Include platform-specific definitions
#include <PlatformTypes.hpp>
namespace Fw {
// Integer types
typedef PlatformU8 U8;
typedef PlatformI8 I8;
typedef PlatformU16 U16;
typedef PlatformI16 I16;
typedef PlatformU32 U32;
typedef PlatformI32 I32;
typedef PlatformU64 U64;
typedef PlatformI64 I64;
// Boolean type
typedef PlatformBoolean Boolean;
// String types
typedef PlatformChar Char;
typedef PlatformString String;
// Define platform-specific printf
#define FW_PRINTF PlatformPrintf
// Memory alignment
#define FW_ALIGN(x) PLATFORM_ALIGN(x)
// Byte order configuration
#define FW_LITTLE_ENDIAN // or FW_BIG_ENDIAN
} // namespace Fw
#endif // FP_CONFIG_HPP Platform-Specific Types (PlatformTypes.hpp)#ifndef PLATFORM_TYPES_HPP
#define PLATFORM_TYPES_HPP
#include <stdint.h>
// Platform-specific type definitions
typedef uint8_t PlatformU8;
typedef int8_t PlatformI8;
typedef uint16_t PlatformU16;
typedef int16_t PlatformI16;
typedef uint32_t PlatformU32;
typedef int32_t PlatformI32;
typedef uint64_t PlatformU64;
typedef int64_t PlatformI64;
typedef bool PlatformBoolean;
typedef char PlatformChar;
typedef char* PlatformString;
// Platform-specific alignment macro
#define PLATFORM_ALIGN(x) __attribute__((aligned(x)))
// Platform printf implementation
#define PlatformPrintf printf
#endif // PLATFORM_TYPES_HPP 3. Hardware Driver ExampleGPIO Driver Component#include <Drv/GpioDriver/GpioDriverComponentImpl.hpp>
namespace Drv {
// Constructor
GpioDriverComponentImpl::GpioDriverComponentImpl(const char* name) :
GpioDriverComponentBase(name)
{
}
// Initialize GPIO hardware
void GpioDriverComponentImpl::init(NATIVE_INT_TYPE instance) {
GpioDriverComponentBase::init(instance);
// Platform-specific GPIO initialization
initializeGpioHardware();
}
// Set GPIO output
void GpioDriverComponentImpl::GPIO_OUT_write_handler(
NATIVE_INT_TYPE portNum,
Fw::Logic value
) {
// Convert F Prime Logic type to hardware-specific value
bool hwValue = (value == Fw::Logic::HIGH) ? true : false;
// Write to hardware GPIO
writeGpioPin(portNum, hwValue);
}
// Read GPIO input
void GpioDriverComponentImpl::GPIO_IN_read_handler(
NATIVE_INT_TYPE portNum,
Fw::Logic &value
) {
// Read from hardware GPIO
bool hwValue = readGpioPin(portNum);
// Convert hardware value to F Prime Logic type
value = hwValue ? Fw::Logic::HIGH : Fw::Logic::LOW;
}
private:
void initializeGpioHardware() {
// Platform-specific implementation
// Example for STM32:
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void writeGpioPin(NATIVE_INT_TYPE pin, bool value) {
// Platform-specific implementation
// Example for STM32:
HAL_GPIO_WritePin(GPIOA, (1 << pin), value ? GPIO_PIN_SET : GPIO_PIN_RESET);
}
bool readGpioPin(NATIVE_INT_TYPE pin) {
// Platform-specific implementation
// Example for STM32:
return HAL_GPIO_ReadPin(GPIOA, (1 << pin)) == GPIO_PIN_SET;
}
};
4. OSAL SupportOSAL Task Implementation#include <Os/Task.hpp>
namespace Os {
Task::Task() :
m_handle(0),
m_identifier(0),
m_affinity(-1),
m_started(false),
m_suspendedOnPurpose(false)
{
}
Task::TaskStatus Task::start(const Fw::StringBase &name,
NATIVE_INT_TYPE identifier,
NATIVE_INT_TYPE priority,
NATIVE_INT_TYPE stackSize,
taskRoutine routine,
void* arg,
NATIVE_INT_TYPE cpuAffinity) {
// Store task parameters
m_identifier = identifier;
m_affinity = cpuAffinity;
// Create RTOS task
BaseType_t status = xTaskCreate(
reinterpret_cast<TaskFunction_t>(routine),
name.toChar(),
stackSize,
arg,
priority,
&m_handle
);
if (status != pdPASS) {
return TASK_ERROR;
}
// Set CPU affinity if specified
if (cpuAffinity != -1) {
#if configNUM_CORES > 1
vTaskCoreAffinitySet(m_handle, (1 << cpuAffinity));
#endif
}
m_started = true;
return TASK_OK;
}
Task::TaskStatus Task::delay(NATIVE_UINT_TYPE milliseconds) {
vTaskDelay(pdMS_TO_TICKS(milliseconds));
return TASK_OK;
}
Task::~Task() {
if (m_started) {
vTaskDelete(m_handle);
}
}
}
OSAL Queue Implementation#include <Os/Queue.hpp>
namespace Os {
Queue::Queue() :
m_handle(nullptr),
m_size(0),
m_maxMsgSize(0)
{
}
Queue::QueueStatus Queue::create(const Fw::StringBase &name,
NATIVE_INT_TYPE depth,
NATIVE_INT_TYPE msgSize) {
// Store queue parameters
m_size = depth;
m_maxMsgSize = msgSize;
// Create FreeRTOS queue
m_handle = xQueueCreate(depth, msgSize);
if (m_handle == nullptr) {
return QUEUE_ERROR;
}
return QUEUE_OK;
}
Queue::QueueStatus Queue::send(const U8* buffer,
NATIVE_INT_TYPE size,
NATIVE_INT_TYPE timeout) {
if (size > m_maxMsgSize) {
return QUEUE_SIZE_ERROR;
}
BaseType_t status = xQueueSend(
m_handle,
buffer,
pdMS_TO_TICKS(timeout)
);
return (status == pdTRUE) ? QUEUE_OK : QUEUE_FULL;
}
Queue::QueueStatus Queue::receive(U8* buffer,
NATIVE_INT_TYPE capacity,
NATIVE_INT_TYPE &actualSize,
NATIVE_INT_TYPE timeout) {
if (capacity < m_maxMsgSize) {
return QUEUE_SIZE_ERROR;
}
BaseType_t status = xQueueReceive(
m_handle,
buffer,
pdMS_TO_TICKS(timeout)
);
if (status == pdTRUE) {
actualSize = m_maxMsgSize;
return QUEUE_OK;
}
return QUEUE_EMPTY;
}
Queue::~Queue() {
if (m_handle != nullptr) {
vQueueDelete(m_handle);
}
}
} These implementations demonstrate:
Key aspects include:
|
Feature Description
As a follow-up to #76, the Porting Guide should include a reference implementation for the concepts mentioned in the guide, i.e.,
Rationale
As to provide a working example of how these concepts should be implemented
The text was updated successfully, but these errors were encountered: