Deploying Kanzi applications to RCar Gen3/INTEGRITY

You can deploy your Kanzi application to Renesas R-Car Gen 3 platform, such as M3 or H3, that runs the INTEGRITY real-time operating system.

These instructions are verified on Windows 10 and Ubuntu 18.04.5 LTS.

Prerequisites

Before you can build and deploy Kanzi applications you need a working INTEGRITY development environment for Renesas R-Car including:

  • GHS MULTI IDE

  • INTEGRITY system development kit

  • INTEGRITY AARCH compiler toolchain

  • Renesas R-Car Gen 3 board support package

  • SCons and Python:

    • For SCons 2.5.1 or newer, Python 2.7.

    • For SCons 3.0.0 or newer, Python 2.7, or Python 3.5 or newer.

    • For SCons 4.0.0 or newer, Python 3.5 or newer.

  • The means to deploy your application and transfer files to the target device, such as U-boot using TFTP server and a FAT-formatted memory card, or GHS Probe.

For information on how to set up the INTEGRITY development environment, see the Renesas R-Car BSP User's Guide provided by Green Hills Software at /opt/sdk/ghs/int1178/manuals/devtree-arm64_rcar_notes.pdf.

Before you start deploying Kanzi applications to the R-Car Gen 3 board, make sure you can successfully deploy and run one of the OpenGL examples provided with the GPU support package.

The examples in this topic assume that:

  • Your development environment is installed in /opt/sdk/ghs/.

  • You configured the target device to use U-boot bootloader to load binary images from a TFTP server.

  • You use a FAT-formatted memory card to transfer Kanzi binary and configuration files to the target device.

Developing Kanzi applications for RCar-Gen3/INTEGRITY

You receive the Kanzi development files as a compressed archive. Extract the archive to the <KanziWorkspace>/Engine directory.

The package contains a minimal example project called kzb_player. You can use this project as a template to create Kanzi applications.

When developing Kanzi applications for RCar-Gen3/INTEGRITY, keep in mind that you must call these INTEGRITY-specific functions before onConfigure():

  • kzsFileBaseSetResourceDirectory("/") function tells Kanzi where in the file system is the kzb file.

  • WaitForFileSystemInitialization() function solves a race condition that stems from the way processes are started in parallel under INTEGRITY.

Memory mapping files on INTEGRITY

On INTEGRITY, Kanzi loads kzb files from the file system and tries to access them using memory mapping.

On INTEGRITY, mmap():

  • By default maps into a virtual address space only a shared memory object.

  • Does not support mapping regular files.

See Integrity Libraries and Utilities Reference Guide in the int<INTEGRITY_version>/manuals/libref.pdf file.

The full POSIX-compliant mmap() support requires an additional library that you can request from the Green Hills Software support.

If Kanzi cannot map a file, it copies the entire file to memory and prints to the log Memory mapping failed. Reading the file to memory. If Kanzi does not log such a warning, the memory mapping works as expected and Kanzi does not copy the entire file to memory.

If your target device does not support POSIX memory mapping of file contents, you can load kzb files from a memory buffer.

To load kzb files from a memory buffer:

  1. In your Kanzi application, add the registerKzbFromMemory function:

    /// Registers in the Resource Manager a kzb file that resides in memory.
    /// Kanzi expects that a memory area registered this way is read-only
    /// and remains valid and unmodified throughout the lifetime of the process.
    /// \param bufferStart Pointer to the start of the kzb file.
    /// \param bufferSize Size of the kzb file in bytes.
    void registerKzbFromMemory(const byte* bufferStart, uintmax_t bufferSize)
    {
        // Load a file used for memory mapping.
        unique_ptr<File> file(new ReadOnlyMemoryFile(bufferStart, bufferSize));
        unique_ptr<KzbFile> kzbFile(new KzbFile(getDomain(), kanzi::move(file)));
        string startupPrefab("kzb://" + kzbFile->getProjectName() + "/StartupPrefab");
        // Pass the memory file to the Kanzi resource manager.
        getResourceManager()->addKzbFile(kanzi::move(kzbFile));
    
        // Assign startup prefab for scene graph initialization.
        kzLogInfo(KZ_LOG_CATEGORY_GENERIC, ("Setting startup prefab '{}'", startupPrefab));
        m_startupPrefabUrl = startupPrefab;
        kzLogInfo(KZ_LOG_CATEGORY_GENERIC, ("onStartup [DONE]"));
    }
    
  2. In the onStartup() callback, call the registerKzbFromMemory function.

    The MULTI Linker can generate globally visible symbols for the start and size of each file that is linked to your address space image. You can use these symbols to refer to the start and size of each kzb file that you load.

    // Symbols generated by MULTI Linker.
    //extern char __ghsbegin_kzbfile_a[]; // Start of first kzb file.
    //extern char __ghssize_kzbfile_a[];  // Size of first kzb file.
    //extern char __ghsbegin_kzbfile_b[]; // Start of second kzb file.
    //extern char __ghssize_kzbfile_b[];  // Size of second kzb file.
    
    // Override onStartup() callback.
    virtual void onStartup() KZ_OVERRIDE
    {
        registerKzbFromMemory(reinterpret_cast<byte*>(__ghsbegin_kzbfile_a), reinterpret_cast<size_t>(__ghssize_kzbfile_a));
        registerKzbFromMemory(reinterpret_cast<byte*>(__ghsbegin_kzbfile_b), reinterpret_cast<size_t>(__ghssize_kzbfile_b));
    }
    

