P. 1
QDK_FreeRTOS

QDK_FreeRTOS

|Views: 141|Likes:
Published by Pham Cong Dung

More info:

Published by: Pham Cong Dung on Dec 29, 2011
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

11/17/2012

pdf

text

original

QP state machine frameworks for FreeRTOS.

org™

QDK™ FreeRTOS.org™
Document Revision B September 2008

Copyright © Quantum Leaps, LLC www.quantum-leaps.com www.state-machine.com

Table of Contents
1 1.1 1.2 Introduction.................................................................................................... 1 What’s Included in the QDK-FreeRTOS? ............................................................... 2 Licensing QDK-MSP430-IAR................................................................................ 2

2

Getting Started ............................................................................................... 3 2.1 Installation ...................................................................................................... 3 2.2 Building the QP Libraries .................................................................................... 4 2.3 Building the Examples ....................................................................................... 5 2.4 Running the Examples ....................................................................................... 6 2.4.1 Minimal FreeRTOS.org Demo Application ........................................................ 7 2.4.2 Dining Philosopher Problem (DPP) Example Application .................................... 7 3.1 3.2 3.3 3.4 3.5 The Modified FreeRTOS.org Port STR9x_IAR................................................... 9 Augmented FreeRTOS.org Interrupt Processing ..................................................... 9 General Limitations of FreeRTOS.org Ports.......................................................... 10 Changes in the portmacro.h file ......................................................................... 10 Changes in the port.c File................................................................................ 13 Demo Application for the Updated FreeRTOS.org Port........................................... 14

3

4

The QP Port to FreeRTOS.org ........................................................................ 15 4.1 The FreeRTOSConfig.h Header File .................................................................... 15 4.2 The qep_port.h Header File .............................................................................. 16 4.3 The qf_port.h Header File................................................................................. 16 4.3.1 The Active Object Event Queue and Thread .................................................. 17 4.3.2 The QF Critical Section .............................................................................. 17 4.3.3 FreeRTOS.org Include Files ........................................................................ 17 4.3.4 QP Include Files........................................................................................ 17 4.3.5 Memory Pool ............................................................................................ 18 4.4 The qf_port.c Source File ................................................................................. 18 4.5 ARM/THUMB Compilation ................................................................................. 22 5.1 5.2 5.3 5.4 5.5 The Example QP Application.......................................................................... 23 The main() Function ........................................................................................ 23 ISRs ............................................................................................................. 24 Starting Interrupts in vStartInterrupts()............................................................. 25 Idle Processing in vApplicationIdleHook() ........................................................... 25 Assertion Handling Policy in Q_onAssert() .......................................................... 26 The Quantum Spy (QS) Instrumentation....................................................... 27 QS Time Stamp Callback QS_onGetTime().......................................................... 29 Invoking the QSpy Host Application ................................................................... 30 Related Documents and References .............................................................. 31 Contact Information...................................................................................... 32

5

6 6.1 6.2 7 8

Copyright © Quantum Leaps, LLC. All Rights Reserved.

i

1 Introduction
This QP™ Development Kit (QDK) describes how to use QP™ event-driven platform with the FreeRTOS.org™ real-time kernel. The actual hardware/software used in this QDK is described below (see also Figure 1): 1. IAR STR912-SK board with STR912F device (ARM966E-S core, 96KB RAM, 512KB ROM). 2. IAR Embedded Workbench for ARM (EWARM) KickStart edition version 5.11. 3. FreeRTOS.org™ version 5.0.0 or higher. 4. QP/C/C++ v4.0 or higher. J-Link USB Debugger QS trace data (UART0) LED/Peripheral Jumpers

Two groups of user LEDs 8 LEDs each STR912F Target Device

USB to PC

External power

Power source selection Jumper

Figure 1 IAR STR912-SK evaluation board with the J-Link JTAG pod.

Copyright © Quantum Leaps, LLC. All Rights Reserved.

1 of 32

The DPP example application is described in the Application Note “Dining Philosophers Application” [QL AN-DPP 08] (included in this DPP).state-machine.TXT included in the packaging of every Quantum Leaps software distribution.quantumleaps. Additionally. 2 of 32 .quantum-leaps.QDK™ FreeRTOS. which are designed for customers who wish to retain the proprietary status of their code and therefore cannot use the GNU General Public License. the QDK should require minimal adaptation for any other platform supported by FreeRTOS. The GPL open source license allows you to use the software at no charge under the condition that if you redistribute the original software or applications derived from it. a minimal demo application that tests this updated FreeRTOS. In other words.org™ to access the hardware. All Rights Reserved. NOTE: Even though the QDK uses a specific target board (STR912-SK in this case).com/msp430 website is offered with the following two licensing options: • The GNU General Public License version 2 (GPL) as published by the Free Software Foundation and appearing in the file GPL. One of several Quantum Leaps commercial licenses. 1. 1. NOTE: This QDK covers both the C and C++ version of QP. The customers who license Quantum Leaps software under the commercial licenses do not use the software under the GPL and therefore are not subject to any of its terms.org™. the complete source code for your application must be also available under the conditions of the GPL (GPL Section 2[b]). LLC.2 Licensing QDK-MSP430-IAR The Generally Available (GA) distribution of QDK-MSP430-IAR available for download from the www. the STR912-SK board is connected via a 20-pin ribbon cable to the J-Link USB debugger.1 What’s Included in the QDK-FreeRTOS? This QDK provides a modified FreeRTOS port to STR91-IAR. You need a straight serial cable with DB9 connectors to connect UART0 to the COM port of your PC. please visit the licensing section of our website at: www.org port. • For more information. The DPP application also demonstrates the QS (“Spy”) software tracing.com/freertos As shown in Figure 1. Copyright © Quantum Leaps. The concrete code examples are taken from the C version. the QDK has been designed generically to rely on the FreeRTOS.org™ www. as well as QP port to FreeRTOS and the Dining Philosopher Problem (DPP) application to test the QP port to FreeRTOS.com/licensing. the UART0 connector of the STR912-SK board is used in this QDK for QS (“Spy”) software tracing of the live QP applications. but the C++ version is essentially identical except for some trivial syntax differences.

2. build. NOTE: This QDK assumes that the standard QP distribution. LLC. The following Listing 1 shows the directory structure and selected files included in the QDK-FreeRTOS distribution.pdf .pdf +-QDK_FreeRTOS. .zip.c | | | | +-portmacro.h | +-ports/ | +-arm/ | | +-freertos/ | | | +-iar/ | | | | +-dbg/ . It is also strongly recommended that you read the QP Tutorial (www. and use QDK-FreeRTOS. This information is intentionally included early in this document. – | +-Source/ | +-portable/ – | | +-IAR/ – | | | +-STR9x/ – | | | | +-port.h | +-qf.org root directory FreeRTOS.h | +-qequeue.h | +-qpset. consisting of QEP.QDK™ FreeRTOS.org™ www.org demo applicaitons – Modified ARM9_STR91X_IAR demo application the main() function of the application FreeRTOS configuration IAR workspace to build the application other files in the application FreeRTOS.org source files FreeRTOS.com/freertos 2 Getting Started This section describes how to install.state-machine.org ports ports for the IAR toolset ports for the STR9x MCUs (!! MODIFIED from the original !!) port-specific code (!! MODIFIED from the original !!) port-specific macros (!! MODIFIED from the original !!) context-switch support (unchanged) vPortStartFirstTask and vPortYieldProcessor (unchanged) FreeRTOS/ | +-Demo/ | +-ARM9_STR91X_IAR_light/ | | +-main.h | | | | +-portasm.h | +-qep. You should uncompress the archive into the same directory into which you’ve installed all the standard QP components.html) before you start experimenting with this QDK.c | | | | +-ISR_Support.1 Installation The QDK code is distributed in a ZIP archive (qdkc_freertos_<ver>.h | +-qmpool.c – | | +-FreeRTOSConfig. .Documentation for this QDK .com/doxygen/qpc/tutorial_page. has been installed. before installing this QDK.0. so that you could start using the QDK as soon as possible. (Please note that the QP directory structure is described in detail in a separate Application Note: “QP Directory Structure” [QL AN-Directory 07]): doc\ | +-AN_DPP. and QS.QP root directory (qpcpp for QP/C++) – – – – – – QP public include files Quantum Assertions platform-independent public include QEP platform-independent public include QF platform-independent public include native QF event queue include native QF memory pool include native QF priority set include QP ports ARM port FreeRTOS.quantum-leaps. QF. where <ver> stands for a specific QDK-FreeRTOS version.This “QDK Programmer’s Manual” FreeRTOS.s79 <qp>/ | +-include/ | +-qassert. All Rights Reserved.eww – | | +-.01).org ports IAR compiler QP libraries for Debug configuration 3 of 32 Copyright © Quantum Leaps.h – | | +-RTOSDemo.Application Note “Dining Philosophers Application” . such as 4. The installation directory you choose will be referred henceforth as QP Root Directory (<qp>). .

