C
Monitor Integration to Qt Ultralite with AUTOSAR
Demonstrates how to integrate Qt Safe Renderer Monitor to a Qt Ultralite application targeting AUTOSAR-compliant environments.
This example demonstrates how to integrate the Qt Safe Renderer (QSR) Monitor module into a Qt Ultralite application with AUTOSAR CRC checking. It shows how to generate and use output verification data, and how to interact with the AUTOSAR hardware interface to verify that the rendering is correct.
For more information about implementing safety-critical elements in Qt Ultralite, see: Qt Quick Ultralite application with safety-critical items
The build system uses CMake. The example builds QSR modules, generates the golden CRC values from QML using the QSR Monitor Config Tool, and links the resulting data library into a monitor test application.
Overview
The QML layout is parsed at build time to generate output verification data. The tool produces a data library containing the golden CRC values for each safety item state. This data is later used during runtime to verify that the rendering output on the screen matches the expected results.
The verification is done by calling AUTOSAR CDD stub functions that simulate the hardware CRC checking mechanism.
Building the Project
The project uses CMake for building. The CMakeLists.txt file configures the build process and sets up the necessary dependencies:
cmake_minimum_required(VERSION 3.10) project(QSRMonitor C CXX) # Check for required QSR source directory if(NOT DEFINED QSR_SOURCE_DIR) message(FATAL_ERROR "QSR_SOURCE_DIR must be defined. Please provide it with -DQSR_SOURCE_DIR=<path>") endif() # Define build options option(BUILD_FOR_MCU "Build for MCU target" ON) option(BUILD_LIBRARIES_ONLY "Build only libraries without executable" OFF) # Include QSR tools macros and header export include(${QSR_SOURCE_DIR}/cmake/qsr_tools_custom_macros.cmake) include(${QSR_SOURCE_DIR}/cmake/export_qsr_headers.cmake) # Set the QML file for monitor data generation set(QSR_INPUT_QML "${CMAKE_CURRENT_SOURCE_DIR}/qml/SafeUI.qml" CACHE STRING "The QML file for the monitor data generation") # Add QSR subdirectories with binary directories add_subdirectory(${QSR_SOURCE_DIR}/src/saferenderer ${CMAKE_BINARY_DIR}/qsr/saferenderer) add_subdirectory(${QSR_SOURCE_DIR}/src/adaptation/outputverifier ${CMAKE_BINARY_DIR}/qsr/outputverifier) add_subdirectory(${QSR_SOURCE_DIR}/src/monitor ${CMAKE_BINARY_DIR}/qsr/monitor) # Generate monitorconfig data from QML to a library add_subdirectory(libmonitordata) # Create a custom target for all libraries add_custom_target(qsr_libraries DEPENDS SafeRenderer OutputVerifier SafeMonitor qsrmonitordata COMMENT "Building QSR libraries" ) # Create the test executable set(TEST_SRCS cdd_qsr_stub.c main.c ) add_executable(test_exe ${TEST_SRCS}) target_link_libraries(test_exe SafeRenderer OutputVerifier SafeMonitor qsrmonitordata )
The build configuration requires:
QSR_SOURCE_DIR
: Path to Qt Safe Renderer Runtime sources (typically<Qt installation directory>/Src/QtSafeRenderer-2.2.0
).BUILD_LIBRARIES_ONLY
: Optional flag to build only QSR libraries for separate AUTOSAR projects.QSR_TOOLS_PATH
: Path to Qt Safe Renderer tools (typically<Qt installation directory>/Tools/QSR-2.2.0/bin
).QSR_INPUT_QML
: Path to the safety-critical UI design.
The build process includes:
- Building QSR libraries (SafeRenderer, OutputVerifier, Monitor) into
${CMAKE_BINARY_DIR}/lib
. - Generating monitor data from QML using the QSR Monitor Config Tool.
- Creating a data library with CRC values for verification.
- Linking the test executable with all required components.
- Exporting header files to
${CMAKE_BINARY_DIR}/include
for use in other projects.
The monitor data generation is configured in a separate CMakeLists.txt:
cmake_minimum_required(VERSION 3.10) project(QSRMonitorDataLib C CXX) # Set library properties set(LIBRARY_NAME qsrmonitordata) # Include directories include_directories( ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/generated ${CMAKE_BINARY_DIR}/include/QtSafeRenderer ) # Generate the monitor data qsr_generate_monitor_data(monitordata_gen SAFE_QML ${QSR_INPUT_QML} CRC_ALGORITHM ${SAFE_LAYOUT_CRC_ALGORITHM} ) # Create an object library with the generated files add_library(${LIBRARY_NAME} ${monitordata_gen_GENERATED_FILES}) # Add dependency on the generation target add_dependencies(${LIBRARY_NAME} monitordata_gen) # Set library properties set_target_properties(${LIBRARY_NAME} PROPERTIES OUTPUT_NAME ${LIBRARY_NAME} LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib ) # Install rules for library only install(TARGETS ${LIBRARY_NAME} LIBRARY DESTINATION lib ARCHIVE DESTINATION lib RUNTIME DESTINATION bin )
This configuration:
- Uses
qsr_generate_monitor_data
to process the QML file. - Creates a library containing the generated CRC data in
${CMAKE_BINARY_DIR}/lib
. - The CRC algorithm for the target platform is set in the build configuration:
crc32
for Renesas RH850.mpeg2
for Infineon Traveo II.
To build the project, run:
mkdir build cd build cmake .. -G Ninja -DCMAKE_TOOLCHAIN_FILE=<Qt installation directory>/Src/QtSafeRenderer-2.2.0/cmake/ghs.cmake -DQSR_TARGET_TOOLCHAIN_DIR="<GHS compiler installation>" -DQSR_SOURCE_DIR=<Qt installation directory>/Src/QtSafeRenderer-2.2.0 -DQSR_TOOLS_PATH=<Qt installation directory>/Tools/QSR-2.2.0/bin cmake --build .
If you modify the QML layout, rebuild the project to regenerate the CRC data.
Output Verification
The QML layout defines safety items that need to be verified. Each item is identified by its QML id:
import QtQuick import Qt.SafeRenderer Window { id: test width: 640 height: 480 SafeImage { id: iconBattery objectName: "iconBattery" width: 64 height: 64 anchors.centerIn: parent fillColor: "black" source: "battery_icon.png" } }
The item ID used in verification is calculated from the QML id using the qsafe_hash
function:
// Calculate item ID from QML id using qsafe_hash const char *itemName = "iconBattery"; const quint32 itemId = qsafe_hash(itemName, strlen(itemName)); const quint32 stateId = 1U; //visible const qint32 ret = addItemToVerification(itemId, stateId);
The main.c
file initializes the output verification, adds items for CRC checking, and runs the verification sequence:
// main.c #include <stdio.h> #include <stdint.h> #include <string.h> #include "errorcode.h" #include "qsafeglobal.h" #include "qsafechecksum.h" #include "outputverifier_capi.h" #include "qsrmonitor.h" int main(void) { const char *itemName = "iconBattery"; const quint32 itemId = qsafe_hash(itemName, strlen(itemName)); const quint32 stateId = 1U; //visible int ret = addItemToVerification(itemId, stateId); printf("Testing monitor integration\n"); initVerifierDevice(100U, 100U); printf("Item id: %d State id: %d\n", itemId, stateId); if (ret == 0) { OutputVerifier_verifyOutput(); verifyOutput(defaultErrorHandler); return 0; } else { printf("Failed to add item for verification\n"); return 1; } }
The API addItemToVerification()
adds an item and its expected state to the verification queue. Items are verified using OutputVerifier_verifyOutput()
followed by verifyOutput()
.
The queue is FIFO-based and supports state updates automatically. The application code only needs to enqueue the new item state; internal logic ensures the latest state is verified.
The verification device is initialized with offset values to position the verification area:
void initVerifierDevice(quint32 xOffset, quint32 yOffset) { static SafeRenderer::OutputVerifierDevice outputVerifierDevice(xOffset, yOffset, getStaticOutputVerifier()); }
The AUTOSAR CRC checking stubs used by this example are:
void Cdd_Qsr_RequestCrc(quint32 x, quint32 y, quint32 width, quint32 height) { // Define region to verify // In real implementation, this would configure the hardware CRC unit (void)x; (void)y; (void)width; (void)height; } void Cdd_Qsr_WaitForResult(void) { // Wait for CRC calculation to complete // In real implementation, this would wait for hardware CRC unit } quint32 Cdd_Qsr_ReadCrc(void) { // Read the calculated CRC value // In real implementation, this would read from hardware CRC unit return 0U; }
These stub functions represent the device API:
For details about implementing the AUTOSAR CDD interface, see: Adapting Output Monitor to AUTOSAR
Cdd_Qsr_RequestCrc()
- Defines the region to verify.Cdd_Qsr_WaitForResult()
- Waits for the result.Cdd_Qsr_ReadCrc()
- Reads the actual CRC.
The read CRC value is compared against the pre-generated golden CRCs. If the values do not match, the error handler is invoked to handle the verification failure.
Customizing Error Handling
The default error handler prints the error to the debug output. In production systems, implement your own version to raise alerts or initiate system recovery.
static void defaultErrorHandler(ErrorCode errorType, qint64 arg1, qint64 arg2) { printf("Error: %s\n", errorCodeToString(errorType)); printf("Item id: %d, CRC checking failed. Actual value: %x\n", (quint32)arg1, (quint32)arg2); }
AUTOSAR HW Integration
The example includes only a stub implementation of the AUTOSAR CDD interface. Real implementations must provide CRC access logic using MCU hardware features.
The Qt Ultralite reference implementation supports the following HW targets:
- Infineon Traveo II.
- Renesas RH850.
For more information and a reference AUTOSAR project for the platforms, contact The Qt Company.
Example Files
CMakeLists.txt
- Build setup.main.c
- Monitor test loop and verification setup.cdd_qsr_stub.c
- AUTOSAR CDD interface stubs for CRC verification.SafeUI.qml
- Safety-critical UI layout.
Files:
- saferenderer/qul-monitor/CMakeLists.txt
- saferenderer/qul-monitor/libmonitordata/CMakeLists.txt
- saferenderer/qul-monitor/qml/SafeUI.qml
Images:
Available under certain Qt licenses.
Find out more.