uCOS ppt

81
uCOS II RTOS

Transcript of uCOS ppt

Page 1: uCOS ppt

uCOS II

RTOS

Page 2: uCOS ppt

Reference Book

Page 3: uCOS ppt

Bu ild G C C f o r th e 1 s t t im e( w ith o u t G lib c )

Bu ild Bin ar y to o ls

Bu ild G lib c( N eed k er n e l h ead f ile )

Bu ild G C C f o r th e 2 n dtim e

( W ith G lib c )

Bu ild u G lib c f o r em b ed d edd ev e lo p m en t

Bu ild G D B

Build Toolchain

Page 4: uCOS ppt

Binutils

cd binutils-2.13.90.0.16./configure --target=powerpc-linux --prefix=/opt/linuxppcmakemake install

生成的可执行文件将被安装到 /opt/linuxppc/bin 目录下。也可以通过改变 --prefix 的值来指定其他任意路径。但最好不要将其指定为 /usr/local 或 /usr 以免毁坏操错系统现有的文件

Page 5: uCOS ppt

GCC (1st Compile)

cd gcc-2.95.3./configure --target=powerpc-linux –prefix=/opt/linuxppc \--enable-shared --enable-languages=c --with-newlibmakemake install

Page 6: uCOS ppt

Extract Kernel

tar xvfz …

Page 7: uCOS ppt

GLIBCUn-compress GLIBC & glibc-linuxthreads

ln –s include/asm-ppc /opt/powerpc-linux/include/asmln –s include/linux /opt/powerpc-linux/include/linux

CC = powerpc-linux-gccAR=powerpc-linux-arRANLIB=powerpc-linux-ranlib./configure --host=powerpc-linux –enable-add-ons \ --with-headers=/opt/powerpc-linux/include\

--prefix=/opt/linuxppcmakemake install_root=/opt/powerpc-linux install

Page 8: uCOS ppt

GCC (2nd Compile)

make distclean./configure --prefix=/opt/linuxppc –target=powerpc-linux \         --enable-shared –enable-threadsmake && make install

Page 9: uCOS ppt

Why RTOS? Learn RTOS:

– Fill the gap between Computer Science Experts and Application Engineers

– Understanding Computer more theoretically

Using RTOS:– Simplify the Application Programming

Higher the System Performance and Reliability

Page 10: uCOS ppt

Feature of Morden RTOS

CPU的管理 (硬件初始化、MMU 、定时器、中断 )

提供任务内存管理设备管理文件和网络的支持提供 C/C++ JAVA 图形模块等编程接口

Page 11: uCOS ppt

Real Time Kernel

Page 12: uCOS ppt

Advantage/Disadvantage of Using RTOS Advantage

– Split application to multi tasks, simplify the design, easy to be understand, expend and maintenance

– Time latency is guaranteed– Higher system reliability

Disadvantage– More RAM/ROM usage– 2~5% CPU overhead– Adding additional cost, if commercial TROS is

usedAbout 80 RTOS vendors, cost from $70 to $30,000 some are royalty free, some need $5 to $250 /MCU, MCU dependent

Page 13: uCOS ppt

What is uCOS II?

Micro-Controller Operating Systems, Version 2

A very small real-time kernel. Memory footprint is about 20KB for a

fully functional kernel. Source code is about 5,500 lines,

mostly in ANSI C. It’s source is open but not free for

commercial usages.

Page 14: uCOS ppt

Feature of uC/OSII

Preemptible priority-driven real-time scheduling.

64 priority levels (max 64 tasks), 8 reserved for uC/OS-II

Each task is an infinite loop. Deterministic execution times for most

uC/OS-II functions and services. Nested interrupts could go up to 256 levels.

Page 15: uCOS ppt

Real Time Kernel on uCOS

Page 16: uCOS ppt

µC/OS is Widely Used in Many Fields

cameras medical instruments Engine control musical instruments network adapter highway telephone call

box ATM machine industrial robots ……

Page 17: uCOS ppt

Ports On Different CPUsManufacture MCU

AMD 80x86 Analog Device SHARC (AD21065L) ARM ARM7 Atmel AVR, AT103 Fujitsu SPARC Hitachi 64180, H8-300H, H8S,SH2,SH3 Infineon Tri.Core, 80C166/167 Intel Strong ARM110,80C251,XC52, 80x86,

196K Motorola M68HC08, M68HC11, M68HC12,

M68HC16, M68000, CPU32, DSP568xx, Cold.Fire,M.Core, PowerPC8xx,MPC555

Philips XA ST 80C166/167 TI TMS320-C40, TMS320-C6201 Automation V8 Zilog Z-80, Z-180

Page 18: uCOS ppt

Roadmap of Learning Read the book and the µC/OS-II source code

– Understanding RTOS concepts Compiler the µC/OS-II with examples and run

on a PC– Add some codes to the examples

Porting the µC/OS-II to a MCU, which you are familiar with– Write the CPU.c and the CPU.a files

Do a project with a MCU board– Learn how to divide an application to several tasks– Communication and synchronization within tasks

Page 19: uCOS ppt

uCOS II ArchitectureApplications (Tasks)