eww . The code distribution contains all the batch file make_ARM966E-S.c .com/freertos | | | | +-rel/ . you typically don’t need to rebuild them—at least not on the daily basis as you work on your application. 2.org task implementation Listing 1 Selected QP directories and files after installing QDK-FreeRTOS.QDK™ FreeRTOS.org configuration to use in the QP port | | | | +-qep_port.subdirectory containing the examples | +-arm/ .raw FreeRTOS. NOTE: To streamline and simplify the QP-library build process. Quantum Leaps software does not use the vendor-specific IDEs.h .h . Instead. In fact. All Rights Reserved.IAR EWARM examples | | | | +-dpp-str912-sk/ .FreeRTOS examples | | | +-iar/ .driver library header files | | | | | | +-source/ .the Table active object | | | | | +-freertos_task.h . 4 of 32 .state-machine.driver library source files | | | | | +-dpp-freertos.Board Support Package for MSP430 | | | | | +-bsp. This QDK uses the IAR EWARM IDE to build the example applications. such as the IAR Embedded Workbench IDE. once you have the QP libraries.the main function | | | | | +-philo. and QS are provided inside the <qp>\ports\arm\freertos\iar\ directory (see Listing 1). you open a console window on a Windows PC.2 Building the QP Libraries QP is deployed as a set of libraries that you statically link to your application.QP libraries for Spy configuration | | | | +-make_ARM966E-S.c .h .QP port | +-examples/ .c .QF port to FreeRTOS.org with the IAR ARM compiler. The build process for your application is largely independent on the QP-library builds.directory containing the Spy build | | | | | +-STR91xlibrary/ . to build the debug version of all the QP libraries for FreeRTOS.QEP port | | | | +-qf_port. LLC. The highlighted elements are included the files included in QDK-FreeRTOS.h .bat Copyright © Quantum Leaps.h .org | | | | +-qs_port.make script for building QP libraries (ARM966E-S core) | | | | +-FreeRTOSConfig. but you are free to use any other build strategy.bat for building all the libraries located in <qp>\ports\arm\freertos\iar\ directory.directory containing the ST driver library for STR91x | | | | | | +-include/ .QS port | | | | +-qp_port.h .ARM examples | | +-freertos/ .IAR workspace to build the DPP example | | | | | +-bsp. This section describes steps you need to take to rebuild the libraries yourself.directory containing the Debug build | | | | | +-rel/ .FreeRTOS.bat . change directory to <qp>\ports\freertos\iar\. QF. and invoke the batch script by typing at the command prompt the following command: make_ARM966E-S.org task header file | | | | | +-freertos_task.the Philosopher active object | | | | | +-dpp.c .directory containing the Release build | | | | | +-spy/ .BSP header file | | | | | +-main.h .org™ www.Dining Philosophers example for STR912-SK | | | | | +-dbg/ .QP libraries for Release configuration | | | | +-spy/ . The pre-built libraries for QEP.the DPP header file | | | | | +-table. For example. this QDK provides command-line build process based on simple batch scripts.c .raw FreeRTOS. for building the QP libraries.

. All Rights Reserved.bat utility with the “spy” target. The make_ARM966E-S. LLC.QDK™ FreeRTOS.bat file if you’ve installed the IAR toolset in a different directory. The workspaces are located in <qp>\examples\arm\freertos\iar\dpp-str92-sk\dpp-freertos. you select the build configuration from the drop-down box in the top-left corner of the IDE.org in a different directory.\FreeRTOS\Source\include relative to the QP port directory (see Listing 1).state-machine. As shown in Figure 2. Other targets are “rel”.bat. You choose the build configuration by providing a target to the make_ARM966E-S.\.\. The default target is “dbg”.esw. You also need to adjust the symbol RTOS_INCDIR if you’ve installed FreeRTOS.\.com/freertos The make process should produce the QP libraries in the location: <qp>\ports\arm\freertos\iar\dbg\. and “spy” respectively. you need to build the Spy version of the QP libraries.\. NOTE: You need to adjust the symbol IAR_ARM at the top of the make_ARM966E-S.org™ www. Release. The batch script also assumes that FreeRTOS is installed in the directory .3 Building the Examples This QDK-FreeRTOS uses the DPP (“Dining Philosophers Problem”) example described in Application Note [QP AN-DPP 08]. and Spy. like this: make_ARM966E-S spy The make process should produce the QP libraries in the directory: <qp>\ports\arm\freertos\iar\spy\. and spy software versions 2. Each workspace contains three build configurations: Debug.bat utility. In order to take advantage of the Q-SPY instrumentation.bat assumes that the IAR ARM toolset has been installed in the directory c:\tools\IAR\ARM_KS_5.. The following table summarizes the targets accepted by make. You achieve this by invoking the make_ARM966E-S. 5 of 32 . Software Version Debug (default) Release Spy Build command make_ARM966E-S make_ARM966E-S rel make_ARM966E-S spy Table 1 Make targets for the debug. Copyright © Quantum Leaps. The QDK contains the IAR Embedded Workbench workspaces to build the examples..11. release...

Release.org™ www. Copyright © Quantum Leaps. All Rights Reserved.state-machine. this QDK contains two example applications for the STR912-SK board. LLC. or Spy Figure 2 IAR Embedded Workbench with the dpp-freertos.4 Running the Examples As mentioned before.eww workspace. LED 16 LED 15 LED 14 LED 13 LED 12 LED 11 LED 10 LED 9 LED 8 LED 7 LED 6 LED 5 LED 4 LED 3 LED 2 Figure 3 LED/Peripheral jumper setting on the STR912-SK board.QDK™ FreeRTOS. LED 1 6 of 32 .com/freertos Use the drop-down list to select one of the build configurations: Debug. 2. Both of these examples require setting up the jumpers as shown in Figure 1 and in greater detail in Figure 3.

