Sunday, July 24, 2011

Building an Application for AT91SAM7S with FreeRTOS RTOS and IAR

 Le Trung Thang 2011 

After ported success the FreeRTOS kernel to AT91SAM7S board, see: “Porting Real Time OS "FreeRTOS" to AT91SAM7S256 Evaluation board”. Now, we can start to create an application using FreeRTOS. The preparation tools, you can see at above article.

The first, you need download the demo project at here. Unzip downloaded file and go to folder Atmel\at91sam7s-ek\FreeRTOS-getting-started  and open file FreeRTOS- this getting-started.eww to start IAR Embedded Workbench for ARM IDE.
From demo project, you can edit the project hierarchy as your requirement.

1.     Configuration Project
 Although the demo project was configured completely, however if you want modify the project as add new files, remove file,… then you need to know how to configure the project suitability.
To use library files no standard as Atmel library, FreeRTOS,… you need add directory path of them to IAR. Go to Project -> Option… -> C/C++ Compiler. Choose tab Preprocessor to add library directory (figure 1).

Fig 1. Include Directories for C/C++ compiler

 If you want to use libraries in Assembly files, then you need add path of libraries to tab Preprocessor of  Project -> Option… -> Assembler (figure 2). As in our project, to use FreeRTOS, we added directory FreeRTOS\Source and its sub-directories to IAR.

Fig 2. Include Directories for Assembler

2.     Include files
Like as any normal C/C++ library, to use FreeRTOS APIs, we need include the header file of FreeRTOS to our source file. The most important header files are FreeRTOS.h, task.h, semphr.h, queue.h
File FreeRTOS.h stores definitions for OS configuration as there are either using Mutex, Timer, Semaphore,.. or not.
File task.h defines core APIs as create task, start scheduler, context switch,…
File semphr.h and queue.h are for mutex, semaphore and message queue,…
In addition, if you want to use Software Timer, you need add file timers.h too.
Timer is a task which is scheduled to run after each determinate period.
A shortcoming of FreeRTOS (version 7.0 or previous) is it didn’t support the Flag API, a useful feature in Operating System.

3.     Write an Application
After configure the project as desire. We can begin to write an application. FreeRTOS supports both pre-empty and cooperative mode. To enable pre-empty mode, go to file FreeRTOSConfig.h and set macro configUSE_PREEMPTION to 1. Go to file FreeRTOS.h and set macro configUSE_MUTEXES to 1 to enable Mutex.
In demo project, our application has 4 tasks: vLED1FlashTask (named is tLED1), vLED2FlashTask (named is tLED2), vADCTask (named is tADC) and vSerialTask (named is tSerial).
Task tLED1 and tLED2 are simply to toggle status of 2 LEDs in turns in the board.
Task tADC will continuously get ADC value from ADC module (at channel 4) and send the ADC value to a buffer and then task tSerial will read this buffer to send its value to USART1 port (figure 3). Of course we would like synchronize between these tasks.
To synchronize 2 tasks tLED1 and tLED2, we ought to have to use Flag API, however, because FreeRTOS doesn’t support Flag mechanics, so we used the Queue. In this way, we didn’t use the Queue for sending data but is for synchronizing between 2 tasks.
To synchronize 2 tasks tDAC and t Serial, we used a Mutex. Before task tADC start a ADC conversion or task tSerial start to send data to USART1 port, they must check to know the Mutex is either available or not. After completed their mission, they need release the Mutex.
In addition, we used two GPIO interrupts to get interrupt from two buttons and also used interrupt of Timer 1. Two buttons are used to increase or decrease toggle speed of 2 the LEDs whereas Timer 1 is used to count time. Because Timer 1 interrupt has highest priority, so whenever Timer 1 interrupt occurs and global interrupt is enabled, it will always be serviced regardless of tasks state. Be noted that our program doesn’t support Nested interrupt.
In general, main purpose of this application is to demonstrate of using Queue, Mutex in FreeRTOS as well as their combination with interrupts. You can alternate the Queue, Mutex by other system-calls.  

Fig 3. Synchronization between tasks

Function main:
Like as a normal C/C++ program, main function is the entry of program. With a program have using RTOS, before we create tasks and start OS, we need init hardware modules as PIO, AIC, DBGU… We do this in function InitHardware.
Moreover, we should also create other needed system-calls before create tasks.
In our program, we created both Mutex and Message Queue in two functions: CreateAllSemaphore and CreateAllQueue. Four tasks were also created in function CreateAllTask. Start OS will be final work in main function.

In general, sequence of a program using RTOS should be (figure 4):
- Initialize low-level hardware (init CPU clock rate, operation mode, stack,..).
- Initialize hardware peripherals (GPIO, AIC, DBGU,…).
- Initialize OS resources (Semaphore, Mutex, Message Queue, Task,…).
- Start OS.

Fig 4. A typical main function of an OS-program

Finally, to test the application in the board, build and load execute file (in bin or hex format) to board. Use a terminal program as HyperTerminal of Windows or Tera Term to receive data from DBGU, for debug information (figure 5) and from USART1, for ADC data transfer (figure 6). Both DBGU and USART1 module were setup at speed 115200 bit/s, 8 bit data, 1 stop bit, no parity. 

Fig 5. Data from DBGU port

Fig 6. ADC data in mV from USART1 port

You need also setup jumpers in board suitable to enable USART1 and DBGU module (figure 7).
(fifffffffffffff figuere 7 here)

= = = =***= = = =***= = = =***= = = =
FreeRTOS is Copyright (C) Real Time Engineers Ltd.
IAR Embedded Workbench for ARM is Copyright (C) IAR Systems AB.


Anonymous said...

Thank You, Sir!

Anonymous said...

Hi, is this source still available? The link is dead. Thanks

Le Trung Thang said...

Hi. The link is still there, alive :))