Skip to content

Commit

Permalink
Example on Zynq®-7000
Browse files Browse the repository at this point in the history
  • Loading branch information
Boris committed Aug 17, 2023
1 parent 21a4496 commit 0c26fd9
Show file tree
Hide file tree
Showing 28 changed files with 167,432 additions and 195 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ bld/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/

# Xilinx SDK
webtalk/


# Visual Studio 2017 auto generated files
Generated\ Files/

Expand Down
8 changes: 5 additions & 3 deletions Examples/Xilinx/ZYBOZ7/DemoRTSHA/.cproject
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
<tool id="xilinx.gnu.armv7.cxx.toolchain.compiler.debug.541797115" name="ARM v7 g++ compiler" superClass="xilinx.gnu.armv7.cxx.toolchain.compiler.debug">
<option defaultValue="gnu.c.optimization.level.none" id="xilinx.gnu.compiler.option.optimization.level.1815619909" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" value="gnu.c.optimization.level.none" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.1068260221" name="Debug Level" superClass="xilinx.gnu.compiler.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.666116975" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.666116975" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes"/>
<option id="xilinx.gnu.compiler.misc.other.669344370" name="Other flags" superClass="xilinx.gnu.compiler.misc.other" value="-c -fmessage-length=0 -MT&quot;$@&quot; -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard" valueType="string"/>
<option id="xilinx.gnu.compiler.dircategory.includes.793247203" name="Include Paths" superClass="xilinx.gnu.compiler.dircategory.includes" valueType="includePath">
<listOptionValue builtIn="false" value="../../DemoRTSHA_bsp0/ps7_cortexa9_0/include"/>
Expand Down Expand Up @@ -112,15 +112,16 @@
<inputType id="xilinx.gnu.armv7.c.compiler.input.1743050683" name="C source files" superClass="xilinx.gnu.armv7.c.compiler.input"/>
</tool>
<tool id="xilinx.gnu.armv7.cxx.toolchain.compiler.release.1820516951" name="ARM v7 g++ compiler" superClass="xilinx.gnu.armv7.cxx.toolchain.compiler.release">
<option defaultValue="gnu.c.optimization.level.more" id="xilinx.gnu.compiler.option.optimization.level.1635346409" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option defaultValue="gnu.c.optimization.level.more" id="xilinx.gnu.compiler.option.optimization.level.1635346409" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" value="gnu.c.optimization.level.most" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.1297503381" name="Debug Level" superClass="xilinx.gnu.compiler.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.145403029" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.145403029" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes"/>
<option id="xilinx.gnu.compiler.misc.other.421504139" name="Other flags" superClass="xilinx.gnu.compiler.misc.other" value="-c -fmessage-length=0 -MT&quot;$@&quot; -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard" valueType="string"/>
<option id="xilinx.gnu.compiler.dircategory.includes.530936438" name="Include Paths" superClass="xilinx.gnu.compiler.dircategory.includes" valueType="includePath">
<listOptionValue builtIn="false" value="../../DemoRTSHA_bsp0/ps7_cortexa9_0/include"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/DemoRTSHA/../../../../Include}&quot;"/>
<listOptionValue builtIn="false" value="../../Include"/>
<listOptionValue builtIn="false" value="../Include"/>
<listOptionValue builtIn="false" value="../../../../../include"/>
</option>
<inputType id="xilinx.gnu.armv7.cxx.compiler.input.1335291458" name="C++ source files" superClass="xilinx.gnu.armv7.cxx.compiler.input"/>
</tool>
Expand Down Expand Up @@ -160,6 +161,7 @@
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule moduleId="ilg.gnuarmeclipse.managedbuild.packs"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
Expand Down
144 changes: 144 additions & 0 deletions Examples/Xilinx/ZYBOZ7/DemoRTSHA/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Real Time Safety Heap Allocator (RTSHA) Demo on Digilent ZYBOZ7 ZYNQ-7020 Development Board



> [!WARNING]
> This project is currently a work in progress. The release of the initial version is tentatively scheduled for December. Please consider this before using the code.

## Overview

The provided code showcases how to manage and utilize a custom heap storage system within an application based on the Cortex-A9, specifically on the Xilinx Zynq®-7000 SoC platform.
The code demonstrates how the standard heap functions (malloc, free, etc.) from the standard library and FreeRTOS have been overridden with RTSHA functions. It provides insights into memory allocation, heap configurations, and details about overloading new and delete operators.
Moreover, this implementation measures and reports the performance of its heap operations (in terms of CPU cycles), providing insights into the efficiency of the memory management operations.

The Cortex-A9 (I-Cache) and data (D-Cache) caches are enabled.

## Details

## Memory Setup

The linker script is responsible for defining the layout of the program in memory. One of the critical settings in the linker file pertains to the memory segments or regions, which define the starting location and length of each memory block used by the application.

**Original Setting**

ps7_ddr_0 : ORIGIN = 0x100000, LENGTH = 0x3FF00000