CPU Independent CodeuCOS-II.h (Global Var)uCOS_II.c Groups:

OS_Core.c OS_Task.c OS_Time.c OS_Sem.c OS_Mbox.c OS_Q.c OS_Mem.c

ApplicationConfiguration Code

OS_CFG.hIncludes.h

CPU Dependent CodeOS_CPU.H OS_CPU_A.ASM OS_CPU_C.C

CPU Startup Code ISR (Timer and Other INT)

Page 20: uCOS ppt

Feature of uCOSII Portable : portable C, minimum uC dependent ASM

ROMable & Scalable

Preemptive : uC/OS-II is a fully preemptive real-time kernel

Multitasking : uC/OS-II can manage up to 64 tasks

Deterministic : Execution time of all uC/OS-II functions and service are deterministic

Deterministic : Each task requires its own different stack size

Services : Mailboxes, Queues, Semaphores, fixed-sized memory partitions, time-related functions

Interrupt Management

Int. can be nested up to 255 levels deep

Robust and Reliable

Page 21: uCOS ppt

OS Functions Provided by uCOSII

Page 22: uCOS ppt

Feature Not Supported by uCOS• Not support priority inheritance.

• With uC/OS-II, all tasks must have a unique priority, (Cannot Change While Running)

Page 23: uCOS ppt

Term (1) Multitasking

– The process of scheduling and switching the CPU between several tasks

Task– A simple program which thinks it has the CPU all to

itself. Kernel

– The part of the multitasking system responsible for the management of tasks and communication between tasks

Task Switch– Kernel saves the current task's context (CPU

registers) onto the current task's stack.– Kernel load new task's context from the task’s stack

of new task

Page 24: uCOS ppt

Term (2)

TCB– Task Control Block

Scheduler– Also called the dispatcher, is the part of the kernel

which is responsible for determining which task will run next

Non-preemptive scheduling– Each task is required to explicitly give up control of

the CPU. (ex. System API Call)– cooperative multitasking; tasks cooperate with each

other to gain control of the CPU.

Page 25: uCOS ppt

Term (3)

Preemptive Kernel– In it, when an event makes a higher priority

task ready to run, the current task is immediately suspended and the higher priority task is given control of the CPU

Reentrancy– A reentrant function is a function which can

be used by more than one task without fear of data corruption.

Page 26: uCOS ppt

uC/OS II Overview

TaskA() TaskB() TaskC()

IRQ1 IRQ2 IRQ3

Task Scheduler

{ { {

} } }

External IRQ

Timer

Page 27: uCOS ppt

Multi-Tasking Overview

Page 28: uCOS ppt

Sample Code (0)

Task0 Task1

MBox0 MBox1

Page 29: uCOS ppt

Sample Code (1)

Global Variables

main(){ init OS; init Global Variables; init Task0 and Task1}

Task0(){ … }

Task1(){ … }

Page 30: uCOS ppt

Sample Code (2)

#include "includes.h"

// Registers and data definition for our MX1 CPU#include "type.h" #include "mx1.h"

// Basic IO operation functionextern void EUARTinit(void);extern U8 EUARTgetData(void);extern void EUARTputString(U8 *line);

// Define stacks for eack task (32-bit)#define TASK_STK_SIZE 512OS_STK TaskStk[2][TASK_STK_SIZE];

// Function prototypes of tasksvoid Task0(void *data); void Task1(void *data);

// Mail boxes (Just two points)OS_EVENT* MBox0;OS_EVENT* MBox1;

Page 31: uCOS ppt

Sample Code (3)

