2023-12-09 01:16 PM
I had to resolve multiple issues when I used CubeMX to regenerate Ux_Device_HID example code. An example is not very useful if it can't easily be used as the basis to develop functionality. Here is the story.
I created example Ux_Device_HID targeting a Nucleo-F767ZI board. Compiled and ran generated code. No compile or link errors. Device showed up when connected to a Windows 10 computer. HID Device recognized and driver was loaded. Seems functional but I never got the mouse to move.
Using STM32CubeIDE 1.13.2
STM32CubeMX 6.9.2.202309101412
Opened IOC.
Using X-CUBE-AZRTOS-F7 Version 1.1.0 with 1.0.0 installed as well. Using STM32F7 FW Package 1.17.1
Changed ThreadX memory pool size from 1024 to 1025 and then back to 1024 to trick Cube into thinking there was a change.
Saved IOC and said generate code.
To really use these examples, we need to be able to use them with CubeMX and the code it generates.
Did a Project->Clean… and rebuilt the Ux_Device_HID project.
With no intentional source code changes, the project now has 3 errors and 2 warnings.
C:/TMS/stm_cube/Ux_Device_HID/Core/Src/main.c:51:13: warning: 'MPU_Initialize' declared 'static' but never defined [-Wunused-function]
51 | static void MPU_Initialize(void);
| ^~~~~~~~~~~~~~
C:/TMS/stm_cube/Ux_Device_HID/Core/Src/stm32f7xx_hal_timebase_tim.c:111:3: warning: implicit declaration of function 'HAL_TIM_RegisterCallback'; did you mean 'HAL_DMA_RegisterCallback'? [-Wimplicit-function-declaration]
111 | HAL_TIM_RegisterCallback(&htim6, HAL_TIM_PERIOD_ELAPSED_CB_ID, TimeBase_TIM_PeriodElapsedCallback);
| ^~~~~~~~~~~~~~~~~~~~~~~~
| HAL_DMA_RegisterCallback
C:/TMS/stm_cube/Ux_Device_HID/Core/Src/stm32f7xx_hal_timebase_tim.c:111:36: error: 'HAL_TIM_PERIOD_ELAPSED_CB_ID' undeclared (first use in this function)
111 | HAL_TIM_RegisterCallback(&htim6, HAL_TIM_PERIOD_ELAPSED_CB_ID, TimeBase_TIM_PeriodElapsedCallback);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:/TMS/stm_cube/Ux_Device_HID/Core/Src/stm32f7xx_hal_timebase_tim.c:111:36: note: each undeclared identifier is reported only once for each function it appears in
make: *** [Application/User/Core/subdir.mk:58: Application/User/Core/stm32f7xx_hal_timebase_tim.o] Error 1
Neglected to note previous usage of MPU_Initialize.
HAL_TIM_RegisterCallback doesn't have a prototype as the IOC has not enabled registered callbacks for timers. Also as was noted in another problem report I made and it was confirmed, this call even when it does not have a compile error doesn't work as TIM6 is already running at this point and the register callback returns an error.
I open the IOC, go to Advanced Settings and enable TIM 'Register Callback'. This is the only way to allow generated code to not produce an error without always editing the generated code.
I do another clean build of this project.
I now only get the warning of MPU_Initialize as static but never defined. It is a warning so I ignore it.
I didn't check before but in IOC, the SYS options no longer let me specify the timer used by the HAL functions. It no longer has Debug options specified either. I did not note this with the freshly created example but seems off. I closed the IOC without saving and reopend. I now see 'Timebase Source' and 4 wakeup options. Debug still says disable. Weird behavior.
Code loads in with debugger so Debug option didn't seem to affect anything. I run.
The code is looping in Error_Handler after the call in line 167 tx_byte_allocate in app_usbx_device.c returns error code 5, TX_SIZE_ERROR as their now isn't enough room in the UX memory pool to allocate a 1024 byte stack.
I open the IOC and increase the UXDevice memory pool size from 7*1024 to 12*1024 to give some margin as there are other thread stacks to allocate. Code is generated and I do a clean build.
I run again.
Same error. Debugging deeper, somehow the byte pool size is 0 at this point. tx_byte_pool_available is 8176. There has only been 1 previous allocation of 4096 from this byte pool when a buffer was allocated for ux_system_initialize. This was the size that used to work in this example before CubeMX rebuilt things.
I'm trying increasing the ux_system buffer from 4*1024 to 6*1024 based on a define in the app_usbx_device.c file. The overall buffer is 12K.
That fixes the allocation error. Weird again as they may have been some allocation or overrun error. FYI: The USBX routines use their own memory allocation routines I've found. Most of the examples use the ThreadX memory allocation routines thread stacks but from the same memory pool.
So code now seems to be running. When I suspend it is in a HID wait call as expected. No host is plugged in at this point. Host recognizes it like before. Still no mouse movement but driver and everything like that is the same.
I hope STM realizes how hard it is for users to figure how to use your tools and processors when the examples are so fragile. This example I walked through here took days of background activity trying to figure out to work through each of these issues. This is a core example of getting USBX to work on a STM32F7 family processor with a full speed USB interface on the Nucleo board. Having this as a solid example with current tools seems very important. Most other examples are for an STM32H723 which uses the high speed USB interface and the examples are complicated to adapt for those with less experience.
I am documenting my experience to this point. My real objective is to get the USB CDC ACM class to work on an F7 processor. That absolutely requires generating new code and libraries. The examples are devalued significantly if they can't easily be used as the basis for extending functionality.