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

Include reference implementation for concepts mentioned in Porting Guide #1487

Open
capsulecorplab opened this issue Jun 3, 2022 · 4 comments

Comments

@capsulecorplab
Copy link
Contributor

F´ Version v3.0.0
Affected Component

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.,

  1. CMake Toolchain and F´ platform files
  2. Fw::Types and configuration
  3. Hardware drivers
  4. OSAL support

Rationale

As to provide a working example of how these concepts should be implemented

@ThibFrgsGmz
Copy link
Contributor

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.

@LeStarch
Copy link
Collaborator

@pelmini look here too. These are some other ideas on stuff to include.

@LeStarch
Copy link
Collaborator

We need to add this to system reference.

@matt392code
Copy link
Contributor

matt392code commented Dec 27, 2024

F-Prime-Reference-Implementations.txt

F Prime Reference Implementations

1. CMake Toolchain and Platform Files

Example 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 Configuration

Example 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 Example

GPIO 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 Support

OSAL 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:

  1. Platform configuration through CMake
  2. Type system configuration
  3. Hardware driver implementation example
  4. OSAL implementations for tasks and queues

Key aspects include:

  • Cross-compilation setup
  • Platform-specific configurations
  • Hardware abstraction
  • RTOS integration
  • Error handling
  • Resource management

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants
@LeStarch @matt392code @capsulecorplab @ThibFrgsGmz and others