cancel
Showing results for 
Search instead for 
Did you mean: 

A note on patching internal templates during code generation

TPeča.1
Associate II

Lately I got stuck at a particular issue in STMCubeMX / STM32CubeIDE Device configuration tool, where a certain portion of the HAL library configuration was fixed and overwritten during code generation, more info here.

---

This above issue has been fixed in the later versions of STMCubeMX (don't know exactly, versions after mid 2020) / STM32CubeIDE (version 1.4.0 onwards).

See the linked thread for more info.

The workaround below can however be applied to other issues - but it's pretty hacky and you should really only use it when all other options have been exhausted.

Original post follows.

---

I've figured out a workaround for this and since I suspect that this might be applied to other issues as well, I'm posting it here.

---

The idea is to use a user template (which is a FreeMarker template with alternate square bracket syntax) to wrap specific blocks of the auto-generated header file into USER CODE sections.

This allows user modifications within that block to survive code regeneration. Other things could be done as well.

You create a [original file to replace]_[extension].ftl with the following content

[#--
    Include original template
    
    Base path is project root.
--]
[#assign origFile]
[#include "workspace path to original file"]
[/#assign]
[#--
    Add USER CODE sections
--]
[#assign userCodeBeginTag   = "text in original file, before which to start user code wrapper"]
[#assign userCodeEndTag     = "text in original file, after which to end user code wrapper"]
[#assign outFile            = origFile?replace(userCodeBeginTag,  "/* USER CODE BEGIN 0 */" + "\n" + userCodeBeginTag       )]
[#assign outFile            = outFile?replace(userCodeEndTag,     userCodeEndTag            + "\n" + "/* USER CODE END 0 */")]
[#--
    Output section
--]
${outFile}

In my case, it was

[#assign origFile]
[#include "Core/Inc/stm32f3xx_hal_conf.h"]
[/#assign]
[#assign userCodeBeginTag   = "#define  USE_HAL_ADC_REGISTER_CALLBACKS         0U /* ADC register callback disabled       */"]
[#assign userCodeEndTag     = "#define  USE_HAL_PCD_REGISTER_CALLBACKS         0U /* PCD register callback disabled       */"]
[#assign outFile            = origFile?replace(userCodeBeginTag,  "/* USER CODE BEGIN 0 */" + "\n" + userCodeBeginTag       )]
[#assign outFile            = outFile?replace(userCodeEndTag,     userCodeEndTag            + "\n" + "/* USER CODE END 0 */")]
${outFile}

(full file attached to post)

You add this as a user template (do note that all user template files are generated to the same destination folder)

0693W000001qBrOQAU.png

0693W000001qBqaQAE.png

And since the original file is still generated, you need to manage the conflict somehow

  • original source files can be excluded from build
  • original header files can be overridden by moving the user modified ones earlier in the include search path

0693W000001qBqfQAE.png

---

Also note that, if there are any issues with the template file, the output file might be empty, or might not even be generated.

Some additional error info is available in STM32CubeIDE/your_workspace/.metadata/.ide.log

---

While this is obviously a hack and a misuse of the user template feature, it works as a quick fix.

Hope this is useful.

2 REPLIES 2
S.Ma
Principal

I try not to interleave in the SAME source file code coming from different sources with different version control system.

Just minimize one of them by calling functions to another file which will have user version control and not under the MX or HAL version dependent code.

While I'm also not fond of the idea of having multiple variants of the same file around, I could not find a different solution for my original problem, which was how to keep user modifications in the *_hal_conf.h header file, which is included in other HAL libraries, and still have it managed by the code generator.

There are usually better solutions to the problem, with my workaround being a sort of a last-resort measure.