Skip to main content
chriskuku
Senior II
December 19, 2025
Question

Recognizing a project by reading the flash

  • December 19, 2025
  • 4 replies
  • 491 views

 

It happens to from time to time that I have a flashed project in a hardware, e.g. a bluepill, but I forgot which source project was belonging to it in the STM32CubeIDE's project treeview.

Is there a way to write the name of the project by means of some C-macro in text form into the program as kind of a signature or even more safely, compute a checksum of the flash binary and write that checksum into the program (yes I know, this may become tricky since the checksum alters the checksum itself :)

Is there a common technique for this?

4 replies

Andrew Neil
Super User
December 19, 2025

@chriskuku wrote:

Is there a way to write the name of the project by means of some C-macro in text form into the program as kind of a signature 


Sure there is - no need for macros; eg,

const char signature[] = "This is my Signature string";

The string will be readable in flash.

Better yet, have your code write it out to a UART on startup.

 

PS:

You could locate that string at a specific address, to make it easier to find; eg,

Locate Constant Data in Flash at Fixed Address

https://stackoverflow.com/a/54128613

Defining Variables at Absolute Addresses with gcc

GCC Documentation: Specifying Attributes of Variables

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
chriskuku
chriskukuAuthor
Senior II
December 19, 2025

The least I'm demanding is an automatism that gets the project name as a string. (similar to __DATE__,__TIME__, __LINE__,__FILE__ macros in C). Or some Makefile construct, that does something like "echo "const char signature =\" `echo  $(PROJECT)` \";" >project.h". 

Associate II
December 20, 2025

I usually use something like the signature string as well.

But additionally I have my version control system update the content automatically. I use subversion usually, but other VCSs work similiar.

Probably all VCS are able to replace specific patterns in a file with some content, e.g. replace "$Rev: any text$" with "$Rev: 76 $" if the file is at revision 76 in the VCS.

In my C source it looks like this:

const char *whoami __attribute__ ((section (".init"))) = "$HeadURL: svn+ssh://klaus@myserver.xxx/svn/stm32workspace/trunk/NUCLEO-F030R8_test_doubleprecision/Core/Src/main.c $ $Rev: 76 $ $Date: 2025-12-20 12:02:11 +0100 (Sa, 20. Dez 2025) $";

(no, my server is NOT myserver.xxx)

 

To make subversion do so it is necessary to set an attribute on the file like:

svn propset svn:keywords "Date Revision HeadURL Author Id" main.c

Other VCS require some similiar setting. Perforce requires in p4v to make a setting on the file properties in  "Change Filetype..."; check "+k" or "+ky" there. Git has no sequential rev numbers but arbitrary hashes instead, see https://stackoverflow.com/questions/1792838/how-do-i-enable-the-ident-string-for-a-git-repository (I try to avoid git...).

 

A note on the __attribute__ ((section (".init"))): It is a bit dirty admittedly. You can omit this if you really use the string somewhere in your program, e.g. write it to UART.

But if you do not use it gcc will drop the string. This can be avoided with __attribute((used)). Then the string goes into the object file, but will be dropped when flashing because it goes to a section like .rodata.whoami which has no KEEP in the linker config (*.ld). You could force the linker to keep it by fixing the ld file (see https://community.st.com/t5/stm32cubeide-mcus/used-attribute-appears-ineffective/td-p/692448 for a similiar problem with a BSS variable). But I am too lazy to adapt the ld file for this and want to have a simple setting in the C source only. This is why I abuse .init section for this with STM projects - this section will not be dropped by the linker.

Then the Id string will be found in the source, the object file, in the ELF and in the flash as well; see attached png.

The effort is really low: I copy the single code line from an existing project to main.c in a new project and set the file property with the VCS. That's all, the content of the Id string will be wrong until the VCS touches the file for the first time.

This workflow requires using a VCS. But if you do not use it up to now you should consider this anyway...

id.png

gbm
Principal
December 20, 2025

With the code as above, your string goes to .rodata section and a not-really-needed pointer object declared as a variable but really being a constant is placed in .init section. With some bad luck with a linker script it could even lead to some data corruption. ;)

I would definitely not recommend the technique presented above.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
Associate II
December 22, 2025

You are right, the pointer wastes 4 Byte in .init section, and the string itself goes to .rodata resp. .rodata.whoami.

But why should there happen data corruption? With every entry the linker makes the section grow for the requested size.

You could place the string directly in the Flash with a simple change in the ld file to save the 4 byte pointer. But as I said I do not change the ld file on every simple program to do this. And I never failed because of 4 bytes in flash; if this happens I would shorten the string...

gbm
Principal
December 22, 2025

Right, no extra problems if .init input sections goes to .text output section like in ST linker scripts, just the extra pointer constant mimicking a variable. :)

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice