In the previous example, we implemented a simple demo program that reads buttons by continually checking their status in the main program loop. This isn’t an efficient and convenient way to do that. Imagine your application has to do lots of tasks, and in between, you also need to check button status – mission becomes impossible unless you use interrupts. In this part, we briefly introduce to STM32F10x interrupt system and write example code where LEDs and buttons are serviced within interrupts. ARM Cortex-M3 microcontrollers have advanced interrupt system that is pretty easily manageable. All interrupts are controlled inside Nested Vectored Interrupt Controller (NVIC) which is close to the Cortex core to ensure low latency and robust performance. Main features of NVIC include:
Last time we have made a good starting point with setting up a project template for STM32F103ZET6 development board using GNU tools. Using the same project template, we can move forward and start programming other elements. This time a quick note about adding button library. This is a modest implementation which initializes port pins and then reads their status. Development board is equipped with four user programmable buttons named WAKEUP, TAMPER, USER1, and USER2. We are not going to care about the meaning of names use them as general purpose buttons for now.
Couple years ago I have purchased LPC2148 development board called BlueBoard form ngxtexhnologes. It is quite powerful board with ATM7TDMI series microcontroller which is considered an old guy comparing to Cortex ones. But still these are widely used and are powerful. Development board has some handy features installed. 12MHz crustal allowing to run processor at full 60Mhz speed. Couple RS232 ports, VGA connector, PS/2 connector for keyboard or mouse, 20-pin JTAG, SD/MMC slot, USB B-type, 8 LEDs driven with serial-in parallel-out shift register, 2×16 LCD, buzzer, audio jack with amplifier, two programmable buttons and 256Kb of I2C interfaced EEPROM. Microcontroller itself has 512KB of internal flash and 32+8KB of RAM. All ports are accessible and any external hardware can be disconnected with jumpers. This is great board for prototyping and end application.
I found some time to play with the STM32F103ZET6 development board and decided to set up a simple project for it. Probably the trickiest part of this is to set up a project environment that would serve as a template for following developments. Many ARM developers chose CodeSourcery Lite edition toolchain. It has full command line functionality – this is what we usually need. If you want some alternative – you can select gnu yagarto ARM toolchain which is also great and free. No matter which tool you select code will work on both. Let’s stick to CodeSourcery. Just download it and install to your PC. As we said Lite version supports only command line tools – we need an interface for it. Eclipse IDE is one of the favorite choices so that we will grab this one too. Yagarto website has an excellent tutorial on how to set up the Eclipse IDE in a step-by-step manner. We won’t go into details with this.
AVR microcontrollers aren’t the best choice to run FreeRTOS scheduler due to low on-chip RAM. Atmega128 has only 4K of RAM, so this limits the FreeRTOS functionality to very basic. Anyway, this problem can be solved by adding extra RAM which may be connected to an external memory interface. We have already built an external memory block of 8K previously so now we can test it with FreeRTOS applications. Lets continue with our previous code which runs several simple tasks (button state reading, LCD output and LED flash), and we can add more to it. We are going to set up an external RAM for storing heaps. This will allow to store large data buffers without worrying too much about heap and stack overlaps.
In the previous post, we just run a single task. Running RTOS with single task has no meaning at all. This can be quickly done with a conventional program. But what if we need to have more separate functions. To execute them at exact timing would require a separate timer or interrupt. But microcontroller cannot guarantee an interrupt for every task. This way it is hard to make code modular, and testing can be painful. Using RTOS solves this kind of problem. It allows programming each task as an endless loop. Kernel scheduler takes care of assuring each task gets its chunk of processing time. Additionally, it does bearing the priority systems – more critical tasks are executed before less important ones. Let us go further with our example code and add more tasks to our FreeRTOS engine. We already have LED flashing task that toggles LED every second. Additionally, we are going to create another task that checks the button state. Also, we are going to send some information to the LCD. As always let’s take care of drivers for all of them.
FreeRTOS is known as Real-Time Operating System. Probably it would be too dare call it real-time-os, preferably a real-time scheduler where applications can be split into independent tasks that share full processor resources by switching them rapidly it looks like all functions are executed in parallel. This feature is called multitasking. There are lots of debates on using RTOS on AVR microcontrollers as they are arguably too small for the running scheduler. The main limitation is a small amount of ram and increased power usage. If you are going to use lots of tasks in the application, probably you will run out of RAM that is used for saving context when switching between tasks. Consider FreeRTOS only if you use larger scale AVRs like Atmega128 or Atmega256. Surely you can find smaller schedulers that are specially designed for smaller microcontrollers even tiny series. In another hand, if you master FreeRTOS, it can be used with multiple types of microcontrollers like ARM, Cortex, PIC and various compilers including IAR, GCC, Keil, Rowley, Attolic. And the main reason to keep an eye on it – it is free. Probably it would take lots of time and space to go through RTOS theory.…