int main (void){ P_U32 temp; // Init UART controller EUARTinit(); EUARTputString("\nEntering main() now!\n");

// Init uCOS kernel OSInit(); // Create Mailbox MBox0 = OSMboxCreate((void*)0); MBox1 = OSMboxCreate((void*)0);

// Create two task OSTaskCreate(Task0, // Task function (void *)0, // point to data struct for this task &(TaskStk[0][TASK_STK_SIZE - 1]), // stacks for the task 1); // priority OSTaskCreate(Task1, // Task function (void *)0, // no data transfered &(TaskStk[1][TASK_STK_SIZE - 1]), // point to data struct for this task 2); // priority OSStart(); // Start multi-tasking now return 0; // Never comes here}

Page 32: uCOS ppt

Sample Code (4)void Task0 (void *data){ int n = 0; int i; void* msg; INT8U err; while (1) { // Do something for (i = 0; i < 10000; i++) n++; // Tell people task0 is running EUARTputString("Enter task0\n"); // Send mail to mailbox 1 (to task 1) err = OSMboxPost(MBox1, (void*)&n);

// Waiting for mail from mailbox 0 (reply from task1)

msg = OSMboxPend(MBox0, 100, &err); // Get data attached in the mail n = *((int*)msg); } }

void Task1 (void *data){ int m = 0; int i; void* msg; INT8U err; while (1) { // Do something for (i = 0; i < 1234; i++) m++; // Tell people task1 is running EUARTputString("Enter task1\n"); // Waiting for mail from mailbox 1 (mail

from task 0) msg = OSMboxPend(MBox1, 100, &err);

// Get data attached in the mail m = *((int*)msg); // Reply the mail to mailbox 0 (to task 0) err = OSMboxPost(MBox0, (void*)&m); }}

Page 33: uCOS ppt

Sample Code (5)

Calculate n

Send mail to 1

Waiting reply from 1

Retrieve data from mail

Calculate n

Send mail to 1

Waiting reply from 1

Retrieve data from mail

Calculate m

Reply 0

Wait mail from 0

Retrieve data from mail

Calculate m

Reply 0

Wait mail from 0

Retrieve data from mail

Task0 Task1

Page 34: uCOS ppt

OSInit (1)

int main (void){ … OSInit(); … OSTaskCreate(…); … OSTaskCreate(…); … OSStart(); return 0; // Never return}

internal structures of uC/OS-2. Task ready list. Priority table. Task control blocks (TCB). Free pool. Create housekeeping tasks. The idle task. The statistics task.

Page 35: uCOS ppt

OSInit (2)

OSTCBStkPtrOSTCBExtPtr = NULLOSTCBStkBottomOSTCBStkSize = stack sizeOSTCBId = OS_LOWEST_PRIOOSTCBNextOSTCBPrevOSTCBEventPtr = NULLOSTCBMsg = NULLOSTCBDly = 0OSTCBStat = OS_STAT_RDYOSTCBPrio = OS_LOWEST_PRIO-1OSTCBX = 6OSTCBY = 7OSTCBBitX = 0x40OSTCBBitY = 0x80OSTCBDelReq = FALSE

OSTCBStkPtrOSTCBExtPtr = NULLOSTCBStkBottomOSTCBStkSize = stack sizeOSTCBId = OS_LOWEST_PRIOOSTCBNextOSTCBPrevOSTCBEventPtr = NULLOSTCBMsg = NULLOSTCBDly = 0OSTCBStat = OS_STAT_RDYOSTCBPrio = OS_LOWEST_PRIOOSTCBX = 7OSTCBY = 7OSTCBBitX = 0x80OSTCBBitY = 0x80OSTCBDelReq = FALSE

0 0

000

00

00000

[OS_LOWEST_PRIO][OS_LOWEST_PRIO - 1]

[0][1][2][3][4][5][6]

OS_TCB OS_TCBOSTaskStat() OSTaskIdle()

OSTCBPrioTbl[]

OSTCBList

OSPrioCur = 0OSPrioHighRdy = 0OSTCBCur = NULLOSTCBHighRdy = NULLOSTime = 0LOSIntNesting = 0OSLockNesting = 0OSCtxSwCtr = 0OSTaskCtr = 2OSRunning = FALSEOSCPUUsage = 0OSIdleCtrMax = 0LOSIdleCtrRun = 0LOSIdleCtr = 0LOSStatRdy = FALSE Task Stack

Task Stack

0 0 0 0 0 0 0 00 0 0 0 0 0 0 00 0 0 0 0 0 0 00 0 0 0 0 0 0 00 0 0 0 0 0 0 00 0 0 0 0 0 0 00 0 0 0 0 0 0 01 1 0 0 0 0 0 0

1 0 0 0 0 0 0 0

OSRdyGrp

OSRdyTbl[]

Ready List

Page 36: uCOS ppt

OSInit (4)

OSTCBStkPtrOSTCBExtPtrOSTCBStkBottomOSTCBStkSizeOSTCBId OSTCBNextOSTCBPrevOSTCBEventPtrOSTCBMsg OSTCBDly OSTCBStat OSTCBPrio OSTCBX OSTCBY OSTCBBitX OSTCBBitY OSTCBDelReq

OS_TCB

0OSTCBFreeList

OS_MAX_TASKS

0OSEventFreeList

OS_MAX_EVENTSOS_EVENT OS_EVENT OS_EVENT OS_EVENT

OSQPtrOSQStartOSQEndOSQInOSQOutOSQSizeOSQEntries

OSEventPtrOSEventTbl[]OSEventCntOSEventTypeOSEventGrp

OSTCBStkPtrOSTCBExtPtrOSTCBStkBottomOSTCBStkSizeOSTCBId OSTCBNextOSTCBPrevOSTCBEventPtrOSTCBMsg OSTCBDly OSTCBStat OSTCBPrio OSTCBX OSTCBY OSTCBBitX OSTCBBitY OSTCBDelReq

OS_TCB

OSTCBStkPtrOSTCBExtPtrOSTCBStkBottomOSTCBStkSizeOSTCBId OSTCBNextOSTCBPrevOSTCBEventPtrOSTCBMsg OSTCBDly OSTCBStat OSTCBPrio OSTCBX OSTCBY OSTCBBitX OSTCBBitY OSTCBDelReq

OS_TCB

OSEventPtrOSEventTbl[]OSEventCntOSEventTypeOSEventGrp

OSEventPtrOSEventTbl[]OSEventCntOSEventTypeOSEventGrp

OSEventPtrOSEventTbl[]OSEventCntOSEventTypeOSEventGrp

OSTCBStkPtrOSTCBExtPtrOSTCBStkBottomOSTCBStkSizeOSTCBId OSTCBNextOSTCBPrevOSTCBEventPtrOSTCBMsg OSTCBDly OSTCBStat OSTCBPrio OSTCBX OSTCBY OSTCBBitX OSTCBBitY OSTCBDelReq

OS_TCB

0OSQFreeList

OS_MAX_QSOS_Q OS_Q OS_Q

OSQPtrOSQStartOSQEndOSQInOSQOutOSQSizeOSQEntries

OSQPtrOSQStartOSQEndOSQInOSQOutOSQSizeOSQEntries

OSQPtrOSQStartOSQEndOSQInOSQOutOSQSizeOSQEntries

OSMemAddrOSMemFreeListOSMemBlkSizeOSMemNBlksOSNFree

0OSMemFreeList

OS_MAX_MEM_PARTOS_MEM

OSMemAddrOSMemFreeListOSMemBlkSizeOSMemNBlksOSNFree

OS_MEM OS_MEM OS_MEM

OSMemAddrOSMemFreeListOSMemBlkSizeOSMemNBlksOSNFree

OSMemAddrOSMemFreeListOSMemBlkSizeOSMemNBlksOSNFree

OS_Q

Page 37: uCOS ppt

OSInit (3)

01234567

89101112131415

1617181920212223

2425262728293031

3233343536373839

4041424344454647

4849505152535455

5657585960616263

Task Priority #

Lowest Priority Task(Idle Task)

Highest Priority Task

X

Y

OSRdyTbl[OS_LOWEST_PRIO / 8 + 1]01234567

OSRdyGrp

[7]

[6]

[5]

[4]

[3]

[2]

[1]

[0]

0 0 Y Y Y X X X

Bit position in OSRdyTbl[OS_LOWEST_PRIO / 8 + 1]

Bit position in OSRdyGrp andIndex into OSRdyTbl[OS_LOWEST_PRIO / 8 + 1]

Task's Priority

Page 38: uCOS ppt

OSTaskCreate (1)

Create tasks with the given arguments. Tasks become “ready” after they are created. Task

– An active entity which could do some computations.

– Priority, CPU registers, stack, text, housekeeping status.

– Task never return;

int main (void){ … OSInit(); … OSTaskCreate(…); … OSTaskCreate(…); … OSStart(); return 0; // Never return}

Page 39: uCOS ppt

OSTaskCreate (2)

INT8U OSTaskCreate (void (*task)(void *pd), void *pdata,

OS_STK *ptos, INT8U prio)

Task Function

Private Data For Task

Stack For TaskPriority of

created task

Note that OSTaskCreate can be called by main when OSStart is not invoked, but it can also be called in tasks when more task should be created at the run time

Page 40: uCOS ppt

Creating Task, OSTaskCreate()INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio){ void *psp; INT8U err;

if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */ return (OS_PRIO_INVALID); } OS_ENTER_CRITICAL(); if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */ OSTCBPrioTbl[prio] = (OS_TCB *)1; /* Reserve the priority to prevent others from doing ... */ /* ... the same thing until task is created. */ OS_EXIT_CRITICAL(); psp = (void *)OSTaskStkInit(task, pdata, ptos, 0); /* Initialize the task's stack */ err = OSTCBInit(prio, psp, (void *)0, 0, 0, (void *)0, 0); if (err == OS_NO_ERR) { OS_ENTER_CRITICAL(); OSTaskCtr++; /* Increment the #tasks counter */ OSTaskCreateHook(OSTCBPrioTbl[prio]); /* Call user defined hook */ OS_EXIT_CRITICAL(); if (OSRunning) { /* Find highest priority task if multitasking has started */ OSSched(); } } else { OS_ENTER_CRITICAL(); OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Make this priority available to others */ OS_EXIT_CRITICAL(); } return (err); } else { OS_EXIT_CRITICAL(); return (OS_PRIO_EXIST); }}

Page 41: uCOS ppt

OSStart Start multitasking of uC/OS-2. It never returns to main() The uC/OS-II picks up the highest-

priority task to run on context-switching.– Tightly coupled with RTC ISR.

int main (void){ … OSInit(); … OSTaskCreate(…); … OSTaskCreate(…); … OSStart(); return 0; // Never return}

Page 42: uCOS ppt

Task Management

RUNNINGREADY

OSTaskCreate()OSTaskCreateExt()

Task is Preempted

OSMBoxPend()OSQPend()

OSSemPend()OSTaskSuspend()OSTimeDly()OSTimeDlyHMSM()

OSMBoxPost()OSQPost()OSQPostFront()OSSemPost()OSTaskResume()OSTimeDlyResume()OSTimeTick()

OSTaskDel()

DORMANT

WAITING

OSStart()OSIntExit()

OS_TASK_SW()

OSTaskDel()

OSTaskDel()

Interrupt

OSIntExit()

ISR

• Task is created by calling OSTaskCreate()

• Task is deleted by calling OSTaskDel() (After calling the function OS will never touch the task)

• Task is in waiting when request a system resource or singal (OSSemPend(),OSMboxPend(),OSQPend(), OSTimeDly() or OSTimeDlyHMSM() )

Page 43: uCOS ppt

Task Management (contd.)

uC/OS-II can manage up to 64 tasks- two task are used for system use.- Reserve prorities 0, 1, 2, 3, OS_LOWEST_PRIO-3, 2, 1, 0

Use 56 application taskUse 56 application task

Page 44: uCOS ppt

Task Control Block (TCB)

• When a task is created, it is assigned a Task Control Block, OS_TCB

• OS_TCB is a data structure that is used by uC/OS-II to maintain the state of a task when it is preempted.

• All OS_TCB reside in RAM

• An OS_TCB is initialized when a task is created.

Page 45: uCOS ppt

typedef struct os_tcb { OS_STK *OSTCBStkPtr; // Can be accessed by ASM #if OS_TASK_CREATE_EXT_EN // Data for advanced task void *OSTCBExtPtr; // (record more info.) OS_STK *OSTCBStkBottom; INT32U OSTCBStkSize; INT16U OSTCBOpt; INT16U OSTCBId;#endif  struct os_tcb *OSTCBNext; // 2 dir link struct os_tcb *OSTCBPrev; #if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN || OS_SEM_EN OS_EVENT *OSTCBEventPtr; // Point to event list for#endif #if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN void *OSTCBMsg; // Point to message list #endif INT16U OSTCBDly; // Task call delay() INT8U OSTCBStat; INT8U OSTCBPrio; // Lower value higher prio. INT8U OSTCBX; // For fast task schedule INT8U OSTCBY; INT8U OSTCBBitX; INT8U OSTCBBitY; #if OS_TASK_DEL_EN BOOLEAN OSTCBDelReq;#endif} OS_TCB;

TCB Structure

OSTCBY = priority >> 3; OSTCBBitY = OSMapTbl[priority >> 3]; OSTCBX = priority & 0x07; OSTCBBitX = OSMapTbl[priority & 0x07];

Page 46: uCOS ppt

TCB Structure (contd.)

0OSTCBFreeList OSTCBNext OSTCBNext OSTCBNext OSTCBNext

OSTCBTbl[0] OSTCBTbl[1] OSTCBTbl[2]

OSTCBTbl[OS_MAX_TASKS+OS_N_SYS_TASKS-1]

OS_MAX_TASKS is specified in OS_CFG.H

Page 47: uCOS ppt

Task SchedulingTask-level scheduling is performed by OSSched().

ISR-level scheduling is handled by OSIntExit().void OSSched (void){ INT8U y;

OS_ENTER_CRITICAL(); if ((OSLockNesting | OSIntNesting) == 0) {/* Task scheduling must be enabled and not ISR level */ y = OSUnMapTbl[OSRdyGrp]; /* Get pointer to highest priority task ready to run */ OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]); if (OSPrioHighRdy != OSPrioCur) { /* No context switch if current task is highest ready */ OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; OSCtxSwCtr++; /* Increment context switch counter */ OS_TASK_SW(); /* Perform a context switch */ } } OS_EXIT_CRITICAL();}

Page 48: uCOS ppt

Memory Management in uCOS malloc() and free() is dangerous in Embedded

real-time system – Unable to obtain a single contiguous memory area

due to fragmentation Execution time of malloc() and free() are also

nondeterministic– Algorithms used to locate a contiguous block of free

memory– Time for de-fragmentation

Fixed-sized memory blocks from a partition made of a contiguous memory area.– All memory blocks are the same size and the

partition contains an integral number of blocks– Allocation and deallocation of these memory blocks

is done in constant time and is deterministic

Page 49: uCOS ppt

Memory Management in uCOS (contd.) Partition #1 Partition #2 Partition #3 Partition #4

OSMemAddr

OSMemFreeList

OSMemBlkSize

OSMemNBlks

OSMemNFree

OSMemAddr

OSMemFreeList

OSMemBlkSize

OSMemNBlks

OSMemNFree

OSMemAddr

OSMemFreeList

OSMemBlkSize

OSMemNBlks

OSMemNFree

0OSMemFreeList

OS_MAX_MEM_PART

Only empty data structs

after init

0

OSMemAddr = addr

OSMemFreeList= addr

OSMemBlkSize = blksize

OSMemNBlks = nblks

OSMemNFree = nblks

Contiguous memory

pmem

OSMemCreate() arguments

Get one node from OSMemFreeList, & fill

with real memory partition info.

Page 50: uCOS ppt

Memory Management in uCOS (contd.)

typedef struct { void *OSMemAddr; void *OSMemFreeList; INT32U OSMemBlkSize; INT32U OSMemNBlks; INT32U OSMemBNFree;} OS_MEM;

OS_MEM *CommTxBuf;INT8U CommTxPart[100][32];void main(void){ INT8U err; . . . OSInit(); . . . CommTxBuf = OSMemCreate(CommTxPart, 100, 32, &err); . . . OSStart();}

Page 51: uCOS ppt

Memory Management Functions OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err) – Format a memory partition

OSMemGet (OS_MEM *pmem, INT8U *err) – Get a memory block from one of the created memory partitions

OSMemPut (OS_MEM *pmem, void *pblk) – Returning a Memory Block to the appropriate partition

OSMemQuery() – Obtaining status of a Memory partition

Page 52: uCOS ppt

Memory Management Example

ErrMsgPart

ErrMsgQ

ErrorHandler

AITask

0

OSMemGet() OSMemPut()

OSQPost() OSQPend()

OSTime

OSTimeGet()

(1)

AnalogInputs

(2)

(3)

(4)

(5) (6)

(7)

(8)

Page 53: uCOS ppt

Time Management

5ms

10ms

Tick Interrupt

OSTic kISR ()

All HP T

Low- P rio rity Task

Task c alls  OSTimeDly(1)  here!

(1)(2)

(3)

(4)

(5)

(6)

Page 54: uCOS ppt

Time Management Function OSTimeDly()–Delay for a user-specified number of clock ticks

 OSTimeDlyHMSM()hours(H), minutes(M), seconds(S),

milliseconds(m), Maximum Delay 256hours (11days)OSTimeDlyHMSM( 0, 0, 1, 500);

 OSTimeDlyResume()–Resuming a Delayed Task

 OSTimeGet() & OSTimeSet()–32-bit counter

Page 55: uCOS ppt

Time Management Function (contd.)

Task A

OSTimeDly(100)

Task A

Task BTask A sleep now

Task A call

Find the highest priority ready task B, and activate it

1

23

OSTickISR

This ISR is called every time tick to advance the clock

Page 56: uCOS ppt

Hooks

A hook function will be called by uC/OS- when the corresponding event occurs.– Event handlers could be in user programs.– For example, OSTaskSwHook () is called every

time when context switch occurs. The hooks are specified in the compiling time

in uC/OS-II:– uC/OS-II is an embedded OS.

• OS_CFG.H (OS_CPU_HOOKS_EN = 0)

– Many OS’s can register and un-register hooks.

Page 57: uCOS ppt

Hook Functions

void OSInitHookBegin (void) void OSInitHookEnd (void) void OSTaskCreateHook (OS_TCB *ptcb) void OSTaskDelHook (OS_TCB *ptcb) void OSTaskIdleHook (void) void OSTaskStatHook (void) void OSTaskSwHook (void) void OSTCBInitHook (OS_TCB *ptcb) void OSTimeTickHook (void)

Empty function, can be overridden by user

Page 58: uCOS ppt

Mail Box A mailbox is for data exchanging between

tasks.– A mailbox consists of a data pointer and a wait-list.

OSMboxPend():– The message in the mailbox is retrieved.– If the mailbox is empty, the task is immediately

blocked and moved to the wait-list.– A time-out value can be specified.

OSMboxPost():– A message is posted in the mailbox.– If there is already a message in the mailbox, then

an error is returned (not overwritten).– If tasks are waiting for a message from the mailbox,

then the task with the highest priority is removed from the wait-list and scheduled to run.

Page 59: uCOS ppt

Mail Box OperationOS_EVENT* MBox0;

OS_EVENT* MBox1;

MBox0 = OSMboxCreate((void*)0);

MBox1 = OSMboxCreate((void*)0);

err = OSMboxPost(MBox1, (void*)&n);

msg = OSMboxPend(MBox0, 100, &err);

Page 60: uCOS ppt

OSMboxCreate Step 1

– Get a OS_EVENTOS_EVENT node from OSEventFreeListOSEventFreeList

Step 2– Assign type OS_EVENT_TYPE_MBOXOS_EVENT_TYPE_MBOX to the OS_EVENT

node

Step 3– Attach the messageAttach the message (given from caller) to the OS_EVENT

node

Step 4– Return the point point of the OS_EVENT node to the caller

NoteNote– Mail box is an event in the view of uCOS– Mail box is not attach to specific task when created– The mail box has a table to record the tasks that are waiting

on the mail box.

Page 61: uCOS ppt

OSMboxPost

Step 1– If there has some Task waitingTask waiting on the mail box,

wake up it and give the message to it directly

Step 2 (Step 1 is not run)– If the mail box is fullfull returnreturn error

OS_MBOX_FULLOS_MBOX_FULL

Step 3 (Step 2 is not run)– AttachAttach mailmail messagemessage to the mail box (mail box is

a special event)

Page 62: uCOS ppt

OSMboxPend Step 1

– If mail box is emptyempty, pendingpending the task by calling OSEventTaskWait() OSEventTaskWait() (This function will register the task on the event table of the mail box, so that when mail box receive a message, it can check its table to wake up those tasks)

Step 2 (Step 1 is not run)– This step is run either because mail box get new

email or timeout event occur– The mail will be sent to task directly– Note:

• The message can be found by task’s message pointer. If there are already tasking waiting for mail in the mailbox, the arriving mail is given to task directly instead of storing to mailbox and then inform the task

• The message can be found in mail box’s pointer if the mail is sent when no tasking is pending for mail of the mail box.

Page 63: uCOS ppt

Message Qeue A message queue consists of an array of elements and a

wait-list. Different from a mailbox, a message queue can hold

many data elements (in a FIFO basis). As same as mailboxes, there can be multiple tasks

pend/post to a message queue. OSQPost(): a message is appended to the queue. The

highest-priority pending task (in the wait-list) receives the message and is scheduled to run, if any.

OSQPend(): a message is removed from the array of elements. If no message can be retrieved, the task is moved to the wait-list and becomes blocked.

Page 64: uCOS ppt

Intertask Comm. & Synch.

ISR TaskE C B

TaskE C BTask

E C B

Task

Task

ISR

Task

E C B

Task

Task

S ign al

S ign al

S ign al

S ign al

W ait/S ign al

W ait/S ign al

W ait

W ait

W ait

W ait

T im eou t

T im eou t

T im eou t

T im eou t

Page 65: uCOS ppt

Event Control Blocks

typedef struct {

void *OSEventPtr;INT8U OSEventTbl[OS_EVENT_TBL_SIZE];INT16U OSEventCnt;INT8U OSEventType;INT8U OSEventGrp;

} OS_EVENT;

•OSEventPtr

ECB is assigned to a mailbox or a queue

•OSEventTbl[] & .OSEventGrp

Contains a list of tasks waiting on the event

•OSEventCnt

Hold the semaphore count

•OSEventType

The type associated with the ECB

OS_EVENT_SEM, OS_EVENT_TYPE_MBOX, OS_EVENT_TYPE_Q

Page 66: uCOS ppt

Event Control Blocks

7 6 5 4 3 2 1 0

15 14 13 12 11 10 9 8

23 22 21 20 19 18 17 16

31 30 29 28 27 26 25 24

39 38 37 36 35 34 33 32

47 46 45 44 43 42 41 40

55 54 53 52 51 50 49 48

63 62 61 60 59 58 57 56

y

x

Highest Priority Task Waiting

Priority of task waitingfor the event to occur

Lowest Priority Task

7 6 5 4 3 2 1 0

[0]

[1]

[2]

[3]

[4]

[5]

[6]

[7]

0 0 Y Y Y X X X

Bit position in .OSEventTbl[]Bit posion in .OSEventGrpand Index into .OSEventTbl[]

Task’s Priority

.OSEventGrp.OSEventTbl[OS_LOWEST_PRIO/8+1]

Page 67: uCOS ppt

Making a task wait for an event

pevent->OSEvebtGrp |= OSMapTbl[prio >> 3]; pevent->OSEventTbl[prio>>3] |= OSMapTbl[prio & 0x07];

Content of OSMapTbl[]

Removing a task from a wait list

if ((pevent->OSEventTbl[prio>>3] &= ~OSMapTbl[prio & 0x07]) == 0) { pevent->OSEventGrp &= ~OSMapTbl[prio >> 3]; }

Finding the highest priority task waiting for the event

y = OSUnMapTbl[pevent->OSEventGrp]; x = OSUnMapTbl[pevent->OSEvenTbl[y]]; prio = (y<<3) + x;

Index Bit Mask(Binary)0 0000 00011 0000 00102 0000 01003 0000 10004 0001 00005 0010 00006 0100 00007 1000 0000

Page 68: uCOS ppt

OSEventWaitListInit()

: a function called when a semaphore, message mailbox, message queue is created

initializing an ECB

OSEventTaskRdy()

: Removes the highest priority task(HPT) from the wait list of the ECB and make this task ready to run

called by OSSemPost(), OSMboxPosr(), OSQPost(), OSQPostFront()

OSEventTaskWait()

: called by OSSemPend(), OSMboxPend(), OSQPend() when a task must wait on an ECB

Removes the current task from the ready list and places it in the wait list of the ECB

Page 69: uCOS ppt

Semaphores16-bit unsigned integer used to hod the semaphore count (0 to 65535)

a list of tasks waiting for the semaphore count to be greater than 0

uC/OS-II provides five services to semaphores

- OSSemCreate()

- OSSemPend()

- OSSemPost()

- OSSemAccept()

- OSSemQuery()Task

Task

ISR

OR

OSSemP ost()OSSemAccept()

OSSemP ost()OSSemP end()OSSemAccept()OSSemQuery()

OSSemC reate()

N

N

Page 70: uCOS ppt

OSSemCreate()

: Creates and initializes a semaphore

OS_EVENT *DispSem;

void main(void) {

. . . OSInit(); . . . DispSem = OSSemCreate(1); . . . OSStart();

}

OSSemPend()

: When a task wants exclusive access to a resource, needs to synchronize its activities with an ISR or a task, or is waiting until an event occurs

void DispTask(void *pdata)

{

INT8U err; pdata = pdata; for (;;) { . . . OSSemPend(DispSem, 0, &err);

. . . }

}

Page 71: uCOS ppt

OSSemPost()

: A semaphore is signaled by calling OSSemPost().

void TaskX(void *pdata){

INT8U err; pdata = pdata;

for (;;) { . . . err = OSSemPost(DispSem); if (err == OS_NO_ERR) {

/* Semaphore signaled */

} else {

/* Semaphore has overflowed */

….

OSSemQuery()

: Obtain information about a semaphore

void Task (void *pdata)

{

OS_SEM_DAT sem_data: INT8U err, highest, x, y; pdata = pdata;

for (;;) {

. . . err = OSSemQuery(DispSem,&sem_data);

if (err==OS_NO_ERR) {

y=OSUnMapTbl[sem_data.OSEventGrp]; x=OSunMapTbl[sem_data.OSEventTbl[y]];

highest = (y<<3)+x;

. . .

Page 72: uCOS ppt

Message MailboxesA message mailbox is a uC/OS-II object that allows a task or an ISR to send a pointer sized variable to another task

uC/OS-II provides five services to mailboxes

- OSMboxCreate()

- OSMboxPend()

- OSMboxPost()

- OSMboxAccept()

- OSMboxQuery() Task

Task

ISR

OSMboxP ost()OSMboxAccept()

OSMboxP ost()OSMboxP end()OSMboxAccept()OSMboxQuery()

OSMboxC reate()

M ailbox

Message

Page 73: uCOS ppt

OSMboxCreate()

: Creates and initializes a mailbox

OS_EVENT *CommMbox;

void main(void) {

. . . OSInit(); . . . CommMbox = OSMboxCreate((void *)0); . . . OSStart();

}

OSMboxPend()

: When a task task expects to receive a message.

void CommTask(void *pdata)

{

INT8U err; void *msg;

pdata = pdata; for (;;) { . . .

msg=OSMboxPend(CommMbox, 10, &err);

if (err==OS_NO_ERR) {

/* Code for received message */

} else {

/* Code for message not received within time out */

. . .

Page 74: uCOS ppt

OSMboxPost()

: Send a message to a task through a mailbox

OS_EVENT *CommMBox

INT8U CommRxBuf[100];

void CommTaskRx(void *pdata)

{

INT8U err; . . .

pdata = pdata; for (;;) {

. . . err = OSMboxPost(CommMbox, (void *)

&CommRxbuf[0]);

. . .

OSMboxQuery()

: Obtain information about a message mailbox

void Task (void *pdata)

{

OS_MBOXDATA mbox_data: INT8U err;

pdata=pdata; for (;;) {

. . . err = OSMboxQuery(CommMbox, &mbox_data);

if (err==OS_NO_ERR) { /* Mailbox contains a message if mbox_data.OSMsg is not NULL */ }

. . .

Page 75: uCOS ppt

Message QueuesA message queue is a uC/OS-II object that allows a task or an ISR to send pointer sized variables to another task.

uC/OS-II provides seven services to Queues

- OSQCreate()

- OSQPend()

- OSQPost()

- OSQPostFront()

- OSQAccept()

- OSQFlush()

- OSQQuery()

Task

Task

ISR

OSQP ost()OSQP ostF ront()OSQF lush()OSQAccept()

OSQP ost()OSQP ostF ront()OSQF lush() OSQP end()

OSQAccept()OSQQuery()

OSQC reate()

Queue

Message

N

Page 76: uCOS ppt

OSQCreate()

: Creates a message queue

OS_EVENT *CommQ;

void *CommMsg[10];

void main(void) {

. . . OSInit(); . . . CommQ=OSQCreate(&CommMsg[0],10); . . . OSStart();

}

OSQPend()

: When a task task expects to receive a message from a queue

void CommTask(void *pdata)

{

INT8U err; void *msg;

pdata = pdata; for (;;) { . . .

msg=OSQPend(CommQ, 100, &err); if (err==OS_NO_ERR) {

/* Message received wihin 100 ticks! */ } else {

/* Message not received, must have timed out */

. . .

Page 77: uCOS ppt

OSQPost()

: Send a message to a task through a queue

OS_EVENT *CommQ;

INT8U CommRxBuf[100];

void CommTaskRx(void *pdata)

{

INT8U err; . . .

pdata = pdata; for (;;) {

. . . err = OSQPost(CommQ, (void *)

&CommRxBuf[0]);

. . .

OSQPostFront()

: Send a message to a task through a queue

OS_EVENT *CommQ;

INT8U CommRxBuf[100];

void CommTaskRx(void *pdata)

{

INT8U err; . . .

pdata = pdata; for (;;) {

. . . err = OSQPostFront(CommQ, (void *)

&CommRxBuf[0]);

. . .

Page 78: uCOS ppt

Semaphore

Page 79: uCOS ppt

How to Transplant to ARM? MMU?

Not implemented

Startup.sBasic init before main is run

OS_CPU_a.sSystem code for task swapping & IRQ (FIQ)

OS_CPU.c, OS_CPU.hHooks and the C extention of IRQ (FIQ) handler

OS_CFG.hWhich modules are compiled into code?

Page 80: uCOS ppt

How Many Codes on uCOS Box

Startup.s

uCOS core

OS_CPU_a.s

Reset

TaskA(){…}TaskB(){…}TaskC(){…}TaskD(){…}

InterruptHow many codes on a uCOS box?

All of them are

compiled into a large binary file

Page 81: uCOS ppt

Interrupts under uC/OS-IIuC/OS-II requires that an Interrupt Service Routine(ISR) be written in assembly language.

Pseudocode for an ISR

YourISR:

Save all CPU registers;

Call OSIntEnter() or, increment OSIntNesting directly;

Execute user code to service ISR;

Call OSIntExit();

Restore all CPU registers;

Execute a return from interrupt instruction;