This line indicates that there's a DDR RAM segment named ps7_ddr_0 starting at the memory address 0x100000. The LENGTH value of 0x3FF00000 suggests the size of this memory block, which was quite substantial.

**Updated Settings**

To accommodate more precise memory management requirements, especially for multi-core processing and specialized heap handling, the original setting was split into four separate segments:

1. Application Memory for CPU0:

ps7_ddr_0 0x100000 0x10000000

This setting reserves memory specifically for the application running on CPU0. It starts from the address 0x100000 and spans 0x10000000 bytes.

2. RTSHA Heap Memory:

ps7_ddr_1 0x10100000 0x10000000

The RTSHA (Real-Time Safe Heap Allocator) requires a dedicated segment for the heap. This segment starts at 0x10100000 and spans 256MB (or 0x10000000 bytes).

3. Reserved Memory for a Potential Second CPU Core:

ps7_ddr_2 0x10200000 0x10000000

Though not utilized in the current configuration, this memory segment is reserved for potential use with a second CPU core. Starting at 0x10200000, it also spans 256MB.

4. Another Reserved Block for the Second CPU Core:

ps7_ddr_3 0x10300000 0x0FF00000

This is an additional reserved memory block for the second CPU core, starting at address 0x10300000. The size is slightly less than the previous blocks, spanning 0x0FF00000 bytes.


The heap used by this demo, specifically on CPU0, begins at the address 0x10200000. With a length of 0x10000000 bytes, it spans 256MB. It's worth noting that this dedicated heap space is integral for systems that demand predictable and efficient memory allocation, especially in real-time scenarios.

Implications

By breaking down the memory into specific segments, the system can achieve:

**Isolation:** Preventing one part of the system (like the RTSHA heap) from inadvertently affecting another.
**Optimization:** Ensuring that each CPU has its dedicated memory, reducing contention.
**Flexibility:** Reserved segments mean that future adaptations (like integrating a second CPU core) become easier.

Such granularity and deliberate segmentation are crucial in embedded and real-time systems where efficient memory management can make a significant difference in performance and reliability.


## Overloaded New and Delete

The operators new and delete have been overloaded, redirecting memory allocation and deallocation to the RTSHA heap functions instead of the standard malloc and free.
For detailed implementation, refer to the newnew.cpp file.

## Overriding Default Memory Management

Standard heap functions are overridden using RTSHA functions. This is further explained in newmalloc.cpp.
It's crucial to ensure safe memory management practices to prevent memory leaks and undefined behavior.

## Heap Initialization

The function rtsha_create_heap initializes the heap, specifying its start address and size.
Pages with specific sizes and purposes can be added to this heap using the rtsha_add_page function.

The example demonstrates adding pages of types RTSHA_PAGE_TYPE_32, RTSHA_PAGE_TYPE_64, and RTSHA_PAGE_TYPE_POWER_TWO.

## Usage

Ensure that you have the required hardware platform and setup.
Deploy the code.
Monitor the log outputs to see the memory management in action and the performance metrics.

Memory can be allocated and deallocated using rtsha_malloc and rtsha_free, respectively.
Additional functions like rtsha_memset and rtsha_memcpy allow for common safety memory operations.
In the example, the time taken for allocations and deallocations is measured in CPU cycles using the XTime_GetTime function.


## Important Reminders

Ensure memory safety and proper management to prevent memory leaks and undefined behavior.
Handle allocations and deallocations appropriately. Failure to do so can lead to system instability.

## Example Outputs

The code sends formatted strings to a UART terminal, reporting the performance (in terms of cycles) of various heap operations. It will report either the performance metrics or an error message if the operation fails.

Example Output:

Power2 Page rtsha_malloc: 1436 cycles, rtsha_free: 775 cycles MaxM=3563 MaxF=1470
Small Fix Page rtsha_malloc: 487 cycles, rtsha_free: 350 cycles


## Measured Performance


Based on the results obtained from the system's profiling, here are the performance metrics in terms of CPU cycles for the memory operations:

**CPU Frequency: 333Mhz**

Measured Performance for Release Version:

*Power2 Page:*
rtsha_malloc: 963 to 3563 Cycles
rtsha_free: 726 to 1470 Cycles

This represents the time taken for memory allocation and deallocation in a flexible page system that can handle a range of block sizes in power-of-two increments,
up to a specified maximum. These metrics are crucial for understanding the efficiency of the RTSHA heap system.
Depending on the application's requirements, developers can utilize these metrics to optimize memory operations further and make informed decisions regarding
which type of page to use for different allocation needs.

*Small Fix Page:*
rtsha_malloc: 450 to 560 Cycles
rtsha_free: 330 to 400 Cycles

This represents the time taken for memory allocation and deallocation for smaller fixed-size pages, specifically designed for handling memory chunks less than 32 bytes.

## Potential Improvements

**Error handling:** While the code checks for memory allocation errors, robust applications might require more comprehensive error handling and recovery mechanisms.

**Code Modularization:** Depending on the project's size, consider splitting the memory management, performance measurement, and reporting functionalities into separate modules or functions for better code organization.

