2025-09-21 4:27 AM - edited 2025-09-21 6:48 AM
Hi, I have been using NemaGFX on STM32U5G9J-DK2 kit with no problems.
My luck with the STM32H7S78-DK kit, however, is different.
1. The NemaGFX for this platform only seems to work with 32-bit framebuffers, not 24-bit ones. Or am I doing something wrong?
2. The NemaGFX for this platform uses the beginning of the framebuffer as a sort of workspace. We see random dots at the beginning. I think I'm having trouble allocating buffers correctly.
3. I can draw filled rectangles, but filled circles with 'nema_vg_draw_circle' only show the edge slightly and produce small images in a sort of workspace at the beginning of the frame buffer.
nema_vg_set_fill_rule(NEMA_VG_FILL_NON_ZERO); does not fill the shape, as it should.
nema_vg_set_fill_rule(NEMA_VG_FILL_EVEN_ODD); It does, but there still are the four small images in the frame buffer displayed in white.
What am I doing wrong?
My nema_hal.c looks like this:
#include <stdlib.h>
#include <string.h>
#include "nema_hal.h"
#include "nema_vg.h"
#include "nema_graphics.h"
#include "main.h"
#include "gpu2d.h"
#include "stm32h7rsxx_hal.h"
#include "stm32h7rsxx_hal_gpu2d.h"
#define RING_SIZE 1024 /* Ring Buffer Size in byte */
#if defined(STM32H7S7xx)
#define NEMAGFX_MEM_POOL_SIZE 10240 /* NemaGFX byte pool size in byte */
#define NEMAGFX_STENCIL_POOL_SIZE DISPLAY_FRAMEBUFFER_SIZE /* NemaGFX stencil buffer pool size in byte */
/* NemaGFX frame buffer memory 0x90000000 */
//uint8_t FrameBuffer[DISPLAY_NO_OF_FRAMEBUFFERS][DISPLAY_FRAMEBUFFER_SIZE] __attribute__((section("Nemagfx_Framebuffer")));
#if (DISPLAY_BYTES_PER_PIXEL == 2)
Color_RGB565_t FrameBuffer[DISPLAY_NO_OF_FRAMEBUFFERS][DISPLAY_SIZE_H][DISPLAY_SIZE_W] __attribute__((section("Nemagfx_Framebuffer")));
#elif (DISPLAY_BYTES_PER_PIXEL == 3)
Color_RGB888_t FrameBuffer[DISPLAY_NO_OF_FRAMEBUFFERS][DISPLAY_SIZE_H][DISPLAY_SIZE_W] __attribute__((section("Nemagfx_Framebuffer")));
#elif (DISPLAY_BYTES_PER_PIXEL == 4)
Color_RGBA8888_t FrameBuffer[DISPLAY_NO_OF_FRAMEBUFFERS][DISPLAY_SIZE_H][DISPLAY_SIZE_W] __attribute__((section("Nemagfx_Framebuffer")));
#endif
/* NemaGFX stencil buffer memory 0x90000000 DISPLAY_FRAMEBUFFER_SIZE=800*480*4=1536000 */
uint8_t StencilBuffer[DISPLAY_FRAMEBUFFER_SIZE] __attribute__((section("Nemagfx_Framebuffer")));
/* NemaGFX memory pool 10240 bytes */
static uint8_t nemagfx_pool_mem[NEMAGFX_MEM_POOL_SIZE] __attribute__((section("Nemagfx_Memory_Pool_Buffer"))); /* Good */
// NemaGFX_t NemaGFX __attribute__((section("Nemagfx_Memory_Pool_Buffer_RAM_CMD")));
#endif /* STM32H7S7xx */
/* NemaGFX ring buffer memory */
static nema_ringbuffer_t ring_buffer_str = {{0}};
static volatile int last_cl_id = -1;
void HAL_GPU2D_CommandListCpltCallback(GPU2D_HandleTypeDef *hgpu2d, uint32_t CmdListID)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hgpu2d);
last_cl_id = CmdListID;
}
int32_t nema_sys_init(void)
{
/*
* NEMA| GFX includes the following API calls for memory allocation, deallocation and mapping:
* - nema_buffer_create() - Allocate memory
* - nema_buffer_create_pool() - Allocate memory from specific memory pool
* - nema_buffer_map() - Map allocated memory space for CPU access
* - nema_buffer_unmap() - Unmap previously mapped memory space
* - nema_buffer_destroy() - Deallocate memory space
*
*/
int error_code = 0;
/* Initialize GPU2D */
hgpu2d.Instance = GPU2D;
HAL_GPU2D_Init(&hgpu2d);
#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1)
/* Register Command List Comlete Callback */
HAL_GPU2D_RegisterCommandListCpltCallback(&hgpu2d, GPU2D_CommandListCpltCallback);
#endif /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 1 */
/* Allocate ring_buffer memory */
#if defined(STM32U599xx) || defined(STM32U5A9xx) || defined(STM32U5G9xx)
ring_buffer_str.bo = nema_buffer_create_pool(0, RING_SIZE);
// (void)nema_buffer_map(&ring_buffer_str.bo);
#elif defined(STM32H7S7xx)
ring_buffer_str.bo.base_virt = nemagfx_pool_mem;
ring_buffer_str.bo.base_phys = (uint32_t)ring_buffer_str.bo.base_virt;
ring_buffer_str.bo.size = RING_SIZE;
ring_buffer_str.bo.fd = 0; /* Buffer allocated */
#endif
/* Initialize Ring Buffer */
error_code = nema_rb_init(&ring_buffer_str, 1);
if (error_code < 0)
{
return error_code;
}
/* Reset last_cl_id counter */
last_cl_id = 0;
return error_code;
}
void nema_stencil_init(void)
{
/* This disturbs FrameBuffer[0] */
/**
* brief Initializes NemaVG library and allocates the stencil buffer to the default memory pool (NEMA_MEM_POOL_FB)
* Call either this or nema_vg_init_stencil_pool to allocate the stencil buffer to a different memory pool
* or nema_vg_init_stencil_prealloc to provide the stencil buffer
* \param width Stencil buffer width - Must be the first multiple of 4 that is equal to or greater than framebuffer width
* \param height Stencil buffer height - Must be the first multiple of 4 that is equal to or greater than framebuffer height
*/
nema_vg_init(DISPLAY_SIZE_W, DISPLAY_SIZE_H);
}
int nema_wait_irq(void)
{
return 0;
}
int nema_wait_irq_cl(int cl_id)
{
while (last_cl_id < cl_id)
{
(void)nema_wait_irq();
}
return 0;
}
int nema_wait_irq_brk(int brk_id)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(brk_id);
while (nema_reg_read(GPU2D_BREAKPOINT) == 0U)
{
(void)nema_wait_irq();
}
return 0;
}
uint32_t nema_reg_read(uint32_t reg)
{
return HAL_GPU2D_ReadRegister(&hgpu2d, reg);
}
void nema_reg_write(uint32_t reg, uint32_t value)
{
HAL_GPU2D_WriteRegister(&hgpu2d, reg, value);
}
/* Used to select the framebuffer */
nema_buffer_t nema_buffer_create_pool(int pool, int size)
{
nema_buffer_t bo;
#if defined(STM32U599xx) || defined(STM32U5A9xx) || defined(STM32U5G9xx)
/* Prevent unused argument(s) compilation warning */
UNUSED(pool);
bo.base_virt = malloc(size);
#elif defined(STM32H7S7xx)
bo.base_virt = FrameBuffer[pool + 1];
#endif
bo.base_phys = (uint32_t)bo.base_virt;
bo.size = size;
bo.fd = 0; /* Buffer allocated */
// SCB_CleanInvalidateDCache_by_Addr((uint32_t *)bo.base_virt, bo.size);
return bo;
}
void *nema_buffer_map(nema_buffer_t *bo)
{
return bo->base_virt;
}
void nema_buffer_unmap(nema_buffer_t *bo)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(bo);
}
void nema_buffer_destroy(nema_buffer_t *bo)
{
if (bo->fd == -1)
{
return; /* Buffer weren't allocated! */
}
#if defined(STM32U599xx) || defined(STM32U5A9xx) || defined(STM32U5G9xx)
free(bo->base_virt);
#endif
bo->base_virt = (void*)0;
bo->base_phys = 0;
bo->size = 0;
bo->fd = -1; /* Buffer not allocated */
}
uintptr_t nema_buffer_phys(nema_buffer_t *bo)
{
return bo->base_phys;
}
void nema_buffer_flush(nema_buffer_t * bo)
{
#if defined(NEMA_CACHED_MEMORY)
SCB_CleanInvalidateDCache_by_Addr((uint32_t *)bo->base_virt, bo->size);
#else /* !NEMA_CACHED_MEMORY */
/* Prevent unused argument(s) compilation warning */
UNUSED(bo);
#endif /* NEMA_CACHED_MEMORY */
}
void nema_host_free(void *ptr)
{
if (ptr)
{
free(ptr);
}
}
void *nema_host_malloc(unsigned size)
{
return malloc(size);
}
int nema_mutex_lock(int mutex_id)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(mutex_id);
return 0;
}
int nema_mutex_unlock(int mutex_id)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(mutex_id);
return 0;
}
void platform_disable_cache(void)
{
}
void platform_invalidate_cache(void)
{
}
When I run nema_stencil_init(), a row of white dots appears at the beginning of the framebuffer.
This happens if this function calls one of these:
- nema_vg_init()
- nema_vg_init_stencil_pool(DISPLAY_SIZE_W, DISPLAY_SIZE_H, 1);
- nema_vg_init_stencil_prealloc(fbo.w, fbo.h, stencil_bo);
So something is definitely wrong. Even when nema_vg_init() is executed, this seems to happen, regardless of where my framebuffer is located.
My ld file looks like this:
/*
******************************************************************************
**
** @file : LinkerScript.ld
**
** @author : STM32CubeIDE
**
** Abstract : Linker script for STM32H7Sxx Device
**
** 64KBytes FLASH
** 456KBytes RAM
**
** 256MBytes EXTFLASH
** 32MBytes EXTRAM
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used
**
** Target : STM32H7S7L8
**
******************************************************************************
** @attention
**
** Copyright (c) 2025 STMicroelectronics.
** All rights reserved.
**
** This software is licensed under terms that can be found in the LICENSE file
** in the root directory of this software component.
** If no LICENSE file comes with this software, it is provided AS-IS.
**
******************************************************************************
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = ORIGIN(DTCM) + LENGTH(DTCM); /* end of "DTCM" Ram type memory */
_Min_Heap_Size = 0x1000; /* required amount of heap */
_Min_Stack_Size = 0x2000; /* required amount of stack */
__RAM_BEGIN = 0x24000000;
__RAM_SIZE = 0x00072000; /* 456kB */
__FLASH_BEGIN = 0x70000000; /* XSPI2 0x70000000 - 0x7FFFFFFF EXTFLASH 256MB */
__FLASH_SIZE = 0x10000000; /* XSPI2 EXTFLASH 256MB */
__EXTFLASH_BEGIN = 0x70000000; /* XSPI2 0x70000000 - 0x7FFFFFFF EXTFLASH 256MB */
__EXTFLASH_SIZE = 0x10000000; /* XSPI2 EXTFLASH 256MB */
__EXTRAM_BEGIN = 0x90000000; /* XSPI1 0x90000000 - 0x92000000 EXTRAM 32MB */
__EXTRAM_SIZE = 0x02000000; /* XSPI1 EXTRAM 32MB */
/* Memories definition */
MEMORY
{
RAM (rw) : ORIGIN = 0x24000000, LENGTH = 0x0006e000 /* 0x24000000 - 0x2406E000 440kB */
RAM_CMD (rw) : ORIGIN = 0x2406E000, LENGTH = 0x00004000 /* 0x2406E000 - 0x24072000 16kB Nemagfx_Memory_Pool_Buffer nemagfx_pool_mem */
ITCM (xrw) : ORIGIN = 0x00000000, LENGTH = 0x00010000
DTCM (rw) : ORIGIN = 0x20000000, LENGTH = 0x00010000
SRAMAHB (rw) : ORIGIN = 0x30000000, LENGTH = 0x00008000
BKPSRAM (rw) : ORIGIN = 0x38800000, LENGTH = 0x00001000
FLASH (xr) : ORIGIN = 0x70000000, LENGTH = 0x01000000 /* XSPI2 0x70000000 - 0x707FFFFF EXTFLASH 16MB */
FLASH_GFX (r) : ORIGIN = 0x71000000, LENGTH = 0x0FE00000 /* XSPI2 0x70800000 - 0x7FFFFFFF EXTFLASH 256-8=240MB */
EXTFLASH (xr) : ORIGIN = 0x70000000, LENGTH = 0x10000000 /* XSPI2 0x70000000 - 0x7FFFFFFF EXTFLASH 256MB */
EXTRAM (rw) : ORIGIN = 0x90000000, LENGTH = 0x02000000 /* XSPI1 0x90000000 - 0x92000000 EXTRAM 32MB */
}
/* Sections */
SECTIONS
{
/* The startup code into "FLASH" FLASH type memory */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/* The program code and other data into "FLASH" FLASH type memory */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH
/* Constant data into "FLASH" FLASH type memory */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
.ARM.extab (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
. = ALIGN(4);
*(.ARM.extab* .gnu.linkonce.armextab.*)
. = ALIGN(4);
} >FLASH
.ARM (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
. = ALIGN(4);
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
. = ALIGN(4);
} >FLASH
.preinit_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
. = ALIGN(4);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
} >FLASH
.init_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
. = ALIGN(4);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
} >FLASH
.fini_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
. = ALIGN(4);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(4);
} >FLASH
/* Used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections into "RAM" Ram type memory */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
*(.RamFunc) /* .RamFunc sections */
*(.RamFunc*) /* .RamFunc* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH
/* Uninitialized data section into "RAM" Ram type memory */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss section */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
/* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >DTCM
/* Remove information from the compiler libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
BufferSection (NOLOAD) :
{
*(Nemagfx_Framebuffer Nemagfx_Framebuffer.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x8);
} >EXTRAM
UncachedSection (NOLOAD) :
{
*(Nemagfx_Memory_Pool_Buffer Nemagfx_Memory_Pool_Buffer.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x8);
*(Nemagfx_Ring_Buffer Nemagfx_Ring_Buffer.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x8);
*(Nemagfx_Memory_Pool_Buffer_RAM_CMD Nemagfx_Memory_Pool_Buffer_RAM_CMD.*) /* nemagfx_pool_mem 16kB 0x2406E000 */
*(.gnu.linkonce.r.*)
. = ALIGN(0x8);
} >RAM_CMD
FontFlashSection :
{
*(FontFlashSection FontFlashSection.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x4);
} >FLASH_GFX
TextFlashSection :
{
*(TextFlashSection TextFlashSection.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x4);
} >FLASH_GFX
ExtFlashSection :
{
*(ExtFlashSection ExtFlashSection.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x4);
} >FLASH_GFX
}
My MPU configuration:
static void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
/* Disables the MPU */
HAL_MPU_Disable();
/* Disables all MPU regions */
for(uint8_t i=0; i<__MPU_REGIONCOUNT; i++)
{
HAL_MPU_DisableRegion(i);
}
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x00000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
MPU_InitStruct.SubRegionDisable = 0x87;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/**
* Initializes and configures the Region and the memory to be protected
* XSPI2 Range 0x70000000 - 0x7FFFFFFF, Size 0x10000000 = 256MB
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0x70000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256MB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/**
* Initializes and configures the Region and the memory to be protected
* XSPI2 Range 0x70000000 - 0x70200000, Size 0x00200000 = 2MB
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.BaseAddress = 0x70000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_2MB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/**
* Initializes and configures the Region and the memory to be protected
* XSPI1 Range 0x90000000 - 0x91FFFFFF, Size 0x02000000 = 32MB
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER3;
MPU_InitStruct.BaseAddress = 0x90000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_32MB;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/**
* Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER4;
MPU_InitStruct.BaseAddress = 0x20000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_64KB;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/**
* Initializes and configures the Region and the memory to be protected
* RAM Range 0x24000000 - 0x24080000, Size 0x00080000 = 512kB
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER5;
MPU_InitStruct.BaseAddress = 0x24000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/**
* Initializes and configures the Region and the memory to be protected
* RAM_CMD for GPU2D - Nemagfx_Memory_Pool_Buffer nemagfx_pool_mem 16kB
* RAM Range 0x2406E000 - 24072000, Size 0x00004000 = 16kB
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER6;
MPU_InitStruct.BaseAddress = 0x2406E000;
MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; /* For GPU2D - no cache! */
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enables the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
What can I to better?
Thanks for any help, it is much appreciated!