Switching from STM32 to GD32

Switching from STM32 to GD32
7 min read
2 weeks ago

STM32 and GigaDevice GD32 microcontrollers are often compared due to similar architecture and compatibility. GD32 is a kind of “clone” of STM32, using the same ARM Cortex-M core. The main difference between the two is price, as the GD32 is generally cheaper, making it attractive for projects with a limited budget. However, despite the similarities, there are differences in features and support levels that can affect the choice between these two microcontroller families.

Differences between the STM32 and GD32

While the external similarities and the same name with STMicroelectronics microcontrollers might lead one to think that they are a complete copy, this is not entirely true. The chips from GigaDevice have some fundamental differences from STM. For example:

frequency of operation: up to 108 MHz for the GD32F1 family (vs. 72 MHz for the STM32F1); Flash memory capacity: up to 3 MB (STM32F2 supports up to 1 MB).

Real-world experience

A few years ago (not at Selectel) we developed an automation controller on the STM32F107RCTx. The project used UART, Ethernet and several GPIOs (the project is under NDA, so we don't reveal any secrets). The software was written in CubeIDE using FreeRTOS, HAL and lwIP and several third-party libraries. The device was configured via USB and web interface. The project was successfully completed and the customer was satisfied. However, the shortage of microchips began (chippaggedon), STM32 controllers sharply increased in price and disappeared from warehouses.

We were offered to switch to GD32F107, claiming that it was fully pin-to-pin compatible. It was possible to write software for GD32 in Keil or IAR (it was necessary to put GD32Fx AddOn). GD32Fx Firmware Library with all drivers and examples is available for easy development. We proceeded to develop in IAR, writing all the software again. The customer is happy again, everything works.

But in the process of operation new ideas come or bugs are discovered. As a result, the software needs to be improved and the exciting support of two hardware in two different IDEs begins.

Are all programmers like that and like to do the same job twice? I'm starting to look for a way to make a piece of software that works on both hardware at the same time. The hardware chips are similar, registers and pins are the same. After a bit of searching, I find a document called GD32 and STM32 Compatibility (compatibility summary between GD32 and STM32_V2.0.pdf).

It lists hardware differences between GD32 and STM32 chips, and practical recommendations on how to "work around" these differences (a kind of errata). After reading the document and seeing no particular "crime", I decide to flash the STM binary into GD and see what happens.

Surprisingly, the software starts immediately and the display shows numbers. Ethernet didn't work, but that's nothing, we can work with it. But will debugging work? When we try to start debugging we get the error "Could not verify ST device! Well, that makes sense, it's not exactly an ST.

Switching from STM32 to GD32

Debug doesn't work, so let's try to solve it in a different way and debug the software in a non-contact way (build binary and flash). Let's go deeper into compatibility sumup. First of all, we need to teach the software to determine in which hardware it “woke up”. This can be done by Jtag ID.

uint16_t Get_JTAG_ID()
{
	if(*(uint8_t *)(0xE00FFFE8) & 0x08)
	{
	return ((*(uint8_t *)(0xE00FFFD0)&0x0F)<<8) | ((*(uint8_t *)(0xE00FFFE4)&0xFF)>>3) | ((*(uint8_t *)(0xE00FFFE8)&0x07)<<5)+1;
	}
	return 0;
}

Since the most serious “difference” between the chips was the operating frequency, I make a separate function SystemClock_Config for GD. In this function I use PLL to overclock the frequency up to 108 MHz (against 72 MHz for STM).

I build the binary, flash it (thank you, STM32 Link utility does not divide chips into its own and other people's and works with all of them), display and buttons work, Ethernet works once in a while. By means of telepathic efforts I am trying to find out why Ethernet may not work. And after about 10 attempts I build a new binary with disabled autonegotiation, let the network always work at a speed of 100 Mbit (as per the ToR). The guess turns out to be correct and the Ethernet interface starts working, IP-address by DHCP is obtained, data is transmitted, lights are blinking.

Then a couple more touches: we need to add a sign in the web-interface to indicate what kind of hardware we have in front of us (this is important in case of potential problems and bugs). We already know how to distinguish hardware by Jtag ID.

Now the unified project is theoretically ready, the software works the same in both hardware. But what if there are problems on GD in the future? How will I fix them without debugging?

Searching for a way to debug software written in CubeIDE on GD hardware.

I find an exotic variant on YouTube. In it you need to run several different versions of CubeIDE and by manipulations and switching through the menu start debugging. I thank the author, of course, but this variant obviously doesn't work.

Then I came across this instruction several times on different forums.

  1. Set Debug probe - OpenOCD in the project settings.
  2. Edit the configuration file C:\ST\ST\STM32CubeIDE_1.3.0\STM32CubeIDE\plugins\ com.st.stm32cube.ide.mcu.debug.openocd_1.3.0.202002181050\ resources\openocd\st_scripts\target\stm32f1x.cfg by adding the line set CPUTAPID 0.

The zero tells OpenOCD to ignore ID numbers, which means that all clones or non-STM microcontrollers should work.

I download CubeIDE 1.3, because under Windows you can install several different versions of IDE at the same time and they will not interfere with each other. I make a new test project. In Debug probe settings I choose OpenOCD, start Debug. And - oh wonder - I see that debug has started (on GD32F107x), you can walk through the steps and look at the variables in memory.

Now the task is to drag and drop a working project made in the older version of the IDE. When opening vorxpace, we get a threatening message that the version is not the same and performance is not guaranteed. We take risks, open the project and see the message about Missing nature (I didn't understand what it is and why). CubeIDE seems to offer a solution, but it doesn't work.

Switching from STM32 to GD32

Since the project made directly in IDE 1.3 works, but in the newer version it doesn't, let's try to find the difference in the files. And it is found in the .project file. Here is what we have in the project from 1.3:

com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAProjectNature

And here's what we have in the project from 1.15:

com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature

Switching from STM32 to GD32

We change one line in the combat project with our hands and it opens immediately. It is better now, we try to build it - again the problem. We see that the project is no longer able to fit into the RAM areas allocated to it. But how can this be? What has changed? Let's see who is responsible for building and compilation.

In IDE 1.15, where the project was originally made, the toolchain gnu-tools-for-stm32.12.3.rel1 was used, and the only one available in version 1.3 is gnu-tools-for-stm32.7-2018-q2.

On community.st.com I find information on how to add an alternative version of toolchain to CubeIDE. You just need to copy with replacement all files from here:

C:\ST\STM32CubeIDE_1.15.0\STM32CubeIDE\plugins\ com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.12.3.rel1.win32_1.0.100.202403111256

After the files need to be pasted here:

C:\ST\STM32CubeIDE_1.3.0\STM32CubeIDE\plugins\ com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610

Also in the project settings you should forcibly set Fixed-version of toolchain. Build the project - and success! I start debugging - and success too. We go step by step, the problem is solved.

Switching from STM32 to GD32

What about setting CPUTAPID 0?

I answer: there is no way. CubeIDE 1.3 version when debugging through OpenOCD doesn't ask unnecessary questions about chip origin (if it is GD32), everything works without this trick. I tried to do the trick of writing CPUTAPID 0 in IDE with versions 1.8, 1.7 and 1.5 and long story short - it never worked. But I didn't need to.

Conclusion

Now I have a project made in CubeIDE 1.3 which can be equally successfully run and debugged on STM32 and GD32 hardware. Is it possible to do this in production on real projects? Rather no than yes. In my opinion, CubeIDE user agreement doesn't allow such things. Or am I wrong?

So, all the above was done only for research purposes and not in the field. And we continue to make two versions of software for this hardware in two different IDEs, making all changes twice, because all programmers like that. :-)

In case you have found a mistake in the text, please send a message to the author by selecting the mistake and pressing Ctrl-Enter.
Den W. 2K
I'm a passionate tech enthusiast who loves diving into the world of software, programming, and tech reviews.
Comments (0)

    No comments yet

You must be logged in to comment.

Sign In