**Performance:** Try investigate other compiler flags that might be specific to your toolchain and beneficial to your application.
29 changes: 23 additions & 6 deletions Examples/Xilinx/ZYBOZ7/DemoRTSHA/src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ void onHeapError( uint32_t errorCode )

SemaphoreHandle_t xSemaphore;

void HeapLock()
inline void HeapLock()
{
xSemaphoreTake(xSemaphore, portMAX_DELAY);
}

void HeapUnLock()
inline void HeapUnLock()
{
xSemaphoreGive(xSemaphore);
}
Expand All @@ -71,6 +71,7 @@ int main()

init_platform();


_heap = NULL;

HeapCallbacksStruct callbacks;
Expand Down Expand Up @@ -212,15 +213,20 @@ void prvTestThread(void *pvParam)
uint32_t val = 0U;
uint32_t val32m = 0U;
uint32_t val32f = 0U;
uint32_t total_cycles_malloc, total_cycles_free;
uint32_t total_cycles_malloc, total_cycles_free, maxm, maxf;

XTime tStart, tEnd;
XTime tStart, tEnd, sec0, sec1;

maxm = 0U;
maxf = 0U;
while(1)
{
total_cycles_malloc = 0U;

XTime_GetTime(&sec0);
vTaskDelay(pdMS_TO_TICKS(1000U));
XTime_GetTime(&sec1);

total_cycles_malloc = 0U;
XTime_GetTime(&tStart);
memory1 = rtsha_malloc(2000U);
XTime_GetTime(&tEnd);
Expand All @@ -244,6 +250,12 @@ void prvTestThread(void *pvParam)
total_cycles_malloc = val;
}

if( total_cycles_malloc > maxm )
{
maxm = total_cycles_malloc;
}


XTime_GetTime(&tStart);
rtsha_free(memory1);
XTime_GetTime(&tEnd);
Expand All @@ -268,6 +280,11 @@ void prvTestThread(void *pvParam)
total_cycles_free = val;
}

if( total_cycles_free > maxf )
{
maxf = total_cycles_free;
}


/*The small RTSHA_PAGE_TYPE_32 will be used automatically*/
XTime_GetTime(&tStart);
Expand All @@ -283,7 +300,7 @@ void prvTestThread(void *pvParam)

if( memory1 != NULL )
{
sprintf( (char*) data, (const char*) "Power2 Page rtsha_malloc: %u cycles, rtsha_free: %u cycles\n\r", (int) total_cycles_malloc, total_cycles_free);
sprintf( (char*) data, (const char*) "Power2 Page rtsha_malloc: %u cycles, rtsha_free: %u cycles MaxM=%u MaxF=%u\n\r", (int) total_cycles_malloc, total_cycles_free, maxm, maxf);
}
else
{
Expand Down
29 changes: 3 additions & 26 deletions Examples/Xilinx/ZYBOZ7/DemoRTSHA/src/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,34 +35,11 @@

#include "platform_config.h"

/*
* Uncomment one of the following two lines, depending on the target,
* if ps7/psu init source files are added in the source directory for
* compiling example outside of SDK.
*/
/*#include "ps7_init.h"*/
/*#include "psu_init.h"*/

#ifdef STDOUT_IS_16550
#include "xuartns550_l.h"

#define UART_BAUD 9600
#endif

void
enable_caches()
void enable_caches()
{
#ifdef __PPC__
Xil_ICacheEnableRegion(CACHEABLE_REGION_MASK);
Xil_DCacheEnableRegion(CACHEABLE_REGION_MASK);
#elif __MICROBLAZE__
#ifdef XPAR_MICROBLAZE_USE_ICACHE
Xil_ICacheEnable();
#endif
#ifdef XPAR_MICROBLAZE_USE_DCACHE
Xil_DCacheEnable();
#endif
#endif
Xil_ICacheEnable();
Xil_DCacheEnable();
}

void
Expand Down
12 changes: 12 additions & 0 deletions Examples/Xilinx/ZYBOZ7/RemoteSystemsTempFiles/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>RemoteSystemsTempFiles</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
<nature>org.eclipse.rse.ui.remoteSystemsTempNature</nature>
</natures>
</projectDescription>
41 changes: 41 additions & 0 deletions Examples/Xilinx/ZYBOZ7/system_wrapper_hw_platform_0/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>system_wrapper_hw_platform_0</name>
<comment>Created by SDK v2019.1</comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
<nature>com.xilinx.sdk.hw.HwProject</nature>
</natures>
<filteredResources>
<filter>
<id>1692173467941</id>
<name></name>
<type>6</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-*.xml</arguments>
</matcher>
</filter>
<filter>
<id>1692173467949</id>
<name></name>
<type>6</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-*.svd</arguments>
</matcher>
</filter>
<filter>
<id>1692173467958</id>
<name></name>
<type>6</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-*.hwh</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>
Loading

0 comments on commit 0c26fd9

Please sign in to comment.