Nucleo Boards
Contents
Configuring the environment
Install Compiler gcc-arm-none-eabi
Download last version of GCC ARM Embedded from: https://launchpad.net/gcc-arm-embedded/+download
Untar the compiler:
tar -xvjf gcc-arm-none-eabi-<VERSION>.tar.bz2
Copy it to a common place:
sudo cp -r gcc-arm-none-eabi-<VERSION> /opt/compilerNucleoST
Install OpenOCD On-Chip Debugger
Instal dependencies:
sudo apt-get install flex bison libgmp3-dev libmpfr-dev libncurses5-dev libmpc-dev autoconf texinfo build-essential \\ libftdi-dev libusb-1.0-0-dev libexpat1-dev
Download last version of Openocd from: http://openocd.org/
Untar openocd:
tar -xvzf openocd-<VERSION>.tar.gz
Go into the directory:
cd openocd-<VERSION>
Configure openocd compilation:
./configure --prefix=/opt/openocdNucleoST --enable-maintainer-mode --enable-stlink
Compile it:
make
Install:
sudo make install
Prepare its use according to udev:
sudo cp -r contrib/99-openocd.rules /etc/udev/rules.d/ sudo udevadm control --reload-rules
In order to run openocd as a non root user, you must to add your user name to plugdev group.
- Edit /etc/group
- Find plugdev
- Add your user after the colon symbol (e.g. plugdev:x:46:user1), or after the last user by adding a coma in between (e.g. plugdev:x:46:user1,user2,user3)
For connection, check in GDB Section
Hello World experiment
Download STMCube
STMicroelectronics introduces STMCube as an initiative to ease developers life. They are sharing packages containing libraries, documentation and examples. Packages are delivered per series (such as STM32CubeF4 for STM32F4 series)
and select the STMCubeXX according to your microcontroller (e.g. STM32CubeL4 for STM32L4 series) and load it in a prefered directory:
Untar STM32CubeXX:
unzip stm32cubexx.zip
This will create a Firmware directory which will be referred in this tutorial as <STM32_CUBE_FW_ROOTDIR>.
Create the experiment
The example is done for a toggle led experiment. It will be compiled for a specific nucleo board, named in this tutoral as <BOARD>.
Create experiment dir in your prefered directory:
mkdir helloWorld mkdir helloWorld/bin
Copy experiment sources:
cp -r <STM32_CUBE_FW_ROOTDIR>/Projects/<BOARD>/Examples/GPIO/GPIO_IOToggle/Src helloWorld/src cp -r <STM32_CUBE_FW_ROOTDIR>/Projects/<BOARD>/Examples/GPIO/GPIO_IOToggle/Inc helloWorld/include
Copy STM32 libraries:
cp -r <STM32_CUBE_FW_ROODIR>/Drivers/ helloWorld/lib
Copy startup code to src dir:
cp <STM32_CUBE_FW_ROOTDIR>/Projects/<BOARD>/Templates/SW4STM32/startup_<NUCLEO_BOARD>.s helloWorld/src
where <NUCLE_BOARD> refers to your nucleo board model.
Important If SW4STM32 does not exists use TrueStudio instead.
Copy linker file:
cp <STM32_CUBE_FW_ROOTDIR>/Projects/<BOARD>/Templates/SW4STM32/<BOARD>_Nucleo/<NUCLEO_BOARD>_FLASH.ld helloWorld/
where <NUCLE_BOARD> refers to your nucleo board model.
Important If TrueStudio does not exists use SW4STM32 instead.
Create an environment file to export PATH:
cd helloWorld echo $PATH > env.sh
Edit env.sh and at the begining of the line include:
export PATH=/opt/openocdNucleoST/bin:/opt/compilerNucleoST/bin:
Your file should look like this:
export PATH=/opt/openocdNucleoST/bin:/opt/compilerNucleoST/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
Download Makefile, rename it as "Makefile" and copy it to <HELLOWORLD> dir.
Open makefile and substitute:
- <PROJECT_NAME> with the name you want to give to your project
- <STM32_NUCLEO_BOARD> with the nucleo board name (e.g. STM32F4xx).
- <STM32_LNKER_FILE> with the name of the linker file in <HELLOWORLD> dir (e.g. STM32F446RETx_FLASH.ld)
- <STM32_MICROCONTROLLER> with the compilation directive of your specific microcontroller (e.g. STM32L053xx) found in your CMSIS STincludes dir (e.g. lib/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h)
- <CPU_INFO> with the mcpu of the controller (e.g. cortex-m0plus)
- <STARTUP_NAME> with the name of your startup filename. (e.g. startup_stm32f446xx) found in src dir (important: name it without extension).
After this, everything should be ready:
Export you PATH
source env.sh
Compile:
make
Copy the bin/<FILE>.bin to the disc that is created when the board is connected to the PC. An LED should be blinking.
NOTE It is interesting to clean the project before submitting to any repository. lib dir is full of unusfull information:
- In lib/BSP keep only the dir that refers to your board
- In lib/CMSIS keep only the Device and Include dirs
- In lib/HAL_DRIVER dir, keep only the Inc and Src dirs.
FreeRTOS Port
Before proceed with this section, you should have already implemented the previous section
Download and prepare sources
Download last version of FreeRTOS from: http://www.freertos.org/
Unzip it:
unzip FreeRTOS<VERSION>.zip
Copy FreeRTOS source to your working dir
cp -r <FREERTOS_DIR>/FreeRTOS/ helloWorld/
Go in helloworld/FreeRTOS dir and remove all but Source dir
Go in helloworld/FreeRTOS/Source/portable dir and remove all but GCC dir and <MemMag> dir
Go in helloworld/FreeRTOS/Source/portable/GCC dir and remove all but your CPU related (e.g. ARM_C0 for Cortex-M0)
Configure FreeRTOS
This is the most complex task, but this manual is not intended for it.
If you have a board already supported by FreeRTOS which is provided in the Demo examples, copy the FreeRTOSConfig.h found in those examples to your helloworld/include dir.
If not, download this FreeRTOSConfig.h , rename it as "FreeRTOSConfig.h", copy it to <HELLOWORLD>/include dir and work on it.
Go in your helloworld/src/stmXXXX_it.c file and comment the SVC_Handler, PendSV_Handler and SysTick_Handler functions
Download Makefile, rename it as "Makefile" and copy it to <HELLOWORLD> dir.
Open makefile and substitute:
- <PROJECT_NAME> with the name you want to give to your project
- <STM32_NUCLEO_BOARD> with the nucleo board name (e.g. STM32F4xx).
- <STM32_LNKER_FILE> with the name of the linker file in <HELLOWORLD> dir (e.g. STM32F446RETx_FLASH.ld)
- <STM32_MICROCONTROLLER> with the compilation directive of your specific microcontroller (e.g. STM32L053xx) found in your CMSIS STincludes dir (e.g. lib/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h)
- <CPU_INFO> with the mcpu of the controller (e.g. cortex-m0plus)
- <STARTUP_NAME> with the name of your startup filename. (e.g. startup_stm32f446xx) found in src dir (important: name it without extension).
- <RTOS_GCC_CPUINFO> with the name of the mcpu of the controller of the FreeRTOS dir (e.g. ARM_CM0) found in RTOS_SOURCE_DIR/portable/GCC/
Create a Basic Task
Open your main.c
Include FreeRTOS libs:
/* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "semphr.h"
Define a task and its handler
xTaskHandle ledpTask_Handle; void Ledp_Task();
In the main function, comment the while loop and provide instead the following code to create a task and start the scheduler:
xTaskCreate(Ledp_Task, "Ledp_Task", 70, NULL, 1, &ledpTask_Handle); vTaskStartScheduler();
Create a Task (function) with the following code:
void Ledp_Task (void * pvParams) { while(1) { HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); vTaskDelay(1000); } }
After this, everything should be ready:
Export you PATH
source env.sh
Compile:
make
Copy the bin/<FILE>.bin to the disc that is created when the board is connected to the PC. An LED should be blinking.
GDB Debug
It is mandatory openocd is installed in your system (see OpenOCD section)
You need an openocd.cfg file which is related to your board and jtag.
Here we provide a file with the configuration of an stlink and a STM32L053 mcu:
source [find interface/stlink-v2-1.cfg] transport select hla_swd set WORKAREASIZE 0x2000 source [find target/stm32l0.cfg] reset_config srst_only
However, find your jtag filename in interface of your openocd sources and your mcu filename on the target dir.
Once the file is configured, load the PATH
source env.sh
Connect to your board:
openocd -s /opt/openocdNucleoST/share/openocd/scripts/ -f openocd.cfg -c "init" -c "halt" -c "reset halt"
Output should be something similar to:
Open On-Chip Debugger 0.9.0 (2016-07-05-21:42) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html adapter speed: 300 kHz adapter_nsrst_delay: 100 Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD none separate srst_only separate srst_nogate srst_open_drain connect_deassert_srst Info : Unable to match requested speed 300 kHz, using 240 kHz Info : Unable to match requested speed 300 kHz, using 240 kHz Info : clock speed 240 kHz Info : STLINK v2 JTAG v24 API v2 SWIM v11 VID 0x0483 PID 0x374B Info : using stlink api v2 Info : Target voltage: 3.246505 Info : stm32l0.cpu: hardware has 4 breakpoints, 2 watchpoints Info : Unable to match requested speed 300 kHz, using 240 kHz Info : Unable to match requested speed 300 kHz, using 240 kHz adapter speed: 240 kHz target state: halted target halted due to debug-request, current mode: Thread xPSR: 0xf1000000 pc: 0x08000244 msp: 0x20002000
If the terminal gets there and does not return, you are now connected to the board.
Open a new terminal and load the PATH
source env.sh <pre> Launch ARM GDB <pre> arm-none-eabi-gdb
Connect GDB to openocd
target remote :3333
Reset the board
monitor reset halt
Import the file
file bin/ledp.elf
Load the binaries into the mcu
load
Reset the board
monitor reset halt
Run the board
continue
The board should be blinking at this point