PPU examples
This guide contains instructions for successful compilations of the following projects using HighTec LLVM toolchain version 9.1.1:
-
iLLD_TC49xA_ADS_PPU-IPC -
iLLD_TC49xA_ADS_PPU-IRQ -
iLLD_TC49xA_ADS_PPU-SIMD -
iLLD_TC49xA_ADS_PPU-STU
It assumes that one of the projects has been imported into the current workspace.
The following changes are required before the first project build attempt:
-
Wait until the indexer finishes.
-
Right-click on the project, then Project updater → Update iLLD → Finish.
-
Right-click on the project and click on Refresh.
-
Wait until the indexer finishes.
-
Add the
Lcf_Hightec_Tricore_Ppu.lsllinker script specifically adapted for the PPU use case. The default linker scriptLcf_Metaware_ArcEV_Ppu.lslgenerated into the PROJECT_ROOT/PPU folder.
PPU MetaWare build configuration
The following changes are required to build the PPU project for the existing PPU Debug (Ext. MetaWare) build configuration:
-
Right-click on the project, then Build Configurations → Set Active → PPU Debug →
Ext. MetaWare.
-
Right-click on the project, then Properties → C/C++ Build → Settings → Settings. Update
MetaWareInstallation Path to, i.e., "C:\HighTec\toolchains\mwaurix\v1.0.0" and click on Apply and close. -
Click on the project, then Properties → C/C++ Build → Behavior. Disable parallel build by deselecting the "enable parallel build" checkbox, then click on Apply and close. Optionally, configure the option "use optimal jobs" to "use parallel jobs" and set the value to be lower or equal to the physical cores of the used laptop. This is not a fail-proof option, and one might encounter a compiler crash during the build.
-
Under the options for
MetaWare C/C++ Compiler, click on "Miscellaneous" and add-Hnocrt, click on Apply and close.
-
Under the options for
MetaWare Linker, click on "Miscellaneous" and add-Hnocrt, click on Apply and close.
-
Under the options for
MetaWare Linker, click on "Runtime Libraries" and mark Do not link in standard C/C++ library (-Hnolib), click on Apply and close. -
Click on AURIX Development Studio → AURIX Build Booster click on Ignore paths and add the following folders and click on Apply.:
-
/Libraries/Infra/Platform/Tricore
/Libraries/Infra/Ssw/TC49A/Tricore
/Libraries/iLLD/TC49A/Scr
/Libraries/iLLD/TC49A/Tricore/Cpu
/Libraries/iLLD/TC49A/CpuGeneric/Asclin
-
-
One by one, right-click on the following directories/files, then Resource Configuration → Exclude from build → Select your build configuration and click OK (some may already have been disabled).
-
/Libraries/iLLD/TC49A/CpuGeneric/Asclin
/Libraries/iLLD/TC49A/Tricore/Cpu
/Libraries/iLLD/TC49A/Scr
/Libraries/Infra/Platform/Tricore
/Libraries/Infra/Ssw/TC49A/Tricore
AllowAccess.c,PpuInterface.c
Cpu0_Main.c,Cpu1_Main.c,Cpu2_Main.c,Cpu3_Main.c,Cpu4_Main.c,Cpu5_Main.c
-
-
Remove the following code in
iLLD/Tricore/Cpu/std/IfxCpu_Intrinsics.hdue to the error: redefinition of '<_functions_>':#if defined(__arc__) IFX_INLINE void Ifx__ldmst(volatile void *address, unsigned mask, unsigned value) { *(volatile uint32 *)address = (*(volatile uint32 *)address & ~(mask)) | (mask & value); } IFX_INLINE uint32 __clz(sint32 x) { uint32 n = 0; uint32 bits = sizeof(x) * 8; for (int i = 1; i < bits; i ++) { if (x < 0) break; n ++; x <<= 1; } return n; } IFX_INLINE void Ifx__imaskldmst(volatile void *address, unsigned value, unsigned bitoffset, unsigned bits) { uint32 mask = (((1u << bits) - 1u) << bitoffset); uint32 shiftValue = (value << bitoffset); *(volatile uint32 *)address = (*(volatile uint32 *)address & ~(mask)) | (mask & shiftValue); } #endif /** 32bit load operation */ IFX_INLINE uint32 __ld32(void *addr) { return *(volatile uint32 *)addr; } /** 32bit store operation */ IFX_INLINE void __st32(void *addr, uint32 value) { *(volatile uint32 *)addr = value; } /** 64bit load operation */ IFX_INLINE uint64 __ld64(void *addr) { return *(volatile uint64 *)addr; } /** 64bit store operation */ IFX_INLINE void __st64(void *addr, uint64 value) { *(volatile uint64 *)addr = value; } /** 64bit load operation which returns the lower and upper 32bit word */ IFX_INLINE void __ld64_lu(void *addr, uint32 *valueLower, uint32 *valueUpper) { uint64 value; value = __ld64(addr); *valueLower = (uint32)value; *valueUpper = (uint32)(value >> 32); } /** 64bit store operation which stores a lower and upper 32bit word */ IFX_INLINE void __st64_lu(void *addr, uint32 valueLower, uint32 valueUpper) { uint64 value = ((uint64)valueUpper << 32) | valueLower; __st64(addr, value); } -
Build the PPU project.
TriCore™ external LLVM build configuration
The following changes are required to build the Tricore project part: * Wait until the indexer finishes.
-
Right-click on the project, then Project updater → Update iLLD → Finish.
-
Right-click on the project and click on Refresh.
-
Wait until the indexer finishes.
-
Update the generated
Lcf_Hightec_Tricore_Tc.lsllinker script with the baseTC49xlinker script.
The following changes are required to build the project:
-
Right-click on the project, then Build Configurations → Manage → New
-
Give any name
-
Select the option Import predefined, then TriCore Application → External →
LLVM→ Debug and click OK.
-
-
Set the newly created configuration to active by clicking on Set Active and click OK.
-
Wait until the indexer finishes.
-
Edit the build settings: right-click on the project Properties → C/C++ Build → Settings
-
Click on Settings and Update Path to the
LLVMbin directory, i.e., "C:\HighTec\toolchains\tricore\v9.1.1\bin" and click on Apply.
-
-
Under the options for LLVM C Compiler, click on "Miscellaneous" and add
-merrata=cpu141, click on Apply.
-
Under the options for LLVM C++ Compiler, click on "Miscellaneous" and add
-merrata=cpu141, click on Apply. -
Click on LLVM Assembler, extend the command string with
-merrata=cpu141toclang -merrata=cpu141and click on Apply. -
Click on LLVM Linker, extend the command string with
-merrata=cpu141toclang -merrata=cpu141and click on Apply. -
Click on LLVM Linker → Libraries and change libraries from
htcostosemihostand click on Apply.
-
Right-click on the project, then Properties → AURIX Development Studio → AURIX Build Booster → Libraries paths → Delete /Libraries/iLLD if present and click on Apply and close.
-
Right-click on the project, then Properties → AURIX Development Studio → AURIX Build Booster → Ignore paths → Add the following folders and click on Apply and close.
-
/Libraries/iLLD/TC49A/ArcEV
/Libraries/iLLD/TC49A/Scr
/Libraries/Infra/Platform/ArcEV
/PPU
-
-
Right-click on the project, then Properties → C/C++ General → Paths and Symbols → Includes → GNU C, and ensure that the include paths do not contain any of the following directories and their subdirectories, click on Apply and close.
-
/Libraries/iLLD/TC49A/ArcEV
/Libraries/iLLD/TC49A/Scr
/Libraries/Infra/Platform/ArcEV
/PPU
-
-
One by one, Right-click on the following directories, then Resource Configuration → Exclude from build → Select your build configuration and click OK (some may already have been disabled).
-
/Libraries/iLLD/TC49A/ArcEV
/Libraries/iLLD/TC49A/Scr
/Libraries/Infra/Platform/ArcEV
/PPU
-
-
Change the definition of
uncached data/bsssections in Cpu0_Main.c due to the warning: unknown pragma ignored [-Wunknown-pragmas] -
Change
uncached.lmubsssection definition (applies toiLLD_TC49xA_ADS_PPU-IPC,iLLD_TC49xA_ADS_PPU-IRQ, andiLLD_TC49xA_ADS_PPU-STU)
From:#pragma section all "uncached.lmubss" /* Declaration of global uninitialized variables */ #pragma section allTo:
#if defined(__HIGHTEC__) && defined(__clang__) #pragma clang section bss=".uncached.lmubss" #else #pragma section all "uncached.lmubss" #endif /* Declaration of global uninitialized variables */ #if defined(__HIGHTEC__) && defined(__clang__) #pragma clang section bss="" #else #pragma section all "uncached.lmubss" #endif -
Change
uncached.lmudatasection definition (applies to iLLD_TC49xA_ADS_PPU-STU):
From:#pragma section all "uncached.lmudata" /* Definition of global initialized variables */ #pragma section all "uncached.lmudata"To:
#if defined(__HIGHTEC__) && defined(__clang__) #pragma clang section data=".uncached.lmudata" #else #pragma section all "uncached.lmudata" #endif /* Definition of global initialized variables */ #if defined(__HIGHTEC__) && defined(__clang__) #pragma clang section data="" #else #pragma section all "uncached.lmudata" #endif -
Change the following code in
AllowAccess.cdue to the warning: non-portable path to file; specified path differs in case from file name on disk [-Wnonportable-include-path]:
From:#include "IfxCpu_Cfg.h" #include "IfxGtm_Cfg.h" #include "IfxEgtm_Cfg.h" #include "IfxQspi_Cfg.h" #include "IfxCan_Cfg.h" #include "IfxAsclin_Cfg.h" #include "IfxSent_Cfg.h" #include "IfxGpt12_Cfg.h" #include "IfxI2c_Cfg.h" #include "IfxGeth_Cfg.h"To:
#include "IfxCpu_cfg.h" #include "IfxGtm_cfg.h" #include "IfxEgtm_cfg.h" #include "IfxQspi_cfg.h" #include "IfxCan_cfg.h" #include "IfxAsclin_cfg.h" #include "IfxSent_cfg.h" #include "IfxGpt12_cfg.h" #include "IfxI2c_cfg.h" #include "IfxGeth_cfg.h" -
Build TriCore™ project.
Possible errors
Undefined symbol: __heap*
ld.lld: error: undefined symbol: __heap_end
>>> did you mean: __HEAP_END
ld.lld: error: undefined symbol: __heap_start
-
Update the corresponding linker script:
From:/* Heap allocation */ .heap (NOLOAD): ALIGN(4) { . = ALIGN(4); __HEAP = .; . += LCF_HEAP_SIZE; __HEAP_END = .; } > default_ramTo:
/* Heap allocation */ .heap (NOLOAD): ALIGN(4) { . = ALIGN(4); __heap_start = .; . += LCF_HEAP_SIZE; __heap_end = .; } > default_ram