2024-02-29 06:43 AM
I'm working on a custom STM32U5 board with TouchGFX. The board features an external NOR flash memory used for storing the ExtFlashSection (as documented here).
In my project testing, I aim to display a simple black and white image with a transparent area. Initially, I configured TouchGFX Designer to place both the "Section" and "Extra Section" within the internal flash (IntFlashSection), and everything functioned as expected. However, my application necessitates storing media files in the external memory.
To achieve this, I successfully linked the ExtFlashSection to the external NOR flash. Subsequently, I modified the positions of both the "Section" and "Extra Section" from IntFlashSection to ExtFlashSection.
after compilation this my external memory:
When running the code, a hard fault occurs. This is likely due to TouchGFX attempting to directly fetch data from external memory during the loading of the "Extra Section" data, instead of using the BlockCopy function.
This is the Trace:
And these are the registers:
I came across this post and suspected it might be related to a known TouchGFX bug. I decided to move only the extra data to the IntFlashSection, which initially resolved the issue. However, when I tried changing the background image from bg_1.png to bg_2.png, a hard fault occurred again....here there are trace and registers
This time r1 is contains the base address for Extra Section of bg_2 in internal flash. So memory access should be ok....
What is the difference between bg_1.png and bg_2.png that could be causing this problem?
I would appreciate any suggestions or hints to resolve my problem.
2024-04-26 06:01 AM
Hello @Dadigno ,
Thank you for the extra information.
I do not have the answer myself, I am currently asking colleagues.
I will come back to you as soon as I have a potential solution.
Regards,
2024-04-29 04:44 AM
Hello @Dadigno ,
Can you try to change your images so that the black area is a color (ex: red) instead. Because, by default, the background of a TouchGFX is black. This will help us verify that everything worked properly when it does run correctly.
The extra section should be useless if not using L8. However, for image 1, your extra section is 75Kb. Can you check what those 75Kb are, what data is in there.
In your first post, you show a hardfault at the function blitCopyAlphaPerPixel but after, the hardfault is at blitCopyARGB8888solid. This function converts a ARGB8888 image into a 16 bits bitmap and copies it into the frame buffer. However, the "solid" at the end of the functions means that no transparency have been detected.
Also, for your information, first blockcopy is called and then blitCopyARGB8888solid.
Can you try to debug your blockcopy function, try to, see what size is asked, what the data looks like, etc.
Can you try to set the image without transparency to ARGB8888 and see if it runs.
Also, see if you get hardfault at blitCopyARGB8888 or at blitCopyARGB8888solid to see if the image is considered with or without transparency.
Finally, can you check that your images are actually what you want them to be (full solid color for one and half solid color plus half transparency for the other one).
Regards,
2024-04-30 06:16 AM - edited 2024-04-30 06:17 AM
Hi @GaetanGodart,
Can you try to change your images so that the black area is a color (ex: red) instead. Because, by default, the background of a TouchGFX is black. This will help us verify that everything worked properly when it does run correctly.
I repeated the tests using colored images with and without transparency, and the results are always the same. It doesn't matter if the image is colored.
The extra section should be useless if not using L8. However, for image 1, your extra section is 75Kb. Can you check what those 75Kb are, what data is in there.
If you use an image with transparencies with the designer and set the type to RGB565, all the bytes corresponding to the transparencies are collected in the extra section. Is this expected behavior and is it then handled by the core in the rendering phase even when using external memory? Can you try it yourself?
Can you try to debug your blockcopy function, try to, see what size is asked, what the data looks like, etc.
I cannot debug the blockcopy because, in the case of images with transparencies saved in external memory, it is not called!
Can you try to set the image without transparency to ARGB8888 and see if it runs.
I've done some tests and it seems it doesn't work this way either: using the ARGB8888 type with a non-transparent image saved in the external memory generates a hardfault in the blitCopyARGB8888Solid function without the blockcopy function being called. Can you check too?
Also, see if you get hardfault at blitCopyARGB8888 or at blitCopyARGB8888solid to see if the image is considered with or without transparency.
I get an hardfault at the blitCopyARGB8888 function if the top-left image starts with at least one transparent pixel, while I get an hardfault at the blitCopyARGB8888Solid function if the image starts with colored pixels (transparency in the middle). I suppose these functions are called for a portion of the image at a time and based on whether or not they contain transparent pixels.
Regards
2024-05-06 07:15 AM
Hello @Dadigno ,
Using latest TouchGFX, STM32CubeIDE and STM32CubeMX.
I have created a TouchGFX project using a STM32U5G9J DK2 (16 bits image color depth and 800*480 screen resolution).
I have created an image with transparency using Gimp.
I have added that image to my TouchGFX project.
I have also added a button to go to screen 2 (empty screen) and a button on screen 2 to go back to screen 1 to try to trigger the blockcopy function when going back to screen 1 (with transparency image).
I have also added a moving box to see hardfault in case it happens.
Case 1 : When the image is in RGB565 (section and extra section in internal) it works fine but the transparent pixels are turned black, there is an extra section.
Case 2 : When the image is in ARGB8888 (section and extra section in internal) it works fine but the transparent pixels are turned black, I can see the image being 4*800*480bytes=1.46Mb in the internal flash region, no extra section.
Case 3 : When the image is in ARGB8888 (section and extra section in external) it works fine, I can see the image being 1.46Mb in the external flash region, no extra section.
Cases X : Tried the same things with your image (bg_2.png) and got the same results.
In either case I cannot reach breakpoint on blockcopy, seems like blockcopy is never called.
I repeated the tests using colored images with and without transparency, and the results are always the same. It doesn't matter if the image is colored.
Yes, It was mostly to verify the behavior visually.
If you use an image with transparencies with the designer and set the type to RGB565, all the bytes corresponding to the transparencies are collected in the extra section. Is this expected behavior and is it then handled by the core in the rendering phase even when using external memory? Can you try it yourself?
I had the same behavior. But the behavior of RGB565 is only there for debugging in our case, we only care about ARGB.
ARGB worked fine for me.
I cannot debug the blockcopy because, in the case of images with transparencies saved in external memory, it is not called!
Since it works for regular image and because we have not found anything related to the blokccopy function, we can assume here that it works fines and look for something else.
I've done some tests and it seems it doesn't work this way either: using the ARGB8888 type with a non-transparent image saved in the external memory generates a hardfault in the blitCopyARGB8888Solid function without the blockcopy function being called. Can you check too?
Here is the definition of the blitCopy function:
/**
* Blits a 2D source-array to the framebuffer performing alpha-blending per pixel as
* specified. If ARGB8888 is not supported by the DMA a software blend is performed.
*
* @param sourceData The source-array pointer (points to the beginning of the data). The
* sourceData must be stored as 32 bits ARGB8888 values.
* @param source The location and dimensions of the source.
* @param blitRect A rectangle describing what region is to be drawn.
* @param alpha The alpha value to use for blending applied to the whole image (255 =
* solid, no blending)
*/
static void blitCopyARGB8888(const uint32_t* sourceData, const Rect& source, const Rect& blitRect, uint8_t alpha);
/**
* Blits a 2D source-array to the framebuffer never performing alpha-blending per pixel as
* because it is assumed that all pixels in the bitmap are solid (i.e. alpha for each pixel is
* 255).
*
* @param sourceData The source-array pointer (points to the beginning of the data). The
* sourceData must be stored as 32 bits ARGB8888 values.
* @param source The location and dimensions of the source.
* @param blitRect A rectangle describing what region is to be drawn.
*/
void blitCopyARGB8888Solid(const uint32_t* sourceData, const Rect& source, const Rect& blitRect) const;
Using the verb blit which means "The term "blit" is short for "block image transfer" and is a computer graphics operation in which a block of pixels is copied or moved from one area in memory to another."
So it is similar to block copy but for transparency images.
I get an hardfault at the blitCopyARGB8888 function if the top-left image starts with at least one transparent pixel, while I get an hardfault at the blitCopyARGB8888Solid function if the image starts with colored pixels (transparency in the middle). I suppose these functions are called for a portion of the image at a time and based on whether or not they contain transparent pixels.
In the description of the function they say "a 2d array" but they do not mention if it is just part of the image or the full image. Either way, at some point, it will find a pixel that has transparency completely different than the previous ones.
However, they mention 32 bits.
Can you check your linker script and make sure that your external memory is aligned for 4 bytes like so (this is the linker script of our TBS for the STM32U5G9J DK2):
ExtFlashSection :
{
*(ExtFlashSection ExtFlashSection.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x4);
} >EXT_FLASH
}
If that doesn't solve your problem.
Can you please tell me which version of tools you use.
Also, what MCU are you using?
Regards,
2024-05-07 12:49 AM - edited 2024-05-07 02:43 AM
Hi @GaetanGodart ,
during your tests did you perhaps use memory-mapped mode instead of using direct memory read and therefore BlockCopy?
Align memory for 4byte do not solve my problem.
MCU: STM32U599NJH6Q
Tools: lastest version for all of them ( Designer, STM32Cube and MX )
2024-05-24 08:12 AM
Hi @GaetanGodart ,
Do you have any updates for me?
I can run additional tests if it helps. It is crucial for us to resolve this issue, otherwise we cannot proceed with the project using this framework and will be forced to find an alternative.
Regards,
2024-05-24 09:38 AM
Hello
This could be silly question, but are caching the bitmaps, like this document instructs:
After reading this document
I think it is necessary to cahe bitmaps to ram when using non-memory-mapped flash.
But I could be wrong, I'm a complete newbie in this field as well :grinning_face_with_sweat:
Br JTP
2024-05-24 10:07 AM
I mean idea not use memory-mapped mode isnt way here. Why you dont use memory-mapped mode ?
2024-05-26 11:57 PM
Hi @JTP1 , There is no such thing as a *** question, only *** answers cit.
I'm not caching bitmaps, and I think the problem would still occur because I need to call the BlockCopy function to access the external memory, even for images with transparency.
2024-05-27 12:02 AM