Compiling Bootloader

Hello,

I am looking to compile the artekit stm32 bootloader. I read on another post that Eclipse CDT with the ARM Cortex Plugin compiles with GCC? Is there any particular instructions to go about this or things to watch for? Also i’m compiling for a STM32F405 instead of a STM32401, so I know about adjusting the pins for my particular setup. Anything else to be aware of?

Thank you.

Hello @5mc

We don’t have a tutorial for setting up the Eclipse environment but instructions can be easily found on Google by searching stm32 eclipse gcc.

Then you import the bootloader project directly from the IDE and you can compile it from there.

Thanks for the quick response. I will give it a try today and report back.

@Ivan
I have the tools installed and was able to compile a blink test no problem.

However do you have any recommendations when importing the bootloader project? I have been following the readme documentation here:

https://help.eclipse.org/latest/index.jsp?topic=%2Forg.eclipse.cdt.doc.user%2Fgetting_started%2Fcdt_w_import.htm

However it seems the entire file layout system is not playing nice when importing the bootloader folder. Not only that, seems to be a missing audio.h which I do not see in the project files.

thanks

@Oluwadara_Olaifa @5mc

It seems the Ecplise project files for the bootloader were missing. I’ve just pushed them to Github. See here. You can copy the .project and .cproject files yourselves or clone/update the repository, which is what I recommend.

Then in Eclipse, right-click in your workspace and select Import. Then Existing Projects into Workspace. Browse to the project folder and select “Bootloader”. This will import the project into eclipse.

I tried this and it worked. I pressed ctrl + b and it just compiled.

Also, right-clicking project you can see the compiler settings, like flags and preprocessor so you can create your own project using alternative methods or newer IDEs. I know Eclipse was cool like 10 years ago when this project started but now there may be better IDEs.

If you want to build the bootloader for PropBoard or WaveTooEasy you need to change this value, between BOOTLOADER_PROPBOARD and BOOTLOADER_WAVETOOEASY.

I hope it helps.

@Ivan Thank you Ivan, it compiles perfectly now. Very much appreciated :smiley:

1 Like

@Ivan I am getting gibberish on my serial monitor, I believe it may be linked to the USARTDIV getting set at 10Mhz (wave too easy board). I am using a 8Mhz crystal, which might be causing the issue? Is the libstm32f4xx.a in the variants folder specifically built for 10Mhz for the f401 or is it just a generic file from stm for the f4 series chips?

This is for the core files and not the bootloader. Are there any specific settings that may need to be changed for a 8Mhz crystal aside from the compile settings of -DHSE_VALUE which I set to 8000000

For example I see in the bootloader you have

USART6->BRR = 84000000 / 115200

Which is 84mhz/115200 baud rate for the serial debug. For a STM32F405, it would be:

USART6->BRR = 168000000 / 115200;

I do not see any configuration like that for the main core files though.

thanks.

The system clock is initialized by the bootloader, and that’s where the HSE_VALUE makes sense (if I recall correctly).

The UART in core files (UARTClass.cpp) is configured using the ST library (no direct handling of registers).

If you are not using the bootloader then you are going to initialize the clocks in the core files and that includes recompiling libstm32f4xx.a or including the files you need from the ST peripheral library.

@Ivan hmm I see in the core files the clocks get initalize if you bypass the bootloader, so the libstm32f4xx.a needs to be recompiled if bypassing the bootloader for the clocks to be setup properly? Does the libstm32f4xx.a that you include have any clock settings compiled in it which could be causing issues for me?

I do notice when compiling the core, that /system/stm32f4xx/src/system_stm32f4xx.c which has clock setup information seems to get ignored. I assume thats what you mean by including the files from the ST peripheral library?
(From variants.cpp)

(From bootloader)

@Ivan I forgot to mention, i’ve done both, using the bootloader and then load the main core from it, and also no bootloader and loading the core at 0x8000000 directly, either way when running, I still get the bad serial terminal output. The HSE_VALUE is set to 8000000 in the compile options in Eclipse for the bootloader and also in boards.txt for the core files when compiling.

The #define STM32F40_41xxx is uncommented out in the stm32f4xx.h so the compiler also knows the target is a STM32F405

The libstm32f4xx.a seems to be required even when loading the core from the bootloader, as not including it does nothing. So I suspect there is something here which was compiled specifically for the F401 that is causing issues.

Do you happen to have a Makefile for when you compiled it and or which version of the library is used? I assume it is this one?
https://www.st.com/en/embedded-software/stsw-stm32065.html

Or if you want to generate an libstm32f4xx.a for a stm32f405 with a 8mhz crystal. I would like to build it myself though, but either or.

Doing a simple blink sketch with the Generic STM32F405 library in works no problem by itself with proper serial output.

Thanks again.

@Ivan Also I have been doing some testing with just the bootloader only. I am compiling with -DHSE_VALUE=8000000, and I reconfigured for testing purposes to serial debug out from the UART1, and I noticed if the USART1->BRR = 84000000 / 9600; is set, the serial output is ok and clean at 9600 baud.

However what is strange is, 84000000 should be the 84mhz of the stm32f401 chip, yet on the STM32F405 I am using, everything I read in documentation says to do: USART1->BRR = 168000000 / 9600; which should be the 168mhz of the STM32F405, but when doing that, I get the garbage output in the serial terminal.

