2020-03-11 03:06 AM
I've generated a STM32F429I-DISCO project using CubeIDE's CubeMX.
I've added the X-CUBE-TOUCHGFX 4.13.0 software to the project, under Additional Software.
By changing LTDC and FMC settings, I was able to configure X-CUBE-TOUCHGFX successfully.
The project had a file with a .part extension. (I can't remember the filename, but an ApplicationTemplate.touchgfx.part still exists, it might well be that.) Clicking that launched TouchGFX Designer.
I used the designer to choose a template project, saved it and also clicked Generate Code.
Exiting TouchGFX designer, I found that it had generated code in the CubeIDE project. Specifically project/Middlewares/ST/touchgfx and project/TouchGFX trees had been added.
After a few include-path tweaks, the project built and ran, but showed only a white screen.
When I looked at the generated main.c code, I found only a dummy task. No GUI task had been created or added.
I added the following, based on other questions on this site:
#define GUI_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define GUI_TASK_STK_SIZE ( 1024 )
void *guiTaskHandle;
void touchgfx_taskEntry();
void GUI_Task(void * argument)
{
touchgfx_taskEntry();
}
...
int main(void) {
...
xTaskCreate(GUI_Task,
"GUI",
GUI_TASK_STK_SIZE,
NULL,
GUI_TASK_PRIORITY,
&guiTaskHandle);
(When I add my own infinite loop and a breakpoint into GUI_Task I can see it being successfully run by the scheduler, so I'm happy that it's not a FreeRTOS issue. touchgfx_init() is being called by MX_TouchGFX_Init(), so that's also not the issue.)
touchgfx_taskentry() is defined in the generated project/TouchGFX/target/generated/TouchGFXConfiguration.cpp:
void touchgfx_taskEntry()
{
/*
* Main event loop. Will wait for VSYNC signal, and then process next frame. Call
* this function from your GUI task.
*
* Note This function never returns
*/
hal.taskEntry();
}
When I ran this code in the debugger, I could not step into hal.taskEntry(), it returned immediately.
Then I learned that it is possible for a unimplemented virtual function to called in C++ and for the program to still compile. (I haven't used C++ since last century, so I'm rusty.)
Using grep over the whole project directory, I was unable to find an implementation of HAL::taskEntry(). (I'm normally a Linux developer. I'm just using Windows for TouchGFXDesigner (which is a Windows executable) so I use WSL and Linux tools, rather than PowerShell.)
vm@DESKTOP-2IPU7SQ:/mnt/c/Users/vm/STM32CubeIDE/workspace_1.1.0/project$ grep -R taskEntry * 2> /dev/null | grep -v "Binary file"
Core/Src/main.c:void touchgfx_taskEntry();
Core/Src/main.c: touchgfx_taskEntry();
Debug/f429.list:void touchgfx_taskEntry();
Debug/f429.list: touchgfx_taskEntry();
Debug/f429.list: 8000600: f013 fdec bl 80141dc <touchgfx_taskEntry>
Debug/f429.list:080141dc <touchgfx_taskEntry>:
Debug/f429.list:void touchgfx_taskEntry()
Debug/f429.list: hal.taskEntry();
Debug/f429.list: 80141e0: 4802 ldr r0, [pc, #8] ; (80141ec <touchgfx_taskEntry+0x10>)
Debug/f429.list: 80141e2: f001 f8d0 bl 8015386 <_ZN8touchgfx3HAL9taskEntryEv>
Debug/f429.list:08015386 <_ZN8touchgfx3HAL9taskEntryEv>:
Debug/f429.list: 80153a0: e7f8 b.n 8015394 <_ZN8touchgfx3HAL9taskEntryEv+0xe>
Debug/f429.map: .text.touchgfx_taskEntry
Debug/f429.map: 0x00000000080141dc touchgfx_taskEntry
Debug/f429.map: .text._ZN8touchgfx3HAL9taskEntryEv
Debug/f429.map: 0x0000000008015386 touchgfx::HAL::taskEntry()
Debug/TouchGFX/target/generated/TouchGFXConfiguration.su:TouchGFXConfiguration.cpp:51:6:void touchgfx_taskEntry() 8static
Middlewares/ST/touchgfx/framework/include/platform/hal/simulator/sdl2/HALSDL2.hpp: * @fn virtual void HALSDL2::taskEntry();
Middlewares/ST/touchgfx/framework/include/platform/hal/simulator/sdl2/HALSDL2.hpp: virtual void taskEntry();
Middlewares/ST/touchgfx/framework/include/touchgfx/hal/HAL.hpp: * @fn virtual void HAL::taskEntry();
Middlewares/ST/touchgfx/framework/include/touchgfx/hal/HAL.hpp: virtual void taskEntry();
Middlewares/ST/touchgfx/framework/source/platform/hal/simulator/sdl2/HALSDL2.cpp:void HALSDL2::taskEntry()
TouchGFX/App/app_touchgfx.c:void touchgfx_taskEntry(void);
TouchGFX/App/app_touchgfx.c: touchgfx_taskEntry();
TouchGFX/App/app_touchgfx.c: touchgfx_taskEntry();
TouchGFX/simulator/main.cpp: touchgfx::HAL::getInstance()->taskEntry(); //Never returns
TouchGFX/target/generated/TouchGFXConfiguration.cpp:extern "C" void touchgfx_taskEntry();
TouchGFX/target/generated/TouchGFXConfiguration.cpp:void touchgfx_taskEntry()
TouchGFX/target/generated/TouchGFXConfiguration.cpp: hal.taskEntry();
TouchGFXHAL derives from TouchGFXGeneratedHAL which derives from HAL. taskEntry is virtual in HAL:
/**
* @fn virtual void HAL::taskEntry();
*
* @brief Main event loop.
*
* Main event loop. Will wait for VSYNC signal, and then process next frame. Call
* this function from your GUI task.
*
* @note This function never returns!
*/
virtual void taskEntry();
and not mentioned in TouchGFGeneratedHAL.[ch]pp or TouchGFXHAL.[ch]pp.
How do I make TouchGFX Designer generate this essential code?
2020-03-11 04:00 AM
I found a libtouchgfx-float-abi-hard.a library which TouchGFXDesigner must have added to the CubeIDE project.
Disassembling it, with /usr/arm-none-eabi/bin/objdump -d libtouchgfx-float-abi-hard.a, I found:
Disassembly of section .text._ZN8touchgfx3HAL9taskEntryEv:
00000000 <_ZN8touchgfx3HAL9taskEntryEv>:
0: b508 push {r3, lr}
2: 6803 ldr r3, [r0, #0]
4: 4604 mov r4, r0
6: 6e9b ldr r3, [r3, #104] ; 0x68
8: 4798 blx r3
a: 6823 ldr r3, [r4, #0]
c: 6e1b ldr r3, [r3, #96] ; 0x60
e: 4620 mov r0, r4
10: 4798 blx r3
12: f7ff fffe bl 0 <_ZN8touchgfx10OSWrappers12waitForVSyncEv>
16: 6823 ldr r3, [r4, #0]
18: 6d9b ldr r3, [r3, #88] ; 0x58
1a: e7f8 b.n e <_ZN8touchgfx3HAL9taskEntryEv+0xe>
The name _ZN8touchgfx3HAL8endFrameEv demangles to touchgfx::HAL::taskEntry(). Thanks https://demangler.com/
So it seems to have a default implementation in the (closed-source?) touchgfx library.
Is this why the debugger refuses to step into .taskEntry()?
How can I debug through closed-source code?
2023-11-15 03:04 PM
Did you ever figure this out? I'm having this exact issue right now. STM32u5 and the hal::taskEntry() function doesn't seem to exist