chore: migrate project into clean repository

This commit is contained in:
yuuux
2026-08-13 16:50:52 +08:00
commit d1d25a09e7
27405 changed files with 9422808 additions and 0 deletions

View File

@@ -0,0 +1 @@
add_subdirectory(arcs/hal)

1
arcs-sdk/soc/Kconfig Normal file
View File

@@ -0,0 +1 @@
rsource "arcs/hal/Kconfig"

View File

@@ -0,0 +1,174 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.base.361635877">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.base.361635877" moduleId="org.eclipse.cdt.core.settings" name="Default">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.autotools.core.ErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="listenai_rtos" buildProperties="" description="" id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.base.361635877" name="Default" optionalBuildProperties="" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.base.361635877.1823503393" name="/" resourcePath="">
<toolChain id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.base.846311125" name="ARM Cross GCC">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.452813266" name="Architecture" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.architecture"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix.968839337" name="Prefix" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.suffix.298975493" name="Suffix" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.suffix"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.c.1452799825" name="C compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.c"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp.1856178907" name="C++ compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar.612025400" name="Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy.761942309" name="Hex/Bin converter" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump.1317788921" name="Listing generator" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.size.1661402592" name="Size command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.size"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.make.300279340" name="Build command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.make"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm.407681865" name="Remove command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.useglobalpath.193010974" name="Use global path" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.useglobalpath"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.path.1621980950" name="Path" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.path"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash.554993987" name="Create flash image" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createlisting.240801711" name="Create extended listing" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createlisting"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize.2128605112" name="Print size" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family.950312746" name="ARM family (-mcpu)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.architecture.137550165" name="Architecture (-march)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.architecture"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.1317672380" name="Instruction set" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.thumbinterwork.1912062050" name="Thumb interwork (-mthumb-interwork)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.thumbinterwork"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.endianness.2100302759" name="Endianness" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.endianness"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi.500750265" name="Float ABI" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit.802302928" name="FPU Type" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.unalignedaccess.655273139" name="Unaligned access" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.unalignedaccess"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.mcmse.130210320" name="TrustZone (-mcmse)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.mcmse"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.family.364032768" name="AArch64 family" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.family"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.feature.crc.1854315739" name="Feature crc" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.feature.crc"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.feature.crypto.362609276" name="Feature crypto" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.feature.crypto"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.feature.fp.728579174" name="Feature fp" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.feature.fp"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.feature.simd.109794242" name="Feature simd" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.feature.simd"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.cmodel.1669736903" name="Code model" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.cmodel"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.strictalign.353715706" name="Strict align (-mstrict-align)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.strictalign"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.target.other.1412998157" name="Other target flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.target.other"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.1796372114" name="Optimization Level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength.1318982700" name="Message length (-fmessage-length=0)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar.1660284071" name="'char' is signed (-fsigned-char)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections.1649292843" name="Function sections (-ffunction-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections.1084014429" name="Data sections (-fdata-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.nocommon.928847150" name="No common unitialized (-fno-common)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.nocommon"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.noinlinefunctions.1136331401" name="Do not inline functions (-fno-inline-functions)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.noinlinefunctions"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.freestanding.467360263" name="Assume freestanding environment (-ffreestanding)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.freestanding"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.nobuiltin.1400591049" name="Disable builtin (-fno-builtin)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.nobuiltin"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.spconstant.1038311187" name="Single precision constants (-fsingle-precision-constant)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.spconstant"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.PIC.263082498" name="Position independent code (-fPIC)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.PIC"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.lto.1369527266" name="Link-time optimizer (-flto)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.lto"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.nomoveloopinvariants.919183819" name="Disable loop invariant move (-fno-move-loop-invariants)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.nomoveloopinvariants"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.other.1512703082" name="Other optimization flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.other"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name.1782878766" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.id.945023031" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.id"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.syntaxonly.1876188932" name="Check syntax only (-fsyntax-only)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.syntaxonly"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pedantic.1083885910" name="Pedantic (-pedantic)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pedantic"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pedanticerrors.1734199405" name="Pedantic warnings as errors (-pedantic-errors)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pedanticerrors"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.nowarn.1931127408" name="Inhibit all warnings (-w)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.nowarn"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.unused.1404529577" name="Warn on various unused elements (-Wunused)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.unused"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.uninitialized.1921394205" name="Warn on uninitialized variables (-Wuninitialised)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.uninitialized"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn.1577286712" name="Enable all common warnings (-Wall)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.extrawarn.1078261749" name="Enable extra warnings (-Wextra)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.extrawarn"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.missingdeclaration.2138800763" name="Warn on undeclared global function (-Wmissing-declaration)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.missingdeclaration"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.conversion.784271964" name="Warn on implicit conversions (-Wconversion)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.conversion"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pointerarith.1876710956" name="Warn if pointer arithmetic (-Wpointer-arith)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pointerarith"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.padded.1758531120" name="Warn if padding is included (-Wpadded)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.padded"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.shadow.310617968" name="Warn if shadowed variable (-Wshadow)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.shadow"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.logicalop.903041103" name="Warn if suspicious logical ops (-Wlogical-op)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.logicalop"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.agreggatereturn.181430058" name="Warn if struct is returned (-Wagreggate-return)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.agreggatereturn"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.floatequal.1095363731" name="Warn if floats are compared as equal (-Wfloat-equal)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.floatequal"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.toerrors.1338357772" name="Generate errors instead of warnings (-Werror)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.toerrors"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.other.2135413607" name="Other warning flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.other"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.164818117" name="Debug level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.597591432" name="Debug format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.prof.980677783" name="Generate prof information (-p)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.prof"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.gprof.1936312826" name="Generate gprof information (-pg)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.gprof"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.other.628267684" name="Other debugging flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.other"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.showDevicesTab.438596554" name="showDevicesTab" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.showDevicesTab"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.501532944" isAbstract="false" osList="all"/>
<builder arguments="CHIP=vega TGT=rom IC_BOARD=0" cleanBuildTarget="clean" command="make" id="ilg.gnuarmeclipse.managedbuild.cross.builder.1277017060" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder"/>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
<storageModule moduleId="ilg.gnumcueclipse.managedbuild.packs"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="venus_rtos_arm.null.2138492598" name="venus_rtos_arm"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="ilg.gnuarmeclipse.managedbuild.cross.toolchain.base.361635877;ilg.gnuarmeclipse.managedbuild.cross.toolchain.base.361635877.1823503393;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.658120710;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.1873885037">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="ilg.gnuarmeclipse.managedbuild.cross.toolchain.base.361635877;ilg.gnuarmeclipse.managedbuild.cross.toolchain.base.361635877.1823503393;ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.414710004;ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.input.999129306">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="Xtensa.111507953">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Default">
<resource resourceType="PROJECT" workspacePath="/venus_rtos_arm"/>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
<buildTargets>
<target name="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>CHIP=mars TGT=drv_demo_mars/gpio IC_BOARD=0 BUILD_NANO=1</buildArguments>
<buildTarget>all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>CHIP=mars TGT=drv_demo_mars/gpio IC_BOARD=0</buildArguments>
<buildTarget>IC_BOARD=0 clean</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="bt" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>CHIP=vega TGT=rom IC_BOARD=0</buildArguments>
<buildTarget>IC_BOARD=0 bt</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="arcs_fhost" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>CHIP=arcs TGT=fhost IC_BOARD=0</buildArguments>
<buildTarget>IC_BOARD=0 all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="arcs_c0_dmbt" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>CHIP=arcs</buildCommand>
<buildArguments>TGT=dmbt IC_BOARD=0 INNER=1</buildArguments>
<buildTarget/>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
</buildTargets>
</storageModule>
</cproject>

2
arcs-sdk/soc/arcs/hal/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
**/guardian-out*/
**/build*/

View File

@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>listenai_rtos</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
<dictionary>
<key>?name?</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.append_environment</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildArguments</key>
<value>CHIP=vega TGT=rom IC_BOARD=0</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildCommand</key>
<value>make</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
<value>clean</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.contents</key>
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
<value>false</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.stopOnError</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
<value>false</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,80 @@
SET(ARCS_HAL_LIB_PATH ${CMAKE_CURRENT_SOURCE_DIR}/)
listenai_library_named(arcs-hal)
add_subdirectory(${ARCS_HAL_LIB_PATH}/chip/arcs/driver)
add_subdirectory(${ARCS_HAL_LIB_PATH}/modules/vrtc)
add_subdirectory(${ARCS_HAL_LIB_PATH}/chip/arcs/event)
add_subdirectory(${ARCS_HAL_LIB_PATH}/chip/arcs/ipc)
add_subdirectory(${ARCS_HAL_LIB_PATH}/chip/arcs/wlif)
add_subdirectory(${ARCS_HAL_LIB_PATH}/chip/arcs/wcnd)
add_subdirectory(${ARCS_HAL_LIB_PATH}/chip/arcs/cli_cmd)
add_subdirectory(${ARCS_HAL_LIB_PATH}/modules/shell)
add_subdirectory(${ARCS_HAL_LIB_PATH}/chip/arcs/simsocket)
add_subdirectory(${ARCS_HAL_LIB_PATH}/chip/arcs/lib)
add_subdirectory(${ARCS_HAL_LIB_PATH}/chip/arcs/lwip)
add_subdirectory(${ARCS_HAL_LIB_PATH}/chip/arcs/atcmd)
add_subdirectory(${ARCS_HAL_LIB_PATH}/chip/arcs/flash_if)
add_subdirectory(${ARCS_HAL_LIB_PATH}/chip/arcs/ic_lock)
add_subdirectory(${ARCS_HAL_LIB_PATH}/chip/arcs/utils)
add_subdirectory(${ARCS_HAL_LIB_PATH}/chip/arcs/pm_impl)
add_subdirectory(${ARCS_HAL_LIB_PATH}/chip/arcs/mbedtls)
add_subdirectory(${ARCS_HAL_LIB_PATH}/modules/nvs)
add_subdirectory(${ARCS_HAL_LIB_PATH}/chip/arcs/btos)
add_subdirectory(${ARCS_HAL_LIB_PATH}/modules/profiles)
add_subdirectory(${ARCS_HAL_LIB_PATH}/modules/audio)
add_subdirectory(${ARCS_HAL_LIB_PATH}/modules/codec)
##部分依赖组件头文件!!!
listenai_include_directories(
${ARCS_HAL_LIB_PATH}/include/bsp
${ARCS_HAL_LIB_PATH}/include/NMSIS/Core/Include
${ARCS_HAL_LIB_PATH}/include/NMSIS/DSP/Include
${ARCS_HAL_LIB_PATH}/include/NMSIS/DSP/Include/dsp
${ARCS_HAL_LIB_PATH}/include/NMSIS/DSP/PrivateInclude
${ARCS_HAL_LIB_PATH}/chip/arcs/atcmd/
${ARCS_HAL_LIB_PATH}/chip/arcs/bsp/
${ARCS_HAL_LIB_PATH}/chip/arcs/include/
${ARCS_HAL_LIB_PATH}/chip/arcs/include/bt
${ARCS_HAL_LIB_PATH}/chip/arcs/include/utils
${ARCS_HAL_LIB_PATH}/chip/arcs/include/wifi
${ARCS_HAL_LIB_PATH}/chip/arcs/include/register
${ARCS_HAL_LIB_PATH}/chip/arcs/driver/private_include
${ARCS_HAL_LIB_PATH}/modules/debug/include/
${ARCS_HAL_LIB_PATH}/modules/debug/
${ARCS_HAL_LIB_PATH}/modules/ota/include
${ARCS_HAL_LIB_PATH}/modules/nvs/include
)
listenai_library_compile_options_ifdef(
CONFIG_ARCS_HAL_WARNING_DISABLE
PRIVATE
-w
)
listenai_compile_definitions(
CHIP=4 IC_BOARD=1
IC_HAL_DCACHE_SIZE=32
CONFIG_EXT_RAM
)
if (DEFINED CONFIG_ARCS_HAL_DCACHE_COHERENT)
listenai_compile_definitions(IC_HAL_DCACHE_IS_COHERENT=1)
else()
listenai_compile_definitions(IC_HAL_DCACHE_IS_COHERENT=0)
endif()
if (DEFINED CONFIG_BOOT_HART)
listenai_compile_definitions(-DBOOT_HARTID=${CONFIG_HARTID})
else()
listenai_compile_definitions(-DBOOT_HARTID=0)
endif()
if(${CONFIG_HARTID} EQUAL 0)
listenai_compile_definitions(MBX_AP_WORK=1)
elseif(${CONFIG_HARTID} EQUAL 1)
listenai_compile_definitions(MBX_CP_WORK=1)
endif()
listenai_compile_definitions_ifdef(CONFIG_MODULE_FREERTOS CFG_RTOS=1 IC_USE_RTOS=1)

View File

@@ -0,0 +1,86 @@
menu "arcs hal"
config ARCS_HAL_WARNING_DISABLE
bool "disable hal warnings"
default n
config ARCS_FREE_RTOS
bool "Enable FreeRTOS support"
default n
choice
prompt "core type"
default ARCS_CP_CORE
config ARCS_AP_CORE
bool "ap core"
imply FPU
config ARCS_CP_CORE
bool "cp core"
endchoice
config BOOT_HART
bool "boot hart"
default y
config HARTID
int
default 0 if ARCS_AP_CORE
default 1 if ARCS_CP_CORE
choice
prompt "GPDMA initialization level"
default ARCS_GPDMA_FULL_INIT
help
In AP/CP dual-core systems, GPDMA registers only need to be initialized by one core.
Select the appropriate initialization level for the current core.
config ARCS_GPDMA_FULL_INIT
bool "Complete GPDMA initialization"
help
Enable full GPDMA initialization including register configuration.
Only one core in a dual-core system should use this option.
config ARCS_GPDMA_DATA_ONLY
bool "GPDMA data structure only"
help
Initialize only data structures but skip register initialization.
Use this for cores that need to use GPDMA but rely on another core
to initialize the GPDMA hardware registers.
endchoice
config SMP_CPU_COUNT
int "cpu count"
default 1
config ARCS_HAL_FAST_FUNC_SRAM_SECTION
string "_FAST_FUNC_SRAM section"
default ".fast_text"
rsource "chip/arcs/event/Kconfig"
rsource "chip/arcs/wlif/Kconfig"
rsource "chip/arcs/cli_cmd/Kconfig"
rsource "chip/arcs/driver/Kconfig"
rsource "chip/arcs/wcnd/Kconfig"
rsource "chip/arcs/simsocket/Kconfig"
rsource "chip/arcs/ipc/Kconfig"
rsource "modules/shell/Kconfig"
rsource "modules/vrtc/Kconfig"
rsource "modules/nvs/Kconfig"
rsource "chip/arcs/lwip/Kconfig"
rsource "chip/arcs/lib/Kconfig.wifi"
rsource "chip/arcs/atcmd/Kconfig"
rsource "chip/arcs/flash_if/Kconfig"
rsource "chip/arcs/ic_lock/Kconfig"
rsource "chip/arcs/utils/Kconfig"
rsource "chip/arcs/lib/Kconfig.ble"
rsource "chip/arcs/btos/Kconfig"
rsource "chip/arcs/pm_impl/Kconfig"
rsource "chip/arcs/mbedtls/Kconfig"
rsource "modules/profiles/Kconfig"
rsource "modules/audio/Kconfig"
rsource "modules/codec/Kconfig"
endmenu

View File

@@ -0,0 +1,32 @@
TOPDIR=.
# default value
IC_BOARD=1
CHIP=arcs
INNER=0
MKDEFS=CHIP=${CHIP} TGT=${TGT} IC_BOARD=${IC_BOARD} INNER=${INNER}
.PHONY: all clean allclean
all:
@if [ 'a$(TGT)' = 'a' ]; then echo TGT not defined, nothind done! && exit 1; fi
@if [ -f "src/${TGT}/Makefile" ]; then make -C src/${TGT}/ apps ${MKDEFS} ||exit 1; fi
@if [ -f "src/${CHIP}/${TGT}/Makefile" ]; then make -C src/${CHIP}/${TGT}/ apps ${MKDEFS} ||exit 1; fi
@if [ -f "src/bt/${TGT}/Makefile" ]; then make -C src/bt/${TGT}/ apps ${MKDEFS} ||exit 1; fi
@if [ -f "src/drv_demo/${TGT}/Makefile" ]; then make -C src/drv_demo/${TGT}/ apps ${MKDEFS} ||exit 1; fi
clean:
@if [ 'a$(TGT)' = 'a' ]; then echo TGT not defined, nothind done! && exit 1; fi
@if [ -f "src/${TGT}/Makefile" ]; then make -C src/${TGT}/ clean ${MKDEFS} ||exit 1; fi
@if [ -f "src/${CHIP}/${TGT}/Makefile" ]; then make -C src/${CHIP}/${TGT}/ clean ${MKDEFS} ||exit 1; fi
@if [ -f "src/bt/${TGT}/Makefile" ]; then make -C src/bt/${TGT}/ clean ${MKDEFS} ||exit 1; fi
@if [ -f "src/drv_demo/${TGT}/Makefile" ]; then make -C src/drv_demo/${TGT}/ clean ${MKDEFS} ||exit 1; fi
allclean: clean
@if [ -f "src/Makefile" ]; then make -C src clean||exit 1; fi
@if [ -f "modules/Makefile" ]; then make -C modules clean||exit 1; fi
@if [ -f "chip/Makefile" ]; then make -C chip clean||exit 1; fi
@if [ -f "bt/Makefile" ]; then make -C bt clean ${MKDEFS} APP_PATH=${CHIP}/rom ||exit 1; fi
rm -rf lib/*
rm -rf out/*

View File

@@ -0,0 +1,9 @@
-- Download Git for windows from https://git-scm.com/downloads and install it.
-- Copy 2 files(make.exe, sh.exe) in "tools" folder to "GIT_INSTALL_PATH/cmd" folder.
-- Install toolchain to the PATH which shouldn't include space and illegal characters.
(https://nucleisys.com/download.php for Nuclei RISC-V & https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads for ARM)
-- Set environment variable GNUARMEMB_TOOLCHAIN_PATH(for ARM) or NUCLEI_TOOLCHAIN_PATH(for Nuclei RISC-V) according to your TOOLCHAIN PATH, eg. C:/GNUArmEmbedded/2020-q2-update.
-- Download gnumcueclipse or Nuclei IDE and run it. (https://gnu-mcu-eclipse.github.io/ or https://nucleisys.com/download.php)
-- Window/Show View/Make Target, click "all" to build in Make Target view.
-- If build fail, move up GIT_PATH item in environment variable path.

View File

@@ -0,0 +1,6 @@
TOPDIR=..
exclude_dirs =
include $(TOPDIR)/rules.mk

View File

@@ -0,0 +1,10 @@
TOPDIR=../..
# this makefile only for clean
#exclude subdirs
exclude_dirs=
include $(TOPDIR)/rules.mk

View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,10 @@
SPDXVersion: SPDX-2.2
DataLicense: CC0-1.0
Creator: Organization: Percepio AB ()
PackageName: TraceRecorderSource
PackageOriginator: Percepio AB
PackageDownloadLocation: git+https://github.com/percepio/TraceRecorderSource.git
PackageLicenseDeclared: Apache-2.0
PackageCopyrightText: <text>Copyright 2023 Percepio AB</text>
PackageSummary: <text>Trace Recorder</text>
PackageDescription: <text>A generic software Trace Recorder that can generate trace events and transmit or store them.</text>

View File

@@ -0,0 +1,28 @@
TOPDIR=../../..
#lib or target you want to build: eg. LIB=libmisc.a or TARGET=wlan
LIB = libtrace.a
TARGET =
#libraries depend: eg. LIBS = -lbsp -ldrv -lrtos
LIBS =
ifeq ($(IC_BOARD), 0)
LIBS +=
else
LIBS +=
endif
#exclude subdirs
exclude_dirs=
#files want to build: eg. CSRCS=a.c CPPSRCS=b.cpp SSRCS=c.S
CSRCS = $(wildcard *.c) $(wildcard streamports/Jlink_RTT/*.c)
CPPSRCS =
SSRCS =
CFLAGS = -I ./include \
-I ./config \
-I ./streamports/Jlink_RTT/include \
-I ./streamports/Jlink_RTT/config
include $(TOPDIR)/rules.mk

View File

@@ -0,0 +1,5 @@
Trace Recorder source code for use with Percepio's Tracealyzer.
Read more at https://percepio.com/tracealyzer/ and https://percepio.com/gettingstarted.
Repository at https://github.com/percepio/TraceRecorderSource

View File

@@ -0,0 +1,327 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* Main configuration parameters for the trace recorder library.
* More settings can be found in trcStreamingConfig.h and trcSnapshotConfig.h.
*/
#ifndef TRC_CONFIG_H
#define TRC_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************************************
* Include of processor header file
*
* Here you may need to include the header file for your processor. This is
* required at least for the ARM Cortex-M port, that uses the ARM CMSIS API.
* Try that in case of build problems. Otherwise, remove the #error line below.
*****************************************************************************/
// #error "Trace Recorder: Please include your processor's header file here and remove this line."
// #include "nmsis_core.h"
/**
* @def TRC_CFG_HARDWARE_PORT
* @brief Specify what hardware port to use (i.e., the "timestamping driver").
*
* All ARM Cortex-M MCUs are supported by "TRC_HARDWARE_PORT_ARM_Cortex_M".
* This port uses the DWT cycle counter for Cortex-M3/M4/M7 devices, which is
* available on most such devices. In case your device don't have DWT support,
* you will get an error message opening the trace. In that case, you may
* force the recorder to use SysTick timestamping instead, using this define:
*
* #define TRC_CFG_ARM_CM_USE_SYSTICK
*
* For ARM Cortex-M0/M0+ devices, SysTick mode is used automatically.
*
* See trcHardwarePort.h for available ports and information on how to
* define your own port, if not already present.
*/
// #define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_HWIndependent
#define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_RISCV_RV32I
// #define TRC_CFG_ARM_CM_USE_SYSTICK
// #define TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING
/**
* @def TRC_CFG_SCHEDULING_ONLY
* @brief Macro which should be defined as an integer value.
*
* If this setting is enabled (= 1), only scheduling events are recorded.
* If disabled (= 0), all events are recorded (unless filtered in other ways).
*
* Default value is 0 (= include additional events).
*/
#define TRC_CFG_SCHEDULING_ONLY 0
/**
* @def TRC_CFG_INCLUDE_MEMMANG_EVENTS
* @brief Macro which should be defined as either zero (0) or one (1).
*
* This controls if malloc and free calls should be traced. Set this to zero (0)
* to exclude malloc/free calls, or one (1) to include such events in the trace.
*
* Default value is 1.
*/
#define TRC_CFG_INCLUDE_MEMMANG_EVENTS 1
/**
* @def TRC_CFG_INCLUDE_USER_EVENTS
* @brief Macro which should be defined as either zero (0) or one (1).
*
* If this is zero (0), all code related to User Events is excluded in order
* to reduce code size. Any attempts of storing User Events are then silently
* ignored.
*
* User Events are application-generated events, like "printf" but for the
* trace log, generated using vTracePrint and vTracePrintF.
* The formatting is done on host-side, by Tracealyzer. User Events are
* therefore much faster than a console printf and can often be used
* in timing critical code without problems.
*
* Note: In streaming mode, User Events are used to provide error messages
* and warnings from the recorder (in case of incorrect configuration) for
* display in Tracealyzer. Disabling user events will also disable these
* warnings. You can however still catch them by calling xTraceErrorGetLast
* or by putting breakpoints in xTraceError and xTraceWarning.
*
* Default value is 1.
*/
#define TRC_CFG_INCLUDE_USER_EVENTS 1
/**
* @def TRC_CFG_INCLUDE_ISR_TRACING
* @brief Macro which should be defined as either zero (0) or one (1).
*
* If this is zero (0), the code for recording Interrupt Service Routines is
* excluded, in order to reduce code size. This means that any calls to
* vTraceStoreISRBegin/vTraceStoreISREnd will be ignored.
* This does not completely disable ISR tracing, in cases where an ISR is
* calling a traced kernel service. These events will still be recorded and
* show up in anonymous ISR instances in Tracealyzer, with names such as
* "ISR sending to <queue name>".
* To disable such tracing, please refer to vTraceSetFilterGroup and
* vTraceSetFilterMask.
*
* Default value is 1.
*
* Note: tracing ISRs requires that you insert calls to vTraceStoreISRBegin
* and vTraceStoreISREnd in your interrupt handlers.
*/
#define TRC_CFG_INCLUDE_ISR_TRACING 1
/**
* @def TRC_CFG_INCLUDE_READY_EVENTS
* @brief Macro which should be defined as either zero (0) or one (1).
*
* If one (1), events are recorded when tasks enter scheduling state "ready".
* This allows Tracealyzer to show the initial pending time before tasks enter
* the execution state, and present accurate response times.
* If zero (0), "ready events" are not created, which allows for recording
* longer traces in the same amount of RAM.
*
* Default value is 1.
*/
#define TRC_CFG_INCLUDE_READY_EVENTS 1
/**
* @def TRC_CFG_INCLUDE_OSTICK_EVENTS
* @brief Macro which should be defined as either zero (0) or one (1).
*
* If this is one (1), events will be generated whenever the OS clock is
* increased. If zero (0), OS tick events are not generated, which allows for
* recording longer traces in the same amount of RAM.
*
* Default value is 1.
*/
#define TRC_CFG_INCLUDE_OSTICK_EVENTS 1
/**
* @def TRC_CFG_ENABLE_STACK_MONITOR
* @brief If enabled (1), the recorder periodically reports the unused stack space of
* all active tasks.
* The stack monitoring runs in the Tracealyzer Control task, TzCtrl. This task
* is always created by the recorder when in streaming mode.
* In snapshot mode, the TzCtrl task is only used for stack monitoring and is
* not created unless this is enabled.
*/
#define TRC_CFG_ENABLE_STACK_MONITOR 0
/**
* @def TRC_CFG_STACK_MONITOR_MAX_TASKS
* @brief Macro which should be defined as a non-zero integer value.
*
* This controls how many tasks that can be monitored by the stack monitor.
* If this is too small, some tasks will be excluded and a warning is shown.
*
* Default value is 10.
*/
#define TRC_CFG_STACK_MONITOR_MAX_TASKS 10
/**
* @def TRC_CFG_STACK_MONITOR_MAX_REPORTS
* @brief Macro which should be defined as a non-zero integer value.
*
* This defines how many tasks that will be subject to stack usage analysis for
* each execution of the Tracealyzer Control task (TzCtrl). Note that the stack
* monitoring cycles between the tasks, so this does not affect WHICH tasks that
* are monitored, but HOW OFTEN each task stack is analyzed.
*
* This setting can be combined with TRC_CFG_CTRL_TASK_DELAY to tune the
* frequency of the stack monitoring. This is motivated since the stack analysis
* can take some time to execute.
* However, note that the stack analysis runs in a separate task (TzCtrl) that
* can be executed on low priority. This way, you can avoid that the stack
* analysis disturbs any time-sensitive tasks.
*
* Default value is 1.
*/
#define TRC_CFG_STACK_MONITOR_MAX_REPORTS 1
/**
* @def TRC_CFG_CTRL_TASK_PRIORITY
* @brief The scheduling priority of the Tracealyzer Control (TzCtrl) task.
*
* In streaming mode, TzCtrl is used to receive start/stop commands from
* Tracealyzer and in some cases also to transmit the trace data (for stream
* ports that uses the internal buffer, like TCP/IP). For such stream ports,
* make sure the TzCtrl priority is high enough to ensure reliable periodic
* execution and transfer of the data, but low enough to avoid disturbing any
* time-sensitive functions.
*
* In Snapshot mode, TzCtrl is only used for the stack usage monitoring and is
* not created if stack monitoring is disabled. TRC_CFG_CTRL_TASK_PRIORITY should
* be low, to avoid disturbing any time-sensitive tasks.
*/
#define TRC_CFG_CTRL_TASK_PRIORITY 1
/**
* @def TRC_CFG_CTRL_TASK_DELAY
* @brief The delay between loops of the TzCtrl task (see TRC_CFG_CTRL_TASK_PRIORITY),
* which affects the frequency of the stack monitoring.
*
* In streaming mode, this also affects the trace data transfer if you are using
* a stream port leveraging the internal buffer (like TCP/IP). A shorter delay
* increases the CPU load of TzCtrl somewhat, but may improve the performance of
* of the trace streaming, especially if the trace buffer is small.
*
* The unit depends on the delay function used for the specific kernel port (trcKernelPort.c).
* For example, FreeRTOS uses ticks while Zephyr uses ms.
*/
#define TRC_CFG_CTRL_TASK_DELAY 10
/**
* @def TRC_CFG_CTRL_TASK_STACK_SIZE
* @brief The stack size of the Tracealyzer Control (TzCtrl) task.
* See TRC_CFG_CTRL_TASK_PRIORITY for further information about TzCtrl.
*/
#define TRC_CFG_CTRL_TASK_STACK_SIZE 1024
/**
* @def TRC_CFG_RECORDER_BUFFER_ALLOCATION
* @brief Specifies how the recorder buffer is allocated (also in case of streaming, in
* port using the recorder's internal temporary buffer)
*
* Values:
* TRC_RECORDER_BUFFER_ALLOCATION_STATIC - Static allocation (internal)
* TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC - Malloc in vTraceEnable
* TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM - Use vTraceSetRecorderDataBuffer
*
* Static and dynamic mode does the allocation for you, either in compile time
* (static) or in runtime (malloc).
* The custom mode allows you to control how and where the allocation is made,
* for details see TRC_ALLOC_CUSTOM_BUFFER and vTraceSetRecorderDataBuffer().
*/
#define TRC_CFG_RECORDER_BUFFER_ALLOCATION TRC_RECORDER_BUFFER_ALLOCATION_STATIC
/**
* @def TRC_CFG_MAX_ISR_NESTING
* @brief Defines how many levels of interrupt nesting the recorder can handle, in
* case multiple ISRs are traced and ISR nesting is possible. If this
* is exceeded, the particular ISR will not be traced and the recorder then
* logs an error message. This setting is used to allocate an internal stack
* for keeping track of the previous execution context (4 byte per entry).
*
* This value must be a non-zero positive constant, at least 1.
*
* Default value: 8
*/
#define TRC_CFG_MAX_ISR_NESTING 8
/**
* @def TRC_CFG_ISR_TAILCHAINING_THRESHOLD
* @brief Macro which should be defined as an integer value.
*
* If tracing multiple ISRs, this setting allows for accurate display of the
* context-switching also in cases when the ISRs execute in direct sequence.
*
* vTraceStoreISREnd normally assumes that the ISR returns to the previous
* context, i.e., a task or a preempted ISR. But if another traced ISR
* executes in direct sequence, Tracealyzer may incorrectly display a minimal
* fragment of the previous context in between the ISRs.
*
* By using TRC_CFG_ISR_TAILCHAINING_THRESHOLD you can avoid this. This is
* however a threshold value that must be measured for your specific setup.
* See http://percepio.com/2014/03/21/isr_tailchaining_threshold/
*
* The default setting is 0, meaning "disabled" and that you may get an
* extra fragments of the previous context in between tail-chained ISRs.
*
* Note: This setting has separate definitions in trcSnapshotConfig.h and
* trcStreamingConfig.h, since it is affected by the recorder mode.
*/
#define TRC_CFG_ISR_TAILCHAINING_THRESHOLD 0
/**
* @def TRC_CFG_RECORDER_DATA_INIT
* @brief Macro which states wether the recorder data should have an initial value.
*
* In very specific cases where traced objects are created before main(),
* the recorder will need to be started even before that. In these cases,
* the recorder data would be initialized by vTraceEnable(TRC_INIT) but could
* then later be overwritten by the initialization value.
* If this is an issue for you, set TRC_CFG_RECORDER_DATA_INIT to 0.
* The following code can then be used before any traced objects are created:
*
* extern uint32_t RecorderInitialized;
* RecorderInitialized = 0;
* xTraceInitialize();
*
* After the clocks are properly initialized, use vTraceEnable(...) to start
* the tracing.
*
* Default value is 1.
*/
#define TRC_CFG_RECORDER_DATA_INIT 1
/**
* @def TRC_CFG_RECORDER_DATA_ATTRIBUTE
* @brief When setting TRC_CFG_RECORDER_DATA_INIT to 0, you might also need to make
* sure certain recorder data is placed in a specific RAM section to avoid being
* zeroed out after initialization. Define TRC_CFG_RECORDER_DATA_ATTRIBUTE as
* that attribute.
*
* Example:
* #define TRC_CFG_RECORDER_DATA_ATTRIBUTE __attribute__((section(".bss.trace_recorder_data")))
*
* Default value is empty.
*/
#define TRC_CFG_RECORDER_DATA_ATTRIBUTE
/**
* @def TRC_CFG_USE_TRACE_ASSERT
* @brief Enable or disable debug asserts. Information regarding any assert that is
* triggered will be in trcAssert.c.
*/
#define TRC_CFG_USE_TRACE_ASSERT 0
#ifdef __cplusplus
}
#endif
#endif /* _TRC_CONFIG_H */

View File

@@ -0,0 +1,120 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* Configuration parameters for the kernel port.
* More settings can be found in trcKernelPortStreamingConfig.h and
* trcKernelPortSnapshotConfig.h.
*/
#ifndef TRC_KERNEL_PORT_CONFIG_H
#define TRC_KERNEL_PORT_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @def TRC_CFG_RECORDER_MODE
* @brief Specify what recording mode to use. Snapshot means that the data is saved in
* an internal RAM buffer, for later upload. Streaming means that the data is
* transferred continuously to the host PC.
*
* For more information, see http://percepio.com/2016/10/05/rtos-tracing/
* and the Tracealyzer User Manual.
*
* Values:
* TRC_RECORDER_MODE_SNAPSHOT
* TRC_RECORDER_MODE_STREAMING
*/
#define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_STREAMING
/**
* @def TRC_CFG_FREERTOS_VERSION
* @brief Specify what version of FreeRTOS that is used (don't change unless using the
* trace recorder library with an older version of FreeRTOS).
*
* TRC_FREERTOS_VERSION_7_3_X If using FreeRTOS v7.3.X
* TRC_FREERTOS_VERSION_7_4_X If using FreeRTOS v7.4.X
* TRC_FREERTOS_VERSION_7_5_X If using FreeRTOS v7.5.X
* TRC_FREERTOS_VERSION_7_6_X If using FreeRTOS v7.6.X
* TRC_FREERTOS_VERSION_8_X_X If using FreeRTOS v8.X.X
* TRC_FREERTOS_VERSION_9_0_0 If using FreeRTOS v9.0.0
* TRC_FREERTOS_VERSION_9_0_1 If using FreeRTOS v9.0.1
* TRC_FREERTOS_VERSION_9_0_2 If using FreeRTOS v9.0.2
* TRC_FREERTOS_VERSION_10_0_0 If using FreeRTOS v10.0.0
* TRC_FREERTOS_VERSION_10_0_1 If using FreeRTOS v10.0.1
* TRC_FREERTOS_VERSION_10_1_0 If using FreeRTOS v10.1.0
* TRC_FREERTOS_VERSION_10_1_1 If using FreeRTOS v10.1.1
* TRC_FREERTOS_VERSION_10_2_0 If using FreeRTOS v10.2.0
* TRC_FREERTOS_VERSION_10_2_1 If using FreeRTOS v10.2.1
* TRC_FREERTOS_VERSION_10_3_0 If using FreeRTOS v10.3.0
* TRC_FREERTOS_VERSION_10_3_1 If using FreeRTOS v10.3.1
* TRC_FREERTOS_VERSION_10_4_0 If using FreeRTOS v10.4.0
* TRC_FREERTOS_VERSION_10_4_1 If using FreeRTOS v10.4.1
* TRC_FREERTOS_VERSION_10_4_2 If using FreeRTOS v10.4.2
* TRC_FREERTOS_VERSION_10_4_3 If using FreeRTOS v10.4.3
* TRC_FREERTOS_VERSION_10_5_0 If using FreeRTOS v10.5.0
* TRC_FREERTOS_VERSION_10_5_1 If using FreeRTOS v10.5.1 or later
*/
#define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_3_1
/**
* @def TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS
* @brief Macro which should be defined as either zero (0) or one (1).
*
* If this is zero (0), the trace will exclude any "event group" events.
*
* Default value is 0 (excluded) since dependent on event_groups.c
*/
#define TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS 0
/**
* @def TRC_CFG_INCLUDE_TIMER_EVENTS
* @brief Macro which should be defined as either zero (0) or one (1).
*
* If this is zero (0), the trace will exclude any Timer events.
*
* Default value is 0 since dependent on timers.c
*/
#define TRC_CFG_INCLUDE_TIMER_EVENTS 0
/**
* @def TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS
* @brief Macro which should be defined as either zero (0) or one (1).
*
* If this is zero (0), the trace will exclude any "pending function call"
* events, such as xTimerPendFunctionCall().
*
* Default value is 0 since dependent on timers.c
*/
#define TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS 0
/**
* @def TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS
* @brief Macro which should be defined as either zero (0) or one (1).
*
* If this is zero (0), the trace will exclude any stream buffer or message
* buffer events.
*
* Default value is 0 since dependent on stream_buffer.c (new in FreeRTOS v10)
*/
#define TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS 0
/**
* @def TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND
* @brief When using FreeRTOS v10.3.0 or v10.3.1, please make sure that the trace
* point in prvNotifyQueueSetContainer() in queue.c is renamed from
* traceQUEUE_SEND to traceQUEUE_SET_SEND in order to tell them apart from
* other traceQUEUE_SEND trace points. Then set this to TRC_ACKNOWLEDGED.
*/
#define TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND 0 /* TRC_ACKNOWLEDGED */
#ifdef __cplusplus
}
#endif
#endif /* TRC_KERNEL_PORT_CONFIG_H */

View File

@@ -0,0 +1,69 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* Kernel port configuration parameters for snapshot mode.
*/
#ifndef TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H
#define TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @def TRC_CFG_NTASK, TRC_CFG_NISR, TRC_CFG_NQUEUE, TRC_CFG_NSEMAPHORE...
* @brief A group of macros which should be defined as integer values, zero or larger.
*
* These define the capacity of the Object Property Table, i.e., the maximum
* number of objects active at any given point, within each object class (e.g.,
* task, queue, semaphore, ...).
*
* If tasks or other objects are deleted in your system, this
* setting does not limit the total amount of objects created, only the number
* of objects that have been successfully created but not yet deleted.
*
* Using too small values will cause vTraceError to be called, which stores an
* error message in the trace that is shown when opening the trace file. The
* error message can also be retrieved using xTraceGetLastError.
*
* It can be wise to start with large values for these constants,
* unless you are very confident on these numbers. Then do a recording and
* check the actual usage by selecting View menu -> Trace Details ->
* Resource Usage -> Object Table.
*/
#define TRC_CFG_NTASK 15
#define TRC_CFG_NISR 5
#define TRC_CFG_NQUEUE 10
#define TRC_CFG_NSEMAPHORE 10
#define TRC_CFG_NMUTEX 10
#define TRC_CFG_NTIMER 5
#define TRC_CFG_NEVENTGROUP 5
#define TRC_CFG_NSTREAMBUFFER 5
#define TRC_CFG_NMESSAGEBUFFER 5
/**
* @def TRC_CFG_NAME_LEN_TASK, TRC_CFG_NAME_LEN_QUEUE, ...
* @brief Macros that specify the maximum lengths (number of characters) for names of
* kernel objects, such as tasks and queues. If longer names are used, they will
* be truncated when stored in the recorder.
*/
#define TRC_CFG_NAME_LEN_TASK 15
#define TRC_CFG_NAME_LEN_ISR 15
#define TRC_CFG_NAME_LEN_QUEUE 15
#define TRC_CFG_NAME_LEN_SEMAPHORE 15
#define TRC_CFG_NAME_LEN_MUTEX 15
#define TRC_CFG_NAME_LEN_TIMER 15
#define TRC_CFG_NAME_LEN_EVENTGROUP 15
#define TRC_CFG_NAME_LEN_STREAMBUFFER 15
#define TRC_CFG_NAME_LEN_MESSAGEBUFFER 15
#ifdef __cplusplus
}
#endif
#endif /* TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H */

View File

@@ -0,0 +1,24 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* Kernel port configuration parameters for streaming mode.
*/
#ifndef TRC_KERNEL_PORT_STREAMING_CONFIG_H
#define TRC_KERNEL_PORT_STREAMING_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
/* Nothing yet */
#ifdef __cplusplus
}
#endif
#endif /* TRC_KERNEL_PORT_STREAMING_CONFIG_H */

View File

@@ -0,0 +1,245 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* Configuration parameters for trace recorder library in snapshot mode.
* Read more at http://percepio.com/2016/10/05/rtos-tracing/
*/
#ifndef TRC_SNAPSHOT_CONFIG_H
#define TRC_SNAPSHOT_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @def TRC_CFG_SNAPSHOT_MODE
* @brief Macro which should be defined as one of:
* - TRC_SNAPSHOT_MODE_RING_BUFFER
* - TRC_SNAPSHOT_MODE_STOP_WHEN_FULL
* Default is TRC_SNAPSHOT_MODE_RING_BUFFER.
*
* With TRC_CFG_SNAPSHOT_MODE set to TRC_SNAPSHOT_MODE_RING_BUFFER, the
* events are stored in a ring buffer, i.e., where the oldest events are
* overwritten when the buffer becomes full. This allows you to get the last
* events leading up to an interesting state, e.g., an error, without having
* to store the whole run since startup.
*
* When TRC_CFG_SNAPSHOT_MODE is TRC_SNAPSHOT_MODE_STOP_WHEN_FULL, the
* recording is stopped when the buffer becomes full. This is useful for
* recording events following a specific state, e.g., the startup sequence.
*/
#define TRC_CFG_SNAPSHOT_MODE TRC_SNAPSHOT_MODE_RING_BUFFER
/**
* @def TRC_CFG_EVENT_BUFFER_SIZE
* @brief Macro which should be defined as an integer value.
*
* This defines the capacity of the event buffer, i.e., the number of records
* it may store. Most events use one record (4 byte), although some events
* require multiple 4-byte records. You should adjust this to the amount of RAM
* available in the target system.
*
* Default value is 1000, which means that 4000 bytes is allocated for the
* event buffer.
*/
#define TRC_CFG_EVENT_BUFFER_SIZE 1000
/**
* @def TRC_CFG_INCLUDE_FLOAT_SUPPORT
* @brief Macro which should be defined as either zero (0) or one (1).
*
* If this is zero (0), the support for logging floating point values in
* vTracePrintF is stripped out, in case floating point values are not used or
* supported by the platform used.
*
* Floating point values are only used in vTracePrintF and its subroutines, to
* allow for storing float (%f) or double (%lf) arguments.
*
* vTracePrintF can be used with integer and string arguments in either case.
*
* Default value is 0.
*/
#define TRC_CFG_INCLUDE_FLOAT_SUPPORT 0
/**
* @def TRC_CFG_SYMBOL_TABLE_SIZE
* @brief Macro which should be defined as an integer value.
*
* This defines the capacity of the symbol table, in bytes. This symbol table
* stores User Events labels and names of deleted tasks, queues, or other kernel
* objects. If you don't use User Events or delete any kernel
* objects you set this to a very low value. The minimum recommended value is 4.
* A size of zero (0) is not allowed since a zero-sized array may result in a
* 32-bit pointer, i.e., using 4 bytes rather than 0.
*
* Default value is 800.
*/
#define TRC_CFG_SYMBOL_TABLE_SIZE 800
#if (TRC_CFG_SYMBOL_TABLE_SIZE == 0)
#error "TRC_CFG_SYMBOL_TABLE_SIZE may not be zero!"
#endif
/******************************************************************************
*** ADVANCED SETTINGS ********************************************************
******************************************************************************
* The remaining settings are not necessary to modify but allows for optimizing
* the recorder setup for your specific needs, e.g., to exclude events that you
* are not interested in, in order to get longer traces.
*****************************************************************************/
/**
* @def TRC_CFG_HEAP_SIZE_BELOW_16M
* @brief An integer constant that can be used to reduce the buffer usage of memory
* allocation events (malloc/free). This value should be 1 if the heap size is
* below 16 MB (2^24 byte), and you can live with reported addresses showing the
* lower 24 bits only. If 0, you get the full 32-bit addresses.
*
* Default value is 0.
*/
#define TRC_CFG_HEAP_SIZE_BELOW_16M 0
/**
* @def TRC_CFG_USE_IMPLICIT_IFE_RULES
* @brief Macro which should be defined as either zero (0) or one (1).
* Default is 1.
*
* Tracealyzer groups the events into "instances" based on Instance Finish
* Events (IFEs), produced either by default rules or calls to the recorder
* functions xTraceTaskInstanceFinishedNow and xTraceTaskInstanceFinishedNext.
*
* If TRC_CFG_USE_IMPLICIT_IFE_RULES is one (1), the default IFE rules is
* used, resulting in a "typical" grouping of events into instances.
* If these rules don't give appropriate instances in your case, you can
* override the default rules using xTraceTaskInstanceFinishedNow/Next for one
* or several tasks. The default IFE rules are then disabled for those tasks.
*
* If TRC_CFG_USE_IMPLICIT_IFE_RULES is zero (0), the implicit IFE rules are
* disabled globally. You must then call xTraceTaskInstanceFinishedNow or
* xTraceTaskInstanceFinishedNext to manually group the events into instances,
* otherwise the tasks will appear a single long instance.
*
* The default IFE rules count the following events as "instance finished":
* - Task delay, delay until
* - Task suspend
* - Blocking on "input" operations, i.e., when the task is waiting for the
* next a message/signal/event. But only if this event is blocking.
*/
#define TRC_CFG_USE_IMPLICIT_IFE_RULES 1
/**
* @def TRC_CFG_USE_16BIT_OBJECT_HANDLES
* @brief Macro which should be defined as either zero (0) or one (1).
*
* If set to 0 (zero), the recorder uses 8-bit handles to identify kernel
* objects such as tasks and queues. This limits the supported number of
* concurrently active objects to 255 of each type (tasks, queues, mutexes,
* etc.) Note: 255, not 256, since handle 0 is reserved.
*
* If set to 1 (one), the recorder uses 16-bit handles to identify kernel
* objects such as tasks and queues. This limits the supported number of
* concurrent objects to 65535 of each type (object class). However, since the
* object property table is limited to 64 KB, the practical limit is about
* 3000 objects in total.
*
* Default is 0 (8-bit handles)
*
* NOTE: An object with handle above 255 will use an extra 4-byte record in
* the event buffer whenever the object is referenced. Moreover, some internal
* tables in the recorder gets slightly larger when using 16-bit handles.
*/
#define TRC_CFG_USE_16BIT_OBJECT_HANDLES 0
/**
* @def TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER
* @brief Macro which should be defined as an integer value.
*
* Set TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER to 1 to enable the
* separate user event buffer (UB).
* In this mode, user events are stored separately from other events,
* e.g., RTOS events. Thereby you can get a much longer history of
* user events as they don't need to share the buffer space with more
* frequent events.
*
* The UB is typically used with the snapshot ring-buffer mode, so the
* recording can continue when the main buffer gets full. And since the
* main buffer then overwrites the earliest events, Tracealyzer displays
* "Unknown Actor" instead of task scheduling for periods with UB data only.
*
* In UB mode, user events are structured as UB channels, which contains
* a channel name and a default format string. Register a UB channel using
* xTraceRegisterUBChannel.
*
* Events and data arguments are written using vTraceUBEvent and
* vTraceUBData. They are designed to provide efficient logging of
* repeating events, using the same format string within each channel.
*
* Examples:
* TraceStringHandle_t chn1;
* TraceStringHandle_t fmt1;
* xTraceStringRegister("Channel 1", &chn1);
* xTraceStringRegister("Event!", &fmt1);
* traceUBChannel UBCh1 = xTraceRegisterUBChannel(chn1, fmt1);
*
* TraceStringHandle_t chn2;
* TraceStringHandle_t fmt2;
* xTraceStringRegister("Channel 2", &chn2);
* xTraceStringRegister("X: %d, Y: %d", &fmt2);
* traceUBChannel UBCh2 = xTraceRegisterUBChannel(chn2, fmt2);
*
* // Result in "[Channel 1] Event!"
* vTraceUBEvent(UBCh1);
*
* // Result in "[Channel 2] X: 23, Y: 19"
* vTraceUBData(UBCh2, 23, 19);
*
* You can also use the other user event functions, like xTracePrintF.
* as they are then rerouted to the UB instead of the main event buffer.
* vTracePrintF then looks up the correct UB channel based on the
* provided channel name and format string, or creates a new UB channel
* if no match is found. The format string should therefore not contain
* "random" messages but mainly format specifiers. Random strings should
* be stored using %s and with the string as an argument.
*
* // Creates a new UB channel ("Channel 2", "%Z: %d")
* xTracePrintF(chn2, "%Z: %d", value1);
*
* // Finds the existing UB channel
* xTracePrintF(chn2, "%Z: %d", value2);
*/
#define TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER 0
/**
* @def TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE
* @brief Macro which should be defined as an integer value.
*
* This defines the capacity of the user event buffer (UB), in number of slots.
* A single user event can use multiple slots, depending on the arguments.
*
* Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1.
*/
#define TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE 200
/**
* @def TRC_CFG_UB_CHANNELS
* @brief Macro which should be defined as an integer value.
*
* This defines the number of User Event Buffer Channels (UB channels).
* These are used to structure the events when using the separate user
* event buffer, and contains both a User Event Channel (the name) and
* a default format string for the channel.
*
* Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1.
*/
#define TRC_CFG_UB_CHANNELS 32
#ifdef __cplusplus
}
#endif
#endif /*TRC_SNAPSHOT_CONFIG_H*/

View File

@@ -0,0 +1,51 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* Configuration parameters for the trace recorder library in streaming mode.
* Read more at http://percepio.com/2016/10/05/rtos-tracing/
*/
#ifndef TRC_STREAMING_CONFIG_H
#define TRC_STREAMING_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @def TRC_CFG_ENTRY_SLOTS
* @brief The maximum number of objects and symbols that can be stored. This includes:
* - Task names
* - Named ISRs (vTraceSetISRProperties)
* - Named kernel objects (vTraceStoreKernelObjectName)
* - User event channels (xTraceStringRegister)
*
* If this value is too small, not all symbol names will be stored and the
* trace display will be affected. In that case, there will be warnings
* (as User Events) from TzCtrl task, that monitors this.
*/
#define TRC_CFG_ENTRY_SLOTS 50
/**
* @def TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH
* @brief The maximum length of symbol names, including:
* - Task names
* - Named ISRs (vTraceSetISRProperties)
* - Named kernel objects (vTraceStoreKernelObjectName)
* - User event channel names (xTraceStringRegister)
*
* If longer symbol names are used, they will be truncated by the recorder,
* which will affect the trace display. In that case, there will be warnings
* (as User Events) from TzCtrl task, that monitors this.
*/
#define TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH 28
#ifdef __cplusplus
}
#endif
#endif /* TRC_STREAMING_CONFIG_H */

View File

@@ -0,0 +1,142 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace assert APIs.
*/
#ifndef TRC_ASSERT_H
#define TRC_ASSERT_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup trace_assert_apis Trace Asserts APIs
* @ingroup trace_recorder_apis
* @{
*/
#ifndef TRC_CFG_USE_TRACE_ASSERT
#error "TRC_CFG_USE_TRACE_ASSERT is not defined. Please define it in trcConfig.h"
#endif
#if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
/* Standard assert */
#define TRC_ASSERT(__condition) if (!(__condition)) { prvTraceAssertCreate(__FILE__, __LINE__); return TRC_FAIL; }
#define TRC_ASSERT_ALWAYS_EVALUATE TRC_ASSERT
/* Standard assert with custom on fail actions */
#define TRC_ASSERT_CUSTOM_ON_FAIL(__condition, __custom_on_fail) if (!(__condition)) { prvTraceAssertCreate(__FILE__, __LINE__); __custom_on_fail; }
#define TRC_ASSERT_CUSTOM_ON_FAIL_ALWAYS_EVALUATE TRC_ASSERT_CUSTOM_ON_FAIL
#if (defined(TRC_CFG_TEST_MODE) && (TRC_CFG_TEST_MODE) == 1)
/* Asserts that two types have an equal size. Condition passed to function to avoid compilers warning about unreachable code due to constant value. */
#define TRC_ASSERT_EQUAL_SIZE(x, y) if (!prvTraceAssertCheckCondition((TraceBaseType_t)(sizeof(x) == sizeof(y)))) { prvTraceAssertCreate(__FILE__, __LINE__); return TRC_FAIL; }
/**
* @brief Inlined condition check to get around some compiler warnings for unused variables.
*
* @param[in] condition The condition
*/
inline TraceBaseType_t prvTraceAssertCheckCondition(TraceBaseType_t condition)
{
return condition;
}
#else
#define TRC_ASSERT_EQUAL_SIZE(x, y)
#endif
typedef struct TraceAssertData /* Aligned */
{
TraceEntryHandle_t xEntry;
} TraceAssertData_t;
/**
* @internal Initializes assert system
*
* @param[in] pxBuffer The assert data buffer
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceAssertInitialize(TraceAssertData_t *pxBuffer);
/**
* @internal Creates an assert
*
* @param[in] szFilePath File name
* @param[in] uxLineNumber Line number
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
void prvTraceAssertCreate(const char* szFilePath, TraceUnsignedBaseType_t uxLineNumber);
/**
* @brief Retrieves the assert and line number
*
* @param[out] pxFileNameStringHandle File name string handle
* @param[out] puxLineNumber Line number
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceAssertGet(TraceStringHandle_t* pxFileNameStringHandle, TraceUnsignedBaseType_t* puxLineNumber);
#else /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
#define TRC_ASSERT(__condition)
#define TRC_ASSERT_ALWAYS_EVALUATE(__condition) (void)(__condition)
#define TRC_ASSERT_CUSTOM_ON_FAIL(__condition, __custom_on_fail)
#define TRC_ASSERT_CUSTOM_ON_FAIL_ALWAYS_EVALUATE(__condition, __custom_on_fail) (__condition)
#define TRC_ASSERT_EQUAL_SIZE(x, y)
typedef struct TraceAssertData
{
TraceUnsignedBaseType_t buffer[1];
} TraceAssertData_t;
#define xTraceAssertInitialize(pxBuffer) ((void)pxBuffer, TRC_SUCCESS)
#define xTraceAssertGet(pxFileNameStringHandle, puxLineNumber) ((void)pxFileNameStringHandle, (void)puxLineNumber, TRC_FAIL)
#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
#endif /* TRC_ASSERT_H */

View File

@@ -0,0 +1,225 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace counter APIs.
*/
#ifndef TRC_COUNTER_H
#define TRC_COUNTER_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#define TRC_COUNTER_VALUE_INDEX 0
#define TRC_COUNTER_LOWER_LIMIT_INDEX 1
#define TRC_COUNTER_UPPER_LIMIT_INDEX 2
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup trace_counter_apis Trace Counter APIs
* @ingroup trace_recorder_apis
* @{
*/
typedef struct TraceCounterData /* Aligned */
{
TraceCounterCallback_t xCallbackFunction;
} TraceCounterData_t;
/**
* @brief Initializes the Counter trace system
*
* @param[in] pxBuffer Pointer to memory that is used by the counter system
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceCounterInitialize(TraceCounterData_t *pxBuffer);
/**
* @brief Sets trace counter callback.
*
* @param[in] xCallback Callback
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceCounterSetCallback(TraceCounterCallback_t xCallback);
/**
* @brief Creates trace counter.
*
* @param[in] szName Name.
* @param[in] xInitialValue Initial value.
* @param[in] xLowerLimit Lower limit.
* @param[in] xUpperLimit Upper limit.
* @param[out] pxCounterHandle Uninitialized trace counter handle.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceCounterCreate(const char* szName, TraceBaseType_t xInitialValue, TraceBaseType_t xLowerLimit, TraceBaseType_t xUpperLimit, TraceCounterHandle_t* pxCounterHandle);
/**
* @brief Adds value to trace counter.
*
* @param[in] xCounterHandle Initialized trace counter handle.
* @param[in] xValue Value.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceCounterAdd(xCounterHandle, xValue) xTraceCounterSet(xCounterHandle, (TraceBaseType_t)(xTraceEntryGetStateReturn((TraceEntryHandle_t)(xCounterHandle), TRC_COUNTER_VALUE_INDEX)) + (xValue))
/**
* @brief Sets trace counter value.
*
* @param[in] xCounterHandle Initialized trace counter handle.
* @param[in] xValue Value.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceCounterSet(TraceCounterHandle_t xCounterHandle, TraceBaseType_t xValue);
/**
* @brief Gets trace counter value.
*
* @param[in] xCounterHandle Initialized trace counter handle.
* @param[out] pxValue Returned value.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceCounterGet(xCounterHandle, pxValue) xTraceEntryGetState((TraceEntryHandle_t)(xCounterHandle), TRC_COUNTER_VALUE_INDEX, (TraceUnsignedBaseType_t*)(pxValue))
/**
* @brief Increases trace counter value.
*
* @param[in] xCounterHandle Initialized trace counter handle
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceCounterIncrease(xCounterHandle) xTraceCounterAdd(xCounterHandle, 1)
/**
* @brief Decreases trace counter value.
*
* @param[in] xCounterHandle Initialized trace counter handle
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceCounterDecrease(xCounterHandle) xTraceCounterAdd(xCounterHandle, -1)
/**
* @brief Gets trace counter upper limit.
*
* @param[in] xCounterHandle Initialized trace counter handle
* @param[out] pxValue Returned value
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceCounterGetUpperLimit(xCounterHandle, pxValue) xTraceEntryGetState((TraceEntryHandle_t)(xCounterHandle), TRC_COUNTER_UPPER_LIMIT_INDEX, (TraceUnsignedBaseType_t*)(pxValue))
/**
* @brief Gets trace counter lower limit.
*
* @param[in] xCounterHandle Initialized trace counter handle
* @param[out] pxValue Returned value
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceCounterGetLowerLimit(xCounterHandle, pxValue) xTraceEntryGetState((TraceEntryHandle_t)(xCounterHandle), TRC_COUNTER_LOWER_LIMIT_INDEX, (TraceUnsignedBaseType_t*)(pxValue))
/**
* @brief Gets trace counter name.
*
* @param[in] xCounterHandle Initialized trace counter handle.
* @param[out] pszName Returned name.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceCounterGetName(xCounterHandle, pszName) xTraceEntryGetSymbol((TraceEntryHandle_t)(xCounterHandle), pszName)
/** @} */
#ifdef __cplusplus
}
#endif
#else
/**
* @brief Disabled by TRC_CFG_RECORDER_MODE
*/
#define xTraceCounterSetCallback(__xCallback) ((void)(__xCallback), TRC_SUCCESS)
/**
* @brief Disabled by TRC_CFG_RECORDER_MODE
*/
#define xTraceCounterCreate(__szName, __xInitialValue, __xLowerLimit, __xUpperLimit, __pxCounterHandle) ((void)(__szName), (void)(__xInitialValue), (void)(__xLowerLimit), (void)(__xUpperLimit), *(__pxCounterHandle) = 0, TRC_SUCCESS)
/**
* @brief Disabled by TRC_CFG_RECORDER_MODE
*/
#define xTraceCounterAdd(__xCounterHandle, __xValue) ((void)(__xCounterHandle), (void)(__xValue), TRC_SUCCESS)
/**
* @brief Disabled by TRC_CFG_RECORDER_MODE
*/
#define xTraceCounterSet(__xCounterHandle, __xValue) ((void)(__xCounterHandle), (void)(__xValue), TRC_SUCCESS)
/**
* @brief Disabled by TRC_CFG_RECORDER_MODE
*/
#define xTraceCounterGet(__xCounterHandle, __pxValue) ((void)(__xCounterHandle), *(__pxValue) = 0, TRC_SUCCESS)
/**
* @brief Disabled by TRC_CFG_RECORDER_MODE
*/
#define xTraceCounterIncrease(__xCounterHandle) ((void)(__xCounterHandle), TRC_SUCCESS)
/**
* @brief Disabled by TRC_CFG_RECORDER_MODE
*/
#define xTraceCounterDecrease(__xCounterHandle) ((void)(__xCounterHandle), TRC_SUCCESS)
/**
* @brief Disabled by TRC_CFG_RECORDER_MODE
*/
#define xTraceCounterGetUpperLimit(__xCounterHandle, __pxValue) ((void)(__xCounterHandle), *(__pxValue) = 0, TRC_SUCCESS)
/**
* @brief Disabled by TRC_CFG_RECORDER_MODE
*/
#define xTraceCounterGetLowerLimit(__xCounterHandle, __pxValue) ((void)(__xCounterHandle), *(__pxValue) = 0, TRC_SUCCESS)
/**
* @brief Disabled by TRC_CFG_RECORDER_MODE
*/
#define xTraceCounterGetName(__xCounterHandle, __pszName) ((void)(__xCounterHandle), *(__pszName) = "N/A", TRC_SUCCESS)
#endif
#endif
#endif

View File

@@ -0,0 +1,202 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* Some common defines for the trace recorder.
*/
#ifndef TRC_DEFINES_H
#define TRC_DEFINES_H
#define TRC_SUCCESS ((traceResult)0)
#define TRC_FAIL ((traceResult)1)
#define TRC_FREE_RUNNING_32BIT_INCR 1
#define TRC_FREE_RUNNING_32BIT_DECR 2
#define TRC_OS_TIMER_INCR 3
#define TRC_OS_TIMER_DECR 4
#define TRC_CUSTOM_TIMER_INCR 5
#define TRC_CUSTOM_TIMER_DECR 6
#define TRC_STATE_IN_STARTUP 0
#define TRC_STATE_IN_TASKSWITCH 1
#define TRC_STATE_IN_APPLICATION 2
/* Start options for vTraceEnable. */
#define TRC_START_FROM_HOST 0UL
#define TRC_START 1UL
#define TRC_START_AWAIT_HOST 2UL
#define TRC_ACKNOWLEDGED (0xABC99123)
/* Command codes for TzCtrl task */
#define CMD_SET_ACTIVE 1 /* Start (param1 = 1) or Stop (param1 = 0) */
/* The final command code, used to validate commands. */
#define CMD_LAST_COMMAND 1
#define TRC_RECORDER_MODE_SNAPSHOT 0
#define TRC_RECORDER_MODE_STREAMING 1
#define TRC_SNAPSHOT_MODE_RING_BUFFER (0x01UL)
#define TRC_SNAPSHOT_MODE_STOP_WHEN_FULL (0x02UL)
#define TRC_RECORDER_BUFFER_ALLOCATION_STATIC (0x00UL)
#define TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC (0x01UL)
#define TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM (0x02UL)
#define TRC_OPTION_BIT_SHIFT_IRQ_ORDER 0
#define TRC_OPTION_BIT_SHIFT_BASE_SIZE 8
/******************************************************************************/
/*** ERROR AND WARNING CODES (check using xTraceErrorGetLast) *****************/
/******************************************************************************/
#define TRC_ERROR_NONE 0x00UL
#define TRC_ERROR_ASSERT 0x01UL
#define TRC_ERROR_EVENT_CODE_TOO_LARGE 0x02UL
#define TRC_ERROR_ISR_NESTING_OVERFLOW 0x03UL
#define TRC_ERROR_DWT_NOT_SUPPORTED 0x04UL
#define TRC_ERROR_DWT_CYCCNT_NOT_SUPPORTED 0x05UL
#define TRC_ERROR_TZCTRLTASK_NOT_CREATED 0x06UL
#define TRC_ERROR_STREAM_PORT_WRITE 0x07UL
#define TRC_WARNING_ENTRY_TABLE_SLOTS 0x08UL
#define TRC_WARNING_ENTRY_SYMBOL_MAX_LENGTH 0x09UL
#define TRC_WARNING_EVENT_SIZE_TRUNCATED 0x0AUL
#define TRC_WARNING_STREAM_PORT_READ 0x0BUL
#define TRC_WARNING_STREAM_PORT_WRITE 0x0CUL
#define TRC_WARNING_STREAM_PORT_INITIAL_BLOCKING 0x0DUL
#define TRC_WARNING_STACKMON_NO_SLOTS 0x0EUL
/* Entry Option definitions */
#define TRC_ENTRY_OPTION_EXCLUDED 0x00000001UL
#define TRC_ENTRY_OPTION_HEAP 0x80000000UL
#define TRC_ENTRY_OPTION_EXTENSION 0x40000000UL
#define TRC_ENTRY_OPTION_STATE_MACHINE 0x20000000UL
#define TRC_ENTRY_OPTION_STATE_MACHINE_STATE 0x10000000UL
#define TRC_ENTRY_OPTION_INTERVAL_CHANNEL 0x08000000UL
#define TRC_ENTRY_OPTION_COUNTER 0x04000000UL
#define TRC_ENTRY_OPTION_INTERVAL_CHANNEL_SET 0x02000000UL
#define TRC_ENTRY_OPTION_IDLE_NAME 0x01000000UL
#define TRC_ENTRY_OPTION_RUNNABLE 0x00800000UL
#define TRC_ENTRY_OPTION_DEPENDENCY 0x00400000UL
#define TRC_DEPENDENCY_TYPE_ELF 0x00000001UL
#define TRC_RECORDER_COMPONENT_CORE 0x00000001UL
#define TRC_RECORDER_COMPONENT_ASSERT 0x00000002UL
#define TRC_RECORDER_COMPONENT_BLOB 0x00000004UL
#define TRC_RECORDER_COMPONENT_DIAGNOSTICS 0x00000008UL
#define TRC_RECORDER_COMPONENT_ENTRY 0x00000010UL
#define TRC_RECORDER_COMPONENT_ERROR 0x00000020UL
#define TRC_RECORDER_COMPONENT_EVENT 0x00000040UL
#define TRC_RECORDER_COMPONENT_EVENT_BUFFER 0x00000080UL
#define TRC_RECORDER_COMPONENT_EXTENSION 0x00000100UL
#define TRC_RECORDER_COMPONENT_HEAP 0x00000200UL
#define TRC_RECORDER_COMPONENT_INTERNAL_EVENT_BUFFER 0x00000400UL
#define TRC_RECORDER_COMPONENT_INTERVAL 0x00000800UL
#define TRC_RECORDER_COMPONENT_ISR 0x00001000UL
#define TRC_RECORDER_COMPONENT_MULTI_CORE_EVENT_BUFFER 0x00002000UL
#define TRC_RECORDER_COMPONENT_OBJECT 0x00004000UL
#define TRC_RECORDER_COMPONENT_PRINT 0x00008000UL
#define TRC_RECORDER_COMPONENT_STACK_MONITOR 0x00010000UL
#define TRC_RECORDER_COMPONENT_STATE_MACHINE 0x00020000UL
#define TRC_RECORDER_COMPONENT_STATIC_BUFFER 0x00040000UL
#define TRC_RECORDER_COMPONENT_STRING 0x00080000UL
#define TRC_RECORDER_COMPONENT_TASK 0x00100000UL
#define TRC_RECORDER_COMPONENT_TIMESTAMP 0x00200000UL
#define TRC_RECORDER_COMPONENT_COUNTER 0x00400000UL
/* Filter Groups */
#define FilterGroup0 (uint16_t)0x0001
#define FilterGroup1 (uint16_t)0x0002
#define FilterGroup2 (uint16_t)0x0004
#define FilterGroup3 (uint16_t)0x0008
#define FilterGroup4 (uint16_t)0x0010
#define FilterGroup5 (uint16_t)0x0020
#define FilterGroup6 (uint16_t)0x0040
#define FilterGroup7 (uint16_t)0x0080
#define FilterGroup8 (uint16_t)0x0100
#define FilterGroup9 (uint16_t)0x0200
#define FilterGroup10 (uint16_t)0x0400
#define FilterGroup11 (uint16_t)0x0800
#define FilterGroup12 (uint16_t)0x1000
#define FilterGroup13 (uint16_t)0x2000
#define FilterGroup14 (uint16_t)0x4000
#define FilterGroup15 (uint16_t)0x8000
/**
*
*/
#define TRC_INTERNAL_EVENT_BUFFER_OPTION_WRITE_MODE_COPY (0U)
#define TRC_INTERNAL_EVENT_BUFFER_OPTION_WRITE_MODE_DIRECT (1U)
/**
*
*/
#define TRC_INTERNAL_EVENT_BUFFER_OPTION_TRANSFER_MODE_ALL (0U)
#define TRC_INTERNAL_EVENT_BUFFER_OPTION_TRANSFER_MODE_CHUNKED (1U)
/******************************************************************************
* Supported ports
*
* TRC_HARDWARE_PORT_HWIndependent
* A hardware independent fallback option for event timestamping. Provides low
* resolution timestamps based on the OS tick.
* This may be used on the Win32 port, but may also be used on embedded hardware
* platforms. All time durations will be truncated to the OS tick frequency,
* typically 1 KHz. This means that a task or ISR that executes in less than
* 1 ms get an execution time of zero.
*
* TRC_HARDWARE_PORT_APPLICATION_DEFINED
* Allows for defining the port macros in other source code files.
*
* TRC_HARDWARE_PORT_Win32
* "Accurate" timestamping based on the Windows performance counter for Win32
* builds. Note that this gives the host machine time, not the kernel time.
*
* Hardware specific ports
* To get accurate timestamping, a hardware timer is necessary. Below are the
* available ports. Some of these are "unofficial", meaning that
* they have not yet been verified by Percepio but have been contributed by
* external developers. They should work, otherwise let us know by emailing
* support@percepio.com. Some work on any OS platform, while other are specific
* to a certain operating system.
*****************************************************************************/
/****** Port Name ************************************* Code ** Official ** OS Platform *********/
#define TRC_HARDWARE_PORT_APPLICATION_DEFINED 98 /* - - */
#define TRC_HARDWARE_PORT_NOT_SET 99 /* - - */
#define TRC_HARDWARE_PORT_HWIndependent 0 /* Yes Any */
#define TRC_HARDWARE_PORT_Win32 1 /* Yes FreeRTOS on Win32 */
#define TRC_HARDWARE_PORT_Atmel_AT91SAM7 2 /* No Any */
#define TRC_HARDWARE_PORT_Atmel_UC3A0 3 /* No Any */
#define TRC_HARDWARE_PORT_ARM_Cortex_M 4 /* Yes Any */
#define TRC_HARDWARE_PORT_Renesas_RX600 6 /* Yes Any */
#define TRC_HARDWARE_PORT_MICROCHIP_PIC24_PIC32 7 /* Yes Any */
#define TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48 8 /* Yes Any */
#define TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_MSP430 9 /* No Any */
#define TRC_HARDWARE_PORT_XILINX_PPC405 11 /* No FreeRTOS */
#define TRC_HARDWARE_PORT_XILINX_PPC440 12 /* No FreeRTOS */
#define TRC_HARDWARE_PORT_XILINX_MICROBLAZE 13 /* No Any */
#define TRC_HARDWARE_PORT_XILINX_ZyncUltraScaleR5 14 /* No FreeRTOS */
#define TRC_HARDWARE_PORT_NXP_LPC210X 15 /* No Any */
#define TRC_HARDWARE_PORT_ARM_CORTEX_A9 16 /* Yes Any */
#define TRC_HARDWARE_PORT_POWERPC_Z4 17 /* No FreeRTOS */
#define TRC_HARDWARE_PORT_Altera_NiosII 18 /* Yes Any (Tested with FreeRTOS) */
#define TRC_HARDWARE_PORT_ZEPHYR 19 /* Yes Zephyr */
#define TRC_HARDWARE_PORT_XTensa_LX6 20 /* Yes ESP-IDF FreeRTOS */
#define TRC_HARDWARE_PORT_XTensa_LX7 21 /* Yes ESP-IDF FreeRTOS */
#define TRC_HARDWARE_PORT_Win64 22 /* Yes FreeRTOS on Win64 */
#define TRC_HARDWARE_PORT_XMOS_XCOREAI 23 /* Yes FreeRTOS SMP */
#define TRC_HARDWARE_PORT_RISCV_RV32I 24 /* Yes FreeRTOS */
#define TRC_HARDWARE_PORT_CYCLONE_V_HPS 25 /* Yes FreeRTOS */
#define TRC_HARDWARE_PORT_ARM_Cortex_M_NRF_SD 26 /* Yes FreeRTOS */
#define TRC_HARDWARE_PORT_ARMv8AR_A32 27 /* Yes Any */
#endif /* TRC_PORTDEFINES_H */

View File

@@ -0,0 +1,62 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace dependency APIs.
*/
#ifndef TRC_DEPENDENCY_H
#define TRC_DEPENDENCY_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup trace_dependency_apis Trace Dependency APIs
* @ingroup trace_recorder_apis
* @{
*/
/**
* @brief Registers a dependency.
*
* @param[in] szName Name.
* @param[in] uxDependencyType The type of dependency.
* TRC_DEPENDENCY_TYPE_ELF: .elf file. Currently the only supported type.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceDependencyRegister(const char* szName, TraceUnsignedBaseType_t uxDependencyType);
/** @} */
#ifdef __cplusplus
}
#endif
#else
#ifndef xTraceDependencyRegister
#define xTraceDependencyRegister(szName, uxDependencyType) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4((void)(szName), (void)(uxRegisterMethod), (void)(pxRunnableHandle), TRC_SUCCESS)
#endif
#endif
#endif
#endif

View File

@@ -0,0 +1,145 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace diagnostic APIs.
*/
#ifndef TRC_DIAGNOSTICS_H
#define TRC_DIAGNOSTICS_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
#define TRC_DIAGNOSTICS_COUNT 5UL
typedef enum TraceDiagnosticsType
{
TRC_DIAGNOSTICS_ENTRY_SYMBOL_LONGEST_LENGTH = 0x00UL,
TRC_DIAGNOSTICS_ENTRY_SLOTS_NO_ROOM = 0x01UL,
TRC_DIAGNOSTICS_BLOB_MAX_BYTES_TRUNCATED = 0x02UL,
TRC_DIAGNOSTICS_STACK_MONITOR_NO_SLOTS = 0x03UL,
TRC_DIAGNOSTICS_ASSERTS_TRIGGERED = 0x04UL,
} TraceDiagnosticsType_t;
typedef struct TraceDiagnostics /* Aligned */
{
TraceBaseType_t metrics[TRC_DIAGNOSTICS_COUNT];
} TraceDiagnosticsData_t;
/**
* @internal Initialize diagnostics
*
* @param[in] pxBuffer Diagnostics buffer
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceDiagnosticsInitialize(TraceDiagnosticsData_t* pxBuffer);
/**
* @brief Retrieve diagnostics value
*
* @param[in] xType Diagnostics type
* @param[out] pxValue Pointer to value
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceDiagnosticsGet(TraceDiagnosticsType_t xType, TraceBaseType_t* pxValue);
/**
* @brief Set diagnostics value
*
* @param[in] xType Diagnostics type
* @param[in] xValue Value
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceDiagnosticsSet(TraceDiagnosticsType_t xType, TraceBaseType_t xValue);
/**
* @brief Add to diagnostics value
*
* @param[in] xType Diagnostics type
* @param[in] xValue Value
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceDiagnosticsAdd(TraceDiagnosticsType_t xType, TraceBaseType_t xValue);
/**
* @brief Increase diagnostics value
*
* @param[in] xType Diagnostics type
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceDiagnosticsIncrease(TraceDiagnosticsType_t xType);
/**
* @brief Decrease diagnostics value
*
* @param[in] xType Diagnostics type
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceDiagnosticsDecrease(TraceDiagnosticsType_t xType);
/**
* @brief Set a new diagnostics value if higher than previous value
*
* @param[in] xType Dagnostics type
* @param[in] xValue Value
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceDiagnosticsSetIfHigher(TraceDiagnosticsType_t xType, TraceBaseType_t xValue);
/**
* @brief Set a new diagnostics value if lower than previous value
*
* @param[in] xType Dagnostics type
* @param[in] xValue Value
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceDiagnosticsSetIfLower(TraceDiagnosticsType_t xType, TraceBaseType_t xValue);
/**
* @brief Check the diagnostics status
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceDiagnosticsCheckStatus(void);
#ifdef __cplusplus
}
#endif
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
#endif /* TRC_DIAGNOSTICS_H */

View File

@@ -0,0 +1,302 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace entry table APIs.
*/
#ifndef TRC_ENTRY_TABLE_H
#define TRC_ENTRY_TABLE_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup trace_entry_table_apis Trace Entry Table APIs
* @ingroup trace_recorder_apis
* @{
*/
#define TRC_ENTRY_CREATE_WITH_ADDRESS(_pvAddress, _pxEntryHandle) (xTraceEntryCreate(_pxEntryHandle) == TRC_SUCCESS ? (((TraceEntry_t*)*(_pxEntryHandle))->pvAddress = (_pvAddress), TRC_SUCCESS) : TRC_FAIL)
#define TRC_ENTRY_SET_STATE(xEntryHandle, uxStateIndex, uxState) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(((TraceEntry_t*)(xEntryHandle))->xStates[uxStateIndex] = (uxState), TRC_SUCCESS)
#define TRC_ENTRY_SET_OPTIONS(xEntryHandle, uiMask) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(((TraceEntry_t*)(xEntryHandle))->uiOptions |= (uiMask), TRC_SUCCESS)
#define TRC_ENTRY_CLEAR_OPTIONS(xEntryHandle, uiMask) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(((TraceEntry_t*)(xEntryHandle))->uiOptions &= ~(uiMask), TRC_SUCCESS)
#define TRC_ENTRY_GET_ADDRESS(xEntryHandle, ppvAddress) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(ppvAddress) = ((TraceEntry_t*)(xEntryHandle))->pvAddress, TRC_SUCCESS)
#define TRC_ENTRY_GET_SYMBOL(xEntryHandle, pszSymbol) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(pszSymbol) = ((TraceEntry_t*)(xEntryHandle))->szSymbol, TRC_SUCCESS)
#define TRC_ENTRY_GET_STATE(xEntryHandle, uxStateIndex, puxState) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(puxState) = ((TraceEntry_t*)(xEntryHandle))->xStates[uxStateIndex], TRC_SUCCESS)
#define TRC_ENTRY_GET_STATE_RETURN(xEntryHandle, uxStateIndex) (((TraceEntry_t*)(xEntryHandle))->xStates[uxStateIndex])
#define TRC_ENTRY_GET_OPTIONS(xEntryHandle, puiOptions) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(puiOptions) = ((TraceEntry_t*)(xEntryHandle))->uiOptions, TRC_SUCCESS)
#define TRC_ENTRY_TABLE_STATE_COUNT (3UL)
#define TRC_ENTRY_TABLE_SYMBOL_LENGTH ((uint32_t)(TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH))
/* TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE has to be aligned to TraceUnsignedBaseType_t but with a uint32_t padding to ensure that TraceEntry_t size is aligned (uiOptions is uint32_t) */
#define TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE (((((sizeof(char) * (uint32_t)(TRC_ENTRY_TABLE_SYMBOL_LENGTH) - sizeof(uint32_t)) + (sizeof(TraceUnsignedBaseType_t) - 1UL)) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t)) + sizeof(uint32_t))
#if (TRC_CFG_ENTRY_SLOTS > 256UL)
typedef uint16_t TraceEntryIndex_t;
#define TRC_ENTRY_INDEX_ALIGNMENT_MULTIPLE (4) /* Must align to 64-bit (sizeof(uint64_t) / sizeof(uint16_t)) */
#else
typedef uint8_t TraceEntryIndex_t;
#define TRC_ENTRY_INDEX_ALIGNMENT_MULTIPLE (8) /* Must align to 64-bit (sizeof(uint64_t) / sizeof(uint8_t)) */
#endif
#define TRC_ENTRY_TABLE_SLOTS ((((TRC_CFG_ENTRY_SLOTS) + (TRC_ENTRY_INDEX_ALIGNMENT_MULTIPLE) - 1) / TRC_ENTRY_INDEX_ALIGNMENT_MULTIPLE) * TRC_ENTRY_INDEX_ALIGNMENT_MULTIPLE)
typedef struct EntryIndexTable /* Aligned because TRC_ENTRY_TABLE_SLOTS is always a multiple that aligns to 64-bit */
{
TraceEntryIndex_t axFreeIndexes[TRC_ENTRY_TABLE_SLOTS]; /* slot count and size is aligned to 64-bit */
uint32_t uiFreeIndexCount;
uint32_t reserved; /* alignment */
} TraceEntryIndexTable_t;
/** Trace Entry Structure */
typedef struct TraceEntry /* Aligned because TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE will align together with uiOptions */
{
void* pvAddress; /**< */
TraceUnsignedBaseType_t xStates[TRC_ENTRY_TABLE_STATE_COUNT]; /**< */
uint32_t uiOptions; /**< */
char szSymbol[TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE]; /**< */
} TraceEntry_t;
typedef struct TraceEntryTable /* Aligned */
{
TraceUnsignedBaseType_t uxSlots;
TraceUnsignedBaseType_t uxEntrySymbolLength;
TraceUnsignedBaseType_t uxEntryStateCount;
TraceEntry_t axEntries[TRC_ENTRY_TABLE_SLOTS];
} TraceEntryTable_t;
/**
* @internal Initialize trace entry index table.
*
* This routine initializes the trace entry index table which keeps track
* of availables indexes.
*
* @param[in] pxBuffer Pointer to uninitialized trace entry index table buffer.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEntryIndexTableInitialize(TraceEntryIndexTable_t* const pxBuffer);
/**
* @internal Initialize trace entry table.
*
* This routine initializes the trace entry table which maps objects to
* symbolic identifiers, state information, and options.
*
* @param[in] pxBuffer Pointer to uninitialized trace entry table buffer.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEntryTableInitialize(TraceEntryTable_t* const pxBuffer);
/**
* @brief Creates trace entry.
*
* @param[out] pxEntryHandle Pointer to uninitialized trace entry handle.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEntryCreate(TraceEntryHandle_t *pxEntryHandle);
/**
* @brief Deletes trace entry.
*
* @param[in] xEntryHandle Pointer to initialized trace entry handle.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEntryDelete(TraceEntryHandle_t xEntryHandle);
/**
* @brief Finds trace entry mapped to object address.
*
* @param[in] pvAddress Address of object.
* @param[out] pxEntryHandle Pointer to uninitialized trace entry handle.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEntryFind(const void* const pvAddress, TraceEntryHandle_t* pxEntryHandle);
/**
* @brief Gets the number of entries in the trace entry table.
*
* @param[out] puiCount Count.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEntryGetCount(uint32_t* puiCount);
/**
* @brief Gets trace table entry at index.
*
* @param[in] index Entry index.
* @param[out] pxEntryHandle Pointer to uninitialized trace entry handle.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEntryGetAtIndex(uint32_t index, TraceEntryHandle_t* pxEntryHandle);
/**
* @brief Sets symbol for entry.
*
* @param[in] xEntryHandle Pointer to initialized trace entry handle.
* @param[in] szSymbol Pointer to symbol string, set by function
* @param[in] uiLength Symbol length
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEntrySetSymbol(const TraceEntryHandle_t xEntryHandle, const char* szSymbol, uint32_t uiLength);
#if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
/**
* @brief Creates trace entry mapped to memory address.
*
* @param[in] pvAddress Address.
* @param[out] pxEntryHandle Pointer to uninitialized trace entry handle.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEntryCreateWithAddress(void* const pvAddress, TraceEntryHandle_t* pxEntryHandle);
/**
* @brief Sets trace entry state.
*
* @param[in] xEntryHandle Pointer to initialized trace entry handle.
* @param[in] uxStateIndex Index of state (< TRC_ENTRY_TABLE_STATE_COUNT).
* @param[in] uxState State.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEntrySetState(const TraceEntryHandle_t xEntryHandle, TraceUnsignedBaseType_t uxStateIndex, TraceUnsignedBaseType_t uxState);
/**
* @brief Sets trace entry option(s).
*
* @param[in] xEntryHandle Pointer to initialized trace entry handle.
* @param[in] uiMask Option(s) set mask.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEntrySetOptions(const TraceEntryHandle_t xEntryHandle, uint32_t uiMask);
/**
* @brief Clears trace entry option(s).
*
* @param[in] xEntryHandle Pointer to initialized trace entry handle.
* @param[in] uiMask Options(s) clear mask.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEntryClearOptions(const TraceEntryHandle_t xEntryHandle, uint32_t uiMask);
/**
* @brief Gets linked address for trace entry.
*
* @param[in] xEntryHandle Pointer to initialized trace entry handle.
* @param[out] ppvAddress Address.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEntryGetAddress(const TraceEntryHandle_t xEntryHandle, void **ppvAddress);
/**
* @brief Gets symbol for trace entry.
*
* @param[in] xEntryHandle Pointer to initialized trace entry handle.
* @param[out] pszSymbol Symbol.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEntryGetSymbol(const TraceEntryHandle_t xEntryHandle, const char** pszSymbol);
/**
* @brief Gets state for trace entry.
*
* @param[in] xEntryHandle Pointer to initialized trace entry handle.
* @param[in] uxStateIndex State index (< TRC_ENTRY_TABLE_STATE_COUNT).
* @param[out] puxState State.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEntryGetState(const TraceEntryHandle_t xEntryHandle, TraceUnsignedBaseType_t uxStateIndex, TraceUnsignedBaseType_t *puxState);
/**
* @internal Returns state for trace entry.
*
* @param[in] xEntryHandle Pointer to initialized trace entry handle.
* @param[in] uxStateIndex State index (< TRC_ENTRY_TABLE_STATE_COUNT).
*
* @returns State
*/
TraceUnsignedBaseType_t xTraceEntryGetStateReturn(const TraceEntryHandle_t xEntryHandle, TraceUnsignedBaseType_t uxStateIndex);
/**
* @brief Gets options for trace entry.
*
* @param[in] xEntryHandle Pointer to initialized trace entry handle.
* @param[out] puiOptions Options.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEntryGetOptions(const TraceEntryHandle_t xEntryHandle, uint32_t *puiOptions);
#else
#define xTraceEntryCreateWithAddress TRC_ENTRY_CREATE_WITH_ADDRESS
#define xTraceEntrySetState TRC_ENTRY_SET_STATE
#define xTraceEntrySetOptions TRC_ENTRY_SET_OPTIONS
#define xTraceEntryClearOptions TRC_ENTRY_CLEAR_OPTIONS
#define xTraceEntryGetAddress TRC_ENTRY_GET_ADDRESS
#define xTraceEntryGetSymbol TRC_ENTRY_GET_SYMBOL
#define xTraceEntryGetState TRC_ENTRY_GET_STATE
#define xTraceEntryGetStateReturn TRC_ENTRY_GET_STATE_RETURN
#define xTraceEntryGetOptions TRC_ENTRY_GET_OPTIONS
#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
#endif /* TRC_ENTRY_TABLE_H */

View File

@@ -0,0 +1,99 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace error APIs.
*/
#ifndef TRC_ERROR_H
#define TRC_ERROR_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup trace_assert_apis Trace Asserts APIs
* @ingroup trace_recorder_apis
* @{
*/
typedef struct TraceErrorData /* Aligned */
{
uint32_t uiErrorAndWarningFlags;
uint32_t uiErrorCode;
TraceStringHandle_t xWarningChannel;
} TraceErrorData_t;
/**
* @internal Initializes the error system
*
* @param[in] pxBuffer Pointer to buffer
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceErrorInitialize(TraceErrorData_t* pxBuffer);
/**
* @brief Register a warning
*
* @param[in] uiErrorCode Label
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceWarning(uint32_t uiErrorCode);
/**
* @brief Register an error
*
* @param[in] uiErrorCode Error code
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceError(uint32_t uiErrorCode);
/**
* @brief Retrieve the string for the last error
*
* @param[out] pszError Error string pointer
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceErrorGetLast(const char** pszError);
/**
* @brief Clears any errors
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceErrorClear(void);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
#endif /* TRC_ERROR_H*/

View File

@@ -0,0 +1,768 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace event APIs.
*/
#ifndef TRC_EVENT_H
#define TRC_EVENT_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup trace_event_apis Trace Event APIs
* @ingroup trace_recorder_apis
* @{
*/
/**
* @internal Macro helper for setting trace event parameter count.
*/
#define TRC_EVENT_SET_PARAM_COUNT(id, n) ((uint16_t)(((uint16_t)(id)) | ((((uint16_t)(n)) & 0xF) << 12)))
/**
* @internal Macro helper for getting trace event parameter count.
*/
#define TRC_EVENT_GET_PARAM_COUNT(id) (((id) >> 12u) & 0xFU)
#if (TRC_CFG_CORE_COUNT > 1)
#define TRC_EVENT_SET_EVENT_COUNT(c) ((uint16_t)(((TRC_CFG_GET_CURRENT_CORE() & 0xF) << 12) | ((uint16_t)(c) & 0xFFF)))
#else
#define TRC_EVENT_SET_EVENT_COUNT(c) ((uint16_t)(c))
#endif
/**
* @internal Macro helper for setting base event data.
*/
#define SET_BASE_EVENT_DATA(pxEvent, eventId, paramCount, eventCount) \
( \
(pxEvent)->EventID = TRC_EVENT_SET_PARAM_COUNT(eventId, paramCount), \
(pxEvent)->EventCount = TRC_EVENT_SET_EVENT_COUNT(eventCount), \
xTraceTimestampGet(&(pxEvent)->TS) \
)
/**
* @internal Macro helper for resetting trace event data.
*/
#define RESET_EVENT_DATA(p) \
( \
(p)->pvBlob = 0, \
(p)->size = 0, \
(p)->offset = 0 \
)
/**
* @internal Macro optimization for getting trace event size.
*/
#define TRC_EVENT_GET_SIZE(pvAddress, puiSize) (*(uint32_t*)(puiSize) = sizeof(TraceEvent0_t) + (TRC_EVENT_GET_PARAM_COUNT(((TraceEvent0_t*)(pvAddress))->EventID)) * sizeof(TraceBaseType_t), TRC_SUCCESS)
/**
* @internal Macro optimization for getting trace event data pointer with an offset.
*/
#define TRC_EVENT_GET_RAW_DATA(xEventHandle, uiOffset, uiSize, ppvData) ((void)(uiSize), *(void**)(ppvData) = (void*)&((uint8_t*)((TraceEventData_t*)(xEventHandle))->pvBlob)[uiOffset], TRC_SUCCESS)
/**
* @internal Macro optimization for getting trace event payload pointer with an offset.
*/
#define TRC_EVENT_GET_PAYLOAD(xEventHandle, uiOffset, uiSize, ppvData) ((void)(uiSize), *(void**)(ppvData) = (void*)&((uint8_t*)((TraceEventData_t*)(xEventHandle))->pvBlob)[sizeof(TraceEvent0_t) + (uiOffset)], TRC_SUCCESS)
/**
* @internal Macro optimization for getting trace event remaining payload size.
*/
#define TRC_EVENT_PAYLOAD_REMAINING(xEventHandle, puiValue) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(uint32_t*)(puiValue) = ((TraceEventData_t*)(xEventHandle))->size - ((TraceEventData_t*)(xEventHandle))->offset, TRC_SUCCESS)
/**
* @internal Macro optimization for getting trace event used payload size.
*/
#define TRC_EVENT_PAYLOAD_USED(xEventHandle, puiValue) (*(uint32_t*)(puiValue) = ((TraceEventData_t*)(xEventHandle))->offset - sizeof(TraceEvent0_t), TRC_SUCCESS)
/**
* @internal Macro optimization getting trace event payload size.
*/
#define TRC_EVENT_PAYLOAD_SIZE(xEventHandle, puiValue) (*(uint32_t*)(puiValue) = ((TraceEventData_t*)(xEventHandle))->size - sizeof(TraceEvent0_t), TRC_SUCCESS)
/**
* @internal Macro optimization for adding a pointer address to trace event.
*/
#define TRC_EVENT_ADD_POINTER(xEventHandle, value) \
TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( \
((void**)((TraceEventData_t*)(xEventHandle))->pvBlob)[((TraceEventData_t*)(xEventHandle))->offset / sizeof(void*)] = (value), \
((TraceEventData_t*)(xEventHandle))->offset += sizeof(void*), \
TRC_SUCCESS \
)
/**
* @internal Macro optimization for adding a unsigned base type to trace event.
*/
#define TRC_EVENT_ADD_UNSIGNED_BASE_TYPE(xEventHandle, value) \
TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( \
((TraceUnsignedBaseType_t*)((TraceEventData_t*)(xEventHandle))->pvBlob)[((TraceEventData_t*)(xEventHandle))->offset / sizeof(TraceUnsignedBaseType_t)] = (value), \
((TraceEventData_t*)(xEventHandle))->offset += sizeof(TraceUnsignedBaseType_t), \
TRC_SUCCESS \
)
/**
* @internal Macro optimization for adding a 32-bit value to trace event.
*/
#define TRC_EVENT_ADD_32(xEventHandle, value) \
TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( \
((uint32_t*)((TraceEventData_t*)(xEventHandle))->pvBlob)[((TraceEventData_t*)(xEventHandle))->offset / sizeof(uint32_t)] = (value), \
((TraceEventData_t*)(xEventHandle))->offset += sizeof(uint32_t), \
TRC_SUCCESS \
)
/**
* @internal Macro optimization for adding a 16-bit value to trace event.
*/
#define TRC_EVENT_ADD_16(xEventHandle, value) \
TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( \
((uint16_t*)((TraceEventData_t*)(xEventHandle))->pvBlob)[((TraceEventData_t*)(xEventHandle))->offset / sizeof(uint16_t)] = (value), \
((TraceEventData_t*)(xEventHandle))->offset += sizeof(uint16_t), \
TRC_SUCCESS \
)
/**
* @internal Macro optimization for adding a 8-bit value to trace event.
*/
#define TRC_EVENT_ADD_8(xEventHandle, value) \
TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( \
((uint8_t*)((TraceEventData_t*)(xEventHandle))->pvBlob)[((TraceEventData_t*)(xEventHandle))->offset / sizeof(uint8_t)] = (value), \
((TraceEventData_t*)(xEventHandle))->offset += sizeof(uint8_t), \
TRC_SUCCESS \
)
/**
* @internal Macro optimization for beginning an offline trace event.
*/
#define TRC_EVENT_BEGIN_OFFLINE(uiEventCode, uiPayloadSize, pxEventHandle) \
( \
(xTraceEventBeginRawOffline((uint32_t)(sizeof(TraceEvent0_t) + (uiPayloadSize)), pxEventHandle)) == TRC_SUCCESS ? \
( \
SET_BASE_EVENT_DATA((TraceEvent0_t*)(((TraceEventData_t*)*(pxEventHandle))->pvBlob), \
uiEventCode, \
(((TraceEventData_t*)*(pxEventHandle))->size - sizeof(TraceEvent0_t)) / sizeof(TraceBaseType_t), \
pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventCounter), \
((TraceEventData_t*)*(pxEventHandle))->offset += sizeof(TraceEvent0_t), \
TRC_SUCCESS \
) : TRC_FAIL \
)
/**
* @internal Trace Event Structure without uTraceUnsignedBaseType_t parameters
*/
typedef struct { /* Aligned */
uint16_t EventID; /**< */
uint16_t EventCount; /**< */
uint32_t TS; /**< */
} TraceEvent0_t;
/**
* @internal Trace Event Structure with one uTraceUnsignedBaseType_t parameter
*/
typedef struct { /* Aligned */
uint16_t EventID; /**< */
uint16_t EventCount; /**< */
uint32_t TS; /**< */
TraceUnsignedBaseType_t uxParams[1]; /**< */
} TraceEvent1_t;
/**
* @internal Trace Event Structure with two uTraceUnsignedBaseType_t parameters
*/
typedef struct { /* Aligned */
uint16_t EventID; /**< */
uint16_t EventCount; /**< */
uint32_t TS; /**< */
TraceUnsignedBaseType_t uxParams[2]; /**< */
} TraceEvent2_t;
/**
* @internal Trace Event Structure with three uTraceUnsignedBaseType_t parameters
*/
typedef struct { /* Aligned */
uint16_t EventID; /**< */
uint16_t EventCount; /**< */
uint32_t TS; /**< */
TraceUnsignedBaseType_t uxParams[3]; /**< */
} TraceEvent3_t;
/**
* @internal Trace Event Structure with four uTraceUnsignedBaseType_t parameters
*/
typedef struct { /* Aligned */
uint16_t EventID; /**< */
uint16_t EventCount; /**< */
uint32_t TS; /**< */
TraceUnsignedBaseType_t uxParams[4]; /**< */
} TraceEvent4_t;
/**
* @internal Trace Event Structure with five uTraceUnsignedBaseType_t parameters
*/
typedef struct { /* Aligned */
uint16_t EventID; /**< */
uint16_t EventCount; /**< */
uint32_t TS; /**< */
TraceUnsignedBaseType_t uxParams[5]; /**< */
} TraceEvent5_t;
/**
* @internal Trace Event Structure with six uTraceUnsignedBaseType_t parameters
*/
typedef struct { /* Aligned */
uint16_t EventID; /**< */
uint16_t EventCount; /**< */
uint32_t TS; /**< */
TraceUnsignedBaseType_t uxParams[6]; /**< */
} TraceEvent6_t;
/**
* @internal Trace Event Structure with seven uTraceUnsignedBaseType_t parameters
*/
typedef struct { /* Aligned */
uint16_t EventID; /**< */
uint16_t EventCount; /**< */
uint32_t TS; /**< */
TraceUnsignedBaseType_t uxParams[7]; /**< */
} TraceEvent7_t;
/**
* @internal Trace Event Data Structure
*/
typedef struct TraceEventData /* Aligned */
{
void* pvBlob; /**< */
uint32_t size; /**< */
uint32_t offset; /**< */
} TraceEventData_t;
/**
* @internal Trace Core Event Data Structure
*/
typedef struct TraceCoreEventData /* Aligned */
{
TraceEventData_t eventData[(TRC_CFG_MAX_ISR_NESTING)+1]; /* aligned */
uint32_t eventCounter; /**< */
uint32_t reserved; /* alignment */
TRACE_ALLOC_CRITICAL_SECTION()
} TraceCoreEventData_t;
/**
* @internal Trace Event Data Table Structure.
*/
typedef struct TraceEventDataTable /* Aligned */
{
TraceCoreEventData_t coreEventData[TRC_CFG_CORE_COUNT]; /**< Holds data about current event for each core/isr depth */
} TraceEventDataTable_t;
extern TraceEventDataTable_t* pxTraceEventDataTable;
/**
* @internal Initialize event trace system.
*
* @param[in] pxBuffer Pointer to memory that will be used by the event
* trace system.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventInitialize(TraceEventDataTable_t* pxBuffer);
/**
* @brief Gets trace event size.
*
* @param[in] pvAddress Pointer to initialized trace event.
* @param[out] puiSize Size.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventGetSize(const void* const pvAddress, uint32_t* puiSize);
/**
* @brief Creates an event with 0 parameters.
*
* @param[in] uiEventCode Event code.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventCreate0(uint32_t uiEventCode);
/**
* @brief Creates an event with 1 parameters.
*
* @param[in] uiEventCode Event code.
* @param[in] uxParam1 First parameter.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventCreate1(uint32_t uiEventCode, TraceUnsignedBaseType_t uxParam1);
/**
* @brief Creates an event with 2 parameters.
*
* @param[in] uiEventCode Event code.
* @param[in] uxParam1 First parameter.
* @param[in] uxParam2 Second parameter.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventCreate2(uint32_t uiEventCode, TraceUnsignedBaseType_t uxParam1, TraceUnsignedBaseType_t uxParam2);
/**
* @brief Creates an event with 3 parameters.
*
* @param[in] uiEventCode Event code.
* @param[in] uxParam1 First parameter.
* @param[in] uxParam2 Second parameter.
* @param[in] uxParam3 Third parameter.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventCreate3(uint32_t uiEventCode, TraceUnsignedBaseType_t uxParam1, TraceUnsignedBaseType_t uxParam2, TraceUnsignedBaseType_t uxParam3);
/**
* @brief Creates an event with 4 parameters.
*
* @param[in] uiEventCode Event code.
* @param[in] uxParam1 First parameter.
* @param[in] uxParam2 Second parameter.
* @param[in] uxParam3 Third parameter.
* @param[in] uxParam4 Fourth parameter.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventCreate4(uint32_t uiEventCode, TraceUnsignedBaseType_t uxParam1, TraceUnsignedBaseType_t uxParam2, TraceUnsignedBaseType_t uxParam3, TraceUnsignedBaseType_t uxParam4);
/**
* @brief Creates an event with 5 parameters.
*
* @param[in] uiEventCode Event code.
* @param[in] uxParam1 First parameter.
* @param[in] uxParam2 Second parameter.
* @param[in] uxParam3 Third parameter.
* @param[in] uxParam4 Fourth parameter.
* @param[in] uxParam5 Fifth parameter.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventCreate5(uint32_t uiEventCode, TraceUnsignedBaseType_t uxParam1, TraceUnsignedBaseType_t uxParam2, TraceUnsignedBaseType_t uxParam3, TraceUnsignedBaseType_t uxParam4, TraceUnsignedBaseType_t uxParam5);
/**
* @brief Creates an event with 6 parameters.
*
* @param[in] uiEventCode Event code.
* @param[in] uxParam1 First parameter.
* @param[in] uxParam2 Second parameter.
* @param[in] uxParam3 Third parameter.
* @param[in] uxParam4 Fourth parameter.
* @param[in] uxParam5 Fifth parameter.
* @param[in] uxParam6 Sixth parameter.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventCreate6(uint32_t uiEventCode, TraceUnsignedBaseType_t uxParam1, TraceUnsignedBaseType_t uxParam2, TraceUnsignedBaseType_t uxParam3, TraceUnsignedBaseType_t uxParam4, TraceUnsignedBaseType_t uxParam5, TraceUnsignedBaseType_t uxParam6);
/**
* @internal Begins a raw trace event offline.
*
* This routine begins a trace event with specified size. Must call xTraceEventEnd()
* to finalize event creation. Does not care about RecorderEnabled.
*
* @param[in] uiSize Size.
* @param[in] pxEventHandle Pointer to initialized trace event.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventBeginRawOffline(uint32_t uiSize, TraceEventHandle_t* pxEventHandle);
/**
* @internal Begins a blocking trace event offline.
*
* This routine begins a trace event with specified size. Must call xTraceEventEnd()
* to finalize event creation. Does not care about RecorderEnabled.
*
* @param[in] uiSize Size.
* @param[in] pxEventHandle Pointer to initialized trace event.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventBeginRawOfflineBlocking(uint32_t uiSize, TraceEventHandle_t* pxEventHandle);
/**
* @internal Begins a trace event offline.
*
* This routine begins a trace event with specified size. Must call xTraceEventEnd()
* to finalize event creation. Does not care about RecorderEnabled.
*
* @param[in] uiSize Size.
* @param[in] pxEventHandle Pointer to initialized trace event.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceEventBeginOffline TRC_EVENT_BEGIN_OFFLINE
/**
* @brief Begins a trace event.
*
* This routine begins a trace event with specified size. Must call xTraceEventEnd()
* to finalize event creation. Does not care about RecorderEnabled.
*
* @param[in] uiSize Size.
* @param[in] pxEventHandle Pointer to initialized trace event.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceEventBegin(uiEventCode, uiTotalPayloadSize, pxEventHandle) \
(xTraceIsRecorderEnabled() ? xTraceEventBeginOffline(uiEventCode, uiTotalPayloadSize, pxEventHandle) : TRC_FAIL)
/**
* @internal Ends a trace event offline.
*
* This routine ends the event that was begun by calling on xTraceEventBegin().
* Does not care about uiRecorderEnabled.
*
* @param[in] xEventHandle Pointer to initialized trace event.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventEndOffline(TraceEventHandle_t xEventHandle);
/**
* @internal Ends a blocking event offline.
*
* Ends the event that was begun by calling on xTraceEventBegin()
*
* @param[in] xEventHandle Pointer to initialized trace event.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventEndOfflineBlocking(TraceEventHandle_t xEventHandle);
/**
* @brief Ends a trace event.
*
* This routine ends the event that was begun by calling on xTraceEventBegin().
* Does not care about uiRecorderEnabled.
*
* @param[in] xEventHandle Pointer to initialized trace event.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceEventEnd(xEventHandle) \
(!xTraceIsRecorderEnabled() ? TRC_FAIL : xTraceEventEndOffline(xEventHandle))
/**
* @brief Adds data to event payload.
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[in] puxData Pointer to data.
* @param[in] uxSize Size.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventAddData(TraceEventHandle_t xEventHandle, const TraceUnsignedBaseType_t* const puxData, TraceUnsignedBaseType_t uxSize);
/**
* @brief Adds string to event payload.
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[in] szString Pointer to string.
* @param[in] uiLength Size.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceEventAddString(xEventHandle, szString, uiLength) xTraceEventAddData(xEventHandle, (TraceUnsignedBaseType_t*)(szString), (((uiLength) + (sizeof(TraceUnsignedBaseType_t) - 1)) / sizeof(TraceUnsignedBaseType_t)))
#if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
/**
* @brief Gets trace event data pointer with an offset.
*
* This routine gets a trace event data pointer with an offset. It also verifies
* the size so it won't go outside its' buffer.
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[in] uiOffset Offset.
* @param[in] uiSize Size.
* @param[out] ppvData Data.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventGetRawData(TraceEventHandle_t xEventHandle, uint32_t uiOffset, uint32_t uiSize, void** ppvData);
/**
* @brief Gets trace event payload pointer with an offset.
*
* This routine gets a trace event payload pointer with an offset. It also verifies
* the size so it won't go outside its payload buffer.
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[in] uiOffset Offset.
* @param[in] uiSize Size.
* @param[out] ppvData Data.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventGetPayload(const TraceEventHandle_t xEventHandle, uint32_t uiOffset, uint32_t uiSize, void** ppvData);
/**
* @brief Gets the amount of remaining trace event payload.
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[out] puiValue Value.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventPayloadRemaining(const TraceEventHandle_t xEventHandle, uint32_t* puiValue);
/**
* @brief Gets the amount of used trace event payload.
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[out] puiValue Value
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventPayloadUsed(TraceEventHandle_t xEventHandle, uint32_t* puiValue);
/**
* @brief Gets trace event payload size.
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[out] puiValue Value
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventPayloadSize(TraceEventHandle_t xEventHandle, uint32_t* puiValue);
/**
* @brief Adds an unsigned base type value as trace event payload
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[in] uxValue Value.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventAddUnsignedBaseType(TraceEventHandle_t xEventHandle, TraceUnsignedBaseType_t uxValue);
/**
* @brief Adds a pointer address as trace event payload
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[in] pvAddress Address.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventAddPointer(TraceEventHandle_t xEventHandle, void *pvAddress);
/**
* @brief Adds an uint32_t as trace event payload
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[in] value Value.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventAdd32(TraceEventHandle_t xEventHandle, uint32_t value);
/**
* @brief Adds an uint16_t as trace event payload
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[in] value Value.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventAdd16(TraceEventHandle_t xEventHandle, uint16_t value);
/**
* @brief Adds an uint8_t as trace event payload.
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[in] value Value.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventAdd8(TraceEventHandle_t xEventHandle, uint8_t value);
#else /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
/**
* @brief Gets trace event size.
*
* @param[in] pvAddress Pointer to initialized trace event.
* @param[out] puiSize Size.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceEventGetSize(pvAddress, puiSize) (*(uint32_t*)(puiSize) = sizeof(TraceEvent0_t) + (TRC_EVENT_GET_PARAM_COUNT(((TraceEvent0_t*)(pvAddress))->EventID)) * sizeof(uint32_t), TRC_SUCCESS)
/**
* @brief Gets trace event data pointer with an offset.
*
* This routine gets a trace event data pointer with an offset. It also verfies
* that the size so it won't go outside its buffer.
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[in] uiOffset Offset.
* @param[in] uiSize Size.
* @param[out] ppvData Data.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceEventGetRawData TRC_EVENT_GET_RAW_DATA
/**
* @brief Gets trace event payload pointer with an offset.
*
* This routine gets a trace event payload pointer with an offset. It also verifies
* that the size so it won't go outside its payload buffer.
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[in] uiOffset Offset.
* @param[in] uiSize Size.
* @param[out] ppvData Data.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceEventGetPayload TRC_EVENT_GET_PAYLOAD
/**
* @brief Gets the amount of remaining trace event payload.
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[out] puiValue Value.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceEventPayloadRemaining TRC_EVENT_PAYLOAD_REMAINING
/**
* @brief Gets the amount of used trace event payload.
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[out] puiValue Value
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceEventPayloadUsed TRC_EVENT_PAYLOAD_USED
/**
* @brief Gets trace event payload size.
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[out] puiValue Value
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceEventPayloadSize TRC_EVENT_PAYLOAD_SIZE
/* Adds a pointer as event payload with no errors checks */
#define xTraceEventAddPointer TRC_EVENT_ADD_POINTER
/**
* @brief Adds an unsigned base type value as trace event payload
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[in] uxValue Value.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceEventAddUnsignedBaseType TRC_EVENT_ADD_UNSIGNED_BASE_TYPE
/**
* @brief Adds an uint32_t as trace event payload
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[in] value Value.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceEventAdd32 TRC_EVENT_ADD_32
/**
* @brief Adds an uint16_t as trace event payload
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[in] value Value.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceEventAdd16 TRC_EVENT_ADD_16
/**
* @brief Adds an uint8_t as trace event payload.
*
* @param[in] xEventHandle Pointer to initialized trace event.
* @param[in] value Value.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceEventAdd8 TRC_EVENT_ADD_8
#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
#endif /* TRC_EVENT_H */

View File

@@ -0,0 +1,180 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace event buffer APIs.
*/
#ifndef TRC_EVENT_BUFFER_H
#define TRC_EVENT_BUFFER_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup trace_event_buffer_apis Trace Event Buffer APIs
* @ingroup trace_recorder_apis
* @{
*/
/**
* @def TRC_EVENT_BUFFER_OPTION_SKIP
* @brief Buffer should skip new events when full
*/
#define TRC_EVENT_BUFFER_OPTION_SKIP (0U)
/**
* @def TRC_EVENT_BUFFER_OPTION_OVERWRITE
* @brief Buffer should overwrite old events when full
*/
#define TRC_EVENT_BUFFER_OPTION_OVERWRITE (1U)
/**
* @brief Trace Event Buffer Structure
*/
typedef struct TraceEventBuffer /* Aligned */
{
uint32_t uiHead; /**< Head index of buffer */
uint32_t uiTail; /**< Tail index of buffer */
uint32_t uiSize; /**< Buffer size */
uint32_t uiOptions; /**< Options (skip/overwrite when full) */
uint32_t uiDroppedEvents; /**< Nr of dropped events */
uint32_t uiFree; /**< Nr of free bytes */
uint32_t uiSlack; /**< */
uint32_t uiNextHead; /**< */
uint32_t uiTimerWraparounds; /**< Nr of timer wraparounds */
uint32_t uiReserved; /**< Reserved */
uint8_t* puiBuffer; /**< Trace Event Buffer: may be NULL */
} TraceEventBuffer_t;
/**
* @internal Initialize trace event buffer.
*
* This routine initializes a trace event buffer and assigns it a
* memory area based on the supplied buffer.
*
* Trace event buffer options specifies the buffer behavior regarding
* old data, the alternatives are TRC_EVENT_BUFFER_OPTION_SKIP and
* TRC_EVENT_BUFFER_OPTION_OVERWRITE (mutual exclusive).
*
* @param[out] pxTraceEventBuffer Pointer to uninitialized trace event buffer.
* @param[in] uiOptions Trace event buffer options.
* @param[in] puiBuffer Pointer to buffer that will be used by the trace event buffer.
* @param[in] uiSize Size of buffer
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventBufferInitialize(TraceEventBuffer_t *pxTraceEventBuffer, uint32_t uiOptions,
uint8_t *puiBuffer, uint32_t uiSize);
/**
* @brief Allocates a data slot directly from the event buffer.
*
* @param[in] pxTraceEventBuffer Pointer to initialized trace event buffer.
* @param[in] uiSize Allocation size
* @param[out] ppvData Pointer that will hold the area from the buffer.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventBufferAlloc(TraceEventBuffer_t *pxTraceEventBuffer, uint32_t uiSize, void **ppvData);
/**
* @brief Commits the last allocated block to the event buffer.
*
* @param[in] pxTraceEventBuffer Pointer to initialized trace event buffer.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventBufferAllocCommit(TraceEventBuffer_t *pxTraceEventBuffer, const void *pvData, uint32_t uiSize, int32_t *piBytesWritten);
/**
* @brief Pushes data into trace event buffer.
*
* This routine attempts to push data into the trace event buffer.
*
* @param[in] pxTraceEventBuffer Pointer to initialized trace event buffer.
* @param[in] pvData Pointer to data that should be pushed into trace event buffer.
* @param[in] uiSize Size of data.
* @param[out] piBytesWritten Bytes written.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventBufferPush(TraceEventBuffer_t *pxTraceEventBuffer, void *pvData, uint32_t uiSize, int32_t *piBytesWritten);
/**
* @brief Transfer trace event buffer data through streamport.
*
* This routine will attempt to transfer all existing data in the trace event
* buffer through the streamport. New data pushed to the trace event buffer
* during the execution of this routine will not be transferred
*
* @param[in] pxTraceEventBuffer Pointer to initialized trace event buffer.
* @param[out] piBytesWritten Bytes written.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventBufferTransferAll(TraceEventBuffer_t* pxTraceEventBuffer, int32_t* piBytesWritten);
/**
* @brief Transfer trace event buffer data through streamport.
*
* This routine will attempt to transfer a chunk of existing data in the trace
* event buffer through the streamport. New data pushed to the trace event buffer
* during the execution of this routine will not be transfered.
*
* When transferring a chunk which wraps the buffer, a singular transfer
* is made to avoid issuing dual writes. This configuration means that
* during wrapping, the chunk might be reduced in size even if there is
* more data at the start of the buffer. To transfer more data check
* piBytesWritten and issue multiple transfers if required.
*
* @param[in] pxTraceEventBuffer Pointer to initialized trace event buffer.
* @param[out] piBytesWritten Bytes written.
* @param[in] uiChunkSize Maximum transfer chunk in bytes.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventBufferTransferChunk(TraceEventBuffer_t* pxTraceEventBuffer, uint32_t uiChunkSize, int32_t* piBytesWritten);
/**
* @brief Clears all data from event buffer.
*
* @param[in] pxTraceEventBuffer Pointer to initialized trace event buffer.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEventBufferClear(TraceEventBuffer_t* pxTraceEventBuffer);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
#endif /* TRC_EVENT_BUFFER_H */

View File

@@ -0,0 +1,110 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace extension APIs.
*/
#ifndef TRC_EXTENSION_H
#define TRC_EXTENSION_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
#define TRC_EXTENSION_STATE_INDEX_VERSION 0
#define TRC_EXTENSION_STATE_INDEX_BASE_EVENT_ID 1
#define TRC_EXTENSION_STATE_INDEX_EVENT_COUNT 2
/**
* @defgroup trace_extension_apis Trace Extension APIs
* @ingroup trace_recorder_apis
* @{
*/
typedef struct TraceExtensionData /* Aligned */
{
TraceUnsignedBaseType_t uxNextFreeExtensionEventId;
} TraceExtensionData_t;
/**
* @brief Initializes the Extension trace system
*
* @param[in] pxBuffer Pointer to memory that is used by the extension trace system
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceExtensionInitialize(TraceExtensionData_t* const pxBuffer);
/**
* @brief Creates trace extension.
*
* @param[in] szName Name.
* @param[in] uiMajor Major version.
* @param[in] uiMinor Minor version.
* @param[in] uiPatch Patch version.
* @param[in] uiEventCount Event count.
* @param[out] pxExtensionHandle Pointer to uninitialized extension handle.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceExtensionCreate(const char *szName, uint8_t uiMajor, uint8_t uiMinor, uint16_t uiPatch, uint32_t uiEventCount, TraceExtensionHandle_t *pxExtensionHandle);
/**
* @brief Gets extension base event id.
*
* @param[in] xExtensionHandle Pointer to initialized extension handle.
* @param[out] puiBaseEventId Base event id.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceExtensionGetBaseEventId(TraceExtensionHandle_t xExtensionHandle, uint32_t *puiBaseEventId);
/**
* @brief Gets extension configuration name.
*
* @param[in] xExtensionHandle Pointer to initialized extension handle.
* @param[out] pszName Name.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceExtensionGetConfigName(TraceExtensionHandle_t xExtensionHandle, const char** pszName);
/**
* @brief Returns extension event id.
*
* @param[in] xExtensionHandle Pointer to initialized extension handle.
* @param[in] uiLocalEventId Local event id.
*
* @returns Extension event id
*/
#define xTraceExtensionGetEventId(xExtensionHandle, uiLocalEventId) ((uint32_t)xTraceEntryGetStateReturn((TraceEntryHandle_t)(xExtensionHandle), TRC_EXTENSION_STATE_INDEX_BASE_EVENT_ID) + (uiLocalEventId))
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
#endif /* TRC_EXTENSION_H */

View File

@@ -0,0 +1,806 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The hardware abstraction layer for the trace recorder.
*/
#ifndef TRC_HARDWARE_PORT_H
#define TRC_HARDWARE_PORT_H
#include <trcDefines.h>
/*
* @brief
* This macro must be used as name for the variable in the critical section allocation.
* Example: #define TRACE_ALLOC_CRITICAL_SECION uint32_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
*/
#define TRACE_ALLOC_CRITICAL_SECTION_NAME xTraceCriticalSectionStatus
#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NOT_SET)
#error "TRC_CFG_HARDWARE_PORT not selected - see trcConfig.h"
#endif
/*******************************************************************************
* TRC_IRQ_PRIORITY_ORDER
*
* Macro which should be defined as an integer of 0 or 1.
*
* This should be 0 if lower IRQ priority values implies higher priority
* levels, such as on ARM Cortex M. If the opposite scheme is used, i.e.,
* if higher IRQ priority values means higher priority, this should be 1.
*
* This setting is not critical. It is used only to sort and colorize the
* interrupts in priority order, in case you record interrupts using
* the vTraceStoreISRBegin and vTraceStoreISREnd routines.
*
******************************************************************************
*
* HWTC Macros
*
* These macros provides a hardware isolation layer representing the
* hardware timer/counter used for the event timestamping.
*
* TRC_HWTC_COUNT: How to read the current value of the timer/counter.
*
* TRC_HWTC_TYPE: Tells the type of timer/counter used for TRC_HWTC_COUNT:
*
* - TRC_FREE_RUNNING_32BIT_INCR:
* Free-running 32-bit timer/counter, counting upwards from 0.
*
* - TRC_FREE_RUNNING_32BIT_DECR
* Free-running 32-bit timer/counter, counting downwards from 0xFFFFFFFF.
*
* - TRC_OS_TIMER_INCR
* Periodic timer that drives the OS tick interrupt, counting upwards
* from 0 until (TRC_HWTC_PERIOD-1).
*
* - TRC_OS_TIMER_DECR
* Periodic timer that drives the OS tick interrupt, counting downwards
* from TRC_HWTC_PERIOD-1 until 0.
*
* - TRC_CUSTOM_TIMER_INCR
* A custom timer or counter independent of the OS tick, counting
* downwards from TRC_HWTC_PERIOD-1 until 0. (Currently only supported
* in streaming mode).
*
* - TRC_CUSTOM_TIMER_DECR
* A custom timer independent of the OS tick, counting downwards
* from TRC_HWTC_PERIOD-1 until 0. (Currently only supported
* in streaming mode).
*
* TRC_HWTC_PERIOD: The number of HWTC_COUNT ticks until the timer wraps
* around. If using TRC_FREE_RUNNING_32BIT_INCR/DECR, this should be 0.
*
* TRC_HWTC_FREQ_HZ: The clock rate of the TRC_HWTC_COUNT counter in Hz. If using
* TRC_OS_TIMER_INCR/DECR, this is should be TRC_HWTC_PERIOD * TRC_TICK_RATE_HZ.
* If using a free-running timer, this is often TRACE_CPU_CLOCK_HZ (if running at
* the core clock rate). If using TRC_CUSTOM_TIMER_INCR/DECR, this should match
* the clock rate of your custom timer (i.e., TRC_HWTC_COUNT). If the default value
* of TRC_HWTC_FREQ_HZ is incorrect for your setup, you can override it by calling
* vTraceSetFrequency before calling vTraceEnable.
*
* TRC_HWTC_DIVISOR (used in snapshot mode only):
* In snapshot mode, the timestamp resolution is TRC_HWTC_FREQ_HZ/TRC_HWTC_DIVISOR.
* If the timer frequency is very high (hundreds of MHz), we recommend increasing
* the TRC_HWTC_DIVISOR prescaler, to reduce the bandwidth needed to store
* timestamps. This since extra "XTS" events are inserted if the time since the
* previous event exceeds a certain limit (255 or 65535 depending on event type).
* It is advised to keep the time between most events below 65535 native ticks
* (after division by TRC_HWTC_DIVISOR) to avoid frequent XTS events.
******************************************************************************/
#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NOT_SET)
#error "TRC_CFG_HARDWARE_PORT not selected - see trcConfig.h"
#endif
#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win32)
/* This can be used as a template for any free-running 32-bit counter */
void vTraceTimerReset(void);
uint32_t uiTraceTimerGetFrequency(void);
uint32_t uiTraceTimerGetValue(void);
#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
#define TRC_HWTC_COUNT ((TraceUnsignedBaseType_t)uiTraceTimerGetValue())
#define TRC_HWTC_PERIOD 0
#define TRC_HWTC_DIVISOR 1
#define TRC_HWTC_FREQ_HZ ((TraceUnsignedBaseType_t)uiTraceTimerGetFrequency())
#define TRC_IRQ_PRIORITY_ORDER 1
#define TRC_PORT_SPECIFIC_INIT() vTraceTimerReset()
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win64)
/* This can be used as a template for any free-running 32-bit counter */
void vTraceTimerReset(void);
uint32_t uiTraceTimerGetFrequency(void);
uint32_t uiTraceTimerGetValue(void);
#define TRC_BASE_TYPE int64_t
#define TRC_UNSIGNED_BASE_TYPE uint64_t
#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
#define TRC_HWTC_COUNT ((TraceUnsignedBaseType_t)uiTraceTimerGetValue())
#define TRC_HWTC_PERIOD 0
#define TRC_HWTC_DIVISOR 1
#define TRC_HWTC_FREQ_HZ ((TraceUnsignedBaseType_t)uiTraceTimerGetFrequency())
#define TRC_IRQ_PRIORITY_ORDER 1
#define TRC_PORT_SPECIFIC_INIT() vTraceTimerReset()
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_HWIndependent)
/* Timestamping by OS tick only (typically 1 ms resolution) */
#define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
#define TRC_HWTC_COUNT 0
#define TRC_HWTC_PERIOD 1
#define TRC_HWTC_DIVISOR 1
#define TRC_HWTC_FREQ_HZ TRC_TICK_RATE_HZ
/* Set the meaning of IRQ priorities in ISR tracing - see above */
// #define TRC_IRQ_PRIORITY_ORDER NOT_SET
#define TRC_IRQ_PRIORITY_ORDER 0
#elif ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M_NRF_SD))
#ifndef __CORTEX_M
#error "Can't find the CMSIS API. Please include your processor's header file in trcConfig.h"
#endif
#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M)
#define TRACE_ALLOC_CRITICAL_SECTION() TraceUnsignedBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
#define TRACE_ENTER_CRITICAL_SECTION() {TRACE_ALLOC_CRITICAL_SECTION_NAME = __get_PRIMASK(); __set_PRIMASK(1);} /* PRIMASK disables ALL interrupts - allows for tracing in any ISR */
#define TRACE_EXIT_CRITICAL_SECTION() {__set_PRIMASK(TRACE_ALLOC_CRITICAL_SECTION_NAME);}
#else
#include "nrf_nvic.h"
#define TRACE_ALLOC_CRITICAL_SECTION() TraceUnsignedBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
#define TRACE_ENTER_CRITICAL_SECTION() {(void) sd_nvic_critical_region_enter((uint8_t*)&TRACE_ALLOC_CRITICAL_SECTION_NAME);}
#define TRACE_EXIT_CRITICAL_SECTION() {(void) sd_nvic_critical_region_exit((uint8_t)TRACE_ALLOC_CRITICAL_SECTION_NAME);}
#endif
/**************************************************************************
* For Cortex-M3, M4 and M7, the DWT cycle counter is used for timestamping.
* For Cortex-M0 and M0+, the SysTick timer is used since DWT is not
* available. Systick timestamping can also be forced on Cortex-M3, M4 and
* M7 by defining the preprocessor directive TRC_CFG_ARM_CM_USE_SYSTICK,
* either directly below or in trcConfig.h.
*
* #define TRC_CFG_ARM_CM_USE_SYSTICK
**************************************************************************/
#if ((__CORTEX_M >= 0x03) && (! defined TRC_CFG_ARM_CM_USE_SYSTICK))
void xTraceHardwarePortInitCortexM(void);
#define TRC_REG_DEMCR (*(volatile uint32_t*)0xE000EDFC)
#define TRC_REG_DWT_CTRL (*(volatile uint32_t*)0xE0001000)
#define TRC_REG_DWT_CYCCNT (*(volatile uint32_t*)0xE0001004)
#define TRC_REG_DWT_EXCCNT (*(volatile uint32_t*)0xE000100C)
#define TRC_REG_ITM_LOCKACCESS (*(volatile uint32_t*)0xE0001FB0)
#define TRC_ITM_LOCKACCESS_UNLOCK (0xC5ACCE55)
/* Bit mask for TRCENA bit in DEMCR - Global enable for DWT and ITM */
#define TRC_DEMCR_TRCENA (1 << 24)
/* Bit mask for NOPRFCNT bit in DWT_CTRL. If 1, DWT_EXCCNT is not supported */
#define TRC_DWT_CTRL_NOPRFCNT (1 << 24)
/* Bit mask for NOCYCCNT bit in DWT_CTRL. If 1, DWT_CYCCNT is not supported */
#define TRC_DWT_CTRL_NOCYCCNT (1 << 25)
/* Bit mask for EXCEVTENA_ bit in DWT_CTRL. Set to 1 to enable DWT_EXCCNT */
#define TRC_DWT_CTRL_EXCEVTENA (1 << 18)
/* Bit mask for EXCEVTENA_ bit in DWT_CTRL. Set to 1 to enable DWT_CYCCNT */
#define TRC_DWT_CTRL_CYCCNTENA (1)
#define TRC_PORT_SPECIFIC_INIT() xTraceHardwarePortInitCortexM()
#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
#define TRC_HWTC_COUNT TRC_REG_DWT_CYCCNT
#define TRC_HWTC_PERIOD 0
#define TRC_HWTC_DIVISOR 4
#define TRC_HWTC_FREQ_HZ TRACE_CPU_CLOCK_HZ
#define TRC_IRQ_PRIORITY_ORDER 0
#else
/* Uses the lower bits of the 64-bit free running timer in the RP2040. SysTick can not be used since it is different for both cores. */
#ifdef _CMSIS_RP2040_H_
#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
#define TRC_HWTC_COUNT (*((volatile uint32_t*)0x4005400c))
#define TRC_HWTC_PERIOD 0
#define TRC_HWTC_DIVISOR 1
#define TRC_HWTC_FREQ_HZ 1000000
#define TRC_IRQ_PRIORITY_ORDER 0
#else
#define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
#define TRC_HWTC_COUNT (*((volatile uint32_t*)0xE000E018))
#define TRC_HWTC_PERIOD ((*((volatile uint32_t*)0xE000E014)) + 1)
#define TRC_HWTC_DIVISOR 4
#define TRC_HWTC_FREQ_HZ TRACE_CPU_CLOCK_HZ
#define TRC_IRQ_PRIORITY_ORDER 0
#endif
#endif
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Renesas_RX600)
#define TRACE_ALLOC_CRITICAL_SECTION() TraceBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
#define TRACE_ENTER_CRITICAL_SECTION() { TRACE_ALLOC_CRITICAL_SECTION_NAME = TRC_KERNEL_PORT_SET_INTERRUPT_MASK(); }
#define TRACE_EXIT_CRITICAL_SECTION() { TRC_KERNEL_PORT_CLEAR_INTERRUPT_MASK(TRACE_ALLOC_CRITICAL_SECTION_NAME); }
#include <iodefine.h>
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
#define TRC_HWTC_COUNT (CMT0.CMCNT)
#elif (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
/* Decreasing counters better for Tickless Idle? */
#define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
#define TRC_HWTC_COUNT (CMT0.CMCOR - CMT0.CMCNT)
#endif
#define TRC_HWTC_PERIOD (CMT0.CMCOR + 1)
#define TRC_HWTC_DIVISOR 1
#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
#define TRC_IRQ_PRIORITY_ORDER 1
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_MICROCHIP_PIC24_PIC32)
#define TRACE_ALLOC_CRITICAL_SECTION() TraceBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
#define TRACE_ENTER_CRITICAL_SECTION() { TRACE_ALLOC_CRITICAL_SECTION_NAME = TRC_KERNEL_PORT_SET_INTERRUPT_MASK(); }
#define TRACE_EXIT_CRITICAL_SECTION() { TRC_KERNEL_PORT_CLEAR_INTERRUPT_MASK(TRACE_ALLOC_CRITICAL_SECTION_NAME); }
#define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
#define TRC_HWTC_COUNT (TMR1)
#define TRC_HWTC_PERIOD (PR1 + 1)
#define TRC_HWTC_DIVISOR 1
#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
#define TRC_IRQ_PRIORITY_ORDER 1
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48)
#define TRC_RTIFRC0 *((uint32_t *)0xFFFFFC10)
#define TRC_RTICOMP0 *((uint32_t *)0xFFFFFC50)
#define TRC_RTIUDCP0 *((uint32_t *)0xFFFFFC54)
#define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
#define TRC_HWTC_COUNT (TRC_RTIFRC0 - (TRC_RTICOMP0 - TRC_RTIUDCP0))
#define TRC_HWTC_PERIOD (TRC_RTIUDCP0)
#define TRC_HWTC_DIVISOR 1
#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
#define TRC_IRQ_PRIORITY_ORDER 0
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Atmel_AT91SAM7)
/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
#define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
#define TRC_HWTC_COUNT ((uint32_t)(AT91C_BASE_PITC->PITC_PIIR & 0xFFFFF))
#define TRC_HWTC_PERIOD ((uint32_t)(AT91C_BASE_PITC->PITC_PIMR + 1))
#define TRC_HWTC_DIVISOR 1
#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
#define TRC_IRQ_PRIORITY_ORDER 1
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Atmel_UC3A0)
/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO*/
/* For Atmel AVR32 (AT32UC3A) */
#define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
#define TRC_HWTC_COUNT ((uint32_t)sysreg_read(AVR32_COUNT))
#define TRC_HWTC_PERIOD ((uint32_t)(sysreg_read(AVR32_COMPARE) + 1))
#define TRC_HWTC_DIVISOR 1
#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
#define TRC_IRQ_PRIORITY_ORDER 1
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NXP_LPC210X)
/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
/* Tested with LPC2106, but should work with most LPC21XX chips. */
#define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
#define TRC_HWTC_COUNT *((uint32_t *)0xE0004008 )
#define TRC_HWTC_PERIOD *((uint32_t *)0xE0004018 )
#define TRC_HWTC_DIVISOR 1
#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
#define TRC_IRQ_PRIORITY_ORDER 0
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_MSP430)
/* UNOFFICIAL PORT - NOT YET VERIFIED */
#define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
#define TRC_HWTC_COUNT (TA0R)
#define TRC_HWTC_PERIOD (((uint16_t)TACCR0)+1)
#define TRC_HWTC_DIVISOR 1
#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
#define TRC_IRQ_PRIORITY_ORDER 1
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_PPC405)
/* UNOFFICIAL PORT - NOT YET VERIFIED */
#define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
#define TRC_HWTC_COUNT mfspr(0x3db)
#define TRC_HWTC_PERIOD (TRACE_CPU_CLOCK_HZ / TRC_TICK_RATE_HZ)
#define TRC_HWTC_DIVISOR 1
#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
#define TRC_IRQ_PRIORITY_ORDER 0
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_PPC440)
/* UNOFFICIAL PORT */
/* This should work with most PowerPC chips */
#define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
#define TRC_HWTC_COUNT mfspr(0x016)
#define TRC_HWTC_PERIOD (TRACE_CPU_CLOCK_HZ / TRC_TICK_RATE_HZ)
#define TRC_HWTC_DIVISOR 1
#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
#define TRC_IRQ_PRIORITY_ORDER 0
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_MICROBLAZE)
/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
/* This should work with most Microblaze configurations.
* It uses the AXI Timer 0 - the tick interrupt source.
* If an AXI Timer 0 peripheral is available on your hardware platform, no modifications are required.
*/
#include <xtmrctr_l.h>
#define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
#define TRC_HWTC_COUNT XTmrCtr_GetTimerCounterReg( XPAR_TMRCTR_0_BASEADDR, 0 )
#define TRC_HWTC_PERIOD (XTmrCtr_GetLoadReg( XPAR_TMRCTR_0_BASEADDR, 0) + 1)
#define TRC_HWTC_DIVISOR 16
#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
#define TRC_IRQ_PRIORITY_ORDER 0
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_ZyncUltraScaleR5)
extern TraceUnsignedBaseType_t cortex_a9_r5_enter_critical(void);
extern void cortex_a9_r5_exit_critical(TraceUnsignedBaseType_t irq_already_masked_at_enter);
#define TRACE_ALLOC_CRITICAL_SECTION() TraceUnsignedBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
#define TRACE_ENTER_CRITICAL_SECTION() { TRACE_ALLOC_CRITICAL_SECTION_NAME = cortex_a9_r5_enter_critical(); }
#define TRACE_EXIT_CRITICAL_SECTION() { cortex_a9_r5_exit_critical(TRACE_ALLOC_CRITICAL_SECTION_NAME); }
#include <xttcps_hw.h>
#define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
#define TRC_HWTC_COUNT (*(volatile uint32_t *)(configTIMER_BASEADDR + XTTCPS_COUNT_VALUE_OFFSET))
#define TRC_HWTC_PERIOD (*(volatile uint32_t *)(configTIMER_BASEADDR + XTTCPS_INTERVAL_VAL_OFFSET))
#define TRC_HWTC_DIVISOR 16
#define TRC_HWTC_FREQ_HZ (TRC_HWTC_PERIOD * TRC_TICK_RATE_HZ)
#define TRC_IRQ_PRIORITY_ORDER 0
#ifdef __GNUC__
static inline uint32_t prvGetCPSR(void)
{
unsigned long ret;
/* GCC-style assembly for getting the CPSR/APSR register, where the system execution mode is found. */
asm volatile (" mrs %0, cpsr" : "=r" (ret) : /* no inputs */ );
return ret;
}
#else
#error "Only GCC Supported!"
#endif
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Altera_NiosII)
/* OFFICIAL PORT */
#include <system.h>
#include <altera_avalon_timer_regs.h>
#include <sys/alt_irq.h>
#define TRACE_ALLOC_CRITICAL_SECTION() alt_irq_context TRACE_ALLOC_CRITICAL_SECTION_NAME;
#define TRACE_ENTER_CRITICAL_SECTION(){TRACE_ALLOC_CRITICAL_SECTION_NAME = alt_irq_disable_all();}
#define TRACE_EXIT_CRITICAL_SECTION() {alt_irq_enable_all(TRACE_ALLOC_CRITICAL_SECTION_NAME);}
#define NOT_SET 1
/* The base address for the sustem timer set.
* The name user for the system timer can be found in the BSP editor.
* If the name of the timer is sys_tmr SYSTEM_TIMER_BASE should be set to SYS_TMR_BASE.
*/
#define SYSTEM_TIMER_BASE NOT_SET
#if (SYSTEM_TIMER == NOT_SET)
#error "Set SYSTEM_TIMER_BASE to the timer base used for system ticks."
#endif
static inline uint32_t altera_nios2_GetTimerSnapReg(void)
{
/* A processor can read the current counter value by first writing to either snapl or snaph to request a coherent snapshot of the counter,
* and then reading snapl and snaph for the full 32-bit value.
*/
IOWR_ALTERA_AVALON_TIMER_SNAPL(SYSTEM_TIMER_BASE, 0);
return (IORD_ALTERA_AVALON_TIMER_SNAPH(SYSTEM_TIMER_BASE) << 16) | IORD_ALTERA_AVALON_TIMER_SNAPL(SYSTEM_TIMER_BASE);
}
#define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
#define TRC_HWTC_COUNT altera_nios2_GetTimerSnapReg()
#define TRC_HWTC_PERIOD (configCPU_CLOCK_HZ / configTICK_RATE_HZ )
#define TRC_HWTC_DIVISOR 16
#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
#define TRC_IRQ_PRIORITY_ORDER 0
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9)
/**************************************************************************
* This hardware port only supports FreeRTOS and the GCC compiler at the
* moment, due to the implementation of critical sections (trcKernelPort.h).
*
* Assuming FreeRTOS is used:
*
* For critical sections, this uses vTaskEnterCritical is when called from
* task context and ulPortSetInterruptMask when called from ISR context.
* Thus, it does not disable all ISRs. This means that the trace recorder
* can only be called from ISRs with priority less or equal to
* configMAX_API_CALL_INTERRUPT_PRIORITY (like FreeRTOS fromISR functions).
*
* This hardware port has been tested on a Xilinx Zync 7000 (Cortex-A9).
**************************************************************************/
extern TraceUnsignedBaseType_t cortex_a9_r5_enter_critical(void);
extern void cortex_a9_r5_exit_critical(TraceUnsignedBaseType_t irq_already_masked_at_enter);
#define TRACE_ALLOC_CRITICAL_SECTION() TraceUnsignedBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
#define TRACE_ENTER_CRITICAL_SECTION() { TRACE_ALLOC_CRITICAL_SECTION_NAME = cortex_a9_r5_enter_critical(); }
#define TRACE_EXIT_CRITICAL_SECTION() { cortex_a9_r5_exit_critical(TRACE_ALLOC_CRITICAL_SECTION_NAME); }
/* INPUT YOUR PERIPHERAL BASE ADDRESS HERE (0xF8F00000 for Xilinx Zynq 7000)*/
#define TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS 0
#if (TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS == 0)
#error "Please specify TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS."
#endif
#define TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET 0x0600
#define TRC_CA9_MPCORE_PRIVCTR_PERIOD_REG (*(volatile uint32_t*)(TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x00))
#define TRC_CA9_MPCORE_PRIVCTR_COUNTER_REG (*(volatile uint32_t*)(TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x04))
#define TRC_CA9_MPCORE_PRIVCTR_CONTROL_REG (*(volatile uint32_t*)(TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x08))
#define TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK 0x0000FF00
#define TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT 8
#define TRC_CA9_MPCORE_PRIVCTR_PRESCALER (((TRC_CA9_MPCORE_PRIVCTR_CONTROL_REG & TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK) >> TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT) + 1)
#define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
#define TRC_HWTC_COUNT TRC_CA9_MPCORE_PRIVCTR_COUNTER_REG
#define TRC_HWTC_PERIOD (TRC_CA9_MPCORE_PRIVCTR_PERIOD_REG + 1)
/****************************************************************************************
NOTE: The private timer ticks with a very high frequency (half the core-clock usually),
depending on the prescaler used. If a low prescaler is used, the number of HW ticks between
the trace events gets large, and thereby inefficient to store (sometimes extra events are
needed). To improve efficiency, you may use the TRC_HWTC_DIVISOR as an additional prescaler.
*****************************************************************************************/
#define TRC_HWTC_DIVISOR 1
#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
#define TRC_IRQ_PRIORITY_ORDER 0
#ifdef __GNUC__
static inline uint32_t prvGetCPSR(void)
{
unsigned long ret;
/* GCC-style assembly for getting the CPSR/APSR register, where the system execution mode is found. */
asm volatile (" mrs %0, cpsr" : "=r" (ret) : /* no inputs */ );
return ret;
}
#else
#error "Only GCC Supported!"
#endif
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_CYCLONE_V_HPS)
#include "alt_clock_manager.h"
extern TraceUnsignedBaseType_t cortex_a9_r5_enter_critical(void);
extern void cortex_a9_r5_exit_critical(TraceUnsignedBaseType_t irq_already_masked_at_enter);
#define TRACE_ALLOC_CRITICAL_SECTION() TraceUnsignedBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
#define TRACE_ENTER_CRITICAL_SECTION() { TRACE_ALLOC_CRITICAL_SECTION_NAME = cortex_a9_r5_enter_critical(); }
#define TRACE_EXIT_CRITICAL_SECTION() { cortex_a9_r5_exit_critical(TRACE_ALLOC_CRITICAL_SECTION_NAME); }
#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
#define TRC_HWTC_COUNT *((uint32_t *)0xFFFEC200)
#define TRC_HWTC_PERIOD 0
#define TRC_HWTC_DIVISOR 1
#define TRC_HWTC_FREQ_HZ (({ \
uint32_t __freq; \
alt_clk_freq_get( ALT_CLK_MPU_PERIPH, &__freq ); \
__freq; \
}))
#define TRC_IRQ_PRIORITY_ORDER 0
#ifdef __GNUC__
/* For Arm Cortex-A and Cortex-R in general. */
static inline uint32_t prvGetCPSR(void)
{
unsigned long ret;
/* GCC-style assembly for getting the CPSR/APSR register, where the system execution mode is found. */
__asm__ __volatile__(" mrs %0, cpsr" : "=r" (ret) : /* no inputs */ );
return ret;
}
#else
#error "Only GCC Supported!"
#endif
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ZEPHYR)
#ifdef CONFIG_64BIT
#define TRC_BASE_TYPE int64_t
#define TRC_UNSIGNED_BASE_TYPE uint64_t
#else
#define TRC_BASE_TYPE int32_t
#define TRC_UNSIGNED_BASE_TYPE uint32_t
#endif
#define TRACE_ALLOC_CRITICAL_SECTION() TraceBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
#define TRACE_ENTER_CRITICAL_SECTION() { TRACE_ALLOC_CRITICAL_SECTION_NAME = irq_lock(); }
#define TRACE_EXIT_CRITICAL_SECTION() { irq_unlock(TRACE_ALLOC_CRITICAL_SECTION_NAME); }
#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
#define TRC_HWTC_COUNT k_cycle_get_32()
#define TRC_HWTC_PERIOD (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / CONFIG_SYS_CLOCK_TICKS_PER_SEC)
#define TRC_HWTC_DIVISOR 4
#define TRC_HWTC_FREQ_HZ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
#define TRC_IRQ_PRIORITY_ORDER 0 // Lower IRQ priority values are more significant
#define TRC_PORT_SPECIFIC_INIT()
#elif ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XTensa_LX6) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XTensa_LX7))
/**
* @note When running with SMP FreeRTOS we cannot use the CCOUNT register for timestamping,
* instead we use the external 40MHz timer for synchronized timestamping between the cores.
*/
#if CONFIG_FREERTOS_UNICORE == 1
#define TRACE_ALLOC_CRITICAL_SECTION() TraceUnsignedBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
#define TRACE_ENTER_CRITICAL_SECTION() {TRACE_ALLOC_CRITICAL_SECTION_NAME = __extension__({ unsigned __tmp; \
__asm__ __volatile__("rsil %0, 15\n" \
: "=a" (__tmp) : : "memory" ); \
__tmp;});}
#define TRACE_EXIT_CRITICAL_SECTION() {portCLEAR_INTERRUPT_MASK_FROM_ISR(TRACE_ALLOC_CRITICAL_SECTION_NAME);}
#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
#define TRC_HWTC_COUNT ({ unsigned int __ccount; \
__asm__ __volatile__("rsr.ccount %0" : "=a"(__ccount)); \
__ccount; })
#ifdef CONFIG_IDF_TARGET_ESP32
#define TRC_HWTC_FREQ_HZ (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ * 1000000)
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
#define TRC_HWTC_FREQ_HZ (CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ * 1000000)
#else
#error "Invalid IDF target, check your sdkconfig."
#endif
#define TRC_HWTC_PERIOD 0
#define TRC_HWTC_DIVISOR 4
#define TRC_IRQ_PRIORITY_ORDER 0
#else
/**
* @brief Fetch core agnostic timestamp using the external boot timestamp timer used by ESP IDF.
*
* @return Ticks since the timer started
*/
uint32_t prvGetSMPTimestamp();
#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
#define TRC_HWTC_COUNT prvGetSMPTimestamp()
#define TRC_HWTC_FREQ_HZ 1000000
#define TRC_HWTC_PERIOD 0
#define TRC_HWTC_DIVISOR 4
#define TRC_IRQ_PRIORITY_ORDER 0
#endif
#if !defined(TRC_HWTC_FREQ_HZ)
#error "The XTensa LX6/LX7 trace hardware clock frequency is not defined."
#endif
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_RISCV_RV32I)
// #include "core_feature_timer.h"
#include <stddef.h>
#include "arcs_ap_base.h"
#include "nmsis_core.h"
#define TRACE_ALLOC_CRITICAL_SECTION() TraceUnsignedBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
#define TRACE_ENTER_CRITICAL_SECTION() __asm__ __volatile__("csrr %0, mstatus \n\t" \
"csrci mstatus, 8 \n\t" \
"andi %0, %0, 8 \n\t" \
: "=r"(TRACE_ALLOC_CRITICAL_SECTION_NAME))
#define TRACE_EXIT_CRITICAL_SECTION() __asm__ __volatile__("csrr a1, mstatus \n\t" \
"or %0, %0, a1 \n\t" \
"csrs mstatus, %0 \n\t" \
: \
: "r" (TRACE_ALLOC_CRITICAL_SECTION_NAME) \
: "a1")
#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
#define TRC_HWTC_COUNT ({ unsigned int __count; \
uint8_t *addr; \
addr = (uint8_t *)(&(SysTimer->MTIMER)); \
__count = __LW(addr); \
__count; })
#define TRC_HWTC_PERIOD 0
#define TRC_HWTC_DIVISOR 1
#define TRC_HWTC_FREQ_HZ 1000000
#define TRC_IRQ_PRIORITY_ORDER 0
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XMOS_XCOREAI)
#define TRC_PORT_SPECIFIC_INIT()
#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
#define TRC_HWTC_COUNT xscope_gettime()
#define TRC_HWTC_PERIOD (configCPU_CLOCK_HZ / configTICK_RATE_HZ )
#define TRC_HWTC_DIVISOR 4
#define TRC_HWTC_FREQ_HZ 100000000
#define TRC_IRQ_PRIORITY_ORDER 0
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_POWERPC_Z4)
/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
#define TRACE_ALLOC_CRITICAL_SECTION() TraceBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
#define TRACE_ENTER_CRITICAL_SECTION() { TRACE_ALLOC_CRITICAL_SECTION_NAME = TRC_KERNEL_PORT_SET_INTERRUPT_MASK(); }
#define TRACE_EXIT_CRITICAL_SECTION() { TRC_KERNEL_PORT_CLEAR_INTERRUPT_MASK(TRACE_ALLOC_CRITICAL_SECTION_NAME); }
#define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
//#define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
#define TRC_HWTC_COUNT PIT.TIMER[configTICK_PIT_CHANNEL].CVAL.R // must be the PIT channel used for the systick
#define TRC_HWTC_PERIOD ((configPIT_CLOCK_HZ / configTICK_RATE_HZ) - 1U) // TODO FIXME or maybe not -1? what's the right "period" value?
#define TRC_HWTC_FREQ_HZ configPIT_CLOCK_HZ
#define TRC_HWTC_DIVISOR 1
#define TRC_IRQ_PRIORITY_ORDER 1 // higher IRQ priority values are more significant
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARMv8AR_A32)
extern TraceUnsignedBaseType_t cortex_a9_r5_enter_critical(void);
extern void cortex_a9_r5_exit_critical(TraceUnsignedBaseType_t irq_already_masked_at_enter);
#define TRACE_ALLOC_CRITICAL_SECTION() TraceUnsignedBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
#define TRACE_ENTER_CRITICAL_SECTION() { TRACE_ALLOC_CRITICAL_SECTION_NAME = cortex_a9_r5_enter_critical(); }
#define TRACE_EXIT_CRITICAL_SECTION() { cortex_a9_r5_exit_critical(TRACE_ALLOC_CRITICAL_SECTION_NAME); }
#include <cmsis_compiler.h>
#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
#define TRC_HWTC_COUNT ((uint32_t)__get_CNTPCT())
#define TRC_HWTC_PERIOD 0
#define TRC_HWTC_DIVISOR 16
#define TRC_HWTC_FREQ_HZ (R_GSC->CNTFID0)
#define TRC_IRQ_PRIORITY_ORDER 0
#ifdef __GNUC__
/* For Arm Cortex-A and Cortex-R in general. */
static inline uint32_t prvGetCPSR(void)
{
unsigned long ret;
/* GCC-style assembly for getting the CPSR/APSR register, where the system execution mode is found. */
__asm volatile (" mrs %0, cpsr" : "=r" (ret) : /* no inputs */ );
return ret;
}
#else
#error "Only GCC Supported!"
#endif
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_APPLICATION_DEFINED)
#if !( defined (TRC_HWTC_TYPE) && defined (TRC_HWTC_COUNT) && defined (TRC_HWTC_PERIOD) && defined (TRC_HWTC_FREQ_HZ) && defined (TRC_IRQ_PRIORITY_ORDER) )
#error "The hardware port is not completely defined!"
#endif
#elif (TRC_CFG_HARDWARE_PORT != TRC_HARDWARE_PORT_NOT_SET)
#error "TRC_CFG_HARDWARE_PORT had unsupported value!"
#define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_NOT_SET
#endif
#ifndef TRC_HWTC_DIVISOR
#define TRC_HWTC_DIVISOR 1
#endif
#ifndef TRC_PORT_SPECIFIC_INIT
#define TRC_PORT_SPECIFIC_INIT()
#endif
/* If Win32 port */
#ifdef WIN32
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0600
/* Standard includes. */
#include <stdio.h>
#include <windows.h>
#include <direct.h>
/***************************************************************************
* The Win32 port by default saves the trace to file and then kills the
* program when the recorder is stopped, to facilitate quick, simple tests
* of the recorder.
***************************************************************************/
#define WIN32_PORT_SAVE_WHEN_STOPPED 1
#define WIN32_PORT_EXIT_WHEN_STOPPED 1
#endif
#if (TRC_CFG_HARDWARE_PORT != TRC_HARDWARE_PORT_NOT_SET)
#ifndef TRC_HWTC_TYPE
#error "TRC_HWTC_TYPE is not set!"
#endif
#ifndef TRC_HWTC_COUNT
#error "TRC_HWTC_COUNT is not set!"
#endif
#ifndef TRC_HWTC_PERIOD
#error "TRC_HWTC_PERIOD is not set!"
#endif
#ifndef TRC_HWTC_DIVISOR
#error "TRC_HWTC_DIVISOR is not set!"
#endif
#ifndef TRC_IRQ_PRIORITY_ORDER
#error "TRC_IRQ_PRIORITY_ORDER is not set!"
#elif (TRC_IRQ_PRIORITY_ORDER != 0) && (TRC_IRQ_PRIORITY_ORDER != 1)
#error "TRC_IRQ_PRIORITY_ORDER has bad value!"
#endif
#if (TRC_HWTC_DIVISOR < 1)
#error "TRC_HWTC_DIVISOR must be a non-zero positive value!"
#endif
#ifndef TRC_HWTC_FREQ_HZ
#error "TRC_HWTC_FREQ_HZ not defined!"
#endif
#endif
/* If a custom TRC_CFG_ALLOC_CRITICAL_SECTION is defined it will override the default definition */
#ifdef TRC_CFG_ALLOC_CRITICAL_SECTION
#undef TRACE_ALLOC_CRITICAL_SECTION
#define TRACE_ALLOC_CRITICAL_SECTION() TRC_CFG_ALLOC_CRITICAL_SECTION()
#endif
/* If a custom TRC_CFG_ENTER_CRITICAL_SECTION is defined it will override the default definition */
#ifdef TRC_CFG_ENTER_CRITICAL_SECTION
#undef TRACE_ENTER_CRITICAL_SECTION
#define TRACE_ENTER_CRITICAL_SECTION() TRC_CFG_ENTER_CRITICAL_SECTION()
#endif
/* If a custom TRC_CFG_EXIT_CRITICAL_SECTION is defined it will override the default definition */
#ifdef TRC_CFG_EXIT_CRITICAL_SECTION
#undef TRACE_EXIT_CRITICAL_SECTION
#define TRACE_EXIT_CRITICAL_SECTION() TRC_CFG_EXIT_CRITICAL_SECTION()
#endif
#ifndef TRACE_ALLOC_CRITICAL_SECTION
#define TRACE_ALLOC_CRITICAL_SECTION() TRC_KERNEL_PORT_ALLOC_CRITICAL_SECTION()
#endif
#ifndef TRACE_ENTER_CRITICAL_SECTION
#define TRACE_ENTER_CRITICAL_SECTION() TRC_KERNEL_PORT_ENTER_CRITICAL_SECTION()
#endif
#ifndef TRACE_EXIT_CRITICAL_SECTION
#define TRACE_EXIT_CRITICAL_SECTION() TRC_KERNEL_PORT_EXIT_CRITICAL_SECTION()
#endif
#endif /*TRC_HARDWARE_PORT_H*/

View File

@@ -0,0 +1,172 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace heap APIs.
*/
#ifndef TRC_HEAP_H
#define TRC_HEAP_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#ifndef TRC_USE_HEAPS
#define TRC_USE_HEAPS 1
#endif
#if (TRC_USE_HEAPS == 1)
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
#define TRC_HEAP_STATE_INDEX_CURRENT 0u
#define TRC_HEAP_STATE_INDEX_HIGHWATERMARK 1u
#define TRC_HEAP_STATE_INDEX_MAX 2u
/**
* @defgroup trace_heap_apis Trace Heap APIs
* @ingroup trace_recorder_apis
* @{
*/
/**
* @brief Creates trace heap.
*
* @param[in] szName Name.
* @param[in] uxCurrent Current level.
* @param[in] uxHighWaterMark High water mark
* @param[in] uxMax Maximum level.
* @param[out] pxHeapHandle Pointer to uninitialized trace heap handle.
* @return traceResult
*/
traceResult xTraceHeapCreate(const char *szName, TraceUnsignedBaseType_t uxCurrent, TraceUnsignedBaseType_t uxHighWaterMark, TraceUnsignedBaseType_t uxMax, TraceHeapHandle_t *pxHeapHandle);
/**
* @brief Signals trace heap alloc.
*
* @param[in] xHeapHandle Trace heap handle.
* @param[in] pvAddress Address.
* @param[in] uxSize Size.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceHeapAlloc(TraceHeapHandle_t xHeapHandle, void *pvAddress, TraceUnsignedBaseType_t uxSize);
/**
* @brief Signals trace heap free.
*
* @param[in] xHeapHandle Trace heap handle.
* @param[in] pvAddress Address.
* @param[in] uxSize Size.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceHeapFree(TraceHeapHandle_t xHeapHandle, void* pvAddress, TraceUnsignedBaseType_t uxSize);
/**
* @brief Gets trace heap current allocation size.
*
* @param[in] xHeapHandle Trace heap handle.
* @param[out] puxCurrent Current.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceHeapGetCurrent(xHeapHandle, puxCurrent) xTraceEntryGetState(xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, puxCurrent)
/**
* @brief Sets trace heap current allocation size.
*
* @param[in] xHeapHandle Trace heap handle.
* @param[in] uxCurrent Current.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceHeapSetCurrent(xHeapHandle, uxCurrent) xTraceEntrySetState(xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, uxCurrent)
/**
* @brief Gets trace heap high water mark.
*
* @param[in] xHeapHandle Trace heap handle.
* @param[out] puxHighWaterMark High water mark.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceHeapGetHighWaterMark(xHeapHandle, puxHighWaterMark) xTraceEntryGetState(xHeapHandle, TRC_HEAP_STATE_INDEX_HIGHWATERMARK, puxHighWaterMark)
/**
* @brief Sets trace heap high water mark.
*
* @param[in] xHeapHandle Trace heap handle.
* @param[in] uxHighWaterMark High water mark.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceHeapSetHighWaterMark(xHeapHandle, uxHighWaterMark) xTraceEntrySetState(xHeapHandle, TRC_HEAP_STATE_INDEX_HIGHWATERMARK, uxHighWaterMark)
/**
* @brief Gets trace heap max size.
*
* @param[in] xHeapHandle Trace heap handle.
* @param[out] puxMax Max.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceHeapGetMax(xHeapHandle, puxMax) xTraceEntryGetState(xHeapHandle, TRC_HEAP_STATE_INDEX_MAX, puxMax)
/**
* @brief Sets trace heap max size.
*
* @param[in] xHeapHandle Trace heap handle.
* @param[in] uxMax Max heap size.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceHeapSetMax(xHeapHandle, uxMax) xTraceEntrySetState(xHeapHandle, TRC_HEAP_STATE_INDEX_MAX, uxMax)
/** @} */
#ifdef __cplusplus
}
#endif
#else
#define xTraceHeapCreate(szName, uxCurrent, uxHighWaterMark, uxMax, pxHeapHandle) ((void)szName, (void)uxCurrent, (void)uxHighWaterMark, (void)uxMax, pxHeapHandle != 0 ? TRC_SUCCESS : TRC_FAIL)
#define xTraceHeapAlloc(xHeapHandle, pvAddress, uxSize) ((void)xHeapHandle, (void)pvAddress, (void)uxSize, TRC_SUCCESS)
#define xTraceHeapFree(xHeapHandle, pvAddress, uxSize) ((void)xHeapHandle, (void)pvAddress, (void)uxSize, TRC_SUCCESS)
#define xTraceHeapGetCurrent(xHeapHandle, puxCurrent) ((void)xHeapHandle, puxCurrent != 0 ? *puxCurrent = 0 : 0, puxCurrent != 0 ? TRC_SUCCESS : TRC_FAIL)
#define xTraceHeapGetHighWaterMark(xHeapHandle, puxHighWaterMark) ((void)xHeapHandle, puxHighWaterMark != 0 ? *puxHighWaterMark = 0 : 0, puxHighWaterMark != 0 ? TRC_SUCCESS : TRC_FAIL)
#define xTraceHeapGetMax(xHeapHandle, puxMax) ((void)xHeapHandle, puxMax != 0 ? *puxMax = 0 : 0, puxMax != 0 ? TRC_SUCCESS : TRC_FAIL)
#endif /* (TRC_USE_HEAPS == 1) */
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
#endif /* TRC_HEAP_H */

View File

@@ -0,0 +1,216 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace ISR APIs.
*/
#ifndef TRC_ISR_H
#define TRC_ISR_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup trace_isr_apis Trace ISR APIs
* @ingroup trace_recorder_apis
* @{
*/
/**
* @internal Trace ISR Core Data Structure
*/
typedef struct TraceISRCoreData /* Aligned */
{
TraceISRHandle_t handleStack[TRC_CFG_MAX_ISR_NESTING]; /**< */
int32_t stackIndex; /**< */
uint32_t isPendingContextSwitch; /**< */
} TraceISRCoreData_t;
/**
* @internal Trace ISR Data Structure
*/
typedef struct TraceISRData /* Aligned */
{
TraceISRCoreData_t cores[TRC_CFG_CORE_COUNT]; /* ISR handles */
} TraceISRData_t;
/* We expose this to enable faster access */
extern TraceISRData_t* pxTraceISRData;
/**
* @internal Initialize ISR trace system.
*
* @param[in] pxBuffer Pointer to memory that will be used by the ISR
* trace system.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceISRInitialize(TraceISRData_t *pxBuffer);
/**
* @brief Registers trace ISR.
*
* This routine stores a name and priority level for an Interrupt Service Routine,
* to allow for better visualization. Returns a TraceISRHandle_t used by
* xTraceISRBegin/xTraceISREnd.
*
* Example:
* #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt
* TraceISRHandle_t xISRTimer1Handle = 0; // The ID set by the recorder
* ...
* xTraceISRRegister("ISRTimer1", PRIO_OF_ISR_TIMER1, &xISRTimer1Handle);
* ...
* void ISR_handler()
* {
* xTraceISRBegin(xISRTimer1Handle);
* ...
* xTraceISREnd(0);
* }
*
* @param[in] szName Name.
* @param[in] uiPriority Priority.
* @param[out] pxISRHandle Pointer to uninitialized ISR trace handle.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceISRRegister(const char* szName, uint32_t uiPriority, TraceISRHandle_t* pxISRHandle);
/**
* @brief Registers the beginning of an Interrupt Service Routine.
*
* This routine register the beginning of an ISR using a TraceISRHandle_t.
* See xTraceISRRegister for and example of using ISR tracing.
*
* @param[in] xISRHandle Pointer to initialized ISR trace handle.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceISRBegin(TraceISRHandle_t xISRHandle);
/**
* @brief Registers the end of an Interrupt Service Routine.
*
* This routine register the end of an ISR using a TraceISRHandle_t.
* See xTraceISRRegister for and example of using ISR tracing.
*
* The parameter uxIsTaskSwitchRequired indicates if the interrupt has requested
* a task-switch (= 1), e.g., by signaling a semaphore. Otherwise (= 0) the
* interrupt is assumed to return to the previous context.
*
* @param[in] xIsTaskSwitchRequired Task switch required.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceISREnd(TraceBaseType_t xIsTaskSwitchRequired);
#if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
/**
* @brief Gets current trace ISR nesting level.
*
* This routine gets the current trace ISR nesting level for the
* CPU on which it is called.
*
* @param[out] puiValue Value.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceISRGetCurrentNesting(int32_t* puiValue);
/**
* @brief
*
* @return int32_t
*/
int32_t xTraceISRGetCurrentNestingReturned(void);
/**
* @brief Gets current ISR trace handle.
*
* @param[out] pxISRHandle ISR Handle.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceISRGetCurrent(TraceISRHandle_t* pxISRHandle);
#else /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
/**
* @brief Gets current trace ISR nesting level.
*
* This routine gets the current trace ISR nesting level for the
* CPU on which it is called.
*
* @param[out] puiValue Value.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceISRGetCurrentNesting(puiValue) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(puiValue) = pxTraceISRData->cores[TRC_CFG_GET_CURRENT_CORE()].stackIndex, TRC_SUCCESS)
/**
* @brief
*
* @return int32_t
*/
#define xTraceISRGetCurrentNestingReturned() (pxTraceISRData->cores[TRC_CFG_GET_CURRENT_CORE()].stackIndex)
/**
* @brief Gets current trace ISR nesting level.
*
* This routine gets the current trace ISR nesting level for the
* CPU on which it is called.
*
* @param[out] puiValue Value.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceISRGetCurrent(pxISRHandle) (xTraceISRGetCurrentNestingReturned() >= 0 ? (*(pxISRHandle) = pxTraceISRData->cores[TRC_CFG_GET_CURRENT_CORE()].handleStack[xTraceISRGetCurrentNestingReturned()], TRC_SUCCESS) : TRC_FAIL)
#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
/** @internal Deprecated - Provides backwards-compability with older recorders for now, will be removed in the future */
TraceISRHandle_t xTraceSetISRProperties(const char* szName, uint32_t uiPriority);
/** @internal Deprecated - Provides backwards-compability with older recorders for now, will be removed in the future */
#define xTraceGetCurrentISRNesting(puiValue) xTraceISRGetCurrentNesting(puiValue)
/** @internal Deprecated - Provides backwards-compability with older recorders for now, will be removed in the future */
#define vTraceStoreISRBegin(xISRHandle) xTraceISRBegin(xISRHandle)
/** @internal Deprecated - Provides backwards-compability with older recorders for now, will be removed in the future */
#define vTraceStoreISREnd(xIsTaskSwitchRequired) xTraceISREnd(xIsTaskSwitchRequired)
/** @} */
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif

View File

@@ -0,0 +1,187 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public internal event buffer APIs.
*/
#ifndef TRC_INTERNAL_BUFFER_H
#define TRC_INTERNAL_BUFFER_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#include <trcDefines.h>
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#ifndef TRC_USE_INTERNAL_BUFFER
#define TRC_USE_INTERNAL_BUFFER 1
#endif
#ifndef TRC_INTERNAL_EVENT_BUFFER_WRITE_MODE
#define TRC_INTERNAL_EVENT_BUFFER_WRITE_MODE TRC_INTERNAL_EVENT_BUFFER_OPTION_WRITE_MODE_DIRECT
#endif
#ifndef TRC_INTERNAL_EVENT_BUFFER_TRANSFER_MODE
#define TRC_INTERNAL_EVENT_BUFFER_TRANSFER_MODE TRC_INTERNAL_EVENT_BUFFER_OPTION_TRANSFER_MODE_ALL
#endif
#ifndef TRC_INTERNAL_BUFFER_CHUNK_SIZE
#define TRC_INTERNAL_BUFFER_CHUNK_SIZE 1024UL
#endif
#ifndef TRC_INTERNAL_BUFFER_PAGE_SIZE
#define TRC_INTERNAL_BUFFER_PAGE_SIZE 1024UL
#endif
#ifndef TRC_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_SIZE_LIMIT
#define TRC_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_SIZE_LIMIT (TRC_INTERNAL_BUFFER_PAGE_SIZE / 2UL)
#endif
#ifndef TRC_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_COUNT_LIMIT
#define TRC_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_COUNT_LIMIT (5UL)
#endif
#if (TRC_USE_INTERNAL_BUFFER == 1)
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup trace_internal_event_buffer_apis Trace Internal Event Buffer APIs
* @ingroup trace_recorder_apis
* @{
*/
/**
* @internal Initializes the internal trace event buffer used by certain stream ports.
*
* @param[in] puiBuffer Pointer to previously allocated memory buffer
* @param[in] uiSize Size of buffer
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceInternalEventBufferInitialize(uint8_t* puiBuffer, uint32_t uiSize);
/**
* @brief Allocates a data slot directly from the internal event buffer.
*
* @param[in] uiSize Allocation size
* @param[out] ppvData Pointer that will hold the area from the buffer.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceInternalEventBufferAlloc(uint32_t uiSize, void **ppvData);
/**
* @brief Commits the last allocated block to the internal event buffer.
*
* For the sake of conformity this function accepts the same arguments as
* xTraceInternalEventBufferPush. These arguments are not used in the
* traditional sense since the alloc already managed these parts. This
* function simply marks the allocate stage as complete and ready
* for transfer.
*
* @param[in] pvData Pointer to data
* @param[in] uiSize Size of data
* @param[out] piBytesWritten Bytes written.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceInternalEventBufferAllocCommit(void *pvData, uint32_t uiSize, int32_t *piBytesWritten);
/**
* @brief Pushes data to the internal trace event buffer.
*
* @param[in] pvData Pointer to data
* @param[in] uiSize Size of data
* @param[out] piBytesWritten Bytes written.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceInternalEventBufferPush(void *pvData, uint32_t uiSize, int32_t *piBytesWritten);
#if (TRC_INTERNAL_EVENT_BUFFER_TRANSFER_MODE == TRC_INTERNAL_EVENT_BUFFER_OPTION_TRANSFER_MODE_ALL)
#define xTraceInternalEventBufferTransfer xTraceInternalEventBufferTransferAll
#else
#define xTraceInternalEventBufferTransfer xTraceInternalEventBufferTransferChunk
#endif
/**
* @brief Transfers all internal trace event buffer data using the function
* xTraceStreamPortWriteData(...) as defined in trcStreamPort.h.
*
* This function is intended to be called by the periodic TzCtrl task with a
* suitable delay (e.g. 10-100 ms).
*
* In case of errors from the streaming interface, it registers a warning
* (TRC_WARNING_STREAM_PORT_WRITE) provided by xTraceErrorGetLast().
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceInternalEventBufferTransferAll(void);
/**
* @brief Transfer internal trace event buffer data through streamport.
*
* This routine will attempt to transfer a chunk of existing data in the trace
* event buffer through the streamport. New data pushed to the trace event buffer
* during the execution of this routine will not be transfered.
*
* When transferring a chunk which wraps the buffer, a singular transfer
* is made to avoid issuing dual writes. This configuration means that
* during wrapping, the chunk might be reduced in size even if there is
* more data at the start of the buffer. To transfer more data check
* piBytesWritten and issue multiple transfers if required.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceInternalEventBufferTransferChunk(void);
/**
* @brief Clears all trace events in the internal trace event buffer.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceInternalEventBufferClear(void);
/** @} */
#ifdef __cplusplus
}
#endif
#else /* (TRC_USE_INTERNAL_BUFFER == 1)*/
#define xTraceInternalEventBufferInitialize(puiBuffer, uiSize) ((void)(uiSize), (puiBuffer) != 0 ? TRC_SUCCESS : TRC_FAIL)
#define xTraceInternalEventBufferAlloc(ppvData, uiSize) ((void)(uiSize), (ppvData) != 0 ? TRC_SUCCESS : TRC_FAIL)
#define xTraceInternalEventBufferAllocCommit(pvData, uiSize, piBytesWritten) ((void)(pvData), (void)(uiSize), (void)(piBytesWritten), TRC_SUCCESS)
#define xTraceInternalEventBufferPush(pvData, uiSize, piBytesWritten) ((void)(uiSize), (void)(piBytesWritten), (pvData) != 0 ? TRC_SUCCESS : TRC_FAIL)
#define xTraceInternalEventBufferTransfer() (void)(TRC_SUCCESS)
#define xTraceInternalEventBufferTransferChunk(piBytesWritten, uiChunkSize) ((void)(piBytesWritten), (void)(uiChunkSize), TRC_SUCCESS)
#define xTraceInternalEventBufferClear() (void)(TRC_SUCCESS)
#endif /* (TRC_USE_INTERNAL_BUFFER == 1)*/
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
#endif /* TRC_INTERNAL_BUFFER_H */

View File

@@ -0,0 +1,130 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace interval APIs.
*/
#ifndef TRC_INTERVAL_H
#define TRC_INTERVAL_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#ifdef __cplusplus
extern "C" {
#endif
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#define TRC_INTERVAL_CHANNEL_SET_INDEX 0u
/**
* @defgroup trace_interval_apis Trace Interval APIs
* @ingroup trace_recorder_apis
* @{
*/
/**
* @brief Creates trace interval channel set.
*
* @param[in] szName Name.
* @param[out] pxIntervalChannelSetHandle Pointer to uninitialized trace interval channel set.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceIntervalChannelSetCreate(const char* szName, TraceIntervalChannelSetHandle_t* pxIntervalChannelSetHandle);
/**
* @brief Creates trace interval channel.
*
* @param[in] szName Name.
* @param[in] xIntervalChannelSetHandle Interval set that this channel belongs to.
* @param[out] pxIntervalChannelHandle Pointer to uninitialized trace interval channel.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceIntervalChannelCreate(const char *szName, TraceIntervalChannelSetHandle_t xIntervalChannelSetHandle, TraceIntervalChannelHandle_t *pxIntervalChannelHandle);
/**
* @brief Starts trace interval instance.
*
* @param[in] xIntervalChannelHandle Interval handle.
* @param[in] uxValue Value that can be used to tell instances apart.
* @param[out] pxIntervalInstanceHandle Pointer to interval instance variable.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceIntervalStart(TraceIntervalChannelHandle_t xIntervalChannelHandle, TraceUnsignedBaseType_t uxValue, TraceIntervalInstanceHandle_t* pxIntervalInstanceHandle);
/**
* @brief Stops trace interval instance.
*
* @param[in] xIntervalChannelHandle Interval handle.
* @param[in] xIntervalInstanceHandle Interval instance.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceIntervalStop(TraceIntervalChannelHandle_t xIntervalChannelHandle, TraceIntervalInstanceHandle_t xIntervalInstanceHandle);
/**
* @brief Gets trace interval channel state.
*
* @param[in] xIntervalChannelHandle Pointer to initialized trace interval.
* @param[out] puxState State.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceIntervalGetState(xIntervalChannelHandle, puxState) xTraceEntryGetState((TraceEntryHandle_t)(xIntervalChannelHandle), TRC_INTERVAL_CHANNEL_SET_INDEX, puxState)
/** @} */
#else
/**
* @brief Disabled by TRC_CFG_RECORDER_MODE
*/
#define xTraceIntervalChannelSetCreate(__szName, __pxIntervalChannelSetHandle) ((void)(__szName), *(__pxIntervalChannelSetHandle) = 0, TRC_SUCCESS)
/**
* @brief Disabled by TRC_CFG_RECORDER_MODE
*/
#define xTraceIntervalChannelCreate(__szName, __xIntervalChannelSetHandle, __pxIntervalChannelHandle) ((void)(__szName), (void)(__xIntervalChannelSetHandle), *(__pxIntervalChannelHandle) = 0, TRC_SUCCESS)
/**
* @brief Disabled by TRC_CFG_RECORDER_MODE
*/
#define xTraceIntervalStart(__xIntervalHandle, __uxValue, __pxIntervalInstanceHandle) ((void)(__xIntervalHandle), (void)(__uxValue), *(__pxIntervalInstanceHandle) = 0, TRC_SUCCESS)
/**
* @brief Disabled by TRC_CFG_RECORDER_MODE
*/
#define xTraceIntervalStop(__xIntervalHandle, __xIntervalInstanceHandle) ((void)(__xIntervalHandle), (void)(__xIntervalInstanceHandle), TRC_SUCCESS)
/**
* @brief Disabled by TRC_CFG_RECORDER_MODE
*/
#define xTraceIntervalGetState(__xIntervalHandle, __puxState) ((void)(__xIntervalHandle), *(__puxState) = 0, TRC_SUCCESS)
#endif
#ifdef __cplusplus
}
#endif
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,203 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @internal Public trace multicore event buffer APIs.
*/
#ifndef TRC_MULTI_CORE_EVENT_BUFFER_H
#define TRC_MULTI_CORE_EVENT_BUFFER_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup trace_multi_core_event_buffer_apis Trace Multi-Core Event Buffer APIs
* @ingroup trace_recorder_apis
* @{
*/
/**
* @brief Trace Multi-Core Event Buffer Structure
*/
typedef struct TraceMultiCoreEventBuffer /* Aligned */
{
TraceEventBuffer_t *xEventBuffer[TRC_CFG_CORE_COUNT]; /**< */
} TraceMultiCoreEventBuffer_t;
/**
* @internal Initialize multi-core event buffer.
*
* This routine initializes a multi-core trace event buffer and assignts it
* a memory area based on the supplied buffer.
*
* Trace event buffer options specifies the buffer behavior regarding
* old data, the alternatives are TRC_EVENT_BUFFER_OPTION_SKIP and
* TRC_EVENT_BUFFER_OPTION_OVERWRITE (mutal exclusive).
*
* @param[out] pxTraceMultiCoreEventBuffer Pointer to unitialized multi-core trace event buffer.
* @param[in] uiOptions Trace event buffer options.
* @param[in] puiBuffer Pointer to buffer that will be used by the multi-core trace event buffer.
* @param[in] uiSize Size of buffer.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceMultiCoreEventBufferInitialize(TraceMultiCoreEventBuffer_t* const pxTraceMultiCoreEventBuffer, uint32_t uiOptions,
uint8_t* puiBuffer, uint32_t uiSize);
#if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
/**
* @brief Allocates a data slot directly from the event buffer.
*
* @param[in] pxTraceMultiCoreEventBuffer Pointer to initialized multi-core trace event buffer.
* @param[in] uiSize Allocation size
* @param[out] ppvData Pointer that will hold the area from the buffer.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceMultiCoreEventBufferAlloc(const TraceMultiCoreEventBuffer_t * const pxTraceMultiCoreEventBuffer, uint32_t uiSize, void** ppvData);
/**
* @brief Commits the last allocated block to the event buffer.
*
* @param[in] pxTraceMultiCoreEventBuffer Pointer to initialized multi-core trace event buffer.
* @param[in] pvData Data pointer.
* @param[in] uiSize Data size.
* @param piBytesWritten The number of bytes that was written.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceMultiCoreEventBufferAllocCommit(const TraceMultiCoreEventBuffer_t * const pxTraceMultiCoreEventBuffer, void *pvData, uint32_t uiSize, int32_t *piBytesWritten);
/**
* @brief Pushes data into multi-core trace event buffer.
*
* This routine attempts to push data into the multi-core trace event buffer. Selection
* of which core the data is pushed for is managed automatically through the
* TRC_CFG_GET_CURRENT_CORE macro which is defined on an RTOS basis.
*
* @param[in] pxTraceMultiCoreEventBuffer Pointer to initialized multi-core event buffer.
* @param[in] pvData Pointer to data should be pushed into multi-core event buffer.
* @param[in] uiSize Size of data that should be pushed into multi-core trace event buffer.
* @param[out] piBytesWritten Pointer to variable which the routine will write the number
* of bytes that was pushed into the multi-core trace event buffer.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceMultiCoreEventBufferPush(const TraceMultiCoreEventBuffer_t* const pxTraceMultiCoreEventBuffer, void* pvData, uint32_t uiSize, int32_t* piBytesWritten);
#else
/**
* @brief Allocates a data slot directly from the event buffer.
*
* @param[in] pxTraceEventBuffer Pointer to initialized multi-core trace event buffer.
* @param[in] uiSize Allocation size
* @param[out] ppvData Pointer that will hold the area from the buffer.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceMultiCoreEventBufferAlloc(pxTraceMultiCoreEventBuffer, uiSize, ppvData) xTraceEventBufferAlloc((pxTraceMultiCoreEventBuffer)->xEventBuffer[TRC_CFG_GET_CURRENT_CORE()], uiSize, ppvData)
/**
* @brief Commits the last allocated block to the event buffer.
*
* @param[in] pxTraceEventBuffer Pointer to initialized multi-core trace event buffer.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceMultiCoreEventBufferAllocCommit(pxTraceMultiCoreEventBuffer, pvData, uiSize, piBytesWritten) xTraceEventBufferAllocCommit((pxTraceMultiCoreEventBuffer)->xEventBuffer[TRC_CFG_GET_CURRENT_CORE()], pvData, uiSize, piBytesWritten)
/**
* @brief Pushes data into multi-core trace event buffer.
*
* This routine attempts to push data into the multi-core trace event buffer. Selection
* of which core the data is pushed for is managed automatically through the
* TRC_CFG_GET_CURRENT_CORE macro which is defined on an RTOS basis.
*
* @param[in] pxTraceMultiCoreEventBuffer Pointer to initialized multi-core event buffer.
* @param[in] pvData Pointer to data should be pushed into multi-core event buffer.
* @param[in] uiSize Size of data that should be pushed into multi-core trace event buffer.
* @param[out] piBytesWritten Pointer to variable which the routine will write the number
* of bytes that was pushed into the multi-core trace event buffer.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceMultiCoreEventBufferPush(pxTraceMultiCoreEventBuffer, pvData, uiSize, piBytesWritten) xTraceEventBufferPush((pxTraceMultiCoreEventBuffer)->xEventBuffer[TRC_CFG_GET_CURRENT_CORE()], pvData, uiSize, piBytesWritten)
#endif
/**
* @brief Transfer multi-core trace event buffer data through streamport.
*
* This routine will attempt to transfer all existing data in the multi-core trace event
* buffer through the streamport. New data pushed to the trace event buffer
* during the execution of this routine will not be transfered to
*
* @param[in] pxTraceMultiCoreEventBuffer Pointer to initialized multi-core event buffer.
* @param[out] piBytesWritten Pointer to variable which the routine will write the number
* of bytes that was pushed into the multi-core trace event buffer.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceMultiCoreEventBufferTransferAll(const TraceMultiCoreEventBuffer_t* const pxTraceMultiCoreEventBuffer, int32_t* piBytesWritten);
/**
* @brief Transfer multi-core trace event buffer data through streamport.
*
* This routine will attempt to transfer a chunk of stored event data in the multi-core
* trace event buffer. Note that the chunk size is on a per-core basis with each core
* event buffer attempting to push up to uiChunkSize of bytes.
*
* @param[in] pxTraceMultiCoreEventBuffer Pointer to initialized multi-core event buffer.
* @param[in] uiChunkSize Number of bytes to attempt to transfer per core.
* @param[out] piBytesWritten Pointer to variable which the routine will write the number
* of bytes that was pushed into the multi-core trace event buffer.
*/
traceResult xTraceMultiCoreEventBufferTransferChunk(const TraceMultiCoreEventBuffer_t* const pxTraceMultiCoreEventBuffer, uint32_t uiChunkSize, int32_t* piBytesWritten);
/**
* @brief Clears all data from event buffer.
*
* @param[in] pxTraceMultiCoreEventBuffer Pointer to initialized multi-core trace event buffer.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceMultiCoreEventBufferClear(const TraceMultiCoreEventBuffer_t* const pxTraceMultiCoreEventBuffer);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
#endif /* TRC_MULTI_CORE_EVENT_BUFFER_H */

View File

@@ -0,0 +1,202 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace object APIs.
*/
#ifndef TRC_OBJECT_H
#define TRC_OBJECT_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup trace_object_apis Trace Object APIs
* @ingroup trace_recorder_apis
* @{
*/
/**
* @brief Registers trace object.
*
* @param[in] uiEventCode Event code.
* @param[in] pvObject Object.
* @param[in] szName Name.
* @param[in] uxStateCount State count.
* @param[in] uxStates States.
* @param[in] uxOptions Options.
* @param[out] pxObjectHandle Pointer to uninitialized trace object.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceObjectRegisterInternal(uint32_t uiEventCode, void* const pvObject, const char* szName, TraceUnsignedBaseType_t uxStateCount, const TraceUnsignedBaseType_t uxStates[], TraceUnsignedBaseType_t uxOptions, TraceObjectHandle_t* pxObjectHandle);
/**
* @brief Registers trace object.
*
* @param[in] uiEventCode Event code.
* @param[in] pvObject Object.
* @param[in] szName Name.
* @param[in] uxState State.
* @param[out] pxObjectHandle Pointer to uninitialized trace object.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceObjectRegister(uint32_t uiEventCode, void* const pvObject, const char* szName, TraceUnsignedBaseType_t uxState, TraceObjectHandle_t *pxObjectHandle);
/**
* @brief Unregisters trace object.
*
* @param[in] xObjectHandle Pointer to initialized trace object.
* @param[in] uiEventCode Event code.
* @param[in] uxState State.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceObjectUnregister(TraceObjectHandle_t xObjectHandle, uint32_t uiEventCode, TraceUnsignedBaseType_t uxState);
/**
* @brief Sets trace object name.
*
* @param[in] xObjectHandle Pointer to initialized trace object.
* @param[in] szName Name.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceObjectSetName(TraceObjectHandle_t xObjectHandle, const char *szName);
/**
* @brief Sets trace object state.
*
* @param[in] xObjectHandle Pointer to initialized trace object.
* @param[in] uxState State.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceObjectSetState(xObjectHandle, uxState) xTraceObjectSetSpecificState(xObjectHandle, 0, uxState)
/**
* @brief Sets trace object specific state state.
*
* @param[in] xObjectHandle Pointer to initialized trace object.
* @param[in] uiIndex State Index.
* @param[in] uxState State.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceObjectSetSpecificState(xObjectHandle, uiIndex, uxState) xTraceEntrySetState((TraceEntryHandle_t)(xObjectHandle), uiIndex, uxState)
/**
* @brief Sets trace object options.
*
* @param[in] xObjectHandle Pointer to initialized trace object.
* @param[in] uiOptions Options.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceObjectSetOptions(xObjectHandle, uiOptions) xTraceEntrySetOptions((TraceEntryHandle_t)(xObjectHandle), uiOptions)
/**
* @brief Registers trace object without trace object handle.
*
* @param[in] uiEventCode Event code.
* @param[in] pvObject Object.
* @param[in] szName Name.
* @param[in] uxState State.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceObjectRegisterWithoutHandle(uint32_t uiEventCode, void* pvObject, const char* szName, TraceUnsignedBaseType_t uxState);
/**
* @brief Unregisters trace object without trace object handle.
*
* @param[in] uiEventCode Event code.
* @param[in] pvObject Object.
* @param[in] uxState State.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceObjectUnregisterWithoutHandle(uint32_t uiEventCode, void* pvObject, TraceUnsignedBaseType_t uxState);
/**
* @brief Set trace object name without trace object handle.
*
* @param[in] pvObject Object.
* @param[in] szName Name.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceObjectSetNameWithoutHandle(void* pvObject, const char* szName);
/**
* @brief Set trace object state without trace object handle.
*
* @param[in] pvObject Object.
* @param[in] uxState State.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceObjectSetStateWithoutHandle(pvObject, uxState) xTraceObjectSetSpecificStateWithoutHandle(pvObject, 0, uxState)
/**
* @brief Sets trace object specific state without trace object
* handle.
*
* @param[in] pvObject Object.
* @param[in] uiIndex State index.
* @param[in] uxState State.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceObjectSetSpecificStateWithoutHandle(void* pvObject, uint32_t uiIndex, TraceUnsignedBaseType_t uxState);
/**
* @brief Sets trace object options without trace object handle.
*
* @param[in] pvObject Object.
* @param[in] uiOptions Options.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceObjectSetOptionsWithoutHandle(void* pvObject, uint32_t uiOptions);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
#endif /* TRC_OBJECT_H */

View File

@@ -0,0 +1,460 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace print APIs.
*/
#ifndef TRC_PRINT_H
#define TRC_PRINT_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <stdarg.h>
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup trace_print_apis Trace Print APIs
* @ingroup trace_recorder_apis
* @{
*/
#if (TRC_CFG_INCLUDE_USER_EVENTS == 1)
typedef struct TracePrintData /* Aligned */
{
TraceStringHandle_t defaultChannel;
TraceStringHandle_t consoleChannel;
} TracePrintData_t;
/**
* @internal Initialize print trace system.
*
* @param[in] pxBuffer Pointer to memory that will be used by the print
* trace system.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTracePrintInitialize(TracePrintData_t* pxBuffer);
/**
* @brief Generate a "User Event". Channel and format string are only stored in ELF.
*
* This is a compact version of xTracePrintF(). Only addresses to channel and format strings are stored and an ELF file must be provided to interpret the trace.
* NOTE! All parameters must be cast to TraceUnsignedBaseType_t/TraceBaseType_t!
*
* Example:
* xTracePrintCompact("MyChannel", "MyFormat %d", 1);
*
* @param[in] szChannel Channel string.
* @param[in] szFormat Format string.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTracePrintCompactF(const char* szChannel, const char* szFormat, ...);
/**
* @brief Generate a "User Event" with 0 parameters. Channel and format string are only stored in ELF.
*
* This is a compact and fixed version of xTracePrintF(). Only addresses to channel and format strings are stored and an ELF file must be provided to interpret the trace.
*
* Example:
* xTraceDependencyRegister("my_project.elf", TRC_DEPENDENCY_TYPE_ELF);
* ...
* xTracePrintCompactF0("MyChannel", "MyText");
*
* @param[in] szChannel Channel string.
* @param[in] szFormat Format string.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTracePrintCompactF0(szChannel, szFormat) xTraceEventCreate2(PSF_EVENT_USER_EVENT_FIXED, (TraceUnsignedBaseType_t)(szChannel), (TraceUnsignedBaseType_t)(szFormat))
/**
* @brief Generate a "User Event" with 1 parameter. Channel and format string are only stored in ELF.
*
* This is a compact and fixed version of xTracePrintF(). Only addresses to channel and format strings are stored and an ELF file must be provided to interpret the trace.
*
* Example:
* xTraceDependencyRegister("my_project.elf", TRC_DEPENDENCY_TYPE_ELF);
* ...
* xTracePrintCompactF1("MyChannel", "MyFormat %u", 1);
*
* @param[in] szChannel Channel string.
* @param[in] szFormat Format string.
* @param[in] uxParam1 First parameter.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTracePrintCompactF1(szChannel, szFormat, uxParam1) xTraceEventCreate3(PSF_EVENT_USER_EVENT_FIXED + 1, (TraceUnsignedBaseType_t)(szChannel), (TraceUnsignedBaseType_t)(szFormat), uxParam1)
/**
* @brief Generate a "User Event" with 2 parameters. Channel and format string are only stored in ELF.
*
* This is a compact and fixed version of xTracePrintF(). Only addresses to channel and format strings are stored and an ELF file must be provided to interpret the trace.
*
* Example
* xTraceDependencyRegister("my_project.elf", TRC_DEPENDENCY_TYPE_ELF);
* ...
* xTracePrintCompactF2("MyChannel", "MyFormat %u %u", 1, 2);
*
* @param[in] szChannel Channel string.
* @param[in] szFormat Format string.
* @param[in] uxParam1 First parameter.
* @param[in] uxParam2 Second parameter.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTracePrintCompactF2(szChannel, szFormat, uxParam1, uxParam2) xTraceEventCreate4(PSF_EVENT_USER_EVENT_FIXED + 2, (TraceUnsignedBaseType_t)(szChannel), (TraceUnsignedBaseType_t)(szFormat), uxParam1, uxParam2)
/**
* @brief Generate a "User Event" with 3 parameters. Channel and format string are only stored in ELF.
*
* This is a compact and fixed version of xTracePrintF(). Only addresses to channel and format strings are stored and an ELF file must be provided to interpret the trace.
*
* Example:
* xTraceDependencyRegister("my_project.elf", TRC_DEPENDENCY_TYPE_ELF);
* ...
* xTracePrintCompactF3("MyChannel", "MyFormat %u %u %u", 1, 2, 3);
*
* @param[in] szChannel Channel string.
* @param[in] szFormat Format string.
* @param[in] uxParam1 First parameter.
* @param[in] uxParam2 Second parameter.
* @param[in] uxParam3 Third parameter.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTracePrintCompactF3(szChannel, szFormat, uxParam1, uxParam2, uxParam3) xTraceEventCreate5(PSF_EVENT_USER_EVENT_FIXED + 3, (TraceUnsignedBaseType_t)(szChannel), (TraceUnsignedBaseType_t)(szFormat), uxParam1, uxParam2, uxParam3)
/**
* @brief Generate a "User Event" with 4 parameters. Channel and format string are only stored in ELF.
*
* This is a compact and fixed version of xTracePrintF(). Only addresses to channel and format strings are stored and an ELF file must be provided to interpret the trace.
*
* Example:
* xTraceDependencyRegister("my_project.elf", TRC_DEPENDENCY_TYPE_ELF);
* ...
* xTracePrintCompactF4("MyChannel", "MyFormat %u %u %u %u", 1, 2, 3, 4);
*
* @param[in] szChannel Channel string.
* @param[in] szFormat Format string.
* @param[in] uxParam1 First parameter.
* @param[in] uxParam2 Second parameter.
* @param[in] uxParam3 Third parameter.
* @param[in] uxParam4 Fourth parameter.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTracePrintCompactF4(szChannel, szFormat, uxParam1, uxParam2, uxParam3, uxParam4) xTraceEventCreate6(PSF_EVENT_USER_EVENT_FIXED + 4, (TraceUnsignedBaseType_t)(szChannel), (TraceUnsignedBaseType_t)(szFormat), uxParam1, uxParam2, uxParam3, uxParam4)
/**
* @brief Generate a "User Event" with 0 parameters.
*
* This is a highly optimized version of xTracePrintF().
* The channel and format string must be registered using xTraceStringRegister().
*
* Example:
* TraceStringHandle_t xChannel;
* TraceStringHandle_t xHelloWorld;
*
* xTraceStringRegister("MyChannel", &xChannel);
* xTraceStringRegister("Hello world!", &xHelloWorld);
* ...
* xTracePrintFormat0(xChannel, xHelloWorld);
*
* @param[in] xChannel Channel handle.
* @param[in] xFormatStringHandle Format string handle.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTracePrintF0(xChannelStringHandle, xFormatStringHandle) xTraceEventCreate2(PSF_EVENT_USER_EVENT_FIXED, (TraceUnsignedBaseType_t)(xChannelStringHandle), (TraceUnsignedBaseType_t)(xFormatStringHandle))
/**
* @brief Generate a "User Event" with 1 parameter.
*
* This is a highly optimized version of xTracePrintF().
* The channel and format string must be registered using xTraceStringRegister().
*
* Example:
* TraceStringHandle_t xChannel;
* TraceStringHandle_t xHelloWorld;
*
* xTraceStringRegister("MyChannel", &xChannel);
* xTraceStringRegister("Hello world! %d", &xHelloWorld);
* ...
* xTracePrintFormat1(xChannel, xHelloWorld, 1);
*
* @param[in] xChannel Channel handle.
* @param[in] xFormatStringHandle Format string handle.
* @param[in] uxParam1 First parameter.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTracePrintF1(xChannelStringHandle, xFormatStringHandle, uxParam1) xTraceEventCreate3(PSF_EVENT_USER_EVENT_FIXED + 1, (TraceUnsignedBaseType_t)(xChannelStringHandle), (TraceUnsignedBaseType_t)(xFormatStringHandle), uxParam1)
/**
* @brief Generate a "User Event" with 2 parameters.
*
* This is a highly optimized version of xTracePrintF().
* The channel and format string must be registered using xTraceStringRegister().
*
* Example:
* TraceStringHandle_t xChannel;
* TraceStringHandle_t xHelloWorld;
*
* xTraceStringRegister("MyChannel", &xChannel);
* xTraceStringRegister("Hello world! %d %d", &xHelloWorld);
* ...
* xTracePrintFormat2(xChannel, xHelloWorld, 1, 2);
*
* @param[in] xChannel Channel handle.
* @param[in] xFormatStringHandle Format string handle.
* @param[in] uxParam1 First parameter.
* @param[in] uxParam2 Second parameter.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTracePrintF2(xChannelStringHandle, xFormatStringHandle, uxParam1, uxParam2) xTraceEventCreate4(PSF_EVENT_USER_EVENT_FIXED + 2, (TraceUnsignedBaseType_t)(xChannelStringHandle), (TraceUnsignedBaseType_t)(xFormatStringHandle), uxParam1, uxParam2)
/**
* @brief Generate a "User Event" with 3 parameters.
*
* This is a highly optimized version of xTracePrintF().
* The channel and format string must be registered using xTraceStringRegister().
*
* Example:
* TraceStringHandle_t xChannel;
* TraceStringHandle_t xHelloWorld;
*
* xTraceStringRegister("MyChannel", &xChannel);
* xTraceStringRegister("Hello world! %d %d %d", &xHelloWorld);
* ...
* xTracePrintFormat3(xChannel, xHelloWorld, 1, 2, 3);
*
* @param[in] xChannel Channel handle.
* @param[in] xFormatStringHandle Format string handle.
* @param[in] uxParam1 First parameter.
* @param[in] uxParam2 Second parameter.
* @param[in] uxParam3 Third parameter.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTracePrintF3(xChannelStringHandle, xFormatStringHandle, uxParam1, uxParam2, uxParam3) xTraceEventCreate5(PSF_EVENT_USER_EVENT_FIXED + 3, (TraceUnsignedBaseType_t)(xChannelStringHandle), (TraceUnsignedBaseType_t)(xFormatStringHandle), uxParam1, uxParam2, uxParam3)
/**
* @brief Generate a "User Event" with 4 parameters.
*
* This is a highly optimized version of xTracePrintF().
* The channel and format string must be registered using xTraceStringRegister().
*
* Example:
* TraceStringHandle_t xChannel;
* TraceStringHandle_t xHelloWorld;
*
* xTraceStringRegister("MyChannel", &xChannel);
* xTraceStringRegister("Hello world! %d %d %d %d", &xHelloWorld);
* ...
* xTracePrintFormat4(xChannel, xHelloWorld, 1, 2, 3, 4);
*
* @param[in] xChannel Channel handle.
* @param[in] xFormatStringHandle Format string handle.
* @param[in] uxParam1 First parameter.
* @param[in] uxParam2 Second parameter.
* @param[in] uxParam3 Third parameter.
* @param[in] uxParam4 Fourth parameter.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTracePrintF4(xChannelStringHandle, xFormatStringHandle, uxParam1, uxParam2, uxParam3, uxParam4) xTraceEventCreate6(PSF_EVENT_USER_EVENT_FIXED + 4, (TraceUnsignedBaseType_t)(xChannelStringHandle), (TraceUnsignedBaseType_t)(xFormatStringHandle), uxParam1, uxParam2, uxParam3, uxParam4)
/**
* @brief Generate "User Events" with unformatted text.
*
* User Events can be used for very efficient application logging, and are shown
* as yellow labels in the main trace view.
*
* You may group User Events into User Event Channels. The yellow User Event
* labels shows the logged string, preceded by the channel name within
* brackets. For example:
*
* "[MyChannel] Hello World!"
*
* The User Event Channels are shown in the View Filter, which makes it easy to
* select what User Events you wish to display. User Event Channels are created
* using xTraceStringRegister().
*
* Example:
*
* TraceStringHandle_t xChannel;
* xTraceStringRegister("MyChannel", &xChannel);
* ...
* xTracePrint(xChannel, "Hello World!");
*
* @param[in] xChannel Channel.
* @param[in] szString String.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTracePrint(TraceStringHandle_t xChannel, const char* szString);
/**
* @brief Wrapper for xTracePrintF for printing to default channel.
*
* Wrapper for vTracePrintF, using the default channel. Can be used as a drop-in
* replacement for printf and similar functions, e.g. in a debug logging macro.
* NOTE! All parameters must be cast to TraceUnsignedBaseType_t/TraceBaseType_t!
*
* Example:
* // Old: #define LogString debug_console_printf
*
* // New, log to Tracealyzer instead:
* #define LogString xTraceConsoleChannelPrintF
* ...
* LogString("My value is: %d", myValue);
*
* @param[in] szFormat Format.
* @param[in] ... Parameters.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceConsoleChannelPrintF(const char* szFormat, ...);
/**
* @brief Generates "User Events" with formatted text and data.
*
* Generates "User Events", with formatted text and data, similar to a "printf".
* It is very fast since the actual formatting is done on the host side when the
* trace is displayed.
*
* User Events can be used for very efficient application logging, and are shown
* as yellow labels in the main trace view.
* An advantage of User Events is that data can be plotted in the "User Event
* Signal Plot" view, visualizing any data you log as User Events, discrete
* states or control system signals (e.g. system inputs or outputs).
*
* You may group User Events into User Event Channels. The yellow User Event
* labels show the logged string, preceded by the channel name within brackets.
*
* Example:
*
* "[MyChannel] Hello World!"
*
* The User Event Channels are shown in the View Filter, which makes it easy to
* select what User Events you wish to display. User Event Channels are created
* using xTraceStringRegister().
*
* Example:
*
* TraceStringHandle_t adc_uechannel;
* xTraceStringRegister("ADC User Events", &adc_uechannel);
* ...
* xTracePrintF(adc_uechannel,
* "ADC channel %d: %d volts",
* ch, adc_reading);
*
* NOTE! All data arguments are assumed to be TraceUnsignedBaseType_t/TraceBaseType_t. The following formats are
* supported:
* %d - signed integer. The following width and padding format is supported: "%05d" -> "-0042" and "%5d" -> " -42"
* %u - unsigned integer. The following width and padding format is supported: "%05u" -> "00042" and "%5u" -> " 42"
* %X - hexadecimal (uppercase). The following width and padding format is supported: "%04X" -> "002A" and "%4X" -> " 2A"
* %x - hexadecimal (lowercase). The following width and padding format is supported: "%04x" -> "002a" and "%4x" -> " 2a"
* %s - string (currently, this must be an earlier stored symbol name)
*
* Up to 15 data arguments are allowed, with a total size of maximum 60 byte
* including 8 byte for the base event fields and the format string. So with
* one data argument, the maximum string length is 48 chars. If this is exceeded
* the string is truncated (4 bytes at a time).
*
* @param[in] xChannel Channel.
* @param[in] szFormat Format.
* @param[in] ... Parameters.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTracePrintF(TraceStringHandle_t xChannel, const char* szFormat, ...);
/**
* @brief Generates "User Events" with formatted text and data.
*
* @param[in] xChannel Channel.
* @param[in] szFormat Format.
* @param[in] pxVariableList Pointer to variable list arguments.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceVPrintF(TraceStringHandle_t xChannel, const char* szFormat, va_list* pxVariableList);
#else
typedef struct TracePrintData
{
TraceUnsignedBaseType_t buffer[1];
} TracePrintData_t;
#define xTracePrintInitialize(p) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2((void)p, p != 0 ? TRC_SUCCESS : TRC_FAIL)
#define xTracePrint(_c, _s) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3((void)(_c), (void)(_s), TRC_SUCCESS)
#define xTracePrintF(_c, _s, ...) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3((void)(_c), (void)(_s), TRC_SUCCESS)
#define xTraceConsoleChannelPrintF(_s, ...) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2((void)(_s), TRC_SUCCESS)
#define xTraceVPrintF(_c, _s, _v) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4((void)(_c), (void)(_s), (void)(_v), TRC_SUCCESS)
#define xTracePrintF0(_c, _f) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3((void)(_c), (void)(_f), TRC_SUCCESS)
#define xTracePrintF1(_c, _f, _p1) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4((void)(_c), (void)(_f), (void)(_p1), TRC_SUCCESS)
#define xTracePrintF2(_c, _f, _p1, _p2) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_5((void)(_c), (void)(_f), (void)(_p1), (void)(_p2), TRC_SUCCESS)
#define xTracePrintF3(_c, _f, _p1, _p2, _p3) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_6((void)(_c), (void)(_f), (void)(_p1), (void)(_p2), (void)(_p3), TRC_SUCCESS)
#define xTracePrintF4(_c, _f, _p1, _p2, _p3, _p4) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_7((void)(_c), (void)(_f), (void)(_p1), (void)(_p2), (void)(_p3), (void)(_p4), TRC_SUCCESS)
#define xTracePrintCompactF xTracePrintF
#define xTracePrintCompactF0 xTracePrintF0
#define xTracePrintCompactF1 xTracePrintF1
#define xTracePrintCompactF2 xTracePrintF2
#define xTracePrintCompactF3 xTracePrintF3
#define xTracePrintCompactF4 xTracePrintF4
#endif
/** @} */
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,146 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace runnable APIs.
*/
#ifndef TRC_RUNNABLE_H
#define TRC_RUNNABLE_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup trace_runnable_apis Trace Runnable APIs
* @ingroup trace_recorder_apis
* @{
*/
typedef enum TraceRunnableRegisterMethod
{
TRC_RUNNABLE_REGISTER_METHOD_USE_ENTRY_TABLE,
TRC_RUNNABLE_REGISTER_METHOD_USE_STRING_ADDRESS,
TRC_RUNNABLE_REGISTER_METHOD_USE_HANDLE_ADDRESS,
} TraceRunnableRegisterMethod_t;
/**
* @brief Registers a runnable. Can be called multiple times, will not create additional entries.
*
* @param[in] szName Name.
* @param[in] uxRegisterMethod Indicates how to register the runnable. Since there can be thousands of runnables, storing in entry table is not always a good idea.
* TRC_RUNNABLE_REGISTER_METHOD_USE_ENTRY_TABLE: Store in entry table normally and handle will point to entry.
* TRC_RUNNABLE_REGISTER_METHOD_USE_STRING_ADDRESS: For this method the string address must be unique and will be used as handle value.
* TRC_RUNNABLE_REGISTER_METHOD_USE_HANDLE_ADDRESS: For this method the handle address must be unique and will be used as handle value.
* @param[out] pxRunnableHandle Pointer to 0 initialized TraceRunnableHandle_t. If handle that is pointed to is not 0 no entry will be created.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceRunnableRegister(const char* szName, TraceRunnableRegisterMethod_t uxRegisterMethod, TraceRunnableHandle_t* pxRunnableHandle);
/**
* @brief Creates an event indicating a runnable started.
*
* @param[in] xRunnableHandle Runnable handle.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceRunnableStart(xRunnableHandle) xTraceEventCreate1(PSF_EVENT_RUNNABLE_START, (TraceUnsignedBaseType_t)(xRunnableHandle))
/**
* @brief Creates an event indicating a runnable stopped.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceRunnableStop() xTraceEventCreate0(PSF_EVENT_RUNNABLE_STOP)
/**
* @brief Registers a set of static runnables. Requires XML configuration to properly interpret.
*
* @param[in] szName Name.
* @param[in] uiMajor Major version.
* @param[in] uiMinor Minor version.
* @param[in] uiPatch Patch version.
* @param[in] uiRunnableCount Runnables count.
* @param[out] pxRunnableSetHandle Pointer to uninitialized TraceRunnableStaticSetHandle_t.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceRunnableRegisterStaticSet(szName, uiMajor, uiMinor, uiPatch, uiRunnableCount, pxRunnableSetHandle) xTraceExtensionCreate(szName, uiMajor, uiMinor, uiPatch, uiRunnableCount, pxRunnableSetHandle)
/**
* @brief Start a static runnable. Requires XML configuration to properly interpret.
*
* @param[in] xRunnableSetHandle Pointer to initialized runnable set handle.
* @param[out] puiBaseEventId Base event id.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceRunnableStartStatic(xRunnableSetHandle, uiRunnableId) xTraceEventCreate0(xTraceExtensionGetEventId(xRunnableSetHandle, uiRunnableId))
/**
* @brief Stop a static runnable. Requires XML configuration to properly interpret.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceRunnableStopStatic() xTraceRunnableStop()
/** @} */
#ifdef __cplusplus
}
#endif
#else
#ifndef xTraceRunnableRegister
#define xTraceRunnableRegister(szName, uxRegisterMethod, pxRunnableHandle) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4((void)(szName), (void)(uxRegisterMethod), (void)(pxRunnableHandle), TRC_SUCCESS)
#endif
#ifndef xTraceRunnableStart
#define xTraceRunnableStart(xRunnableHandle) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2((void)(xRunnableHandle), TRC_SUCCESS)
#endif
#ifndef xTraceRunnableStop
#define xTraceRunnableStop() (TRC_SUCCESS)
#endif
#endif
#else
#ifndef xTraceRunnableRegister
#define xTraceRunnableRegister(szName, uxRegisterMethod, pxRunnableHandle) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4((void)(szName), (void)(uxRegisterMethod), (void)(pxRunnableHandle), TRC_SUCCESS)
#endif
#ifndef xTraceRunnableStart
#define xTraceRunnableStart(xRunnableHandle) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2((void)(xRunnableHandle), TRC_SUCCESS)
#endif
#ifndef xTraceRunnableStop
#define xTraceRunnableStop() (TRC_SUCCESS)
#endif
#endif
#endif

View File

@@ -0,0 +1,138 @@
/*
* Percepio Trace Recorder SDK for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace stack monitor APIs.
*/
#ifndef TRC_STACK_MONITOR_H
#define TRC_STACK_MONITOR_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <stdint.h>
#include <trcRecorder.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup trace_stack_monitor_apis Trace Stack Monitor APIs
* @ingroup trace_recorder_apis
* @{
*/
#if (((TRC_CFG_ENABLE_STACK_MONITOR) == 1) && ((TRC_CFG_SCHEDULING_ONLY) == 0))
typedef struct TraceStackMonitorEntry /* Aligned */
{
void *pvTask;
TraceUnsignedBaseType_t uxPreviousLowWaterMark;
} TraceStackMonitorEntry_t;
typedef struct TraceStackMonitorData /* Aligned */
{
TraceStackMonitorEntry_t xEntries[TRC_CFG_STACK_MONITOR_MAX_TASKS];
TraceUnsignedBaseType_t uxEntryCount;
} TraceStackMonitorData_t;
/**
* @internal Initialize trace stack monitor system.
*
* @param[in] pxBuffer Pointer to memory that will be used by the trace
* stack monitor system.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStackMonitorInitialize(TraceStackMonitorData_t* pxBuffer);
/**
* @brief Adds task/thread to trace stack monitor.
*
* @param[in] pvTask Task/Thread.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStackMonitorAdd(void* pvTask);
/**
* @brief Removes task/thread from trace stack monitor.
*
* @param[in] pvTask Task/Thread.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStackMonitorRemove(void* pvTask);
/**
* @brief Gets trace stack monitor tread/task at index.
*
* @param[in] uiIndex Index.
* @param[in] ppvTask Task/Thread.
* @param[out] puxLowWaterMark Low water mark.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStackMonitorGetAtIndex(uint32_t uiIndex, void** ppvTask, TraceUnsignedBaseType_t* puxLowWaterMark);
/**
* @brief Performs trace stack monitor reporting.
*
* This routine performs a trace stack monitor check and report
* for TRC_CFG_STACK_MONITOR_MAX_REPORTS number of registered
* tasks/threads.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStackMonitorReport(void);
#else
typedef struct TraceStackMonitorData
{
uint32_t buffer[1];
} TraceStackMonitorData_t;
#define xTraceStackMonitorInitialize(pxBuffer) ((void)(pxBuffer), TRC_SUCCESS)
#define xTraceStackMonitorDiagnosticsGet(xType, puiValue) ((void)(xType), (puiValue) != 0 ? *(puiValue) = 0 : 0, (puiValue) != 0 ? TRC_SUCCESS : TRC_FAIL)
#define xTraceStackMonitorDiagnosticsSet(xType, uiValue) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3((void)(xType), (void)(uiValue), TRC_SUCCESS)
#define xTraceStackMonitorAdd(pvTask) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2((void)(pvTask), TRC_SUCCESS)
#define xTraceStackMonitorRemove(pvTask) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2((void)(pvTask), TRC_SUCCESS)
#define xTraceStackMonitorGetAtIndex(uiIndex, ppvTask, puxLowWaterMark) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4((void)(uiIndex), (void)(ppvTask), (void)(puxLowWaterMark), TRC_SUCCESS)
#define xTraceStackMonitorReport() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1(TRC_SUCCESS)
#endif
/** @} */
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif

View File

@@ -0,0 +1,95 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace state machine APIs.
*/
#ifndef TRC_STATE_MACHINE_H
#define TRC_STATE_MACHINE_H
#include <trcTypes.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup trace_state_machine_apis Trace State Machine APIs
* @ingroup trace_recorder_apis
* @{
*/
/**
* @brief Creates trace state machine.
*
* @param[in] szName Name.
* @param[out] pxStateMachineHandle Pointer to uninitialized trace state machine.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStateMachineCreate(const char *szName, TraceStateMachineHandle_t *pxStateMachineHandle);
/**
* @brief Creates trace state machine state.
*
* @param[in] xStateMachineHandle Pointer to initialized trace state machine.
* @param[in] szName Name.
* @param[out] pxStateHandle Pointer to uninitialized trace state machine state.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStateMachineStateCreate(TraceStateMachineHandle_t xStateMachineHandle, const char *szName, TraceStateMachineStateHandle_t *pxStateHandle);
/**
* @brief Sets trace state machine state.
*
* @param[in] xStateMachineHandle Pointer to initialized trace state machine.
* @param[in] xStateHandle Pointer to initialized trace state machine state.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStateMachineSetState(TraceStateMachineHandle_t xStateMachineHandle, TraceStateMachineStateHandle_t xStateHandle);
/** @} */
#ifdef __cplusplus
}
#endif
#else
/**
* @brief Disabled by TRC_CFG_RECORDER_MODE
*/
#define xTraceStateMachineCreate(__szName, __pxStateMachineHandle) ((void)(__szName), *(__pxStateMachineHandle) = 0, TRC_SUCCESS)
/**
* @brief Disabled by TRC_CFG_RECORDER_MODE
*/
#define xTraceStateMachineStateCreate(__xStateMachineHandle, __szName, __pxStateHandle) ((void)(__xStateMachineHandle), (void)(__szName), *(__pxStateHandle) = 0, TRC_SUCCESS)
/**
* @brief Disabled by TRC_CFG_RECORDER_MODE
*/
#define xTraceStateMachineSetState(__xStateMachineHandle, __xStateHandle) ((void)(__xStateMachineHandle), (void)(__xStateHandle), TRC_SUCCESS)
#endif
#endif
#endif

View File

@@ -0,0 +1,102 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace static buffer APIs.
*/
#ifndef TRC_STATIC_BUFFER_H
#define TRC_STATIC_BUFFER_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup trace_static_buffer_apis Trace Static Buffer APIs
* @ingroup trace_recorder_apis
* @{
*/
/* A buffer type that is maximum size */
typedef uint8_t TraceStaticBuffer_t[TRC_MAX_BLOB_SIZE];
/**
* @internal Trace Core Static Buffer Core Structure
*/
typedef struct TraceCoreStaticBufferCore /* Aligned */
{
TraceStaticBuffer_t dummyEvents[(TRC_CFG_MAX_ISR_NESTING) + 1]; /**< */
} TraceCoreStaticBuffer_t;
/**
* @internal Trace Static Buffer Table Structure
*/
typedef struct TraceStaticBufferTable /* Aligned */
{
TraceCoreStaticBuffer_t coreDummyEvents[TRC_CFG_CORE_COUNT]; /**< Temporary buffers used for event or blob creation. */
} TraceStaticBufferTable_t;
extern TraceStaticBufferTable_t* pxTraceStaticBufferTable;
/**
* @internal Initialize trace static buffer.
*
* @param[in] pxBuffer Pointer to memory that will be used by the
* trace static buffer.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStaticBufferInitialize(TraceStaticBufferTable_t* pxBuffer);
#if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
/**
* @brief Gets trace static buffer.
*
* @param[out] ppvBuffer Buffer.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStaticBufferGet(void **ppvBuffer);
#else /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
/**
* @brief Gets trace static buffer.
*
* @param[out] ppvBuffer Buffer.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceStaticBufferGet(ppvBuffer) (*(ppvBuffer) = (void*)&pxTraceStaticBufferTable->coreDummyEvents[TRC_CFG_GET_CURRENT_CORE()].dummyEvents[xTraceISRGetCurrentNestingReturned() + 1], TRC_SUCCESS)
#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
#endif /* TRC_STATIC_BUFFER_H */

View File

@@ -0,0 +1,76 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace string APIs.
*/
#ifndef TRC_STRING_H
#define TRC_STRING_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup trace_string_apis Trace String APIs
* @ingroup trace_recorder_apis
* @{
*/
/**
* @brief Registers a trace string.
*
* This routine registers a strings in the recorder, e.g. for names of user
* event channels.
*
* Example:
* TraceStringHandle_t myEventHandle;
* xTraceStringRegister("MyUserEvent", &myEventHandle);
* ...
* xTracePrintF(myEventHandle, "My value is: %d", myValue);
*
* @param[in] szString String.
* @param[out] pString Pointer to uninitialized trace string.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStringRegister(const char *szString, TraceStringHandle_t* pString);
/**
* @brief Registers a trace string.
*
* @deprecated Remains for backward compability with pre v4.6 versions
* of the recorder.
*
* @param[in] name Name.
*
* @return TraceStringHandle_t
*/
TraceStringHandle_t xTraceRegisterString(const char *name);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
#endif /* TRC_STRING_H */

View File

@@ -0,0 +1,262 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace task APIs.
*/
#ifndef TRC_TASK_H
#define TRC_TASK_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup trace_task_apis Trace Task APIs
* @ingroup trace_recorder_apis
* @{
*/
#ifndef TRC_CFG_ENABLE_STACK_MONITOR
#define TRC_CFG_ENABLE_STACK_MONITOR 0
#endif
/**
* @internal Trace Task Data Structure
*/
typedef struct TraceTaskData /* Aligned */
{
void* coreTasks[TRC_CFG_CORE_COUNT];
} TraceTaskData_t;
extern TraceTaskData_t* pxTraceTaskData;
/**
* @internal Initialize trace task system.
*
* @param[in] pxBuffer Pointer to memory that will be used by the
* trace task system.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceTaskInitialize(TraceTaskData_t* pxBuffer);
/**
* @brief Register trace task in the trace.
*
* @param[in] pvTask Task.
* @param[in] szName Name.
* @param[in] uxPriority Priority.
* @param[out] pxTaskHandle Pointer to uninitialized trace task.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceTaskRegister(pvTask, szName, uxPriority, pxTaskHandle) ((((pvTask) != 0) && (xTraceObjectRegister(PSF_EVENT_TASK_CREATE, pvTask, szName, uxPriority, (TraceObjectHandle_t*)(pxTaskHandle)) == TRC_SUCCESS)) ? (xTraceStackMonitorAdd(pvTask), TRC_SUCCESS) : TRC_FAIL)
/**
* @brief Unregister trace task from trace.
*
* @param[in] xTaskHandle Pointer to initialized trace task.
* @param[in] uxPriority Priority.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceTaskUnregister(TraceTaskHandle_t xTaskHandle, TraceUnsignedBaseType_t uxPriority);
/**
* @brief Sets trace task name.
*
* @param[in] pvTask Task.
* @param[in] szName Name.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceTaskSetName xTraceObjectSetName
/**
* @brief Sets trace task priority.
*
* @param[in] xTaskHandle Pointer to initialized trace task.
* @param[in] uxPriority Priority.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceTaskSetPriority(TraceTaskHandle_t xTaskHandle, TraceUnsignedBaseType_t uxPriority);
/**
* @brief Registers trace task without trace task handle.
*
* @param[in] pvTask Task.
* @param[in] szName Name.
* @param[in] uxPriority Priority.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceTaskRegisterWithoutHandle(pvTask, szName, uxPriority) ((((pvTask) != 0) && (xTraceObjectRegisterWithoutHandle(PSF_EVENT_TASK_CREATE, pvTask, szName, uxPriority) == TRC_SUCCESS)) ? (xTraceStackMonitorAdd(pvTask), TRC_SUCCESS) : TRC_FAIL)
/**
* @brief Unregisters trace task without trace task handle.
*
* @param[in] pvTask Task.
* @param[in] uxPriority Priority.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceTaskUnregisterWithoutHandle(pvTask, uxPriority) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(xTraceStackMonitorRemove(pvTask), xTraceObjectUnregisterWithoutHandle(PSF_EVENT_TASK_DELETE, pvTask, uxPriority))
/**
* @brief Sets trace task name without trace task handle.
*
* @param[in] pvTask Task.
* @param[in] szName Name.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceTaskSetNameWithoutHandle xTraceObjectSetNameWithoutHandle
/**
* @brief Sets trace task priority without trace task handle.
*
* @param[in] pvTask Task.
* @param[in] uxPriority Priority.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceTaskSetPriorityWithoutHandle(void* pvTask, TraceUnsignedBaseType_t uxPriority);
/**
* @brief Registers trace task switch event.
*
* @param[in] pvTask Task.
* @param[in] uxPriority Priority.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceTaskSwitch(void* pvTask, TraceUnsignedBaseType_t uxPriority);
#if (TRC_CFG_INCLUDE_READY_EVENTS == 1)
/**
* @brief Registers trace task ready event.
*
* @param[in] pvTask Task.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceTaskReady(pvTask) xTraceEventCreate1(PSF_EVENT_TASK_READY, (TraceUnsignedBaseType_t)(pvTask))
#else
#define xTraceTaskReady(p) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2((void)p, TRC_SUCCESS)
#endif
/**
* @brief Sets current trace task on current core.
*
* @param[in] pvTask Task.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceTaskSetCurrent(pvTask) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(pxTraceTaskData->coreTasks[TRC_CFG_GET_CURRENT_CORE()] = (pvTask), TRC_SUCCESS)
/**
* @brief Sets current trace task on specific core.
*
* @param[in] coreId Core id.
* @param[in] pvTask Task.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceTaskSetCurrentOnCore(coreId, pvTask) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(pxTraceTaskData->coreTasks[coreId] = (pvTask), TRC_SUCCESS)
/**
* @brief Gets current trace task on current core.
*
* @param[out] ppvTask Task.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceTaskGetCurrent(ppvTask) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(ppvTask) = pxTraceTaskData->coreTasks[TRC_CFG_GET_CURRENT_CORE()], TRC_SUCCESS)
/**
* @brief Gets current trace task on specific core.
*
* @param[in] coreId Core id.
* @param[out] ppvTask Task.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceTaskGetCurrentOnCore(coreId, ppvTask) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(ppvTask) = pxTraceTaskData->coreTasks[coreId], TRC_SUCCESS)
/**
* @brief Returns current trace task.
*
* @returns Current trace task.
*/
#define xTraceTaskGetCurrentReturn() (pxTraceTaskData->coreTasks[TRC_CFG_GET_CURRENT_CORE()])
/**
* @brief Registers trace task instance finished event.
*
* This routine creates a trace event that ends the current task instance at
* this very instant. This makes the viewer split the current fragment at
* this point and begin a new actor instance, even if no task-switch has
* occurred
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceTaskInstanceFinishedNow() xTraceEventCreate0(PSF_EVENT_IFE_DIRECT)
/**
* @brief Marks the current trace task instance as finished on the next
* kernel call.
*
* If that kernel call is blocking, the instance ends after the blocking event
* and the corresponding return event is then the start of the next instance.
* If the kernel call is not blocking, the viewer instead splits the current
* fragment right before the kernel call, which makes this call the first event
* of the next instance.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceTaskInstanceFinishedNext() xTraceEventCreate0(PSF_EVENT_IFE_NEXT)
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
#endif /* TRC_TASK_H */

View File

@@ -0,0 +1,243 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Public trace timestamp APIs.
*/
#ifndef TRC_TIMESTAMP_H
#define TRC_TIMESTAMP_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup trace_timestamp_apis Trace Timestamp APIs
* @ingroup trace_recorder_apis
* @{
*/
/**
* @brief Trace Timestamp Structure
*/
typedef struct TraceTimestampData /* Aligned */
{
uint32_t type; /**< Timer type (direction) */
uint32_t period; /**< Timer Period */
TraceUnsignedBaseType_t frequency; /**< Timer Frequency */
uint32_t wraparounds; /**< Nr of timer wraparounds */
uint32_t osTickHz; /**< RTOS tick frequency */
uint32_t latestTimestamp; /**< Latest timestamp */
uint32_t osTickCount; /**< RTOS tick count */
} TraceTimestampData_t;
extern TraceTimestampData_t* pxTraceTimestamp;
/**
* @internal Initialize trace timestamp system.
*
* @param[in] pxBuffer Pointer to memory that will be used by the
* trace timestamp system.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceTimestampInitialize(TraceTimestampData_t *pxBuffer);
#if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
/**
* @brief Gets current trace timestamp.
*
* @param[out] puiTimestamp Timestamp.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceTimestampGet(uint32_t* puiTimestamp);
/**
* @brief Gets trace timestamp wraparounds.
*
* @param[out] puiTimerWraparounds Timer wraparounds.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceTimestampGetWraparounds(uint32_t* puiTimerWraparounds);
/**
* @brief Sets trace timestamp frequency.
*
* @param[in] uxFrequency Frequency.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceTimestampSetFrequency(TraceUnsignedBaseType_t uxFrequency);
/**
* @brief Gets trace timestamp frequency.
*
* @param[out] puxFrequency Frequency.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceTimestampGetFrequency(TraceUnsignedBaseType_t* puxFrequency);
/**
* @brief Sets trace timestamp period.
*
* @param[in] uiPeriod Period.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceTimestampSetPeriod(uint32_t uiPeriod);
/**
* @brief Gets trace timestamp period.
*
* @param[out] puiPeriod Period.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceTimestampGetPeriod(uint32_t* puiPeriod);
/**
* @brief Sets trace timestamp OS tick count.
*
* @param[in] uiOsTickCount OS tick count.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceTimestampSetOsTickCount(uint32_t uiOsTickCount);
/**
* @brief Gets trace timestamp OS tick count.
*
* @param[in] puiOsTickCount
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceTimestampGetOsTickCount(uint32_t *puiOsTickCount);
#else /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
/**
* @brief Gets current trace timestamp.
*
* @param[out] puiTimestamp Timestamp.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#if ((TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_INCR) || (TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR))
#define xTraceTimestampGet(puiTimestamp) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4(*(puiTimestamp) = TRC_HWTC_COUNT, (*(puiTimestamp) < pxTraceTimestamp->latestTimestamp) ? pxTraceTimestamp->wraparounds++ : 0, pxTraceTimestamp->latestTimestamp = *(puiTimestamp), TRC_SUCCESS)
#elif ((TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_DECR) || (TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR))
#define xTraceTimestampGet(puiTimestamp) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4(*(puiTimestamp) = TRC_HWTC_COUNT, (*(puiTimestamp) > pxTraceTimestamp->latestTimestamp) ? pxTraceTimestamp->wraparounds++ : 0, pxTraceTimestamp->latestTimestamp = *(puiTimestamp), TRC_SUCCESS)
#elif ((TRC_HWTC_TYPE == TRC_OS_TIMER_INCR) || (TRC_HWTC_TYPE == TRC_OS_TIMER_DECR))
#define xTraceTimestampGet(puiTimestamp) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4(*(puiTimestamp) = ((TRC_HWTC_COUNT) & 0x00FFFFFFU) + ((pxTraceTimestamp->osTickCount & 0x000000FFU) << 24), pxTraceTimestamp->wraparounds = pxTraceTimestamp->osTickCount, pxTraceTimestamp->latestTimestamp = *(puiTimestamp), TRC_SUCCESS)
#endif
/**
* @brief Gets trace timestamp wraparounds.
*
* @param[out] puiTimerWraparounds Timer wraparounds.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceTimestampGetWraparounds(puiTimerWraparounds) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(puiTimerWraparounds) = pxTraceTimestamp->wraparounds, TRC_SUCCESS)
/**
* @brief Sets trace timestamp frequency.
*
* @param[in] uxFrequency Frequency.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceTimestampSetFrequency(uxFrequency) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(pxTraceTimestamp->frequency = uxFrequency, TRC_SUCCESS)
/**
* @brief Sets trace timestamp period.
*
* @param[in] uiPeriod Period.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceTimestampSetPeriod(uiPeriod) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(pxTraceTimestamp->period = uiPeriod, TRC_SUCCESS)
/**
* @brief Sets trace timestamp OS tick count.
*
* @param[in] uiOsTickCount OS tick count.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceTimestampSetOsTickCount(uiOsTickCount) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(pxTraceTimestamp->osTickCount = uiOsTickCount, TRC_SUCCESS)
/**
* @brief Gets trace timestamp frequency.
*
* @param[out] puxFrequency Frequency.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceTimestampGetFrequency(puxFrequency) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(puxFrequency) = pxTraceTimestamp->frequency, TRC_SUCCESS)
/**
* @brief Gets trace timestamp period.
*
* @param[out] puiPeriod Period.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceTimestampGetPeriod(puiPeriod) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(puiPeriod) = pxTraceTimestamp->period, TRC_SUCCESS)
/**
* @brief Gets trace timestamp OS tick count.
*
* @param[in] puiOsTickCount
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceTimestampGetOsTickCount(puiOsTickCount) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(puiOsTickCount) = pxTraceTimestamp->osTickCount, TRC_SUCCESS)
#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
#endif /* TRC_TIMESTAMP_H */

View File

@@ -0,0 +1,83 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The common types.
*/
#ifndef TRC_TYPES_H
#define TRC_TYPES_H
#include <stdint.h>
#include <trcConfig.h>
#include <trcHardwarePort.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef TRC_BASE_TYPE
#define TRC_BASE_TYPE int32_t
#endif
#ifndef TRC_UNSIGNED_BASE_TYPE
#define TRC_UNSIGNED_BASE_TYPE uint32_t
#endif
typedef TRC_UNSIGNED_BASE_TYPE TraceUnsignedBaseType_t;
typedef TRC_BASE_TYPE TraceBaseType_t;
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
typedef void* TraceHandleBaseType_t;
#else
typedef TraceUnsignedBaseType_t TraceHandleBaseType_t;
#endif
typedef TraceUnsignedBaseType_t traceResult;
typedef TraceHandleBaseType_t TraceEventHandle_t;
typedef TraceHandleBaseType_t TraceISRHandle_t;
typedef TraceHandleBaseType_t TraceEntryHandle_t;
typedef TraceHandleBaseType_t TraceTaskHandle_t;
typedef TraceHandleBaseType_t TraceObjectHandle_t;
typedef TraceHandleBaseType_t TraceExtensionHandle_t;
typedef TraceHandleBaseType_t TraceHeapHandle_t;
typedef TraceHandleBaseType_t TraceIntervalChannelSetHandle_t;
typedef TraceHandleBaseType_t TraceIntervalChannelHandle_t;
typedef TraceHandleBaseType_t TraceIntervalInstanceHandle_t;
typedef TraceHandleBaseType_t TraceStateMachineHandle_t;
typedef TraceHandleBaseType_t TraceStateMachineStateHandle_t;
typedef TraceHandleBaseType_t TraceStringHandle_t;
typedef TraceHandleBaseType_t TraceCounterHandle_t;
typedef TraceHandleBaseType_t TraceRunnableHandle_t;
typedef TraceHandleBaseType_t TraceRunnableStaticSetHandle_t;
typedef void (*TraceCounterCallback_t)(TraceCounterHandle_t xCounterHandle);
/* DEPRECATED. Backwards compatibility */
typedef TraceStringHandle_t traceString;
#ifdef __cplusplus
}
#endif
#endif /* TRC_TYPES_H */

View File

@@ -0,0 +1,55 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The interface for trace utility functions.
*/
#ifndef TRC_UTILITY_H
#define TRC_UTILITY_H
#ifndef TRC_MEMCPY
#define TRC_MEMCPY(dst, src, size) \
{ \
uint32_t __i; \
for (__i = 0; __i < size; __i++) { \
((uint8_t*)(dst))[__i] = ((uint8_t*)(src))[__i]; \
} \
}
#endif
#define TRC_STRCAT(dst, dst_size, pDstLength, src) \
{ \
TraceUnsignedBaseType_t uxTRC_STRCAT_INDEX = 0; \
while (*(pDstLength) < (dst_size)) \
{ \
dst[*(pDstLength)] = src[uxTRC_STRCAT_INDEX]; \
if (dst[*(pDstLength)] == 0) \
break; \
(*(pDstLength))++; \
uxTRC_STRCAT_INDEX++; \
} \
}
#if (defined(TRC_CFG_USE_GCC_STATEMENT_EXPR) && TRC_CFG_USE_GCC_STATEMENT_EXPR == 1) || __GNUC__ || __IAR_SYSTEMS_ICC__ || __TI_ARM__
#define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1(e1) __extension__({e1;})
#define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(e1, e2) __extension__({e1; e2;})
#define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3(e1, e2, e3) __extension__({e1; e2; e3;})
#define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4(e1, e2, e3, e4) __extension__({e1; e2; e3; e4;})
#define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_5(e1, e2, e3, e4, e5) __extension__({e1; e2; e3; e4; e5;})
#define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_6(e1, e2, e3, e4, e5, e6) __extension__({e1; e2; e3; e4; e5; e6;})
#define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_7(e1, e2, e3, e4, e5, e6, e7) __extension__({e1; e2; e3; e4; e5; e6; e7;})
#else
#define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1(e1) (e1)
#define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(e1, e2) (e1, e2)
#define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3(e1, e2, e3) (e1, e2, e3)
#define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4(e1, e2, e3, e4) (e1, e2, e3, e4)
#define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_5(e1, e2, e3, e4, e5) (e1, e2, e3, e4, e5)
#define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_6(e1, e2, e3, e4, e5, e6) (e1, e2, e3, e4, e5, e6)
#define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_7(e1, e2, e3, e4, e5, e6, e7) (e1, e2, e3, e4, e5, e6, e7)
#endif
#endif /* TRC_UTILITY_H */

View File

@@ -0,0 +1,21 @@
Tracealyzer Stream Port for SEGGER J-Link
Percepio AB
www.percepio.com
-----------------------------------------
This directory contains a "stream port" for the Tracealyzer recorder library,
i.e., the specific code needed to use a particular interface for streaming a
Tracealyzer RTOS trace. The stream port is defined by a set of macros in
trcStreamPort.h, found in the "include" directory.
This particular stream port targets SEGGER J-Link debug probes, using the RTT
interface provided by SEGGER.
To use this stream port, make sure that include/trcStreamPort.h is found
by the compiler (i.e., add this folder to your project's include paths) and
add all included source files to your build. Make sure no other versions of
trcStreamPort.h are included by mistake!
Note that this stream port also contains SEGGER's RTT driver.
See also http://percepio.com/2016/10/05/rtos-tracing.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,169 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The configuration for trace streaming ("stream ports").
*/
#ifndef TRC_STREAM_PORT_CONFIG_H
#define TRC_STREAM_PORT_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @def TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER
*
* @brief This define will determine whether to use the internal buffer or not.
* If file writing creates additional trace events (i.e. it uses semaphores or mutexes),
* then the internal buffer must be enabled to avoid infinite recursion.
*/
#define TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER 0
/**
* @def TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE
*
* @brief Configures the size of the internal buffer if used.
*/
#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE 5120
/**
* @def TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_WRITE_MODE
*
* @brief This should be set to TRC_INTERNAL_EVENT_BUFFER_OPTION_WRITE_MODE_DIRECT for best performance.
*/
#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_WRITE_MODE TRC_INTERNAL_EVENT_BUFFER_OPTION_WRITE_MODE_DIRECT
/**
* @def TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_TRANSFER_MODE
*
* @brief Defines if the internal buffer will attempt to transfer all data each time or limit it to a chunk size.
*/
#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_TRANSFER_MODE TRC_INTERNAL_EVENT_BUFFER_OPTION_TRANSFER_MODE_ALL
/**
* @def TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_SIZE
*
* @brief Defines the maximum chunk size when transferring
* internal buffer events in chunks.
*/
#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_SIZE 1024
/**
* @def TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_SIZE_LIMIT
*
* @brief Defines the number of transferred bytes needed to trigger another transfer.
* It also depends on TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_COUNT_LIMIT to set a maximum number
* of additional transfers this loop.
* This will increase throughput by immediately doing a transfer and not wait for another xTraceTzCtrl() loop.
*/
#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_SIZE_LIMIT 256
/**
* @def TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_COUNT_LIMIT
*
* @brief Defines the maximum number of times to trigger another transfer before returning to xTraceTzCtrl().
* It also depends on TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_SIZE_LIMIT to see if a meaningful amount of data was
* transferred in the last loop.
* This will increase throughput by immediately doing a transfer and not wait for another xTraceTzCtrl() loop.
*/
#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_COUNT_LIMIT 5
/**
* @def TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_SIZE
*
* @brief Defines the size of the "up" RTT buffer (target -> host) to use for writing
* the trace data, for RTT buffer 1 or higher.
*
* This setting is ignored for RTT buffer 0, which can't be reconfigured
* in runtime and therefore hard-coded to use the defines in SEGGER_RTT_Conf.h.
*
* Default buffer size for Tracealyzer is 5120 bytes.
*
* If you have a stand-alone J-Link probe, the can be decreased to around 1 KB.
* But integrated J-Link OB interfaces are slower and needs about 5-10 KB,
* depending on the amount of data produced.
*/
#define TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_SIZE 5120
/**
* @def TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_SIZE
*
* @brief Defines the size of the "down" RTT buffer (host -> target) to use for reading
* commands from Tracealyzer, for RTT buffer 1 or higher.
*
* Default buffer size for Tracealyzer is 32 bytes.
*
* This setting is ignored for RTT buffer 0, which can't be reconfigured
* in runtime and therefore hard-coded to use the defines in SEGGER_RTT_Conf.h.
*/
#define TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_SIZE 32
/**
* @def TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX
*
* @brief Defines the RTT buffer to use for writing the trace data. Make sure that
* the PC application has the same setting (File->Settings).
*
* Default: 1
*
* We don't recommend using RTT buffer 0, since mainly intended for terminals.
* If you prefer to use buffer 0, it must be configured in SEGGER_RTT_Conf.h.
*/
#define TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX 1
/**
* @def TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX
*
* @brief Defines the RTT buffer to use for reading the trace data. Make sure that
* the PC application has the same setting (File->Settings).
*
* Default: 1
*
* We don't recommend using RTT buffer 0, since mainly intended for terminals.
* If you prefer to use buffer 0, it must be configured in SEGGER_RTT_Conf.h.
*/
#define TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX 1
/**
* @def TRC_CFG_STREAM_PORT_RTT_MODE
*
* @brief This stream port for J-Link streaming relies on SEGGER RTT, that contains an
* internal RAM buffer read by the J-Link probes during execution.
*
* Possible values:
* - SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL
* - SEGGER_RTT_MODE_NO_BLOCK_SKIP (default)
*
* Using SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL ensure that you get a
* complete and valid trace. This may however cause blocking if your streaming
* interface isn't fast enough, which may disturb the real-time behavior.
*
* We therefore recommend SEGGER_RTT_MODE_NO_BLOCK_SKIP. In this mode,
* Tracealyzer will report lost events if the transfer is not
* fast enough. In that case, try increasing the size of the "up buffer".
*/
#define TRC_CFG_STREAM_PORT_RTT_MODE SEGGER_RTT_MODE_NO_BLOCK_SKIP
/**
* @def TRC_CFG_STREAM_PORT_RTT_NO_LOCK_WRITE
*
* @brief Sets if RTT should write without locking or not when writing
* RTT data. This should normally be disabled with an exception being
* Zephyr, where the SEGGER RTT locks aren't necessary and causes
* problems if enabled.
*
* Default: 0
*/
#define TRC_CFG_STREAM_PORT_RTT_NO_LOCK_WRITE 0
#ifdef __cplusplus
}
#endif
#endif /* TRC_STREAM_PORT_CONFIG_H */

View File

@@ -0,0 +1,238 @@
/*********************************************************************
* SEGGER MICROCONTROLLER GmbH & Co. KG *
* Solutions for real time microcontroller applications *
**********************************************************************
* *
* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* SEGGER RTT * Real Time Transfer for embedded targets *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* * This software may in its unmodified form be freely redistributed *
* in source, linkable, or executable form. *
* * The source code may be modified, provided the source code *
* retains the above copyright notice, this list of conditions and *
* the following disclaimer. *
* * Modified versions of this software in source, executable, or *
* linkable form may not be distributed without prior consent of *
* SEGGER. *
* * This software may only be used for communication with SEGGER *
* J-Link debug probes. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
* *
* RTT version: 6.00e *
* *
**********************************************************************
---------------------------END-OF-HEADER------------------------------
File : SEGGER_RTT.h
Purpose : Implementation of SEGGER real-time transfer which allows
real-time communication on targets which support debugger
memory accesses while the CPU is running.
Revision: $Rev: 4079 $
----------------------------------------------------------------------
*/
#ifndef SEGGER_RTT_H
#define SEGGER_RTT_H
#include "SEGGER_RTT_Conf.h"
/*********************************************************************
*
* Defines, fixed
*
**********************************************************************
*/
/*********************************************************************
*
* Types
*
**********************************************************************
*/
//
// Description for a circular buffer (also called "ring buffer")
// which is used as up-buffer (T->H)
//
typedef struct {
const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4"
char* pBuffer; // Pointer to start of buffer
unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty.
unsigned WrOff; // Position of next item to be written by either target.
volatile unsigned RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host.
unsigned Flags; // Contains configuration flags
} SEGGER_RTT_BUFFER_UP;
//
// Description for a circular buffer (also called "ring buffer")
// which is used as down-buffer (H->T)
//
typedef struct {
const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4"
char* pBuffer; // Pointer to start of buffer
unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty.
volatile unsigned WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host.
unsigned RdOff; // Position of next item to be read by target (down-buffer).
unsigned Flags; // Contains configuration flags
} SEGGER_RTT_BUFFER_DOWN;
//
// RTT control block which describes the number of buffers available
// as well as the configuration for each buffer
//
//
typedef struct {
char acID[16]; // Initialized to "SEGGER RTT"
int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2)
int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2)
SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host
SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target
} SEGGER_RTT_CB;
/*********************************************************************
*
* Global data
*
**********************************************************************
*/
extern SEGGER_RTT_CB _SEGGER_RTT;
/*********************************************************************
*
* RTT API functions
*
**********************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
int SEGGER_RTT_AllocDownBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
int SEGGER_RTT_AllocUpBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
int SEGGER_RTT_GetKey (void);
unsigned SEGGER_RTT_HasData (unsigned BufferIndex);
int SEGGER_RTT_HasKey (void);
void SEGGER_RTT_Init (void);
unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize);
unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize);
int SEGGER_RTT_SetNameDownBuffer (unsigned BufferIndex, const char* sName);
int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName);
int SEGGER_RTT_SetFlagsDownBuffer (unsigned BufferIndex, unsigned Flags);
int SEGGER_RTT_SetFlagsUpBuffer (unsigned BufferIndex, unsigned Flags);
int SEGGER_RTT_WaitKey (void);
unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s);
void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
//
// Function macro for performance optimization
//
#define SEGGER_RTT_HASDATA(n) (_SEGGER_RTT.aDown[n].WrOff - _SEGGER_RTT.aDown[n].RdOff)
/*********************************************************************
*
* RTT "Terminal" API functions
*
**********************************************************************
*/
int SEGGER_RTT_SetTerminal (char TerminalId);
int SEGGER_RTT_TerminalOut (char TerminalId, const char* s);
/*********************************************************************
*
* RTT printf functions (require SEGGER_RTT_printf.c)
*
**********************************************************************
*/
int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...);
#ifdef __cplusplus
}
#endif
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
//
// Operating modes. Define behavior if buffer is full (not enough space for entire message)
//
#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0U) // Skip. Do not block, output nothing. (Default)
#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1U) // Trim: Do not block, output as much as fits.
#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2U) // Block: Wait until there is space in the buffer.
#define SEGGER_RTT_MODE_MASK (3U)
//
// Control sequences, based on ANSI.
// Can be used to control color, and clear the screen
//
#define RTT_CTRL_RESET "" // Reset to default colors
#define RTT_CTRL_CLEAR "" // Clear screen, reposition cursor to top left
#define RTT_CTRL_TEXT_BLACK ""
#define RTT_CTRL_TEXT_RED ""
#define RTT_CTRL_TEXT_GREEN ""
#define RTT_CTRL_TEXT_YELLOW ""
#define RTT_CTRL_TEXT_BLUE ""
#define RTT_CTRL_TEXT_MAGENTA ""
#define RTT_CTRL_TEXT_CYAN ""
#define RTT_CTRL_TEXT_WHITE ""
#define RTT_CTRL_TEXT_BRIGHT_BLACK ""
#define RTT_CTRL_TEXT_BRIGHT_RED ""
#define RTT_CTRL_TEXT_BRIGHT_GREEN ""
#define RTT_CTRL_TEXT_BRIGHT_YELLOW ""
#define RTT_CTRL_TEXT_BRIGHT_BLUE ""
#define RTT_CTRL_TEXT_BRIGHT_MAGENTA ""
#define RTT_CTRL_TEXT_BRIGHT_CYAN ""
#define RTT_CTRL_TEXT_BRIGHT_WHITE ""
#define RTT_CTRL_BG_BLACK ""
#define RTT_CTRL_BG_RED ""
#define RTT_CTRL_BG_GREEN ""
#define RTT_CTRL_BG_YELLOW ""
#define RTT_CTRL_BG_BLUE ""
#define RTT_CTRL_BG_MAGENTA ""
#define RTT_CTRL_BG_CYAN ""
#define RTT_CTRL_BG_WHITE ""
#define RTT_CTRL_BG_BRIGHT_BLACK ""
#define RTT_CTRL_BG_BRIGHT_RED ""
#define RTT_CTRL_BG_BRIGHT_GREEN ""
#define RTT_CTRL_BG_BRIGHT_YELLOW ""
#define RTT_CTRL_BG_BRIGHT_BLUE ""
#define RTT_CTRL_BG_BRIGHT_MAGENTA ""
#define RTT_CTRL_BG_BRIGHT_CYAN ""
#define RTT_CTRL_BG_BRIGHT_WHITE ""
#endif
/*************************** End of file ****************************/

View File

@@ -0,0 +1,263 @@
/*********************************************************************
* SEGGER MICROCONTROLLER GmbH & Co. KG *
* Solutions for real time microcontroller applications *
**********************************************************************
* *
* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* SEGGER RTT * Real Time Transfer for embedded targets *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* * This software may in its unmodified form be freely redistributed *
* in source, linkable, or executable form. *
* * The source code may be modified, provided the source code *
* retains the above copyright notice, this list of conditions and *
* the following disclaimer. *
* * Modified versions of this software in source, executable, or *
* linkable form may not be distributed without prior consent of *
* SEGGER. *
* * This software may only be used for communication with SEGGER *
* J-Link debug probes. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
* *
* RTT version: 6.00e *
* *
**********************************************************************
----------------------------------------------------------------------
File : SEGGER_RTT_Conf.h
Purpose : Implementation of SEGGER real-time transfer (RTT) which
allows real-time communication on targets which support
debugger memory accesses while the CPU is running.
Revision: $Rev: 3892 $
---------------------------END-OF-HEADER------------------------------
*/
#ifndef SEGGER_RTT_CONF_H
#define SEGGER_RTT_CONF_H
#ifdef __IAR_SYSTEMS_ICC__
#include <intrinsics.h>
#endif
/*********************************************************************
*
* Defines, configurable
*
**********************************************************************
*/
#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (3) // Max. number of up-buffers (T->H) available on this target (Default: 3)
#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (3) // Max. number of down-buffers (H->T) available on this target (Default: 3)
#define BUFFER_SIZE_UP (64) // Size of the buffer for terminal output of target, up to host (Default: 1k)
#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16)
#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64)
#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0)
// This can be used to place the RTT control block in the right memory range, if no found automatically.
// This example is for NXP LPC54018, needs to be adapted for each MCU family.
//#define SEGGER_RTT_SECTION ".data.$RAM2"
//
// Target is not allowed to perform other RTT operations while string still has not been stored completely.
// Otherwise we would probably end up with a mixed string in the buffer.
// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here.
//
// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4.
// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches.
// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly.
// (Higher priority = lower priority number)
// Default value for embOS: 128u
// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC
// or define SEGGER_RTT_LOCK() to completely disable interrupts.
//
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20)
/*********************************************************************
*
* RTT lock configuration for SEGGER Embedded Studio,
* Rowley CrossStudio and GCC
*/
#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)
#ifdef __ARM_ARCH_6M__
#define SEGGER_RTT_LOCK() { \
unsigned int LockState; \
__asm volatile ("mrs %0, primask \n\t" \
"mov r1, $1 \n\t" \
"msr primask, r1 \n\t" \
: "=r" (LockState) \
: \
: "r1" \
);
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \
: \
: "r" (LockState) \
: \
); \
}
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
#endif
#define SEGGER_RTT_LOCK() { \
unsigned int LockState; \
__asm volatile ("mrs %0, basepri \n\t" \
"mov r1, %1 \n\t" \
"msr basepri, r1 \n\t" \
: "=r" (LockState) \
: "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \
: "r1" \
);
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \
: \
: "r" (LockState) \
: \
); \
}
#elif defined(__ARM_ARCH_7A__)
#define SEGGER_RTT_LOCK() { \
unsigned int LockState; \
__asm volatile ("mrs r1, CPSR \n\t" \
"mov %0, r1 \n\t" \
"orr r1, r1, #0xC0 \n\t" \
"msr CPSR_c, r1 \n\t" \
: "=r" (LockState) \
: \
: "r1" \
);
#define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \
"mrs r1, CPSR \n\t" \
"bic r1, r1, #0xC0 \n\t" \
"and r0, r0, #0xC0 \n\t" \
"orr r1, r1, r0 \n\t" \
"msr CPSR_c, r1 \n\t" \
: \
: "r" (LockState) \
: "r0", "r1" \
); \
}
#else
#define SEGGER_RTT_LOCK()
#define SEGGER_RTT_UNLOCK()
#endif
#endif
/*********************************************************************
*
* RTT lock configuration for IAR EWARM
*/
#ifdef __ICCARM__
#if (defined (__ARM6M__) && (__CORE__ == __ARM6M__))
#define SEGGER_RTT_LOCK() { \
unsigned int LockState; \
LockState = __get_PRIMASK(); \
__set_PRIMASK(1);
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
}
#elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__)))
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
#endif
#define SEGGER_RTT_LOCK() { \
unsigned int LockState; \
LockState = __get_BASEPRI(); \
__set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
#define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \
}
#endif
#endif
/*********************************************************************
*
* RTT lock configuration for IAR RX
*/
#ifdef __ICCRX__
#define SEGGER_RTT_LOCK() { \
unsigned long LockState; \
LockState = __get_interrupt_state(); \
__disable_interrupt();
#define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \
}
#endif
/*********************************************************************
*
* RTT lock configuration for KEIL ARM
*/
#ifdef __CC_ARM
#if (defined __TARGET_ARCH_6S_M)
#define SEGGER_RTT_LOCK() { \
unsigned int LockState; \
register unsigned char PRIMASK __asm( "primask"); \
LockState = PRIMASK; \
PRIMASK = 1u; \
__schedule_barrier();
#define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \
__schedule_barrier(); \
}
#elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
#endif
#define SEGGER_RTT_LOCK() { \
unsigned int LockState; \
register unsigned char BASEPRI __asm( "basepri"); \
LockState = BASEPRI; \
BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \
__schedule_barrier();
#define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \
__schedule_barrier(); \
}
#endif
#endif
/*********************************************************************
*
* RTT lock configuration fallback
*/
#ifndef SEGGER_RTT_LOCK
#define SEGGER_RTT_LOCK() // Lock RTT (nestable) (i.e. disable interrupts)
#endif
#ifndef SEGGER_RTT_UNLOCK
#define SEGGER_RTT_UNLOCK() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state)
#endif
#endif
/*************************** End of file ****************************/

View File

@@ -0,0 +1,166 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The interface definitions for trace streaming ("stream ports").
* This "stream port" sets up the recorder to use SEGGER RTT as streaming channel.
*
* Note that this stream port is more complex than the typical case, since
* the J-Link interface uses a separate RAM buffer in SEGGER_RTT.c, instead
* of the default buffer included in the recorder core. The other stream ports
* offer more typical examples of how to define a custom streaming interface.
*/
#ifndef TRC_STREAM_PORT_H
#define TRC_STREAM_PORT_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#ifdef __cplusplus
extern "C" {
#endif
#include <trcDefines.h>
#include <trcTypes.h>
#include <trcStreamPortConfig.h>
#include <SEGGER_RTT_Conf.h>
#include <SEGGER_RTT.h>
#define TRC_USE_INTERNAL_BUFFER (TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER)
#define TRC_INTERNAL_EVENT_BUFFER_WRITE_MODE (TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_WRITE_MODE)
#define TRC_INTERNAL_EVENT_BUFFER_TRANSFER_MODE (TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_TRANSFER_MODE)
#define TRC_INTERNAL_BUFFER_CHUNK_SIZE (TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_SIZE)
#define TRC_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_SIZE_LIMIT (TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_SIZE_LIMIT)
#define TRC_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_COUNT_LIMIT (TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_COUNT_LIMIT)
/* Aligned */
#define TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t))
/* Aligned */
#define TRC_STREAM_PORT_RTT_UP_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t))
/* Aligned */
#define TRC_STREAM_PORT_RTT_DOWN_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t))
/**
* @brief A structure representing the trace stream port buffer.
*/
typedef struct TraceStreamPortBuffer /* Aligned */
{
#if (TRC_USE_INTERNAL_BUFFER == 1)
uint8_t bufferInternal[TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE];
#endif
uint8_t bufferUp[TRC_STREAM_PORT_RTT_UP_BUFFER_SIZE];
uint8_t bufferDown[TRC_STREAM_PORT_RTT_DOWN_BUFFER_SIZE];
} TraceStreamPortBuffer_t;
/**
* @internal Stream port initialize callback.
*
* This function is called by the recorder as part of its initialization phase.
*
* @param[in] pxBuffer Buffer
*
* @retval TRC_FAIL Initialization failed
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer);
/**
* @brief Allocates data from the stream port.
*
* @param[in] uiSize Allocation size
* @param[out] ppvData Allocation data pointer
*
* @retval TRC_FAIL Allocate failed
* @retval TRC_SUCCESS Success
*/
#if (TRC_USE_INTERNAL_BUFFER == 1)
#if (TRC_INTERNAL_EVENT_BUFFER_WRITE_MODE == TRC_INTERNAL_EVENT_BUFFER_OPTION_WRITE_MODE_COPY)
#define xTraceStreamPortAllocate(uiSize, ppvData) ((void)(uiSize), xTraceStaticBufferGet(ppvData))
#else
#define xTraceStreamPortAllocate(uiSize, ppvData) ((void)(uiSize), xTraceInternalEventBufferAlloc(uiSize, ppvData))
#endif
#else
#define xTraceStreamPortAllocate(uiSize, ppvData) ((void)(uiSize), xTraceStaticBufferGet(ppvData))
#endif
/**
* @brief Commits data to the stream port, depending on the implementation/configuration of the
* stream port this data might be directly written to the stream port interface, buffered, or
* something else.
*
* @param[in] pvData Data to commit
* @param[in] uiSize Data to commit size
* @param[out] piBytesCommitted Bytes committed
*
* @retval TRC_FAIL Commit failed
* @retval TRC_SUCCESS Success
*/
#if (TRC_USE_INTERNAL_BUFFER == 1)
#if (TRC_INTERNAL_EVENT_BUFFER_WRITE_MODE == TRC_INTERNAL_EVENT_BUFFER_OPTION_WRITE_MODE_COPY)
#define xTraceStreamPortCommit xTraceInternalEventBufferPush
#else
#define xTraceStreamPortCommit xTraceInternalEventBufferAllocCommit
#endif
#else
#define xTraceStreamPortCommit xTraceStreamPortWriteData
#endif
/**
* @brief Writes data through the stream port interface.
*
* @param[in] pvData Data to write
* @param[in] uiSize Data to write size
* @param[out] piBytesWritten Bytes written
*
* @retval TRC_FAIL Write failed
* @retval TRC_SUCCESS Success
*/
#if (defined(TRC_CFG_STREAM_PORT_RTT_NO_LOCK_WRITE) && TRC_CFG_STREAM_PORT_RTT_NO_LOCK_WRITE == 1)
#define xTraceStreamPortWriteData(pvData, uiSize, piBytesWritten) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(piBytesWritten) = (int32_t)SEGGER_RTT_WriteNoLock((TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX), (const char*)pvData, uiSize), TRC_SUCCESS)
#else
#define xTraceStreamPortWriteData(pvData, uiSize, piBytesWritten) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(piBytesWritten) = (int32_t)SEGGER_RTT_Write((TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX), (const char*)pvData, uiSize), TRC_SUCCESS)
#endif
/**
* @brief Reads data through the stream port interface.
*
* @param[in] pvData Destination data buffer
* @param[in] uiSize Destination data buffer size
* @param[out] piBytesRead Bytes read
*
* @retval TRC_FAIL Read failed
* @retval TRC_SUCCESS Success
*/
#define xTraceStreamPortReadData(pvData, uiSize, piBytesRead) ((SEGGER_RTT_HASDATA(TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX)) ? (*(piBytesRead) = (int32_t)SEGGER_RTT_Read((TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX), (char*)(pvData), uiSize), TRC_SUCCESS) : TRC_SUCCESS)
traceResult xTraceStreamPortOnEnable(uint32_t uiStartOption);
#define xTraceStreamPortOnDisable() (void)(TRC_SUCCESS)
#define xTraceStreamPortOnTraceBegin() (void)(TRC_SUCCESS)
#define xTraceStreamPortOnTraceEnd() (void)(TRC_SUCCESS)
#ifdef __cplusplus
}
#endif
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
#endif /* TRC_STREAM_PORT_H */

View File

@@ -0,0 +1,63 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* Supporting functions for trace streaming, used by the "stream ports"
* for reading and writing data to the interface.
*
* Note that this stream port is more complex than the typical case, since
* the J-Link interface uses a separate RAM buffer in SEGGER_RTT.c, instead
* of the default buffer included in the recorder core. The other stream ports
* offer more typical examples of how to define a custom streaming interface.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
static TraceStreamPortBuffer_t* pxStreamPortRTT TRC_CFG_RECORDER_DATA_ATTRIBUTE;
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer)
{
TRC_ASSERT_EQUAL_SIZE(TraceStreamPortBuffer_t, TraceStreamPortRTT_t);
if (pxBuffer == 0)
{
return TRC_FAIL;
}
pxStreamPortRTT = (TraceStreamPortBuffer_t*)pxBuffer;
#if (TRC_USE_INTERNAL_BUFFER == 1)
return xTraceInternalEventBufferInitialize(pxStreamPortRTT->bufferInternal, sizeof(pxStreamPortRTT->bufferInternal));
#else
return TRC_SUCCESS;
#endif
}
traceResult xTraceStreamPortOnEnable(uint32_t uiStartOption)
{
(void)uiStartOption;
/* Configure the RTT buffers */
if (SEGGER_RTT_ConfigUpBuffer(TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX, "TzData", pxStreamPortRTT->bufferUp, sizeof(pxStreamPortRTT->bufferUp), TRC_CFG_STREAM_PORT_RTT_MODE) < 0)
{
return TRC_FAIL;
}
if (SEGGER_RTT_ConfigDownBuffer(TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX, "TzCtrl", pxStreamPortRTT->bufferDown, sizeof(pxStreamPortRTT->bufferDown), TRC_CFG_STREAM_PORT_RTT_MODE) < 0)
{
return TRC_FAIL;
}
return TRC_SUCCESS;
}
#endif
#endif

View File

@@ -0,0 +1,119 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation for errors.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
#if (defined(TRC_CFG_TEST_MODE) && (TRC_CFG_TEST_MODE) == 1)
extern inline TraceBaseType_t prvTraceAssertCheckCondition(TraceBaseType_t condition);
#endif
#define TRC_ASSERT_STATE_INDEX_LINE_NUMBER 0u
static TraceAssertData_t* pxAssertData TRC_CFG_RECORDER_DATA_ATTRIBUTE;
traceResult xTraceAssertInitialize(TraceAssertData_t *pxBuffer)
{
TRC_ASSERT(pxBuffer != (void*)0);
pxAssertData = pxBuffer;
pxAssertData->xEntry = 0;
xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_ASSERT);
return TRC_SUCCESS;
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
void prvTraceAssertCreate(const char* szFilePath, TraceUnsignedBaseType_t uxLineNumber)
{
TraceBaseType_t i, xLength;
TraceUnsignedBaseType_t uxEntryLineNumber = 0xFFFFFFFFUL;
static TraceUnsignedBaseType_t uxRecursionGuard = 0u;
if (uxRecursionGuard == 0u)
{
/* Recursion can only get here once */
uxRecursionGuard = 1u;
if (xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ASSERT) == 0U)
{
return;
}
if (pxAssertData->xEntry == 0)
{
if (xTraceEntryCreate(&pxAssertData->xEntry) == TRC_FAIL)
{
return;
}
}
(void)xTraceEntryGetState(pxAssertData->xEntry, TRC_ASSERT_STATE_INDEX_LINE_NUMBER, &uxEntryLineNumber);
/* We only save the first ASSERT information */
if (uxEntryLineNumber == 0u)
{
/* Find length */
for (i = 0; (szFilePath[i] != (char)0) && (i < 128); i++) {} /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/ /*cstat !MISRAC2004-17.4_b We need to access every character in the string*/
xLength = i;
/* Find last slash or backslash */
for (i = xLength - 1; (i >= 0) && ((szFilePath[i] != '\\') && (szFilePath[i] != '/')); i--) {} /*cstat !MISRAC2004-17.4_b We need to access every character in the string*/
/* We treat the entry as an object and set it's name and state */
(void)xTraceObjectSetName((TraceObjectHandle_t)pxAssertData->xEntry, &szFilePath[i + 1]); /*cstat !MISRAC2004-17.4_b We need to access a specific character in the string*/
(void)xTraceObjectSetState((TraceObjectHandle_t)pxAssertData->xEntry, uxLineNumber);
(void)xTraceError(TRC_ERROR_ASSERT);
}
}
(void)xTraceDiagnosticsIncrease(TRC_DIAGNOSTICS_ASSERTS_TRIGGERED);
}
traceResult xTraceAssertGet(TraceStringHandle_t *pxFileNameStringHandle, TraceUnsignedBaseType_t *puxLineNumber)
{
TRC_ASSERT(pxFileNameStringHandle != (void*)0);
TRC_ASSERT(puxLineNumber != (void*)0);
if (xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ASSERT) == 0U)
{
return TRC_FAIL;
}
*puxLineNumber = 0u;
(void)xTraceEntryGetState(pxAssertData->xEntry, TRC_ASSERT_STATE_INDEX_LINE_NUMBER, puxLineNumber);
if (*puxLineNumber == 0u)
{
return TRC_FAIL;
}
/* The string handle can be set to the entry handle */
*pxFileNameStringHandle = (TraceStringHandle_t)pxAssertData->xEntry;
return TRC_SUCCESS;
}
#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */

View File

@@ -0,0 +1,102 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation of intervals.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
static TraceCounterData_t *pxCounterData TRC_CFG_RECORDER_DATA_ATTRIBUTE;
traceResult xTraceCounterInitialize(TraceCounterData_t *pxBuffer)
{
TRC_ASSERT(pxBuffer != (void*)0);
pxCounterData = pxBuffer;
pxCounterData->xCallbackFunction = 0;
xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER);
return TRC_SUCCESS;
}
traceResult xTraceCounterSetCallback(const TraceCounterCallback_t xCallback)
{
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER));
TRC_ASSERT(xCallback != 0);
pxCounterData->xCallbackFunction = xCallback;
return TRC_SUCCESS;
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceCounterCreate(const char *szName, TraceBaseType_t xInitialValue, TraceBaseType_t xLowerLimit, TraceBaseType_t xUpperLimit, TraceCounterHandle_t *pxCounterHandle)
{
TraceObjectHandle_t xObjectHandle;
TraceUnsignedBaseType_t uxStates[3] = { 0 };
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER));
/* This should never fail */
TRC_ASSERT(pxCounterHandle != (void*)0);
TRC_ASSERT((xInitialValue >= xLowerLimit) && (xInitialValue <= xUpperLimit));
uxStates[TRC_COUNTER_VALUE_INDEX] = (TraceUnsignedBaseType_t)xInitialValue;
uxStates[TRC_COUNTER_LOWER_LIMIT_INDEX] = (TraceUnsignedBaseType_t)xLowerLimit;
uxStates[TRC_COUNTER_UPPER_LIMIT_INDEX] = (TraceUnsignedBaseType_t)xUpperLimit;
/* We need to check this */
if (xTraceObjectRegisterInternal(PSF_EVENT_COUNTER_CREATE, (void*)0, szName, 3u, uxStates, TRC_ENTRY_OPTION_COUNTER, &xObjectHandle) == TRC_FAIL)
{
return TRC_FAIL;
}
*pxCounterHandle = (TraceCounterHandle_t)xObjectHandle;
return TRC_SUCCESS;
}
traceResult xTraceCounterSet(TraceCounterHandle_t xCounterHandle, TraceBaseType_t xValue)
{
TraceBaseType_t xLowerLimit = 0;
TraceBaseType_t xUpperLimit = 0;
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER));
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceObjectSetSpecificState((TraceEntryHandle_t)xCounterHandle, TRC_COUNTER_VALUE_INDEX, (TraceUnsignedBaseType_t)xValue) == TRC_SUCCESS);
(void)xTraceEventCreate2(PSF_EVENT_COUNTER_CHANGE, (TraceUnsignedBaseType_t)xCounterHandle, (TraceUnsignedBaseType_t)xValue); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 Suppress conversion from pointer to integer check*/
/* These should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceCounterGetLowerLimit(xCounterHandle, &xLowerLimit) == TRC_SUCCESS);
TRC_ASSERT_ALWAYS_EVALUATE(xTraceCounterGetUpperLimit(xCounterHandle, &xUpperLimit) == TRC_SUCCESS);
if ((xValue < xLowerLimit) || (xValue > xUpperLimit))
{
(void)xTraceEventCreate1(PSF_EVENT_COUNTER_LIMIT_EXCEEDED, (TraceUnsignedBaseType_t)xCounterHandle); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 Suppress conversion from pointer to integer check*/
if (pxCounterData->xCallbackFunction != 0)
{
pxCounterData->xCallbackFunction(xCounterHandle);
}
}
return TRC_SUCCESS;
}
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */

View File

@@ -0,0 +1,48 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation of dependencies.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#define TRC_DEPENDENCY_STATE_INDEX_TYPE 0UL
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceDependencyRegister(const char* szName, TraceUnsignedBaseType_t uxDependencyType)
{
TraceObjectHandle_t xObjectHandle;
TraceUnsignedBaseType_t auxStates[TRC_ENTRY_TABLE_STATE_COUNT] = { 0UL };
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_CORE));
/* This should never fail */
TRC_ASSERT(szName != (void*)0);
/* This should never fail */
TRC_ASSERT(szName[0] != (char)0); /*cstat !MISRAC2004-17.4_b Checking first character*/ /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
switch (uxDependencyType)
{
case TRC_DEPENDENCY_TYPE_ELF:
auxStates[TRC_DEPENDENCY_STATE_INDEX_TYPE] = uxDependencyType;
break;
default:
return TRC_FAIL;
break;
}
return xTraceObjectRegisterInternal(PSF_EVENT_DEPENDENCY_REGISTER, (void*)0, szName, 1u, auxStates, TRC_ENTRY_OPTION_DEPENDENCY, &xObjectHandle);
}
#endif
#endif

View File

@@ -0,0 +1,159 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation of the diagnostics.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
static TraceDiagnosticsData_t *pxDiagnostics TRC_CFG_RECORDER_DATA_ATTRIBUTE;
traceResult xTraceDiagnosticsInitialize(TraceDiagnosticsData_t *pxBuffer)
{
uint32_t i;
/* This should never fail */
TRC_ASSERT(pxBuffer != (void*)0);
pxDiagnostics = pxBuffer;
for (i = 0u; i < (TRC_DIAGNOSTICS_COUNT); i++)
{
pxDiagnostics->metrics[i] = 0;
}
xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_DIAGNOSTICS);
return TRC_SUCCESS;
}
traceResult xTraceDiagnosticsGet(TraceDiagnosticsType_t xType, TraceBaseType_t* pxValue)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_DIAGNOSTICS));
/* This should never fail */
TRC_ASSERT((TraceUnsignedBaseType_t)xType < TRC_DIAGNOSTICS_COUNT);
/* This should never fail */
TRC_ASSERT(pxValue != (void*)0);
*pxValue = pxDiagnostics->metrics[(TraceUnsignedBaseType_t)xType];
return TRC_SUCCESS;
}
traceResult xTraceDiagnosticsSet(TraceDiagnosticsType_t xType, TraceBaseType_t xValue)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_DIAGNOSTICS));
/* This should never fail */
TRC_ASSERT((TraceUnsignedBaseType_t)xType < TRC_DIAGNOSTICS_COUNT);
pxDiagnostics->metrics[(TraceUnsignedBaseType_t)xType] = xValue;
return TRC_SUCCESS;
}
traceResult xTraceDiagnosticsAdd(TraceDiagnosticsType_t xType, TraceBaseType_t xValue)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_DIAGNOSTICS));
/* This should never fail */
TRC_ASSERT((TraceUnsignedBaseType_t)xType < TRC_DIAGNOSTICS_COUNT);
pxDiagnostics->metrics[(TraceUnsignedBaseType_t)xType] += xValue;
return TRC_SUCCESS;
}
traceResult xTraceDiagnosticsIncrease(TraceDiagnosticsType_t xType)
{
return xTraceDiagnosticsAdd(xType, 1);
}
traceResult xTraceDiagnosticsDecrease(TraceDiagnosticsType_t xType)
{
return xTraceDiagnosticsAdd(xType, -1);
}
traceResult xTraceDiagnosticsSetIfHigher(TraceDiagnosticsType_t xType, TraceBaseType_t xValue)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_DIAGNOSTICS));
/* This should never fail */
TRC_ASSERT((TraceUnsignedBaseType_t)xType < TRC_DIAGNOSTICS_COUNT);
if (xValue > pxDiagnostics->metrics[xType])
{
pxDiagnostics->metrics[(TraceUnsignedBaseType_t)xType] = xValue;
}
return TRC_SUCCESS;
}
traceResult xTraceDiagnosticsSetIfLower(TraceDiagnosticsType_t xType, TraceBaseType_t xValue)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_DIAGNOSTICS));
/* This should never fail */
TRC_ASSERT((TraceUnsignedBaseType_t)xType < TRC_DIAGNOSTICS_COUNT);
if (xValue < pxDiagnostics->metrics[(TraceUnsignedBaseType_t)xType])
{
pxDiagnostics->metrics[(TraceUnsignedBaseType_t)xType] = xValue;
}
return TRC_SUCCESS;
}
traceResult xTraceDiagnosticsCheckStatus(void)
{
/* It is probably good if we always check this */
if (xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_DIAGNOSTICS) == 0U)
{
return TRC_FAIL;
}
if (pxDiagnostics->metrics[TRC_DIAGNOSTICS_ENTRY_SLOTS_NO_ROOM] > 0)
{
(void)xTraceWarning(TRC_WARNING_ENTRY_TABLE_SLOTS);
pxDiagnostics->metrics[TRC_DIAGNOSTICS_ENTRY_SLOTS_NO_ROOM] = 0;
}
if (pxDiagnostics->metrics[TRC_DIAGNOSTICS_ENTRY_SYMBOL_LONGEST_LENGTH] > (TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH))
{
(void)xTraceWarning(TRC_WARNING_ENTRY_SYMBOL_MAX_LENGTH);
pxDiagnostics->metrics[TRC_DIAGNOSTICS_ENTRY_SYMBOL_LONGEST_LENGTH] = 0;
}
if (pxDiagnostics->metrics[TRC_DIAGNOSTICS_BLOB_MAX_BYTES_TRUNCATED] > 0)
{
(void)xTraceWarning(TRC_WARNING_EVENT_SIZE_TRUNCATED);
pxDiagnostics->metrics[TRC_DIAGNOSTICS_BLOB_MAX_BYTES_TRUNCATED] = 0;
}
if (pxDiagnostics->metrics[TRC_DIAGNOSTICS_STACK_MONITOR_NO_SLOTS] > 0)
{
(void)xTraceWarning(TRC_WARNING_STACKMON_NO_SLOTS);
pxDiagnostics->metrics[TRC_DIAGNOSTICS_STACK_MONITOR_NO_SLOTS] = 0;
}
return TRC_SUCCESS;
}
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */

View File

@@ -0,0 +1,426 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation of the entry table.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <string.h>
/* (EntryAddress >= FirstEntryAddress) && (EntryAddress < EntryAddressOutsideArray) */
#define VALIDATE_ENTRY_HANDLE(xEntryHandle) (((void*)(xEntryHandle) >= (void*)&pxEntryTable->axEntries[0]) && ((void*)(xEntryHandle) < (void*)&pxEntryTable->axEntries[TRC_ENTRY_TABLE_SLOTS]))
/*cstat !MISRAC2004-19.4 Suppress macro check*/
#define GIVE_ENTRY_INDEX(xIndex) pxIndexTable->axFreeIndexes[pxIndexTable->uiFreeIndexCount] = (xIndex); pxIndexTable->uiFreeIndexCount++
/*cstat !MISRAC2004-19.4 Suppress macro check*/
#define GET_FREE_INDEX_COUNT() pxIndexTable->uiFreeIndexCount
/* Index = (EntryAddress - FirstEntryAddress) / EntrySize */
#define CALCULATE_ENTRY_INDEX(xEntryHandle) (TraceEntryIndex_t)(((TraceUnsignedBaseType_t)(xEntryHandle) - (TraceUnsignedBaseType_t)&pxEntryTable->axEntries[0]) / sizeof(TraceEntry_t))
/* Private function definitions */
static traceResult prvEntryIndexInitialize(void);
static traceResult prvEntryIndexTake(TraceEntryIndex_t *pxIndex);
/* Variables */
static TraceEntryTable_t *pxEntryTable TRC_CFG_RECORDER_DATA_ATTRIBUTE;
static TraceEntryIndexTable_t *pxIndexTable TRC_CFG_RECORDER_DATA_ATTRIBUTE;
traceResult xTraceEntryIndexTableInitialize(TraceEntryIndexTable_t* const pxBuffer)
{
/* This should never fail */
TRC_ASSERT(pxBuffer != (void*)0);
pxIndexTable = pxBuffer;
return prvEntryIndexInitialize();
}
traceResult xTraceEntryTableInitialize(TraceEntryTable_t* const pxBuffer)
{
uint32_t i, j;
/* This should never fail */
TRC_ASSERT(pxBuffer != (void*)0);
/* This should never fail */
TRC_ASSERT((TRC_ENTRY_TABLE_SLOTS) != 0);
pxEntryTable = pxBuffer;
pxEntryTable->uxSlots = (TraceUnsignedBaseType_t)(TRC_ENTRY_TABLE_SLOTS);
pxEntryTable->uxEntrySymbolLength = (TraceUnsignedBaseType_t)(TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE);
pxEntryTable->uxEntryStateCount = (TraceUnsignedBaseType_t)(TRC_ENTRY_TABLE_STATE_COUNT);
for (i = 0u; i < (uint32_t)(TRC_ENTRY_TABLE_SLOTS); i++)
{
pxEntryTable->axEntries[i].pvAddress = 0;
for (j = 0u; j < TRC_ENTRY_TABLE_STATE_COUNT; j++)
{
pxEntryTable->axEntries[i].xStates[j] = (TraceUnsignedBaseType_t)0;
}
pxEntryTable->axEntries[i].szSymbol[0] = (char)0; /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
}
xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY);
return TRC_SUCCESS;
}
traceResult xTraceEntryCreate(TraceEntryHandle_t *pxEntryHandle)
{
uint32_t i;
TraceEntryIndex_t xIndex;
TraceEntry_t *pxEntry;
TRACE_ALLOC_CRITICAL_SECTION();
/* We always check this */
if (xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY) == 0U)
{
return TRC_FAIL;
}
/* This should never fail */
TRC_ASSERT(pxEntryHandle != (void*)0);
TRACE_ENTER_CRITICAL_SECTION();
if (prvEntryIndexTake(&xIndex) != TRC_SUCCESS)
{
(void)xTraceDiagnosticsIncrease(TRC_DIAGNOSTICS_ENTRY_SLOTS_NO_ROOM);
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
pxEntry = &pxEntryTable->axEntries[xIndex];
pxEntry->pvAddress = (void*)pxEntry; /* We set a temporary address */
for (i = 0u; i < (uint32_t)(TRC_ENTRY_TABLE_STATE_COUNT); i++)
{
pxEntry->xStates[i] = (TraceUnsignedBaseType_t)0;
}
pxEntry->uiOptions = 0u;
pxEntry->szSymbol[0] = (char)0; /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
*pxEntryHandle = (TraceEntryHandle_t)pxEntry;
TRACE_EXIT_CRITICAL_SECTION();
return TRC_SUCCESS;
}
traceResult xTraceEntryDelete(TraceEntryHandle_t xEntryHandle)
{
TraceEntryIndex_t xIndex;
TRACE_ALLOC_CRITICAL_SECTION();
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* This should never fail */
TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
/* Calculate the index based on the entry address */
/* Does not need to be locked. */
/* This should never fail */
xIndex = CALCULATE_ENTRY_INDEX(xEntryHandle); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 Suppress conversion from pointer to integer check*/ /*cstat !MISRAC2004-17.2 !MISRAC2012-Rule-18.2 !MISRAC2012-Rule-18.4 Suppress pointer comparison check*/
TRC_ASSERT(xIndex < (TraceEntryIndex_t)TRC_ENTRY_TABLE_SLOTS);
TRACE_ENTER_CRITICAL_SECTION();
if (((TraceEntry_t*)xEntryHandle)->pvAddress == 0)
{
/* Someone else has deleted this already? */
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
/* A valid address, so we assume it is OK. */
/* We clear the address field which is used on host to see if entries are active. */
((TraceEntry_t*)xEntryHandle)->pvAddress = 0;
/* Give back the index */
GIVE_ENTRY_INDEX(xIndex);
TRACE_EXIT_CRITICAL_SECTION();
return TRC_SUCCESS;
}
traceResult xTraceEntryFind(const void* const pvAddress, TraceEntryHandle_t* pxEntryHandle)
{
uint32_t i;
TraceEntry_t* pxEntry;
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* This should never fail */
TRC_ASSERT(pxEntryHandle != (void*)0);
/* This should never fail */
TRC_ASSERT(pvAddress != (void*)0);
for (i = 0u; i < (uint32_t)(TRC_ENTRY_TABLE_SLOTS); i++)
{
pxEntry = &pxEntryTable->axEntries[i];
if (pxEntry->pvAddress == pvAddress)
{
*pxEntryHandle = (TraceEntryHandle_t)pxEntry;
return TRC_SUCCESS;
}
}
return TRC_FAIL;
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceEntrySetSymbol(const TraceEntryHandle_t xEntryHandle, const char* szSymbol, uint32_t uiLength)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
if (szSymbol == (void*)0)
{
szSymbol = ""; /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
uiLength = 0u; /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
}
/* Remember the longest symbol name */
(void)xTraceDiagnosticsSetIfHigher(TRC_DIAGNOSTICS_ENTRY_SYMBOL_LONGEST_LENGTH, (int32_t)uiLength);
if (uiLength >= (uint32_t)(TRC_ENTRY_TABLE_SYMBOL_LENGTH))
{
/* No room for null termination. Set to max. */
uiLength = (uint32_t)(TRC_ENTRY_TABLE_SYMBOL_LENGTH); /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
}
else
{
/* Include null termination by increasing the size by 1 */
uiLength = uiLength + 1u; /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
}
/* Does not need to be locked. */
/* This should never fail */
TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
/* This will also copy the null termination, if possible */
memcpy(((TraceEntry_t*)xEntryHandle)->szSymbol, szSymbol, uiLength);
return TRC_SUCCESS;
}
traceResult xTraceEntryGetCount(uint32_t* puiCount)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* This should never fail */
TRC_ASSERT(puiCount != (void*)0);
*puiCount = (uint32_t)(TRC_ENTRY_TABLE_SLOTS) - GET_FREE_INDEX_COUNT();
return TRC_SUCCESS;
}
traceResult xTraceEntryGetAtIndex(uint32_t index, TraceEntryHandle_t* pxEntryHandle)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* This should never fail */
TRC_ASSERT(index < (uint32_t)(TRC_ENTRY_TABLE_SLOTS));
/* This should never fail */
TRC_ASSERT(pxEntryHandle != (void*)0);
*pxEntryHandle = (TraceEntryHandle_t)&pxEntryTable->axEntries[index];
return TRC_SUCCESS;
}
#if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
traceResult xTraceEntryCreateWithAddress(void* const pvAddress, TraceEntryHandle_t* pxEntryHandle)
{
/* This should never fail */
TRC_ASSERT(pvAddress != (void*)0);
return TRC_ENTRY_CREATE_WITH_ADDRESS(pvAddress, pxEntryHandle);
}
traceResult xTraceEntrySetState(const TraceEntryHandle_t xEntryHandle, TraceUnsignedBaseType_t uxStateIndex, TraceUnsignedBaseType_t uxState)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* This should never fail */
TRC_ASSERT(uxStateIndex < (TraceUnsignedBaseType_t)(TRC_ENTRY_TABLE_STATE_COUNT));
/* This should never fail */
TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
return TRC_ENTRY_SET_STATE(xEntryHandle, uxStateIndex, uxState);
}
traceResult xTraceEntrySetOptions(const TraceEntryHandle_t xEntryHandle, uint32_t uiMask)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* Does not need to be locked. */
/* This should never fail */
TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
return TRC_ENTRY_SET_OPTIONS(xEntryHandle, uiMask);
}
traceResult xTraceEntryClearOptions(const TraceEntryHandle_t xEntryHandle, uint32_t uiMask)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* Does not need to be locked. */
/* This should never fail */
TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
return TRC_ENTRY_CLEAR_OPTIONS(xEntryHandle, uiMask);
}
traceResult xTraceEntryGetAddress(const TraceEntryHandle_t xEntryHandle, void **ppvAddress)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* This should never fail */
TRC_ASSERT(ppvAddress != (void*)0);
/* Does not need to be locked. */
/* This should never fail */
TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
return TRC_ENTRY_GET_ADDRESS(xEntryHandle, ppvAddress);
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceEntryGetSymbol(const TraceEntryHandle_t xEntryHandle, const char** pszSymbol)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* This should never fail */
TRC_ASSERT(pszSymbol != (void*)0);
/* Does not need to be locked. */
/* This should never fail */
TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
return TRC_ENTRY_GET_SYMBOL(xEntryHandle, pszSymbol);
}
traceResult xTraceEntryGetState(const TraceEntryHandle_t xEntryHandle, TraceUnsignedBaseType_t uxStateIndex, TraceUnsignedBaseType_t *puxState)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* This should never fail */
TRC_ASSERT(puxState != (void*)0);
/* This should never fail */
TRC_ASSERT(uxStateIndex < (TraceUnsignedBaseType_t)(TRC_ENTRY_TABLE_STATE_COUNT));
/* Does not need to be locked. */
/* This should never fail */
TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
return TRC_ENTRY_GET_STATE(xEntryHandle, uxStateIndex, puxState);
}
/*cstat !MISRAC2012-Rule-8.13 Suppress const check for xEntryHandle*/
TraceUnsignedBaseType_t xTraceEntryGetStateReturn(const TraceEntryHandle_t xEntryHandle, TraceUnsignedBaseType_t uxStateIndex)
{
return TRC_ENTRY_GET_STATE_RETURN(xEntryHandle, uxStateIndex);
}
traceResult xTraceEntryGetOptions(const TraceEntryHandle_t xEntryHandle, uint32_t *puiOptions)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* This should never fail */
TRC_ASSERT(puiOptions != (void*)0);
/* Does not need to be locked. */
/* This should never fail */
TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
return TRC_ENTRY_GET_OPTIONS(xEntryHandle, puiOptions);
}
#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
/* PRIVATE FUNCTIONS */
static traceResult prvEntryIndexInitialize(void)
{
uint32_t i;
for (i = 0u; i < (uint32_t)(TRC_ENTRY_TABLE_SLOTS); i++)
{
pxIndexTable->axFreeIndexes[i] = (TraceEntryIndex_t)i;
}
pxIndexTable->uiFreeIndexCount = TRC_ENTRY_TABLE_SLOTS;
return TRC_SUCCESS;
}
static traceResult prvEntryIndexTake(TraceEntryIndex_t *pxIndex)
{
/* Critical Section must be active! */
TraceEntryIndex_t xIndex;
if (pxIndexTable->uiFreeIndexCount == 0u)
{
return TRC_FAIL;
}
/* Always take the first item */
xIndex = pxIndexTable->axFreeIndexes[0];
pxIndexTable->uiFreeIndexCount--;
/* Move the last item to the first slot, to avoid holes */
pxIndexTable->axFreeIndexes[0] = pxIndexTable->axFreeIndexes[pxIndexTable->uiFreeIndexCount];
#if (TRC_ENTRY_TABLE_SLOTS > 256)
pxIndexTable->axFreeIndexes[pxIndexTable->uiFreeIndexCount] = UINT16_MAX;
#else
pxIndexTable->axFreeIndexes[pxIndexTable->uiFreeIndexCount] = UINT8_MAX;
#endif
*pxIndex = xIndex;
return TRC_SUCCESS;
}
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */

View File

@@ -0,0 +1,317 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation for errors.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
/* We skip the slot for TRC_ERROR_NONE so error code 1 is the first bit */
#define GET_ERROR_WARNING_FLAG(errorCode) (pxErrorInfo->uiErrorAndWarningFlags & (1UL << ((errorCode) - 1UL)))
#define SET_ERROR_WARNING_FLAG(errorCode) (pxErrorInfo->uiErrorAndWarningFlags |= (1UL << ((errorCode) - 1UL)))
static traceResult prvTraceErrorPrint(uint32_t uiErrorCode);
static traceResult prvTraceErrorGetDescription(uint32_t uiErrorCode, const char** pszDesc);
static TraceErrorData_t* pxErrorInfo TRC_CFG_RECORDER_DATA_ATTRIBUTE;
traceResult xTraceErrorInitialize(TraceErrorData_t* pxBuffer)
{
/* This should never fail */
TRC_ASSERT(pxBuffer != (void*)0);
pxErrorInfo = pxBuffer;
pxErrorInfo->uiErrorAndWarningFlags = 0u;
pxErrorInfo->uiErrorCode = 0u;
pxErrorInfo->xWarningChannel = 0;
xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_ERROR);
return TRC_SUCCESS;
}
traceResult xTraceWarning(uint32_t uiErrorCode)
{
/* Probably good to verify this */
if (xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ERROR) == 0U)
{
/* If not initialized */
return TRC_FAIL;
}
if (GET_ERROR_WARNING_FLAG(uiErrorCode) == 0u)
{
/* Will never reach this point more than once per warning type, since we verify if uiErrorAndWarningFlags[uiErrorCode] has already been set */
SET_ERROR_WARNING_FLAG(uiErrorCode);
(void)prvTraceErrorPrint(uiErrorCode);
}
return TRC_SUCCESS;
}
traceResult xTraceError(uint32_t uiErrorCode)
{
/* Probably good to verify this */
if (xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ERROR) == 0U)
{
return TRC_FAIL;
}
if (pxErrorInfo->uiErrorCode == TRC_ERROR_NONE)
{
/* Will never reach this point more than once, since we verify if uiErrorCode has already been set */
SET_ERROR_WARNING_FLAG(uiErrorCode);
pxErrorInfo->uiErrorCode = uiErrorCode;
if (prvTraceErrorPrint(uiErrorCode) == TRC_FAIL)
{
(void)xTraceDisable();
return TRC_FAIL;
}
(void)xTracePrint(pxErrorInfo->xWarningChannel, "Recorder stopped in xTraceError(...)!");
(void)xTraceDisable();
}
return TRC_SUCCESS;
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceErrorGetLast(const char **pszError)
{
/* Probably good to verify this */
if (xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ERROR) == 0U)
{
return TRC_FAIL;
}
/* This should never fail */
TRC_ASSERT(pszError != (void*)0);
return prvTraceErrorGetDescription(pxErrorInfo->uiErrorCode, pszError);
}
traceResult xTraceErrorClear(void)
{
/* Probably good to verify this */
if (xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ERROR) == 0U)
{
/* If not initialized */
return TRC_FAIL;
}
pxErrorInfo->uiErrorCode = TRC_ERROR_NONE;
return TRC_SUCCESS;
}
static traceResult prvTraceErrorPrint(uint32_t uiErrorCode)
{
const char* szDesc; /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
TraceUnsignedBaseType_t uxLineNumber;
TraceStringHandle_t xFileName;
/* Note: the error messages are short, in order to fit in a User Event.
Instead, the users can read more in the below comments.*/
if (pxErrorInfo->xWarningChannel == 0)
{
/* The #WFR channel means "Warnings from Recorder" and
* is used to store warnings and errors from the recorder.
* The abbreviation #WFR is used instead of the longer full name,
* to avoid truncation by small slots in the symbol table.
* This is translated in Tracealyzer and shown as the full name,
* "Warnings from Recorder".
*/
if (xTraceStringRegister("#WFR", &pxErrorInfo->xWarningChannel) == TRC_FAIL)
{
return TRC_FAIL;
}
}
(void)prvTraceErrorGetDescription(uiErrorCode, &szDesc);
switch (uiErrorCode)
{
case TRC_WARNING_ENTRY_TABLE_SLOTS:
case TRC_WARNING_ENTRY_SYMBOL_MAX_LENGTH:
case TRC_WARNING_EVENT_SIZE_TRUNCATED:
case TRC_WARNING_STREAM_PORT_READ:
case TRC_WARNING_STREAM_PORT_WRITE:
case TRC_WARNING_STREAM_PORT_INITIAL_BLOCKING:
case TRC_WARNING_STACKMON_NO_SLOTS:
case TRC_ERROR_STREAM_PORT_WRITE:
case TRC_ERROR_EVENT_CODE_TOO_LARGE:
case TRC_ERROR_ISR_NESTING_OVERFLOW:
case TRC_ERROR_DWT_NOT_SUPPORTED:
case TRC_ERROR_DWT_CYCCNT_NOT_SUPPORTED:
case TRC_ERROR_TZCTRLTASK_NOT_CREATED:
(void)xTracePrint(pxErrorInfo->xWarningChannel, szDesc);
break;
case TRC_ERROR_ASSERT:
/* A TRC_ASSERT has triggered */
if (xTraceAssertGet(&xFileName, &uxLineNumber) == TRC_FAIL)
{
return TRC_FAIL;
}
(void)xTracePrintF(pxErrorInfo->xWarningChannel, szDesc, xFileName, (uint32_t)uxLineNumber);
return TRC_SUCCESS;
break;
default:
/* No error, or an unknown error occurred */
(void)xTracePrintF(pxErrorInfo->xWarningChannel, "Unknown error code: 0x%08X", uiErrorCode);
return TRC_FAIL;
break;
}
return TRC_SUCCESS;
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
static traceResult prvTraceErrorGetDescription(uint32_t uiErrorCode, const char** pszDesc)
{
/* Note: the error messages are short, in order to fit in a User Event.
Instead, the users can read more in the below comments.*/
switch (uiErrorCode)
{
case TRC_ERROR_NONE:
return TRC_FAIL;
break;
case TRC_WARNING_ENTRY_TABLE_SLOTS:
/* There was not enough symbol table slots for storing symbol names.
The number of missing slots is counted by NoRoomForSymbol. Inspect this
variable and increase TRC_CFG_ENTRY_TABLE_SLOTS by at least that value. */
*pszDesc = "Exceeded TRC_CFG_ENTRY_TABLE_SLOTS";
break;
case TRC_WARNING_ENTRY_SYMBOL_MAX_LENGTH:
/* A symbol name exceeded TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH in length.
Make sure the symbol names are at most TRC_CFG_SYMBOL_MAX_LENGTH,
or inspect uiLongestSymbolName in trcEntryTable and increase
TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH to at least this value. */
*pszDesc = "Exceeded TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH";
break;
case TRC_WARNING_EVENT_SIZE_TRUNCATED:
/* Some arguments was longer than the maximum payload size
and has been truncated by "uiMaxBytesTruncated" bytes.
This usually happens for the following functions:
- xTracePrint
- xTracePrintF
- xTraceStringRegister
A trace event may store a maximum of 56 bytes payload, including
data arguments and string characters. */
*pszDesc = "Event size exceeded";
break;
case TRC_WARNING_STREAM_PORT_READ:
/* TRC_STREAM_PORT_READ_DATA is expected to return 0 when completed successfully.
This means there is an error in the communication with host/Tracealyzer. */
*pszDesc = "TRC_STREAM_PORT_READ_DATA returned error";
break;
case TRC_WARNING_STREAM_PORT_WRITE:
/* TRC_STREAM_PORT_WRITE_DATA is expected to return 0 when completed successfully.
This means there is an error in the communication with host/Tracealyzer. */
*pszDesc = "TRC_STREAM_PORT_WRITE_DATA returned error";
break;
case TRC_WARNING_STREAM_PORT_INITIAL_BLOCKING:
/* Blocking occurred during xTraceEnable. This happens if the trace buffer is
smaller than the initial transmission (trace header, object table, and symbol table). */
*pszDesc = "Blocking in xTraceEnable";
break;
case TRC_WARNING_STACKMON_NO_SLOTS:
/* Some tasks did not fit in the stack monitor. Increase the slot count. */
*pszDesc = "No slots left in Stack Monitor";
break;
case TRC_ERROR_STREAM_PORT_WRITE:
/* TRC_STREAM_PORT_WRITE_DATA is expected to return 0 when completed successfully.
This means there is an error in the communication with host/Tracealyzer. */
*pszDesc = "TRC_STREAM_PORT_WRITE_DATA returned error";
break;
case TRC_ERROR_EVENT_CODE_TOO_LARGE:
/* The highest allowed event code is 4095, anything higher is an unexpected error.
Please contact support@percepio.com for assistance.*/
*pszDesc = "Invalid event code";
break;
case TRC_ERROR_ISR_NESTING_OVERFLOW:
/* Nesting of ISR trace calls exceeded the limit (TRC_CFG_MAX_ISR_NESTING).
If this is unlikely, make sure that you call vTraceStoreISRExit in the end
of all ISR handlers. Or increase TRC_CFG_MAX_ISR_NESTING. */
*pszDesc = "Exceeded ISR nesting";
break;
case TRC_ERROR_DWT_NOT_SUPPORTED:
/* On ARM Cortex-M only - failed to initialize DWT Cycle Counter since not supported by this chip.
DWT timestamping is selected automatically for ART Cortex-M3, M4 and higher, based on the __CORTEX_M
macro normally set by ARM's CMSIS library, since typically available. You can however select
SysTick timestamping instead by defining adding "#define TRC_CFG_ARM_CM_USE_SYSTICK".*/
*pszDesc = "DWT not supported";
break;
case TRC_ERROR_DWT_CYCCNT_NOT_SUPPORTED:
/* On ARM Cortex-M only - failed to initialize DWT Cycle Counter since not supported by this chip.
DWT timestamping is selected automatically for ART Cortex-M3, M4 and higher, based on the __CORTEX_M
macro normally set by ARM's CMSIS library, since typically available. You can however select
SysTick timestamping instead by defining adding "#define TRC_CFG_ARM_CM_USE_SYSTICK".*/
*pszDesc = "DWT_CYCCNT not supported";
break;
case TRC_ERROR_TZCTRLTASK_NOT_CREATED:
/* xTraceEnable failed creating the trace control task (TzCtrl) - incorrect parameters (priority?)
or insufficient heap size? */
*pszDesc = "Could not create TzCtrl";
break;
case TRC_ERROR_ASSERT:
/* A TRC_ASSERT has triggered */
*pszDesc = "ASSERT: %s (%d)";
break;
default:
/* An unknown error occurred */
*pszDesc = "Unknown error code: 0x%08X";
break;
}
return TRC_SUCCESS;
}
#endif
#endif

View File

@@ -0,0 +1,727 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation for events.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <string.h>
/*cstat !MISRAC2004-19.4 Suppress macro check*/
#define VERIFY_EVENT_SIZE(i) \
if ((TraceUnsignedBaseType_t)(i) > (TraceUnsignedBaseType_t)(TRC_MAX_BLOB_SIZE)) \
{ \
(void)xTraceDiagnosticsSetIfHigher(TRC_DIAGNOSTICS_BLOB_MAX_BYTES_TRUNCATED, (TraceBaseType_t)(i) - (TraceBaseType_t)(TRC_MAX_BLOB_SIZE)); \
(i) = (uint32_t)(TRC_MAX_BLOB_SIZE); \
}
TraceEventDataTable_t *pxTraceEventDataTable TRC_CFG_RECORDER_DATA_ATTRIBUTE;
traceResult xTraceEventInitialize(TraceEventDataTable_t* pxBuffer)
{
TraceCoreEventData_t* pxCoreEventData;
uint32_t i, j;
/* This should never fail */
TRC_ASSERT(pxBuffer != (void*)0);
pxTraceEventDataTable = pxBuffer;
for (i = 0u; i < (uint32_t)(TRC_CFG_CORE_COUNT); i++)
{
pxCoreEventData = &pxTraceEventDataTable->coreEventData[i];
pxCoreEventData->eventCounter = 0u;
for (j = 0u; j < ((uint32_t)(TRC_CFG_MAX_ISR_NESTING) + 1u); j++)
{
RESET_EVENT_DATA(&pxCoreEventData->eventData[j]);
}
}
xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_EVENT);
return TRC_SUCCESS;
}
traceResult xTraceEventCreate0(uint32_t uiEventCode)
{
TraceEvent0_t* pxEventData = (void*)0;
int32_t iBytesCommitted = 0;
TRACE_ALLOC_CRITICAL_SECTION();
/* We need to check this */
if (!xTraceIsRecorderEnabled())
{
return TRC_FAIL;
}
TRACE_ENTER_CRITICAL_SECTION();
pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventCounter++;
if (xTraceStreamPortAllocate(sizeof(TraceEvent0_t), (void**)&pxEventData) == TRC_FAIL) /*cstat !MISRAC2004-11.4 !MISRAC2012-Rule-11.3 Suppress pointer checks*/
{
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
SET_BASE_EVENT_DATA(pxEventData, uiEventCode, 0, pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventCounter); /*cstat !MISRAC2012-Rule-11.5 Suppress pointer checks*/
(void)xTraceStreamPortCommit(pxEventData, sizeof(TraceEvent0_t), &iBytesCommitted);
TRACE_EXIT_CRITICAL_SECTION();
/* We need to use iBytesCommitted for the above call but do not use the value,
* remove potential warnings */
(void)iBytesCommitted;
return TRC_SUCCESS;
}
traceResult xTraceEventCreate1(uint32_t uiEventCode, TraceUnsignedBaseType_t uxParam1)
{
TraceEvent1_t* pxEventData = (void*)0;
int32_t iBytesCommitted = 0;
TRACE_ALLOC_CRITICAL_SECTION();
/* We need to check this */
if (!xTraceIsRecorderEnabled())
{
return TRC_FAIL;
}
TRACE_ENTER_CRITICAL_SECTION();
pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventCounter++;
if (xTraceStreamPortAllocate(sizeof(TraceEvent1_t), (void**)&pxEventData) == TRC_FAIL) /*cstat !MISRAC2004-11.4 !MISRAC2012-Rule-11.3 Suppress pointer checks*/
{
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
SET_BASE_EVENT_DATA(pxEventData, uiEventCode, 1, pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventCounter); /*cstat !MISRAC2012-Rule-11.5 Suppress pointer checks*/
pxEventData->uxParams[0] = uxParam1;
(void)xTraceStreamPortCommit(pxEventData, sizeof(TraceEvent1_t), &iBytesCommitted);
TRACE_EXIT_CRITICAL_SECTION();
/* We need to use iBytesCommitted for the above call but do not use the value,
* remove potential warnings */
(void)iBytesCommitted;
return TRC_SUCCESS;
}
traceResult xTraceEventCreate2(uint32_t uiEventCode, TraceUnsignedBaseType_t uxParam1, TraceUnsignedBaseType_t uxParam2)
{
TraceEvent2_t* pxEventData = (void*)0;
int32_t iBytesCommitted = 0;
TRACE_ALLOC_CRITICAL_SECTION();
/* We need to check this */
if (!xTraceIsRecorderEnabled())
{
return TRC_FAIL;
}
TRACE_ENTER_CRITICAL_SECTION();
pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventCounter++;
if (xTraceStreamPortAllocate(sizeof(TraceEvent2_t), (void**)&pxEventData) == TRC_FAIL) /*cstat !MISRAC2004-11.4 !MISRAC2012-Rule-11.3 Suppress pointer checks*/
{
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
SET_BASE_EVENT_DATA(pxEventData, uiEventCode, 2, pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventCounter); /*cstat !MISRAC2012-Rule-11.5 Suppress pointer checks*/
pxEventData->uxParams[0] = uxParam1;
pxEventData->uxParams[1] = uxParam2;
(void)xTraceStreamPortCommit(pxEventData, sizeof(TraceEvent2_t), &iBytesCommitted);
TRACE_EXIT_CRITICAL_SECTION();
/* We need to use iBytesCommitted for the above call but do not use the value,
* remove potential warnings */
(void)iBytesCommitted;
return TRC_SUCCESS;
}
traceResult xTraceEventCreate3(uint32_t uiEventCode, TraceUnsignedBaseType_t uxParam1, TraceUnsignedBaseType_t uxParam2, TraceUnsignedBaseType_t uxParam3)
{
TraceEvent3_t* pxEventData = (void*)0;
int32_t iBytesCommitted = 0;
TRACE_ALLOC_CRITICAL_SECTION();
/* We need to check this */
if (!xTraceIsRecorderEnabled())
{
return TRC_FAIL;
}
TRACE_ENTER_CRITICAL_SECTION();
pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventCounter++;
if (xTraceStreamPortAllocate(sizeof(TraceEvent3_t), (void**)&pxEventData) == TRC_FAIL) /*cstat !MISRAC2004-11.4 !MISRAC2012-Rule-11.3 Suppress pointer checks*/
{
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
SET_BASE_EVENT_DATA(pxEventData, uiEventCode, 3, pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventCounter); /*cstat !MISRAC2012-Rule-11.5 Suppress pointer checks*/
pxEventData->uxParams[0] = uxParam1;
pxEventData->uxParams[1] = uxParam2;
pxEventData->uxParams[2] = uxParam3;
(void)xTraceStreamPortCommit(pxEventData, sizeof(TraceEvent3_t), &iBytesCommitted);
TRACE_EXIT_CRITICAL_SECTION();
/* We need to use iBytesCommitted for the above call but do not use the value,
* remove potential warnings */
(void)iBytesCommitted;
return TRC_SUCCESS;
}
traceResult xTraceEventCreate4(uint32_t uiEventCode, TraceUnsignedBaseType_t uxParam1, TraceUnsignedBaseType_t uxParam2, TraceUnsignedBaseType_t uxParam3, TraceUnsignedBaseType_t uxParam4)
{
TraceEvent4_t* pxEventData = (void*)0;
int32_t iBytesCommitted = 0;
TRACE_ALLOC_CRITICAL_SECTION();
/* We need to check this */
if (!xTraceIsRecorderEnabled())
{
return TRC_FAIL;
}
TRACE_ENTER_CRITICAL_SECTION();
pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventCounter++;
if (xTraceStreamPortAllocate(sizeof(TraceEvent4_t), (void**)&pxEventData) == TRC_FAIL) /*cstat !MISRAC2004-11.4 !MISRAC2012-Rule-11.3 Suppress pointer checks*/
{
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
SET_BASE_EVENT_DATA(pxEventData, uiEventCode, 4, pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventCounter); /*cstat !MISRAC2012-Rule-11.5 Suppress pointer checks*/
pxEventData->uxParams[0] = uxParam1;
pxEventData->uxParams[1] = uxParam2;
pxEventData->uxParams[2] = uxParam3;
pxEventData->uxParams[3] = uxParam4;
(void)xTraceStreamPortCommit(pxEventData, sizeof(TraceEvent4_t), &iBytesCommitted);
TRACE_EXIT_CRITICAL_SECTION();
/* We need to use iBytesCommitted for the above call but do not use the value,
* remove potential warnings */
(void)iBytesCommitted;
return TRC_SUCCESS;
}
traceResult xTraceEventCreate5(uint32_t uiEventCode, TraceUnsignedBaseType_t uxParam1, TraceUnsignedBaseType_t uxParam2, TraceUnsignedBaseType_t uxParam3, TraceUnsignedBaseType_t uxParam4, TraceUnsignedBaseType_t uxParam5)
{
TraceEvent5_t* pxEventData = (void*)0;
int32_t iBytesCommitted = 0;
TRACE_ALLOC_CRITICAL_SECTION();
/* We need to check this */
if (!xTraceIsRecorderEnabled())
{
return TRC_FAIL;
}
TRACE_ENTER_CRITICAL_SECTION();
pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventCounter++;
if (xTraceStreamPortAllocate(sizeof(TraceEvent5_t), (void**)&pxEventData) == TRC_FAIL) /*cstat !MISRAC2004-11.4 !MISRAC2012-Rule-11.3 Suppress pointer checks*/
{
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
SET_BASE_EVENT_DATA(pxEventData, uiEventCode, 5, pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventCounter); /*cstat !MISRAC2012-Rule-11.5 Suppress pointer checks*/
pxEventData->uxParams[0] = uxParam1;
pxEventData->uxParams[1] = uxParam2;
pxEventData->uxParams[2] = uxParam3;
pxEventData->uxParams[3] = uxParam4;
pxEventData->uxParams[4] = uxParam5;
(void)xTraceStreamPortCommit(pxEventData, sizeof(TraceEvent5_t), &iBytesCommitted);
TRACE_EXIT_CRITICAL_SECTION();
/* We need to use iBytesCommitted for the above call but do not use the value,
* remove potential warnings */
(void)iBytesCommitted;
return TRC_SUCCESS;
}
traceResult xTraceEventCreate6(uint32_t uiEventCode, TraceUnsignedBaseType_t uxParam1, TraceUnsignedBaseType_t uxParam2, TraceUnsignedBaseType_t uxParam3, TraceUnsignedBaseType_t uxParam4, TraceUnsignedBaseType_t uxParam5, TraceUnsignedBaseType_t uxParam6)
{
TraceEvent6_t* pxEventData = (void*)0;
int32_t iBytesCommitted = 0;
TRACE_ALLOC_CRITICAL_SECTION();
/* We need to check this */
if (!xTraceIsRecorderEnabled())
{
return TRC_FAIL;
}
TRACE_ENTER_CRITICAL_SECTION();
pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventCounter++;
if (xTraceStreamPortAllocate(sizeof(TraceEvent6_t), (void**)&pxEventData) == TRC_FAIL) /*cstat !MISRAC2004-11.4 !MISRAC2012-Rule-11.3 Suppress pointer checks*/
{
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
SET_BASE_EVENT_DATA(pxEventData, uiEventCode, 6, pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventCounter); /*cstat !MISRAC2012-Rule-11.5 Suppress pointer checks*/
pxEventData->uxParams[0] = uxParam1;
pxEventData->uxParams[1] = uxParam2;
pxEventData->uxParams[2] = uxParam3;
pxEventData->uxParams[3] = uxParam4;
pxEventData->uxParams[4] = uxParam5;
pxEventData->uxParams[5] = uxParam6;
(void)xTraceStreamPortCommit(pxEventData, sizeof(TraceEvent6_t), &iBytesCommitted);
TRACE_EXIT_CRITICAL_SECTION();
/* We need to use iBytesCommitted for the above call but do not use the value,
* remove potential warnings */
(void)iBytesCommitted;
return TRC_SUCCESS;
}
traceResult xTraceEventBeginRawOffline(uint32_t uiSize, TraceEventHandle_t* pxEventHandle)
{
int32_t ISR_nesting = 0;
TraceEventData_t* pxEventData;
TraceCoreEventData_t* pxCoreEventData;
TRACE_ALLOC_CRITICAL_SECTION();
/* We need to check this */
if (xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT) == 0U)
{
return TRC_FAIL;
}
/* This should never fail */
TRC_ASSERT(pxEventHandle != (void*)0);
TRACE_ENTER_CRITICAL_SECTION();
pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventCounter++;
pxCoreEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()];
/* We backup the local variable to the CORE specific variable */
pxCoreEventData->TRACE_ALLOC_CRITICAL_SECTION_NAME = TRACE_ALLOC_CRITICAL_SECTION_NAME;
(void)xTraceISRGetCurrentNesting(&ISR_nesting);
/* We add 1 since xTraceISRGetCurrentNesting(...) returns -1 if no ISR is active */
pxEventData = &pxCoreEventData->eventData[ISR_nesting + 1];
/* This should never fail */
TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData->pvBlob == 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
VERIFY_EVENT_SIZE(uiSize); /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
pxEventData->size = ((uiSize + (sizeof(TraceUnsignedBaseType_t) - 1u)) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t); /* BaseType align */
pxEventData->offset = 0u;
/* This can fail and we should handle it */
if (xTraceStreamPortAllocate(pxEventData->size, &pxEventData->pvBlob) == TRC_FAIL)
{
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
*pxEventHandle = (TraceEventHandle_t)pxEventData;
return TRC_SUCCESS;
}
traceResult xTraceEventBeginRawOfflineBlocking(uint32_t uiSize, TraceEventHandle_t* pxEventHandle)
{
TraceEventData_t* pxEventData;
TraceCoreEventData_t* pxCoreEventData;
int32_t ISR_nesting = 0;
uint32_t uiAttempts = 0u;
TRACE_ALLOC_CRITICAL_SECTION();
/* We need to check this */
if (xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT) == 0U)
{
return TRC_FAIL;
}
/* This should never fail */
TRC_ASSERT(pxEventHandle != (void*)0);
TRACE_ENTER_CRITICAL_SECTION();
pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventCounter++;
pxCoreEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()];
/* We backup the local variable to the CORE specific variable */
pxCoreEventData->TRACE_ALLOC_CRITICAL_SECTION_NAME = TRACE_ALLOC_CRITICAL_SECTION_NAME;
(void)xTraceGetCurrentISRNesting(&ISR_nesting);
/* We add 1 since xTraceISRGetCurrentNesting(...) returns -1 if no ISR is active */
pxEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventData[ISR_nesting + 1];
/* This should never fail */
TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData->pvBlob == 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
VERIFY_EVENT_SIZE(uiSize); /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
pxEventData->size = ((uiSize + (sizeof(TraceUnsignedBaseType_t) - 1u)) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t); /* BaseType align */
pxEventData->offset = 0u;
/* This can fail and we should handle it */
while (xTraceStreamPortAllocate(pxEventData->size, &pxEventData->pvBlob) != TRC_SUCCESS)
{
uiAttempts++;
}
*pxEventHandle = (TraceEventHandle_t)pxEventData;
return TRC_SUCCESS;
}
traceResult xTraceEventEndOffline(TraceEventHandle_t xEventHandle)
{
TraceEventData_t* pxEventData = (TraceEventData_t*)xEventHandle;
const TraceCoreEventData_t* pxCoreEventData;
int32_t iBytesCommitted = 0;
TRACE_ALLOC_CRITICAL_SECTION()
pxCoreEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()];
/* We restore the CORE specific variable to the local variable before any EXIT */
TRACE_ALLOC_CRITICAL_SECTION_NAME = pxCoreEventData->TRACE_ALLOC_CRITICAL_SECTION_NAME;
/* This should never fail */
TRC_ASSERT_CUSTOM_ON_FAIL(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT), TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
/* This should never fail */
TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData != (void*)0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
/* This should never fail */
TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData->pvBlob != (void*)0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
(void)xTraceStreamPortCommit(pxEventData->pvBlob, pxEventData->size, &iBytesCommitted);
/* We need to use iBytesCommitted for the above call but do not use the value,
* remove potential warnings */
(void)iBytesCommitted;
RESET_EVENT_DATA(pxEventData);
TRACE_EXIT_CRITICAL_SECTION();
return TRC_SUCCESS;
}
traceResult xTraceEventEndOfflineBlocking(TraceEventHandle_t xEventHandle)
{
TraceEventData_t* pxEventData = (TraceEventData_t*)xEventHandle;
const TraceCoreEventData_t* pxCoreEventData;
int32_t iBytesCommitted;
uint32_t uiByteOffset = 0u;
uint8_t *pubBlob;
TRACE_ALLOC_CRITICAL_SECTION()
pxCoreEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()];
/* We restore the CORE specific variable to the local variable before any EXIT */
TRACE_ALLOC_CRITICAL_SECTION_NAME = pxCoreEventData->TRACE_ALLOC_CRITICAL_SECTION_NAME;
/* This should never fail */
TRC_ASSERT_CUSTOM_ON_FAIL(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT), TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
/* This should never fail */
TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData != (void*)0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
/* This should never fail */
TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData->pvBlob != (void*)0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
pubBlob = (uint8_t*)pxEventData->pvBlob; /*cstat !MISRAC2012-Rule-11.5 Suppress pointer checks*/
while (pxEventData->size > uiByteOffset)
{
iBytesCommitted = 0;
(void)xTraceStreamPortCommit((void*)&pubBlob[uiByteOffset], pxEventData->size - uiByteOffset, &iBytesCommitted); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
uiByteOffset += (uint32_t)iBytesCommitted;
}
RESET_EVENT_DATA(pxEventData);
TRACE_EXIT_CRITICAL_SECTION();
return TRC_SUCCESS;
}
traceResult xTraceEventAddData(TraceEventHandle_t xEventHandle, const TraceUnsignedBaseType_t* const puxData, TraceUnsignedBaseType_t uxSize)
{
TraceEventData_t* pxEventData = (TraceEventData_t*)xEventHandle;
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
/* This should never fail */
TRC_ASSERT(xEventHandle != 0);
/* This should never fail */
TRC_ASSERT(puxData != (void*)0);
/* This should never fail */
TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset + (uint32_t)(uxSize * sizeof(TraceUnsignedBaseType_t))) <= ((TraceEventData_t*)xEventHandle)->size);
memcpy(&((uint8_t*)pxEventData->pvBlob)[pxEventData->offset], puxData, uxSize * sizeof(TraceUnsignedBaseType_t));
pxEventData->offset += uxSize * sizeof(TraceUnsignedBaseType_t);
return TRC_SUCCESS;
}
#if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
traceResult xTraceEventGetSize(const void* const pvAddress, uint32_t* puiSize)
{
/* This should never fail */
TRC_ASSERT(pvAddress != (void*)0);
/* This should never fail */
TRC_ASSERT(puiSize != (void*)0);
/* This should never fail */
TRC_ASSERT((sizeof(TraceEvent0_t) + ((uint32_t)(uint16_t)(TRC_EVENT_GET_PARAM_COUNT(((const TraceEvent0_t*)pvAddress)->EventID)) * sizeof(uint32_t))) <= (uint32_t)(TRC_MAX_BLOB_SIZE)); /*cstat !MISRAC2012-Rule-11.5 Suppress pointer checks*/
return TRC_EVENT_GET_SIZE(pvAddress, puiSize);
}
traceResult xTraceEventGetRawData(TraceEventHandle_t xEventHandle, uint32_t uiOffset, uint32_t uiSize, void** ppvData)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
/* This should never fail */
TRC_ASSERT(xEventHandle != 0);
/* This should never fail */
TRC_ASSERT(ppvData != (void*)0);
/* This should never fail */
TRC_ASSERT((uiOffset + uiSize) <= ((TraceEventData_t*)xEventHandle)->size);
return TRC_EVENT_GET_RAW_DATA(xEventHandle, uiOffset, uiSize, ppvData);
}
traceResult xTraceEventGetPayload(const TraceEventHandle_t xEventHandle, uint32_t uiOffset, uint32_t uiSize, void** ppvData)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
/* This should never fail */
TRC_ASSERT(xEventHandle != 0);
/* This should never fail */
TRC_ASSERT(ppvData != (void*)0);
/* This should never fail */
TRC_ASSERT((uiOffset + uiSize) <= ((const TraceEventData_t*)xEventHandle)->size);
return TRC_EVENT_GET_PAYLOAD(xEventHandle, uiOffset, uiSize, ppvData);
}
traceResult xTraceEventPayloadRemaining(const TraceEventHandle_t xEventHandle, uint32_t* puiValue)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
/* This should never fail */
TRC_ASSERT(xEventHandle != 0);
/* This should never fail */
TRC_ASSERT(puiValue != (void*)0);
/* This should never fail */
TRC_ASSERT(((const TraceEventData_t*)xEventHandle)->pvBlob != (void*)0);
return TRC_EVENT_PAYLOAD_REMAINING(xEventHandle, puiValue);
}
traceResult xTraceEventPayloadUsed(const TraceEventHandle_t xEventHandle, uint32_t* puiValue)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
/* This should never fail */
TRC_ASSERT(xEventHandle != 0);
/* This should never fail */
TRC_ASSERT(puiValue != (void*)0);
/* This should never fail */
TRC_ASSERT(((const TraceEventData_t*)xEventHandle)->pvBlob != (void*)0);
return TRC_EVENT_PAYLOAD_USED(xEventHandle, puiValue);
}
traceResult xTraceEventPayloadSize(const TraceEventHandle_t xEventHandle, uint32_t* puiValue)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
/* This should never fail */
TRC_ASSERT(xEventHandle != 0);
/* This should never fail */
TRC_ASSERT(puiValue != (void*)0);
/* This should never fail */
TRC_ASSERT(((const TraceEventData_t*)xEventHandle)->pvBlob != (void*)0);
return TRC_EVENT_PAYLOAD_SIZE(xEventHandle, puiValue);
}
traceResult xTraceEventAddPointer(TraceEventHandle_t xEventHandle, void* pvAddress)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
/* This should never fail */
TRC_ASSERT(xEventHandle != 0);
/* This should never fail */
TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset + sizeof(void*)) <= ((TraceEventData_t*)xEventHandle)->size);
/* Make sure we are writing at void* aligned offset */
/* This should never fail */
TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & (sizeof(void*) - 1u)) == 0u);
return TRC_EVENT_ADD_POINTER(xEventHandle, pvAddress);
}
traceResult xTraceEventAddUnsignedBaseType(TraceEventHandle_t xEventHandle, TraceUnsignedBaseType_t uxValue)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
/* This should never fail */
TRC_ASSERT(xEventHandle != 0);
/* This should never fail */
TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset + sizeof(TraceUnsignedBaseType_t)) <= ((TraceEventData_t*)xEventHandle)->size);
/* Make sure we are writing at TraceUnsignedBaseType_t aligned offset */
/* This should never fail */
TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & (sizeof(TraceUnsignedBaseType_t) - 1u)) == 0u);
return TRC_EVENT_ADD_UNSIGNED_BASE_TYPE(xEventHandle, uxValue);
}
traceResult xTraceEventAdd32(TraceEventHandle_t xEventHandle, uint32_t value)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
/* This should never fail */
TRC_ASSERT(xEventHandle != 0);
/* This should never fail */
TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset + sizeof(uint32_t)) <= ((TraceEventData_t*)xEventHandle)->size);
/* Make sure we are writing at 32-bit aligned offset */
/* This should never fail */
TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & 3u) == 0u);
return TRC_EVENT_ADD_32(xEventHandle, value);
}
traceResult xTraceEventAdd16(TraceEventHandle_t xEventHandle, uint16_t value)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
/* This should never fail */
TRC_ASSERT(xEventHandle != 0);
/* This should never fail */
TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset + sizeof(uint16_t)) <= ((TraceEventData_t*)xEventHandle)->size);
/* Make sure we are writing at 16-bit aligned offset */
/* This should never fail */
TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & 1u) == 0u);
return TRC_EVENT_ADD_16(xEventHandle, value);
}
traceResult xTraceEventAdd8(TraceEventHandle_t xEventHandle, uint8_t value)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
/* This should never fail */
TRC_ASSERT(xEventHandle != 0);
/* This should never fail */
TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset + sizeof(uint8_t)) <= ((TraceEventData_t*)xEventHandle)->size);
return TRC_EVENT_ADD_8(xEventHandle, value);
}
#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */

View File

@@ -0,0 +1,550 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation for the event buffer.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
traceResult xTraceEventBufferInitialize(TraceEventBuffer_t* pxTraceEventBuffer, uint32_t uiOptions,
uint8_t* puiBuffer, uint32_t uiSize)
{
/* This should never fail */
TRC_ASSERT(pxTraceEventBuffer != (void*)0);
/* This should never fail */
TRC_ASSERT(puiBuffer != (void*)0);
/* This should never fail */
TRC_ASSERT(uiSize != 0u);
pxTraceEventBuffer->uiOptions = uiOptions;
pxTraceEventBuffer->uiHead = 0u;
pxTraceEventBuffer->uiTail = 0u;
pxTraceEventBuffer->uiSize = uiSize;
pxTraceEventBuffer->uiFree = uiSize;
pxTraceEventBuffer->puiBuffer = puiBuffer;
pxTraceEventBuffer->uiSlack = 0u;
pxTraceEventBuffer->uiNextHead = 0u;
pxTraceEventBuffer->uiTimerWraparounds = 0u;
(void)xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_EVENT_BUFFER);
return TRC_SUCCESS;
}
/**
* @brief Pops the oldest event from the Event Buffer.
*
* @param[in] pxTraceEventBuffer Pointer to initialized trace event buffer.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
static traceResult prvTraceEventBufferPop(TraceEventBuffer_t *pxTraceEventBuffer)
{
uint32_t uiFreeSize = 0u;
/* Get size of event we are freeing */
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEventGetSize(((void*)&(pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiTail])), &uiFreeSize) == TRC_SUCCESS); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
pxTraceEventBuffer->uiFree += uiFreeSize;
/* Update tail to point to the new last event */
pxTraceEventBuffer->uiTail = (pxTraceEventBuffer->uiTail + uiFreeSize) % pxTraceEventBuffer->uiSize;
return TRC_SUCCESS;
}
static traceResult prvTraceEventBufferAllocPop(TraceEventBuffer_t *pxTraceEventBuffer)
{
uint32_t uiFreeSize = 0u;
/* Check if tail is in, or at the start of the slack area. We do not want to call
* a free when in the slack area since it would read garbage data and free would
* become undefined.
*/
if (pxTraceEventBuffer->uiTail >= (pxTraceEventBuffer->uiSize - pxTraceEventBuffer->uiSlack))
{
/* Tail was in the slack area, wrap back to the start of the buffer. */
pxTraceEventBuffer->uiTail = 0u;
}
else
{
/* Get size of event we are freeing (this should never fail) */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEventGetSize(((void*)&(pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiTail])), &uiFreeSize) == TRC_SUCCESS); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
/* Update tail to point to the new last event */
pxTraceEventBuffer->uiTail = (pxTraceEventBuffer->uiTail + uiFreeSize) % pxTraceEventBuffer->uiSize;
}
return TRC_SUCCESS;
}
traceResult xTraceEventBufferAlloc(TraceEventBuffer_t *pxTraceEventBuffer, uint32_t uiSize, void **ppvData)
{
uint32_t uiFreeSpace;
uint32_t uiHead;
uint32_t uiTail;
uint32_t uiBufferSize;
/* This should never fail */
TRC_ASSERT(pxTraceEventBuffer != (void*)0);
/* This should never fail */
TRC_ASSERT(ppvData != (void*)0);
uiBufferSize = pxTraceEventBuffer->uiSize;
TRC_ASSERT(uiBufferSize != 0u);
/* Check if the data size is larger than the buffer */
/* This should never fail */
TRC_ASSERT(uiSize <= uiBufferSize);
/* Handle overwrite buffer allocation, since this kind of allocation modifies
* both head and tail it should only be used for internal buffers without any
* flushing calls (Streaming Ringbuffer)
*/
if (pxTraceEventBuffer->uiOptions == TRC_EVENT_BUFFER_OPTION_OVERWRITE)
{
if (pxTraceEventBuffer->uiHead >= pxTraceEventBuffer->uiTail)
{
/* Do we have enough space to directly allocate from the buffer? */
if ((uiBufferSize - pxTraceEventBuffer->uiHead) > uiSize)
{
*ppvData = &pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead]; /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
pxTraceEventBuffer->uiNextHead = (pxTraceEventBuffer->uiHead + uiSize) % uiBufferSize;
}
/* There wasn't enough space for a direct alloc, handle freeing up
* space and wrapping. */
else
{
/* Free space until there is enough space for a contiguous
* allocation */
do
{
(void)prvTraceEventBufferAllocPop(pxTraceEventBuffer);
uiFreeSpace = pxTraceEventBuffer->uiTail - sizeof(uint32_t);
} while (uiFreeSpace < uiSize);
/* Calculate slack from the wrapping */
pxTraceEventBuffer->uiSlack = uiBufferSize - pxTraceEventBuffer->uiHead;
/* Wrap head */
pxTraceEventBuffer->uiHead = 0u;
/* Allocate data */
*ppvData = pxTraceEventBuffer->puiBuffer;
pxTraceEventBuffer->uiNextHead = (pxTraceEventBuffer->uiHead + uiSize) % uiBufferSize;
}
}
else
{
uiFreeSpace = pxTraceEventBuffer->uiTail - pxTraceEventBuffer->uiHead - sizeof(uint32_t);
/* Check if we have to free space */
if (uiFreeSpace < uiSize)
{
/* Check if this is a wrapping alloc */
if ((pxTraceEventBuffer->uiSize - pxTraceEventBuffer->uiHead) < uiSize)
{
/* To avoid uiHead and uiTail from becoming the same we want to
* pop any events that would make uiTail equal uiHead before
* wrapping the head. */
do
{
(void)prvTraceEventBufferAllocPop(pxTraceEventBuffer);
} while (pxTraceEventBuffer->uiTail == 0u);
pxTraceEventBuffer->uiSlack = pxTraceEventBuffer->uiSize - pxTraceEventBuffer->uiHead;
pxTraceEventBuffer->uiHead = 0u;
}
do
{
(void)prvTraceEventBufferAllocPop(pxTraceEventBuffer);
uiFreeSpace = pxTraceEventBuffer->uiTail - pxTraceEventBuffer->uiHead - sizeof(uint32_t);
} while (uiFreeSpace < uiSize);
if (pxTraceEventBuffer->uiTail == 0u)
{
*ppvData = &pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead]; /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
}
}
/* Alloc data */
*ppvData = &pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead]; /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
pxTraceEventBuffer->uiNextHead = (pxTraceEventBuffer->uiHead + uiSize);
}
}
else
{
/* Since a consumer could potentially update tail (free) during the procedure
* we have to save it here to avoid problems with it changing during this call.
*/
uiHead = pxTraceEventBuffer->uiHead;
uiTail = pxTraceEventBuffer->uiTail;
if (uiHead >= uiTail)
{
uiFreeSpace = (uiBufferSize - uiHead - sizeof(uint32_t)) + uiTail;
if (uiFreeSpace < uiSize)
{
*ppvData = 0;
return TRC_FAIL;
}
/* Copy data */
if ((uiBufferSize - uiHead) > uiSize)
{
*ppvData = &pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead]; /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
pxTraceEventBuffer->uiNextHead = (uiHead + uiSize) % uiBufferSize;
}
else
{
uiFreeSpace = uiTail;
if (uiFreeSpace < uiSize)
{
*ppvData = 0;
return TRC_FAIL;
}
/* Calculate slack */
pxTraceEventBuffer->uiSlack = uiBufferSize - uiHead;
*ppvData = pxTraceEventBuffer->puiBuffer;
pxTraceEventBuffer->uiNextHead = (uiHead + pxTraceEventBuffer->uiSlack + uiSize) % uiBufferSize;
}
}
else
{
uiFreeSpace = uiTail - uiHead - sizeof(uint32_t);
if (uiFreeSpace < uiSize)
{
*ppvData = 0;
return TRC_FAIL;
}
/* Alloc data */
*ppvData = &pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead]; /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
pxTraceEventBuffer->uiNextHead = (uiHead + uiSize);
}
}
return TRC_SUCCESS;
}
traceResult xTraceEventBufferAllocCommit(TraceEventBuffer_t *pxTraceEventBuffer, const void *pvData, uint32_t uiSize, int32_t *piBytesWritten)
{
(void)pvData;
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceTimestampGetWraparounds(&pxTraceEventBuffer->uiTimerWraparounds) == TRC_SUCCESS);
/* Advance head location */
pxTraceEventBuffer->uiHead = pxTraceEventBuffer->uiNextHead;
/* Update bytes written */
*piBytesWritten = (int32_t)uiSize;
return TRC_SUCCESS;
}
traceResult xTraceEventBufferPush(TraceEventBuffer_t *pxTraceEventBuffer, void *pvData, uint32_t uiSize, int32_t *piBytesWritten)
{
uint32_t uiBufferSize;
uint32_t uiHead;
uint32_t uiTail;
uint32_t uiFreeSpace;
/* This should never fail */
TRC_ASSERT(pxTraceEventBuffer != (void*)0);
/* This should never fail */
TRC_ASSERT(pvData != (void*)0);
uiBufferSize = pxTraceEventBuffer->uiSize;
TRC_ASSERT(uiBufferSize != 0u);
/* Check if the data size is larger than the buffer */
/* This should never fail */
TRC_ASSERT(uiSize <= uiBufferSize);
/* Check byte alignment */
/* This should never fail */
TRC_ASSERT((uiSize % 4u) == 0u);
/* Ensure bytes written start at 0 */
/* This should never fail */
TRC_ASSERT(piBytesWritten != (void*)0);
*piBytesWritten = 0;
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceTimestampGetWraparounds(&pxTraceEventBuffer->uiTimerWraparounds) == TRC_SUCCESS);
/* In ring buffer mode we cannot provide lock free access since the producer modified
* the head and tail variables in the same call. This option is only safe when used
* with an internal buffer (streaming snapshot) which no consumer accesses.
*/
switch (pxTraceEventBuffer->uiOptions)
{
case TRC_EVENT_BUFFER_OPTION_OVERWRITE:
uiHead = pxTraceEventBuffer->uiHead;
/* If there isn't enough space in the buffer pop events until there is */
while (pxTraceEventBuffer->uiFree < uiSize)
{
(void)prvTraceEventBufferPop(pxTraceEventBuffer);
}
/* Copy data */
if ((uiBufferSize - uiHead) > uiSize)
{
TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[uiHead], pvData, uiSize); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
}
else
{
TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[uiHead], pvData, (uiBufferSize - uiHead)); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
TRC_MEMCPY(pxTraceEventBuffer->puiBuffer, (void*)(&((uint8_t*)pvData)[(uiBufferSize - uiHead)]), (uiSize - (uiBufferSize - uiHead))); /*cstat !MISRAC2012-Rule-11.5 Suppress pointer checks*/ /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
}
pxTraceEventBuffer->uiFree -= uiSize;
pxTraceEventBuffer->uiHead = (uiHead + uiSize) % uiBufferSize;
*piBytesWritten = (int32_t)uiSize;
break;
case TRC_EVENT_BUFFER_OPTION_SKIP:
/* Since a consumer could potentially update tail (free) during the procedure
* we have to save it here to avoid problems with the push algorithm.
*/
uiHead = pxTraceEventBuffer->uiHead;
uiTail = pxTraceEventBuffer->uiTail;
if (uiHead >= uiTail)
{
uiFreeSpace = (uiBufferSize - uiHead - sizeof(uint32_t)) + uiTail;
if (uiFreeSpace < uiSize)
{
*piBytesWritten = 0;
return TRC_SUCCESS;
}
/* Copy data */
if ((uiBufferSize - uiHead) > uiSize)
{
TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead], pvData, uiSize); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
}
else
{
TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[uiHead], pvData, (uiBufferSize - uiHead)); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
TRC_MEMCPY(pxTraceEventBuffer->puiBuffer, (void*)(&((uint8_t*)pvData)[(uiBufferSize - uiHead)]), (uiSize - (uiBufferSize - uiHead))); /*cstat !MISRAC2012-Rule-11.5 Suppress pointer checks*/ /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
}
pxTraceEventBuffer->uiHead = (uiHead + uiSize) % uiBufferSize;
}
else
{
uiFreeSpace = uiTail - uiHead - sizeof(uint32_t);
if (uiFreeSpace < uiSize)
{
*piBytesWritten = 0;
return TRC_SUCCESS;
}
/* Copy data */
TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead], pvData, uiSize); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
pxTraceEventBuffer->uiHead = (uiHead + uiSize);
}
*piBytesWritten = (int32_t)uiSize;
break;
default:
return TRC_FAIL;
break;
}
return TRC_SUCCESS;
}
traceResult xTraceEventBufferTransferAll(TraceEventBuffer_t* pxTraceEventBuffer, int32_t* piBytesWritten)
{
int32_t iBytesWritten = 0;
int32_t iSumBytesWritten = 0;
uint32_t uiHead;
uint32_t uiTail;
uint32_t uiSlack;
/* This should never fail */
TRC_ASSERT(pxTraceEventBuffer != (void*)0);
/* This should never fail */
TRC_ASSERT(piBytesWritten != (void*)0);
uiHead = pxTraceEventBuffer->uiHead;
uiTail = pxTraceEventBuffer->uiTail;
uiSlack = pxTraceEventBuffer->uiSlack;
/* Check if core event buffer is empty */
if (uiHead == uiTail)
{
/* Make sure this value is set in case it was passed uninitialized. */
*piBytesWritten = 0;
return TRC_SUCCESS;
}
/* Check if we can do a direct write or if we have to handle wrapping */
if (uiHead > uiTail)
{
/* No wrapping */
(void)xTraceStreamPortWriteData(&pxTraceEventBuffer->puiBuffer[uiTail], (uiHead - uiTail), &iBytesWritten); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
}
else
{
/* Wrapping */
/* Try to write: tail -> end of buffer */
(void)xTraceStreamPortWriteData(&pxTraceEventBuffer->puiBuffer[uiTail], (pxTraceEventBuffer->uiSize - uiTail - uiSlack), &iBytesWritten); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
/* Did we manage to write all bytes? */
if ((uint32_t)iBytesWritten == (pxTraceEventBuffer->uiSize - uiTail - uiSlack))
{
/* uiTail is moved to start of buffer */
pxTraceEventBuffer->uiTail = 0u;
iSumBytesWritten = iBytesWritten;
/* We zero this here in case it does not get zeroed by the streamport. This isn't really a problem with our
* streamports, but there has been cases with custom streamport forgetting to set this to 0 if there is no
* data to write. */
iBytesWritten = 0;
/* Try to write: start of buffer -> head */
(void)xTraceStreamPortWriteData(&pxTraceEventBuffer->puiBuffer[0], uiHead, &iBytesWritten); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
}
}
/* Move tail */
pxTraceEventBuffer->uiTail += (uint32_t)iBytesWritten;
iSumBytesWritten += iBytesWritten;
*piBytesWritten = iSumBytesWritten;
return TRC_SUCCESS;
}
traceResult xTraceEventBufferTransferChunk(TraceEventBuffer_t* pxTraceEventBuffer, uint32_t uiChunkSize, int32_t* piBytesWritten)
{
int32_t iBytesWritten = 0;
uint32_t uiHead;
uint32_t uiTail;
uint32_t uiSlack;
uint32_t uiBytesToWrite;
/* This should never fail */
TRC_ASSERT(pxTraceEventBuffer != (void*)0);
/* This should never fail */
TRC_ASSERT(piBytesWritten != (void*)0);
uiHead = pxTraceEventBuffer->uiHead;
uiTail = pxTraceEventBuffer->uiTail;
uiSlack = pxTraceEventBuffer->uiSlack;
/* Check if core event buffer is empty */
if (uiHead == uiTail)
{
/* Make sure this value is set in case it was passed uninitialized. */
*piBytesWritten = 0;
return TRC_SUCCESS;
}
/* Check if we can do a direct write or if we have to handle wrapping */
if (uiHead > uiTail)
{
uiBytesToWrite = uiHead - uiTail;
if (uiBytesToWrite > uiChunkSize)
{
uiBytesToWrite = uiChunkSize;
}
(void)xTraceStreamPortWriteData(&pxTraceEventBuffer->puiBuffer[uiTail], uiBytesToWrite, &iBytesWritten); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
pxTraceEventBuffer->uiTail += (uint32_t)iBytesWritten;
}
else
{
uiBytesToWrite = pxTraceEventBuffer->uiSize - uiTail - uiSlack;
if (uiBytesToWrite > uiChunkSize)
{
uiBytesToWrite = uiChunkSize;
}
(void)xTraceStreamPortWriteData(&pxTraceEventBuffer->puiBuffer[uiTail], uiBytesToWrite, &iBytesWritten); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
/* Check if we managed to write until the end or not, if we didn't we
* add the number of bytes written. If we managed to write the last
* segment, reset tail to 0. */
if ((uiTail + (uint32_t)iBytesWritten) == (pxTraceEventBuffer->uiSize - uiSlack))
{
pxTraceEventBuffer->uiTail = 0u;
}
else
{
pxTraceEventBuffer->uiTail += (uint32_t)iBytesWritten;
}
}
*piBytesWritten = iBytesWritten;
return TRC_SUCCESS;
}
traceResult xTraceEventBufferClear(TraceEventBuffer_t* pxTraceEventBuffer)
{
/* This should never fail */
TRC_ASSERT(pxTraceEventBuffer != (void*)0);
pxTraceEventBuffer->uiHead = 0u;
pxTraceEventBuffer->uiTail = 0u;
pxTraceEventBuffer->uiFree = pxTraceEventBuffer->uiSize;
pxTraceEventBuffer->uiSlack = 0u;
pxTraceEventBuffer->uiNextHead = 0u;
return TRC_SUCCESS;
}
#endif
#endif

View File

@@ -0,0 +1,111 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation of extensions.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#define TRC_EXTENSION_BASE_EVENT_ID (TRC_EVENT_LAST_ID + 1UL)
#define TRC_EXTENSION_COMBINE_VERSION(_major, _minor, _patch) \
( \
((0x000000FFUL & (TraceUnsignedBaseType_t)(_major)) << 24) | \
((0x000000FFUL & (TraceUnsignedBaseType_t)(_minor)) << 16) | \
((0x0000FFFFUL & (TraceUnsignedBaseType_t)(_patch)) << 0) \
)
static TraceExtensionData_t *pxExtensionData TRC_CFG_RECORDER_DATA_ATTRIBUTE;
traceResult xTraceExtensionInitialize(TraceExtensionData_t* const pxBuffer)
{
/* This should never fail */
TRC_ASSERT(pxBuffer != (void*)0);
pxExtensionData = pxBuffer;
pxExtensionData->uxNextFreeExtensionEventId = TRC_EXTENSION_BASE_EVENT_ID;
xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_EXTENSION);
return TRC_SUCCESS;
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceExtensionCreate(const char* szName, uint8_t uiMajor, uint8_t uiMinor, uint16_t uiPatch, uint32_t uiEventCount, TraceExtensionHandle_t* pxExtensionHandle)
{
TraceObjectHandle_t xObjectHandle;
TraceUnsignedBaseType_t uxStates[3];
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EXTENSION));
/* This should never fail */
TRC_ASSERT(uiEventCount != 0u);
/* This should never fail */
TRC_ASSERT(pxExtensionHandle != (void*)0);
/* This should never fail */
TRC_ASSERT(pxExtensionHandle != (void*)0);
/* This should never fail */
TRC_ASSERT(szName != (void*)0);
/* This should never fail */
TRC_ASSERT(szName[0] != (char)0); /*cstat !MISRAC2004-17.4_b We need to check the first characted*/ /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
uxStates[TRC_EXTENSION_STATE_INDEX_VERSION] = TRC_EXTENSION_COMBINE_VERSION(uiMajor, uiMinor, uiPatch);
uxStates[TRC_EXTENSION_STATE_INDEX_BASE_EVENT_ID] = pxExtensionData->uxNextFreeExtensionEventId;
uxStates[TRC_EXTENSION_STATE_INDEX_EVENT_COUNT] = uiEventCount;
/* We need to check this */
if (xTraceObjectRegisterInternal(PSF_EVENT_EXTENSION_CREATE, (void*)0, szName, 3u, uxStates, TRC_ENTRY_OPTION_EXTENSION, &xObjectHandle) == TRC_FAIL)
{
return TRC_FAIL;
}
pxExtensionData->uxNextFreeExtensionEventId += uiEventCount;
*pxExtensionHandle = (TraceExtensionHandle_t)xObjectHandle;
return TRC_SUCCESS;
}
traceResult xTraceExtensionGetBaseEventId(TraceExtensionHandle_t xExtensionHandle, uint32_t *puiBaseEventId)
{
TraceUnsignedBaseType_t uxBaseEventId;
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EXTENSION));
/* This should never fail */
TRC_ASSERT(puiBaseEventId != (void*)0);
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetState((TraceEntryHandle_t)xExtensionHandle, TRC_EXTENSION_STATE_INDEX_BASE_EVENT_ID, &uxBaseEventId) == TRC_SUCCESS);
*puiBaseEventId = (uint32_t)uxBaseEventId;
return TRC_SUCCESS;
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceExtensionGetConfigName(TraceExtensionHandle_t xExtensionHandle, const char **pszName)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EXTENSION));
return xTraceEntryGetSymbol((TraceEntryHandle_t)xExtensionHandle, pszName);
}
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */

View File

@@ -0,0 +1,154 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The hardware abstraction layer for the trace recorder.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
/* If using DWT timestamping (default on ARM Cortex-M3, M4 and M7), make sure the DWT unit is initialized. */
#if (((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M_NRF_SD)) && (defined (__CORTEX_M) && (__CORTEX_M >= 0x03)))
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#ifndef TRC_CFG_ARM_CM_USE_SYSTICK
void xTraceHardwarePortInitCortexM(void)
{
/* Make sure the DWT registers are unlocked, in case the debugger doesn't do this. */
TRC_REG_ITM_LOCKACCESS = TRC_ITM_LOCKACCESS_UNLOCK;
/* Make sure DWT is enabled is enabled, if supported */
TRC_REG_DEMCR |= TRC_DEMCR_TRCENA;
do
{
/* Verify that DWT is supported */
if (TRC_REG_DEMCR == 0)
{
/* This function is called on Cortex-M3, M4 and M7 devices to initialize
the DWT unit, assumed present. The DWT cycle counter is used for timestamping.
If the below error is produced, the DWT unit does not seem to be available.
In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build
to use SysTick timestamping instead, or define your own timestamping by
setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED
and make the necessary definitions, as explained in trcHardwarePort.h.*/
xTraceError(TRC_ERROR_DWT_NOT_SUPPORTED);
break;
}
/* Verify that DWT_CYCCNT is supported */
if (TRC_REG_DWT_CTRL & TRC_DWT_CTRL_NOCYCCNT)
{
/* This function is called on Cortex-M3, M4 and M7 devices to initialize
the DWT unit, assumed present. The DWT cycle counter is used for timestamping.
If the below error is produced, the cycle counter does not seem to be available.
In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build
to use SysTick timestamping instead, or define your own timestamping by
setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED
and make the necessary definitions, as explained in trcHardwarePort.h.*/
xTraceError(TRC_ERROR_DWT_CYCCNT_NOT_SUPPORTED);
break;
}
/* Reset the cycle counter */
TRC_REG_DWT_CYCCNT = 0;
/* Enable the cycle counter */
TRC_REG_DWT_CTRL |= TRC_DWT_CTRL_CYCCNTENA;
} while (0); /* breaks above jump here */
}
#endif /* TRC_CFG_ARM_CM_USE_SYSTICK */
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M_NRF_SD)) && (defined (__CORTEX_M) && (__CORTEX_M >= 0x03))) */
#if ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_ZyncUltraScaleR5) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_CYCLONE_V_HPS) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARMv8AR_A32))
#define CS_TYPE_NONE 0
#define CS_TYPE_TASK 1
#define CS_TYPE_ISR_MASK_CHANGED 2
#define CS_TYPE_ISR_MASK_NOT_CHANGED 3
#define CS_TYPE_INVALID 0xFFFFFFFF
TraceUnsignedBaseType_t cortex_a9_r5_enter_critical(void)
{
TraceUnsignedBaseType_t cs_type = CS_TYPE_INVALID;
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
TraceunsignedBaseType_t uxTraceSystemState;
xTraceStateGet(&uxTraceSystemState);
#endif
if ((prvGetCPSR() & 0x001F) == 0x13) // CSPR (ASPR) mode = SVC
{
/* Executing in an ISR other than the context-switch (where interrupts might have been enabled, motivating a critical section). */
if (ulPortSetInterruptMask() == pdTRUE)
{
cs_type = CS_TYPE_ISR_MASK_NOT_CHANGED;
}
else
{
cs_type = CS_TYPE_ISR_MASK_CHANGED;
}
}
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
else if (uxTraceSystemState == TRC_STATE_IN_TASKSWITCH)
#else
else if (uiTraceSystemState == TRC_STATE_IN_TASKSWITCH)
#endif
{
// In the context-switch code. All interrupts are already masked here, so don't modify the mask.
cs_type = CS_TYPE_NONE;
}
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
else if (uxTraceSystemState != TRC_STATE_IN_TASKSWITCH)
#else
else if (uiTraceSystemState != TRC_STATE_IN_TASKSWITCH)
#endif
{
// Not within ISR or task-switch context, use a regular critical section.
vPortEnterCritical();
cs_type = CS_TYPE_TASK;
}
return cs_type;
}
void cortex_a9_r5_exit_critical(TraceUnsignedBaseType_t cs_type)
{
switch (cs_type)
{
case CS_TYPE_TASK:
vPortExitCritical();
break;
case CS_TYPE_ISR_MASK_CHANGED:
vPortClearInterruptMask(pdFALSE); // pdFALSE means it will reset the IRQ mask.
break;
case CS_TYPE_ISR_MASK_NOT_CHANGED:
case CS_TYPE_NONE:
// No action in these two cases.
break;
default:
// Error, should not be possible;
for (;;);
}
}
#endif /* ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_ZyncUltraScaleR5)) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */

View File

@@ -0,0 +1,99 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation for heaps.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#if (TRC_USE_HEAPS == 1)
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceHeapCreate(const char *szName, TraceUnsignedBaseType_t uxCurrent, TraceUnsignedBaseType_t uxHighWaterMark, TraceUnsignedBaseType_t uxMax, TraceHeapHandle_t *pxHeapHandle)
{
TraceUnsignedBaseType_t uxStates[3];
uxStates[TRC_HEAP_STATE_INDEX_CURRENT] = uxCurrent;
uxStates[TRC_HEAP_STATE_INDEX_HIGHWATERMARK] = uxHighWaterMark;
uxStates[TRC_HEAP_STATE_INDEX_MAX] = uxMax;
return xTraceObjectRegisterInternal(PSF_EVENT_HEAP_CREATE, (void*)0, szName, 3u, uxStates, TRC_ENTRY_OPTION_HEAP, (TraceObjectHandle_t*)pxHeapHandle);
}
traceResult xTraceHeapAlloc(TraceHeapHandle_t xHeapHandle, void *pvAddress, TraceUnsignedBaseType_t uxSize)
{
TraceUnsignedBaseType_t uxCurrent, uxHighWaterMark;
if (xHeapHandle == 0)
{
/* This can happen */
return TRC_FAIL;
}
/* If the address is null we assume this was a failed alloc attempt */
if (pvAddress != (void*)0)
{
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetState(xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, &uxCurrent) == TRC_SUCCESS);
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetState(xHeapHandle, TRC_HEAP_STATE_INDEX_HIGHWATERMARK, &uxHighWaterMark) == TRC_SUCCESS);
uxCurrent += uxSize;
if (uxCurrent > uxHighWaterMark)
{
uxHighWaterMark = uxCurrent;
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xHeapHandle, TRC_HEAP_STATE_INDEX_HIGHWATERMARK, uxHighWaterMark) == TRC_SUCCESS);
}
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, uxCurrent) == TRC_SUCCESS);
}
(void)xTraceEventCreate2((pvAddress != (void*)0) ? PSF_EVENT_MALLOC : PSF_EVENT_MALLOC_FAILED, (TraceUnsignedBaseType_t)pvAddress, uxSize); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 !MISRAC2012-Rule-11.6 Suppress conversion from pointer to integer check*/
return TRC_SUCCESS;
}
traceResult xTraceHeapFree(TraceHeapHandle_t xHeapHandle, void *pvAddress, TraceUnsignedBaseType_t uxSize)
{
TraceUnsignedBaseType_t uxCurrent;
if (xHeapHandle == 0)
{
/* This can happen */
return TRC_FAIL;
}
/* If the address is null we assume this was a failed alloc attempt */
if (pvAddress != (void*)0)
{
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetState(xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, &uxCurrent) == TRC_SUCCESS);
uxCurrent -= uxSize;
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, uxCurrent) == TRC_SUCCESS);
}
(void)xTraceEventCreate2((pvAddress != (void*)0) ? PSF_EVENT_FREE : PSF_EVENT_FREE_FAILED, (TraceUnsignedBaseType_t)pvAddress, uxSize); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 !MISRAC2012-Rule-11.6 Suppress conversion from pointer to integer check*/
return TRC_SUCCESS;
}
#endif /* (TRC_USE_HEAPS == 1) */
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */

View File

@@ -0,0 +1,250 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation for ISR tagging.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
TraceISRData_t* pxTraceISRData TRC_CFG_RECORDER_DATA_ATTRIBUTE;
traceResult xTraceISRInitialize(TraceISRData_t *pxBuffer)
{
uint32_t uiCoreIndex;
uint32_t uiStackIndex;
/* This should never fail */
TRC_ASSERT(pxBuffer != (void*)0);
pxTraceISRData = pxBuffer;
for (uiCoreIndex = 0u; uiCoreIndex < (uint32_t)(TRC_CFG_CORE_COUNT); uiCoreIndex++)
{
TraceISRCoreData_t* pxCoreData = &pxTraceISRData->cores[uiCoreIndex];
/* Initialize ISR stack */
for (uiStackIndex = 0u; uiStackIndex < (uint32_t)(TRC_CFG_MAX_ISR_NESTING); uiStackIndex++)
{
pxCoreData->handleStack[uiStackIndex] = 0;
}
pxCoreData->stackIndex = -1;
pxCoreData->isPendingContextSwitch = 0u;
}
xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_ISR);
return TRC_SUCCESS;
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceISRRegister(const char* szName, uint32_t uiPriority, TraceISRHandle_t *pxISRHandle)
{
TraceEntryHandle_t xEntryHandle;
TraceEventHandle_t xEventHandle = 0;
uint32_t i, uiLength, uiValue = 0u;
/* We need to check this */
if (xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR) == 0U)
{
return TRC_FAIL;
}
/* This should never fail */
TRC_ASSERT(pxISRHandle != (void*)0);
if (szName == (void*)0)
{
szName = ""; /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
}
/* Always save in symbol table, in case the recording has not yet started */
/* We need to check this */
if (xTraceEntryCreate(&xEntryHandle) == TRC_FAIL)
{
return TRC_FAIL;
}
for (i = 0u; (szName[i] != (char)0) && (i < 128u); i++) {} /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/ /*cstat !MISRAC2004-17.4_b We need to access every character in the string*/
uiLength = i;
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetSymbol(xEntryHandle, szName, uiLength) == TRC_SUCCESS);
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xEntryHandle, 0u, (TraceUnsignedBaseType_t)uiPriority) == TRC_SUCCESS);
*pxISRHandle = (TraceISRHandle_t)xEntryHandle;
/* We need to check this */
if (xTraceEventBegin(PSF_EVENT_DEFINE_ISR, uiLength + sizeof(void*) + sizeof(uint32_t), &xEventHandle) == TRC_SUCCESS)
{
(void)xTraceEventAddPointer(xEventHandle, (void*)xEntryHandle);
(void)xTraceEventAddUnsignedBaseType(xEventHandle, uiPriority);
(void)xTraceEventAddString(xEventHandle, szName, uiLength);
/* Check if we can truncate */
(void)xTraceEventPayloadRemaining(xEventHandle, &uiValue);
if (uiValue > 0u)
{
(void)xTraceEventAdd8(xEventHandle, 0u);
}
(void)xTraceEventEnd(xEventHandle); /*cstat !MISRAC2012-Rule-17.7*/
}
return TRC_SUCCESS;
}
traceResult xTraceISRBegin(TraceISRHandle_t xISRHandle)
{
TraceISRCoreData_t* pxCoreData;
TRACE_ALLOC_CRITICAL_SECTION();
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
TRACE_ENTER_CRITICAL_SECTION();
/* We are at the start of a possible ISR chain.
* No context switches should have been triggered now.
*/
pxCoreData = &pxTraceISRData->cores[TRC_CFG_GET_CURRENT_CORE()];
if (pxCoreData->stackIndex == -1)
{
pxCoreData->isPendingContextSwitch = 0u;
}
if (pxCoreData->stackIndex < ((TRC_CFG_MAX_ISR_NESTING) - 1))
{
pxCoreData->stackIndex++;
pxCoreData->handleStack[pxCoreData->stackIndex] = xISRHandle;
#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
(void)xTraceEventCreate1(PSF_EVENT_ISR_BEGIN, (TraceUnsignedBaseType_t)xISRHandle); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 Suppress conversion from pointer to integer check*/
#endif
}
else
{
TRACE_EXIT_CRITICAL_SECTION();
(void)xTraceError(TRC_ERROR_ISR_NESTING_OVERFLOW);
return TRC_FAIL;
}
TRACE_EXIT_CRITICAL_SECTION();
return TRC_SUCCESS;
}
traceResult xTraceISREnd(TraceBaseType_t xIsTaskSwitchRequired)
{
TraceISRCoreData_t* pxCoreData;
TRACE_ALLOC_CRITICAL_SECTION();
(void)xIsTaskSwitchRequired;
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
TRACE_ENTER_CRITICAL_SECTION();
pxCoreData = &pxTraceISRData->cores[TRC_CFG_GET_CURRENT_CORE()];
pxCoreData->stackIndex--;
#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
/* Is there a pending task-switch? (perhaps from an earlier ISR) */
pxCoreData->isPendingContextSwitch |= (uint32_t)xIsTaskSwitchRequired;
if (pxCoreData->stackIndex >= 0)
{
/* Store return to interrupted ISR (if nested ISRs)*/
(void)xTraceEventCreate1(PSF_EVENT_ISR_RESUME, (TraceUnsignedBaseType_t)pxCoreData->handleStack[pxCoreData->stackIndex]); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 Suppress conversion from pointer to integer check*/
}
else
{
/* Store return to interrupted task, if no context switch will occur in between. */
if ((pxCoreData->isPendingContextSwitch == 0U) || (xTraceKernelPortIsSchedulerSuspended() == 1U)) /*cstat !MISRAC2004-13.7_b For some kernel ports xTraceKernelPortIsSchedulerSuspended() will never return 1, and that is expected*/
{
(void)xTraceEventCreate1(PSF_EVENT_TASK_ACTIVATE, (TraceUnsignedBaseType_t)xTraceTaskGetCurrentReturn()); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 !MISRAC2012-Rule-11.6 Suppress conversion from pointer to integer check*/
}
}
#endif
TRACE_EXIT_CRITICAL_SECTION();
return TRC_SUCCESS;
}
#if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
traceResult xTraceISRGetCurrentNesting(int32_t* puiValue)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
/* This should never fail */
TRC_ASSERT(puiValue != (void*)0);
TraceISRCoreData_t* pxCoreData = &pxTraceISRData->cores[TRC_CFG_GET_CURRENT_CORE()];
*puiValue = pxCoreData->stackIndex;
return TRC_SUCCESS;
}
int32_t xTraceISRGetCurrentNestingReturned(void)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
return pxTraceISRData->cores[TRC_CFG_GET_CURRENT_CORE()].stackIndex;
}
traceResult xTraceISRGetCurrent(TraceISRHandle_t* pxISRHandle)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
/* This should never fail */
TRC_ASSERT(pxISRHandle != (void*)0);
TraceISRCoreData_t* pxCoreData = &pxTraceISRData->cores[TRC_CFG_GET_CURRENT_CORE()];
if (pxCoreData->stackIndex < 0)
{
return TRC_FAIL;
}
*pxISRHandle = pxCoreData->handleStack[pxCoreData->stackIndex];
return TRC_SUCCESS;
}
#endif
/* DEPRECATED */
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
TraceISRHandle_t xTraceSetISRProperties(const char* szName, uint32_t uiPriority)
{
TraceISRHandle_t xISRHandle = 0;
(void)xTraceISRRegister(szName, uiPriority, &xISRHandle);
return xISRHandle;
}
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */

View File

@@ -0,0 +1,117 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation of the internal buffer.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#if (TRC_USE_INTERNAL_BUFFER == 1)
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
static TraceMultiCoreEventBuffer_t *pxInternalEventBuffer TRC_CFG_RECORDER_DATA_ATTRIBUTE;
traceResult xTraceInternalEventBufferInitialize(uint8_t* puiBuffer, uint32_t uiSize)
{
/* uiSize must be larger than sizeof(TraceMultiCoreEventBuffer_t) or there will be no room for any data */
/* This should never fail */
TRC_ASSERT(uiSize > sizeof(TraceMultiCoreEventBuffer_t));
/* pxInternalBuffer will be placed at the beginning of the puiBuffer */
pxInternalEventBuffer = (TraceMultiCoreEventBuffer_t*)puiBuffer;
/* Send in a an address pointing after the TraceMultiCoreEventBuffer_t */
/* We need to check this */
if (xTraceMultiCoreEventBufferInitialize(pxInternalEventBuffer, TRC_EVENT_BUFFER_OPTION_SKIP,
&puiBuffer[sizeof(TraceMultiCoreEventBuffer_t)], uiSize - sizeof(TraceMultiCoreEventBuffer_t)) == TRC_FAIL)
{
return TRC_FAIL;
}
xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_INTERNAL_EVENT_BUFFER);
return TRC_SUCCESS;
}
traceResult xTraceInternalEventBufferAlloc(uint32_t uiSize, void **ppvData)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_INTERNAL_EVENT_BUFFER));
return xTraceMultiCoreEventBufferAlloc(pxInternalEventBuffer, uiSize, ppvData);
}
traceResult xTraceInternalEventBufferAllocCommit(void *pvData, uint32_t uiSize, int32_t *piBytesWritten)
{
(void)pvData;
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_INTERNAL_EVENT_BUFFER));
return xTraceMultiCoreEventBufferAllocCommit(pxInternalEventBuffer, pvData, uiSize, piBytesWritten);
}
traceResult xTraceInternalEventBufferPush(void *pvData, uint32_t uiSize, int32_t *piBytesWritten)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_INTERNAL_EVENT_BUFFER));
return xTraceMultiCoreEventBufferPush(pxInternalEventBuffer, pvData, uiSize, piBytesWritten);
}
traceResult xTraceInternalEventBufferTransferAll(void)
{
int32_t iBytesWritten = 0;
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_INTERNAL_EVENT_BUFFER));
return xTraceMultiCoreEventBufferTransferAll(pxInternalEventBuffer, &iBytesWritten);
}
traceResult xTraceInternalEventBufferTransferChunk(void)
{
int32_t iBytesWritten = 0;
int32_t iCounter = 0;
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_INTERNAL_EVENT_BUFFER));
do
{
if (xTraceMultiCoreEventBufferTransferChunk(pxInternalEventBuffer, TRC_INTERNAL_BUFFER_CHUNK_SIZE, &iBytesWritten) == TRC_FAIL)
{
return TRC_FAIL;
}
iCounter++;
/* This will do another loop if TRC_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_SIZE_LIMIT of data was transferred and we haven't already looped TRC_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_COUNT_LIMIT number of times */
} while (iBytesWritten >= (int32_t)(TRC_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_SIZE_LIMIT) && iCounter < (int32_t)(TRC_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_COUNT_LIMIT));
return TRC_SUCCESS;
}
traceResult xTraceInternalEventBufferClear()
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_INTERNAL_EVENT_BUFFER));
return xTraceMultiCoreEventBufferClear(pxInternalEventBuffer);
}
#endif /* (TRC_USE_INTERNAL_BUFFER == 1) */
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */

View File

@@ -0,0 +1,91 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation of intervals.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceIntervalChannelSetCreate(const char* szName, TraceIntervalChannelSetHandle_t* pxIntervalChannelSetHandle)
{
TraceObjectHandle_t xObjectHandle;
/* This should never fail */
TRC_ASSERT(pxIntervalChannelSetHandle != (void*)0);
/* We need to check this */
if (xTraceObjectRegister(PSF_EVENT_INTERVAL_CHANNEL_SET_CREATE, (void*)0, szName, 0u, &xObjectHandle) == TRC_FAIL)
{
return TRC_FAIL;
}
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetOptions((TraceEntryHandle_t)xObjectHandle, TRC_ENTRY_OPTION_INTERVAL_CHANNEL_SET) == TRC_SUCCESS);
*pxIntervalChannelSetHandle = (TraceIntervalChannelSetHandle_t)xObjectHandle;
return TRC_SUCCESS;
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceIntervalChannelCreate(const char *szName, TraceIntervalChannelSetHandle_t xIntervalChannelSetHandle, TraceIntervalChannelHandle_t *pxIntervalChannelHandle)
{
TraceObjectHandle_t xObjectHandle;
/* This should never fail */
TRC_ASSERT(pxIntervalChannelHandle != (void*)0);
/* This should never fail */
TRC_ASSERT(xIntervalChannelSetHandle != 0);
/* We need to check this */
if (xTraceObjectRegister(PSF_EVENT_INTERVAL_CHANNEL_CREATE, (void*)0, szName, (TraceUnsignedBaseType_t)xIntervalChannelSetHandle, &xObjectHandle) == TRC_FAIL) /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 Suppress conversion from pointer to integer check*/
{
return TRC_FAIL;
}
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetOptions((TraceEntryHandle_t)xObjectHandle, TRC_ENTRY_OPTION_INTERVAL_CHANNEL) == TRC_SUCCESS);
*pxIntervalChannelHandle = (TraceIntervalChannelHandle_t)xObjectHandle;
return TRC_SUCCESS;
}
traceResult xTraceIntervalStart(TraceIntervalChannelHandle_t xIntervalChannelHandle, TraceUnsignedBaseType_t uxValue, TraceIntervalInstanceHandle_t *pxIntervalInstanceHandle)
{
TRC_ASSERT(xIntervalChannelHandle != 0);
TRC_ASSERT(pxIntervalInstanceHandle != (void*)0);
/* We null all of it first in case it's 64-bit and we only write 32-bit */
*pxIntervalInstanceHandle = 0;
TRC_ASSERT_ALWAYS_EVALUATE(xTraceTimestampGet((uint32_t*)pxIntervalInstanceHandle) == TRC_SUCCESS); /*cstat !MISRAC2004-11.4 !MISRAC2012-Rule-11.3 Suppress conversion between pointer types checks*/
(void)xTraceEventCreate3(PSF_EVENT_INTERVAL_START, (TraceUnsignedBaseType_t)xIntervalChannelHandle, (TraceUnsignedBaseType_t)*pxIntervalInstanceHandle, uxValue); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 Suppress conversion from pointer to integer check*/
return TRC_SUCCESS;
}
traceResult xTraceIntervalStop(TraceIntervalChannelHandle_t xIntervalChannelHandle, TraceIntervalInstanceHandle_t xIntervalInstanceHandle)
{
TRC_ASSERT(xIntervalChannelHandle != 0);
(void)xTraceEventCreate2(PSF_EVENT_INTERVAL_STOP, (TraceUnsignedBaseType_t)xIntervalChannelHandle, (TraceUnsignedBaseType_t)xIntervalInstanceHandle); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 Suppress conversion from pointer to integer check*/
return TRC_SUCCESS;
}
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */

View File

@@ -0,0 +1,664 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The FreeRTOS specific parts of the trace recorder
*/
#include <FreeRTOS.h>
#include <trcRecorder.h>
#if (!defined(TRC_USE_TRACEALYZER_RECORDER) && configUSE_TRACE_FACILITY == 1)
#error Trace Recorder: You need to include trcRecorder.h at the end of your FreeRTOSConfig.h!
#endif
#if (defined(TRC_USE_TRACEALYZER_RECORDER) && TRC_USE_TRACEALYZER_RECORDER == 1)
#ifndef TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS
/* TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS is missing in trcConfig.h. */
#error "TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS must be defined in trcConfig.h."
#endif
#ifndef TRC_CFG_INCLUDE_TIMER_EVENTS
/* TRC_CFG_INCLUDE_TIMER_EVENTS is missing in trcConfig.h. */
#error "TRC_CFG_INCLUDE_TIMER_EVENTS must be defined in trcConfig.h."
#endif
#ifndef TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS
/* TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS is missing in trcConfig.h. */
#error "TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS must be defined in trcConfig.h."
#endif
#ifndef TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS
/* TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS is missing in trcConfig.h. Define this as 1 if using FreeRTOS v10 or later and like to trace stream buffer or message buffer events, otherwise 0. */
#error "TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS must be defined in trcConfig.h."
#endif
#if (configUSE_TICKLESS_IDLE != 0 && (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR))
/*
The below error message is to alert you on the following issue:
The hardware port selected in trcConfig.h uses the operating system timer for the
timestamping, i.e., the periodic interrupt timer that drives the OS tick interrupt.
When using "tickless idle" mode, the recorder needs an independent time source in
order to correctly record the durations of the idle times. Otherwise, the trace may appear
to have a different length than in reality, and the reported CPU load is also affected.
You may override this warning by defining the TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING
macro in your trcConfig.h file. But then the time scale may be incorrect during
tickless idle periods.
To get this correct, override the default timestamping by setting TRC_CFG_HARDWARE_PORT
in trcConfig.h to TRC_HARDWARE_PORT_APPLICATION_DEFINED and define the HWTC macros
accordingly, using a free running counter or an independent periodic interrupt timer.
See trcHardwarePort.h for details.
For ARM Cortex-M3, M4 and M7 MCUs this is not an issue, since the recorder uses the
DWT cycle counter for timestamping in these cases.
*/
#ifndef TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING
#error Trace Recorder: This timestamping mode is not recommended with Tickless Idle.
#endif
#endif
#include <task.h>
#include <queue.h>
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) || (defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0))
#if defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1)
#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0)
static StackType_t stackTzCtrl[TRC_CFG_CTRL_TASK_STACK_SIZE];
static StaticTask_t tcbTzCtrl;
#else
#error "configSUPPORT_STATIC_ALLOCATION not supported before FreeRTOS v9"
#endif
#endif
/* The TzCtrl task - receives commands from Tracealyzer (start/stop) */
static portTASK_FUNCTION(TzCtrl, pvParameters);
#endif
#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X)
/* If the project does not include the FreeRTOS timers, TRC_CFG_INCLUDE_TIMER_EVENTS must be set to 0 */
#include <timers.h>
#endif
#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X)
/* If the project does not include the FreeRTOS event groups, TRC_CFG_INCLUDE_TIMER_EVENTS must be set to 0 */
#include <event_groups.h>
#endif
#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
/* If the project does not include the FreeRTOS stream buffers, TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS must be set to 0 */
#include <stream_buffer.h>
#endif
#if (TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND != TRC_ACKNOWLEDGED) && (TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_10_3_0 || TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_10_3_1) && (configUSE_QUEUE_SETS == 1)
#error "When using FreeRTOS v10.3.0 or v10.3.1, please make sure that the trace point in prvNotifyQueueSetContainer() in queue.c is renamed from traceQUEUE_SEND to traceQUEUE_SET_SEND in order to tell them apart from other traceQUEUE_SEND trace points. Then set TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND in trcConfig.h to TRC_ACKNOWLEDGED to get rid of this error."
#endif
#if defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0)
traceResult xTraceKernelPortGetUnusedStack(void* pvTask, TraceUnsignedBaseType_t* puxUnusedStack)
{
*puxUnusedStack = uxTaskGetStackHighWaterMark(pvTask);
return TRC_SUCCESS;
}
#endif
traceResult xTraceKernelPortDelay(uint32_t uiTicks)
{
vTaskDelay(uiTicks);
return TRC_SUCCESS;
}
unsigned char xTraceKernelPortIsSchedulerSuspended(void)
{
/* Assumed to be available in FreeRTOS. According to the FreeRTOS docs,
INCLUDE_xTaskGetSchedulerState or configUSE_TIMERS must be set to 1 in
FreeRTOSConfig.h for this function to be available. */
return xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED;
}
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
typedef struct TraceKernelPortData
{
TraceHeapHandle_t xSystemHeapHandle;
TraceKernelPortTaskHandle_t xTzCtrlHandle;
} TraceKernelPortData_t;
static TraceKernelPortData_t* pxKernelPortData TRC_CFG_RECORDER_DATA_ATTRIBUTE;
#define TRC_PORT_MALLOC(size) pvPortMalloc(size)
traceResult xTraceKernelPortInitialize(TraceKernelPortDataBuffer_t* pxBuffer)
{
TRC_ASSERT_EQUAL_SIZE(TraceKernelPortDataBuffer_t, TraceKernelPortData_t);
if (pxBuffer == 0)
{
return TRC_FAIL;
}
pxKernelPortData = (TraceKernelPortData_t*)pxBuffer;
pxKernelPortData->xSystemHeapHandle = 0;
pxKernelPortData->xTzCtrlHandle = 0;
return TRC_SUCCESS;
}
traceResult xTraceKernelPortEnable(void)
{
#ifdef configIDLE_TASK_NAME
TraceEntryHandle_t xIdleHandle;
uint32_t i;
for (i = 0; ((configIDLE_TASK_NAME)[i] != 0) && (i < 128); i++) {}
if (xTraceEntryCreate(&xIdleHandle) == TRC_SUCCESS)
{
xTraceEntrySetSymbol(xIdleHandle, configIDLE_TASK_NAME, i);
xTraceEntrySetOptions(xIdleHandle, TRC_ENTRY_OPTION_IDLE_NAME);
}
#endif
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
if (pxKernelPortData->xSystemHeapHandle == 0)
{
#if defined(configTOTAL_HEAP_SIZE)
xTraceHeapCreate("System Heap", 0, 0, configTOTAL_HEAP_SIZE, &pxKernelPortData->xSystemHeapHandle);
#else
/* A heap type is used that doesn't define configTOTAL_HEAP_SIZE so heap size needs to be configured manually. Define TRC_CFG_TOTAL_HEAP_SIZE in trcConfig.h. */
xTraceHeapCreate("System Heap", 0, 0, (TRC_CFG_TOTAL_HEAP_SIZE), &pxKernelPortData->xSystemHeapHandle);
#endif
}
#endif
if (pxKernelPortData->xTzCtrlHandle == 0)
{
/* Creates the TzCtrl task - receives trace commands (start, stop, ...) */
#if defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1)
pxKernelPortData->xTzCtrlHandle = xTaskCreateStatic(TzCtrl, STRING_CAST("TzCtrl"), TRC_CFG_CTRL_TASK_STACK_SIZE, 0, TRC_CFG_CTRL_TASK_PRIORITY, stackTzCtrl, &tcbTzCtrl);
#else
xTaskCreate(TzCtrl, STRING_CAST("TzCtrl"), TRC_CFG_CTRL_TASK_STACK_SIZE, 0, TRC_CFG_CTRL_TASK_PRIORITY, &pxKernelPortData->xTzCtrlHandle);
#endif
if (pxKernelPortData->xTzCtrlHandle == 0)
{
xTraceError(TRC_ERROR_TZCTRLTASK_NOT_CREATED);
return TRC_FAIL;
}
}
return TRC_SUCCESS;
}
static portTASK_FUNCTION(TzCtrl, pvParameters)
{
(void)pvParameters;
while (1)
{
xTraceTzCtrl();
vTaskDelay(TRC_CFG_CTRL_TASK_DELAY);
}
}
#if (TRC_CFG_SCHEDULING_ONLY == 0)
void vTraceSetQueueName(void* pvQueue, const char* szName)
{
xTraceObjectSetNameWithoutHandle(pvQueue, szName);
}
void vTraceSetSemaphoreName(void* pvSemaphore, const char* szName)
{
xTraceObjectSetNameWithoutHandle(pvSemaphore, szName);
}
void vTraceSetMutexName(void* pvMutex, const char* szName)
{
xTraceObjectSetNameWithoutHandle(pvMutex, szName);
}
#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X)
void vTraceSetEventGroupName(void* pvEventGroup, const char* szName)
{
xTraceObjectSetNameWithoutHandle(pvEventGroup, szName);
}
#endif
#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
void vTraceSetStreamBufferName(void* pvStreamBuffer, const char* szName)
{
xTraceObjectSetNameWithoutHandle(pvStreamBuffer, szName);
}
void vTraceSetMessageBufferName(void* pvMessageBuffer, const char* szName)
{
xTraceObjectSetNameWithoutHandle(pvMessageBuffer, szName);
}
#endif
#endif
TraceHeapHandle_t xTraceKernelPortGetSystemHeapHandle(void)
{
return pxKernelPortData->xSystemHeapHandle;
}
#endif
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
uint32_t prvTraceGetQueueNumber(void* handle);
#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X_X)
extern unsigned char ucQueueGetQueueNumber(xQueueHandle pxQueue);
extern void vQueueSetQueueNumber(xQueueHandle pxQueue, unsigned char ucQueueNumber);
extern unsigned char ucQueueGetQueueType(xQueueHandle pxQueue);
uint32_t prvTraceGetQueueNumber(void* handle)
{
return (uint32_t)ucQueueGetQueueNumber(handle);
}
#else
uint32_t prvTraceGetQueueNumber(void* handle)
{
return (uint32_t)uxQueueGetQueueNumber(handle);
}
#endif
uint8_t prvTraceGetQueueType(void* pvQueue)
{
// This is either declared in header file in FreeRTOS 8 and later, or as extern above
return ucQueueGetQueueType(pvQueue);
}
/* Tasks */
uint16_t prvTraceGetTaskNumberLow16(void* pvTask)
{
return TRACE_GET_LOW16(uxTaskGetTaskNumber(pvTask));
}
uint16_t prvTraceGetTaskNumberHigh16(void* pvTask)
{
return TRACE_GET_HIGH16(uxTaskGetTaskNumber(pvTask));
}
void prvTraceSetTaskNumberLow16(void* pvTask, uint16_t uiValue)
{
vTaskSetTaskNumber(pvTask, TRACE_SET_LOW16(uxTaskGetTaskNumber(pvTask), uiValue));
}
void prvTraceSetTaskNumberHigh16(void* pvTask, uint16_t uiValue)
{
vTaskSetTaskNumber(pvTask, TRACE_SET_HIGH16(uxTaskGetTaskNumber(pvTask), uiValue));
}
uint16_t prvTraceGetQueueNumberLow16(void* pvQueue)
{
return TRACE_GET_LOW16(prvTraceGetQueueNumber(pvQueue));
}
uint16_t prvTraceGetQueueNumberHigh16(void* pvQueue)
{
return TRACE_GET_HIGH16(prvTraceGetQueueNumber(pvQueue));
}
void prvTraceSetQueueNumberLow16(void* pvQueue, uint16_t uiValue)
{
vQueueSetQueueNumber(pvQueue, TRACE_SET_LOW16(prvTraceGetQueueNumber(pvQueue), uiValue));
}
void prvTraceSetQueueNumberHigh16(void* pvQueue, uint16_t uiValue)
{
vQueueSetQueueNumber(pvQueue, TRACE_SET_HIGH16(prvTraceGetQueueNumber(pvQueue), uiValue));
}
#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
uint16_t prvTraceGetTimerNumberLow16(void* pvTimer)
{
return TRACE_GET_LOW16(uxTimerGetTimerNumber(pvTimer));
}
uint16_t prvTraceGetTimerNumberHigh16(void* pvTimer)
{
return TRACE_GET_HIGH16(uxTimerGetTimerNumber(pvTimer));
}
void prvTraceSetTimerNumberLow16(void* pvTimer, uint16_t uiValue)
{
vTimerSetTimerNumber(pvTimer, TRACE_SET_LOW16(uxTimerGetTimerNumber(pvTimer), uiValue));
}
void prvTraceSetTimerNumberHigh16(void* pvTimer, uint16_t uiValue)
{
vTimerSetTimerNumber(pvTimer, TRACE_SET_HIGH16(uxTimerGetTimerNumber(pvTimer), uiValue));
}
#endif
#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
uint16_t prvTraceGetEventGroupNumberLow16(void* pvEventGroup)
{
return TRACE_GET_LOW16(uxEventGroupGetNumber(pvEventGroup));
}
uint16_t prvTraceGetEventGroupNumberHigh16(void* pvEventGroup)
{
return TRACE_GET_HIGH16(uxEventGroupGetNumber(pvEventGroup));
}
void prvTraceSetEventGroupNumberLow16(void* pvEventGroup, uint16_t uiValue)
{
vEventGroupSetNumber(pvEventGroup, TRACE_SET_LOW16(uxEventGroupGetNumber(pvEventGroup), uiValue));
}
void prvTraceSetEventGroupNumberHigh16(void* pvEventGroup, uint16_t uiValue)
{
vEventGroupSetNumber(pvEventGroup, TRACE_SET_HIGH16(uxEventGroupGetNumber(pvEventGroup), uiValue));
}
#endif
#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
uint16_t prvTraceGetStreamBufferNumberLow16(void* pvStreamBuffer)
{
return TRACE_GET_LOW16(uxStreamBufferGetStreamBufferNumber(pvStreamBuffer));
}
uint16_t prvTraceGetStreamBufferNumberHigh16(void* pvStreamBuffer)
{
return TRACE_GET_HIGH16(uxStreamBufferGetStreamBufferNumber(pvStreamBuffer));
}
void prvTraceSetStreamBufferNumberLow16(void* pvStreamBuffer, uint16_t uiValue)
{
vStreamBufferSetStreamBufferNumber(pvStreamBuffer, TRACE_SET_LOW16(uxStreamBufferGetStreamBufferNumber(pvStreamBuffer), uiValue));
}
void prvTraceSetStreamBufferNumberHigh16(void* pvStreamBuffer, uint16_t uiValue)
{
vStreamBufferSetStreamBufferNumber(pvStreamBuffer, TRACE_SET_HIGH16(uxStreamBufferGetStreamBufferNumber(pvStreamBuffer), uiValue));
}
#endif
static TraceKernelPortTaskHandle_t xTzCtrlHandle = 0; /* TzCtrl task TCB */
/* Internal flag to tell the context of tracePEND_FUNC_CALL_FROM_ISR */
int uiInEventGroupSetBitsFromISR = 0;
/**
* @internal Class reference table
*/
traceObjectClass TraceQueueClassTable[5] = {
TRACE_CLASS_QUEUE,
TRACE_CLASS_MUTEX,
TRACE_CLASS_SEMAPHORE,
TRACE_CLASS_SEMAPHORE,
TRACE_CLASS_MUTEX
};
#if (TRC_CFG_SCHEDULING_ONLY == 0)
void vTraceSetQueueName(void* pvQueue, const char* szName)
{
prvTraceSetObjectName(TRACE_CLASS_QUEUE, TRACE_GET_OBJECT_NUMBER(QUEUE, pvQueue), szName);
}
void vTraceSetSemaphoreName(void* pvSemaphore, const char* szName)
{
prvTraceSetObjectName(TRACE_CLASS_SEMAPHORE, TRACE_GET_OBJECT_NUMBER(QUEUE, pvSemaphore), szName);
}
void vTraceSetMutexName(void* pvMutex, const char* szName)
{
prvTraceSetObjectName(TRACE_CLASS_MUTEX, TRACE_GET_OBJECT_NUMBER(QUEUE, pvMutex), szName);
}
#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X)
void vTraceSetEventGroupName(void* pvEventGroup, const char* szName)
{
prvTraceSetObjectName(TRACE_CLASS_EVENTGROUP, TRACE_GET_OBJECT_NUMBER(EVENTGROUP, pvEventGroup), szName);
}
#endif
#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
void vTraceSetStreamBufferName(void* pvStreamBuffer, const char* szName)
{
prvTraceSetObjectName(TRACE_CLASS_STREAMBUFFER, TRACE_GET_OBJECT_NUMBER(STREAMBUFFER, pvStreamBuffer), szName);
}
void vTraceSetMessageBufferName(void* pvStreamBuffer, const char* szName)
{
prvTraceSetObjectName(TRACE_CLASS_MESSAGEBUFFER, TRACE_GET_OBJECT_NUMBER(STREAMBUFFER, pvStreamBuffer), szName);
}
#endif
#endif
void* prvTraceGetCurrentTaskHandle(void)
{
return xTaskGetCurrentTaskHandle();
}
traceResult xTraceKernelPortInitialize(TraceKernelPortDataBuffer_t* pxBuffer)
{
(void)pxBuffer;
return TRC_SUCCESS;
}
traceResult xTraceKernelPortEnable(void)
{
#if defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0)
if (xTzCtrlHandle == 0)
{
#if defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1)
xTzCtrlHandle = xTaskCreateStatic(TzCtrl, STRING_CAST("TzCtrl"), TRC_CFG_CTRL_TASK_STACK_SIZE, 0, TRC_CFG_CTRL_TASK_PRIORITY, stackTzCtrl, &tcbTzCtrl);
#else
xTaskCreate(TzCtrl, STRING_CAST("TzCtrl"), TRC_CFG_CTRL_TASK_STACK_SIZE, 0, TRC_CFG_CTRL_TASK_PRIORITY, &xTzCtrlHandle);
#endif
}
#else
(void)xTzCtrlHandle;
#endif
return TRC_SUCCESS;
}
#if defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0)
static portTASK_FUNCTION(TzCtrl, pvParameters)
{
(void)pvParameters;
while (1)
{
if (xTraceIsRecorderEnabled())
{
prvReportStackUsage();
}
vTaskDelay(TRC_CFG_CTRL_TASK_DELAY);
}
}
#endif
traceResult xTraceKernelPortInitObjectPropertyTable(void)
{
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectClasses = TRACE_NCLASSES;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[0] = TRC_CFG_NQUEUE;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[1] = TRC_CFG_NSEMAPHORE;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[2] = TRC_CFG_NMUTEX;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[3] = TRC_CFG_NTASK;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[4] = TRC_CFG_NISR;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[5] = TRC_CFG_NTIMER;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[6] = TRC_CFG_NEVENTGROUP;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[7] = TRC_CFG_NSTREAMBUFFER;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[8] = TRC_CFG_NMESSAGEBUFFER;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[0] = TRC_CFG_NAME_LEN_QUEUE;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[1] = TRC_CFG_NAME_LEN_SEMAPHORE;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[2] = TRC_CFG_NAME_LEN_MUTEX;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[3] = TRC_CFG_NAME_LEN_TASK;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[4] = TRC_CFG_NAME_LEN_ISR;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[5] = TRC_CFG_NAME_LEN_TIMER;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[6] = TRC_CFG_NAME_LEN_EVENTGROUP;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[7] = TRC_CFG_NAME_LEN_STREAMBUFFER;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[8] = TRC_CFG_NAME_LEN_MESSAGEBUFFER;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[0] = PropertyTableSizeQueue;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[1] = PropertyTableSizeSemaphore;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[2] = PropertyTableSizeMutex;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[3] = PropertyTableSizeTask;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[4] = PropertyTableSizeISR;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[5] = PropertyTableSizeTimer;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[6] = PropertyTableSizeEventGroup;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[7] = PropertyTableSizeStreamBuffer;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[8] = PropertyTableSizeMessageBuffer;
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[0] = StartIndexQueue;
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[1] = StartIndexSemaphore;
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[2] = StartIndexMutex;
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[3] = StartIndexTask;
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[4] = StartIndexISR;
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[5] = StartIndexTimer;
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[6] = StartIndexEventGroup;
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[7] = StartIndexStreamBuffer;
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[8] = StartIndexMessageBuffer;
RecorderDataPtr->ObjectPropertyTable.ObjectPropertyTableSizeInBytes = TRACE_OBJECT_TABLE_SIZE;
return TRC_SUCCESS;
}
traceResult xTraceKernelPortInitObjectHandleStack(void)
{
uint32_t i = 0;
objectHandleStacks.indexOfNextAvailableHandle[0] = objectHandleStacks.lowestIndexOfClass[0] = 0;
objectHandleStacks.indexOfNextAvailableHandle[1] = objectHandleStacks.lowestIndexOfClass[1] = (TRC_CFG_NQUEUE);
objectHandleStacks.indexOfNextAvailableHandle[2] = objectHandleStacks.lowestIndexOfClass[2] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE);
objectHandleStacks.indexOfNextAvailableHandle[3] = objectHandleStacks.lowestIndexOfClass[3] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX);
objectHandleStacks.indexOfNextAvailableHandle[4] = objectHandleStacks.lowestIndexOfClass[4] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK);
objectHandleStacks.indexOfNextAvailableHandle[5] = objectHandleStacks.lowestIndexOfClass[5] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR);
objectHandleStacks.indexOfNextAvailableHandle[6] = objectHandleStacks.lowestIndexOfClass[6] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER);
objectHandleStacks.indexOfNextAvailableHandle[7] = objectHandleStacks.lowestIndexOfClass[7] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP);
objectHandleStacks.indexOfNextAvailableHandle[8] = objectHandleStacks.lowestIndexOfClass[8] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) + (TRC_CFG_NSTREAMBUFFER);
objectHandleStacks.highestIndexOfClass[0] = (TRC_CFG_NQUEUE) - 1;
objectHandleStacks.highestIndexOfClass[1] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) - 1;
objectHandleStacks.highestIndexOfClass[2] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) - 1;
objectHandleStacks.highestIndexOfClass[3] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) - 1;
objectHandleStacks.highestIndexOfClass[4] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) - 1;
objectHandleStacks.highestIndexOfClass[5] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) - 1;
objectHandleStacks.highestIndexOfClass[6] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) - 1;
objectHandleStacks.highestIndexOfClass[7] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) + (TRC_CFG_NSTREAMBUFFER) - 1;
objectHandleStacks.highestIndexOfClass[8] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) + (TRC_CFG_NSTREAMBUFFER) + (TRC_CFG_NMESSAGEBUFFER) - 1;
for (i = 0; i < TRACE_NCLASSES; i++)
{
objectHandleStacks.handleCountWaterMarksOfClass[i] = 0;
}
for (i = 0; i < TRACE_KERNEL_OBJECT_COUNT; i++)
{
objectHandleStacks.objectHandles[i] = 0;
}
return TRC_SUCCESS;
}
const char* pszTraceGetErrorNotEnoughHandles(traceObjectClass objectclass)
{
switch(objectclass)
{
case TRACE_CLASS_TASK:
return "Not enough TASK handles - increase TRC_CFG_NTASK in trcSnapshotConfig.h";
case TRACE_CLASS_ISR:
return "Not enough ISR handles - increase TRC_CFG_NISR in trcSnapshotConfig.h";
case TRACE_CLASS_SEMAPHORE:
return "Not enough SEMAPHORE handles - increase TRC_CFG_NSEMAPHORE in trcSnapshotConfig.h";
case TRACE_CLASS_MUTEX:
return "Not enough MUTEX handles - increase TRC_CFG_NMUTEX in trcSnapshotConfig.h";
case TRACE_CLASS_QUEUE:
return "Not enough QUEUE handles - increase TRC_CFG_NQUEUE in trcSnapshotConfig.h";
case TRACE_CLASS_TIMER:
return "Not enough TIMER handles - increase TRC_CFG_NTIMER in trcSnapshotConfig.h";
case TRACE_CLASS_EVENTGROUP:
return "Not enough EVENTGROUP handles - increase TRC_CFG_NEVENTGROUP in trcSnapshotConfig.h";
case TRACE_CLASS_STREAMBUFFER:
return "Not enough STREAMBUFFER handles - increase TRC_CFG_NSTREAMBUFFER in trcSnapshotConfig.h";
case TRACE_CLASS_MESSAGEBUFFER:
return "Not enough MESSAGEBUFFER handles - increase TRC_CFG_NMESSAGEBUFFER in trcSnapshotConfig.h";
default:
return "pszTraceGetErrorHandles: Invalid objectclass!";
}
}
#endif
#endif

View File

@@ -0,0 +1,164 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The interface for the multi-core event buffer.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
traceResult xTraceMultiCoreEventBufferInitialize(TraceMultiCoreEventBuffer_t* const pxTraceMultiCoreEventBuffer, uint32_t uiOptions,
uint8_t* puiBuffer, uint32_t uiSize)
{
uint32_t i;
uint32_t uiBufferSizePerCore;
/* This should never fail */
TRC_ASSERT(pxTraceMultiCoreEventBuffer != (void*)0);
/* This should never fail */
TRC_ASSERT(puiBuffer != (void*)0);
uiBufferSizePerCore = ((uiSize / (uint32_t)(TRC_CFG_CORE_COUNT)) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t); /* BaseType aligned */
/* This should never fail */
TRC_ASSERT(uiBufferSizePerCore != 0u);
for (i = 0u; i < (uint32_t)(TRC_CFG_CORE_COUNT); i++)
{
/* Set the event buffer pointers to point into the allocated space we have been given, this ensures
* a flat memory layout necessary for usage in streaming snaphot. */
pxTraceMultiCoreEventBuffer->xEventBuffer[i] = (TraceEventBuffer_t*)(&puiBuffer[i * uiBufferSizePerCore]); /*cstat !MISRAC2004-11.4 !MISRAC2012-Rule-11.3 Suppress conversion between pointer types checks*/ /*cstat !MISRAC2004-17.4_b We need to access a spcific point in the buffer*/
/* Initialize the event buffer structure with its memory buffer placed following its own structure data. */
/* We need to check this */
if (xTraceEventBufferInitialize(pxTraceMultiCoreEventBuffer->xEventBuffer[i], uiOptions,
&puiBuffer[(i * uiBufferSizePerCore) + sizeof(TraceEventBuffer_t)], /*cstat !MISRAC2004-17.4_b We need to access a specific point in the buffer*/
uiBufferSizePerCore - sizeof(TraceEventBuffer_t)) == TRC_FAIL)
{
return TRC_FAIL;
}
}
return TRC_SUCCESS;
}
#if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
/*cstat !MISRAC2012-Rule-5.1 Yes, these are long names*/
traceResult xTraceMultiCoreEventBufferAlloc(const TraceMultiCoreEventBuffer_t * const pxTraceMultiCoreEventBuffer, uint32_t uiSize,
void **ppvData)
{
/* This should never fail */
TRC_ASSERT(pxTraceMultiCoreEventBuffer != (void*)0);
TRC_ASSERT((TRC_CFG_GET_CURRENT_CORE()) < (TRC_CFG_CORE_COUNT));
return xTraceEventBufferAlloc(pxTraceMultiCoreEventBuffer->xEventBuffer[TRC_CFG_GET_CURRENT_CORE()], uiSize, ppvData);
}
/*cstat !MISRAC2012-Rule-5.1 Yes, these are long names*/
traceResult xTraceMultiCoreEventBufferAllocCommit(const TraceMultiCoreEventBuffer_t * const pxTraceMultiCoreEventBuffer, void *pvData, uint32_t uiSize, int32_t *piBytesWritten)
{
/* This should never fail */
TRC_ASSERT(pxTraceMultiCoreEventBuffer != (void*)0);
TRC_ASSERT((TRC_CFG_GET_CURRENT_CORE()) < (TRC_CFG_CORE_COUNT));
return xTraceEventBufferAllocCommit(pxTraceMultiCoreEventBuffer->xEventBuffer[TRC_CFG_GET_CURRENT_CORE()], pvData, uiSize, piBytesWritten);
}
traceResult xTraceMultiCoreEventBufferPush(const TraceMultiCoreEventBuffer_t* const pxTraceMultiCoreEventBuffer,
void* pvData, uint32_t uiSize, int32_t* piBytesWritten)
{
/* This should never fail */
TRC_ASSERT(pxTraceMultiCoreEventBuffer != (void*)0);
TRC_ASSERT((TRC_CFG_GET_CURRENT_CORE()) < (TRC_CFG_CORE_COUNT));
return xTraceEventBufferPush(pxTraceMultiCoreEventBuffer->xEventBuffer[TRC_CFG_GET_CURRENT_CORE()], pvData, uiSize, piBytesWritten);
}
#endif
/*cstat !MISRAC2012-Rule-5.1 Yes, these are long names*/
traceResult xTraceMultiCoreEventBufferTransferAll(const TraceMultiCoreEventBuffer_t* const pxTraceMultiCoreEventBuffer, int32_t* piBytesWritten)
{
int32_t iBytesWritten = 0;
uint32_t uiCoreId;
/* This should never fail */
TRC_ASSERT(pxTraceMultiCoreEventBuffer != (void*)0);
/* This should never fail */
TRC_ASSERT(piBytesWritten != (void*)0);
*piBytesWritten = 0;
for (uiCoreId = 0u; uiCoreId < (uint32_t)(TRC_CFG_CORE_COUNT); uiCoreId++)
{
/* We need to check this */
if (xTraceEventBufferTransferAll(pxTraceMultiCoreEventBuffer->xEventBuffer[uiCoreId], &iBytesWritten) == TRC_FAIL)
{
return TRC_FAIL;
}
*piBytesWritten += iBytesWritten;
}
return TRC_SUCCESS;
}
/*cstat !MISRAC2012-Rule-5.1 Yes, these are long names*/
traceResult xTraceMultiCoreEventBufferTransferChunk(const TraceMultiCoreEventBuffer_t* const pxTraceMultiCoreEventBuffer, uint32_t uiChunkSize, int32_t* piBytesWritten)
{
int32_t iBytesWritten = 0;
uint32_t uiCoreId;
/* This should never fail */
TRC_ASSERT(pxTraceMultiCoreEventBuffer != (void*)0);
/* This should never fail */
TRC_ASSERT(piBytesWritten != (void*)0);
*piBytesWritten = 0;
for (uiCoreId = 0u; uiCoreId < (uint32_t)(TRC_CFG_CORE_COUNT); uiCoreId++)
{
/* We need to check this */
if (xTraceEventBufferTransferChunk(pxTraceMultiCoreEventBuffer->xEventBuffer[uiCoreId], uiChunkSize, &iBytesWritten) == TRC_FAIL)
{
return TRC_FAIL;
}
*piBytesWritten += iBytesWritten;
}
return TRC_SUCCESS;
}
traceResult xTraceMultiCoreEventBufferClear(const TraceMultiCoreEventBuffer_t* const pxTraceMultiCoreEventBuffer)
{
uint32_t uiCoreId;
/* This should never fail */
TRC_ASSERT(pxTraceMultiCoreEventBuffer != (void*)0);
for (uiCoreId = 0u; uiCoreId < (uint32_t)(TRC_CFG_CORE_COUNT); uiCoreId++)
{
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEventBufferClear(pxTraceMultiCoreEventBuffer->xEventBuffer[uiCoreId]) == TRC_SUCCESS);
}
return TRC_SUCCESS;
}
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */

View File

@@ -0,0 +1,310 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation for strings.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#ifndef TRC_SEND_NAME_ONLY_ON_DELETE
#define TRC_SEND_NAME_ONLY_ON_DELETE 0
#endif
traceResult prvTraceObjectSendNameEvent(void* pvObject, const char* szName, uint32_t uiLength);
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceObjectRegisterInternal(uint32_t uiEventCode, void* const pvObject, const char* szName, TraceUnsignedBaseType_t uxStateCount, const TraceUnsignedBaseType_t uxStates[], TraceUnsignedBaseType_t uxOptions, TraceObjectHandle_t* pxObjectHandle)
{
TraceEntryHandle_t xEntryHandle;
TraceEventHandle_t xEventHandle = 0;
TraceUnsignedBaseType_t i;
void *pvAddress;
TRACE_ALLOC_CRITICAL_SECTION();
/* This should never fail */
TRC_ASSERT(pxObjectHandle != (void*)0);
/* This should never fail */
TRC_ASSERT(uxStateCount <= (uint32_t)(TRC_ENTRY_TABLE_STATE_COUNT));
TRACE_ENTER_CRITICAL_SECTION();
if (pvObject != (void*)0)
{
/* An address was supplied */
if (xTraceEntryCreateWithAddress(pvObject, &xEntryHandle) == TRC_FAIL)
{
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
pvAddress = pvObject;
}
else
{
/* No address was supplied */
if (xTraceEntryCreate(&xEntryHandle) == TRC_FAIL)
{
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetAddress(xEntryHandle, &pvAddress) == TRC_SUCCESS);
}
for (i = 0u; i < uxStateCount; i++)
{
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xEntryHandle, (uint32_t)i, uxStates[i]) == TRC_SUCCESS);
}
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetOptions(xEntryHandle, (uint32_t)uxOptions) == TRC_SUCCESS);
*pxObjectHandle = (TraceObjectHandle_t)xEntryHandle;
TRACE_EXIT_CRITICAL_SECTION();
if ((szName != (void*)0) && (szName[0] != (char)0)) /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/ /*cstat !MISRAC2004-17.4_b We need to access every character in the string*/
{
/* Not a null or empty string */
/* This will set the symbol and create an event for it */
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceObjectSetName((TraceObjectHandle_t)xEntryHandle, szName) == TRC_SUCCESS);
}
/* Send the create event, if possible */
/*We need to check this */
if (xTraceEventBegin(uiEventCode, sizeof(void*) + (uxStateCount * sizeof(TraceUnsignedBaseType_t)), &xEventHandle) == TRC_SUCCESS)
{
(void)xTraceEventAddPointer(xEventHandle, pvAddress);
for (i = 0u; i < uxStateCount; i++)
{
(void)xTraceEventAddUnsignedBaseType(xEventHandle, uxStates[i]);
}
(void)xTraceEventEnd(xEventHandle); /*cstat !MISRAC2012-Rule-17.7 Suppress ignored return value check (inside macro)*/
}
return TRC_SUCCESS;
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceObjectRegister(uint32_t uiEventCode, void* const pvObject, const char* szName, TraceUnsignedBaseType_t uxState, TraceObjectHandle_t *pxObjectHandle)
{
return xTraceObjectRegisterInternal(uiEventCode, pvObject, szName, 1u, &uxState, 0u, pxObjectHandle);
}
traceResult xTraceObjectUnregister(TraceObjectHandle_t xObjectHandle, uint32_t uiEventCode, TraceUnsignedBaseType_t uxState)
{
void* pvObject = (void*)0;
const char *szName = (void*)0; /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
#if (TRC_SEND_NAME_ONLY_ON_DELETE == 1)
uint32_t uiLength;
uint32_t i;
#endif
/* If asserts are disabled this variable will not get used, this stops warnings. */
(void)szName;
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetAddress((TraceEntryHandle_t)xObjectHandle, &pvObject) == TRC_SUCCESS);
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetSymbol((TraceEntryHandle_t)xObjectHandle, &szName) == TRC_SUCCESS);
#if (TRC_SEND_NAME_ONLY_ON_DELETE == 1)
/* Send name event because this is a delete */
for (i = 0u; (szName[i] != (char)0) && (i < 128u); i++) {} /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/ /*cstat !MISRAC2004-17.4_b We need to access every character in the string*/
uiLength = i;
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(prvTraceObjectSendNameEvent(pvObject, szName, uiLength) == TRC_SUCCESS);
#endif /* (TRC_SEND_NAME_ONLY_ON_DELETE == 1) */
/* Send the delete event, if possible */
(void)xTraceEventCreate2(uiEventCode, (TraceUnsignedBaseType_t)(pvObject), uxState); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 !MISRAC2012-Rule-11.6 Suppress conversion from pointer to integer check*/
return xTraceEntryDelete(xObjectHandle);
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceObjectSetName(TraceObjectHandle_t xObjectHandle, const char* szName)
{
void* pvObject = (void*)0;
uint32_t uiLength;
uint32_t i;
/* If asserts are disabled this variable will not get used, this stops warnings. */
(void)pvObject;
if (szName == (void*)0)
{
szName = ""; /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
}
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetAddress((TraceEntryHandle_t)xObjectHandle, &pvObject) == TRC_SUCCESS);
for (i = 0u; (szName[i] != (char)0) && (i < 128u); i++) {} /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/ /*cstat !MISRAC2004-17.4_b We need to access every character in the string*/
uiLength = i;
#if (TRC_SEND_NAME_ONLY_ON_DELETE == 0)
/* Send name event now since we don't do it on delete events */
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(prvTraceObjectSendNameEvent(pvObject, szName, uiLength) == TRC_SUCCESS);
#endif /* (TRC_SEND_NAME_ONLY_ON_DELETE == 0) */
return xTraceEntrySetSymbol((TraceEntryHandle_t)xObjectHandle, szName, uiLength);
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceObjectRegisterWithoutHandle(uint32_t uiEventCode, void* pvObject, const char* szName, TraceUnsignedBaseType_t uxState)
{
TraceObjectHandle_t xObjectHandle;
return xTraceObjectRegister(uiEventCode, pvObject, szName, uxState, &xObjectHandle);
}
traceResult xTraceObjectUnregisterWithoutHandle(uint32_t uiEventCode, void* pvObject, TraceUnsignedBaseType_t uxState)
{
TraceEntryHandle_t xEntryHandle;
traceResult xResult;
TRACE_ALLOC_CRITICAL_SECTION();
TRACE_ENTER_CRITICAL_SECTION();
if (xTraceEntryFind(pvObject, &xEntryHandle) == TRC_FAIL)
{
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
xResult = xTraceObjectUnregister((TraceObjectHandle_t)xEntryHandle, uiEventCode, uxState);
TRACE_EXIT_CRITICAL_SECTION();
return xResult;
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceObjectSetNameWithoutHandle(void* pvObject, const char* szName)
{
TraceEntryHandle_t xEntryHandle;
traceResult xResult;
TRACE_ALLOC_CRITICAL_SECTION();
TRACE_ENTER_CRITICAL_SECTION();
if (xTraceEntryFind(pvObject, &xEntryHandle) == TRC_FAIL)
{
/* No previous entry found. Create one. */
if (xTraceEntryCreateWithAddress(pvObject, &xEntryHandle) == TRC_FAIL)
{
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
}
xResult = xTraceObjectSetName((TraceObjectHandle_t)xEntryHandle, szName);
TRACE_EXIT_CRITICAL_SECTION();
return xResult;
}
traceResult xTraceObjectSetSpecificStateWithoutHandle(void* pvObject, uint32_t uiIndex, TraceUnsignedBaseType_t uxState)
{
TraceEntryHandle_t xEntryHandle;
traceResult xResult;
TRACE_ALLOC_CRITICAL_SECTION();
TRACE_ENTER_CRITICAL_SECTION();
if (xTraceEntryFind(pvObject, &xEntryHandle) == TRC_FAIL)
{
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
xResult = xTraceObjectSetSpecificState((TraceObjectHandle_t)xEntryHandle, uiIndex, uxState);
TRACE_EXIT_CRITICAL_SECTION();
return xResult;
}
traceResult xTraceObjectSetOptionsWithoutHandle(void* pvObject, uint32_t uiMask)
{
TraceEntryHandle_t xEntryHandle;
traceResult xResult;
TRACE_ALLOC_CRITICAL_SECTION();
TRACE_ENTER_CRITICAL_SECTION();
if (xTraceEntryFind(pvObject, &xEntryHandle) == TRC_FAIL)
{
/* No previous entry found. Create one. */
if (xTraceEntryCreateWithAddress(pvObject, &xEntryHandle) == TRC_FAIL)
{
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
}
xResult = xTraceObjectSetOptions((TraceObjectHandle_t)xEntryHandle, uiMask);
TRACE_EXIT_CRITICAL_SECTION();
return xResult;
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult prvTraceObjectSendNameEvent(void* const pvObject, const char* szName, uint32_t uiLength)
{
uint32_t uiValue = 0u;
TraceEventHandle_t xEventHandle = 0;
if (xTraceEventBegin(PSF_EVENT_OBJ_NAME, sizeof(void*) + uiLength, &xEventHandle) == TRC_SUCCESS)
{
(void)xTraceEventAddPointer(xEventHandle, pvObject);
(void)xTraceEventAddString(xEventHandle, szName, uiLength);
/* Check if we can truncate */
(void)xTraceEventPayloadRemaining(xEventHandle, &uiValue);
if (uiValue > 0u)
{
(void)xTraceEventAdd8(xEventHandle, 0u);
}
(void)xTraceEventEnd(xEventHandle); /*cstat !MISRAC2012-Rule-17.7 Suppress ignored return value check (inside macro)*/
}
return TRC_SUCCESS;
}
#endif
#endif

View File

@@ -0,0 +1,295 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation for print.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#if (TRC_CFG_INCLUDE_USER_EVENTS == 1)
#include <stdarg.h>
static traceResult prvTraceVPrintF(const TraceStringHandle_t xChannel, const char* szFormat, uint32_t uiLength, uint32_t uiArgs, va_list* pxVariableList);
static TracePrintData_t *pxPrintData TRC_CFG_RECORDER_DATA_ATTRIBUTE;
traceResult xTracePrintInitialize(TracePrintData_t *pxBuffer)
{
/* This should never fail */
TRC_ASSERT(pxBuffer != (void*)0);
pxPrintData = pxBuffer;
pxPrintData->defaultChannel = 0;
pxPrintData->consoleChannel = 0;
xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_PRINT);
return TRC_SUCCESS;
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTracePrint(TraceStringHandle_t xChannel, const char* szString)
{
uint32_t uiLength;
uint32_t i;
/* We need to check this */
if (xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_PRINT) == 0U)
{
return TRC_FAIL;
}
if (szString == (void*)0)
{
szString = ""; /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
}
for (i = 0u; (szString[i] != (char)0) && (i < 128u); i++) {} /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress char base type usage checks*/ /*cstat !MISRAC2004-17.4_b We need to access every character in the string*/
uiLength = i + 1u; /* Null termination */
return prvTraceVPrintF(xChannel, szString, uiLength, 0u, (va_list*)0); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 Suppress conversion of pointer to integer check*/ /*cstat !MISRAC2012-Rule-11.9 Suppress NULL recommendation*/
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/ /*cstat !MISRAC2004-16.1 Suppress variable parameter count check*/
traceResult xTraceConsoleChannelPrintF(const char* szFormat, ...)
{
traceResult xResult;
va_list xVariableList; /*cstat !MISRAC2012-Rule-17.1 Suppress stdarg usage check*/
/* We need to check this */
if (xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_PRINT) == 0U)
{
return TRC_FAIL;
}
if (pxPrintData->consoleChannel == 0)
{
if (xTraceStringRegister("Debug Console", &pxPrintData->consoleChannel) == TRC_FAIL)
{
return TRC_FAIL;
}
}
va_start(xVariableList, szFormat);
xResult = xTraceVPrintF(pxPrintData->consoleChannel, szFormat, &xVariableList);
va_end(xVariableList);
return xResult;
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/ /*cstat !MISRAC2004-16.1 Suppress variable parameter count check*/
traceResult xTracePrintCompactF(const char* szChannel, const char* szFormat, ...)
{
uint32_t i;
uint32_t uiArgs = 0u;
traceResult xResult;
va_list xVariableList; /*cstat !MISRAC2012-Rule-17.1 Suppress stdarg usage check*/
TraceUnsignedBaseType_t uxArg1, uxArg2, uxArg3, uxArg4;
/* We need to check this */
if (xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_PRINT) == 0U)
{
return TRC_FAIL;
}
if (szFormat == (void*)0)
{
szFormat = ""; /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
}
/* Count the number of arguments in the format string (e.g., %d) */
for (i = 0u; (szFormat[i] != (char)0) && (i < 128u); i++) /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress char base type usage checks*/ /*cstat !MISRAC2012-Rule-14.2 Suppress malformed for loop due to i being incremented inside*/ /*cstat !MISRAC2004-17.4_b We need to access every character in the string*/
{
if (szFormat[i] == '%') /*cstat !MISRAC2004-17.4_b We need to access a specific character in the string*/
{
if (szFormat[i + 1u] == (char)0) /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/ /*cstat !MISRAC2004-17.4_b We need to access a specific character in the string*/
{
/* Found end of string, let for loop detect it */
continue; /*cstat !MISRAC2004-14.5 Suppress continue usage check*/
}
if (szFormat[i + 1u] != '%') /*cstat !MISRAC2004-17.4_b We need to access a specific character in the string*/
{
uiArgs++; /* Found an argument */
}
/* Move past format specifier or non-argument '%' */
i++; /*cstat !MISRAC2004-13.6 Suppress i increment inside for loop check*/
}
}
va_start(xVariableList, szFormat);
switch(uiArgs)
{
case 0:
xResult = xTraceEventCreate2(PSF_EVENT_USER_EVENT_FIXED, (TraceUnsignedBaseType_t)szChannel, (TraceUnsignedBaseType_t)szFormat); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 We need the addresses*/
break;
case 1:
uxArg1 = va_arg(xVariableList, TraceUnsignedBaseType_t);
xResult = xTraceEventCreate3(PSF_EVENT_USER_EVENT_FIXED + 1UL, (TraceUnsignedBaseType_t)szChannel, (TraceUnsignedBaseType_t)szFormat, uxArg1); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 We need the addresses*/
break;
case 2:
uxArg1 = va_arg(xVariableList, TraceUnsignedBaseType_t);
uxArg2 = va_arg(xVariableList, TraceUnsignedBaseType_t);
xResult = xTraceEventCreate4(PSF_EVENT_USER_EVENT_FIXED + 2UL, (TraceUnsignedBaseType_t)szChannel, (TraceUnsignedBaseType_t)szFormat, uxArg1, uxArg2); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 We need the addresses*/
break;
case 3:
uxArg1 = va_arg(xVariableList, TraceUnsignedBaseType_t);
uxArg2 = va_arg(xVariableList, TraceUnsignedBaseType_t);
uxArg3 = va_arg(xVariableList, TraceUnsignedBaseType_t);
xResult = xTraceEventCreate5(PSF_EVENT_USER_EVENT_FIXED + 3UL, (TraceUnsignedBaseType_t)szChannel, (TraceUnsignedBaseType_t)szFormat, uxArg1, uxArg2, uxArg3); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 We need the addresses*/
break;
case 4:
uxArg1 = va_arg(xVariableList, TraceUnsignedBaseType_t);
uxArg2 = va_arg(xVariableList, TraceUnsignedBaseType_t);
uxArg3 = va_arg(xVariableList, TraceUnsignedBaseType_t);
uxArg4 = va_arg(xVariableList, TraceUnsignedBaseType_t);
xResult = xTraceEventCreate6(PSF_EVENT_USER_EVENT_FIXED + 4UL, (TraceUnsignedBaseType_t)szChannel, (TraceUnsignedBaseType_t)szFormat, uxArg1, uxArg2, uxArg3, uxArg4); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 We need the addresses*/
break;
default:
xResult = TRC_FAIL;
break;
}
va_end(xVariableList);
return xResult;
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/ /*cstat !MISRAC2004-16.1 Suppress variable parameter count check*/
traceResult xTracePrintF(TraceStringHandle_t xChannel, const char* szFormat, ...)
{
traceResult xResult;
va_list xVariableList; /*cstat !MISRAC2012-Rule-17.1 Suppress stdarg usage check*/
/* We need to check this */
if (xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_PRINT) == 0U)
{
return TRC_FAIL;
}
va_start(xVariableList, szFormat);
xResult = xTraceVPrintF(xChannel, szFormat, &xVariableList);
va_end(xVariableList);
return xResult;
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/ /*cstat !MISRAC2012-Rule-17.1 Suppress stdarg usage check*/
traceResult xTraceVPrintF(TraceStringHandle_t xChannel, const char* szFormat, va_list* pxVariableList)
{
uint32_t i;
uint32_t uiArgs = 0u;
uint32_t uiLength;
/* We need to check this */
if (xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_PRINT) == 0U)
{
return TRC_FAIL;
}
if (szFormat == (void*)0)
{
szFormat = ""; /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
}
/* Count the number of arguments in the format string (e.g., %d) */
for (i = 0u; (szFormat[i] != (char)0) && (i < 128u); i++) /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress char base type usage checks*/ /*cstat !MISRAC2012-Rule-14.2 Suppress malformed for loop due to i being incremented inside*/ /*cstat !MISRAC2004-17.4_b We need to access every character in the string*/
{
if (szFormat[i] == '%') /*cstat !MISRAC2004-17.4_b We need to access a specific character in the string*/
{
if (szFormat[i + 1u] == (char)0) /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/ /*cstat !MISRAC2004-17.4_b We need to access a specific character in the string*/
{
/* Found end of string, let for loop detect it */
continue; /*cstat !MISRAC2004-14.5 Suppress continue usage check*/
}
if (szFormat[i + 1u] != '%') /*cstat !MISRAC2004-17.4_b We need to access a specific character in the string*/
{
uiArgs++; /* Found an argument */
}
/* Move past format specifier or non-argument '%' */
i++; /*cstat !MISRAC2004-13.6 Suppress i increment inside for loop check*/
}
}
uiLength = i + 1u; /* Null termination */
return prvTraceVPrintF(xChannel, szFormat, uiLength, uiArgs, pxVariableList);
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/ /*cstat !MISRAC2012-Rule-17.1 Suppress stdarg usage check*/
static traceResult prvTraceVPrintF(TraceStringHandle_t xChannel, const char* szFormat, uint32_t uiLength, uint32_t uiArgs, va_list* pxVariableList)
{
TraceEventHandle_t xEventHandle = 0;
uint32_t i, uiRemaining = 0u;
uint32_t uiValue = 0u;
const uint32_t uiEventCode = PSF_EVENT_USER_EVENT + 1u + uiArgs; /* Add channel (1) */
const uint32_t uiSize = sizeof(void*) + (uiArgs * sizeof(TraceUnsignedBaseType_t)) + uiLength; /* Add channel (sizeof(void*)) */
if (xChannel == 0)
{
if (pxPrintData->defaultChannel == 0)
{
/* Channel is not present */
if (xTraceStringRegister("Default", &pxPrintData->defaultChannel) == TRC_FAIL)
{
return TRC_FAIL;
}
}
xChannel = pxPrintData->defaultChannel; /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
}
/* Added channel to uiEventCode and uiSize */
if (xTraceEventBegin(uiEventCode, uiSize , &xEventHandle) == TRC_FAIL)
{
return TRC_FAIL;
}
/* Add xChannel */
(void)xTraceEventAddPointer(xEventHandle, (void*)xChannel);
/* Add all arguments */
for (i = 0u; i < uiArgs; i++)
{
(void)xTraceEventAddUnsignedBaseType(xEventHandle, va_arg(*pxVariableList, TraceUnsignedBaseType_t));
}
(void)xTraceEventPayloadRemaining(xEventHandle, &uiRemaining);
if (uiRemaining < uiLength)
{
uiLength = uiRemaining - 1u; /* Make room for null termination */ /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
}
/* Add format string */
(void)xTraceEventAddString(xEventHandle, szFormat, uiLength);
/* Check if we can truncate */
(void)xTraceEventPayloadRemaining(xEventHandle, &uiValue);
if (uiValue > 0u)
{
(void)xTraceEventAdd8(xEventHandle, 0u);
}
(void)xTraceEventEnd(xEventHandle); /*cstat !MISRAC2012-Rule-17.7 Suppress ignored return value check (inside macro)*/
return TRC_SUCCESS;
}
#endif
#endif
#endif

View File

@@ -0,0 +1,94 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation for strings.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#define TRC_RUNNABLE_STATE_INDEX_OWNER_TASK 0UL
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceRunnableRegister(const char* szName, TraceRunnableRegisterMethod_t uxRegisterMethod, TraceRunnableHandle_t *pxRunnableHandle)
{
TraceEntryHandle_t xEntryHandle;
TraceEventHandle_t xEventHandle = 0;
int32_t i;
uint32_t uiLength, uiValue = 0u;
/* This should never fail */
TRC_ASSERT(szName != (void*)0);
/* This should never fail */
TRC_ASSERT(pxRunnableHandle != (void*)0);
for (i = 0; (szName[i] != (char)0) && (i < (int32_t)(TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE)); i++) {} /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/ /*cstat !MISRAC2004-17.4_b We need to access every character in the string*/
uiLength = (uint32_t)i;
if (uxRegisterMethod == TRC_RUNNABLE_REGISTER_METHOD_USE_ENTRY_TABLE)
{
/* Check if we have already created an entry previously */
if (*pxRunnableHandle == (void*)0)
{
/* We need to check this */
if (xTraceEntryCreate(&xEntryHandle) == TRC_FAIL)
{
return TRC_FAIL;
}
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetOptions(xEntryHandle, TRC_ENTRY_OPTION_RUNNABLE) == TRC_SUCCESS);
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xEntryHandle, TRC_RUNNABLE_STATE_INDEX_OWNER_TASK, (TraceUnsignedBaseType_t)xTraceTaskGetCurrentReturn()) == TRC_SUCCESS); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 !MISRAC2012-Rule-11.6 We need the address of the task*/
/* The address to the available symbol table slot is the address we use */
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetSymbol(xEntryHandle, szName, uiLength) == TRC_SUCCESS);
*pxRunnableHandle = (TraceRunnableHandle_t)xEntryHandle;
}
}
else if (uxRegisterMethod == TRC_RUNNABLE_REGISTER_METHOD_USE_STRING_ADDRESS)
{
*pxRunnableHandle = (TraceRunnableHandle_t)szName; /*cstat !MISRAC2004-11.5 !MISRAC2012-Rule-11.8 We need the address of the string*/
}
else if (uxRegisterMethod == TRC_RUNNABLE_REGISTER_METHOD_USE_HANDLE_ADDRESS)
{
/* The handle address should be a unique value that we can use as handle */
*pxRunnableHandle = (TraceRunnableHandle_t)pxRunnableHandle;
}
else
{
return TRC_FAIL;
}
/* We need to check this */
if (xTraceEventBegin(PSF_EVENT_RUNNABLE_REGISTER, sizeof(void*) + uiLength, &xEventHandle) == TRC_SUCCESS)
{
(void)xTraceEventAddPointer(xEventHandle, (void*)*pxRunnableHandle);
(void)xTraceEventAddString(xEventHandle, szName, uiLength);
/* Check if we can truncate */
(void)xTraceEventPayloadRemaining(xEventHandle, &uiValue);
if (uiValue > 0u)
{
(void)xTraceEventAdd8(xEventHandle, 0u);
}
(void)xTraceEventEnd(xEventHandle); /*cstat !MISRAC2012-Rule-17.7 Suppress ignored return value check (inside macro)*/
}
return TRC_SUCCESS;
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,211 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation for the stack monitor.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#if (((TRC_CFG_ENABLE_STACK_MONITOR) == 1) && ((TRC_CFG_SCHEDULING_ONLY) == 0))
#ifndef TRC_CFG_ALLOW_TASK_DELETE
#define TRC_CFG_ALLOW_TASK_DELETE 1
#endif
static TraceStackMonitorData_t* pxStackMonitor TRC_CFG_RECORDER_DATA_ATTRIBUTE;
traceResult xTraceStackMonitorInitialize(TraceStackMonitorData_t *pxBuffer)
{
uint32_t i;
/* This should never fail */
TRC_ASSERT(pxBuffer != 0);
pxStackMonitor = pxBuffer;
pxStackMonitor->uxEntryCount = 0;
for (i = 0; i < (TRC_CFG_STACK_MONITOR_MAX_TASKS); i++)
{
pxStackMonitor->xEntries[i].pvTask = 0;
}
xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_STACK_MONITOR);
return TRC_SUCCESS;
}
traceResult xTraceStackMonitorAdd(void *pvTask)
{
TraceUnsignedBaseType_t uxLowMark = 0;
TRACE_ALLOC_CRITICAL_SECTION();
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_STACK_MONITOR));
if (pvTask == 0)
{
/* We don't add null addresses */
return TRC_FAIL;
}
TRACE_ENTER_CRITICAL_SECTION();
if (pxStackMonitor->uxEntryCount >= (TRC_CFG_STACK_MONITOR_MAX_TASKS))
{
xTraceDiagnosticsIncrease(TRC_DIAGNOSTICS_STACK_MONITOR_NO_SLOTS);
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
if (xTraceKernelPortGetUnusedStack(pvTask, &uxLowMark) == TRC_SUCCESS)
{
pxStackMonitor->xEntries[pxStackMonitor->uxEntryCount].pvTask = pvTask;
pxStackMonitor->xEntries[pxStackMonitor->uxEntryCount].uxPreviousLowWaterMark = uxLowMark;
pxStackMonitor->uxEntryCount++;
}
TRACE_EXIT_CRITICAL_SECTION();
return TRC_SUCCESS;
}
traceResult xTraceStackMonitorRemove(void* pvTask)
{
uint32_t i;
TRACE_ALLOC_CRITICAL_SECTION();
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_STACK_MONITOR));
if (pvTask == 0)
{
/* We don't add null addresses */
return TRC_FAIL;
}
TRACE_ENTER_CRITICAL_SECTION();
for (i = 0; i < pxStackMonitor->uxEntryCount; i++)
{
if (pxStackMonitor->xEntries[i].pvTask == pvTask)
{
if (pxStackMonitor->uxEntryCount > 1 && i != (pxStackMonitor->uxEntryCount - 1))
{
/* There are more entries and this is NOT the last entry. Move last entry to this slot. */
pxStackMonitor->xEntries[i].pvTask = pxStackMonitor->xEntries[pxStackMonitor->uxEntryCount - 1].pvTask;
pxStackMonitor->xEntries[i].uxPreviousLowWaterMark = pxStackMonitor->xEntries[pxStackMonitor->uxEntryCount - 1].uxPreviousLowWaterMark;
/* Clear old entry that was moved */
pxStackMonitor->xEntries[pxStackMonitor->uxEntryCount - 1].pvTask = 0;
pxStackMonitor->xEntries[pxStackMonitor->uxEntryCount - 1].uxPreviousLowWaterMark = 0;
}
else
{
/* No other entries or last entry. */
pxStackMonitor->xEntries[i].pvTask = 0;
pxStackMonitor->xEntries[i].uxPreviousLowWaterMark = 0;
}
pxStackMonitor->uxEntryCount--;
TRACE_EXIT_CRITICAL_SECTION();
return TRC_SUCCESS;
}
}
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
traceResult xTraceStackMonitorGetAtIndex(uint32_t uiIndex, void **ppvTask, TraceUnsignedBaseType_t *puxLowWaterMark)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_STACK_MONITOR));
/* This should never fail */
TRC_ASSERT(ppvTask != 0);
/* This should never fail */
TRC_ASSERT(puxLowWaterMark != 0);
/* This should never fail */
TRC_ASSERT(uiIndex < (TRC_CFG_STACK_MONITOR_MAX_TASKS));
*ppvTask = pxStackMonitor->xEntries[uiIndex].pvTask;
*puxLowWaterMark = pxStackMonitor->xEntries[uiIndex].uxPreviousLowWaterMark;
return TRC_SUCCESS;
}
traceResult xTraceStackMonitorReport(void)
{
TraceUnsignedBaseType_t uxLowWaterMark = 0;
TraceStackMonitorEntry_t *pxStackMonitorEntry;
TraceUnsignedBaseType_t uxToReport;
TraceUnsignedBaseType_t i;
static uint32_t uiCurrentIndex = 0;
#if (TRC_CFG_ALLOW_TASK_DELETE == 1)
TRACE_ALLOC_CRITICAL_SECTION();
#endif
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_STACK_MONITOR));
#if (TRC_CFG_ALLOW_TASK_DELETE == 1)
TRACE_ENTER_CRITICAL_SECTION();
#endif
/* Never report more than there are entries */
uxToReport = TRC_CFG_STACK_MONITOR_MAX_REPORTS <= pxStackMonitor->uxEntryCount ? TRC_CFG_STACK_MONITOR_MAX_REPORTS : pxStackMonitor->uxEntryCount;
for (i = 0; i < uxToReport; i++)
{
/* If uiCurrentIndex is too large, reset it */
uiCurrentIndex = uiCurrentIndex < pxStackMonitor->uxEntryCount ? uiCurrentIndex : 0;
pxStackMonitorEntry = &pxStackMonitor->xEntries[uiCurrentIndex];
if (xTraceKernelPortGetUnusedStack(pxStackMonitorEntry->pvTask, &uxLowWaterMark) != TRC_SUCCESS)
{
uiCurrentIndex++;
continue;
}
if (uxLowWaterMark < pxStackMonitorEntry->uxPreviousLowWaterMark)
{
pxStackMonitorEntry->uxPreviousLowWaterMark = uxLowWaterMark;
}
xTraceEventCreate2(PSF_EVENT_UNUSED_STACK, (TraceUnsignedBaseType_t)pxStackMonitorEntry->pvTask, pxStackMonitorEntry->uxPreviousLowWaterMark);
uiCurrentIndex++;
}
#if (TRC_CFG_ALLOW_TASK_DELETE == 1)
TRACE_EXIT_CRITICAL_SECTION();
#endif
return TRC_SUCCESS;
}
#endif /* (((TRC_CFG_ENABLE_STACK_MONITOR) == 1) && ((TRC_CFG_SCHEDULING_ONLY) == 0)) */
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */

View File

@@ -0,0 +1,89 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation of state machines.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#define TRC_STATE_MACHINE_STATE_INDEX 0u
#define TRC_STATE_MACHINE_INDEX 0u
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceStateMachineCreate(const char *szName, TraceStateMachineHandle_t *pxStateMachineHandle)
{
TraceObjectHandle_t xObjectHandle;
/* This should never fail */
TRC_ASSERT(pxStateMachineHandle != (void*)0);
/* We need to check this */
if (xTraceObjectRegister(PSF_EVENT_STATEMACHINE_CREATE , (void*)0, szName, 0u, &xObjectHandle) == TRC_FAIL)
{
return TRC_FAIL;
}
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetOptions((TraceEntryHandle_t)xObjectHandle, (uint32_t)TRC_ENTRY_OPTION_STATE_MACHINE) == TRC_SUCCESS);
*pxStateMachineHandle = (TraceStateMachineHandle_t)xObjectHandle;
return TRC_SUCCESS;
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceStateMachineStateCreate(TraceStateMachineHandle_t xStateMachineHandle, const char* szName, TraceStateMachineStateHandle_t* pxStateHandle)
{
TraceObjectHandle_t xObjectHandle;
/* This should never fail */
TRC_ASSERT(xStateMachineHandle != 0);
/* This should never fail */
TRC_ASSERT(pxStateHandle != (void*)0);
/* We need to check this */
if (xTraceObjectRegister(PSF_EVENT_STATEMACHINE_STATE_CREATE, (void*)0, szName, (TraceUnsignedBaseType_t)xStateMachineHandle, &xObjectHandle) == TRC_FAIL) /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 Suppress conversion from pointer to integer check*/
{
return TRC_FAIL;
}
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetOptions((TraceEntryHandle_t)xObjectHandle, (uint32_t)TRC_ENTRY_OPTION_STATE_MACHINE_STATE) == TRC_SUCCESS);
*pxStateHandle = (TraceStateMachineHandle_t)xObjectHandle;
return TRC_SUCCESS;
}
traceResult xTraceStateMachineSetState(TraceStateMachineHandle_t xStateMachineHandle, TraceStateMachineStateHandle_t xStateHandle)
{
/* This should never fail */
TRC_ASSERT(xStateMachineHandle != 0);
/* This should never fail */
TRC_ASSERT(xStateHandle != 0);
/* Verify that this state machine state was meant to be used with this state machine */
/* This should never fail */
TRC_ASSERT(xStateMachineHandle == (TraceStateMachineHandle_t)xTraceEntryGetStateReturn((TraceEntryHandle_t)xStateHandle, TRC_STATE_MACHINE_INDEX));
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState((TraceEntryHandle_t)xStateMachineHandle, TRC_STATE_MACHINE_STATE_INDEX, (TraceUnsignedBaseType_t)xStateHandle) == TRC_SUCCESS); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 Suppress conversion from pointer to integer check*/
(void)xTraceEventCreate2(PSF_EVENT_STATEMACHINE_STATECHANGE, (TraceUnsignedBaseType_t)xStateMachineHandle, (TraceUnsignedBaseType_t)xStateHandle); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 Suppress conversion from pointer to integer check*/
return TRC_SUCCESS;
}
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */

View File

@@ -0,0 +1,55 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation for the static buffer.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
TraceStaticBufferTable_t *pxTraceStaticBufferTable TRC_CFG_RECORDER_DATA_ATTRIBUTE;
traceResult xTraceStaticBufferInitialize(TraceStaticBufferTable_t *pxBuffer)
{
/* This should never fail */
TRC_ASSERT(pxBuffer != (void*)0);
pxTraceStaticBufferTable = pxBuffer;
xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_STATIC_BUFFER);
return TRC_SUCCESS;
}
#if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
/* Returns a pointer to a maximum sized static buffer */
traceResult xTraceStaticBufferGet(void **ppvBuffer)
{
int32_t ISR_nesting;
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_STATIC_BUFFER));
TRC_ASSERT(ppvBuffer != (void*)0);
TRC_ASSERT(xTraceISRGetCurrentNesting(&ISR_nesting) == TRC_SUCCESS);
/* Task dummy events begin at 0, ISR dummy events begin at index 1 */
*ppvBuffer = (void*)&pxTraceStaticBufferTable->coreDummyEvents[TRC_CFG_GET_CURRENT_CORE()].dummyEvents[ISR_nesting + 1];
return TRC_SUCCESS;
}
#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */

View File

@@ -0,0 +1,707 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The generic core of the trace recorder's streaming mode.
*/
#include <trcRecorder.h>
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#ifndef TRC_KERNEL_PORT_HEAP_INIT
#define TRC_KERNEL_PORT_HEAP_INIT(__size)
#endif
/* Entry symbol length maximum check */
#if ((TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH) > 28UL)
#error Maximum entry symbol length is 28!
#endif
/* Entry symbol length minimum check */
#if ((TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH) < 4UL)
#error Minimum entry symbol length is 4!
#endif
typedef struct TraceHeader
{
uint32_t uiPSF;
uint16_t uiVersion;
uint16_t uiPlatform;
uint32_t uiOptions;
uint32_t uiNumCores;
uint32_t isrTailchainingThreshold;
uint16_t uiPlatformCfgPatch;
uint8_t uiPlatformCfgMinor;
uint8_t uiPlatformCfgMajor;
char platformCfg[8];
} TraceHeader_t;
/* The data structure for commands (a bit overkill) */
typedef struct TraceCommandType_t
{
unsigned char cmdCode;
unsigned char param1;
unsigned char param2;
unsigned char param3;
unsigned char param4;
unsigned char param5;
unsigned char checksumLSB;
unsigned char checksumMSB;
} TraceCommand_t;
#ifndef TRC_CFG_RECORDER_DATA_INIT
#define TRC_CFG_RECORDER_DATA_INIT 1
#endif
/* Used to interpret the data format */
#define TRACE_FORMAT_VERSION ((uint16_t)0x000E)
/* Used to determine endian of data (big/little) */
#define TRACE_PSF_ENDIANESS_IDENTIFIER ((uint32_t)0x50534600)
#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC)
static TraceRecorderData_t xRecorderData TRC_CFG_RECORDER_DATA_ATTRIBUTE; /*cstat !MISRAC2004-8.7 !MISRAC2012-Rule-8.9_a !MISRAC2012-Rule-8.9_b Suppress global variable check*/
TraceRecorderData_t* pxTraceRecorderData TRC_CFG_RECORDER_DATA_ATTRIBUTE;
#else
/* If using DYNAMIC or CUSTOM allocation */
TraceRecorderData_t* pxTraceRecorderData TRC_CFG_RECORDER_DATA_ATTRIBUTE;
#endif
static TraceHeader_t* pxHeader TRC_CFG_RECORDER_DATA_ATTRIBUTE; /*cstat !MISRAC2004-8.7 !MISRAC2012-Rule-8.9_a !MISRAC2012-Rule-8.9_b Suppress global variable check*/
/*******************************************************************************
* RecorderInitialized
*
* Makes sure the recorder data is only initialized once.
*
* NOTE: RecorderInitialized is only initialized to 0 if
* TRC_CFG_RECORDER_DATA_INIT is non-zero.
* This will avoid issues where the recorder must be started before main(),
* which can lead to RecorderInitialized be cleared by late initialization after
* xTraceEnable(TRC_INIT) was called and assigned RecorderInitialized its'
* value.
******************************************************************************/
#if (TRC_CFG_RECORDER_DATA_INIT != 0)
uint32_t RecorderInitialized = 0u;
#else /* (TRC_CFG_RECORDER_DATA_INIT != 0) */
uint32_t RecorderInitialized TRC_CFG_RECORDER_DATA_ATTRIBUTE;
#endif /* (TRC_CFG_RECORDER_DATA_INIT != 0) */
#if (TRC_EXTERNAL_BUFFERS == 0)
/* Stores the header information on Start */
static void prvTraceStoreHeader(void);
/* Store the Timestamp info */
static void prvTraceStoreTimestampInfo(void);
/* Stores the entry table on Start */
static void prvTraceStoreEntryTable(void);
#else /* (TRC_EXTERNAL_BUFFERS == 0) */
#define prvTraceStoreHeader()
#define prvTraceStoreTimestampInfo()
#define prvTraceStoreEntryTable()
#endif /* (TRC_EXTERNAL_BUFFERS == 0) */
/* Store start event. */
static void prvTraceStoreStartEvent(void);
/* Checks if the provided command is a valid command */
static int32_t prvIsValidCommand(const TraceCommand_t* const cmd);
/* Executed the received command (Start or Stop) */
static void prvProcessCommand(const TraceCommand_t* const cmd);
/* Internal function for starting the recorder */
static void prvSetRecorderEnabled(void);
/* Internal function for stopping the recorder */
static void prvSetRecorderDisabled(void);
static TraceUnsignedBaseType_t prvIs64bit(void);
/******************************************************************************
* xTraceInitialize
*
* Initializes the recorder data.
* This function will be called by xTraceEnable(...).
* Only needs to be called manually if traced objects are created before the
* trace recorder can be enabled, at which point make sure to call this function
* as early as possible.
* See TRC_CFG_RECORDER_DATA_INIT in trcConfig.h.
******************************************************************************/
traceResult xTraceInitialize(void)
{
TraceUnsignedBaseType_t i;
TRC_ASSERT_EQUAL_SIZE(TraceUnsignedBaseType_t, TraceBaseType_t);
/* TraceUnsignedBaseType_t is used to store handles (addresses) */
TRC_ASSERT_EQUAL_SIZE(TraceUnsignedBaseType_t, TraceHandleBaseType_t);
if (RecorderInitialized != 0u)
{
return TRC_SUCCESS;
}
TRC_PORT_SPECIFIC_INIT();
#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC)
pxTraceRecorderData = &xRecorderData;
#elif (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC)
/* Initialize heap */
TRC_KERNEL_PORT_HEAP_INIT(sizeof(TraceRecorderData_t));
/* Allocate data */
pxTraceRecorderData = TRC_KERNEL_PORT_HEAP_MALLOC(sizeof(TraceRecorderData_t));
#endif
/* These are set on init so they aren't overwritten by late initialization values. */
pxTraceRecorderData->uiSessionCounter = 0u;
pxTraceRecorderData->uiRecorderEnabled = 0u;
for (i = 0; i < TRC_CFG_CORE_COUNT; i++)
{
pxTraceRecorderData->uxTraceSystemStates[i] = (TraceUnsignedBaseType_t)TRC_STATE_IN_STARTUP;
}
/*cstat !MISRAC2004-13.7_b Suppress always false check*/
if (xTraceEntryIndexTableInitialize(&pxTraceRecorderData->xEntryIndexTableBuffer) == TRC_FAIL)
{
return TRC_FAIL;
}
#if (TRC_EXTERNAL_BUFFERS == 0)
if (xTraceHeaderInitialize(&pxTraceRecorderData->xHeaderBuffer) == TRC_FAIL)
{
return TRC_FAIL;
}
if (xTraceEntryTableInitialize(&pxTraceRecorderData->xEntryTable) == TRC_FAIL)
{
return TRC_FAIL;
}
if (xTraceTimestampInitialize(&pxTraceRecorderData->xTimestampBuffer) == TRC_FAIL)
{
return TRC_FAIL;
}
#endif
if (xTraceCounterInitialize(&pxTraceRecorderData->xCounterBuffer) == TRC_FAIL)
{
return TRC_FAIL;
}
/*cstat !MISRAC2004-13.7_b !MISRAC2012-Rule-14.3_b Suppress always false check*/
if (xTraceStackMonitorInitialize(&pxTraceRecorderData->xStackMonitorBuffer) == TRC_FAIL)
{
return TRC_FAIL;
}
/*cstat !MISRAC2004-13.7_b !MISRAC2012-Rule-14.3_b Suppress always false check*/
if (xTraceStreamPortInitialize(&pxTraceRecorderData->xStreamPortBuffer) == TRC_FAIL)
{
return TRC_FAIL;
}
if (xTraceAssertInitialize(&pxTraceRecorderData->xAssertBuffer) == TRC_FAIL)
{
return TRC_FAIL;
}
if (xTraceDiagnosticsInitialize(&pxTraceRecorderData->xDiagnosticsBuffer) == TRC_FAIL)
{
return TRC_FAIL;
}
/*cstat !MISRAC2004-13.7_b Suppress always false check*/
if (xTraceExtensionInitialize(&pxTraceRecorderData->xExtensionBuffer) == TRC_FAIL)
{
return TRC_FAIL;
}
if (xTraceStaticBufferInitialize(&pxTraceRecorderData->xStaticBufferBuffer) == TRC_FAIL)
{
return TRC_FAIL;
}
if (xTraceEventInitialize(&pxTraceRecorderData->xEventDataBuffer) == TRC_FAIL)
{
return TRC_FAIL;
}
if (xTracePrintInitialize(&pxTraceRecorderData->xPrintBuffer) == TRC_FAIL)
{
return TRC_FAIL;
}
if (xTraceErrorInitialize(&pxTraceRecorderData->xErrorBuffer) == TRC_FAIL)
{
return TRC_FAIL;
}
if (xTraceISRInitialize(&pxTraceRecorderData->xISRBuffer) == TRC_FAIL)
{
return TRC_FAIL;
}
if (xTraceTaskInitialize(&pxTraceRecorderData->xTaskInfoBuffer) == TRC_FAIL)
{
return TRC_FAIL;
}
/*cstat !MISRAC2004-13.7_b !MISRAC2012-Rule-14.3_b Suppress always false check*/
if (xTraceKernelPortInitialize(&pxTraceRecorderData->xKernelPortBuffer) == TRC_FAIL)
{
return TRC_FAIL;
}
pxTraceRecorderData->reserved = 0xFFFFFFFFUL;
(void)xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_CORE);
return TRC_SUCCESS;
}
/* Do this in function to avoid unreachable code warnings */
traceResult prvVerifySizeAlignment(uint32_t ulSize)
{
return (ulSize % sizeof(TraceUnsignedBaseType_t)) == 0 ? TRC_SUCCESS : TRC_FAIL;
}
traceResult xTraceHeaderInitialize(TraceHeaderBuffer_t *pxBuffer)
{
uint32_t i;
const char* platform_cfg = TRC_PLATFORM_CFG; /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
TRC_ASSERT_EQUAL_SIZE(TraceHeaderBuffer_t, TraceHeader_t);
if (pxBuffer == (void*)0)
{
return TRC_FAIL;
}
if (prvVerifySizeAlignment(sizeof(TraceStreamPortBuffer_t)) == TRC_FAIL)
{
/* TraceStreamPortBuffer_t size is not aligned to TraceUnsignedBaseType_t */
return TRC_FAIL;
}
if (prvVerifySizeAlignment(sizeof(TraceEventDataTable_t)) == TRC_FAIL)
{
/* TraceEventDataTable_t size is not aligned to TraceUnsignedBaseType_t */
return TRC_FAIL;
}
if (prvVerifySizeAlignment(sizeof(TraceKernelPortDataBuffer_t)) == TRC_FAIL)
{
/* TraceKernelPortDataBuffer_t size is not aligned to TraceUnsignedBaseType_t */
return TRC_FAIL;
}
pxHeader = (TraceHeader_t*)pxBuffer; /*cstat !MISRAC2004-11.4 !MISRAC2012-Rule-11.3 Suppress conversion between pointer types checks*/
pxHeader->uiPSF = TRACE_PSF_ENDIANESS_IDENTIFIER;
pxHeader->uiVersion = TRACE_FORMAT_VERSION;
pxHeader->uiPlatform = TRACE_KERNEL_VERSION;
for (i = 0u; i < (uint32_t)(TRC_PLATFORM_CFG_LENGTH); i++)
{
pxHeader->platformCfg[i] = platform_cfg[i]; /*cstat !MISRAC2004-17.4_b We need to access every character in the string*/
if (platform_cfg[i] == (char)0) /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/ /*cstat !MISRAC2004-17.4_b We need to access every character in the string*/
{
break;
}
}
pxHeader->uiPlatformCfgPatch = (uint16_t)TRC_PLATFORM_CFG_PATCH;
pxHeader->uiPlatformCfgMinor = (uint8_t)TRC_PLATFORM_CFG_MINOR;
pxHeader->uiPlatformCfgMajor = (uint8_t)TRC_PLATFORM_CFG_MAJOR;
pxHeader->uiNumCores = (uint32_t)TRC_CFG_CORE_COUNT;
#ifdef TRC_STREAM_PORT_MULTISTREAM_SUPPORT
pxHeader->uiNumCores |= 2 << 8;
#else
pxHeader->uiNumCores |= 3 << 8;
#endif
pxHeader->isrTailchainingThreshold = TRC_CFG_ISR_TAILCHAINING_THRESHOLD;
/* Lowest bit used for TRC_IRQ_PRIORITY_ORDER */
pxHeader->uiOptions = (((uint32_t)(TRC_IRQ_PRIORITY_ORDER)) << 0);
/* 3rd bit used for TRC_CFG_TEST_MODE */
pxHeader->uiOptions |= (((uint32_t)(TRC_CFG_TEST_MODE)) << 2);
/* 4th bit used for 64-bit*/
if (prvIs64bit()) /* Call helper function to avoid "unreachable code" */
{
pxHeader->uiOptions |= (1 << 3);
}
return TRC_SUCCESS;
}
traceResult xTraceEnable(uint32_t uiStartOption)
{
TraceCommand_t xCommand = { 0 };
int32_t iBytes;
if (xTraceInitialize() == TRC_FAIL)
{
return TRC_FAIL;
}
/*cstat !MISRAC2004-13.7_b !MISRAC2012-Rule-14.3_b Suppress always false check*/
if (xTraceStreamPortOnEnable(uiStartOption) == TRC_FAIL)
{
return TRC_FAIL;
}
/*cstat !MISRAC2004-13.7_b !MISRAC2012-Rule-14.3_b Suppress always false check*/
if (xTraceKernelPortEnable() == TRC_FAIL)
{
return TRC_FAIL;
}
if (uiStartOption == TRC_START_AWAIT_HOST)
{
/* We keep trying to read commands from host until the recorder has been started */
do
{
iBytes = 0;
if (xTraceStreamPortReadData(&xCommand, sizeof(TraceCommand_t), (int32_t*)&iBytes) == TRC_FAIL)
{
(void)xTraceWarning(TRC_WARNING_STREAM_PORT_READ);
}
if ((uint32_t)iBytes == sizeof(TraceCommand_t))
{
if (prvIsValidCommand(&xCommand) != 0)
{
prvProcessCommand(&xCommand);
}
}
} while (pxTraceRecorderData->uiRecorderEnabled == 0u);
}
else if (uiStartOption == (uint32_t)(TRC_START))
{
/* We start streaming directly - this assumes that the host interface is ready! */
xCommand.cmdCode = CMD_SET_ACTIVE;
xCommand.param1 = 1u;
prvProcessCommand(&xCommand);
}
else if (uiStartOption == TRC_START_FROM_HOST)
{
/* We prepare the system to receive commands from host, but let system resume execution until that happens */
}
else
{
return TRC_FAIL;
}
return TRC_SUCCESS;
}
traceResult xTraceDisable(void)
{
prvSetRecorderDisabled();
(void)xTraceStreamPortOnDisable();
return TRC_SUCCESS;
}
#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM)
traceResult xTraceSetBuffer(TraceRecorderData_t* pxBuffer)
{
if (pxBuffer == 0)
{
return TRC_FAIL;
}
pxTraceRecorderData = pxBuffer;
return TRC_SUCCESS;
}
#endif
traceResult xTraceGetEventBuffer(void **ppvBuffer, TraceUnsignedBaseType_t *puiSize)
{
if ((pxTraceRecorderData == (void*)0) || (ppvBuffer == (void*)0) || (puiSize == (void*)0))
{
return TRC_FAIL;
}
/* Returns the xStreamPortBuffer since that is the one containing trace data */
*ppvBuffer = (void*)&pxTraceRecorderData->xStreamPortBuffer;
*puiSize = sizeof(pxTraceRecorderData->xStreamPortBuffer);
return TRC_SUCCESS;
}
traceResult xTraceTzCtrl(void)
{
TraceCommand_t xCommand = { 0 };
int32_t iRxBytes;
do
{
/* Listen for new commands */
iRxBytes = 0;
if (xTraceStreamPortReadData(&xCommand, sizeof(TraceCommand_t), &iRxBytes) == TRC_FAIL)
{
/* The connection has failed, stop tracing */
(void)xTraceDisable();
return TRC_FAIL;
}
if ((uint32_t)iRxBytes == sizeof(TraceCommand_t))
{
if (prvIsValidCommand(&xCommand) != 0)
{
prvProcessCommand(&xCommand); /* Start or Stop currently... */
}
}
if (xTraceIsRecorderEnabled())
{
(void)xTraceInternalEventBufferTransfer();
}
/* If there was data sent or received (bytes != 0), loop around and repeat, if there is more data to send or receive.
Otherwise, step out of this loop and sleep for a while. */
} while (iRxBytes > 0);
if (xTraceIsRecorderEnabled())
{
(void)xTraceDiagnosticsCheckStatus();
(void)xTraceStackMonitorReport();
}
return TRC_SUCCESS;
}
void vTraceSetFilterGroup(uint16_t filterGroup)
{
(void)filterGroup;
}
void vTraceSetFilterMask(uint16_t filterMask)
{
(void)filterMask;
}
/******************************************************************************/
/*** INTERNAL FUNCTIONS *******************************************************/
/******************************************************************************/
static TraceUnsignedBaseType_t prvIs64bit(void)
{
return sizeof(TraceUnsignedBaseType_t) == 8;
}
/* Internal function for starting/stopping the recorder. */
static void prvSetRecorderEnabled(void)
{
TraceUnsignedBaseType_t uxTimestampFrequency = 0u;
uint32_t uiTimestampPeriod = 0u;
TRACE_ALLOC_CRITICAL_SECTION();
if (pxTraceRecorderData->uiRecorderEnabled == 1u)
{
return;
}
(void)xTraceTimestampGetFrequency(&uxTimestampFrequency);
/* If not overridden using xTraceTimestampSetFrequency(...), use default value */
if (uxTimestampFrequency == 0u)
{
(void)xTraceTimestampSetFrequency((TraceUnsignedBaseType_t)(TRC_HWTC_FREQ_HZ));
}
(void)xTraceTimestampGetPeriod(&uiTimestampPeriod);
/* If not overridden using xTraceTimestampSetPeriod(...), use default value */
if (uiTimestampPeriod == 0u)
{
(void)xTraceTimestampSetPeriod((TraceUnsignedBaseType_t)(TRC_HWTC_PERIOD));
}
TRACE_ENTER_CRITICAL_SECTION();
/* If the internal event buffer is used, we must clear it */
(void)xTraceInternalEventBufferClear();
(void)xTraceStreamPortOnTraceBegin();
prvTraceStoreHeader();
prvTraceStoreTimestampInfo();
prvTraceStoreEntryTable();
prvTraceStoreStartEvent();
pxTraceRecorderData->uiSessionCounter++;
pxTraceRecorderData->uiRecorderEnabled = 1u;
TRACE_EXIT_CRITICAL_SECTION();
}
static void prvSetRecorderDisabled(void)
{
TRACE_ALLOC_CRITICAL_SECTION();
if (pxTraceRecorderData->uiRecorderEnabled == 0u)
{
return;
}
TRACE_ENTER_CRITICAL_SECTION();
pxTraceRecorderData->uiRecorderEnabled = 0u;
(void)xTraceStreamPortOnTraceEnd();
TRACE_EXIT_CRITICAL_SECTION();
}
#if (TRC_EXTERNAL_BUFFERS == 0)
/* Stores the header information on Start */
static void prvTraceStoreHeader(void)
{
TraceEventHandle_t xEventHandle;
if (xTraceEventBeginRawOfflineBlocking(sizeof(TraceHeader_t), &xEventHandle) == TRC_SUCCESS)
{
xTraceEventAddData(xEventHandle, (TraceUnsignedBaseType_t*)pxHeader, sizeof(TraceHeader_t) / sizeof(TraceUnsignedBaseType_t));
xTraceEventEndOfflineBlocking(xEventHandle);
}
}
/* Store the Timestamp */
static void prvTraceStoreTimestampInfo(void)
{
TraceEventHandle_t xEventHandle;
if (xTraceEventBeginRawOfflineBlocking(sizeof(TraceTimestampData_t), &xEventHandle) == TRC_SUCCESS)
{
xTraceEventAddData(xEventHandle, (TraceUnsignedBaseType_t*)&pxTraceRecorderData->xTimestampBuffer, sizeof(TraceTimestampData_t) / sizeof(TraceUnsignedBaseType_t));
xTraceEventEndOfflineBlocking(xEventHandle);
}
}
/* Stores the entry table on Start */
static void prvTraceStoreEntryTable(void)
{
uint32_t i = 0;
TraceEventHandle_t xEventHandle;
TraceEntryHandle_t xEntryHandle;
uint32_t uiEntryCount;
void *pvEntryAddress;
(void)xTraceEntryGetCount(&uiEntryCount);
if (xTraceEventBeginRawOfflineBlocking(sizeof(TraceUnsignedBaseType_t) + sizeof(TraceUnsignedBaseType_t) + sizeof(TraceUnsignedBaseType_t), &xEventHandle) == TRC_SUCCESS)
{
(void)xTraceEventAddUnsignedBaseType(xEventHandle, (TraceUnsignedBaseType_t)uiEntryCount);
(void)xTraceEventAddUnsignedBaseType(xEventHandle, TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE);
(void)xTraceEventAddUnsignedBaseType(xEventHandle, TRC_ENTRY_TABLE_STATE_COUNT);
(void)xTraceEventEndOfflineBlocking(xEventHandle);
}
for (i = 0; i < (TRC_ENTRY_TABLE_SLOTS); i++)
{
(void)xTraceEntryGetAtIndex(i, &xEntryHandle);
(void)xTraceEntryGetAddress(xEntryHandle, &pvEntryAddress);
/* We only send used entry slots */
if (pvEntryAddress != 0)
{
/* Send entry */
if (xTraceEventBeginRawOfflineBlocking(sizeof(TraceEntry_t), &xEventHandle) == TRC_SUCCESS)
{
(void)xTraceEventAddData(xEventHandle, (TraceUnsignedBaseType_t*)xEntryHandle, sizeof(TraceEntry_t) / sizeof(TraceUnsignedBaseType_t));
(void)xTraceEventEndOfflineBlocking(xEventHandle);
}
}
}
}
#endif /* (TRC_EXTERNAL_BUFFERS == 0) */
static void prvTraceStoreStartEvent(void)
{
TraceEventHandle_t xEventHandle = 0;
void* pvCurrentTask = (void*)0;
uint32_t i;
if (xTraceEventBeginOffline(PSF_EVENT_TRACE_START, sizeof(TraceUnsignedBaseType_t) * (TRC_CFG_CORE_COUNT), &xEventHandle) == TRC_SUCCESS)
{
for (i = 0; i < (TRC_CFG_CORE_COUNT); i++)
{
(void)xTraceTaskGetCurrentOnCore(i, &pvCurrentTask);
(void)xTraceEventAddUnsignedBaseType(xEventHandle, (TraceUnsignedBaseType_t)pvCurrentTask); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 !MISRAC2012-Rule-11.6 Suppress conversion from pointer to integer check*/
}
(void)xTraceEventEndOffline(xEventHandle);
}
}
/* Checks if the provided command is a valid command */
static int32_t prvIsValidCommand(const TraceCommand_t* const cmd)
{
uint16_t checksum = (uint16_t)0xFFFFU - (uint16_t)(unsigned char)(cmd->cmdCode + /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
cmd->param1 +
cmd->param2 +
cmd->param3 +
cmd->param4 +
cmd->param5);
if (cmd->checksumMSB != (unsigned char)(checksum >> 8)) /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
{
return 0;
}
if (cmd->checksumLSB != (unsigned char)(checksum & 0xFFU)) /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
{
return 0;
}
if (cmd->cmdCode > (unsigned char)(CMD_LAST_COMMAND)) /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
{
return 0;
}
return 1;
}
/* Executed the received command (Start or Stop) */
static void prvProcessCommand(const TraceCommand_t* const cmd)
{
switch(cmd->cmdCode)
{
case CMD_SET_ACTIVE:
if (cmd->param1 == 1u)
{
prvSetRecorderEnabled();
}
else
{
prvSetRecorderDisabled();
}
break;
default:
break;
}
}
#endif
#endif

View File

@@ -0,0 +1,77 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation for strings.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
traceResult xTraceStringRegister(const char* szString, TraceStringHandle_t *pString)
{
TraceEntryHandle_t xEntryHandle;
TraceEventHandle_t xEventHandle = 0;
int32_t i;
uint32_t uiLength, uiValue = 0u;
/* This should never fail */
TRC_ASSERT(szString != (void*)0);
/* This should never fail */
TRC_ASSERT(pString != (void*)0);
/* We need to check this */
if (xTraceEntryCreate(&xEntryHandle) == TRC_FAIL)
{
return TRC_FAIL;
}
for (i = 0; (szString[i] != (char)0) && (i < (int32_t)(TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE)); i++) {} /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/ /*cstat !MISRAC2004-17.4_b We need to access every character in the string*/
uiLength = (uint32_t)i;
/* The address to the available symbol table slot is the address we use */
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetSymbol(xEntryHandle, szString, uiLength) == TRC_SUCCESS);
*pString = (TraceStringHandle_t)xEntryHandle;
/* We need to check this */
if (xTraceEventBegin(PSF_EVENT_OBJ_NAME, sizeof(void*) + uiLength, &xEventHandle) == TRC_SUCCESS)
{
(void)xTraceEventAddPointer(xEventHandle, (void*)xEntryHandle);
(void)xTraceEventAddString(xEventHandle, szString, uiLength);
/* Check if we can truncate */
(void)xTraceEventPayloadRemaining(xEventHandle, &uiValue);
if (uiValue > 0u)
{
(void)xTraceEventAdd8(xEventHandle, 0u);
}
(void)xTraceEventEnd(xEventHandle); /*cstat !MISRAC2012-Rule-17.7 Suppress ignored return value check (inside macro)*/
}
return TRC_SUCCESS;
}
/*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
TraceStringHandle_t xTraceRegisterString(const char *name)
{
TraceStringHandle_t trcStr = 0;
(void)xTraceStringRegister(name, &trcStr);
return trcStr;
}
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */

View File

@@ -0,0 +1,141 @@
/*
* Percepio Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation for tasks.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#ifndef TRC_KERNEL_PORT_KERNEL_CAN_SWITCH_TO_SAME_TASK
#define TRC_KERNEL_PORT_KERNEL_CAN_SWITCH_TO_SAME_TASK 1
#endif
/* Code used for "task address" when no task has started, to indicate "(startup)".
* This value was used since NULL/0 was already reserved for the idle task. */
#define TRACE_HANDLE_NO_TASK ((void*)2UL)
#define TRC_TASK_STATE_INDEX_PRIORITY 0u
TraceTaskData_t* pxTraceTaskData TRC_CFG_RECORDER_DATA_ATTRIBUTE;
traceResult xTraceTaskInitialize(TraceTaskData_t *pxBuffer)
{
int32_t i;
/* This should never fail */
TRC_ASSERT(pxBuffer != (void*)0);
pxTraceTaskData= pxBuffer;
for (i = 0; i < (TRC_CFG_CORE_COUNT); i++)
{
pxTraceTaskData->coreTasks[i] = TRACE_HANDLE_NO_TASK; /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 !MISRAC2012-Rule-11.6 Suppress conversion from pointer to integer check*/
}
xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_TASK);
return TRC_SUCCESS;
}
traceResult xTraceTaskUnregister(TraceTaskHandle_t xTaskHandle, TraceUnsignedBaseType_t uxPriority)
{
void* pvTask = (void*)0;
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetAddress((TraceEntryHandle_t)xTaskHandle, &pvTask) == TRC_SUCCESS);
xTraceStackMonitorRemove(pvTask);
return xTraceObjectUnregister((TraceObjectHandle_t)xTaskHandle, PSF_EVENT_TASK_DELETE, uxPriority);
}
traceResult xTraceTaskSetPriority(TraceTaskHandle_t xTaskHandle, TraceUnsignedBaseType_t uxPriority)
{
void *pvTask = (void*)0;
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceObjectSetSpecificState((TraceObjectHandle_t)xTaskHandle, TRC_TASK_STATE_INDEX_PRIORITY, uxPriority) == TRC_SUCCESS);
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetAddress((TraceEntryHandle_t)xTaskHandle, &pvTask) == TRC_SUCCESS);
(void)xTraceEventCreate2(PSF_EVENT_TASK_PRIORITY, (TraceUnsignedBaseType_t)pvTask, uxPriority); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 !MISRAC2012-Rule-11.6 Suppress conversion from pointer to integer check*/
return TRC_SUCCESS;
}
traceResult xTraceTaskSetPriorityWithoutHandle(void* pvTask, TraceUnsignedBaseType_t uxPriority)
{
TraceEntryHandle_t xEntryHandle;
if (xTraceEntryFind(pvTask, &xEntryHandle) == TRC_FAIL)
{
return TRC_FAIL;
}
/* This should never fail */
TRC_ASSERT_ALWAYS_EVALUATE(xTraceObjectSetSpecificState((TraceObjectHandle_t)xEntryHandle, TRC_TASK_STATE_INDEX_PRIORITY, uxPriority) == TRC_SUCCESS);
/* We need to check this */
(void)xTraceEventCreate2(PSF_EVENT_TASK_PRIORITY, (TraceUnsignedBaseType_t)pvTask, uxPriority); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 !MISRAC2012-Rule-11.6 Suppress conversion from pointer to integer check*/
return TRC_SUCCESS;
}
traceResult xTraceTaskSwitch(void *pvTask, TraceUnsignedBaseType_t uxPriority)
{
traceResult xResult = TRC_FAIL;
#if (TRC_KERNEL_PORT_KERNEL_CAN_SWITCH_TO_SAME_TASK == 1)
void* pvCurrent = (void*)0;
#endif
TRACE_ALLOC_CRITICAL_SECTION();
(void)pvTask;
(void)uxPriority;
if (!xTraceIsRecorderInitialized())
{
return xResult;
}
if (!xTraceIsRecorderEnabled())
{
/* Make sure we store the current task, even while recorder isn't enabled */
xTraceTaskSetCurrent(pvTask);
return xResult;
}
xTraceStateSet(TRC_STATE_IN_TASKSWITCH);
TRACE_ENTER_CRITICAL_SECTION();
#if (TRC_KERNEL_PORT_KERNEL_CAN_SWITCH_TO_SAME_TASK == 1)
xTraceTaskGetCurrent(&pvCurrent);
if (pvCurrent != pvTask)
#endif
{
xTraceTaskSetCurrent(pvTask);
xResult = xTraceEventCreate2(PSF_EVENT_TASK_ACTIVATE, (TraceUnsignedBaseType_t)pvTask, uxPriority); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 !MISRAC2012-Rule-11.6 Suppress conversion from pointer to integer check*/
}
xTraceStateSet(TRC_STATE_IN_APPLICATION);
TRACE_EXIT_CRITICAL_SECTION();
return xResult;
}
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */

View File

@@ -0,0 +1,175 @@
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation of timestamps.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
TraceTimestampData_t *pxTraceTimestamp TRC_CFG_RECORDER_DATA_ATTRIBUTE;
traceResult xTraceTimestampInitialize(TraceTimestampData_t *pxBuffer)
{
/* This should never fail */
TRC_ASSERT(pxBuffer != (void*)0);
pxTraceTimestamp = pxBuffer;
/* These will be set when tracing is enabled */
pxTraceTimestamp->frequency = 0u;
pxTraceTimestamp->period = 0u;
pxTraceTimestamp->osTickHz = TRC_TICK_RATE_HZ;
pxTraceTimestamp->osTickCount = 0u;
pxTraceTimestamp->wraparounds = 0u;
pxTraceTimestamp->type = TRC_HWTC_TYPE;
#if (TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_INCR || TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_INCR)
pxTraceTimestamp->latestTimestamp = 0u;
#elif (TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_DECR || TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)
pxTraceTimestamp->latestTimestamp = pxTraceTimestamp->period - 1u;
#endif
xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_TIMESTAMP);
return TRC_SUCCESS;
}
#if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
traceResult xTraceTimestampGet(uint32_t *puiTimestamp)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_TIMESTAMP));
/* This should never fail */
TRC_ASSERT(puiTimestamp != (void*)0);
switch (pxTraceTimestamp->type)
{
case TRC_FREE_RUNNING_32BIT_INCR:
case TRC_CUSTOM_TIMER_INCR:
*puiTimestamp = (uint32_t)(TRC_HWTC_COUNT);
if (*puiTimestamp < pxTraceTimestamp->latestTimestamp)
{
pxTraceTimestamp->wraparounds++;
}
break;
case TRC_FREE_RUNNING_32BIT_DECR:
case TRC_CUSTOM_TIMER_DECR:
*puiTimestamp = (uint32_t)(TRC_HWTC_COUNT);
if (*puiTimestamp > pxTraceTimestamp->latestTimestamp)
{
pxTraceTimestamp->wraparounds++;
}
break;
case TRC_OS_TIMER_INCR:
case TRC_OS_TIMER_DECR:
*puiTimestamp = (((uint32_t)(TRC_HWTC_COUNT)) & 0x00FFFFFFUL) + ((pxTraceTimestamp->osTickCount & 0x000000FFUL) << 24);
pxTraceTimestamp->wraparounds = pxTraceTimestamp->osTickCount;
break;
default:
return TRC_FAIL;
break;
}
pxTraceTimestamp->latestTimestamp = *puiTimestamp;
return TRC_SUCCESS;
}
traceResult xTraceTimestampGetWraparounds(uint32_t* puiTimerWraparounds)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_TIMESTAMP));
/* This should never fail */
TRC_ASSERT(puiTimerWraparounds != (void*)0);
*puiTimerWraparounds = pxTraceTimestamp->wraparounds;
return TRC_SUCCESS;
}
traceResult xTraceTimestampSetFrequency(TraceUnsignedBaseType_t uxFrequency)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_TIMESTAMP));
pxTraceTimestamp->frequency = uxFrequency;
return TRC_SUCCESS;
}
traceResult xTraceTimestampSetPeriod(uint32_t uiPeriod)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_TIMESTAMP));
pxTraceTimestamp->period = uiPeriod;
return TRC_SUCCESS;
}
traceResult xTraceTimestampSetOsTickCount(uint32_t uiOsTickCount)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_TIMESTAMP));
pxTraceTimestamp->osTickCount = uiOsTickCount;
return TRC_SUCCESS;
}
traceResult xTraceTimestampGetFrequency(TraceUnsignedBaseType_t *puxFrequency)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_TIMESTAMP));
/* This should never fail */
TRC_ASSERT(puxFrequency != (void*)0);
*puxFrequency = pxTraceTimestamp->frequency;
return TRC_SUCCESS;
}
traceResult xTraceTimestampGetPeriod(uint32_t *puiPeriod)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_TIMESTAMP));
/* This should never fail */
TRC_ASSERT(puiPeriod != (void*)0);
*puiPeriod = pxTraceTimestamp->period;
return TRC_SUCCESS;
}
traceResult xTraceTimestampGetOsTickCount(uint32_t* puiOsTickCount)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_TIMESTAMP));
/* This should never fail */
TRC_ASSERT(puiOsTickCount != (void*)0);
*puiOsTickCount = pxTraceTimestamp->osTickCount;
return TRC_SUCCESS;
}
#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */

View File

@@ -0,0 +1 @@
# keep this file .gitkeep

View File

@@ -0,0 +1,257 @@
/*
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file gcc_evalsoc_ilm.ld
* @brief GNU Linker Script for Nuclei N/NX based device in ilm Download Mode
* @version V1.0.0
* @date 17. Dec 2019
******************************************************************************/
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
__ROM_SIZE = 0x000B0000; /* 768KB ROM :0x00200000~ 0x002A0000 */
__RAM_SIZE = 0x0001A000; /* 104KB RAM :0x20000000~ 0x2001A000 */
__EXT_RAM_SIZE = 0x00006000; /* 24KB RAM :0x2001A000~ 0x20020000 */
MEMORY
{
ilm (rxa!w) : ORIGIN = 0x00200000, LENGTH = __ROM_SIZE
ram (wxa!r) : ORIGIN = 0x20000000, LENGTH = __RAM_SIZE
ext_ram (wxa!r) : ORIGIN = 0x2001A000, LENGTH = __EXT_RAM_SIZE
}
REGION_ALIAS("ROM", ilm)
REGION_ALIAS("RAM", ram)
REGION_ALIAS("DATA_LMA", ilm)
SECTIONS
{
/* To provide symbol __STACK_SIZE, __HEAP_SIZE and __SMP_CPU_CNT */
PROVIDE(__STACK_SIZE = 4K);
PROVIDE(__HEAP_SIZE = 4K);
PROVIDE(__SMP_CPU_CNT = 1);
__TOT_STACK_SIZE = __STACK_SIZE * __SMP_CPU_CNT;
.init :
{
*(.vtable)
*(.vtable_s)
KEEP (*(SORT_NONE(.init)))
. = ALIGN(4);
} >ROM AT>ROM
.text :
{
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >ROM AT>ROM
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >ROM AT>ROM
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >ROM AT>ROM
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >ROM AT>ROM
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >ROM AT>ROM
.ctors :
{
/* gcc uses crtbegin.o to find the start of
* the constructors, so we make sure it is
* first. Because this is a wildcard, it
* doesn't matter if the user does not
* actually link against crtbegin.o; the
* linker won't look for a file to match a
* wildcard. The wildcard also means that it
* doesn't matter which directory crtbegin.o
* is in.
*/
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
* the crtend.o file until after the sorted ctors.
* The .ctor section from the crtend file contains the
* end of ctors marker and it must be last
*/
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >ROM AT>ROM
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >ROM AT>ROM
PROVIDE( _ilm_lma = LOADADDR(.text) );
PROVIDE( _ilm = ADDR(.text) );
PROVIDE( _eilm = . );
PROVIDE( _text_lma = LOADADDR(.text) );
PROVIDE( _text = ADDR(.text) );
PROVIDE (_etext = .);
PROVIDE (__etext = .);
PROVIDE (etext = .);
.data : ALIGN(8)
{
KEEP(*(.data.ctest*))
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.* .sdata*)
*(.gnu.linkonce.s.*)
/* readonly data placed in RAM for access speed */
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
/* below sections are used for rt-thread */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(8);
} >RAM AT>DATA_LMA
.tdata : ALIGN(8)
{
PROVIDE( __tls_base = . );
*(.tdata .tdata.* .gnu.linkonce.td.*)
} >RAM AT>DATA_LMA
PROVIDE( _data_lma = LOADADDR(.data) );
PROVIDE( _data = ADDR(.data) );
PROVIDE( _edata = . );
PROVIDE( edata = . );
PROVIDE( _fbss = . );
PROVIDE( __bss_start = . );
.tbss (NOLOAD) : ALIGN(8)
{
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
PROVIDE( __tls_end = . );
} >RAM AT>RAM
.tbss_space (NOLOAD) : ALIGN(8)
{
. = . + SIZEOF(.tbss);
} >RAM AT>RAM
.bss (NOLOAD) : ALIGN(8)
{
PROVIDE( __bss_start__ = . );
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
PROVIDE( __bss_end__ = . );
} >RAM AT>RAM
PROVIDE( _end = . );
PROVIDE( end = . );
/* Nuclei C Runtime Library requirements:
* 1. heap need to be align at 16 bytes
* 2. __heap_start and __heap_end symbol need to be defined
* 3. reserved at least __HEAP_SIZE space for heap
*/
.heap (NOLOAD) : ALIGN(16)
{
. = ALIGN(16);
PROVIDE( __heap_start = . );
PROVIDE( __heap_bottom = . );
. += __HEAP_SIZE;
. = ALIGN(16);
PROVIDE( __heap_top = . );
PROVIDE( __heap_limit = . );
} >RAM AT>RAM
.stack ORIGIN(RAM) + LENGTH(RAM) - __TOT_STACK_SIZE (NOLOAD) :
{
. = ALIGN(16);
PROVIDE( _heap_end = . );
PROVIDE( __heap_end = . );
PROVIDE( __StackLimit = . );
PROVIDE( __StackBottom = . );
. += __TOT_STACK_SIZE;
. = ALIGN(16);
PROVIDE( __StackTop = . );
PROVIDE( _sp = . );
} >RAM AT>RAM
.ext_ram (ORIGIN(RAM) + LENGTH(RAM)) (COPY):
{
PROVIDE( __ramtxt_size = . );
PROVIDE( __ext_ram_start = . );
. = . + __EXT_RAM_SIZE;
. = ALIGN(16);
PROVIDE( __ext_ram_end = . );
} > ext_ram
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __heap_limit, "region RAM overflowed with stack")
/*ASSERT(__etext + __bss_start__ - __data_start__ <= __ROM_BASE + __ROM_SIZE, "image overflowed") */
}

View File

@@ -0,0 +1,461 @@
/**
******************************************************************************
* @file gcc_riscv32.ld
* @author ListenAI application team
* @brief Linker script
* 8Mbytes FLASH
* 16Kbytes DTCMRAM
* 16Kbytes ITCMRAM
* 128Kbytes RAM
*
* Set heap size, stack size and stack location according
* to application requirements.
*
* Set memory bank area and size if external memory is used
******************************************************************************
* @attentionsss
*
* <h2><center>&copy; Copyright (c) 2021 ListenAI.
* All rights reserved.</center></h2>
*
* This software component is licensed by ListenAI under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
MEMORY
{
ap_ilm (wxa!r) : ORIGIN = 0x80000, LENGTH = 16K
ap_dlm (wxa!r) : ORIGIN = 0x100000, LENGTH = 8K
cp_ilm (wxa!r) : ORIGIN = 0x280000, LENGTH = 16K
cp_dlm (wxa!r) : ORIGIN = 0x300000, LENGTH = 8K
wifi_ram (wxa!r) : ORIGIN = 0x20000000, LENGTH = 256K
cp_ram (wxa!r) : ORIGIN = 0x20040000, LENGTH = 64K
ap_ram (wxa!r) : ORIGIN = 0x20050000, LENGTH = 384K
flash (rxa!w) : ORIGIN = 0x30000000, LENGTH = 8M
}
REGION_ALIAS("AP_ILM", ap_ilm)
REGION_ALIAS("AP_DLM", ap_dlm)
REGION_ALIAS("CP_ILM", cp_ilm)
REGION_ALIAS("CP_DLM", cp_dlm)
REGION_ALIAS("WIFI_RAM", wifi_ram)
REGION_ALIAS("CP_RAM", cp_ram)
REGION_ALIAS("AP_RAM", ap_ram)
REGION_ALIAS("FLASH", flash)
REGION_ALIAS("RAM", ap_ram)
SECTIONS
{
/* To provide symbol __STACK_SIZE, __HEAP_SIZE and __SMP_CPU_CNT */
PROVIDE(__STACK_SIZE = 4K);
PROVIDE(__HEAP_SIZE_LIMIT = 4K);
PROVIDE(__SMP_CPU_CNT = 1);
__TOT_STACK_SIZE = __STACK_SIZE * __SMP_CPU_CNT;
.init :
{
KEEP(*(.OTA_HEADER)) /* OTA header */
KEEP(*(.SIGN_DATA)) /* signature data */
/* vector table locate at FLASH */
. = ALIGN(512);
*(.vtable)
*(.vtable_s)
KEEP (*(SORT_NONE(.init)))
. = ALIGN(4);
} >FLASH AT>FLASH
.copy_table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__ap_ilm_text_lma)
LONG (__ap_ilm_text_start__)
LONG (__ap_ilm_text_end__)
LONG (__cp_ilm_text_lma)
LONG (__cp_ilm_text_start__)
LONG (__cp_ilm_text_end__)
LONG (__wifi_ram_text_lma)
LONG (__wifi_ram_text_start__)
LONG (__wifi_ram_text_end__)
LONG (__cp_ram_text_lma)
LONG (__cp_ram_text_start__)
LONG (__cp_ram_text_end__)
LONG (__ap_ram_text_lma)
LONG (__ap_ram_text_start__)
LONG (__ap_ram_text_end__)
/* data section*/
LONG (__ap_dlm_data_lma)
LONG (__ap_dlm_data_start__)
LONG (__ap_dlm_data_end__)
LONG (__cp_dlm_data_lma)
LONG (__cp_dlm_data_start__)
LONG (__cp_dlm_data_end__)
LONG (__wifi_ram_data_lma)
LONG (__wifi_ram_data_start__)
LONG (__wifi_ram_data_end__)
LONG (__cp_ram_data_lma)
LONG (__cp_ram_data_start__)
LONG (__cp_ram_data_end__)
LONG (__ap_ram_data_lma)
LONG (__ap_ram_data_start__)
LONG (__ap_ram_data_end__)
/* add your own "fast" sections here... */
__copy_table_end__ = .;
} >FLASH
.zero_table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__ap_dlm_bss_start__)
LONG (__ap_dlm_bss_end__)
LONG (__cp_dlm_bss_start__)
LONG (__cp_dlm_bss_end__)
LONG (__wifi_ram_bss_start__)
LONG (__wifi_ram_bss_end__)
LONG (__cp_ram_bss_start__)
LONG (__cp_ram_bss_end__)
LONG (__ap_ram_bss_start__)
LONG (__ap_ram_bss_end__)
__zero_table_end__ = .;
} >FLASH
.ap_ilm_text :
{
. = ALIGN(4);
__ap_ilm_text_start__ = .;
*(.text.ap_ilm .text.ap_ilm.* .text.entry .text.irq .text.irq.* .text.xPortTaskSwitch .text.vPortEnterCritical .text.vPortExitCritical)
. = ALIGN(4);
__ap_ilm_text_end__ = .;
} >AP_ILM AT>FLASH
__ap_ilm_text_lma = LOADADDR(.ap_ilm_text);
.cp_ilm_text :
{
. = ALIGN(4);
__cp_ilm_text_start__ = .;
/* NOTE: .ap_ilm_text SHOULD BE REMOVED if .cp_ilm_text is used, */
/* or else .text.irq etc. sections will be placed into .ap_ilm_text!! */
*(.text.cp_ilm .text.cp_ilm.* .text.entry .text.irq .text.irq.* .text.xPortTaskSwitch)
. = ALIGN(4);
__cp_ilm_text_end__ = .;
} >CP_ILM AT>FLASH
__cp_ilm_text_lma = LOADADDR(.cp_ilm_text);
.wifi_ram_text :
{
. = ALIGN(4);
__wifi_ram_text_start__ = .;
*(.text.wifi_ram .text.wifi_ram.*)
. = ALIGN(4);
__wifi_ram_text_end__ = .;
} >WIFI_RAM AT>FLASH
__wifi_ram_text_lma = LOADADDR(.wifi_ram_text);
.cp_ram_text :
{
. = ALIGN(4);
__cp_ram_text_start__ = .;
*(.text.cp_ram .text.cp_ram.*)
. = ALIGN(4);
__cp_ram_text_end__ = .;
} >CP_RAM AT>FLASH
__cp_ram_text_lma = LOADADDR(.cp_ram_text);
.ap_ram_text :
{
. = ALIGN(4);
__ap_ram_text_start__ = .;
*(.text.ap_ram .text.ap_ram.*)
. = ALIGN(4);
__ap_ram_text_end__ = .;
} >AP_RAM AT>FLASH
__ap_ram_text_lma = LOADADDR(.ap_ram_text);
.ap_dlm_data :
{
. = ALIGN(4);
__ap_dlm_data_start__ = .;
*(.data.ap_dlm .data.ap_dlm.*)
. = ALIGN(4);
__ap_dlm_data_end__ = .;
} >AP_DLM AT>FLASH
__ap_dlm_data_lma = LOADADDR(.ap_dlm_data);
.cp_dlm_data :
{
. = ALIGN(4);
__cp_dlm_data_start__ = .;
*(.data.cp_dlm .data.cp_dlm.*)
. = ALIGN(4);
__cp_dlm_data_end__ = .;
} >CP_DLM AT>FLASH
__cp_dlm_data_lma = LOADADDR(.cp_dlm_data);
/* Code section located at FLASH */
.text :
{
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
_etext = .;
} >FLASH AT>FLASH
PROVIDE( _text_lma = LOADADDR(.text) );
PROVIDE( _text = ADDR(.text) );
.ro_text :
{
/* readonly data placed in FLASH */
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
*(.rdata)
/* *(.rodata .rodata.*) */
*(EXCLUDE_FILE (*spiflash.o *platform.o ) .rodata)
*(EXCLUDE_FILE (*spiflash.o *platform.o ) .rodata.*)
*(.gnu.linkonce.r.*)
} >FLASH AT>FLASH
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >FLASH AT>FLASH
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH AT>FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH AT>FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH AT>FLASH
.wifi_ram_data :
{
. = ALIGN(4);
__wifi_ram_data_start__ = .;
*(.data.wifi_ram .data.wifi_ram.*)
. = ALIGN(4);
__wifi_ram_data_end__ = .;
} >WIFI_RAM AT>FLASH
__wifi_ram_data_lma = LOADADDR(.wifi_ram_data);
.cp_ram_data :
{
. = ALIGN(4);
__cp_ram_data_start__ = .;
*(.data.cp_ram .data.cp_ram.*)
. = ALIGN(4);
__cp_ram_data_end__ = .;
} >CP_RAM AT>FLASH
__cp_ram_data_lma = LOADADDR(.cp_ram_data);
.ap_ram_data :
{
. = ALIGN(4);
__ap_ram_data_start__ = .;
*(.data.ap_ram .data.ap_ram.*)
. = ALIGN(4);
__ap_ram_data_end__ = .;
} >AP_RAM AT>FLASH
__ap_ram_data_lma = LOADADDR(.ap_ram_data);
.data : ALIGN(8)
{
PROVIDE( __global_pointer$ = . + 0x800 );
KEEP(*(.data.ctest*))
*(.data .data.*)
*(.ramcode .ramcode.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
*(.sdata .sdata.* .sdata*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
} >RAM AT>FLASH
.tdata : ALIGN(8)
{
PROVIDE( __tls_base = . );
*(.tdata .tdata.* .gnu.linkonce.td.*)
} >RAM AT>FLASH
.ro_ram :
{
/* readonly data placed in RAM */
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
} >RAM AT>FLASH
PROVIDE( _data_lma = LOADADDR(.data) );
PROVIDE( _data = ADDR(.data) );
PROVIDE( _edata = . );
PROVIDE( edata = . );
.ap_dlm_bss (NOLOAD) :
{
. = ALIGN(4);
__ap_dlm_bss_start__ = .;
*(.bss.ap_dlm .bss.ap_dlm.*)
. = ALIGN(4);
__ap_dlm_bss_end__ = .;
} >AP_DLM AT>FLASH
.cp_dlm_bss (NOLOAD) :
{
. = ALIGN(4);
__cp_dlm_bss_start__ = .;
*(.bss.cp_dlm .bss.cp_dlm.*)
. = ALIGN(4);
__cp_dlm_bss_end__ = .;
} >CP_DLM AT>FLASH
.wifi_ram_bss (NOLOAD) :
{
. = ALIGN(4);
__wifi_ram_bss_start__ = .;
*(.bss.wifi_ram .bss.wifi_ram.*)
. = ALIGN(4);
__wifi_ram_bss_end__ = .;
} >WIFI_RAM AT>FLASH
.cp_ram_bss (NOLOAD) :
{
. = ALIGN(4);
__cp_ram_bss_start__ = .;
*(.bss.cp_ram .bss.cp_ram.*)
. = ALIGN(4);
__cp_ram_bss_end__ = .;
} >CP_RAM AT>FLASH
.ap_ram_bss (NOLOAD) :
{
. = ALIGN(4);
__ap_ram_bss_start__ = .;
*(.bss.ap_ram .bss.ap_ram.*)
. = ALIGN(4);
__ap_ram_bss_end__ = .;
} >AP_RAM AT>FLASH
.tbss (NOLOAD) : ALIGN(8)
{
PROVIDE( __bss_start = . );
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
PROVIDE( __tls_end = . );
} >RAM AT>RAM
.tbss_space (NOLOAD) : ALIGN(8)
{
. = . + SIZEOF(.tbss);
} >RAM AT>RAM
.bss (NOLOAD) : ALIGN(8)
{
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
PROVIDE( _end = . );
PROVIDE( end = . );
} >RAM AT>RAM
/* Nuclei C Runtime Library requirements:
* 1. heap need to be align at 16 bytes
* 2. __heap_start and __heap_end symbol need to be defined
* 3. reserved at least __HEAP_SIZE space for heap
*/
.heap (NOLOAD) : ALIGN(16)
{
. = ALIGN(16);
PROVIDE( __heap_start = . );
PROVIDE( __heap_bottom = . );
} >RAM AT>RAM
.stack ORIGIN(RAM) + LENGTH(RAM) - __TOT_STACK_SIZE (NOLOAD) :
{
. = ALIGN(16);
PROVIDE( __heap_top = . );
PROVIDE( __heap_limit = . );
PROVIDE( _heap_end = . );
PROVIDE( __heap_end = . );
PROVIDE( __StackLimit = . );
PROVIDE( __StackBottom = . );
. += __TOT_STACK_SIZE;
. = ALIGN(16);
PROVIDE( __StackTop = . );
PROVIDE( _sp = . );
} >RAM AT>RAM
__HEAP_SIZE = __heap_end - __heap_start;
ASSERT(__HEAP_SIZE >= __HEAP_SIZE_LIMIT, "HEAP size is under the size limit!!!")
}

View File

@@ -0,0 +1,243 @@
/**
******************************************************************************
* @file gcc_riscv32.ld
* @author ListenAI application team
* @brief Linker script
* 8Mbytes FLASH
* 16Kbytes DTCMRAM
* 16Kbytes ITCMRAM
* 128Kbytes RAM
*
* Set heap size, stack size and stack location according
* to application requirements.
*
* Set memory bank area and size if external memory is used
******************************************************************************
* @attentionsss
*
* <h2><center>&copy; Copyright (c) 2021 ListenAI.
* All rights reserved.</center></h2>
*
* This software component is licensed by ListenAI under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
#if FLASH_ENC_ALL==1
FLASH_BASE = 0x08000000;
#else
FLASH_BASE = 0x30000000;
#endif
MEMORY
{
flash (rxa!w) : ORIGIN = FLASH_BASE, LENGTH = 64K
ram (wxa!r) : ORIGIN = 0x20050000, LENGTH = 64K
}
REGION_ALIAS("ROM", flash)
REGION_ALIAS("RAM", ram)
REGION_ALIAS("DATA_LMA", flash)
SECTIONS
{
/* To provide symbol __STACK_SIZE, __HEAP_SIZE and __SMP_CPU_CNT */
PROVIDE(__STACK_SIZE = 4K);
PROVIDE(__HEAP_SIZE = 4K);
PROVIDE(__SMP_CPU_CNT = 1);
__TOT_STACK_SIZE = __STACK_SIZE * __SMP_CPU_CNT;
.init :
{
KEEP(*(.OTA_HEADER)) /* OTA header */
KEEP(*(.SIGN_DATA)) /* signature data */
. = ALIGN(512);
/* vector table locate at ROM */
*(.vtable)
*(.vtable_s)
KEEP (*(SORT_NONE(.init)))
. = ALIGN(4);
} >ROM AT>ROM
/* Code section located at ROM */
.text :
{
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
/* readonly data placed in ROM */
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
*(.rdata)
*(.ROM_DATA)
*(.gnu.linkonce.r.*)
/* below sections are used for rt-thread */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
} >ROM AT>ROM
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >ROM AT>ROM
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >ROM AT>ROM
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >ROM AT>ROM
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >ROM AT>ROM
PROVIDE(_rom_code_start = ORIGIN(ROM));
PROVIDE(_rom_code_end = .);
.ramcode : ALIGN(8)
{
*(.rodata .rodata.*)
. = ALIGN(8);
} >RAM AT>DATA_LMA
PROVIDE( _ram_code_start = ADDR(.ramcode));
PROVIDE( _ram_code_end = .);
PROVIDE( _ilm_lma = LOADADDR(.text) );
PROVIDE( _ilm = ADDR(.text) );
PROVIDE( _eilm = . );
PROVIDE( _text_lma = LOADADDR(.ramcode) );
PROVIDE( _text = ADDR(.ramcode) );
PROVIDE (_etext = .);
PROVIDE (__etext = .);
PROVIDE (etext = .);
.data : ALIGN(8)
{
KEEP(*(.data.ctest*))
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.* .sdata*)
*(.gnu.linkonce.s.*)
/* readonly data placed in RAM for access speed */
. = ALIGN(8);
*(.gnu.linkonce.r.*)
/* below sections are used for rt-thread */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(8);
} >RAM AT>DATA_LMA
.tdata : ALIGN(8)
{
PROVIDE( __tls_base = . );
*(.tdata .tdata.* .gnu.linkonce.td.*)
} >RAM AT>DATA_LMA
PROVIDE( _data_lma = LOADADDR(.data) );
PROVIDE( _data = ADDR(.data) );
PROVIDE( _edata = . );
PROVIDE( edata = . );
PROVIDE( _fbss = . );
PROVIDE( __bss_start = . );
.tbss (NOLOAD) : ALIGN(8)
{
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
PROVIDE( __tls_end = . );
} >RAM AT>RAM
.tbss_space (NOLOAD) : ALIGN(8)
{
. = . + SIZEOF(.tbss);
} >RAM AT>RAM
.bss (NOLOAD) : ALIGN(8)
{
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
} >RAM AT>RAM
PROVIDE( _end = . );
PROVIDE( end = . );
/* Nuclei C Runtime Library requirements:
* 1. heap need to be align at 16 bytes
* 2. __heap_start and __heap_end symbol need to be defined
* 3. reserved at least __HEAP_SIZE space for heap
*/
.heap (NOLOAD) : ALIGN(16)
{
. = ALIGN(16);
PROVIDE( __heap_start = . );
. += __HEAP_SIZE;
. = ALIGN(16);
PROVIDE( __heap_limit = . );
} >RAM AT>RAM
.stack ORIGIN(RAM) + LENGTH(RAM) - __TOT_STACK_SIZE (NOLOAD) :
{
. = ALIGN(16);
PROVIDE( _heap_end = . );
PROVIDE( __heap_end = . );
PROVIDE( __StackLimit = . );
PROVIDE( __StackBottom = . );
. += __TOT_STACK_SIZE;
. = ALIGN(16);
PROVIDE( __StackTop = . );
PROVIDE( _sp = . );
} >RAM AT>RAM
}

View File

@@ -0,0 +1,319 @@
/******************************************************************************
* @file gcc_arm.ld
* @brief GNU Linker Script for Cortex-M based device
* @version V2.0.0
* @date 21. May 2019
******************************************************************************/
/*
* Copyright (c) 2009-2019 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
*-------- <<< Use Configuration Wizard in Context Menu >>> -------------------
*/
/*---------------------- Flash Configuration ----------------------------------
<h> Flash Configuration
<o0> Flash Base Address <0x0-0xFFFFFFFF:8>
<o1> Flash Size (in Bytes) <0x0-0xFFFFFFFF:8>
</h>
-----------------------------------------------------------------------------*/
__ROM_BASE = 0x20200000;
__ROM_SIZE = 0x00080000; /* 128KB */
/*__ROM_BASE = 0x08000000;*/
/*__ROM_SIZE = 0x00800000;*/ /* 8MB */
/*--------------------- Embedded RAM Configuration ----------------------------
<h> RAM Configuration
<o0> RAM Base Address <0x0-0xFFFFFFFF:8>
<o1> RAM Size (in Bytes) <0x0-0xFFFFFFFF:8>
</h>
-----------------------------------------------------------------------------*/
__RAM_BASE = 0x20280000; /* CODE_RAM + SYS_RAM */
__RAM_SIZE = 0x00080000; /* 128KB */
/*--------------------- Stack / Heap Configuration ----------------------------
<h> Stack / Heap Configuration
<o0> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
<o1> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
</h>
-----------------------------------------------------------------------------*/
__STACK_SIZE = 0x00001000; /* 4KB */
__HEAP_SIZE = 0x00000100; /* 256B */
/*
*-------------------- <<< end of configuration section >>> -------------------
*/
MEMORY
{
FLASH (rx) : ORIGIN = __ROM_BASE, LENGTH = __ROM_SIZE
RAM (rwx) : ORIGIN = __RAM_BASE, LENGTH = __RAM_SIZE
shared_memory (!rx) : ORIGIN = 0x60000000, len = 384K
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __copy_table_start__
* __copy_table_end__
* __zero_table_start__
* __zero_table_end__
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
ENTRY(Reset_Handler)
SECTIONS
{
/* shared RAM */
SHARED (NOLOAD):
{
_sshram = . ;
*(SHAREDRAMIPC)
*(SHAREDRAM)
_eshram = . ;
_trace_start = .;
_trace_end = ORIGIN(shared_memory) + LENGTH(shared_memory);
} > shared_memory
.text :
{
_stext = .;
KEEP(*(.vectors))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
_etext = .;
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
/*
* SG veneers:
* All SG veneers are placed in the special output section .gnu.sgstubs. Its start address
* must be set, either with the command line option --section-start or in a linker script,
* to indicate where to place these veneers in memory.
*/
/*
.gnu.sgstubs :
{
. = ALIGN(32);
} > FLASH
*/
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
/* Add each additional data section here */
/*
LONG (__etext2)
LONG (__data2_start__)
LONG (__data2_end__ - __data2_start__)
*/
__copy_table_end__ = .;
} > FLASH
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
/* Add each additional bss section here */
/*
LONG (__bss2_start__)
LONG (__bss2_end__ - __bss2_start__)
*/
__zero_table_end__ = .;
} > FLASH
/**
* Location counter can end up 2byte aligned with narrow Thumb code but
* __etext is assumed by startup code to be the LMA of a section in RAM
* which must be 4byte aligned
*/
__etext = ALIGN (4);
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data)
*(.data.*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM
/*
* Secondary data section, optional
*
* Remember to add each additional data section
* to the .copy.table above to asure proper
* initialization during startup.
*/
/*
__etext2 = ALIGN (4);
.data2 : AT (__etext2)
{
. = ALIGN(4);
__data2_start__ = .;
*(.data2)
*(.data2.*)
. = ALIGN(4);
__data2_end__ = .;
} > RAM2
*/
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM AT > RAM
/*
* Secondary bss section, optional
*
* Remember to add each additional bss section
* to the .zero.table above to asure proper
* initialization during startup.
*/
/*
.bss2 :
{
. = ALIGN(4);
__bss2_start__ = .;
*(.bss2)
*(.bss2.*)
. = ALIGN(4);
__bss2_end__ = .;
} > RAM2 AT > RAM2
*/
.heap (COPY) :
{
. = ALIGN(8);
__heap_bottom = .;
__end__ = .;
PROVIDE(end = .);
. = . + __HEAP_SIZE;
. = ALIGN(8);
__HeapLimit = .;
__heap_top = .;
} > RAM
.stack (ORIGIN(RAM) + LENGTH(RAM) - __STACK_SIZE) (COPY) :
{
. = ALIGN(8);
__StackLimit = .;
_sstack = .;
. = . + __STACK_SIZE;
. = ALIGN(8);
__StackTop = .;
_estack = .;
} > RAM
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}

View File

@@ -0,0 +1,338 @@
/******************************************************************************
* @file gcc_arm.ld
* @brief GNU Linker Script for Cortex-M based device
* @version V2.0.0
* @date 21. May 2019
******************************************************************************/
/*
* Copyright (c) 2009-2019 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
*-------- <<< Use Configuration Wizard in Context Menu >>> -------------------
*/
/*---------------------- Flash Configuration ----------------------------------
<h> Flash Configuration
<o0> Flash Base Address <0x0-0xFFFFFFFF:8>
<o1> Flash Size (in Bytes) <0x0-0xFFFFFFFF:8>
</h>
-----------------------------------------------------------------------------*/
/*0x0~0x8000 32KB ROM for boot
0x8000~ 0x0068000 384KB RAM for MPW, ROM for MP
0x00200000~0x00280000 512kRAM
0X20200000 0X20A00000 512K SRAM
*/
__ROM_BASE = 0x00200000; /*0x00200000~0x00280000 512kRAM */
__ROM_SIZE = 0x80000; /*0x00200000~0x00280000 512kRAM */
/*__ROM_BASE = 0x08000000;*/
/*__ROM_SIZE = 0x00800000;*/ /* 8MB */
/*--------------------- Embedded RAM Configuration ----------------------------
<h> RAM Configuration
<o0> RAM Base Address <0x0-0xFFFFFFFF:8>
<o1> RAM Size (in Bytes) <0x0-0xFFFFFFFF:8>
</h>
-----------------------------------------------------------------------------*/
/* 0x8000~ 0x0068000 384KB RAM for MPW, ROM for MP */
EXT_ROM_BASE = 0x00008000; /* 384KB RAM for MPW, ROM for MP:0x8000~ 0x0068000 */
EXT_ROM_SIZE = 0x00045000; /* 384KB RAM for MPW, ROM for MP:0x8000~ 0x0068000 */
__RAM_BASE = 0x0004d000; /* SRAM */ /* 384KB RAM for MPW, ROM for MP:0x8000~ 0x0068000 */
__RAM_SIZE = 0x0001b000; /* 80KB */ /* 384KB RAM for MPW, ROM for MP:0x8000~ 0x0068000 */
/*--------------------- Stack / Heap Configuration ----------------------------
<h> Stack / Heap Configuration
<o0> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
<o1> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
</h>
-----------------------------------------------------------------------------*/
__BT_HEAP_SIZE = 0x00010000; /* 16KB */
__HEAP_SIZE = 0x0000a000; /* 32KB */
__STACK_SIZE = 0x00007000; /* 16KB */
/*
*-------------------- <<< end of configuration section >>> -------------------
*/
MEMORY
{
FLASH (rx) : ORIGIN = __ROM_BASE, LENGTH = __ROM_SIZE
RAM_EXT (rx): ORIGIN = EXT_ROM_BASE, LENGTH = EXT_ROM_SIZE
RAM (rwx) : ORIGIN = __RAM_BASE, LENGTH = __RAM_SIZE
shared_memory (!rx) : ORIGIN = 0x70000000, len = 256K
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __copy_table_start__
* __copy_table_end__
* __zero_table_start__
* __zero_table_end__
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
ENTRY(Reset_Handler)
SECTIONS
{
/* shared RAM */
SHARED (NOLOAD):
{
_sshram = . ;
*(SHAREDRAMIPC)
*(SHAREDRAM)
_eshram = . ;
_trace_start = .;
_trace_end = ORIGIN(shared_memory) + LENGTH(shared_memory);
} > shared_memory
.text :
{
_stext = .;
KEEP(*(.vectors))
/* *(EXCLUDE_FILE (*libaudio.a *libcodec.a *liblea.a) .text*) */
*(EXCLUDE_FILE (*libcodec.a) .text*)
/**(.text*)*/
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
_etext = .;
KEEP(*(.eh_frame*))
} > FLASH
.CODE_TEXT :
{
*(.rodata*)
/*libaudio.a *(.text*)*/
libcodec.a *(.text*)
/*liblea.a *(.text*)*/
} > RAM_EXT
/*
* SG veneers:
* All SG veneers are placed in the special output section .gnu.sgstubs. Its start address
* must be set, either with the command line option --section-start or in a linker script,
* to indicate where to place these veneers in memory.
*/
/*
.gnu.sgstubs :
{
. = ALIGN(32);
} > FLASH
*/
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > RAM_EXT
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > RAM_EXT
__exidx_end = .;
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
/* Add each additional data section here */
/*
LONG (__etext2)
LONG (__data2_start__)
LONG (__data2_end__ - __data2_start__)
*/
__copy_table_end__ = .;
} > RAM_EXT
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
/* Add each additional bss section here */
/*
LONG (__bss2_start__)
LONG (__bss2_end__ - __bss2_start__)
*/
LONG (_sshram)
LONG (_eshram - _sshram)
__zero_table_end__ = .;
} > RAM_EXT
/**
* Location counter can end up 2byte aligned with narrow Thumb code but
* __etext is assumed by startup code to be the LMA of a section in RAM
* which must be 4byte aligned
*/
__etext = ALIGN (4);
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data)
*(.data.*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM
/*
* Secondary data section, optional
*
* Remember to add each additional data section
* to the .copy.table above to asure proper
* initialization during startup.
*/
/*
__etext2 = ALIGN (4);
.data2 : AT (__etext2)
{
. = ALIGN(4);
__data2_start__ = .;
*(.data2)
*(.data2.*)
. = ALIGN(4);
__data2_end__ = .;
} > RAM2
*/
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM AT > RAM
/*
* Secondary bss section, optional
*
* Remember to add each additional bss section
* to the .zero.table above to asure proper
* initialization during startup.
*/
/*
.bss2 :
{
. = ALIGN(4);
__bss2_start__ = .;
*(.bss2)
*(.bss2.*)
. = ALIGN(4);
__bss2_end__ = .;
} > RAM2 AT > RAM2
*/
.heap (COPY) :
{
. = ALIGN(8);
__heap_bottom = .;
__end__ = .;
PROVIDE(end = .);
. = . + __HEAP_SIZE;
. = ALIGN(8);
__HeapLimit = .;
__heap_top = .;
} > RAM
.stack (ORIGIN(RAM) + LENGTH(RAM) - __STACK_SIZE) (COPY) :
{
. = ALIGN(8);
__StackLimit = .;
_sstack = .;
. = . + __STACK_SIZE;
. = ALIGN(8);
__StackTop = .;
_estack = .;
} > RAM
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}

View File

@@ -0,0 +1,332 @@
# include by rules.mk
# define platfrom specification
CROSS_COMPILE := $(subst \,/,$(NUCLEI_TOOLCHAIN_PATH))/bin/riscv64-unknown-elf-
ifeq ($(HARD_FLOAT),1)
ifeq ($(CONFIG_HARTID),1)
COREFLAGS := -march=rv32imac_zba_zbb_zbc_zbs -mabi=ilp32 -mcmodel=medlow -mtune=nuclei-300-series --specs=nosys.specs
else
COREFLAGS := -march=rv32imafc_zba_zbb_zbc_zbs -mabi=ilp32f -mcmodel=medlow -mtune=nuclei-300-series --specs=nosys.specs
endif
else
COREFLAGS := -march=rv32imac_zba_zbb_zbc_zbs -mabi=ilp32 -mcmodel=medlow -mtune=nuclei-300-series --specs=nosys.specs
endif
AFLAGS += -x assembler-with-cpp
CFLAGS += -I $(TOPDIR)/chip/$(CHIP)/bsp \
-I $(TOPDIR)/chip/$(CHIP)/include \
-I $(TOPDIR)/chip/$(CHIP)/include/register \
-I $(TOPDIR)/modules/nvs/include \
-I $(TOPDIR)/include/NMSIS/Core/Include \
-I $(TOPDIR)/include/bsp
# rtos module customization
ifeq ($(CFG_RTOS),1)
CFLAGS += -DCFG_RTOS
ifeq ($(CFG_RTOS_SMP),1)
AFLAGS += -DSMP_CPU_CNT=2
CFLAGS += -DSMP_CPU_CNT=2
LDFLAGS += -Wl,-defsym=__SMP_CPU_CNT=2
AFLAGS += -DconfigNUMBER_OF_CORES=2
# CFLAGS += -DconfigNUMBER_OF_CORES=2
endif
ifeq ($(CONFIG_RTOS_AL),1)
$(info "using rtos_al")
# rtos module customization -TARGET.
# Difference: TARGET has MODULES, LIB does not.
ifneq ($(strip $(MODULES)),)
# check if rtos module is included
ifneq ($(findstring rtos,$(MODULES)),)
ifneq ($(findstring -lrtos,$(LIBS)),-lrtos)
$(error "rtos module is included, but -lrtos is not found in LIBS")
endif
# filter out the rtos module
MODULES := $(filter-out rtos, $(MODULES))
# define rtos target
.PHONY: rtos_custom
mk_libs : rtos_custom
rtos_custom :
if [ -f "$(TOPDIR)/chip/$(CHIP)/rtos/Makefile" ]; then $(MAKE) -C $(TOPDIR)/chip/$(CHIP)/rtos $(MKDEFS) libs ||exit 1; fi;
endif # ifneq ($(findstring rtos,$(MODULES)),)
endif # ifneq ($(strip $(MODULES)),)
# rtos module customization - TARGET & modules
# rtos include path & FreeRTOSConfig.h path
include $(TOPDIR)/chip/$(CHIP)/rtos/module_interface.mk
else # ifeq ($(CONFIG_RTOS_AL),1)
# rtos module customization -TARGET.
# Difference: TARGET has MODULES, LIB does not.
ifneq ($(strip $(MODULES)),)
# check if rtos module is included
ifneq ($(findstring rtos,$(MODULES)),)
ifneq ($(findstring -lrtos,$(LIBS)),-lrtos)
$(error "rtos module is included, but -lrtos is not found in LIBS")
endif
# filter out the rtos module
MODULES := $(filter-out rtos, $(MODULES))
# define rtos target
.PHONY: rtos_custom
mk_libs : rtos_custom
rtos_custom :
if [ -f "$(TOPDIR)/modules/rtos/Makefile" ]; then $(MAKE) -C $(TOPDIR)/modules/rtos $(MKDEFS) libs ||exit 1; fi;
endif # ifneq ($(findstring rtos,$(MODULES)),)
endif # ifneq ($(strip $(MODULES)),)
# rtos module customization - TARGET & modules
# rtos include path & FreeRTOSConfig.h path
include $(TOPDIR)/modules/rtos/module_interface.mk
endif # ifeq ($(CONFIG_RTOS_AL),1)
endif # ifeq ($(CFG_RTOS),1)
ifeq ($(CONFIG_TRACE), rtt)
COREFLAGS += -DCONFIG_TRACE
CFLAGS += -I $(TOPDIR)/chip/$(CHIP)/TraceRecorder/include \
-I $(TOPDIR)/chip/$(CHIP)/TraceRecorder/config \
-I $(TOPDIR)/chip/$(CHIP)/TraceRecorder/streamports/Jlink_RTT/include \
-I $(TOPDIR)/chip/$(CHIP)/TraceRecorder/streamports/Jlink_RTT/config
# Nessessary only when compiling TARGET. Difference: TARGET has MODULES, LIB does not.
ifneq ($(strip $(MODULES)),)
MODULES += TraceRecorder
LIBS += -ltrace
endif
endif
CFLAGS += \
-Wall -ffunction-sections -fdata-sections -static -ffast-math -fno-common -fno-builtin-printf
ifeq ($(HARD_FLOAT),1)
ifeq ($(CONFIG_HARTID),1)
LDFLAGS += \
-march=rv32imac_zba_zbb_zbc_zbs -mabi=ilp32 -mtune=nuclei-300-series -static -Wl,-gc-sections -nostartfiles -Wl,--start-group -Wl,--end-group #--specs=nosys.specs -lstdc++
else
LDFLAGS += \
-march=rv32imafc_zba_zbb_zbc_zbs -mabi=ilp32f -mtune=nuclei-300-series -static -Wl,-gc-sections -nostartfiles -Wl,--start-group -Wl,--end-group #--specs=nosys.specs -lstdc++
endif
else
LDFLAGS += \
-march=rv32imac_zba_zbb_zbc_zbs -mabi=ilp32 -mtune=nuclei-300-series -static -Wl,-gc-sections -nostartfiles -Wl,--start-group -Wl,--end-group #--specs=nosys.specs -lstdc++
endif
#remove --specs=nosys.specs for warning when link libc.a
ifeq ($(BUILD_NANO),1)
EXTLIBS += -lc_nano -lg_nano
else
EXTLIBS += -lc -lgcc #-lc_nano -lg_nano #-lstdc++_nano -lsupc++_nano #-lm
endif
ifneq ($(strip $(CONFIG_QEMU_N300)),)
CFLAGS += -DCONFIG_QEMU_N300
endif
ifneq ($(strip $(CONFIG_QEMU_N300)),)
LDSCRIPT ?= $(TOPDIR)/chip/$(CHIP)/arch/rom_qemu.ld
else
LDSCRIPT ?= $(TOPDIR)/chip/$(CHIP)/arch/ram.ld
ifeq ($(CONFIG_HARTID),1)
COREFLAGS += -DBOOT_HARTID=1
COREFLAGS += -DMBX_CP_WORK=1
LDFLAGS += -DBOOT_HARTID=1
else
COREFLAGS += -DBOOT_HARTID=0
COREFLAGS += -DMBX_AP_WORK=1
LDFLAGS += -DBOOT_HARTID=0
endif
endif
ifneq ($(strip $(CONFIG_EXT_RAM)),)
CFLAGS += -DCONFIG_EXT_RAM
endif
ifneq ($(strip $(CONFIG_RAM_CONSTRAINED)),)
CFLAGS += -DCONFIG_RAM_CONSTRAINED
endif
ifneq ($(strip $(CFG_PING)),)
CFLAGS += -DCFG_PING
endif
ifneq ($(strip $(CFG_IPERF)),)
CFLAGS += -DCFG_IPERF
endif
ifneq ($(strip $(CFG_WIFI_MFG)),)
CFLAGS += -DCFG_WIFI_MFG
endif
ifneq ($(strip $(CFG_MEMDUMP)),)
CFLAGS += -DCFG_MEMDUMP
endif
ifneq ($(strip $(CFG_NVS)),)
CFLAGS += -DCFG_NVS=$(CFG_NVS)
endif
ifeq ($(strip $(CFG_MEM_OPT)), on)
CFLAGS += -DCFG_MEM_OPT=1
else
CFLAGS += -DCFG_MEM_OPT=0
endif
ifneq ($(strip $(CFG_EVENT_TASK_STACK_SIZE)),)
CFLAGS += -DCFG_EVENT_TASK_STACK_SIZE=$(CFG_EVENT_TASK_STACK_SIZE)
endif
ifneq ($(strip $(CFG_EVENT_TASK_PRIORITY)),)
CFLAGS += -DCFG_EVENT_TASK_PRIORITY=$(CFG_EVENT_TASK_PRIORITY)
endif
ifneq ($(strip $(CFG_TOTAL_HEAP_SIZE)),)
CFLAGS += -DCFG_TOTAL_HEAP_SIZE=$(CFG_TOTAL_HEAP_SIZE)
endif
ifneq ("$(WIFI_HOST_STANDALONE)", "")
CFLAGS += -DWIFI_HOST_STANDALONE
endif
ifeq ($(CFG_ATCMD), 1)
CFLAGS += -DCFG_ATCMD
endif
ifeq ($(BT_WIFI_COEX), 1)
CFLAGS += -DBT_WIFI_COEX
endif
ifeq ("$(CFG_AMP_IPC)", "1")
CFLAGS += -DCFG_AMP_IPC=1
ifeq ("$(CFG_AMP_IPC_MASTER)", "1")
CFLAGS += -DCFG_AMP_IPC_MASTER=1
else
CFLAGS += -DCFG_AMP_IPC_SLAVE=1
endif
ifeq ("$(CFG_IPC_PRINT)", "1")
CFLAGS += -DCFG_IPC_PRINT=1
endif
ifeq ("$(CFG_AMP_IPC_WIFI_CHAN)", "1")
CFLAGS += -DCFG_AMP_IPC_WIFI_CHAN=1
endif
ifeq ("$(CFG_AMP_IPC_FLASH_AGENT)", "1")
CFLAGS += -DCFG_AMP_IPC_FLASH_AGENT=1
endif
ifeq ("$(CFG_AMP_IPC_MRPC_SERVER)", "1")
CFLAGS += -DCFG_AMP_IPC_MRPC_SERVER=1
endif
ifeq ("$(CFG_AMP_IPC_MRPC_CLIENT)", "1")
CFLAGS += -DCFG_AMP_IPC_MRPC_CLIENT=1
endif
ifeq ("$(CFG_AMP_IPC_MRPC_SERVER_LWIP)", "1")
CFLAGS += -DCFG_AMP_IPC_MRPC_SERVER_LWIP=1
endif
ifeq ("$(CFG_AMP_IPC_MRPC_CLIENT_LWIP)", "1")
CFLAGS += -DCFG_AMP_IPC_MRPC_CLIENT_LWIP=1
endif
ifeq ("$(CFG_AMP_IPC_MRPC_CLIENT_BT)", "1")
CFLAGS += -DCFG_AMP_IPC_MRPC_CLIENT_BT=1
endif
ifeq ("$(CFG_AMP_IPC_MRPC_SERVER_WIFI)", "1")
CFLAGS += -DCFG_AMP_IPC_MRPC_SERVER_WIFI=1
endif
ifeq ("$(CFG_AMP_IPC_MRPC_SERVER_BT)", "1")
CFLAGS += -DCFG_AMP_IPC_MRPC_SERVER_BT=1
endif
ifeq ("$(CFG_AMP_IPC_MRPC_CLIENT_WIFI)", "1")
CFLAGS += -DCFG_AMP_IPC_MRPC_CLIENT_WIFI=1
endif
ifeq ("$(CFG_AMP_IPC_MRPC_CLIENT_NVS)", "1")
CFLAGS += -DCFG_AMP_IPC_MRPC_CLIENT_NVS=1
endif
ifeq ("$(CFG_AMP_IPC_MRPC_SERVER_NVS)", "1")
CFLAGS += -DCFG_AMP_IPC_MRPC_SERVER_NVS=1
endif
ifeq ("$(CFG_AMP_IPC_HALT_PEER_CORE)", "1")
CFLAGS += -DCFG_AMP_IPC_HALT_PEER_CORE=1
endif
ifeq ("$(CFG_AMP_IPC_HALT_BY_PEER_CORE)", "1")
CFLAGS += -DCFG_AMP_IPC_HALT_BY_PEER_CORE=1
endif
ifeq ("$(CFG_AMP_IPC_TCPIP)", "1")
CFLAGS += -DCFG_AMP_IPC_TCPIP=1
endif
ifeq ("$(CFG_AMP_IPC_MRPC_SERVER_FLASH_IF)", "1")
CFLAGS += -DCFG_AMP_IPC_MRPC_SERVER_FLASH_IF=1
endif
ifeq ("$(CFG_AMP_IPC_MRPC_CLIENT_FLASH_IF)", "1")
CFLAGS += -DCFG_AMP_IPC_MRPC_CLIENT_FLASH_IF=1
endif
ifeq ("$(CFG_AMP_IPC_MRPC_CLIENT_UTILS_S2M)", "1")
CFLAGS += -DCFG_AMP_IPC_MRPC_CLIENT_UTILS_S2M=1
endif
ifeq ("$(CFG_AMP_IPC_MRPC_SERVER_UTILS_S2M)", "1")
CFLAGS += -DCFG_AMP_IPC_MRPC_SERVER_UTILS_S2M=1
endif
ifeq ("$(CFG_AMP_IPC_MRPC_CLIENT_UTILS_M2S)", "1")
CFLAGS += -DCFG_AMP_IPC_MRPC_CLIENT_UTILS_M2S=1
endif
ifeq ("$(CFG_AMP_IPC_MRPC_SERVER_UTILS_M2S)", "1")
CFLAGS += -DCFG_AMP_IPC_MRPC_SERVER_UTILS_M2S=1
endif
endif
ifeq ("$(CFG_FLASH_IF)", "1")
CFLAGS += -DCFG_FLASH_IF=1
endif
ifneq ($(strip $(CONFIG_USE_RTT)),)
CFLAGS += -DCONFIG_USE_RTT
CFLAGS += -I $(TOPDIR)/modules/segger_rtt/include
MODULES += segger_rtt
LIBS += -lsegger_rtt
endif
ifeq ("$(strip $(CONFIG_SKIP_BOOTCLOCK))","1")
CFLAGS += -DCONFIG_SKIP_BOOTCLOCK
endif
ifeq ("$(strip $(CALI_BUF))", "1")
CFLAGS += -DCALI_BUF=1
else
CFLAGS += -DCALI_BUF=0
endif
ifneq ($(strip $(CONFIG_DUAL_FLASH)),)
CFLAGS += -DCONFIG_DUAL_FLASH
endif
ifeq ("$(strip $(CONFIG_PM))", "1")
CFLAGS += -DCONFIG_PM=1
else
CFLAGS += -DCONFIG_PM=0
endif
ifeq ("$(strip $(CONFIG_PM))", "1")
ifeq ("$(strip $(CONFIG_PM_CLOSE_AP))", "1")
CFLAGS += -DCONFIG_PM_CLOSE_AP=1
endif
endif

View File

@@ -0,0 +1,338 @@
/******************************************************************************
* @file gcc_arm.ld
* @brief GNU Linker Script for Cortex-M based device
* @version V2.0.0
* @date 21. May 2019
******************************************************************************/
/*
* Copyright (c) 2009-2019 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
*-------- <<< Use Configuration Wizard in Context Menu >>> -------------------
*/
/*---------------------- Flash Configuration ----------------------------------
<h> Flash Configuration
<o0> Flash Base Address <0x0-0xFFFFFFFF:8>
<o1> Flash Size (in Bytes) <0x0-0xFFFFFFFF:8>
</h>
-----------------------------------------------------------------------------*/
__ROM_BASE = 0x0;
__ROM_SIZE = 0x00100000; /* 32KB ROM + 384KB RAM + TCM used as ROM for MPW */
/*__ROM_BASE = 0x08000000;*/
/*__ROM_SIZE = 0x00800000;*/ /* 8MB */
__DTCM_BASE = 0x20100000;
__DTCM_SIZE = 0x8000;
/*--------------------- Embedded RAM Configuration ----------------------------
<h> RAM Configuration
<o0> RAM Base Address <0x0-0xFFFFFFFF:8>
<o1> RAM Size (in Bytes) <0x0-0xFFFFFFFF:8>
</h>
-----------------------------------------------------------------------------*/
__RAM_BASE = 0x20200000; /* SRAM */
__RAM_SIZE = 0x00040000; /* 256KB */
__PSRAM_BASE = 0x30000000; /* PSRAM */
__PSRAM_SIZE = 0x00100000; /* 1MB */
/*--------------------- Stack / Heap Configuration ----------------------------
<h> Stack / Heap Configuration
<o0> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
<o1> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
</h>
-----------------------------------------------------------------------------*/
__STACK_SIZE = 0x00004000; /* 16KB */
__HEAP_SIZE = 0x00015000; /* 84KB */
/*
*-------------------- <<< end of configuration section >>> -------------------
*/
MEMORY
{
FLASH (rx) : ORIGIN = __ROM_BASE, LENGTH = __ROM_SIZE
DTCM (rwx) : ORIGIN = __DTCM_BASE, LENGTH = __DTCM_SIZE
RAM (rwx) : ORIGIN = __RAM_BASE, LENGTH = __RAM_SIZE
PSRAM (rwx) : ORIGIN = __PSRAM_BASE, LENGTH = __PSRAM_SIZE
shared_memory (!rx) : ORIGIN = 0x70000000, len = 256K
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __copy_table_start__
* __copy_table_end__
* __zero_table_start__
* __zero_table_end__
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
ENTRY(Reset_Handler)
SECTIONS
{
/* shared RAM */
SHARED (NOLOAD):
{
_sshram = . ;
*(SHAREDRAMIPC)
*(SHAREDRAM)
_eshram = . ;
_trace_start = .;
_trace_end = ORIGIN(shared_memory) + LENGTH(shared_memory);
} > shared_memory
.text :
{
_stext = .;
KEEP(*(.vectors))
*(EXCLUDE_FILE (*libextra2.a *libextra3.a) .text*)
/*libbsp.a (.text*)*/
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
_etext = .;
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
/*
* SG veneers:
* All SG veneers are placed in the special output section .gnu.sgstubs. Its start address
* must be set, either with the command line option --section-start or in a linker script,
* to indicate where to place these veneers in memory.
*/
/*
.gnu.sgstubs :
{
. = ALIGN(32);
} > FLASH
*/
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
/* Add each additional data section here */
LONG (__etext2)
LONG (__text2_start__)
LONG (__text2_end__ - __text2_start__)
__copy_table_end__ = .;
} > FLASH
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
/* Add each additional bss section here */
/*
LONG (__bss2_start__)
LONG (__bss2_end__ - __bss2_start__)
*/
__zero_table_end__ = .;
} > FLASH
/**
* Location counter can end up 2byte aligned with narrow Thumb code but
* __etext is assumed by startup code to be the LMA of a section in RAM
* which must be 4byte aligned
*/
__etext = ALIGN (4);
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data)
*(.data.*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > PSRAM
__etext2 = __etext + SIZEOF (.data);
.text2 : AT(__etext2)
{
. = ALIGN(4);
__text2_start__ = .;
libextra2.a *(.text*)
libextra3.a *(.text*)
. = ALIGN(4);
__text2_end__ = .;
} > PSRAM
/*
* Secondary data section, optional
*
* Remember to add each additional data section
* to the .copy.table above to asure proper
* initialization during startup.
*/
/*
__etext2 = ALIGN (4);
.data2 : AT (__etext2)
{
. = ALIGN(4);
__data2_start__ = .;
*(.data2)
*(.data2.*)
. = ALIGN(4);
__data2_end__ = .;
} > RAM2
*/
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > PSRAM AT > PSRAM
/*
* Secondary bss section, optional
*
* Remember to add each additional bss section
* to the .zero.table above to asure proper
* initialization during startup.
*/
/*
.bss2 :
{
. = ALIGN(4);
__bss2_start__ = .;
*(.bss2)
*(.bss2.*)
. = ALIGN(4);
__bss2_end__ = .;
} > RAM2 AT > RAM2
*/
.heap (COPY) :
{
. = ALIGN(8);
__heap_bottom = .;
__end__ = .;
PROVIDE(end = .);
. = . + __HEAP_SIZE;
. = ALIGN(8);
__HeapLimit = .;
__heap_top = .;
} > PSRAM
.stack (ORIGIN(DTCM) + LENGTH(DTCM) - __STACK_SIZE) (COPY) :
{
. = ALIGN(8);
__StackLimit = .;
_sstack = .;
. = . + __STACK_SIZE;
. = ALIGN(8);
__StackTop = .;
_estack = .;
} > DTCM
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
/* ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") */
}

View File

@@ -0,0 +1,347 @@
/*
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file gcc_evalsoc_ilm.ld
* @brief GNU Linker Script for Nuclei N/NX based device in ilm Download Mode
* @version V1.0.0
* @date 17. Dec 2019
******************************************************************************/
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
MEMORY
{
ap_ilm (wxa!r) : ORIGIN = 0x80000, LENGTH = 16K
ap_dlm (wxa!r) : ORIGIN = 0x100000, LENGTH = 8K
cp_ilm (wxa!r) : ORIGIN = 0x280000, LENGTH = 16K
cp_dlm (wxa!r) : ORIGIN = 0x300000, LENGTH = 8K
/*
ram0 (rxa!w) : ORIGIN = 0x20040000, LENGTH = 64K
ram1 (wxa!r) : ORIGIN = 0x20050000, LENGTH = 384K
*/
ram0 (rxa!w) : ORIGIN = 0x20040000, LENGTH = 128K
ram1 (wxa!r) : ORIGIN = 0x20060000, LENGTH = 320K
}
REGION_ALIAS("ROM", ram0)
REGION_ALIAS("RAM", ram1)
REGION_ALIAS("DATA_LMA", ram0)
SECTIONS
{
/* To provide symbol __STACK_SIZE, __HEAP_SIZE and __SMP_CPU_CNT */
PROVIDE(__STACK_SIZE = 4K);
PROVIDE(__HEAP_SIZE = 4K);
PROVIDE(__SMP_CPU_CNT = 1);
__TOT_STACK_SIZE = __STACK_SIZE * __SMP_CPU_CNT;
.init :
{
*(.vtable)
*(.vtable_s)
KEEP (*(SORT_NONE(.init)))
. = ALIGN(4);
} >ROM AT>ROM
.copy_table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__ap_ilm_text_lma)
LONG (__ap_ilm_text_start__)
LONG (__ap_ilm_text_end__)
LONG (__cp_ilm_text_lma)
LONG (__cp_ilm_text_start__)
LONG (__cp_ilm_text_end__)
/* data section*/
LONG (__ap_dlm_data_lma)
LONG (__ap_dlm_data_start__)
LONG (__ap_dlm_data_end__)
LONG (__cp_dlm_data_lma)
LONG (__cp_dlm_data_start__)
LONG (__cp_dlm_data_end__)
/* add your own "fast" sections here... */
__copy_table_end__ = .;
} >ROM AT>ROM
.zero_table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__ap_dlm_bss_start__)
LONG (__ap_dlm_bss_end__)
LONG (__cp_dlm_bss_start__)
LONG (__cp_dlm_bss_end__)
__zero_table_end__ = .;
} >ROM AT>ROM
.ap_ilm_text :
{
. = ALIGN(4);
__ap_ilm_text_start__ = .;
*(.text.ap_ilm .text.ap_ilm.* .text.entry .text.irq .text.irq.* .text.xPortTaskSwitch)
. = ALIGN(4);
__ap_ilm_text_end__ = .;
} >ap_ilm AT>ROM
__ap_ilm_text_lma = LOADADDR(.ap_ilm_text);
.cp_ilm_text :
{
. = ALIGN(4);
__cp_ilm_text_start__ = .;
/* NOTE: .ap_ilm_text SHOULD BE REMOVED if .cp_ilm_text is used, */
/* or else .text.irq etc. sections will be placed into .ap_ilm_text!! */
*(.text.cp_ilm .text.cp_ilm.* .text.entry .text.irq .text.irq.* .text.xPortTaskSwitch)
. = ALIGN(4);
__cp_ilm_text_end__ = .;
} >cp_ilm AT>ROM
__cp_ilm_text_lma = LOADADDR(.cp_ilm_text);
.ap_dlm_data :
{
. = ALIGN(4);
__ap_dlm_data_start__ = .;
*(.data.ap_dlm .data.ap_dlm.*)
. = ALIGN(4);
__ap_dlm_data_end__ = .;
} >ap_dlm AT>ROM
__ap_dlm_data_lma = LOADADDR(.ap_dlm_data);
.cp_dlm_data :
{
. = ALIGN(4);
__cp_dlm_data_start__ = .;
*(.data.cp_dlm .data.cp_dlm.*)
. = ALIGN(4);
__cp_dlm_data_end__ = .;
} >cp_dlm AT>ROM
__cp_dlm_data_lma = LOADADDR(.cp_dlm_data);
.text :
{
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >ROM AT>ROM
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >ROM AT>ROM
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >ROM AT>ROM
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >ROM AT>ROM
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >ROM AT>ROM
.ctors :
{
/* gcc uses crtbegin.o to find the start of
* the constructors, so we make sure it is
* first. Because this is a wildcard, it
* doesn't matter if the user does not
* actually link against crtbegin.o; the
* linker won't look for a file to match a
* wildcard. The wildcard also means that it
* doesn't matter which directory crtbegin.o
* is in.
*/
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
* the crtend.o file until after the sorted ctors.
* The .ctor section from the crtend file contains the
* end of ctors marker and it must be last
*/
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >ROM AT>ROM
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >ROM AT>ROM
PROVIDE( _ilm_lma = LOADADDR(.text) );
PROVIDE( _ilm = ADDR(.text) );
PROVIDE( _eilm = . );
PROVIDE( _text_lma = LOADADDR(.text) );
PROVIDE( _text = ADDR(.text) );
PROVIDE (_etext = .);
PROVIDE (__etext = .);
PROVIDE (etext = .);
.data : ALIGN(8)
{
KEEP(*(.data.ctest*))
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.* .sdata*)
*(.gnu.linkonce.s.*)
/* readonly data placed in RAM for access speed */
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
/* below sections are used for rt-thread */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(8);
} >RAM AT>DATA_LMA
.tdata : ALIGN(8)
{
PROVIDE( __tls_base = . );
*(.tdata .tdata.* .gnu.linkonce.td.*)
} >RAM AT>DATA_LMA
PROVIDE( _data_lma = LOADADDR(.data) );
PROVIDE( _data = ADDR(.data) );
PROVIDE( _edata = . );
PROVIDE( edata = . );
.ap_dlm_bss (NOLOAD) :
{
. = ALIGN(4);
__ap_dlm_bss_start__ = .;
*(.bss.ap_dlm .bss.ap_dlm.*)
. = ALIGN(4);
__ap_dlm_bss_end__ = .;
} >ap_dlm AT>ap_dlm
.cp_dlm_bss (NOLOAD) :
{
. = ALIGN(4);
__cp_dlm_bss_start__ = .;
*(.bss.cp_dlm .bss.cp_dlm.*)
. = ALIGN(4);
__cp_dlm_bss_end__ = .;
} >cp_dlm AT>cp_dlm
.tbss (NOLOAD) : ALIGN(8)
{
PROVIDE( __bss_start = . );
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
PROVIDE( __tls_end = . );
} >RAM AT>RAM
.tbss_space (NOLOAD) : ALIGN(8)
{
. = . + SIZEOF(.tbss);
} >RAM AT>RAM
.bss (NOLOAD) : ALIGN(8)
{
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
} >RAM AT>RAM
PROVIDE( _end = . );
PROVIDE( end = . );
/* Nuclei C Runtime Library requirements:
* 1. heap need to be align at 16 bytes
* 2. __heap_start and __heap_end symbol need to be defined
* 3. reserved at least __HEAP_SIZE space for heap
*/
.heap (NOLOAD) : ALIGN(16)
{
. = ALIGN(16);
PROVIDE( __heap_start = . );
PROVIDE( __heap_bottom = . );
. += __HEAP_SIZE;
. = ALIGN(16);
PROVIDE( __heap_top = . );
PROVIDE( __heap_limit = . );
} >RAM AT>RAM
.stack ORIGIN(RAM) + LENGTH(RAM) - __TOT_STACK_SIZE (NOLOAD) :
{
. = ALIGN(16);
PROVIDE( _heap_end = . );
PROVIDE( __heap_end = . );
PROVIDE( __StackLimit = . );
PROVIDE( __StackBottom = . );
. += __TOT_STACK_SIZE;
. = ALIGN(16);
PROVIDE( __StackTop = . );
PROVIDE( _sp = . );
} >RAM AT>RAM
}

View File

@@ -0,0 +1,235 @@
/*
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file gcc_evalsoc_ilm.ld
* @brief GNU Linker Script for Nuclei N/NX based device in ilm Download Mode
* @version V1.0.0
* @date 17. Dec 2019
******************************************************************************/
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
MEMORY
{
ilm (rxa!w) : ORIGIN = 0x00000000, LENGTH = 64K
ram (wxa!r) : ORIGIN = 0x20040000, LENGTH = 64K
}
REGION_ALIAS("ROM", ilm)
REGION_ALIAS("RAM", ram)
REGION_ALIAS("DATA_LMA", ilm)
SECTIONS
{
/* To provide symbol __STACK_SIZE, __HEAP_SIZE and __SMP_CPU_CNT */
PROVIDE(__STACK_SIZE = 4K);
PROVIDE(__HEAP_SIZE = 4K);
PROVIDE(__SMP_CPU_CNT = 1);
__TOT_STACK_SIZE = __STACK_SIZE * __SMP_CPU_CNT;
.init :
{
*(.vtable)
*(.vtable_s)
KEEP (*(SORT_NONE(.init)))
. = ALIGN(4);
} >ROM AT>ROM
.text :
{
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >ROM AT>ROM
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >ROM AT>ROM
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >ROM AT>ROM
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >ROM AT>ROM
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >ROM AT>ROM
.ctors :
{
/* gcc uses crtbegin.o to find the start of
* the constructors, so we make sure it is
* first. Because this is a wildcard, it
* doesn't matter if the user does not
* actually link against crtbegin.o; the
* linker won't look for a file to match a
* wildcard. The wildcard also means that it
* doesn't matter which directory crtbegin.o
* is in.
*/
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
* the crtend.o file until after the sorted ctors.
* The .ctor section from the crtend file contains the
* end of ctors marker and it must be last
*/
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >ROM AT>ROM
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >ROM AT>ROM
PROVIDE( _ilm_lma = LOADADDR(.text) );
PROVIDE( _ilm = ADDR(.text) );
PROVIDE( _eilm = . );
PROVIDE( _text_lma = LOADADDR(.text) );
PROVIDE( _text = ADDR(.text) );
PROVIDE (_etext = .);
PROVIDE (__etext = .);
PROVIDE (etext = .);
.data : ALIGN(8)
{
KEEP(*(.data.ctest*))
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.* .sdata*)
*(.gnu.linkonce.s.*)
/* readonly data placed in RAM for access speed */
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
/* below sections are used for rt-thread */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(8);
} >RAM AT>DATA_LMA
.tdata : ALIGN(8)
{
PROVIDE( __tls_base = . );
*(.tdata .tdata.* .gnu.linkonce.td.*)
} >RAM AT>DATA_LMA
PROVIDE( _data_lma = LOADADDR(.data) );
PROVIDE( _data = ADDR(.data) );
PROVIDE( _edata = . );
PROVIDE( edata = . );
PROVIDE( _fbss = . );
PROVIDE( __bss_start = . );
.tbss (NOLOAD) : ALIGN(8)
{
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
PROVIDE( __tls_end = . );
} >RAM AT>RAM
.tbss_space (NOLOAD) : ALIGN(8)
{
. = . + SIZEOF(.tbss);
} >RAM AT>RAM
.bss (NOLOAD) : ALIGN(8)
{
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
} >RAM AT>RAM
PROVIDE( _end = . );
PROVIDE( end = . );
/* Nuclei C Runtime Library requirements:
* 1. heap need to be align at 16 bytes
* 2. __heap_start and __heap_end symbol need to be defined
* 3. reserved at least __HEAP_SIZE space for heap
*/
.heap (NOLOAD) : ALIGN(16)
{
. = ALIGN(16);
PROVIDE( __heap_start = . );
PROVIDE( __heap_bottom = . );
. += __HEAP_SIZE;
. = ALIGN(16);
PROVIDE( __heap_top = . );
PROVIDE( __heap_limit = . );
} >RAM AT>RAM
.stack ORIGIN(RAM) + LENGTH(RAM) - __TOT_STACK_SIZE (NOLOAD) :
{
. = ALIGN(16);
PROVIDE( _heap_end = . );
PROVIDE( __heap_end = . );
PROVIDE( __StackLimit = . );
PROVIDE( __StackBottom = . );
. += __TOT_STACK_SIZE;
. = ALIGN(16);
PROVIDE( __StackTop = . );
PROVIDE( _sp = . );
} >RAM AT>RAM
}

View File

@@ -0,0 +1,235 @@
/*
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file gcc_evalsoc_ilm.ld
* @brief GNU Linker Script for Nuclei N/NX based device in ilm Download Mode
* @version V1.0.0
* @date 17. Dec 2019
******************************************************************************/
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
MEMORY
{
ilm (rxa!w) : ORIGIN = 0x00000000, LENGTH = 64K
ram (wxa!r) : ORIGIN = 0x20040000, LENGTH = 64K
}
REGION_ALIAS("ROM", ilm)
REGION_ALIAS("RAM", ram)
REGION_ALIAS("DATA_LMA", ilm)
SECTIONS
{
/* To provide symbol __STACK_SIZE, __HEAP_SIZE and __SMP_CPU_CNT */
PROVIDE(__STACK_SIZE = 4K);
PROVIDE(__HEAP_SIZE = 4K);
PROVIDE(__SMP_CPU_CNT = 1);
__TOT_STACK_SIZE = __STACK_SIZE * __SMP_CPU_CNT;
.init :
{
*(.vtable)
*(.vtable_s)
KEEP (*(SORT_NONE(.init)))
. = ALIGN(4);
} >ROM AT>ROM
.text :
{
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >ROM AT>ROM
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >ROM AT>ROM
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >ROM AT>ROM
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >ROM AT>ROM
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >ROM AT>ROM
.ctors :
{
/* gcc uses crtbegin.o to find the start of
* the constructors, so we make sure it is
* first. Because this is a wildcard, it
* doesn't matter if the user does not
* actually link against crtbegin.o; the
* linker won't look for a file to match a
* wildcard. The wildcard also means that it
* doesn't matter which directory crtbegin.o
* is in.
*/
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
* the crtend.o file until after the sorted ctors.
* The .ctor section from the crtend file contains the
* end of ctors marker and it must be last
*/
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >ROM AT>ROM
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >ROM AT>ROM
PROVIDE( _ilm_lma = LOADADDR(.text) );
PROVIDE( _ilm = ADDR(.text) );
PROVIDE( _eilm = . );
PROVIDE( _text_lma = LOADADDR(.text) );
PROVIDE( _text = ADDR(.text) );
PROVIDE (_etext = .);
PROVIDE (__etext = .);
PROVIDE (etext = .);
.data : ALIGN(8)
{
KEEP(*(.data.ctest*))
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.* .sdata*)
*(.gnu.linkonce.s.*)
/* readonly data placed in RAM for access speed */
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
/* below sections are used for rt-thread */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(8);
} >RAM AT>DATA_LMA
.tdata : ALIGN(8)
{
PROVIDE( __tls_base = . );
*(.tdata .tdata.* .gnu.linkonce.td.*)
} >RAM AT>DATA_LMA
PROVIDE( _data_lma = LOADADDR(.data) );
PROVIDE( _data = ADDR(.data) );
PROVIDE( _edata = . );
PROVIDE( edata = . );
PROVIDE( _fbss = . );
PROVIDE( __bss_start = . );
.tbss (NOLOAD) : ALIGN(8)
{
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
PROVIDE( __tls_end = . );
} >RAM AT>RAM
.tbss_space (NOLOAD) : ALIGN(8)
{
. = . + SIZEOF(.tbss);
} >RAM AT>RAM
.bss (NOLOAD) : ALIGN(8)
{
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
} >RAM AT>RAM
PROVIDE( _end = . );
PROVIDE( end = . );
/* Nuclei C Runtime Library requirements:
* 1. heap need to be align at 16 bytes
* 2. __heap_start and __heap_end symbol need to be defined
* 3. reserved at least __HEAP_SIZE space for heap
*/
.heap (NOLOAD) : ALIGN(16)
{
. = ALIGN(16);
PROVIDE( __heap_start = . );
PROVIDE( __heap_bottom = . );
. += __HEAP_SIZE;
. = ALIGN(16);
PROVIDE( __heap_top = . );
PROVIDE( __heap_limit = . );
} >RAM AT>RAM
.stack ORIGIN(RAM) + LENGTH(RAM) - __TOT_STACK_SIZE (NOLOAD) :
{
. = ALIGN(16);
PROVIDE( _heap_end = . );
PROVIDE( __heap_end = . );
PROVIDE( __StackLimit = . );
PROVIDE( __StackBottom = . );
. += __TOT_STACK_SIZE;
. = ALIGN(16);
PROVIDE( __StackTop = . );
PROVIDE( _sp = . );
} >RAM AT>RAM
}

View File

@@ -0,0 +1,234 @@
/*
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file gcc_evalsoc_ilm.ld
* @brief GNU Linker Script for Nuclei N/NX based device in ilm Download Mode
* @version V1.0.0
* @date 17. Dec 2019
******************************************************************************/
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
MEMORY
{
ilm (rxa!w) : ORIGIN = 0x00200000, LENGTH = 32K
ram (wxa!r) : ORIGIN = 0x20050000, LENGTH = 384K
}
REGION_ALIAS("ROM", ilm)
REGION_ALIAS("RAM", ram)
REGION_ALIAS("DATA_LMA", ilm)
SECTIONS
{
/* To provide symbol __STACK_SIZE, __HEAP_SIZE and __SMP_CPU_CNT */
PROVIDE(__STACK_SIZE = 4K);
PROVIDE(__HEAP_SIZE = 4K);
PROVIDE(__SMP_CPU_CNT = 1);
__TOT_STACK_SIZE = __STACK_SIZE * __SMP_CPU_CNT;
.init :
{
*(.vtable)
*(.vtable_s)
KEEP (*(SORT_NONE(.init)))
. = ALIGN(4);
} >ROM AT>ROM
.text :
{
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >ROM AT>ROM
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >ROM AT>ROM
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >ROM AT>ROM
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >ROM AT>ROM
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >ROM AT>ROM
.ctors :
{
/* gcc uses crtbegin.o to find the start of
* the constructors, so we make sure it is
* first. Because this is a wildcard, it
* doesn't matter if the user does not
* actually link against crtbegin.o; the
* linker won't look for a file to match a
* wildcard. The wildcard also means that it
* doesn't matter which directory crtbegin.o
* is in.
*/
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
* the crtend.o file until after the sorted ctors.
* The .ctor section from the crtend file contains the
* end of ctors marker and it must be last
*/
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >ROM AT>ROM
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >ROM AT>ROM
PROVIDE( _ilm_lma = LOADADDR(.text) );
PROVIDE( _ilm = ADDR(.text) );
PROVIDE( _eilm = . );
PROVIDE( _text_lma = LOADADDR(.text) );
PROVIDE( _text = ADDR(.text) );
PROVIDE (_etext = .);
PROVIDE (__etext = .);
PROVIDE (etext = .);
.data : ALIGN(8)
{
KEEP(*(.data.ctest*))
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.* .sdata*)
*(.gnu.linkonce.s.*)
/* readonly data placed in RAM for access speed */
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
/* below sections are used for rt-thread */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(8);
} >RAM AT>DATA_LMA
.tdata : ALIGN(8)
{
PROVIDE( __tls_base = . );
*(.tdata .tdata.* .gnu.linkonce.td.*)
} >RAM AT>DATA_LMA
PROVIDE( _data_lma = LOADADDR(.data) );
PROVIDE( _data = ADDR(.data) );
PROVIDE( _edata = . );
PROVIDE( edata = . );
PROVIDE( _fbss = . );
PROVIDE( __bss_start = . );
.tbss (NOLOAD) : ALIGN(8)
{
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
PROVIDE( __tls_end = . );
} >RAM AT>RAM
.tbss_space (NOLOAD) : ALIGN(8)
{
. = . + SIZEOF(.tbss);
} >RAM AT>RAM
.bss (NOLOAD) : ALIGN(8)
{
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
} >RAM AT>RAM
PROVIDE( _end = . );
PROVIDE( end = . );
/* Nuclei C Runtime Library requirements:
* 1. heap need to be align at 16 bytes
* 2. __heap_start and __heap_end symbol need to be defined
* 3. reserved at least __HEAP_SIZE space for heap
*/
.heap (NOLOAD) : ALIGN(16)
{
. = ALIGN(16);
PROVIDE( __heap_start = . );
PROVIDE( __heap_bottom = . );
. += __HEAP_SIZE;
. = ALIGN(16);
PROVIDE( __heap_top = . );
PROVIDE( __heap_limit = . );
} >RAM AT>RAM
.stack ORIGIN(RAM) + LENGTH(RAM) - __TOT_STACK_SIZE (NOLOAD) :
{
. = ALIGN(16);
PROVIDE( _heap_end = . );
PROVIDE( __heap_end = . );
PROVIDE( __StackLimit = . );
PROVIDE( __StackBottom = . );
. += __TOT_STACK_SIZE;
. = ALIGN(16);
PROVIDE( __StackTop = . );
PROVIDE( _sp = . );
} >RAM AT>RAM
}

View File

@@ -0,0 +1,232 @@
/*
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file gcc_evalsoc_ilm.ld
* @brief GNU Linker Script for Nuclei N/NX based device in ilm Download Mode
* @version V1.0.0
* @date 17. Dec 2019
******************************************************************************/
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
MEMORY
{
ilm (rxa!w) : ORIGIN = 0x80000000, LENGTH = 64K
ram (wxa!r) : ORIGIN = 0x90000000, LENGTH = 64K
}
REGION_ALIAS("ROM", ilm)
REGION_ALIAS("RAM", ram)
REGION_ALIAS("DATA_LMA", ram)
SECTIONS
{
/* To provide symbol __STACK_SIZE, __HEAP_SIZE and __SMP_CPU_CNT */
PROVIDE(__STACK_SIZE = 2K);
PROVIDE(__HEAP_SIZE = 2K);
PROVIDE(__SMP_CPU_CNT = 1);
__TOT_STACK_SIZE = __STACK_SIZE * __SMP_CPU_CNT;
.init :
{
*(.vtable)
*(.vtable_s)
KEEP (*(SORT_NONE(.init)))
. = ALIGN(4);
} >ROM AT>ROM
.text :
{
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >ROM AT>ROM
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >ROM AT>ROM
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >ROM AT>ROM
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >ROM AT>ROM
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >ROM AT>ROM
.ctors :
{
/* gcc uses crtbegin.o to find the start of
* the constructors, so we make sure it is
* first. Because this is a wildcard, it
* doesn't matter if the user does not
* actually link against crtbegin.o; the
* linker won't look for a file to match a
* wildcard. The wildcard also means that it
* doesn't matter which directory crtbegin.o
* is in.
*/
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
* the crtend.o file until after the sorted ctors.
* The .ctor section from the crtend file contains the
* end of ctors marker and it must be last
*/
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >ROM AT>ROM
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >ROM AT>ROM
PROVIDE( _ilm_lma = LOADADDR(.text) );
PROVIDE( _ilm = ADDR(.text) );
PROVIDE( _eilm = . );
PROVIDE( _text_lma = LOADADDR(.text) );
PROVIDE( _text = ADDR(.text) );
PROVIDE (_etext = .);
PROVIDE (__etext = .);
PROVIDE (etext = .);
.data : ALIGN(8)
{
KEEP(*(.data.ctest*))
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.* .sdata*)
*(.gnu.linkonce.s.*)
/* readonly data placed in RAM for access speed */
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
/* below sections are used for rt-thread */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(8);
} >RAM AT>DATA_LMA
.tdata : ALIGN(8)
{
PROVIDE( __tls_base = . );
*(.tdata .tdata.* .gnu.linkonce.td.*)
} >RAM AT>DATA_LMA
PROVIDE( _data_lma = LOADADDR(.data) );
PROVIDE( _data = ADDR(.data) );
PROVIDE( _edata = . );
PROVIDE( edata = . );
PROVIDE( _fbss = . );
PROVIDE( __bss_start = . );
.tbss (NOLOAD) : ALIGN(8)
{
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
PROVIDE( __tls_end = . );
} >RAM AT>RAM
.tbss_space (NOLOAD) : ALIGN(8)
{
. = . + SIZEOF(.tbss);
} >RAM AT>RAM
.bss (NOLOAD) : ALIGN(8)
{
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
} >RAM AT>RAM
PROVIDE( _end = . );
PROVIDE( end = . );
/* Nuclei C Runtime Library requirements:
* 1. heap need to be align at 16 bytes
* 2. __heap_start and __heap_end symbol need to be defined
* 3. reserved at least __HEAP_SIZE space for heap
*/
.heap (NOLOAD) : ALIGN(16)
{
. = ALIGN(16);
PROVIDE( __heap_start = . );
. += __HEAP_SIZE;
. = ALIGN(16);
PROVIDE( __heap_limit = . );
} >RAM AT>RAM
.stack ORIGIN(RAM) + LENGTH(RAM) - __TOT_STACK_SIZE (NOLOAD) :
{
. = ALIGN(16);
PROVIDE( _heap_end = . );
PROVIDE( __heap_end = . );
PROVIDE( __StackLimit = . );
PROVIDE( __StackBottom = . );
. += __TOT_STACK_SIZE;
. = ALIGN(16);
PROVIDE( __StackTop = . );
PROVIDE( _sp = . );
} >RAM AT>RAM
}

View File

@@ -0,0 +1,316 @@
/******************************************************************************
* @file gcc_arm.ld
* @brief GNU Linker Script for Cortex-M based device
* @version V2.0.0
* @date 21. May 2019
******************************************************************************/
/*
* Copyright (c) 2009-2019 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
*-------- <<< Use Configuration Wizard in Context Menu >>> -------------------
*/
/*---------------------- Flash Configuration ----------------------------------
<h> Flash Configuration
<o0> Flash Base Address <0x0-0xFFFFFFFF:8>
<o1> Flash Size (in Bytes) <0x0-0xFFFFFFFF:8>
</h>
-----------------------------------------------------------------------------*/
__ROM_BASE = 0x20200000;
__ROM_SIZE = 0x00080000; /* 512KB */
/*--------------------- Embedded RAM Configuration ----------------------------
<h> RAM Configuration
<o0> RAM Base Address <0x0-0xFFFFFFFF:8>
<o1> RAM Size (in Bytes) <0x0-0xFFFFFFFF:8>
</h>
-----------------------------------------------------------------------------*/
__RAM_BASE = 0x00008000; /* CODE_RAM + SYS_RAM */
__RAM_SIZE = 0x00060000; /* 384KB */
/*--------------------- Stack / Heap Configuration ----------------------------
<h> Stack / Heap Configuration
<o0> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
<o1> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
</h>
-----------------------------------------------------------------------------*/
__STACK_SIZE = 0x00004000; /* 16KB */
__HEAP_SIZE = 0x00019000; /* 100KB */
/*
*-------------------- <<< end of configuration section >>> -------------------
*/
MEMORY
{
FLASH (rx) : ORIGIN = __ROM_BASE, LENGTH = __ROM_SIZE
RAM (rwx) : ORIGIN = __RAM_BASE, LENGTH = __RAM_SIZE
shared_memory (!rx) : ORIGIN = 0x70000000, len = 256K
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __copy_table_start__
* __copy_table_end__
* __zero_table_start__
* __zero_table_end__
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
ENTRY(Reset_Handler)
SECTIONS
{
/* shared RAM */
SHARED (NOLOAD):
{
_sshram = . ;
*(SHAREDRAMIPC)
*(SHAREDRAM)
_eshram = . ;
_trace_start = .;
_trace_end = ORIGIN(shared_memory) + LENGTH(shared_memory);
} > shared_memory
.text :
{
_stext = .;
KEEP(*(.vectors))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
_etext = .;
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
/*
* SG veneers:
* All SG veneers are placed in the special output section .gnu.sgstubs. Its start address
* must be set, either with the command line option --section-start or in a linker script,
* to indicate where to place these veneers in memory.
*/
/*
.gnu.sgstubs :
{
. = ALIGN(32);
} > FLASH
*/
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
/* Add each additional data section here */
/*
LONG (__etext2)
LONG (__data2_start__)
LONG (__data2_end__ - __data2_start__)
*/
__copy_table_end__ = .;
} > FLASH
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
/* Add each additional bss section here */
/*
LONG (__bss2_start__)
LONG (__bss2_end__ - __bss2_start__)
*/
LONG (_sshram)
LONG (_eshram - _sshram)
__zero_table_end__ = .;
} > FLASH
/**
* Location counter can end up 2byte aligned with narrow Thumb code but
* __etext is assumed by startup code to be the LMA of a section in RAM
* which must be 4byte aligned
*/
__etext = ALIGN (4);
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data)
*(.data.*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM
/*
* Secondary data section, optional
*
* Remember to add each additional data section
* to the .copy.table above to asure proper
* initialization during startup.
*/
/*
__etext2 = ALIGN (4);
.data2 : AT (__etext2)
{
. = ALIGN(4);
__data2_start__ = .;
*(.data2)
*(.data2.*)
. = ALIGN(4);
__data2_end__ = .;
} > RAM2
*/
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM AT > RAM
/*
* Secondary bss section, optional
*
* Remember to add each additional bss section
* to the .zero.table above to asure proper
* initialization during startup.
*/
/*
.bss2 :
{
. = ALIGN(4);
__bss2_start__ = .;
*(.bss2)
*(.bss2.*)
. = ALIGN(4);
__bss2_end__ = .;
} > RAM2 AT > RAM2
*/
.heap (COPY) :
{
. = ALIGN(8);
__heap_bottom = .;
__end__ = .;
PROVIDE(end = .);
. = . + __HEAP_SIZE;
. = ALIGN(8);
__HeapLimit = .;
__heap_top = .;
} > RAM
.stack (ORIGIN(RAM) + LENGTH(RAM) - __STACK_SIZE) (COPY) :
{
. = ALIGN(8);
__StackLimit = .;
_sstack = .;
. = . + __STACK_SIZE;
. = ALIGN(8);
__StackTop = .;
_estack = .;
} > RAM
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}

View File

@@ -0,0 +1,41 @@
if (DEFINED CONFIG_ARCS_HAL_AT_CMD)
listenai_library_named(arcs_hal_at_cmd)
# Add source files
listenai_library_sources(
atcmd.c
atcmd_hash.c
atcmd_iperf.c
atcmd_lwip.c
atcmd_tcpip.c
ping.c
)
if (CONFIG_WIFI)
listenai_library_sources(
atcmd_wifi.c
)
endif()
if (CONFIG_BLE)
listenai_library_sources(
atcmd_bt.c
atcmd_bt_if.c
)
endif()
# Add include directories
listenai_include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/
)
listenai_compile_definitions(CFG_ATCMD=1)
listenai_library_compile_options_ifdef(
CONFIG_ARCS_HAL_WARNING_DISABLE
PRIVATE
-Wno-error=incompatible-pointer-types
-Wno-incompatible-pointer-types
)
endif()

View File

@@ -0,0 +1,14 @@
config ARCS_HAL_AT_CMD
bool "Enable ARCS HAL AT CMD"
default n
select ARCS_HAL_MODULE_SHELL
help
Enable AT CMD support
config ARCS_HAL_AT_CMD_BT_HCI_MODE
bool "Enable AT+BT_HCI_MODE (BT HCI test mode)"
default n
depends on ARCS_HAL_AT_CMD
help
Enable BT HCI test mode handler and its dispatch entry.

Some files were not shown because too many files have changed in this diff Show More