2020-06-28 12:29 AM
I try to make a TouchFGX demo for a self designed STM32F750 board.
The board hardware is verified, it works with my "hand made" simple test image graphics. The board does not have any kind of touch input, but some hardware-buttons.
And the memory layout is a bit special.
There is the internal FLASH and SRAM of the STM32F750 extended by 32 MB SDRAM and 32MB SPI flash. In the internal STM32 FLASH a bootloader exists that provides the QSPI as a USB-Memory to an USB attached PC and can use it as a read-only FATFS for itself as well.
At startup the bootloader looks for the application file in FATFS, verifies it and copies it to internal SRAM for execution. The SDRAM is for frame buffer, constants, variables and heap. The QSPI FLASH can be used by application to load assets.
This mechanism allows very easy firmware updates by just drag-and drop the firmware application in the PC's file explorer. The mechanism is fully verified and operating well with other firmware applications.
Now I set-up a TouchGFX project for STM32CubeIDE using STM32CubeMX and TouchGFX Designer as described step-by-step in the online documentation (https://support.touchgfx.com/docs/development/touchgfx-hal-development/touchgfx-al-development-introduction).
This application uses FreeRTOS and all tools and packages are updated to the latest available versions.
But the TouchGFX application fails immediately at startup whith a hardfault within the MX_TouchGFX_Init() function. The debugger is of not much help here, because the fault happens in a pre-compiled part of the TouchGFX library:
Any hints or ideas where to look for a solution of this are more than welcome.
EDIT: Additional Infos:
The bootloader copied the entire application and all of its sections from QSPI FLASH to SDRAM. To overcome some memory bandwidth limitations, the startup code of the application copies most sectors to internal SRAM. The sectors copied are:
text
arm_extab
_exidx
_preinit_array
_init_array
_fini_array
The linker file is made such that the different load and execution addresses are handled correctly.
Maybe I did miss a section here?
Regards
Thomas
Solved! Go to Solution.
2020-11-03 03:15 AM
@FBrag.1 Hi Federico,
thank you for pushing me in the right direction. Actually I had the CRC peripheral enabled and still got the Hard Fault. But your post reminded me that I had a similar issue with STemWIN some time ago. And the same solution works for TouchGFX, too:
1) Ensure CRC is enabled
2) Ensure CRC is in its reset default state!
The problem was not only CRC usage in main application, but I also used the CRC in my boot-loader to verify application data in QSPI-Flash.
And HAL_CRC_DeInit() does *not* reset CRC to its reset state. It keeps INIT and POLY values untouched!
Then a dedicated HAL_CRC_Init() with default reset values did the trick:
hcrc.Instance = CRC;
hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE;
hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE;
hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;
hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_WORDS;
if (HAL_CRC_Init(&hcrc) != HAL_OK) {
Error_Handler();
}
I know this is bit of a special scenatio. But it should be mentioned in official documentation, that CRC has to be in its default state to make TouchGFX work.
Regards
Thomas
2020-06-28 11:22 PM
Hey Thomas,
I would increase the stack task size.
2020-06-29 01:17 AM
Hi MMoon,
thank you for the hint. But I am afraid this does not help.
MX_TouchGFX_Init() gets called in main before osKernelStart(). So there is no task scheduling and therefore no task stack at that time. I tried to call MX_TouchGFX_Init() in my default task, too. But that does not change anything. And debugger tells me there is no stack over/underflow.
My main problem is, that I do not have source code of the failing function call touchgfx::Screen::draw(). So I cannot see which access causes the fault in detail.
I guess I missed some initialization, or there is an issure with peripherals being initialized and running by the boot-loader already?
Regards
Thomas
2020-10-21 03:08 AM
Hi TThan
I got a similar problem. To resolve it, I had to enable the CRC peripheral (which I disabled manually since not used for my project).
It seems that TouchGFX requires it as check that it is running on an STM32 MCU.
I found here the solution:
https://community.st.com/s/question/0D50X0000AaXtnBSQS/hardfault-when-upgrading-touchgfx-493-to-4100
And here the reference on the TouchGFX website:
https://support.touchgfx.com/docs/miscellaneous/known-issues#upgrading-from-49x
I cannot understand why this information is so deep buried in the "known-issues" page.
It should be highlighted somewhere in the board bringup section or similar.
Regards
Federico
2020-10-23 02:51 AM
If you're using CubeMX, the Generator should warn you that CRC is not enabled. Have you tried to step through the Init function to see where it fails? Another option is that you haven't configured QSPI correctly (TouchGFX will start accessing it).
/Martin
2020-10-28 01:40 PM
I agree with Martin. If your QSPI FLASH isn't configured to be programmed (likely need an external loader), it will do this.
2020-11-03 03:15 AM
@FBrag.1 Hi Federico,
thank you for pushing me in the right direction. Actually I had the CRC peripheral enabled and still got the Hard Fault. But your post reminded me that I had a similar issue with STemWIN some time ago. And the same solution works for TouchGFX, too:
1) Ensure CRC is enabled
2) Ensure CRC is in its reset default state!
The problem was not only CRC usage in main application, but I also used the CRC in my boot-loader to verify application data in QSPI-Flash.
And HAL_CRC_DeInit() does *not* reset CRC to its reset state. It keeps INIT and POLY values untouched!
Then a dedicated HAL_CRC_Init() with default reset values did the trick:
hcrc.Instance = CRC;
hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE;
hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE;
hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;
hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_WORDS;
if (HAL_CRC_Init(&hcrc) != HAL_OK) {
Error_Handler();
}
I know this is bit of a special scenatio. But it should be mentioned in official documentation, that CRC has to be in its default state to make TouchGFX work.
Regards
Thomas