Compiling Kanzi applications

You can compile your Kanzi application using either SCons or GHS MULTI.

Use the kzb_player application to load and run kzb files that you create in Kanzi Studio.

Using SCons

When you compile an application with SCons, the build system applies the default options for your target platform.

To use SCons to compile the example Kanzi application:

  1. (Optional) The compiling process depends on Kanzi Engine. When you store your project in the Kanzi workspace directory and the project has the default Kanzi project structure, SCons automatically detects the location of Kanzi Engine.

    To build a project from a directory that is not in the Kanzi workspace directory, set the KANZI_HOME environment variable to the Kanzi workspace path. SCons uses this variable to detect the Kanzi Engine location.

    On Windows, run SCons from the Kanzi Command Prompt. The Kanzi Command Prompt runs with the KANZI_HOME environment variable set. See Using the Kanzi Command Prompt.

  2. On the command line, go to the target configuration directory of the project that you want to build.

    For example, go to <KanziWorkspace>/Engine/applications/kzb_player/configs/platforms/integrity_rcar_rwm_aarch64.

  3. On the command line, run SCons.

    The scripts and configuration files include custom command line arguments that you can use to select build type.

    Command

    Build type

    scons

    Creates a release build.

    scons debug

    Creates a debug build.

    scons profiling

    Creates a profiling build.

    When the building completes, you can find the application executable kzb_player.bin in the <KanziWorkspace>/Engine/Engine/applications/kzb_player/bin directory.

Using GHS MULTI

To learn about the platform-specific defines, compiler flags, and library dependencies, see the build information XML files at <KanziWorkspace>/Engine/lib/integrity_rcar_rwm_aarch64/<BuildVariant>.