4.org demo application for the updated port to the STR1x processor.org™ www. LED 16 is toggled within the idle callback (vApplicationIdleHook()). Figure 4 The RTOSDemo demo application stopped at the IAR debugger You load and debug the application using the IAR Embedded Workbench (see Figure 4).com/freertos 2. Copyright © Quantum Leaps.state-machine.2 Dining Philosopher Problem (DPP) Example Application The second example included in this QDK is the Dining Philosopher Problem (DPP) Example Application described in the Application Note “Dining Philosophers Application” [QL AN-DPP 08].org Demo Application The first example included in this QDK is a minimal FreeRTOS. 2. This example demonstrates QP and its purpose is to validate the QP port to FreeRTOS.org. 7 of 32 .1 Minimal FreeRTOS.org demo).QDK™ FreeRTOS. All Rights Reserved. This example does not use QP and its purpose is to validate the modified FreeRTOS port. LLC. This demo application is located in the directory FreeRTOS\Demo\ARM9_STR91X_IAR_light (see Listing 1).4. The application uses the User LEDs 9-11 to display the status of the three tasks LED-flashing tasks (the standard minimal FreeRTOS. This example application is located in the directory <qp>\examples\arm\freertos\iar\dpp-str912-sk\ (see Listing 1).

Additionally LED 15 should blink once per second with 50% duty cycle.QDK™ FreeRTOS. (Please use the actual COM port number on your PC. LED 16 is toggled from the FreeRTOS idle callback (vApplicationIdleHook()) If you downloaded the Spy build configuration to the target board and connected the UAR0 of the STR912-SK board to the COM port on your PC. LED 16 should glow at lower intensity than the rest of the LEDs. Copyright © Quantum Leaps. LLC.) The following screen shot shows the QSPY output from the DPP run: command-line options used timestamp QS trace record Figure 5 Screen shot from the QSPY output. Finally.org™ www. 8 of 32 . Change the directory to the QSPY host utility <qp>\tools\qspy\win32\mingw\rel and execute: qspy –c COM1 –b 115200 This will start the QSPY host application to listen on COM1 serial port with baud rate 115200.state-machine. the user LEDs 9-13 (see Figure 1) should blink indicating the changing status of the Dining Philosophers. LED 15 is driven from a raw FreeRTOS task running outside the QP framework. you could launch the QSPY host utility to observe the output in the human-readable format. You launch the QSPY utility on a Windows PC as follows.com/freertos As the DPP application is running. All Rights Reserved.

xQueueReceiveFromISR(). To be able to use the FreeRTOS. QF_publish().org ports must be modified to work with QP for the following two reasons: 1. } /* always inform FreeRTOS about exiting an ISR */ (5) (6) Listing 2 Augmented interrupt processing for FreeRTOS. QActive_postFIFO(). Call one of QP services allowed in ISRs: QF_tick(). QEQueue_postFIFO().org. but this is an exception). NOTE: Because of this design aspect of FreeRTOS.org ISR processing to keep track of interrupt nesting as well as critical section established automatically in hardware upon the interrupt entry. (3) (4) /* always inform FreeRTOS about entering an ISR */ /* clear the interrupt source. you need to manually update the FreeRTOS.org critical section mechanism. 3. QP must not inadvertently unlock interrupts within ISRs (again. ARM7/ARM9 processors enter the IRQ exception with IRQs locked at the ARM core level. xQueueSendToFrontFromISR().org Interrupt Processing The solution to both these issues is to augment FreeRTOS. QEQueue_postLIFO(). portISR_EXIT(). because QP uses the same API inside tasks and ISRs). FreeRTOS.com/freertos 3 The Modified FreeRTOS.org to a newer version. */ Call one of FreeRTOS services allowed in ISRs: vTaskIncrementTick().QDK™ FreeRTOS. 9 of 32 .org (1) The ISR is typically entered with interrupts locked in hardware (some CPUs. xQueueSendToBackFromISR(). In contrast. QEQueue_get(). All Rights Reserved. QP uses the same API in all contexts.. Copyright © Quantum Leaps. FreeRTOS.org™ www.h master include file.org generally does not support interrupt nesting and consequently interrupts should never be unlocked inside ISRs. In particular. 2. LLC.org Port STR9x_IAR The standard FreeRTOS.org uses different APIs for posting to message queues from tasks and ISRs.state-machine. vTaskResumeFromISR(). xQueueSendFromISR()..1 Augmented FreeRTOS. The following (1) void Your_ISR(void) { (2) portISR_ENTRY(). Unfortunately. Q_NEW(). because all FreeRTOS ports are hard-coded in the FreeRTOS. xSemaphoreGiveFromISR().org ports each time you update FreeRTOS. it is not possible to define the updated port in a different location than the hardwired directory. QACtive_postLIFO(). such as ARM Cortex-M3 don’t lock interrupts.

org ports.org does not support nesting of interrupts for most CPU architectures. NOTE: Calling postISR_EXIT() at the beginning of every ISR is necessary for correct performance of the QP framework.org™ www. Preferably. . FreeRTOS. */ portCHAR portFLOAT portDOUBLE portLONG portSHORT portSTACK_TYPE portBASE_TYPE char float double long short unsigned portLONG portLONG 10 of 32 Copyright © Quantum Leaps. #include <intrinsics. This means that you should never enable interrupts inside ISRs. (5) You may also call any of the QP services allowed in the ISR context. you should not use FIQ at all. LLC. 3. so they can be copied verbatim to other FreeRTOS. Note that the changes are fairly generic.h file Listing 3 shows the portmacro. Please note that most QP services allowed in ISRs can also be called from the task level.org services from FIQ (“fast interrupt”).3 Changes in the portmacro. (4) You may call any of the FreeRTOS. you should not call any FreeRTOS. either directly or indirectly inside any function you call from ISRs.com/freertos (2) The macro portISR_ENTRY() informs FreeRTOS. (3) If your interrupt source requires clearing.state-machine. This macro is shown in Listing 3. This macro performs also FreeRTOS. All Rights Reserved.h header file located in the port directory (<FreeRTOS>\Source\portable\IAR\STR91x\) in this case.org (and QP) about exiting the ISR. including ARM7/ARM9.org context switch. specifically to ARM7/ARM9 architectures.org services allowed in the ISR context. 3.0. NOTE: Calling postISR_ENTRY() at the beginning of every ISR is necessary for correct performance of the QP framework.org (and QP) about entering the ISR. if preemptive configuration is selected. The explanation section immediately following Listing 3 describes the changes made with respect to the original portmacro.org Ports As of Version 5. (2) The macro portISR_EXIT() informs FreeRTOS. you should perform it right after portISR_ENTRY().2 General Limitations of FreeRTOS. Additionally.QDK™ FreeRTOS.h> #ifdef __cplusplus extern "C" { #endif /* Type #define #define #define #define #define #define #define definitions.h header file from the standard FreeRTOS distribution. The ARM architecture has no means to protect IRQs from preemption by the FIQ and consequently interrupt nesting cannot be prevented when FIQ is used. This macro is shown in Listing 3.

\ } while (0) #endif /* externals and constants required to handle critical sections */ (17) extern volatile unsigned portLONG ulCriticalNesting. \ } while (0) (11) #if configUSE_PREEMPTION == 1 #define portISR_EXIT() do { \ (12) --ulInterruptNesting.QDK™ FreeRTOS. \ (3) ++ulCriticalNesting. \ (13) --ulCriticalNesting. (18) extern volatile unsigned portLONG ulInterruptNesting. #define portMAX_DELAY ( portTickType ) 0xffff #else typedef unsigned portLONG portTickType. \ } while (0) (4) #define portEXIT_CRITICAL() \ (5) if ((--ulCriticalNesting) == portNO_CRITICAL_NESTING) { \ (6) __enable_interrupt(). */ #define portSTACK_GROWTH ( -1 ) #define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 4 #define portYIELD() asm ( "SWI 0" ) #define portNOP() asm ( "NOP" ) /*-----------------------------------------------------------*/ #define portDISABLE_INTERRUPTS() __disable_interrupt() #define portENABLE_INTERRUPTS() __enable_interrupt() /* Critical section handling. #define portMAX_DELAY ( portTickType ) 0xffffffff #endif /*-----------------------------------------------------------*/ /* Hardware specifics. All Rights Reserved. */ (1) #define portENTER_CRITICAL() do { \ (2) __disable_interrupt(). /*-----------------------------------------------------------*/ /* Task utilities.com/freertos #if( configUSE_16_BIT_TICKS == 1 ) typedef unsigned portSHORT portTickType. \ } while (0) #else #define portISR_EXIT() do { \ (15) --ulInterruptNesting.org™ www. LLC. 11 of 32 . */ #define portEND_SWITCHING_ISR(xSwitchRequired) \ if (xSwitchRequired) { \ Copyright © Quantum Leaps. (19) #define portNO_CRITICAL_NESTING ((unsigned portLONG)0) /* application-specific function to start interrupts. \ (10) ++ulCriticalNesting.state-machine. including the timer that generates the tick ISR */ (20) void vStartInterrupts(void). \ (16) --ulCriticalNesting. \ (14) vTaskSwitchContext(). \ (7) } else ((void)0) (8) #define portISR_ENTRY() do { \ (9) ++ulInterruptNesting.

state-machine.org WEB site. \ vTaskSwitchContext(). (The source code of FreeRTOS. (4) The macro portEXIT_CRITICAL() has been re-defined to perform all actions inline to eliminate the function call overhead from the original implementation. \ } \ else ((void)0) /*-----------------------------------------------------------*/ /* Compiler specifics */ #define inline /* Task function macros as described on the FreeRTOS.) (3) The global variable ulCriticalNesting is incremented to account for entering a critical section. (5) The global variable ulInterruptNesting is first decremented and then compared to the portNO_CRITICAL_NESTING constant. (9) The global variable ulInterruptNesting is incremented to account for entering an interrupt level. (10) The global variable ulCriticalNesting is incremented to account for entering a critical section already established automatically in hardware. as described in Section 3. (8) The macro portISR_ENTRY() has been introduced in this updated FreeRTOS.org port. when the code is compiled to ARM.QDK™ FreeRTOS. (1) The macro portENTER_CRITICAL() has been re-defined to perform all actions inline to eliminate the function call overhead from the original implementation. but avoids flushing the pipeline (5-stage pipeline in ARM9 devices) twice per each portENTER_CRITICAL() invocation. Only in this case the interrupts can be unlocked by means of the IAR intrinsic function __enable_interrupt().com/freertos extern void vTaskSwitchContext(void ). NOTE: Incrementing of ulCriticalNesting should only be done for processors that actually lock interrupts in hardware before entering an ISR. This slightly increases code size. */ #define portTASK_FUNCTION_PROTO( vFunction. (6) When ulInterruptNesting drops down to the portNO_CRITICAL_NESTING level it means that the last level of critical section nesting is being exited. 12 of 32 . LLC. (2) The IAR intrinsic function __disable_interrupt() expands inline to 3 ARM instructions.1. which expands inline to 3 ARM instructions.org™ www. ARM7/ARM9 cores do lock interrupts. All Rights Reserved.h header file located in the <FreeRTOS>\Source\portable\IAR\STR91x\ directory. The do { … } while(0) loop around the body of the macro is the standard way of syntactically-correct grouping instructions without creating the dangling-else problem.org and the QF component of QP are compiled to ARM for best performance. when the code is compiled to ARM. (7) Terminating the if branch with else ((void)0) is the standard way of syntactically-correct grouping instructions without creating the dangling-else problem. pvParameters ) \ void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction. Copyright © Quantum Leaps. pvParameters ) \ void vFunction( void * pvParameters ) #ifdef __cplusplus } #endif Listing 3 Updated portmacro.

In fact. the FreeRTOS. including the system clock tick. */ vPortStartFirstTask().4 Changes in the port. because they can be asynchronously modified inside ISRs. LLC. The following Listing 4 shows how the modified port. The vStartInterrupts() function is called from the modified port. to check if a higher-priority task was made ready-to-run and needs to preempt the interrupted task. This step is the exact reverse of step (2).1) depends whether preemptions are configured or not. NOTE: Decrementing of ulCriticalNesting should only be done for processors that actually unlock interrupts in hardware after exiting an ISR. (17-18) The global nesting levels are declared as external and volatile. 13 of 32 . This function replaces the private function prvSetupTimerInterrupt() defined in the original FreeRTOS. (14) When preemptions are configured.com/freertos (11) The behavior of the portISR_EXIT() macro (see Section 3. including the timer that generates the tick ISR. 3. (19) The constant portNO_CRITICAL_NESTING is defined for the port (typically zero). as the ISR return restores the CPU status before the interrupt. but the FreeRTOS. All Rights Reserved. */ vStartInterrupts(). Interrupts are disabled here already. It’s more convenient to define all ISRs consistently at the application level. This step is the exact reverse of step (9). This function is application-specific and cannot be defined at the port level (callback function). (20) The prototype of the new callback function vStartInterrupts() is declared.QDK™ FreeRTOS.c file are just simple consequence of the augmented interrupt handling policy described in Section 3.org context switch is not requested. } Copyright © Quantum Leaps. /* Start the first task.c file has been drastically simplified by removing system clock tick ISRs from the port level. portBASE_TYPE xPortStartScheduler( void ) { extern void vPortStartFirstTask ( void ).org™ www. the port.1. ARM7/ARM9 cores do unlock interrupts by restoring CPSR from SPSR. /* Start interrupts.state-machine. (13) The global variable ulCriticalNesting is decremented to account for exiting the critical section.c file calls the vStartInterrupts() function from xPortStartScheduler().c file to configure and start interrupts. only the nesting levels are decremented. including the system clock tick ISR.c File The changes required in port. /* Should not get here! */ return 0.org context switch is requested by calling vTaskSwitchContext().org port. (12) The global variable ulInterruptNesting is decremented to account for exiting an interrupt level. (15-16) When preemptions are not configured.

