Sunteți pe pagina 1din 19


Empowering Embedded Systems

for the NXP LPC2106 CPU
(Using the IAR LPC2106-SK Evaluation Board)

Application Note

C/OS-II and C/OS-View for the NXP LPC2106 CPU

Table Of Contents
1.00 1.01 1.02 2.00 2.01 2.02 3.00 3.01 3.02 4.00 Licensing References Contacts Introduction Directories and Files IAR Embedded Workbench Example Code Example Code, app.c Example Code, os_cfg.h Board Support Package (BSP) IAR-Specific BSP Files BSP, bsp.c and bsp.h C/OS-View 3 4 6 8 9 12 13 13 14 16 19 19 19

C/OS-II and C/OS-View for the NXP LPC2106 CPU



This document shows example code for using C/OS-II and C/OS-View on a IAR LPC2106SK evaluation board, as shown in Figure 1, which employs NXPs ARM7TDMI-based LPC2106 microcontroller. This physically small but nevertheless flexible device provides support for external communications interfaces such as UART, SPI, and I2C. Its on-board peripherals include 2 32-bit timers and as many as 32 I/O ports. The processor has up to 128 kB of on-chip Flash memory and a 64 kB bank of RAM.

20-Pin J-Tag




LED1 - LED16

Push buttons

9-V DC Power

Figure 1-1, IAR LPC2106-SK board

C/OS-II and C/OS-View for the NXP LPC2106 CPU


Directories and Files

The code and documentation of the port are placed in directories in accordance with AN-2002, C/OS-II Directory Structure. The *.exe file that contains this document provides all of the files that are needed to run the example application described herein. As the previous section notes, this application features software components from Micrim, so the source files for C/OS-II are included in the zip file. Please note that these files, which are described below, are provided for evaluation purposes only. If you choose to use C/OS-II in a commercial product, you must contact Micrim to obtain the necessary licensing.

\Micrium\Software\uCOS-II\Source This directory contains the processor independent code for C/OS-II. The version used was 2.83. \Micrium\Software\uCOS-II\Ports\ARM\Generic\IAR This directory contains the standard processor-specific files for the generic C/OS-II ARM port assuming the IAR toolchain. These files could easily be modified to work with other toolchains (i.e. compiler/assembler/linker/locator/debugger); however, you would place the modified files in a different directory. Specifically, this directory contains the following files: os_cpu.h os_cpu_a.asm os_cpu_c.c os_dcc.c os_dbg.c is included to provide additional information to Kernel Aware debuggers like IARs C-Spy.

With this port, you can use C/OS-II in either ARM or Thumb mode. Thumb mode, which drastically reduces the size of the code, was used in this example, but compiler settings may be switched to generate ARM-mode code without needing to change either the port or the application code. The ARM/Thumb port is fully described in application note AN-1014 which is available from the Micrium web site.

\Micrium\Software\uCOSView\Source This directory contains the processor independent code for C/OS-View. The version used was 1.33. This directory contains the following files: os_view.c os_view.h

C/OS-II and C/OS-View for the NXP LPC2106 CPU

\Micrium\Software\uCOSView\Ports\ARM7\LPC2000\IAR This directory contains the LPC2000-specific port for C/OS-View: os_viewc.c os_viewc.h

Application Code:
\Micrium\Software\EvalBoards\NXP\LPC210x-KickStartCard\IAR\OS-View This directory contains the source code for the example application, composed of the following files: app.c contains the test code for the example application including the functions that start C/OS-II, register tasks with the operating system, and update the user interface (the LEDs and PBs). The initialization functions of supplementary installed module (C/OS-View) are called from this file as well. app_cfg.h is a configuration file specifying stack sizes and priorities for all tasks and #defines for important global application constants. includes.h is a master include file used by the application. os_cfg.h is the C/OS-II configuration file. LPC2106-OS-View.* are the IAR Embedded Workbench project files.

