Profiles and CMake build process

Overview

AMC uses CMake for its build procedure, automating each stage of the compilation processes.

AMC source code has been designed to be agnostic from target board (hardware) and operating system. The CMake build process allows target board and target OS to be configured at compilation.

Build

The build procedure can be broken into two key stages depending on the target OS and board specified:

  • Generation of BSP (Board support package)

  • Source code compilation

The following diagram outlines the build stage called by build.sh, depending on the parameters specified by the user.

images/1107376893.png

Profiles

The profiles layer holds all profile-specific (board-specific) includes and definitions, allowing AMC to be ported to different target board (hardware) without requiring code changes in the AMC or its layers.

The profile directories currently supported on AMC can be seen the src/profiles/.

Cmake will include the appropriate set of header files, depending on the profile specified by the user (rave, v80, etc.). This allows board (hardware) specific data to be changed and AMC source code to remain the same.

Porting AMC to new boards in the future should only require additional profile directories to be created, with no source code changes required. See the following code snippet for detail.

CMakeLists.txt

#set custom profile with -DPROFILE flag (v80, rave, etc), Defaults to rave if not specified
 if(PROFILE MATCHES "^(v80*)$")
    include_directories(src/profiles/v80)
    set(PROFILE_FAL_PATH        "src/profiles/v80/profile_fal.c")
    set(EEPROM_PATH             "src/device_drivers/eeprom/aved/eeprom.c")
    set(PROFILE_DEBUG_MENU_PATH "src/profiles/v80/profile_debug_menu.c")
else()
    include_directories(src/profiles/rave)
    set(PROFILE_FAL_PATH        "src/profiles/rave/profile_fal.c")
    set(EEPROM_PATH             "src/device_drivers/eeprom/rave/eeprom.c")
    set(PROFILE_DEBUG_MENU_PATH "src/profiles/rave/profile_debug_menu.c")
    add_definitions(-DPROFILE_RAVE)
endif()

Each profile directory includes the following header files.

profiles/
├── rave
│   ├── profile_debug_menu.c
│   ├── profile_fal.c
│   ├── profile_hal.h
│   ├── profile_pdr.h
│   └── profile_sensors.h
└── v80
    ├── profile_debug_menu.c
    ├── profile_fal.c
    ├── profile_hal.h
    ├── profile_pdr.h
    └── profile_sensors.h
└── etc...

BIM Profile

The profile_bim.h header file provides event tables for the Built in Monitoring (BIM) Application.

Firmware Interface Abstraction Layer (FAL) Profile

The profile_fal.c file provides specific initialization for the FAL.

The profile_fal.h header file provides profile (hardware) specific definitions for the FAL.

Header Abstraction Layer (HAL) Profile

The profile_hal.h header file provides all other profile (hardware) specific definitions.

PDR Profile

The profile_pdr.h header file provides profile (hardware) specific definitions for Out Of Band PDR and sensor reporting.

Sensors Profile

The profile_sensors.h header file provides profile (hardware) specific definitions for all sensors.

This profile is where sensor thresholds and limits are set - if a sensor value exceeds the “critical” value, the AMI (on the host interface) will kill any host processes that are using the in-band interface (see Sensors and Hardware Monitoring). To add/change thresholds, simply change the value in the relevant sensor_profile. To disable a threshold, set it to ASC_SENSOR_INVALID_VAL (-1).

Device Drivers

The device drivers layer of AMC has similarly been designed to be abstracted from the target boards. Each device driver has been written with a common header file but separate source files for AMR and Linux, providing a common API over the BSP-provided drivers and utilities.

Cmake will include the appropriate source code paths, depending on the profile specified by the user (rave, v80, etc.), for each of the device drivers. This allows AMC to be easily compiled for Linux or FreeRTOS OS.

See the following example of I2c and OSPI device drivers. The common header outlines the API used throughout AMC. OS specific source implementations prevent any further code changes throughout AMC when porting to a new OS/boards.

All future device drivers added to AMC should follow this design pattern.

i2c
│   ├── aved
│   │   └── i2c.c
│   └── debug
│   │   └── i2c_debug.c
|   |   └── i2c_debug.h
│   ├── i2c.h

FAL (Firmware Abstraction Layer)

Similarly, the Firmware abstraction layer of AMC has been designed to be abstracted from the target board. Each FAL implementation has been written with a common header file, providing a common API over the abstracted firmware, but with separate source files for AMC (AMR).

Just as with the device drivers, cmake will include the appropriate source code paths, depending on the profile specified by the user (rave, v80, etc.).

See the following example of gcq, ospi and qsfp FALs. All future FAL implementations added to AMC should follow this design pattern.

├── gcq

│ ├── fw_if_gcq_amc.c

│ ├── fw_if_gcq.h

├── ospi

│ ├── fw_if_ospi_amc.c

│ ├── fw_if_ospi.h

│ └── fw_if_ospi_stub.c

See the following example code snippet for details.

Note: cmake can specify paths for appropriate device driver, and FAL (firmware abstraction layer) implementations depending on the OS specified.

CMakeLists.txt

if(OS MATCHES "^(FreeRTOS)$")
    if (NOT YOCTO)
        add_definitions(-DSDT)
        set(CMAKE_C_COMPILER armr5-none-eabi-gcc)
        set(CMAKE_SYSTEM_NAME Generic)
        set(CMAKE_SYSTEM_PROCESSOR arm)
        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mcpu=cortex-r5 -mfloat-abi=hard -mfpu=vfpv3-d16 -Werror -Wall")
        set(amc_SOURCE_DIR "${CMAKE_SOURCE_DIR}")
    endif()

    set(CMAKE_CROSSCOMPILING 1)
    set(CMAKE_C_COMPILER_WORKS TRUE)
    set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")

    set(OSAL_PATH       "src/osal/src/freeRTOS/osal.c")
    set(FW_IF_PATH      "src/fal/gcq/fw_if_gcq_amc.c")
    set(FW_I2C_PATH     "src/device_drivers/i2c/aved/i2c.c")
    set(FW_SYS_MON_PATH "src/device_drivers/sensors/sys_mon/aved/sys_mon.c")
    set(FW_OSPI_PATH    "src/device_drivers/ospi/aved/ospi.c")
    set(FW_IF_OSPI_PATH "src/fal/ospi/fw_if_ospi_amc.c")
    if(PROFILE MATCHES "^(v80)$")
        set(FW_EMMC_PATH                  "src/device_drivers/emmc/aved/emmc.c")
        set(FW_IF_EMMC_PATH               "src/fal/emmc/fw_if_emmc_amc.c")
        set(FW_IF_SMBUS_BLOCK_IO_PATH     "src/fal/smbus/fw_if_smbus_block_io.c")
        set(FW_IF_MUXED_DEVICE_PATH       "src/fal/muxed_device/fw_if_muxed_device_amc.c")
        set(FW_IF_MUXED_DEVICE_DEBUG_PATH "src/fal/muxed_device/debug/fw_if_muxed_device_debug.c")
    endif()
    set(NAME "amc.elf")

    if(FREERTOS_DEBUG)
        add_definitions(-DFREERTOS_DEBUG)
    endif()