Embedded ARM development under ChibiOS/RT with an STM32-H152 microcontroller from Olimex
Dans le cadre d’un projet de développement embarqué pour un de nos clients, nous avons eu à mettre en place un environnement de développement embarqué ARM sous ChibiOS/RT avec un microcontrôleur STM32-H152 d’Olimex afin de répondre à leurs besoins et de réaliser le projet. L’article qui suit est un tutoriel sur les étapes que nous avons dû franchir afin d’avoir tout en place pour procéder au développement de la solution embarquée.
Material used
STM32-H152 from Olimex
The choice of microcontroller for this project was Olimex's STM32-H152 because it met the specific needs of our customer. It is a low-cost development IC based on STMicroelectronics' STM32L series of processors. The ARM Cortex-M3 processor stands out for its very low power consumption and supports multiple communication interfaces such as USB, USART, SPI and I2C. It integrates 128K bytes of flash memory, 16K bytes of RAM memory, an 8x40 segment LCD driver, 80 GPIO and a 32MHz clock. In short, a little marvel!
ARM-USB-TINY-H by Olimex
We chose to use the ARM USB JTAG debugger because of its low cost and because it works with OpenOCD (open source software). It also offers fast programming speed (copy to flash memory) under USB 2.0.
Preparation of the development environment
Although it is possible and easy to set up an open source ARM development environment under Linux and Mac OS X, this article focuses on configuration under Windows 7 only. There are several commercial solutions to do ARM development, but we have chosen to go with the Eclipse (CDT), OpenOCD, YAGARTO and Zylin solution.
Olimex simplifies the configuration by offering a development suite called Olimex ODS based on OpenOCD. If you are already familiar with the Eclipse integrated development environment, you will appreciate not having to learn a new tool.
Eclipse
One of the most widely used integrated development environments in the world. Version 0.9 of the development suite offers the Helios version with C/C++ Developer Tooling (CDT) of Eclipse.
YAGARTO (Yet Another GNU Arm Toolchain)
YAGARTO contains all the tools needed to compile (GCC) and debug (GDB) with the ARM architecture.
Zylin Embedded CDT
It is an open-source extension that bridges the gap between OpenOCD and Eclipse.
OpenOCD
Open On-Chip Debugger (OpenOCD) is a tool to program ARM circuits supporting different JTAG adapters via USB (including our ARM-USB-OCD-H debugger).
Installation d’Olimex ODS
The installation of the development suite is very simple. Just download the installer at this address and follow the instructions.
We will come back later with some special configuration steps that are necessary in order to transfer the binary to the flash memory and to debug.
ChibiOS/RT
There are several interesting options for the choice of a real-time exploration system (RTOS). Some are commercial and proprietary (Windows CE, VxWorks) while others are free and open source (RTLinux, FreeRTOS). We chose ChibiOS/RT mainly because of its small size, its speed for context switching and its portability. Also note its excellent support for ARM architecture.
ChibiOS/RT is used in production in the automotive, robotics and energy management fields among others. It is well documented and presents several examples to accelerate learning. To develop with ChibiOS, simply download the latest stable version and unzip the files in an easy to access location.
ChibiOS works as subsystems thanks to drivers that can be activated according to our needs. Here are some of them:
- ADC (Analog to Digital Converter)
- CAN (Controller Area Network)
- GPT (General Purpose Timer)
- HAL (Hardware Abstraction Layer)
- I2C (Inter-Integrated Circuit)
- MAC (Media Access Control)
- SDC (Secure Digital Card)
- SPI (Serial Peripheral Interface)
- USB (Universal Serial Bus)
A simple example
The following source code demonstrates a simple but classic example, which only flashes the red LED (PIN 10 of bank E) on the STM32-H152 every second.
#include "ch.h"
#include "hal.h"
int main(void) {
halInit();
chSysInit();
palSetPadMode(GPIOE, GPIOE_PIN10, PAL_MODE_OUTPUT_PUSHPULL);
while (TRUE) {
palSetPad(GPIOE, GPIOE_PIN10);
chThdSleepMilliseconds(500);
palClearPad(GPIOE, GPIOE_PIN10);
chThdSleepMilliseconds(500);
}
}
It is this code that we will use to further configure our environment.
Creation of a new project in Eclipse and compilation
The first step is to create a new project in Eclipse. To do this, simply create a C project (File → New → C Project), give it a name and select the Makefile / Empty Project type with Other Toolchain.
Then, it is advisable to import an already existing project among those available in the ChibiOS/RT distribution. The examples are light and contain little code and can be used as a skeleton for the creation of a new project. So, in the case of the STM32-H152, we simply imported the example named ARMCM3-STM32L152-DISCOVERY present in the "demos" folder (right click on the project → Import... → File System). Then, we have to select the files of the example excluding the "iar" and "keil" folders.
Once the project is created, you will have the following structure.
The links in the "board", "bone" and "test" folders must be modified to point to those contained in the ChibiOS folder (right click on the folder → Properties... → Location Edit...).
If it is not already done, the path of the YAGARTO tools must be added to the PATH environment variable as below. In our case, the executables were installed in C:\OlimexODS\yagarto\bin.
Since this is a copy of an existing example, it is also necessary to modify the Makefile of the project to adjust the value of the variable CHIBIOS so that it points to the right place as in the following figure.
# Imported source files and paths
CHIBIOS = C:\Users\jprimeau\Documents\ChibiOS_2.6.3
include $(CHIBIOS)/boards/ST_STM32L_DISCOVERY/board.mk
include $(CHIBIOS)/os/hal/platforms/STM32L1xx/platform.mk
include $(CHIBIOS)/os/hal/hal.mk
include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32L1xx/port.mk
include $(CHIBIOS)/os/kernel/kernel.mk
include $(CHIBIOS)/test/test.mk
The last step is to copy the source code of our simple example we saw earlier and replace the contents of the main.c file from the imported example. We are now ready to compile the embedded application (Project → Build). This action will produce a "build\ch.bin" file that can be copied to the flash memory of the STM32 processor.
Configuring and launching OpenOCD
Now that we have successfully compiled the source code, we need to add a configuration for an external tool to make it easier to launch an instance of OpenOCD (Run → External Tools → External Tools Configuration) and add a configuration as below.
In our case, the arguments needed to specify the right target for the STM32-H152 and the right interface for the ARM-USB-TINY-H JTAG were the following.
-f C:\OlimexODS\openocd-0.6.1\scripts\interface\olimex-arm-usb-tiny-h.cfg -f C:\OlimexODS\openocd-0.6.1\scripts\target\stm32l.cfg -c "init" -c "reset"
Binary copy and debugging on the STM32-H152
First, it is necessary to create a debug configuration for the project (Run → Debug Configurations...). This configuration must be of type "Zylin Embedded debug (Native)". In the "Debugger" tab, point the "GDB Debugger" field to the YAGARTO GDB. In our case, the path was C:\OlimexODS\yagarto\bin\arm-none-eabi-gdb.exe.
Finally, an initialization script must be specified for GDB so that it connects to the OpenOCD instance (port 3333 on localhost). This same script will copy the (binary) image to the flash memory of the microcontroller to finally put a breakpoint in the main function.
In our case, the script to copy the binary to the microcontroller and to cause a shutdown in the main function was the following.
target remote localhost:3333
monitor reset halt
monitor wait_halt
monitor sleep 100
monitor poll
monitor flash probe 0
monitor flash write_image erase /Users/jprimeau/Documents/workspace/STM32-H152/build/ch.bin 0x08000000
monitor sleep 200
monitor soft_reset_halt
monitor wait_halt
monitor poll
symbol-file /Users/jprimeau/Documents/workspace/STM32-H152/build/ch.elf
thbreak main
continue
Once everything is in place, all you have to do is launch an instance of OpenOCD (Run → External Tools → OpenOCD) and launch an instance of GDB (Run → Debug).
Launching an instance of OpenOCD :
Open On-Chip Debugger 0.6.1 (2012-10-07-10:34)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.sourceforge.net/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
adapter speed: 100 kHz
adapter_nsrst_delay: 100
jtag_ntrst_delay: 100
cortex_m3 reset_config sysresetreq
Info : max TCK change to: 30000 kHz
Info : clock speed 100 kHz
Info : JTAG tap: stm32l.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
Info : JTAG tap: stm32l.bs tap/device found: 0x06416041 (mfg: 0x020, part: 0x6416, ver: 0x0)
Info : stm32l.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : JTAG tap: stm32l.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
Info : JTAG tap: stm32l.bs tap/device found: 0x06416041 (mfg: 0x020, part: 0x6416, ver: 0x0)
Launching the GDB instance :
target remote localhost:3333
0x00000000 in ?? ()
monitor reset halt
JTAG tap: stm32l.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
JTAG tap: stm32l.bs tap/device found: 0x06416041 (mfg: 0x020, part: 0x6416, ver: 0x0)
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08000120 msp: 0x20000400
monitor wait_halt
monitor sleep 100
monitor poll
background polling: on
TAP: stm32l.cpu (enabled)
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08000120 msp: 0x20000400
monitor flash probe 0
flash size = 128kbytes
flash 'stm32lx' found at 0x08000000
monitor flash write_image erase /Users/jprimeau/Documents/workspace/STM32-H152/build/ch.bin 0x08000000
auto erase enabled
wrote 8192 bytes from file /Users/jprimeau/Documents/workspace/STM32-H152/build/ch.bin in 2.195126s (3.644 KiB/s)
monitor sleep 200
monitor soft_reset_halt
requesting target halt and executing a soft reset
target state: halted
target halted due to breakpoint, current mode: Thread
xPSR: 0x01000000 pc: 0x08000120 msp: 0x20000400
monitor wait_halt
monitor poll
background polling: on
TAP: stm32l.cpu (enabled)
target state: halted
target halted due to breakpoint, current mode: Thread
xPSR: 0x01000000 pc: 0x08000120 msp: 0x20000400
symbol-file /Users/jprimeau/Documents/workspace/STM32-H152/build/ch.elf
thbreak main
Hardware assisted breakpoint 1 at 0x8001822: file main.c, line 5.
continue
The Result
If everything worked as expected, you should be able to see the red LED flashing every second as shown in the following picture. Congratulations! You have just done embedded development for an ARM architecture on a microcontroller using a real-time operating system!
Conclusion
We started with an overview of the material used for this tutorial to follow with the preparation of the development environment and the presentation of ChibiOS/RT. We then created an embedded development project for ChibiOS in Eclipse based on an example and we proceeded to compile it to finish with the necessary steps to configure OpenOCD and Zylin.