\Micrium\Software\EvalBoards\NXP\LPC210x-KickStartCard\IAR\BSP This directory contains the Board Support Package for the IAR LPC2106-SK board: bsp.c contains the board support package which initializes critical processor functions (e.g., the clock generation unit) and provides support for peripherals such as the LEDs on the board. bsp.h contains prototypes for functions that may be called by the user. lpc2106_ram.xcl is an IAR linker file which contains information about the placement of data and code segments in the processors memory map. The data, execution stacks, and code are all mapped to the internal RAM. lpc2106_cstartup.s79

\Micrium\Software\uC-CPU\ARM\IAR This directory contains processor-specific code intended to be used with the IAR compiler for ARM processors. cpu_def.h, which is located directly in \Micrium\Software\uC-CPU, declares #define constants for CPU alignment, endianness, and other generic declarations. cpu.h defines the Micrim portable data types for 8, 16, and 32-bit signed and unsigned numbers (such as CPU_INT16U, which is a 16-bit unsigned type). These allow code to be independent of processor and compiler word size definitions. cpu_a.s contains generic assembly code for ARM7 or ARM9 processors which is used to enable and disable interrupts within the operating system. This code is called from C with OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL().

C/OS-II and C/OS-View for the NXP LPC2106 CPU


IAR Embedded Workbench

We used the IAR Embedded Workbench (EW) V4.40a to test the example. Of course, C/OS-II can be used with other tools. We used the IAR Embedded Workbench (EW) V4.40a to test the example. Of course, C/OS-II can be used with other tools. To view the project you can either open the workspace file LPC2106-OS-View.eww (by left-clicking on the file) in the example project directory \Micrium\Software\EvalBoards\NXP\LPC210x-KickStartCard\OS-View or add the project file LPC2106-OS-View.ewp to a new workspace. To do the latter, open IAR EWARM and choose the Add Existing Project menu command under the Project menu. Figure 1-2 shows the project configuration tree in the EW.

Figure 1-2, IAR EW Project Configuration

The test code works either in ARM or Thumb mode. In fact, if you switch between ARM and Thumb Processor Mode in the settings dialog box (see Figure 1-3) and rebuild the project, your code should run just as well. By selecting Thumb and choosing to generate Interwork code, you can mix ARM and Thumb code in your application.

C/OS-II and C/OS-View for the NXP LPC2106 CPU

Figure 1-3, IAR EWARM Options

The IAR Embedded Workbench works with Micriums C/OS-II Kernel Awareness Plug-In which allows you to examine C/OS-II kernel objects in tabular format when running the IAR C-Spy debugger. Figure 1-4 shows all the tasks created in the example. For each task, you can see where the current stack pointer is pointing, how much stack space is being used, and other properties. The task names (which you may assign) are also listed. The Kernel Awareness Plug-In provides much other useful information about C/OS-II including lists of semaphores, mailboxes, queues, and timers.

Figure 1-4, C/OS-II Kernel Awareness in C-Spy, Task List

C/OS-II and C/OS-View for the NXP LPC2106 CPU


Example Code

The example application performs one primary interface function: manipulating the on/off status of the boards LEDs. When started, the LEDs will begin blinking in a repetitive sequence: a chain of 5 LEDs will loop around the row of 16 LEDs. Two push buttons, PB2 (labelled ISP/INT1) and PB4 (labelled INT2) control the rate at which the LEDs blink. Pressing PB2 will cause the delay between change in the LED status to be decremented by 5 ms; pressing PB2 will cause the delay to increment by 5 ms. The user interface components are located on the LPC2106-SK evalueation board in Figure 2-1. PB1:
Does Nothing

Does Nothing

PB2: LEDs:
Blink Decrements Delay Time

Increments Delay Time

Figure 2-1, User interface components

External Interrupt Configuration


LED Jumpers:
Connect to LEDs

Figure 2-2, Jumper settings