in the stm32f4xx.h for the bootloader I have as mentioned the #define STM32F40_41xxx uncommented so it compiles for the STM32F405

Also what I found, in the system_stm32f4xx.c, when changing the PLL_M 25 to PLL_M 8 for the STM32F40_41xxx (basically for the stm32f405 with a 8mhz crystal) (top of below image), the serial output will be ok as mentioned above, but only when USART1->BRR = 84000000 / (baud rate) and not at the 168000000 setting.

Wouldn’t you normally you want to set the clock settings within the main app? Something along the lines like below (for a STM32F405)? Or is that something that is compiled within the libstm32f4xx.a that you mentioned earlier?

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;

I feel like I am getting real close here…

Anyhow thanks again.

The bootloader has its own copy of the stm32fxx library. The pre compiled library is just there for convenience since the core files are compiled with the Arduino IDE, which likes to rebuild everything often and that takes time.

The pre compiled library should have been compiled with the clock settings to run with a 10MHz quartz on an stm32f401. That includes HSE_VALUE and all PLL settings.

HSE_VALUE definition on core files it’s probably being ignored and I think it could be removed from compilation.

BRR settings on USARTs depend on PCLK frequency (PCLK2 for USART 1 and 6) and not directly from the system clock frequency. When configured correctly on our boards (PLL settings) PCLK2 runs at 84MHz, which is the max speed for APB2. I recommend you to use CubeMX to see the clock tree and get the right clock settings and values for your quartz.

Clocks are usually initialized by the very first lines of code, which in our boards is the bootloader. The bootloader calls SystemInit from startup_stm32f401xx.S. The possibility of skipping the bootloader is there, and doing that will call SystemInit from core files (which will point to the precompiled library at this point).

Long story short, you must either recompile the precompiled library, or you can modify how the core files are built and include your own stm32 library (sources, not precompiled).

I know it’s inconvenient but it just how the ST libraries are made. There should be a way to change the clock after but you don’t want to start up the system with the wrong settings. Also, HSE_VALUE is used for some peripheral settings like I2S.

I can check if there is project files for the precompiled library but I am not in the lab today.

@Ivan

If I understand this correctly, when using the main bootloader the clocks are getting initalized based on the settings in the bootloaders stm32fxx library. The uart is initalized in the bootloader to do it’s thing, which is how I managed to get it to output serial data correctly by adjusting the BRR settings in the bootloader stm32fxx library in the system_stm32f4xx.c file. However when the bootloader transitions to the main core program, it un-initializes the uart, and the main core then reinitalizes the uart based on the settings in the precompiled .a library thus getting the wrong settings for my setup?

What I notice is the main core doesn’t ignores / is not affected / does not compile anything of whats in the system/stm32f4xx folder. If I remove linking the .a for the core when compiling it, and force compile the system/stm32fxx folder (much like the bootloader does for it’s own version), with my clock settings, then things like the i2s, uart etc will be using the settings I set for the PLL_M etc settings in that system_stm32f4xx.c file?

Thanks for looking for project files when you get back to the lab, much appreciated.

If the bootloader initializes the clocks correctly and the UART works, then the UART should also work when opened by the core files (because core files don’t initialize the clocks, unless you comment WITH_BOOTLOADER). The UART source code in the ST library gets the clocks timings dynamically so it shouldn’t depend on fixed values (which is not the case of I2S because it does use HSE_VALUE).

The core doesn’t compile what’s inside system/stm32f4xx and uses the precompiled library for the reasons I said in my previous post. You can modify how the core is built to also compile system/stm32f4xx and use the clock settings you need.

@Ivan

Ah ok that explains why when it transitions from the bootloader to the main core, then the output turns out bad. Anyhow, I will keep on testing away on it today and with CubeMX.

Thanks again for looking for the project files, I do not mind longer compile times if it’s neccessary.

@Ivan
I went through the STM32CubeMX and have the clock tree configured. APB2 prescaler of /2 is necessary to be at the max 84mhz or APB2 in my setup.

Here is the rest of the Clock tree configuration: I guess now is to wait for the project files so I can rebuild the libstm32f4xx.a with the settings required.

Thanks again.

@5mc

Please find the project files for libstm32f4xx here: https://github.com/Artekit/artekit_stm32f401-core/tree/master/system

@Ivan

Thanks, I made the changes and got it built. Serial output is working correctly.

Though question, I did the clock tree configuration for the F401, and it says the PLLN should be 84? yet you have it set as double that at 168, why is that? On my clock tree configuration, it says to set mine at 168 as well, but I notice the clock timing is much faster, 5ms set in the code for a led blink is more like 2.5ms. Yet when I double the PLL_N to 336 5ms is truly a 5ms yet my serial debug will be messed up again when doing that. Will this affect the ability to read the SD card as well if the clocks are slightly off like this?

Screenshot 2024-02-06 at 01.57.07

Your clocks are off for some reason. Your system will misbehave.

PLL_N is set to 168 so I can divide it by 7 (PLL_Q) and get 48MHz for SDIO, otherwise you get 42MHz.

PLL_P is set to 4, so 168 / 4 = 84 / 2.