Copyright © Quantum Leaps. which was not working in the original demo. The ARM9_STR91X_IAR_light demo application is minimal and simply spawns three LED-flashing tasks.5 Demo Application for the Updated FreeRTOS.1 describes how to build and run the demo application. The most interesting modifications from the original demo include the augmented interrupt processing. as implemented in <FreeRTOS>\Demo\Common\Minimal\falsh. LLC. /* always inform FreeRTOS about entering an ISR */ TIM3->OC1R += BSP_TIM3_PERIOD . } portISR_EXIT(). TIM3->SR &= ~TIM_IT_OC1.c. 3. The application also shows how to crrect the LED interface for the STR912-SK board. /* set the output compare register */ /* clear interrupt source (Timer3) */ /* handle the FreeRTOS. Section 2. vTaskIncrementTick().1.QDK™ FreeRTOS. 14 of 32 .org port has been derived from the demo included in the standard FreeRTOS distribution for the STR91x processor. as described in Section 4.1.state-machine. All Rights Reserved.org Port The demo application for the updated FreeRTOS.org system clock tick */ /* always inform FreeRTOS about exiting an ISR */ NOTE: The ARM9_STR91X_IAR_light demo uses the modified FreeRTOSConfig.com/freertos Listing 4 Calling vStartInterrupts() from the updated port.h header file.c source file. The demo application is located in the directory <FreeRTOS>\Demo\ARM9_STR91X_IAR_light\.4.org™ www. The ARM9_STR91X_IAR_light demo also uses Timer3 as the source of the system clock tick interrupt. as shown below: __arm void TIM3_IRQHandler(void) { portISR_ENTRY().

org The QP port to FreeRTOS. which is <qp>\ports\arm\freertos\iar\ in case of this QDK.org for critical section mechanism. Therefore. In the QP port. LLC.org™ www.com/freertos 4 The QP Port to FreeRTOS.h header file in the QP port directory. Consequently. or zero to exclude the API function.h Header File As described in the FreeRTOS.org is configured to operate in preemptive mode. however. every FreeRTOS application customizes the FreeRTOS by means of the FreeRTOSConfig.h header files. (1) (2) (3) (4) (5) #define #define #define #define #define #define #define #define #define #define #define #define configUSE_PREEMPTION configUSE_IDLE_HOOK configUSE_TICK_HOOK configTICK_RATE_HZ configMAX_PRIORITIES configMINIMAL_STACK_SIZE configTOTAL_HEAP_SIZE configMAX_TASK_NAME_LEN configUSE_TRACE_FACILITY configUSE_16_BIT_TICKS configIDLE_SHOULD_YIELD configUSE_MUTEXES 1 1 0 ( ( ( ( ( 1 0 1 1 ( portTickType ) 100 ) ( unsigned portBASE_TYPE ) 64 ) ( unsigned portSHORT ) 64 ) ( size_t ) 32000 ) 16 ) /* Co-routine definitions.h header file.QDK™ FreeRTOS. */ #define #define #define #define #define #define #define #define INCLUDE_vTaskPrioritySet INCLUDE_uxTaskPriorityGet INCLUDE_vTaskDelete INCLUDE_vTaskCleanUpResources INCLUDE_vTaskSuspend INCLUDE_vTaskDelayUntil INCLUDE_vTaskDelay INCLUDE_xTaskGetCurrentTaskHandle 1 1 1 0 1 1 1 1 Listing 5 FreeRTOSConfig. The QP applications don’t provide their own FreeRTOSConfig. the FreeRTOSConfig. and queues. In this QDK FreeRTOS.h header file is located in the QP port directory. in case of the QP port.2 describes how to build QP libraries. because QP depends on FreeRTOS. some configuration information contained in the FreeRTOSConfig. (1) QP can work with either preemptive or cooperative kernel.h header file is required to build the QP components.org 08] (User Documentation/Configuration section). All Rights Reserved.h header file located in <qp>\ports\arm\freertos\iar\ directory. 15 of 32 . 4.1 The FreeRTOSConfig.org real-time kernel.h header file is typically located in the application directory.state-machine. */ #define configUSE_CO_ROUTINES #define configMAX_CO_ROUTINE_PRIORITIES 0 ( 2 ) /* Set the following definitions to 1 to include the API function.org online documentation [FreeRTOS. tasks. NOTE: To ensure consistency of configuration you need to rebuild the QP libraries after modifying the FreeRTOSConfig. using the modified FreeRTOS. Copyright © Quantum Leaps.org allows running QP on top of FreeRTOS.org port as described in Section 3. but rather must consistent with the configuration contained in the QP port directory. the FreeRTOSConfig. Section 2.

because all platform-specific elements are defined in terms of FreeRTOS. LLC..h NOTE: The standard exact-width integer types are closely related to the FreeRTOS. int16_t.g. it would be very convenient to define standard exact-width types in terms of portCHAR. However.1. and portLONG.org idle hook to implement software tracing (Q-SPY). so it’s not clear if they correspond to the standard types int8_t. but is not relevant for QP. NOTE: Porting of QF to third-party RTOS is explained in Chapter 9 of [PSiCC2]. (1) #define QF_EQUEUE_TYPE (2) #define QF_THREAD_TYPE /* FreeRTOS.h> header file. which supports priority sharing. #include <stdint.org. 4. The subsections following the listing explain how QF integrates with FreeRTOS.3 The qf_port.state-machine. This QF port is generic.com/freertos (2) QP uses the FreeRTOS.org documentation is not clear about the semantics of portCHAR.h> #include "qep. respectively.h Header File The only platform-specific aspect used inside the QEP event processor is exact-width integer types.h Header File The QF header file for the FreeRTOS port to STR91x with the IAR compiler is located in <qp>\ports\arm\freertos\iar\qf_port. because the modified FreeRTOS port leaves the system clock tick interrupt to be implemented at the application level (see Section 3).h.h header file to adapt it to a different CPU or compiler. (3) The time tick hook is not used.org data types portCHAR. The application then is responsible to place the QF_tick() call inside the system clock tick ISR (e.2 The qep_port. thus making the qep_port. This number can be reduced to save RAM.org port. 16 of 32 .org. Typically.QDK™ FreeRTOS. For pre-standard compilers (no standard <stdint. The IAR compiler is C99-compliant compiler and provides the standard <stdint. The complete qf_port.18. portSHORT. and portLONG (see Listing 3).h> file). the FreeRTOS. see Section ???). and portLONG. and int32_t.h" /* exact-width integers. (4) The system clock tick rate is only necessary to build FreeRTOS.1 */ /* QEP platform-independent public interface */ Listing 6 The mechanism of allocating and accessing data in ROM in qep_port. 4. portSHORT.h header file is shown in Listing 7. because each active object in QP assumes a unique priority level. WG14/N843 C99. portSHORT.org™ www. NOTE: You can reduce configMAX_PRIORITIES to save RAM. All Rights Reserved. 7.h header file adapt automatically to any FreeRTOS.org event queue and thread types */ xQueueHandle xTaskHandle /* The maximum number of active objects in the application */ Copyright © Quantum Leaps. (5) The number of FreeRTOS. you should not need to modify the qf_port.org priorities is configured to the maximum number of active objects supported in QP. This is an unusually high number of priorities for FreeRTOS.

h" "qmpool.state-machine.h" "qequeue.org message queue as event queue for active objects (accessed via xQueueHandle) and each active object executes in a separate FreeRTOS. LLC. as shown in Listing 7(6-8).3.org queue management */ /* QEP port /* FreeRTOS uses native QF memory-pool /* native QF event queue for deferring events /* QF platform-independent public interface */ */ */ */ /***************************************************************************** * interface used only inside QF.3. e_)) Listing 7 The qf_port.h" (7) #include "task. but not in applications */ /* native QF event pool operations */ (13) #define QF_EPOOL_TYPE_ QMPool #define QF_EPOOL_INIT_(p_. poolSto_.com/freertos #define QF_MAX_ACTIVE (3) /* #define QF_INT_KEY_TYPE */ (4) #define QF_INT_LOCK(dummy) (5) #define QF_INT_UNLOCK(dummy) (6) #include "FreeRTOS. The QF critical section is defined in terms of the FreeRTOS. as shown in Listing 7(9-12). e_) (QMPool_put(&(p_).3.h. 4. poolSto_.org task management */ /* FreeRTOS.org Include Files To compile QP.h. and the platform-independent QF interface. evtSize_) \ QMPool_init(&(p_). the qf_port. evtSize_) #define QF_EPOOL_EVENT_SIZE_(p_) ((p_). 17 of 32 .org master include file */ /* FreeRTOS.org critical section mechanism allows for nesting critical sections.h" (8) #include "queue. e_) ((e_) = (QEvent *)QMPool_get(&(p_))) #define QF_EPOOL_PUT_(p_.h. NOTE: The FreeRTOS.4 QP Include Files The qf_port.h header file must include the following FreeRTOS. Copyright © Quantum Leaps.org™ www. native QF memory pool.h" (9) (10) (11) (12) #include #include #include #include "qep_port. poolSize_. 4.org task (accessed via xTaskHandle).h header file includes the QEP port.org critical section.3 FreeRTOS. 4. All Rights Reserved.blockSize) #define QF_EPOOL_GET_(p_.h" "qf.h header file with the generic QF port to FreeRTOS. 4.1 The Active Object Event Queue and Thread As shown in Listing 7(1-2).3. which is defined in Listing 7(3-5). QF uses the FreeRTOS.h" 63 /* FreeRTOS critical section operations */ portENTER_CRITICAL() portEXIT_CRITICAL() /* FreeRTOS. and queue. task. raw event queue for deferring events.org.QDK™ FreeRTOS.2 The QF Critical Section The most important aspect of the port is the interrupt locking/unlocking policy (QF critical section). poolSize_.org include files: FreeRTOS.

. You place such code in the qf_port...... ...................*/ void QActive_start(QActive *me.......com/freertos 4... QEvent const *ie) { portBASE_TYPE err.. The QF port uses the native QF memory pool............ uint32_t qLen.......org does not provide a fast and deterministic memory pool for events.....*/ void QF_run(void) { vTaskStartScheduler()... require some glue-code to bolt the framework to the external RTOS.. as most QF ports to third-party RTOSs.............. QF_ACTIVE_DISPATCH_(&((QActive *)pvParameters)->super... 4.... #include "qf_pkg.c Source File The QF port to FreeRTOS................. return version.4 The qf_port. /* remove AO from the framework */ vTaskDelete(((QActive *)pvParameters)->thread)............ as shown in Listing 7(10.. uint8_t prio... All Rights Reserved.............5 Memory Pool FreeRTOS...................... LLC.............. /* create event queue */ 18 of 32 (13) (14) (15) Copyright © Quantum Leaps..org™ www.. QEvent const *qSto[].. QF_gc(e)........org.... /* delete FreeRTOS task */ (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) } /*............... /* enable thread-loop */ while (((QActive *)pvParameters)->running) { QEvent const *e = QActive_get_((QActive *)pvParameters).....org scheduler */ Q_ERROR()........... Q_REQUIRE((qSto == (QEvent const **)0) && (qLen > 0) && (stkSto == (void *)0) && (stkSize > 0))........org ports............org */ } /*...... /* start the FreeRTOS... You typically don’t need to change this file for different FreeRTOS............ 13).......................... uint32_t stkSize..*/ char const Q_ROM * Q_ROM_VAR QF_getPortVersion(void) { static const char Q_ROM Q_ROM_VAR version[] = "4.......3................QDK™ FreeRTOS......state-machine.*/ void QF_stop(void) { } /*...h" #include "qassert...........org scheduler should never return */ } /*............... /* check if the event is garbage. sizeof(QEvent*))........c source file......*/ void QF_init(void) { /* no special initialization required by FreeRTOS...........................h" Q_DEFINE_THIS_MODULE(qf_port) /* Global objects ----------------------------------------------------------*/ /*.... unsigned portBASE_TYPE freeRTOS_prio....01"....... void *stkSto.......... /* the FreeRTOS... which is located in <qp>\ports\arm\freertos\iar\src\........................ as shown in Listing 8... } /*.......... me->eQueue = xQueueCreate(qLen.....*/ static __arm void task_function(void *pvParameters) { /* FreeRTOS signature */ ((QActive *)pvParameters)->running = (uint8_t)1... e).......0......................... and collect it if so */ } QF_remove_((QActive *)pvParameters)..

..... QS_aoObj_.....org task created (23) (24) (25) (26) } /*.... /* task handle Q_ASSERT(err == pdPASS)....... /* execute initial transition QS_FLUSH(). if (e->dynamic_ != (uint8_t)0) { ++((QEvent *)e)->dynamic_.. /* save the QF priority QF_add_(me)......... /* the dynamic attribute of the event QS_EQC_(0).. /* make QF aware of this active object QF_ACTIVE_INIT_(&me->super.......... &e... /* the signal of the event QS_OBJ_(me)........ } else { /* must be ISR level */ portBASE_TYPE xHigherPriorityTaskWoken.. /* the task function (signed portCHAR *)"AO"............. /* the dynamic attribute of the event */ */ */ */ 19 of 32 QF_INT_UNLOCK_().. QF_INT_LOCK_KEY_ QF_INT_LOCK_()...........*/ void QActive_postFIFO(QActive *me............. /* FreeRTOS queue created me->prio = prio. /* timestamp QS_SIG_(e->sig).. /* this active object QS_U8_(e->dynamic_)................. /* stack me... Copyright © Quantum Leaps.com/freertos (16) (17) (18) (19) Q_ASSERT(me->eQueue != (xQueueHandle)0).......... LLC............ All Rights Reserved.....QDK™ FreeRTOS. /* the 'pvParameters' parameter freeRTOS_prio. QEvent const *e) { portBASE_TYPE err.. } QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_POST_FIFO.... (portTickType)0).. /* cleanup the queue */ } /*......... /* the name of the task (unsigned portSHORT)stkSize/sizeof(portSTACK_TYPE).... QF_INT_LOCK_KEY_ QF_INT_LOCK_().... } Q_ASSERT(err == pdPASS)... QS_aoObj_..... QEvent const *e) { portBASE_TYPE err..... /* timestamp QS_SIG_(e->sig)........ } QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_POST_LIFO.*/ void QActive_stop(QActive *me) { me->running = (uint8_t)0...... ie). /* FreeRTOS..org™ www. .. /* FreeRTOS task priority /* create the FreeRTOS... /* the signal of the event QS_OBJ_(me)....................... &xHigherPriorityTaskWoken)...... if (ulInterruptNesting == (unsigned portLONG)0) { /* task level? */ err = xQueueSendToBack(me->eQueue. /* number of free entries (unknown) QS_EQC_(0).......*/ void QActive_postLIFO(QActive *me.. &e. /* min number of free entries (unknown) QS_END_NOLOCK_() */ */ */ */ */ */ (27) (28) (29) (30) } /*.. /* this active object QS_U8_(e->dynamic_). /* stop the thread loop */ vQueueDelete(me->eQueue).... if (e->dynamic_ != (uint8_t)0) { ++((QEvent *)e)->dynamic_. me) QS_TIME_()....... me) QS_TIME_()...org task for the AO err = xTaskCreate(&task_function. /* FreeRTOS task priority &me->thread).state-machine.... (20) (21) */ */ */ */ /* flush the trace buffer to the host */ */ */ */ */ */ */ */ */ */ (22) freeRTOS_prio = tskIDLE_PRIORITY + me->prio. err = xQueueSendToBackFromISR(me->eQueue.

/* number of free entries (unknown) QS_END_() return e. (7) The event loop continues as long as the QActive.. (5) Under a traditional RTOS.. 20 of 32 */ */ */ */ */ QF_INT_UNLOCK_(). (4) The function QF_stop() stops the framework. .org. the function starts multitasking by the FreeRTOS call vTaskStartScheduler(). &e.*/ QEvent const *QActive_get_(QActive *me) { QEvent const *e. me) QS_TIME_().. /* wait indefinitely. which is always structured as an endless loop.... /* timestamp QS_SIG_(e->sig). QS_aoObj_..QDK™ FreeRTOS.. the active object is removed from the framework. } Listing 8 The qf_port. All Rights Reserved.c source file for the FreeRTOS. Copyright © Quantum Leaps. /* the dynamic attribute of the event QS_EQC_(0).. } else { /* must be ISR level */ portBASE_TYPE xHigherPriorityTaskWoken. &e....... In the case of QF port to FreeRTOS..org port. There is nothing you can do to stop FreeRTOS. (8-10) These are the three steps of the active object thread (waiting for an event. see Chapter 7 in [PSiCC2]).org port can be configured to execute tasks either in ARM (default) or THUMB.. if (ulInterruptNesting == (unsigned portLONG)0) { /* task level? */ err = xQueueSendToFront(me->eQueue....org... } Q_ASSERT(err == pdPASS)....... In the case of QF port to FreeRTOS.....org. /* this active object QS_U8_(e->dynamic_). all active object threads execute the same function task_function().. (1) The function QF_init() initializes the framework. &xHigherPriorityTaskWoken). /* the signal of this event QS_OBJ_(me).. The parameter pvParameters is set to the active object owning in the task. and recycling the event... The __arm keyword in front of the task function means that QF port assumes that all FreeRTOS.. INCLUDE_vTaskSuspend must be set to '1' */ (31) Q_ALLEGE(xQueueReceive(me->eQueue... portMAX_DELAY) == pdPASS).. QS_EQC_(0).. LLC.. dispatching the event.. the function has nothing to do.. QS_BEGIN_(QS_QF_ACTIVE_GET.... you simply abort.state-machine. (6) The task function sets the QActive.org.running flag is set. err = xQueueSendToFrontFromISR(me->eQueue... (portTickType)0)..org tasks will be executed in the ARM state.... (11) After the event loop terminates... QS_END_NOLOCK_() /* number of free entries (unknown) */ /* min number of free entries (unknown) */ } /*.. The task function has the exact signature expected by FreeRTOS.... NOTE: The original FreeRTOS.....running flag to continue the local event loop. (2-3) The function QF_run() transfers control to the framework to run the application........com/freertos QS_EQC_(0)... &e.org™ www. Therefore the only action is to call the cleanup callback..

org (see also Chapter 8 in [PSiCC2]). This happens to be very similar priority numbering as used in the QF framework. The rest of the qf_port.org allocates the storage internally. FreeRTOS.org does not use the native QF active object queues. FreeRTOS.c source file defines these three functions for FreeRTOS. The QF priority is mapped to the µC/OS-II task priority.com/freertos (12) The task is deleted by the FreeRTOS. and QActive_get_() must be replaced by the FreeRTOS-specific code. so the parameter ‘stkSto’ is not used. otherwise the application cannot continue. (23) Clearing the QActive. NOTE: Traditional RTOSs. the QF implementation of QActive_postFIFO(). (22) The task creation must be successful. Therefore. require per-task stacks. The size of the size is provided in the ‘stkSize’ parameter. Therefore the function QActive_postFIFO() must distinguish between these two contexts to use the correct FreeRTOS. This must happen exactly as shown. (27) The choice of the right FreeRTOS. The active object is registered with the QF framework.org call vTaskDelete(). but FreeRTOS allocates the stack storage internally. otherwise the application cannot continue. otherwise it is the ISR level). (21) The active object thread is created by the FreeRTOS. (15) The first step in starting an active object is creating the event queue by the FreeRTOS.org call xTaskCreate(). (13-14) The assertions makes sure that neither event queue storage nor the stack storage are provided by the caller. without exceptions.org requires using different APIs when accessing a queue from an ISR or from a task. (24) The event queue is deleted by the FreeRTOS. because FreeRTOS. All Rights Reserved. such as FreeRTOS.org uses a priority numbering scheme in which tskIDLE_PRIORITY represents the lowest possible priority assigned to the idle task.org.org call xQueueCreate(). (25-26) Posting an event to a queue must always increment the reference counter of a dynamic event.state-machine.1.org™ www.running flag terminates the event loop and exits the active object thread (see line (6)).org API to post an event to the queue depends on the context (interrupt nesting of zero indicates task level.org call vQueueDelete(). 21 of 32 . The active object’s state machine is initialized. This determination is based on the ulInterruptNesting variable introduced in the augmented FreeRTOS.org port (again see Section 3.org API. As described in Section 3. The QF port to FreeRTOS. (16) (17) (18) (19) (20) The queue creation must be successful.1) NOTE: The variable ulInterruptNesting will distinguish correctly between the ISR and the task contexts only when all ISRs. The active object’s priority is set. LLC. and higher numerical values represent higher task urgency. QActive_postLIFO().QDK™ FreeRTOS. Copyright © Quantum Leaps. consistently call the macros portISR_ENTRY() upon entry and portISR_EXIT() upon the exit.

LLC. the higher code density of the THUMB instruction set often makes it actually execute faster. most of the QF modules as well as FreeRTOS modules are compiled to ARM. (29) In the ISR level. 4. the pointer to the event is posted to the FreeRTOS. On the other hand.org call xQueueReceive(). which uses the standard FIFO policy.org message queue with the call xQueueSendToBack(). the pointer to the event is posted to the FreeRTOS. which uses the standard FIFO policy. Generally.state-machine. NOTE: The QP libraries as well as application code must be compiled with the ARM/THUMB interworking enabled (IAR option –-interwork). and consequently all state machines in the system (active objects) should be compiled to THUMB. whereas timeout of portMAX_DELAY indicates indefinite waiting on an empty event queue. The queue is not supposed to block if it cannot accept the message (event pointer). All Rights Reserved. code that must often lock/unlock interrupts.C files) that comprise the QP libraries (linked later statically with the applications) can be compiled either to ARM or THUMB.QDK™ FreeRTOS. 22 of 32 . Therefore. Copyright © Quantum Leaps.5 ARM/THUMB Compilation Contrary to some misconceptions THUMB code is not inherently slower than ARM. (31) The event is retrieved from the message queue with the FreeRTOS.org™ www. To the contrary. or the code that can be executed in the ISR context (both requires ARM instruction set) is certainly faster if compiled to ARM. the QEP event processor. The second argument to this function is the timeout. (30) The assertion makes sure that the event is posted successfully.com/freertos (28) In the task level. Most QP source files (.org message queue with the call xQueueSendToBackFromISR(). The Q_ALLEGE() macro surrounding the FreeRTOS call asserts that the receive operation executed successfully.

....... 23 of 32 .h" "bsp. (uint8_t)(n + 1)... /* storage for the small event pool */ /*.. 5..... Copyright © Quantum Leaps... sizeof(l_smlPoolSto[0])). (QEvent *)0)..... QF_init(). (configMINIMAL_STACK_SIZE * sizeof(portSTACK_TYPE)). ++n) { /* start the active objects.. The function has the very standard structure for any QP application..com/freertos 5 The Example QP Application The QP port to FreeRTOS. (QEvent *)0)......org has been tested with the Dining Philosopher Problem (DPP) application described in the Application Note “Dining Philosophers Application” [QL AN-DPP 08]. N_PHILO...QDK™ FreeRTOS. BSP_init().... The standard DPP application has been augmented to demonstrate an independent FreeRTOS.state-machine. } QActive_start(AO_Table. (configMINIMAL_STACK_SIZE * sizeof(portSTACK_TYPE))..h" "freertos_task... /* instantiate all Philosopher active objects */ /* instantiate the Table active object */ /* initialize the Board Support Package */ /* initialize the framework and the underlying RT kernel */ /* object dictionaries..org is shown in Listing 9... */ QS_OBJ_DICTIONARY(l_smlPoolSto).org™ www... (void *)0. not managed by QP */ xTaskCreate(&vTaskFunction. */ QF_poolInit(l_smlPoolSto. (uint8_t)(N_PHILO + 1)...h task function */ /* Local-scope objects -----------------------------------------------------*/ static QSubscrList l_subscrSto[MAX_PUB_SIG]. The QP example is located in the directory <qp>\examples\arm\freertos\iar\dpp-str92-sk\.... for (n = 0..... Q_DIM(l_subscrSto)). N_PHILO.... LLC. Philo_ctor().h" /* the prototype of the FreeRTOS.org task executing outside of the QP framework.. as described in Chapter 1 of [PSiCC2] and also in the online “QP Tutorial” [QP/C 08]...... TableEvt te... /* create a raw FreeRTOS task... (QEvent const **)0. static union SmallEvent { void *min_size... n < N_PHILO..h" "dpp. /* init publish-subscribe */ /* initialize event pools. All Rights Reserved.. Table_ctor(). (void *)0. #include #include #include #include "qp_port.. /* other event types to go into this pool */ } l_smlPoolSto[2*N_PHILO]..1 The main() Function The main() function of the DPP example for FreeRTOS.. sizeof(l_smlPoolSto)....*/ __arm void main(void) { uint8_t n... */ QActive_start(AO_Philo[n].. QF_psInit(l_subscrSto. (signed portCHAR *)"TASK"... (QEvent const **)0...

This particular BSP uses the Output Compare interrupt of Timer 3 as the source for the system clock tick ISR. portISR_EXIT(). QF_run(). which allow extending the 16-bit free-running Timer 3 to 32-bits to accurately time stamp the trace records. Copyright © Quantum Leaps.1. Also.2 ISRs The ISRs in the DPP application for FreeRTOS. (6) The system clock tick ISR must invoke the FreeRTOS. /* set the output compare register */ /* clear interrupt source (Timer3) */ (5) #ifdef Q_SPY { uint16_t currTime16 = (uint16_t)TIM3->CNTR. (1) In the FreeRTOS.org task. the ISR updates the internal counters. LLC. } Listing 9 The main() function of the DPP application with FreeRTOS.org vTaskIncrementTick() function to manage timeouts and time delays. (2) As described in Section 3.QDK™ FreeRTOS.org system clock tick */ /* handle the QF system clock tick */ /* always inform FreeRTOS about exiting an ISR */ Listing 10 System time tick interrupt (Timer 3). tskIDLE_PRIORITY + N_PHILO + 2. because ISRs are actually called from an assembler wrapper interrupt handler linked to the address 0x18.1. /* run the QF application (never returns) */ 5. every ISR must start with calling the macro portISR_ENTRY(). l_currTime32 += (currTime16 . l_prevTime16 = currTime16. /* always inform FreeRTOS about entering an ISR */ (3) (4) TIM3->OC1R += BSP_TIM3_PERIOD . TIM3->SR &= ~TIM_IT_OC1.c) and are structured as described in Section 3. (3) The Output Compare register must be incremented to ensure that the free-running timer will reach the next deadline in the desired time. } #endif (6) (7) (8) } vTaskIncrementTick().org allocates this storage internally. you don’t need to allocate storage for event queues and stacks of active object tasks.org are located in the Board Support Package (file bsp.org task shown in bold in Listing 9.org port. 24 of 32 .l_prevTime16) & 0xFFFF. /* handle the FreeRTOS.1.state-machine. QF_tick(). /* ISRs --------------------------------------------------------------------*/ (1) __arm void TIM3_IRQHandler(void) { (2) portISR_ENTRY(). (xTaskHandle *)0). (void *)0. (4) The interrupt source (Timer 3 output compare) is then cleared. because FreeRTOS. The only significant differences from the main() function without FreeRTOS.org is creating the raw FreeRTOS. ISRs are regular C functions (no __irq functions). All Rights Reserved.com/freertos configMINIMAL_STACK_SIZE. (5) When the QS software tracing is active.org™ www.

In this BSP only the timer tick interrupt is started. /* called with interrupts locked */ SCU_APBPeriphClockConfig(__TIM23. (8) As described in Section 3. void vApplicationIdleHook(void) { (1) (2) (3) (4) portDISABLE_INTERRUPTS(). LED_OFF(16).state-machine.1. ENABLE). just before starting the idle task.com/freertos (7) The system clock tick ISR must also invoke QF_tick() to manage all armed time events (timers) in the QP application.TIM_Pulse_Length_1 TIM_Init(TIM3.TIM_Clock_Source TIM_InitStruct. &TIM_InitStruct). when the device is placed in one of these modes. . All Rights Reserved. including the system clock tick interrupt.1. The vStartInterrupts() function is designed to start the interrupts. 5. 25 of 32 Copyright © Quantum Leaps. The callback can also be used to place the MCU in a lowpower sleep mode to conserve power. portENABLE_INTERRUPTS(). TIM_DeInit(TIM3).org port calls the function vStartInterrupts().org™ www. void vStartInterrupts(void) { TIM_InitTypeDef TIM_InitStruct. NOTE: The STR912F device used in the STR912-SK board supports the Idle and Stop lowpower modes. TIM_IT_OC1..TIM_Prescaler TIM_InitStruct. However.TIM_Pulse_Level_1 TIM_InitStruct.TIM_Clock_Edge TIM_InitStruct. In the DPP application. TIM_InitStruct. TIM_START). BSP_TICK_PRIO).4. TIM_CounterCmd(TIM3.1. TIM_StructInit(&TIM_InitStruct).TIM_OC1_Modes TIM_InitStruct.4 Idle Processing in vApplicationIdleHook() FreeRTOS.QDK™ FreeRTOS. TIM_CounterCmd(TIM3. BSP_TIM3_PRESCALER . VIC_IRQ.TIM_Mode TIM_InitStruct. ENABLE). TIM_TIMING. LED_ON(16). TIM_CLK_EDGE_RISING. the augmented FreeRTOS. every ISR must end with calling the macro portISR_EXIT(). TIM_ITConfig(TIM3. VIC_ITCmd(TIM3_ITLine. TIM_CLEAR). TIM_CLK_APB. } 5. LLC.org allows to add idle processing to the application through the hook (callback) function vApplicationIdleHook(). = = = = = = = TIM_OCM_CHANNEL_1. the idle hook is used to output the software trace data to the host (see the next section).3 Starting Interrupts in vStartInterrupts() As described in Section 3. TIM_HIGH. Therefore the transition low-power mode is commented out in the vApplicationIdleHook() callback. BSP_TIM3_PERIOD . ENABLE). /* configure the VIC for the TIM3 interrupt */ VIC_Config(TIM3_ITLine. the JTAG debugger stops working and it’s extremely difficult to get control of the device again.

Generally. it's difficult to // get control of the MCU again!!! #endif } Listing 11 vApplicationIdleHook() in the file bsp. (5) The idle hook performs QS data ouptu to the host (see the next section). as described above.. int line) { __disable_interrupt().c (1-4) In order to “see” the activity of the idle task.com/freertos (5) #ifdef Q_SPY /* use the idle cycles for QS transmission if ((UART0->FR & 0x80) != 0) { /* TX FIFO empty? uint16_t nBytes = BSP_UART_TX_FIFO. /* stick the byte to the TX FIFO } } #elif defined NDEBUG /* only if not debugging (Release configuraion) /* shut down unused peripherals to save power . /* make sure that all interrupts are disabled */ LED_ON_ALL().. QF_INT_LOCK(dummy). all QP components use internally assertions to detect errors in the way application is using the QP services. It is also a good idea to log some information as to where the assertion failed.org™ www. These operations occur inside a critical section so that the intensity of the LED accounts only for the frequency of the calls to the idle hook.*/ (6) // SCU_EnterIdleMode(). 26 of 32 . LLC. /* light up all LEDs */ for (.c file. The following code fragment shows the Q_onAssert() callback in the bsp. you would put the system in fail-safe state and try to reset.5 Assertion Handling Policy in Q_onAssert() As described in Chapter 6 of [PSiCC2]. You need to define how the application reacts in case of assertion failure by providing the callback function Q_onAssert(). the idle hook turns LED 16 on and off. but probably is not adequate for the final production release.. but not to preemptions by ISRs and tasks. /* Power-Management: disable the CPU clock // NOTE: idle or sleep mode hangs the J-TAG. The function simply locks all interrupts and enters a for-ever loop. This policy is only adequate for testing. All Rights Reserved. Q_onAssert() should try to put the device in a fail-safe state. Copyright © Quantum Leaps. the idle mode interferes with the J-TAG debugger and that’s why it is commented out.!= 0) { UART0->DR = *block++. */ */ */ */ */ */ */ 5. block = QS_getBlock(&nBytes).) { /* hang here in the for-ever loop */ } } NOTE: You must carefully design the appropriate course of action in Q_onAssert() for your final production release. However. while (nBytes-. __arm void Q_onAssert(char const Q_ROM * const Q_ROM_VAR file.QDK™ FreeRTOS. /* get the data block to transfer QF_INT_UNLOCK(dummy).state-machine. (6) The ST driver function SCU_EnterIdleMode() puts the MCU in the low-power idle mode. /* capacity of the TX FIFO uint8_t const *block. Typically.

which are all summarized in Listing 12 (file bsp.UART_BaudRate = BSP_QS_BAUD_RATE.QDK™ FreeRTOS.. GPIO_InitStruct.. 27 of 32 (13) Copyright © Quantum Leaps. */ GPIO_DeInit(GPIO3). /* buffer for Quantum Spy */ GPIO_InitTypeDef GPIO_InitStruct. sophisticated runtime filtering of events. SCU_APBPeriphReset(__GPIO3.. /* configure UART0. LLC. UART_InitStruct. GPIO_InitStruct. ENABLE). . ENABLE). /* force UART0 registers to reset values */ UART_InitStruct. UART_InitTypeDef UART_InitStruct. GPIO_InitStruct. the kernel. and your application code. #endif /* application-specific trace records */ /*--------------------------------------------------------------------------*/ #ifdef Q_SPY (5) uint8_t QS_onStartup(void const *arg) { (6) static uint8_t qsBuf[BSP_QS_BUF_SIZE].UART_WordLength = UART_WordLength_8D. The complete implementation of the QS software-tracing output consists of several steps. DISABLE).. UART_InitStruct. DISABLE).4 . UART_InitStruct. (3) static uint16_t l_prevTime16. QS allows you to gain unprecedented visibility into your application by selectively logging almost all interesting events occurring within state machines. (7) (8) (9) (10) (11) (12) QS_initBuf(qsBuf.GPIO_IPConnected = GPIO_IPConnected_Disable. (4) enum AppRecords { PHILO_STAT = QS_USER }.UART_StopBits = UART_StopBits_1. /* enable clock for UART0 */ SCU_APBPeriphClockConfig(__GPIO3.GPIO_Direction = GPIO_PinOutput.UART_HardwareFlowControl = UART_HardwareFlowControl_None.. so the QSPY host application can conveniently receive the trace data on the host PC. QS can be configured to send the real-time data out of the serial port of the target device. On the STR912F MCU. &GPIO_InitStruct). */ UART_DeInit(UART0). /* enable clock for GPIO3 */ SCU_APBPeriphReset(__UART0. /* remove UART0 from reset */ /* remove GPIO3 from reset */ /* configure UART0_TX pin GPIO3. sizeof(qsBuf)). QS software tracing is minimally intrusive. (1) #ifdef Q_SPY (2) static uint32_t l_currTime32.GPIO_Pin = GPIO_Pin_4. the QS instrumentation is inactive and does not add any overhead to your application.com/freertos 6 The Quantum Spy (QS) Instrumentation This QDK demonstrates how to use the Quantum Spy (QS) to generate real-time trace of a running QP application. the framework.UART_Parity = UART_Parity_No. All Rights Reserved.GPIO_Alternate = GPIO_OutputAlt3. GPIO_Init(GPIO3. QS uses the built-in USART0 to send the trace data out (see Figure 1).. /* configure the UART0 for QSPY output .org™ www. Normally. but you can turn the instrumentation on by defining the Q_SPY macro and recompiling the code. Quantum Spy (QS) is a software tracing facility built into all QP components and also available to the Application code. UART_InitStruct. GPIO_InitStruct.state-machine.GPIO_Type = GPIO_Type_PushPull. */ SCU_APBPeriphClockConfig(__UART0. offers precise timestamping. GPIO_InitStruct.c). and good data compression (see Chapter 11 in PSiCC2 [PSiCC2]).

....QDK™ FreeRTOS............ UART_InitStruct.!= 0) { UART0->DR = *block++.... the clock to the GPIO3 peripheral is enabled....org™ www.... return l_currTime32......... /* enable UART0 */ (14) QS_FILTER_ON(QS_ALL_RECORDS)......... /* setup the QS filters. while ((block = QS_getBlock(&nBytes)) != (uint8_t *)0) { while ((UART0->FR & 0x80) == 0) { /* TX FIFO not empty? */ } /* keep waiting.. UART_Init(UART0... (5) You need to define the QS_onStartup() callback to initialize the QS software tracing.*/ void QS_onCleanup(void) { } /*.... to demonstrate how to use them........ GPIO3 controls the UART0 transmit and receive pins..........l_prevTime16) & 0xFFFF.... (1) The QS instrumentation is enabled only when the macro Q_SPY is defined (2) The static l_currTime32 variable is used to hold the 32-bit-wide timestamp....... /* for the next time around */ } } #endif /* Q_SPY */ /*--------------------------------------------------------------------------*/ Listing 12 QS implementation to send data out of the UART0 of the STR912 device. (10-11) The UART0 and GPIO3 peripherals are removed from reset....UART_Mode = UART_Mode_Tx..UART_TxFIFOLevel = UART_FIFOLevel_1_8...*/ /* NOTE: getTime is invoked within a critical section (inetrrupts disabled) */ uint32_t QS_onGetTime(void) { uint16_t currTime16 = (uint16_t)TIM3->CNTR.......)... (4) This enumeration defines application-specific QS trace record(s). ENABLE)......... */ (15) (16) (17) (18) (19) (20) (21) (22) (23) (24) (25) return (uint8_t)1... UART_InitStruct...... Also..state-machine.. UART_InitStruct................ .... All Rights Reserved................ (8-9) The clock to the UART0 peripheral is enabled. Copyright © Quantum Leaps.....UART_FIFO = UART_FIFO_Enable...... /* indicate successfull QS initialization */ } /*..... } /*...*/ void QS_onFlush(void) { uint16_t nBytes = BSP_UART_TX_FIFO...... (3) The static l_prevTime16 variable is used to hold the last 16-bit-wide reading of the free-running 16-bit Timer 3 (the same used to generate the system clock tick interrupt)... LLC.... &UART_InitStruct)....com/freertos UART_InitStruct...................UART_RxFIFOLevel = UART_FIFOLevel_1_8... (6) You should adjust the QS buffer size (in bytes) to your particular application (7) You always need to call QS_initBuf() from QS_onStartup() to initialize the trace buffer.... */ while (nBytes-....... 28 of 32 ......... QS_FILTER_OFF(... /* initialize UART0 */ UART_Cmd(UART0...... l_currTime32 += (currTime16 .. /* the capacity of the UART TX FIFO */ uint8_t const *block.......... l_prevTime16 = currTime16......... /* stick the byte to the TX FIFO */ } nBytes = BSP_UART_TX_FIFO...

org™ www. (17-21) The QS_onGetTime() callback provides a fine-granularity timestamp. which is the same timer already used for generation of the system clock-tick interrupt. It is only used in the initialization phase for sending the QS dictionary records to the host. The drawing below shows a free running Timer 3 Count Register (TIM3->CNTR) that counts up from 0 to 0xFFFF and rolls over to 0. as shown in Listing 10(5). The timestamp is discussed in the next section. To provide such a fine-granularity time stamp. the BSP uses the free running Timer 3. (23) The implementation of QS for STR912 uses the block-oriented QS-buffer interface QS_getBlock(). (16) The QS_onCleanup() callback is empty for MSP430 (the application never exits). Because of unsigned 16-bit arithmetic used in Listing 12(19). If the system tick rate is faster than the rollover rate then you could ‘oversample’ this free-running timer by reading it in the clock tick ISR. (14) The QS filters are setup (see Chapter 11 in [PSiCC2] as well as “QP Reference Manual” online).1 QS Time Stamp Callback QS_onGetTime() The platform-specific QS port must provide function QS_onGetTime() (Listing 12(17-21)) that returns the current time stamp in 32-bit resolution. even a ‘small’ current value minus a ‘large’ previous value still results in the proper delta. also needs to update l_currTime32 before it returns the current value. 6.4 is configured as output. The 32-bit variable l_currTime32 contains the sum of the 16-bit deltas from each readout of the free running Timer 3 Count Register. (25) The data byte is inserted into the UART0 data register. 29 of 32 .QDK™ FreeRTOS. Typically. Figure 6 shows how the Timer 3 Count Register (TIM3->CNTR) reading is extended to 32 bits. Copyright © Quantum Leaps. (13) The UART0 is not properly configured using the ST driver library interface. (15) The QS_onStartup() callback returns 1.state-machine.com/freertos (12) The transmit pin GPIO3. which provides up to 16 bytes to fill the FIFO of the UART (see Chapter 11 in [PSiCC2]). NOTE: The QS_onGetTime() callback is always called with interrupts locked. meaning that the QS initialization was successful. (24) The QS_onFlush() callback busy-waits in-line until the transmit buffer is empty. Note that QS_onGetTime() can actually be called at just about any time and thus. LLC. All Rights Reserved. the function busywaits for the transfer to complete. (22) The QS_onFlush() callback flushes the QS trace buffer to the host. alternative function 3 (UART0 Tx) using the ST driver library interface.

2 Invoking the QSpy Host Application The QSPY host application receives the QS trace data. All Rights Reserved. 30 of 32 . 6. LLC.QDK™ FreeRTOS.org™ www.state-machine. you invoke the QSPY host application as follows (please refer to the QSPY section in the “QP Reference Manual”): qspy –c COM1 –b 115200 Copyright © Quantum Leaps.com/freertos count 32-bit time stamp returned from QS_onGetTime() System clock tick period TIM3->CNTR Register 0xFFFF 0x0000 System clock-tick time Figure 6 Using the Timer 3 Count Register to provide 32-bit QS time stamp. parses it and displays on the host workstation (currently Windows or Linux). For the configuration options chosen in this port.

com. Newnes.quantum-leaps. LLC.pdf http://www.htm http://www.org™ www. LLC. Quantum Leaps. 2008 [QP/C 08] “QP/C Reference Manual”. April 2008 “ARM IAR C/C++ Guide”.com/freertos 7 Related Documents and References Document [Samek 08] “Practical UML Statecharts in C/C++. Miro Samek. LLC.com/stonline/products/literature/rm/13742.com/doc/AN_QP_Directory_Structure.org 08] FreeRTOS online documentation. 2007 [QL AN-DPP 08] “Application Note: Dining Philosophers Application”. Quantum Leaps.com/writings/psicc2.pdf The PDF version of this document is included in the IAR Embedded Workbench for ARM. All Rights Reserved. such as amazon.org/ http://www.pdf www.freertos. Quantum Leaps. 2008 [QL AN-Directory 07] “Application Note: QP Directory Structure”.quantumleaps. 2008 [FeeRTOS.quantumleaps. See also: http://www. 2008 “STR91xFA ARM9®-based microcontroller family”.state-machine. ST Microelectronics. Second Edition: Event Driven Programming for Embedded Systems”. 31 of 32 .st. [QP/C++ 08] “QP/C++ Reference Manual”. Copyright © Quantum Leaps. Quantum Leaps.com/doxygen/qpcpp/ http://www.quantum-leaps.QDK™ FreeRTOS. LLC. LLC.com/doxygen/qpc/ http://www.com/doc/AN_DPP.quantum-leaps. IAR Systems Compiler: Reference Location Available from most online book retailers.

by Miro Samek.ARM.FreeRTOS. USA only) +1 919 869-2998 (FAX) e-mail: info@quantum-leaps. LLC 103 Cobble Ridge Drive Chapel Hill. 110 Fulbourn Road Cambridge CB1 9NJ England Tel: (44) 01223 400400 Fax: (44) 01223 400410 WEB : www.com/freertos 8 Contact Information Quantum Leaps.state-machine.state-machine.org WEB : www. Second Edition: Event Driven Programming for Embedded Systems”. All Rights Reserved.com “Practical UML Statecharts in C/C++.org ARM Ltd.com Copyright © Quantum Leaps.org™ www. 32 of 32 .com http://www. 2008 FreeRTOS.quantum-leaps. NC 27516 USA +1 866 450 LEAP (toll free.QDK™ FreeRTOS.com WEB : http://www. Newnes. LLC.

You're Reading a Free Preview

Download
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->