C/OS-II and C/OS-View for the NXP LPC2106 CPU


Example Code, app.c

A limited set of the LPC2106 capabilities are exhibited by the application code in app.c. A few tasks are created, one of which merely updates the LEDs on the board. However, the power and convenience of both C/OS-II Real-Time Kernel and the LPC2106 (in addition to the C/OS-II Kernel Awareness plug-in for C-Spy and C/OS-View) are amply demonstrated with this small application.

Listing 2-1, main()

void { main (void) CPU_INT08U err; /* (2) */ /* (3) */ /* (1) */

BSP_IntDisAll(); OSInit();

OSTaskCreateExt(AppTaskStart, /* (4) */ (void *)0, (OS_STK *)&AppTaskStartStk[APP_TASK_START_STK_SIZE - 1], APP_TASK_START_PRIO, APP_TASK_START_PRIO, (OS_STK *)&AppTaskStartStk[0], APP_TASK_START_STK_SIZE, (void *)0, OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); #if OS_TASK_NAME_SIZE > 13 OSTaskNameSet(APP_TASK_START_PRIO, "Start Task", &err); #endif OSStart(); } /* (5) */

/* (6) */

L2-1(1) L2-1(2)

As with most C applications, the code starts in main(). All interrupts are disabled to make sure the application does not get interrupted until it is fully initialized. As with all C/OS-II applications, OSInit() must be called before creating a task or any other kernel object. We then create at least one task (in this case, using OSTaskCreateExt() to obtain additional information about your task). C/OS-II creates either one or two internal tasks in OSInit(). C/OS-II always creates an idle task, OS_TaskIdle(), and will create a statistics task, OS_TaskStat() if you set OS_TASK_STAT_EN to 1 in OS_CFG. As of V2.6x, you can now name C/OS-II tasks (and other kernel objects) and display task names at run-time or with a debugger. In this case, we name our first task as well as the two internal C/OS-II tasks. Because C-Spy can work with the Kernel Awareness Plug-In available from Micrium, task names can be displayed during debugging.

L2-1(3) L2-1(4)


C/OS-II and C/OS-View for the NXP LPC2106 CPU


Finally, C/OS-II is started by calling OSStart(). C/OS-II will then begin executing AppTaskStart() since that is the highest priority task created (both OS_TaskStat() and OS_TaskIdle() have lower priorities).

Listing 2-2, AppTaskStart()

static void AppTaskStart (void *p_arg) { CPU_INT08U i; CPU_INT16U delay; CPU_INT08U *msg; CPU_INT08U value; (void)p_arg; BSP_Init(); #if OS_TASK_STAT_EN > 0 OSStatInit(); #endif #if OS_VIEW_MODULE > 0 OSView_Init(38400); OSView_TerminalRxSetCallback(AppTerminalRx); OSView_RxIntEn(); #endif AppTaskCreate(); EINT_Mbox = OSMboxCreate((void *)0); delay = 50; PB_EINT1_Init(EINT1_ISRHandler); PB_EINT2_Init(EINT2_ISRHandler); LED_On(13); LED_On(14); LED_On(15); LED_On(16); while (DEF_TRUE) { for (i = 1; i <= 16; i++) { LED_On(i); LED_Off(16 - (21 - i) % 16); msg = (CPU_INT08U *)OSMboxAccept(EINT_Mbox); if (msg != (CPU_INT08U *)0) { value = *msg; if (value == 1) { if (delay > 5) { delay -= 5; } } else { delay += 5; } } OSTimeDlyHMSM(0, 0, 0, delay); } } } /* (7) */ /* (8) */ /* (9) */ /* (1) */ /* (2) */

/* (3) */

/* (4) */ /* (5) */ /* (6) */


BSP_Init() initializes the Board Support Packagethe I/Os, the tick interrupt, etc. (See Section 3.0 for details.)


C/OS-II and C/OS-View for the NXP LPC2106 CPU


OSStatInit() is initializes C/OS-IIs statistic task. This only occurs if you enable the statistics task by setting OS_TASK_STAT_EN to 1 in OS_CFG.H. The statistics task measures overall CPU usage (expressed as a percentage) and also performs stack checking for all the tasks that have been created with OSTaskCreateExt() with the stack checking option set. OSView_Init() initializes the C/OS-View module, including the UART interface, for which reason the baud rate of the RS-232C port connected to the Windows view is specified as an argument. If you purchased C/OS-View, please enable it according to the instructions contained in Section 4.00. The sole additional application task, AppTaskUserIF(), is created. See Listing 24. A mailbox is setup to channel the communication between the External Interrupt ISR handlers and this task. An ISR will use this mechanism to inform the start task that the interface delay should change after PB2 or PB4 is pressed See Listing 2-4 and for further details. The LPC2106s relevant external interrupts are configured. Each is located on an separate interrupt vector number and, for simplicity, separate interrupt service routines are used. PB2 will decrease the interface delay (the delay between changes in the status of the LEDs). PB4 will increase the interface delay. See Listing 2-4 for more details about these functions. Any task managed by C/OS-II must either enter an infinite loop waiting for some event to occur or terminate itself. In an infinite loop, this task will loop a string of 5 consecutive LEDs around the strip of 16. The argument to LED_Off() may appear somewhat cryptic, but this is only an extension of the typical mechanism used to navigate a circular buffer. Before the task enters the infinite loop, the final 4 LEDs (LED13, LED14, LED15, and LED16) are turned on; upon entering the loop, the first LED (LED1) is turned on. This statement will, upon its first execution, turn off LED12; thereby maintaining 5 lit LEDs that will appear to progress across the row and loop around. For this situation, the appropriate LED to turn off will be 16 ((16 i) + 5) % 16 = 16 (21 i) % 16.


L2-2(4) L2-2(5)





The mailbox EINT_Mbox is checked for messages. The message should either be the integer 1 or the integer 2. The former will cause the delay to be decremented by 5 millisecods. The latter will cause the delay to be incremented by 5 milliseconds. If there is no message in the mailbox, then the delay does not change.


C/OS-II and C/OS-View for the NXP LPC2106 CPU

Listing 2-4, EINT1_ISRHandler(), EINT2_ISRHandler ()

static void EINT1_ISRHandler (void) { EINT_Char = 1; OSMboxPost(EINT_Mbox, &EINT_Char); EXTINT |= 0x07; VICVectAddr = 0; } static void EINT2_ISRHandler (void) { EINT_Char = 2; OSMboxPost(EINT_Mbox, &EINT_Char); EXTINT |= 0x07; VICVectAddr = 0; }

/* (1) */

/* (2) */

The BSP functions PB_EINT1_Init() and PB_EINT2_Init() are called from AppStartTask() to initialize the external interrupts on the LPC2106 processor which will be used for the push buttons. After this initialization, an interrupt will be generated whenever one of the push buttons is pressed, whereby the code in these functionsthe interrupt handler attached to the appropriate vectorwill be invoked. If PB2 or PB4 has been pressed, then AppStartTask() will change the delay value it uses. L2-4(1) L2-4(2) If PB2 has been pressed, then the integer 1 will be sent to the user interface task, causing the interface delay to be decreased by 5 milliseconds. If PB4 has been pressed, then the integer 2 will be sent to the user interface task, causing the interface delay to be increased by 5 milliseconds.


Example Code, os_cfg.h

This file is used to configure C/OS-II. Among the approximately 60 #defines in this file are included variables defining the maximum number of tasks that your application can have, which services will be enabled (semaphores, mailboxes, queues, etc.), and the size of the idle and statistic task. Each entry is commented and additional information about the purpose of each #define can be found in C/OS-II, the Real-Time Kernel by Jean Labrosse. os_cfg.h assumes you have C/OS-II V2.83 or higher.


C/OS-II and C/OS-View for the NXP LPC2106 CPU


Board Support Package (BSP)

The Board Support Package (BSP) provides functions to encapsulate common I/O access functions and make porting your application code easier. Essentially, these files are the interface between the application and the IAR LPC2106-SK board. Though one file, bsp.c, contains some functions which are intended to be called direcly by the user (all of which are prototyped in bsp.h), the other files serve the compiler (as with lpc2106_cstartup.s79).


IAR-Specific BSP Files

The BSP includes two files intended specifically for use with IAR tools: lpc2106_ram.xcl and lpc2106_cstartup.s79. These serve to define the memory map and initialize the processor prior to loading or executing code. If the example application is to be used with other toolchains, the services provided by these files must be replicated as appropriate. Before the processor memories can be programmed, the compiler must know where code and data should be placed. To accomplish this, IAR requires a linker command file, such as lpc2106_ram.xcl, that provides directives to accomplish this. All code, data segments, and stack and heap segments are placed in the in the 64 kB internal Flash between 0x40000000 and 0x4000FFFF, with the first 64 bytes of RAM reserved for the exception vector table. In lpc2106_cstartup.s79 is code which will be executed prior to calling main. One important inclusion is the specification of the exception vector table (as required for ARM cores) and the setup of various exception stacks. After executing, this function branches to the IARspecific ?main function, in which the processor is further readied for entering application code.


C/OS-II and C/OS-View for the NXP LPC2106 CPU


BSP, bsp.c and bsp.h

Though the BSP provided with the application code provides only the limited set of capabilities need for the example application to run, the amount of code exceeds what can be practically discussed in this format. Consequently, only the salient features of the BSP, including any remarkable features, problems, or solutions, will be discussed.

Listing 3-1, BSP_Init()

void { BSP_Init (void) MEMMAP = 2; OS_CPU_InitExceptVect(); BSP_PLL_Init(); BSP_IO_Init(); VIC_Init(); LED_Init(); Tmr_TickInit(); } /* (1) */ /* (2) */ /* (3) */ /* (4) */ /* (5) */

The function BSP_Init() should be called before any of the boards features are accessed (such as the LEDs); however, because C/OS-II s timer is initialized herein, this function should not be called until multitasking is started (i.e., OSStart() is called). L3-1(1) L3-1(2) L3-1(3) L3-1(4) The ARM exception vectors located in the bottom 64 bytes of memory are initialized. The processors PLL and clocks are initialized. The I/O ports used on the board (for the LEDs, the PBs, and the UART) are intiailized. The vectors in the Vectored Interrupt Controller (VIC) is initialized and the VIC is enabled. The C/OS-II tick interrupt source is then initialized. See Listing 3-2 for details.



C/OS-II and C/OS-View for the NXP LPC2106 CPU

Listing 3-2, Tmr_TickInit()

static void Tmr_TickInit (void) { CPU_INT32U peripheral_clk_freq;

VICIntSelect VICVectAddr2 VICVectCntl2 VICIntEnable

&= = = =

~(1 << VIC_TIMER0); (CPU_INT32U)Tmr_TickISR_Handler; 0x20 | VIC_TIMER0; (1 << VIC_TIMER0);

/* (1) */

peripheral_clk_freq = BSP_CPU_ClkFreqPeripheral(); T0TCR T0PC T0MR0 T0MCR T0CCR T0EMR T0TCR } = 0; = 0; = peripheral_clk_freq / OS_TICKS_PER_SEC; = 3; = 0; = 0; = 1;

/* (2) */

/* (3) */

L3-2(1) L3-2(2) L3-2(3)

The interrupt controller is setup to vector to Tmr_TickISR_Handler() when timer #0 issues an interrupt. The VIC vector #2 is used for the timer ISR. The peripheral clock frequency BSP_CPU_ClkFreqPeripheral(). is calculated using the function

The timer is set to generate an interrupt when TC equals MR0 and to automatically reset TC.


C/OS-II and C/OS-View for the NXP LPC2106 CPU



C/OS-View, a module that allows you to view useful statistics gathered from C/OS-II, can be readily added to the example application. After licensing C/OS-Views source files from Micrium and obtaining the modules Windows application, you can begin to use C/OS-View after completing a few simple operations. First, you will need to use a serial cable to connect the boards RS232 port (which is marked UART1) to an available serial port on your PC. Second, assign a value of 1 to the constant OS_VIEW_MODULE in os_cfg.h and reinclude C/OSViews source files and the LPC2106 port (as shown in Figure 4-1).

Right-click on the excluded group, and choose Options

Click the check box in the upper-left corner name Exclude from build

Figure 4-1, Re-including C/OS-View files in build


C/OS-II and C/OS-View for the NXP LPC2106 CPU

After making these preparations, build and run your application and start C/OS-Views Windows application. Through the Setup dialog box, specify the COM port on your computer to which the board is connected and a baud rate of 38400. When you have completed these initializations, the Windows application will begin receiving packets from the board, eventually resulting in a graph resembling that which is shown in Figure 4-2.

Figure 4-2, C/OS-View Windows Viewer

Note that you can disable C/OS-View by removing the C/OS-View files from the build and setting OS_VIEW_MODULE to 0 in os_cfg.h. You would need to do this is you didnt purchase C/OS-View from Micrim. C/OS-View is a combination of a Microsoft Windows application program and code that resides in your target system (in this case, the IAR LPC2106-SK Evaluation Board). The Windows application connects to your system via an RS-232C serial port. The status of the tasks which are managed by C/OS-II can be viewed with the Windows application. C/OS-View allows you to view the following information from a C/OS-II based product: The address of the TCB of each task (up to 63 tasks); The name of each task (up to 63 tasks); The status (e.g., ready, delayed, waiting on event) of each task; The number of ticks remaining for a timeout or if a task is delayed; The amount of stack space used and left for each task; 17

C/OS-II and C/OS-View for the NXP LPC2106 CPU

The percentage of CPU time each task relative to all the tasks; The number of times each task has been 'switched-in'; and The execution profile of each task. C/OS-View also allows you to send commands to your target and allow your target to reply back and display information in a 'terminal window'. C/OS-View is licensed on a per-developer basis. In other words, you are allowed to install C/OS-View on multiple PCs as long as the PC is used by the same developer. If multiple developers are using C/OS-View then each needs to obtain his own copy. Contact Micrim for pricing information.


C/OS-II and C/OS-View for the NXP LPC2106 CPU

C/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. If you plan on using C/OS-II in a commercial product you need to contact Micrim to properly license its use in your product. We provide ALL the source code with this application note for your convenience and to help you experience C/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a licensing fee. Please help us continue to provide the Embedded community with the finest software available. Your honesty is greatly appreciated.

C/OS-II, The Real-Time Kernel, 2nd Edition Jean J. Labrosse R&D Technical Books, 2002 ISBN 1-57820-103-9 Embedded Systems Building Blocks Jean J. Labrosse R&D Technical Books, 2000 ISBN 0-87930-604-1

IAR Systems Century Plaza 1065 E. Hillsdale Blvd Foster City, CA 94404 USA +1 650 287 4250 +1 650 287 4253 (FAX) e-mail: WEB : CMP Books, Inc. 1601 W. 23rd St., Suite 200 Lawrence, KS 66046-9950 USA +1 785 841 1631 +1 785 841 2624 (FAX) e-mail: WEB:

Micrim 949 Crestview Circle Weston, FL 33327 USA +1 954 217 2036 +1 954 217 2037 (FAX) e-mail: WEB:

NXP 1110 Ringwood Court San Jose, CA 95131 +1 408 474 8142 WEB: