Ocosii On Dspic
Ocosii On Dspic
Ocosii On Dspic
C/OS-II
and the
Microchip dsPIC33
Application Note
AN-1033
www.Micrium.com
Table of Contents
1.00 Introduction ............................................................................................................. 3 2.00 The Microchip dsPIC33 programmers model ......................................................... 4 3.00 C/OS-II Port for dsPIC33 ..................................................................................... 7 3.01 Directories and Files................................................................................................ 7 3.02 OS_CPU.H .............................................................................................................. 8 3.02.01 OS_CPU.H, macros for externals ..................................................................... 8 3.02.02 OS_CPU.H, Data Types..................................................................................... 8 3.02.03 OS_CPU.H, Critical Sections ............................................................................. 9 3.02.04 OS_CPU.H, Stack growth .................................................................................. 9 3.02.05 OS_CPU.H, Task Level Context Switch ............................................................. 9 3.02.06 OS_CPU.H, Function Prototypes ..................................................................... 10 3.03 OS_CPU_C.C ....................................................................................................... 10 3.03.01 OS_CPU_C.C, OSInitHookBegin()................................................................... 10 3.03.02 OS_CPU_C.C, OSInitHookEnd() ..................................................................... 11 3.03.03 OS_CPU_C.C, OSTaskCreateHook() .............................................................. 11 3.03.04 OS_CPU_C.C, OSTaskStkInit() ....................................................................... 12 3.03.05 OS_CPU_C.C, OSTaskSwHook().................................................................... 15 3.03.06 OS_CPU_C.C, OSTimeTickHook() .................................................................. 15 3.04 OS_CPU_A.S........................................................................................................ 16 3.04.01 OS_CPU_A.S, OSStartHighRdy() .................................................................... 16 3.04.02 OS_CPU_A.S, OSCtxSw() ............................................................................... 17 3.04.03 OS_CPU_A.S, OSIntCtxSw() ........................................................................... 18 3.04.04 OS_CPU_A.S, T2Interrupt() ............................................................................. 18 3.04.05 OS_CPU_A.S, T4Interrupt() ............................................................................. 19 3.05 OS_CPU_UTIL_A.S .............................................................................................. 20 3.06 OS_DBG.C............................................................................................................ 21 4.00 Interrupt Handling.................................................................................................. 22 5.00 Application Code ................................................................................................... 26 5.01 APP.C, APP.H and APP_CFG.H........................................................................... 27 5.02 INCLUDES.H......................................................................................................... 29 5.03 OS_CFG.H ............................................................................................................ 29 6.00 BSP (Board Support Package).............................................................................. 30 7.00 Conclusion............................................................................................................. 31 Licensing ...................................................................................................................... 32 References.................................................................................................................... 32 Contacts ...................................................................................................................... 32
1.00
Introduction
This application note describes how C/OS-II has been ported to the Microchip dsPIC33 family of processors. This application note does not assume any specific dsPIC33 derivative. Figure 1-1 shows a block diagram showing the relationship between your application, C/OS-II, the port code and the BSP (Board Support Package). Relevant sections of this application note are referenced on the figure.
Your Application
Section 5
APP.C APP.H APP_CFG.H INCLUDES.H OS CFG.H
C/OS-II
C/OS-II Book
OS_CORE.C OS_FLAG.C OS_MBOX.C OS_MEM.C OS_MUTEX.C OS_Q.C OS_SEM.C OS_TASK.C OS_TIME.C OS_TMR.C uCOS II.H
C/OS-II
Section 3
dsPIC33 Port
OS_CPU_C.C OS_CPU_A.S OS_CPU_UTIL_A.S OS_CPU.H OS DBG.C
BSP
BSP.C BSP.H
Section 6
Section 2
2.00
This section provides a brief description of the dsPIC33 programmers model. We present enough information in this section to provide a brief introduction. A complete description can be found in the Microchip documentation. The dsPIC33 family of CPU cores features proprietary Microchip architecture and is designed for controller applications using a 16-bit (data), DSP capable architecture. Below are some of the features of the dsPIC33 family of CPU cores: 16 General-purpose Working registers Dual 40 bit Accumulators, 17x17 Multiplier 24 bit variable length instruction word, 23 bit program counter. 40 bit barrel shifter capable of 16 bit shift left of shift right in 1 cycle. Dedicated 1KB of DMA Ram Hardware divider support Dual Address generators for accessing memory blocks X and Y. High speed deterministic interrupt processing
The dsPIC33 is a Little Endian architecture and thus the least significant byte of a value is placed at a lower memory location than its most significant byte. Figure 2-1 shows the register model of the dsPIC33 and consist of 16 Working registers, two 40 bit accumulators, the Data Table Page register, the Program Space Visibility Page Address register, a Repeat Loop Counter, three dedicated DO Loop registers, the Core Configuration register, and a CPU Status register.
3.00
C/OS-II has been ported to the Microchip C30, Hi-Tech dsPICC, and IAR iccDSPIC compilers. All ports currently utilize the MPLAB development environment v7.60 or greater. We strongly recommend checking with your compiler vendor to ensure that you have obtained the latest MPLAB IDE plug-in version available for the compiler of choice. We used an Explorer 16 EVB with a dsPIC33FJ256GP710 dsPIC33 derivative to test the described application. It is assumed that you have C/OS-II V2.82 or higher. Various tool-chains require different extensions for assembly files. This document refers to assembly files having the extension .s in order to be consistent with the Microchip C30 tool-chain. However, in practice, the Hi-Tech dsPICC compiler uses the extension .as while the IAR iccDSPIC compiler uses .s59. Files from different tool-chain ports are not interchangeable.
3.01
The software that accompanies this application note is assumed to be placed within the following directory depending on the tool-chain used: C30: \Micrium\Software\uCOS-II\Ports\Microchip\PIC33FJ256\MPLAB_C30 dsPICC: \Micrium\Software\uCOS-II\Ports\Microchip\PIC33FJ256\MPLAB_HT-DSPICC iccDSPIC: \Micrium\Software\uCOS-II\Ports\Microchip\PIC33FJ256\MPLAB_IAR The source code for the C/OS-II dsPIC33 port is found in the following files: OS_CPU.H OS_CPU_C.C OS_CPU_A.S OS_CPU_UTIL_A.S OS_DBG.C Section 3.02 Section 3.03 Section 3.04 Section 3.05 Section 3.06
3.02
OS_CPU.H
OS_CPU.H contains processor- and implementation-specific #defines constants, macros, and typedefs.
(1)
If you were to consult the MPLab compiler documentation, you would find that an int is 16 bits, an long is 32 bits. Floating-point data types are included even though C/OS-II doesnt make use of floating-point numbers. A stack entry for the dsPIC33 processor is always 16 bits wide; thus, OS_STK is declared accordingly. All task stacks must be declared using OS_STK as its data type. The status register (STATUS) on the dsPIC33 processor is 16 bits wide. The OS_CPU_SR data type is used when OS_CRITICAL_METHOD #3 is used (described below). In fact, this port only supports OS_CRITICAL_METHOD #3 because its the preferred method for C/OS-II ports.
L3-2(2)
L3-2(3)
L3-2(4)
3.03
OS_CPU_C.C
A C/OS-II port requires that you write ten (10) fairly simple C functions: OSInitHookBegin() OSInitHookEnd() OSTaskCreateHook() OSTaskDelHook() OSTaskIdleHook() OSTaskStatHook() OSTaskStkInit() OSTaskSwHook() OSTCBInitHook() OSTimeTickHook() Typically, C/OS-II only requires OSTaskStkInit(). The other functions allow you to extend the functionality of the OS with your own functions.
IMPORTANT
You will also need to set the #define constant OS_CPU_HOOKS_EN to 1 in OS_CFG.H in order for the compiler to use the functions declared in this file.
10
11
The code in Listing 3-13 initializes the stack frame for the task being created. The task received an optional argument p_arg. Most compilers pass a single argument in register W0 and thus, p_arg is passed in W0 when the task is created. The Task Body MUST call either one of the OS???Pend() functions or OSTimedly??() functions. In other words, a task MUST always be waiting for an event to occur. An event can be the reception of a signal or a message from another task or ISR. An event can also be to wait for the passage of time.
12
x = 0; if (CORCONbits.IPL3) { x |= 0x0080; } *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ *ptos++ }
= (OS_STK)(x | (INT16U)pc_high); // Push the SR Low, CORCON IPL3 and PC (22..16) = x; = = = = = = = = = = = = = = = (OS_STK)p_arg; 0x1111; 0x2222; 0x3333; 0x4444; 0x5555; 0x6666; 0x7777; 0x8888; 0x9999; 0xAAAA; 0xBBBB; 0xCCCC; 0xDDDD; 0xEEEE; // Push SR Low and CORCON IPL3 on to the stack // // // // // // // // // // // // // // // W0, Push a dummy argument on to the stack W1 W2 W3 W4 W5 W6 W7 W8 W9 W10 W11 W12 W13 W14
= ACCAL; = ACCAH; = ACCAU; = ACCBL; = ACCBH; = ACCBU; = TBLPAG; = PSVPAG; = RCOUNT; = = = = = DCOUNT; DOSTARTL; DOSTARTH; DOENDL; DOENDH;
// Accumulator A // Accumulator A // Accumulator A // Accumulator B // Accumulator B // Accumulator B // Table Page // Program Space Visibility Page Address // Repeat Loop Counter // // // // // Do Do Do Do Do Loop Loop Loop Loop Loop Counter Start Address Start Address End Address End Address
= 0; = CORCON;
// Status Register (contents irrelevant) // Core Configuration Register // Return the address to the top of the stack
return (ptos);
13
C/OS-II and the Microchip dsPIC33 Figure 3-1 shows how the stack frame is initialized for each task when its created.
Low Memory PC [15:0] (TaskAddr) PC [22:16](TaskAddr) PC [15:0] (TaskAddr) SR Low | IPL3 | PC [22:16] W0 W1 W2 W3 W4 W5 W6 W7 W8 W9 W10 W11 W12 W13 W14 = p_arg = 0x1111 = 0x2222 = 0x3333 = 0x4444 = 0x5555 = 0x6666 = 0x7777 = 0x8888 = 0x9999 = 0xAAAA = 0xBBBB = 0xCCCC = 0xDDDD = 0xEEEE ACCAL ACCAH ACCAU ACCBL ACCBH ACCBU TBLPAG PSVPAG RCOUNT DCOUNT DOSTARTL DOSTARTH DOENDL DOENDH SR (Initialized to 0) CORCON ptos (Top Of Stack) High Memory Stack Bottom
Simulated Interrupt
14
15
3.04
OS_CPU_A.S
A C/OS-II port requires that you write five fairly simple assembly language functions. These functions are needed because you normally cannot save/restore registers from C functions. The five functions are: OS_CPU_SR_Save() OS_CPU_SR_Restore() OSStartHighRdy() OSCtxSw() OSIntCtxSw() It should be noted that since the dsPIC33 has memory mapped registers, the first two functions, namely OS_CPU_SR_Save() and OS_CPU_SR_Restore() have been implemented as C macros. Since the remaining functions involve modifying the program counter, they have been implemented in assembly language in order to leverage off of the RETFIE instruction. The RETFIE instruction will restore the PC from data located on the current tasks stack. This is why an interrupt is simulated during task stack initialization.
Before starting the highest priority task, we call OSTaskSwHook() in case a hook function has been declared (see OS_CPU_C.C). The C/OS-II flag OSRunning is set to TRUE indicating that C/OS-II will be running once the first task is started. We then get the pointer to the tasks top-of-stack (was stored by OSTaskCreate() or OSTaskCreateExt()). See figure 3-1 (ptos is stored in the OS_TCB of the created task). We then pop all the registers from the tasks stack. This is done by calling an assembly language macro which is declared in OS_CPU_UTIL_A.S and will be described later. By executing a return from interrupt instruction, the dsPIC33 pops the PC and the STATUS register from the stack and thus, the dsPIC33 will start executing the tasks code.
L3-18(2) L3-18(3)
L3-18(4)
L3-18(5)
16
Restore the CPU registers from the new tasks stack; Return from Interrupt;
/* (8) */ /* (9) */
The actual code for the task level context switch is shown in Listing 3-19.
OS_REGS_SAVE mov mov call mov mov mov.b mov.b mov _OSTCBCur, w0 w15, [w0] _OSTaskSwHook _OSTCBHighRdy, w1 w1, _OSTCBCur _OSPrioHighRdy, wreg wreg, _OSPrioCur [w1], w15
; (2) Save context of interrupted task ; (3) OSTCBCur->OSTCBStkPtr = SP ; (4) Call user defined task switch hook ; (5) OSPrioCur = OSPrioHighRdy ; (6) OSTCBCur = OSTCBHighRdy ; (7) SP = OSTCBHighRdy->OSTCBStkPtr ; (8) Restore context of interrupted task ; (9) Return from interrupt
OS_REGS_RESTORE retfie
17
OS_REGS_RESTORE retfie
__T2Interrupt: OS_REGS_SAVE inc.b dec.b bra mov mov T2_Cont: call call _OSIntNesting _OSIntNesting, wreg nz, T2_Cont _OSTCBCur, w0 w15, [w0] _OS_Tick_ISR_Handler _OSIntExit
; 4) Call YOUR ISR Handler (May be a C function). ; In this case, the OS Tick ISR Handler ; 5) Call OSIntExit() ; 6) Restore registers
OS_REGS_RESTORE retfie
18
__T4Interrupt: OS_REGS_SAVE inc.b dec.b bra mov mov T4_Cont: call call _OSIntNesting _OSIntNesting, wreg nz, T4_Cont _OSTCBCur, w0 w15, [w0] _OS_Tick_ISR_Handler _OSIntExit
; 4) Call YOUR ISR Handler (May be a C function). ; In this case, the OS Tick ISR Handler ; 5) Call OSIntExit() ; 6) Restore registers
OS_REGS_RESTORE retfie
19
3.05
OS_CPU_UTIL_A.S
OS_CPU_UTIL_A.S is an assembly language file that declares two macros used to save the context of the CPU. These macros are called OS_REGS_SAVE and OS_REGS_RESTORE and are declared as shown below.
.macro OS_REGS_SAVE push.d w0 push.d w2 push.d w4 push.d w6 push.d w8 push.d w10 push.d w12 push w14 push push push push push push push push push push push push push push push push .endm ACCAL ACCAH ACCAU ACCBL ACCBH ACCBU TBLPAG PSVPAG RCOUNT DCOUNT DOSTARTL DOSTARTH DOENDL DOENDH SR CORCON
.macro OS_REGS_RESTORE pop CORCON pop SR pop pop pop pop pop pop pop pop pop pop pop pop pop pop pop pop.d pop.d pop.d pop.d pop.d pop.d pop.d .endm DOENDH DOENDL DOSTARTH DOSTARTL DCOUNT RCOUNT PSVPAG TBLPAG ACCBU ACCBH ACCBL ACCAU ACCAH ACCAL w14 w12 w10 w8 w6 w4 w2 w0
20
IMPORTANT
You MUST include a reference to this file when you write your ISRs (see section 4.00, Interrupt Handling). This is done by using the assembler directive #include as follows: .include os_cpu_util_a.s
3.06
OS_DBG.C
OS_DBG.C is a file that has been added in V2.62 to provide Kernel Aware debugger to extract information about C/OS-II and its configuration. Specifically, OS_DBG.C contains a number of constants that are placed in ROM (code space) which the debugger can read and display. Unfortunately, the MPLab debugger is not C/OS-II aware and thus this file is not needed but should be included in all builds for future reference.
21
4.00
Interrupt Handling
The dsPIC33 contains an interrupt and exception vector table which contains up to 54 entries. Each of these entries point to an interrupt or exception handler. For C/OS-II, each of those interrupt handlers MUST be written in assembly language. In fact, only a portion must be in assembly language as shown in listing 4-1. Note that you ONLY need to change the portion in RED for your own ISR. The rest of the code is IDENTICAL from one ISR to the next. Of course, you will need to give a unique name to your ISRs. Additionally, every tool-chain vendor has a unique method for placing interrupt code and setting interrupt vector table entries. At the time of this writing, the following methods are employed by each of the three tool-chain vendors supported. You may use bsp_a.s as an interrupt example if necessary. C30: .text .global __ISR_Name __ISR_Name: code (1) (2) (3) (4)
1. Place the remaining code below this point within the TEXT section 2. Prototype the name of the ISR Handler. Note that the ISR handler name has two underscores. One provided by the ISR routine programmer, and another by Microchip as part of the ISR naming convention. 3. Declare the ISR with the name specified in the Microchip MPLAB C30 Users Guide. (Document DS51284F, Page 100, table 7-1). This will tell the compiler to add the constant ISR address to the vector table by means of adding carefully placed constant data to the application binary. 4. Include the ISR code under the ISR name label. dsPICC: GLOBAL psect ORG DDW psect __ISR_Name vectors,class=VECTORS,delta=2 01Ch __ISR_Name text,global,reloc=4,class=CODE,delta=2 (1) (2) (3) (4) (5) (6) (7)
__ISR_Name: code
1. Prototype the name of the ISR. 2. Specify the placement of the defined double word (4) to be within the VECTORS section. 3. Specify the address to place ISR vector address. This value must be the vector address as specified in the dsPIC33 datasheet, minus six. The subtraction of six is necessary since ORG directive is NOT absolute and is relative to the current section (VECTORS) which starts from an offset of 0x06 in the memory map. In this case 01Ch represents vector address 0x22, the Timer2 ISR vector address. 4. Declare a double word representing the address of the ISR to be placed in the specified address. 5. Place the remainder of the code within the file in the CODE segment. 6. Declare the ISR with the name of your choice. 7. Include the ISR code under the ISR name label.
22
C/OS-II and the Microchip dsPIC33 iccDSPIC: COMMON INTVEC:CODE:ROOT(2) ORG __ISR_Address * 2 DL __ISR_Name / 2 RSEG CODE:CODE:ROOT(2) PUBLIC __ISR_Name
__ISR_Name: code
1. Place the defined long data word in the INTVEC section. 2. Specify the address to store the following long word (24 bit). This must be the ISR vector address as specified in the datasheet, multiplied by two. 3. Declare a long word whos value is that of the ISR_Handler defined within the same file below. The address to be placed in the above memory address must be that of the ISR_Name divided by two. Additional vectors may be declared at this time before step 4. 4. Place the remainder of the code within the file in the CODE segment. 5. Prototype the ISR Name. Note that the ISR name has two underscores appended to the beginning. This is to maintain consistency with the C30 compiler port, but is not required. 6. Declare the ISR with the name of your choice. 7. Include the ISR code under the ISR name label.
23
_My_ISR_Handler
; 4) Call YOUR ISR Handler (May be a C function). ; You MUST clear the interrupt source either ; from within, or just after your ISR Handler. ; 5) Call OSIntExit() ; 6) Restore registers ; 7) Return to the interrupted task
call
_OSIntExit
OS_REGS_RESTORE retfie
You then MUST save all of the registers using the OS_REGS_SAVE macro. You MUST increment C/OS-IIs interrupt nesting counter (OSIntNesting) You MUST check to see whether this is the first nested ISR by checking if OSIntNesting got incremented to 1. If this is the first nested ISR level then you MUST save the stack pointer into the current tasks OS_TCB. You can now call your actual ISR handler which could be written in C. You dont have to write the handler in C but its generally more readable and portable. You may optionally choose to clear the interrupt source from within your ISR handler, or you may do it before calling OSIntExit() from assembly. When you are done handling the ISR (i.e. the code returns from My_ISR_Handler()), you MUST call OSIntExit(). OSIntExit() checks to see if this is the last nested ISR. If it is then OSIntExit() checks to see if a more important task has been made ready-to-run by the ISR (or any other nested ISRs). If a more important task is ready-to-run, OSIntExit() doesnt return but instead context switches to the more important task. If the interrupted task is still the most important task to run then OSIntExit() returns and we simply need to restore the saved CPU registers in order to return to the interrupted task. To restore the registers, you MUST invoke the OS_REGS_RESTORE macro. The RETFIE instruction MUST be executed to return program execution back to the interrupted task in the event that OSIntExit()does not force a context switch.
L4-1(4)
L4-1(5)
L4-1(6)
L4-1(7)
24
L4-2(1)
Dont forget to clear the interrupting device (i.e. acknowledge that you serviced the interrupt). Failure to do this will cause the ISR to be re-entered which may not be what you want. As indicated, you may enable interrupts (by lowering the IPL level in the SR) if you want to allow nested interrupts. You can now service the interrupting device using the C programming language (instead of doing that in assembly language). If you disabled interrupts (see step #1) then you should disable them before returning to the caller of this function.
L4-2(2)
L4-2(3)
L4-2(4)
25
5.00
Application Code
Your application code can make use of the port presented in this application note as described in this section. Figure 5-1 shows a block diagram of the relationship between your application, C/OS-II, the C/OS-II port, the BSP (Board Support Package), the dsPIC CPU and the target hardware.
Your Application
Section 5
APP.C APP.H APP_CFG.H INCLUDES.H OS_CFG.H
C/OS-II
C/OS-II Book
OS_CORE.C OS_FLAG.C OS_MBOX.C OS_MEM.C OS_MUTEX.C OS_Q.C OS_SEM.C OS_TASK.C OS_TIME.C OS_TMR.C uCOS II.H
C/OS-II
Section 3
dsPIC Port
OS_CPU_C.C OS_CPU_A.ASM OS_CPU_I.ASM OS_CPU.H OS DBG.C
BSP
BSP.C BSP.H
Section 6
Section 2
26
5.01
For sake of discussion, your application is placed in files called APP.C, APP.H and APP_CFG.H. Of course, your application (i.e. product) can contain many more files. APP.C would be where you would place main() but, of course, you can place main() anywhere you want. APP.H contains #define constants, macros, prototypes, etc. that are specific to your application. This file may NOT exist in YOUR application and it is not included in examples provided for the PIC. APP_CFG.H contains #define constants to configure the application. We placed task stack sizes task priorities and other #defines in this file. This allows you to locate task priorities and sizes in one place. APP.C is a standard test file for C/OS-II examples. The two important functions are main() (listing 5-1) and AppStartTask() (listing 5-2).
(4) (5)
L5-1(1)
A BSP function called BSP_IntDisAll() is called to disable ALL interrupts. You would typically prevent the interrupt controller from issuing interrupts until your application is ready to service them. As with all C/OS-II based applications, you need to initialize C/OS-II by calling OSInit(). You need to create at least one task. In this case, we created the task using the extended task create call. This allow C/OS-II to have more information about your task. We can now give a name for our task. In order to start multitasking, you need to call OSStart(). Note that OSStart() will not return from this call.
L5-1(2)
L5-1(3)
L5-1(4) L5-1(5)
27
#if (uC_PROBE_OS_PLUGIN > 0) || (uC_PROBE_COM_MODULE > 0) AppProbeInit(); #endif AppTaskCreate(); while (TRUE) { for (i = 0; i < 4; i++) { for (j = 1; j <= 8; j++) { LED_On(j); OSTimeDlyHMSM(0, 0, 0, 25); LED_Off(j); } for (j = 7; j >= 2; j--) { LED_On(j); OSTimeDlyHMSM(0, 0, 0, 25); LED_Off(j); } } for (i = 0; i < 4; i++) { LED_On(0); OSTimeDlyHMSM(0, 0, 0, 25); LED_Off(0); OSTimeDlyHMSM(0, 0, 0, 25); } } } (3) (4)
(5)
L5-2(1)
If you decided to implement a BSP (see section 6, Board Support Package) for your target board, you would initialize it here. If you enabled the statistic task by setting OS_TASK_STAT_EN in OS_CFG.H to 1) then, you need to call it here. Please note that you need to make sure that you initialized and enabled the C/OS-II clock tick because OSStatInit() assumes the presence of clock ticks. In other words, if the tick ISR is not active when you call OSStatInit(), your application will end up in C/OS-IIs idle task and not be able to run any other tasks. At this point, you can create additional tasks. We decided to place all our task initialization in one function called AppTaskCreate() but, you are certainly welcome to use a different technique. You can now perform whatever additional function you want for this task. We decided to toggle an LED by calling a BSP function called LED_Toggle(). It is in fact these nested loops that perform the LED sweep functionality provided in many of our example applications. Each of your tasks MUST invoke one of the C/OS-II functions that will wait for an event to occur. We decided to use OSTimeDlyHMSM() which suspends the task for a specified amount of time.
L5-2(2)
L5-2(3)
L5-2(4)
L5-2(5)
28
5.02
INCLUDES.H
INCLUDES.H is a master include file and is found at the top of all .C files. INCLUDES.H allows every .C file in your project to be written without concern about which header file is actually needed. The only drawbacks to having a master include file are that INCLUDES.H may include header files that are not pertinent to the actual .C file being compiled and the compilation process may take longer. These inconveniences are offset by code portability. You can edit INCLUDES.H to add your own header files, but your header files should be added at the end of the list. Listing 5-3 shows the typical contents of INCLUDES.H. Of course, you can add your own header files as needed.
#if (uC_PROBE_OS_PLUGIN > 0) #include <os_probe.h> #endif #if (uC_PROBE_COM_MODULE > 0) #include <probe_com.h> #if (PROBE_COM_METHOD_RS232 > 0) #include <probe_rs232.h> #endif #endif #endif /* End of File */
5.03
OS_CFG.H
Every C/OS-II requires that you configure the RTOS for your own application. The configuration of C/OS-II allows to specify how many tasks your application will have, how many semaphores (if any), how many message queues (if any), etc. Configuring C/OS-II allows C/OS-IIs footprint to be only as big as it needs to be.
29
6.00
It is often convenient to create a Board Support Package (BSP) for your target hardware. A BSP could allow you to encapsulate the following functionality: Timer initialization (OS Ticker and View) PLL Initialization ISR Handlers LED control functions Reading switches Setting up communication channels Etc. A BSP consist of 2 files: BSP.C and BSP.H. For example, because a number of evaluation boards are equipped with LEDs, we decided to create LED control functions as follows: void void void void LED_Init(void); LED_On(INT8U led); LED_Off(INT8U led); LED_Toggle(INT8U led);
In this case, LEDs are referenced logically instead of physically. When you write the BSP, you determine which LED is LED #1, which is LED #2, etc. When you want to turn on LED #1, you simply call LED_On(1). If you want to toggle LED #2, you simply call LED_Toggle(2). In fact, you can (and should) associate names to your LEDs using #defines. You could thus specify LED_Off(LED_PM). Where LED_PM could be defined as LED #2. Each BSP should contain a BSP initialization function. We called ours BSP_Init() and should be called by your application code. We decided to encapsulate the C/OS-II clock tick ISR handler and its initialization function in the BSP because they ideally belong in your application code and not as part of C/OS-II. Doing this makes it easier to adapt the C/OS-II port to different target hardware since you could simply change the BSP to select whichever timer or interrupt source for the clock tick that your application requires. The clock tick ISR is in BSP_A.S which in turn calls the OS_Tick_ISR_Handler() that is found in BSP.C.
30
7.00
Conclusion
This application note presented a generic port for the dsPIC33 processor. Of course, if you use C/OS-II and use the port on actual hardware, you will need to initialize and properly handle hardware interrupts.
31
Licensing
If you intend to use C/OS-II in a commercial product, remember that you need to contact Micrim to properly license its use in your product. The use of C/OS-II in commercial applications is NOT-FREE. Your honesty is greatly appreciated.
References
MicroC/OS-II, The Real-Time Kernel, 2nd Edition Jean J. Labrosse CMP Technical Books, 2002 ISBN 1-5782-0103-9
Contacts
CMP Books, Inc. 6600 Silacci Way Gilroy, CA 95020 USA Phone Orders: 1-800-500-6875 or 1-408-848-3854 Fax Orders: 1-408-848-5784 e-mail: [email protected] WEB: http://www.cmpbooks.com Micrim 949 Crestview Circle Weston, FL 33327 USA 954-217-2036 954-217-2037 (FAX) e-mail: [email protected] WEB: www.Micrium.com Microchip Technology Inc. 2355 West Chandler Blvd. Chandler, Arizona 85224-6199 USA 480-792-7200 WEB: www.MicroChip.com
32