To use GHS MULTI to compile the example Kanzi application:

  1. Set the KANZI_HOME environment variable to the Kanzi workspace path.

    This way, you enable GHS MULTI to detect the Kanzi Engine location.

  2. Add this to the kzb_player.gpj file, add the file to your GHS MULTI solution, and edit it to match your platform configuration:

    #!gbuild
    
    macro KZ_ENGINE_DIR=$(KANZI_HOME)/Engine
    macro KZ_ENGINE_PLATFORM_LIBS=$(KZ_ENGINE_DIR)/libraries/platforms/integrity_rcar_rwm_aarch64
    #component integrity_virtual_address_space
    [Program]
    
    # Debug build
    #-G
    #-DKANZI_DEBUG
    #-L$(KZ_ENGINE_DIR)/lib/integrity_rcar_rwm_aarch64/ES3_Debug
    
    # Release build
     -DNDEBUG
     -L$(KZ_ENGINE_DIR)/lib/integrity_rcar_rwm_aarch64/ES3_Release
    
    # Defines
     -DKZ_SUPPORT_GRAPHICS_CONTEXT_API_EGL=1
     -DKZ_SUPPORT_GRAPHICS_API_GLES=1
     -DKZ_DLOAD_GLES_SYMBOLS=32
     -DKZ_LINKED_GLES_SYMBOLS=31
     -DKANZI_FEATURE_3D
     -DINTEGRITY
     -DPOSIX
     -DINT_178B
     -DBOOST_HAS_THREADS
     -DBOOST_HAS_PTHREADS
     -D__LITTLEENDIAN__
     -DKZ_NULL_INPUT
    
    # Include paths
    
    # Kanzi Engine headers
     -I$(KZ_ENGINE_DIR)/include
    
    # Boost headers
     -I$(KZ_ENGINE_PLATFORM_LIBS)/boost/include
     -I$(KZ_ENGINE_DIR)/libraries/platforms/integrity/boost/include
     -I$(KZ_ENGINE_DIR)/libraries/common/boost/include
    
    # Khronos headers. Use only if they are not available in BSP.
    #-I$(KZ_ENGINE_DIR)/libraries/common/opengl_es_2_0/include
    
    # Kanzi Engine third-party dependencies
     -I$(KZ_ENGINE_PLATFORM_LIBS)/freetype/include
     -I$(KZ_ENGINE_DIR)/libraries/common/freetype/include
    
     -I$(KZ_ENGINE_DIR)/libraries/common/harfbuzz/include
    
     -I$(KZ_ENGINE_PLATFORM_LIBS)/icu/include
     -I$(KZ_ENGINE_DIR)/libraries/common/icu/include
    
     -I$(KZ_ENGINE_PLATFORM_LIBS)/libjpeg/include
     -I$(KZ_ENGINE_DIR)/libraries/common/libjpeg/include
    
     -I$(KZ_ENGINE_PLATFORM_LIBS)/libpng/include
     -I$(KZ_ENGINE_DIR)/libraries/common/libpng/include
    
     -I$(KZ_ENGINE_PLATFORM_LIBS)/libunibreak/include
     -I$(KZ_ENGINE_DIR)/libraries/common/libunibreak/include
    
     -I$(KZ_ENGINE_PLATFORM_LIBS)/zlib/include
     -I$(KZ_ENGINE_DIR)/libraries/common/zlib/include
    
    # Linker paths.
     -L$(KZ_ENGINE_PLATFORM_LIBS)/zlib/lib
     -L$(KZ_ENGINE_PLATFORM_LIBS)/freetype/lib
     -L$(KZ_ENGINE_PLATFORM_LIBS)/libjpeg/lib
     -L$(KZ_ENGINE_PLATFORM_LIBS)/libpng/lib
     -L$(KZ_ENGINE_PLATFORM_LIBS)/icu/lib
     -L$(KZ_ENGINE_PLATFORM_LIBS)/libunibreak/lib
     -L$(KZ_ENGINE_PLATFORM_LIBS)/harfbuzz/lib
    # Add BSP library paths as needed.
    
    # Compiler flags
     -os_dir ${__OS_DIR}
     -bsp devtree-arm64
     --rtti
     --exceptions
     --link_once_templates
     --c++11
     -language=cxx
     -fno-strict-aliasing
     --prototype_silent
     --display_error_number
     --diag_remark=1931,236,1934,1974,1,228,997
     --diag_suppress 141
     -Wno-shadow
     -dotciscxx
     -w
     -Wall
     --thread_local_storage
    
    # Release build optimization
     -O2
     -Omax
     -Olink
     -Osize
    
    # System libraries
     -lposix
     -livfs
     -ldl
     -lstd
    # Add system libraries that you need. Note that Kanzi Engine requires Posix threads and pipe.
    
    # Kanzi Engine libraries
     -lkzappfw
     -lkzui
     -lkzcoreui
     -lkzcore
    
    # Kanzi Engine third-party dependencies
     -l$(KZ_ENGINE_PLATFORM_LIBS)/freetype/lib/libfreetype.a
     -l$(KZ_ENGINE_PLATFORM_LIBS)/harfbuzz/lib/libharfbuzz.a
     -l$(KZ_ENGINE_PLATFORM_LIBS)/icu/lib/libicuuc.a
     -l$(KZ_ENGINE_PLATFORM_LIBS)/icu/lib/libicui18n.a
     -l$(KZ_ENGINE_PLATFORM_LIBS)/icu/lib/libicudata.a
     -l$(KZ_ENGINE_PLATFORM_LIBS)/libjpeg/lib/libjpeg.a
     -l$(KZ_ENGINE_PLATFORM_LIBS)/libpng/lib/libpng.a
     -l$(KZ_ENGINE_PLATFORM_LIBS)/libunibreak/lib/libunibreak.a
     -l$(KZ_ENGINE_PLATFORM_LIBS)/zlib/lib/libz.a
    
  3. In GHS MULTI, compile the application and kernel.

  4. Prepare the image using gmemfile. This produces a file called kzb_player.bin.

Deploying your Kanzi application with U-boot

To deploy your Kanzi application as a U-boot image and load it using TFTP:

  1. Make the application executable as a part of a binary image kzb_player.uimage, copy these files to a memory card, and insert the card into the board before you power up the board:

    • kzb_player.bin is the application executable

    • my_project.kzb is the kzb binary that contains the content of your Kanzi application.

      You export a kzb file in Kanzi Studio from the project of your application. Export the kzb binary every time after you make changes to your Kanzi Studio project. See Using kzb files.

    • binaries.cfg contains the names of the kzb files that are part of your application.

    • application.cfg contains optional parameters that you can use to configure your Kanzi application. See Application configuration reference.

  2. To deploy your Kanzi application as a U-boot image and load it using TFTP, execute:

    tftp 48080000 kzb_player.uimage
    bootm 48080000
    

    Tip

    To execute these commands when you power up your device, store them in the U-Boot environment. The deployment address in the above example is 48080000. To find the deployment address, see the documentation of your target device.

Debugging in GHS MULTI

You can attach the debugger using the rtserv2 protocol.

To debug in GHS MULTI:

  1. In the GHS MULTI IDE go to Main > Connect > rtserv2.

    The debugger window opens when the connection is established.

  2. Start the application by selecting the newly created initial process under kzb_player and clicking the green arrow button.

Switching between debug and release in GHS MULTI

The sample kzb_player.gpj by default creates a release build, but contains the macro to switch to debug build.

To switch between debug and release in GHS MULTI:

  1. Define the _DEBUG preprocessor macro and link with the debug libraries by commenting out:

    -G
    -DKANZI_DEBUG
    -L$(KZ_ENGINE_DIR)/lib/integrity_rcar_rwm_aarch64/ES3_Debug
    
  2. Comment out the lines that define the _RELEASE macro:

    #-DNDEBUG
    #-G
    #-L$(KZ_ENGINE_DIR)/lib/integrity_rcar_rwm_aarch64/ES3_Release
    
  3. Recompile and redeploy the application.