Hi all. In recent months I wanted to restart one of my older project, CNC plotter done with stepper motors from old CD drives and controlled with STM32 microcontroller and because of that I needed to get myself familiar again with SMT32 microcontroller and it’s IDE. And with a little twist. I wanted to do this development on Linux. So, how to start STM32 on Linux in 2021.
If you don’t use Linux and want to try please check my other post on that topic.
https://bln364.com/dual-boot-pop-os-and-windows-10/
First time, when I developed CNC plotter with STM32, I used Windows 10 with STM32CubeMX with Keil IDE. And it was fine. But that was couple of years ago and is there now an alternative for development on Linux.
I have couple of STM32 board, and I’m thinking of starting STM32 series and used them in some future project. And this is my collection.
In this post I will try to install IDE for STM32 and run Embedded equal Hello World (blinking led) program on Nucleo F401RE.
Board introduction
Let’s start at new page https://www.st.com/en/evaluation-tools/nucleo-f401re.html.
Common features:
- STM32 microcontroller in LQFP64 package
- 1 user LED shared with ARDUINO®
- 1 user and 1 reset push-buttons
- 32.768 kHz crystal oscillator
- Board connectors:ARDUINO® Uno V3 expansion connectorST morpho extension pin headers for full access to all STM32 I/Os
- Flexible power-supply options: ST-LINK, USB VBUS, or external sources
- On-board ST-LINK debugger/programmer with USB re-enumeration capability: mass storage, Virtual COM port and debug port
- Comprehensive free software libraries and examples available with the STM32Cube MCU Package
- Support of a wide choice of Integrated Development Environments (IDEs) including IAR Embedded Workbench®, MDK-ARM, and STM32CubeIDE
Now, we need to find our Led diode on Nucleo F401RE board that we can control and see how that led diode is connected to microcontroller. In case of Nucleo F401RE, microcontroller is STM32F401RE. Let’s download User Manual for STM32 Nucleo-64 boards (MB1136) 14.0 and search in document for led.
OK, now that we know that we want to control LD2 Led diode, we need figure out how LD2 is connected to our STM32 microcontroller. From User Manual we can see that Led LD2 is connected to SMT32 I/O pin PA5. Or, if you need a bit more detailed overview of hardware connections, you can simply search for hardware schematic.
Open Schematic and search for LD2.
From schematic above we can se that LD2 is connected to I/O pin PA5 of STM32. Also, from schematic we can confirm that we need to se I/O to logic high in order to turn on LD2 led diode. So, now after all this, we can start with installing IDE software and then developing blinking (embedded hello world) software.
Install IDE for STM32 on Linux
For this post I wanted to try STM32CubeIDE. I’m currently using Manjaro Linux distribution, so this installation will be for Arch based OS. This is first step in our process of developing code for STM32 on Linux. So, let’s go to STM32CudeIDE site https://www.st.com/en/development-tools/stm32cubeide.html.
Check out YouTube video below for instruction on how to install STM32CubeIDE on Manjaro.
Embedded Blink software
Init Project for development board
Let’s create a new STM project by clicking on START NEW STM32 Project. Then you will be greeted with new window.
Here we need to chose between MCU/MPU Selector and Board Selector. If project is for STM32 MCU only we would select MCU/MPU Selector and then search and select desired MCU (example STM32F401RE). But in our case we have development board, that is MCU plus some additional components so that you don’t have to worry about adding power supply, external oscillators and other stuff to make your MCU work.
Select Board Selector and search and select Nucleo F401RE.
Now we just need to select couple of options and we are done. First let’s input project name. For this example I will use generic name HelloWorld. Also I will use C and Target language, Executable as Binary Type and Project type as STM32Cube. This last option will give us easy setup for our development board by automatically including parts for code that will initialize needed parts for our Nucleo F401RE board for developing STM32 on Linux.
Then, lets just make sure that we are using the right firmware by double checking Target reference and select Copy only the necessary library files.
And now we have out Nucleo F401RE project.
In image above we can confirm that this initialization is for our board by looking and bottom side pins. We can see that on PA5 pin Green Led (LD2) is defined. Also, we can see that all peripheries of our development are initialize and ready to run. We can now generate out C code automatically and just add blinking diode part.
Generate C code
In order to generate C code for STM32 on Linux with initialization we need to press next button.
And that is all now we have source C code inside STM32CubeIDE. Lets open main.c
Next, we can try to build and download code to our board to establish that everything is working OK. Code, like this will not do anything, but I good thing to acknowledge and solve any errors in this state.
Build and download code
We can start build and download procedure by simply clicking on button RUN AS, shown on image bellow.
This will start build procedure first.
We can now edit lunch configuration properties, but for this example we will leave everything as default.
Sometimes you will need to update firmware on your development board before you can download code, and if that is the case you will get next window.
Here you simply need to click OK and then on next window.
In this windows we first need to click on Open in update mode (this will reboot your development board and put it in update firmware mode), and then when your board is in update mode, you can click on Update. And that is all.
And now I came across first problem.
If this happens to you there is a simple fix.
cd /usr/lib
sudo ln -s libncurses++w.so.6.2 libtinfo.so.5
sudo ln -s libncurses++w.so.6.2 libncurses.so.5
And now we have successful compilation and download.
And now we can add part of code in our main.c file to get our LD2 to blink.
Blinking code
And now the main part of developing STM32 on Linux. We need to write blinking code and it’s pretty simple, we need only two lines of code.
I added two lines 101 and 102. On line 101 there is a function HAL_GPIO_TogglePin which is responsible to change state of our user led diode. Other function HAL_Delay(2000) is simply wait function that will pause our while execution for 2 seconds. But how did I found these functions? If we look at MX_GPIO_Init() by selecting that function, then right mouse click and then Open Declaration we can see declaration of MX_GPIO_Init() function.
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : B1_Pin */
GPIO_InitStruct.Pin = B1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : LD2_Pin */
GPIO_InitStruct.Pin = LD2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct);
}
In configuration section for GPIO pin LD2, we can see initialization steps for our GPIO that is controlling LD2. Also, we can find info for predefined Pin and port name, info that we are gonna need later. At the end there is a function called HAL_GPIO_Init. If we do the same thing as with MX_GPIO_Init() function (right mouse click and Open Declaration), we will open /HelloWorld/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c. In this file there are declared HAL (Hardware Abstraction Layer) function that we need in order to control GPIOs with HAL drivers. If we just open the /Lib/stm32f4xx_hal_gpio.h instead for /Src/stm32f4xx_hal_gpio.c we can clearly see list of defined functions for GPIO support.
/* IO operation functions *****************************************************/
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
And from the list above we can see that best function for blinking LED diode is HAL_GPIO_TooglePin.
Final words
And that is all, just build and download your code once again and led diode will start blinking. Did you manage to achieve this results? Did you have some trouble? Do you think that developing STM32 on Linux is valid choice?
Comment down bellow and see you in next one.
Thanks! This is just what I was looking for as a quick getting started guide to STM32 on Linux. I had a bad USB mini cable that drove me nuts for a couple of hours, but everything worked perfectly once I replaced the cable.
Onward to CAN projects!