- •Preface
- •Introduction
- •1.01 INCLUDES.H
- •1.02 Compiler Independent Data Types
- •1.03 Global Variables
- •1.04 OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL()
- •1.05 PC Based Services
- •1.05.01 PC Based Services, Character Based Display
- •1.05.02 PC Based Services, Elapsed Time Measurement
- •1.05.03 PC Based Services, Miscellaneous
- •1.07 Example #1
- •1.08 Example #2
- •1.09 Example #3
- •2.00 Foreground/Background Systems
- •2.01 Critical Section of Code
- •2.02 Resource
- •2.03 Shared Resource
- •2.04 Multitasking
- •2.05 Task
- •2.06 Context Switch (or Task Switch)
- •2.07 Kernel
- •2.08 Scheduler
- •2.09 Non-Preemptive Kernel
- •2.10 Preemptive Kernel
- •2.11 Reentrancy
- •2.12 Round Robin Scheduling
- •2.13 Task Priority
- •2.14 Static Priorities
- •2.15 Dynamic Priorities
- •2.16 Priority Inversions
- •2.17 Assigning Task Priorities
- •2.19 Mutual Exclusion
- •2.20 Deadlock (or Deadly Embrace)
- •2.21 Synchronization
- •2.22 Event Flags
- •2.23 Intertask Communication
- •2.24 Message Mailboxes
- •2.25 Message Queues
- •2.26 Interrupts
- •2.27 Interrupt Latency
- •2.28 Interrupt Response
- •2.29 Interrupt Recovery
- •2.30 Interrupt Latency, Response, and Recovery
- •2.31 ISR Processing Time
- •2.32 Non-Maskable Interrupts (NMIs)
- •2.33 Clock Tick
- •2.34 Memory Requirements
- •2.35 Advantages and Disadvantages of Real-Time Kernels
- •2.36 Real-Time Systems Summary
- •3.00 Critical Sections
- •3.01 Tasks
- •3.02 Task States
- •3.03 Task Control Blocks (OS_TCBs)
- •3.04 Ready List
- •3.05 Task Scheduling
- •3.06 Locking and Unlocking the Scheduler
- •3.07 Idle Task
- •3.08 Statistics Task
- •3.10 Clock Tick
- •3.14 OSEvent???() functions
- •4.00 Creating a Task, OSTaskCreate()
- •4.01 Creating a Task, OSTaskCreateExt()
- •4.02 Task Stacks
- •4.03 Stack Checking, OSTaskStkChk()
- •4.04 Deleting a Task, OSTaskDel()
- •4.05 Requesting to delete a task, OSTaskDelReq()
- •4.06 Changing a Task’s Priority, OSTaskChangePrio()
- •4.07 Suspending a Task, OSTaskSuspend()
- •4.08 Resuming a Task, OSTaskResume()
- •4.09 Getting Information about a Task, OSTaskQuery()
- •5.00 Delaying a task, OSTimeDly()
- •5.01 Delaying a task, OSTimeDlyHMSM()
- •5.02 Resuming a delayed task, OSTimeDlyResume()
- •5.03 System time, OSTimeGet() and OSTimeSet()
- •6.00 Event Control Blocks
- •6.01 Initializing an ECB, OSEventWaitListInit()
- •6.02 Making a task ready, OSEventTaskRdy()
- •6.03 Making a task wait for an event, OSEventTaskWait()
- •6.04 Making a task ready because of a timeout, OSEventTO()
- •6.05 Semaphores
- •6.06 Message Mailboxes
- •6.07 Message Queues
- •7.00 Memory Control Blocks
- •7.01 Creating a partition, OSMemCreate()
- •7.02 Obtaining a memory block, OSMemGet()
- •7.03 Returning a memory block, OSMemPut()
- •7.04 Obtaining status about memory partition, OSMemQuery()
- •7.05 Using memory partitions
- •7.06 Waiting for memory blocks from a partition
- •8.00 Development Tools
- •8.01 Directories and Files
- •8.02 INCLUDES.H
- •9.00 Development Tools
- •9.01 Directories and Files
- •9.02 INCLUDES.H
- •9.06 Memory requirements
- •9.07 Execution times
- •10.00 Directories and Files
- •10.01 INCLUDES.H
- •10.02.01 OS_CPU.H, Compiler specific data types
- •10.02.02 OS_CPU.H, OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL()
- •10.02.03 OS_CPU.H, OS_STK_GROWTH
- •10.02.04 OS_CPU.H, OS_TASK_SW()
- •10.03.01 OS_CPU_A.ASM, OSStartHighRdy()
- •10.03.02 OS_CPU_A.ASM, OSCtxSw()
- •10.03.03 OS_CPU_A.ASM, OSIntCtxSw()
- •10.03.04 OS_CPU_A.ASM, OSTickISR()
- •10.04.01 OS_CPU_C.C, OSTaskStkInit()
- •10.04.02 OS_CPU_C.C, OSTaskCreateHook()
- •10.04.03 OS_CPU_C.C, OSTaskDelHook()
- •10.04.04 OS_CPU_C.C, OSTaskSwHook()
- •10.04.05 OS_CPU_C.C, OSTaskStatHook()
- •10.04.06 OS_CPU_C.C, OSTimeTickHook()
- •10.05 Summary
- •OSInit()
- •OSIntEnter()
- •OSIntExit()
- •OSMboxAccept()
- •OSMboxCreate()
- •OSMboxPend()
- •OSMboxPost()
- •OSMboxQuery()
- •OSMemCreate()
- •OSMemGet()
- •OSMemPut()
- •OSMemQuery()
- •OSQAccept()
- •OSQCreate()
- •OSQFlush()
- •OSQPend()
- •OSQPost()
- •OSQPostFront()
- •OSQQuery()
- •OSSchedLock()
- •OSSchedUnlock()
- •OSSemAccept()
- •OSSemCreate()
- •OSSemPend()
- •OSSemPost()
- •OSSemQuery()
- •OSStart()
- •OSStatInit()
- •OSTaskChangePrio()
- •OSTaskCreate()
- •OSTaskCreateExt()
- •OSTaskDel()
- •OSTaskDelReq()
- •OSTaskResume()
- •OSTaskStkChk()
- •OSTaskSuspend()
- •OSTaskQuery()
- •OSTimeDly()
- •OSTimeDlyHMSM()
- •OSTimeDlyResume()
- •OSTimeGet()
- •OSTimeSet()
- •OSTimeTick()
- •OSVersion()
peventis a pointer to the queue where the message is to be deposited into. This pointer is returned to your application when the queue is created (see OSQCreate()).
msg is the actual message sent to the task. msg is a pointer size variable and is application specific. You MUST never post a NULL pointer.
Returned Value
OSQPostFront() returns one of these two error codes
1)OS_NO_ERR, if the message was deposited in the queue
2)OS_Q_FULL, if the queue is already full
Notes/Warnings
Queues must be created before they are used.
Example
OS_EVENT *CommQ; |
|
|
INT8U |
CommRxBuf[100]; |
|
void CommTaskRx(void *pdata) |
|
|
{ |
|
|
INT8U |
err; |
|
pdata = pdata; |
|
|
for (;;) { |
|
|
. |
|
|
. |
|
|
err = OSQPostFront(CommQ, (void *)&CommRxBuf[0]); |
|
|
if (err == OS_NO_ERR) { |
|
|
. |
/* Message was deposited into queue |
*/ |
. |
|
|
} else { |
|
|
. |
/* Queue is full |
*/ |
. |
|
|
} |
|
|
.
.
}
}
OSQQuery()
INT8U OSQQuery(OS_EVENT *pevent, OS_Q_DATA *pdata);
File |
Called from |
Code enabled by |
OS_Q.C |
Task or ISR |
OS_MBOX_EN |
OSQQuery() is used to obtain information about a message queue. Your application must allocate an OS_Q_DATA data structure which will be used to receive data from the event control block of the message queue. OSQQuery() allows you to determine whether any task is waiting for message(s) at the queue, how many tasks are waiting (by counting the number of 1s in the .OSEventTbl[] field, how many messages are in the queue, what the message queue size is, and examine the contents of the next message that would be returned if there is at least one message in the queue. You can use the table OSNBitsTbl[] to find out how many ones are set in a given byte. Note that the size of .OSEventTbl[] is established by the #define constant OS_EVENT_TBL_SIZE (see ).
Arguments
pevent is a pointer to the message queue. This pointer is returned to your application when the queue is created (see
OSQCreate()).
pdata is a pointer to a data structure of type OS_Q_DATA which contains the following fields.
void |
*OSMsg; |
/* Next message if one available |
*/ |
|
INT16U |
OSNMsgs; |
/* |
Number of messages in the queue |
*/ |
INT16U |
OSQSize; |
/* |
Size of the message queue |
*/ |
INT8U |
OSEventTbl[OS_EVENT_TBL_SIZE]; /* Message queue wait list |
*/ |
||
INT8U |
OSEventGrp; |
|
|
|
Returned Value
OSQQuery() returns one of these two error codes:
1)OS_NO_ERR, if the call was successful
2)OS_ERR_EVENT_TYPE, if you didn’t pass a pointer to a message queue
Notes/Warnings
Message queues must be created before they are used.
Example
In this example, we check the contents of the message queue to see how many tasks are waiting for it.
OS_EVENT *CommQ;
void Task (void *pdata) |
|
|
{ |
|
|
OS_Q_DATA qdata; |
|
|
INT8U |
err; |
|
INT8U |
nwait; |
/* Number of tasks waiting on queue */ |
INT8U |
i; |
|
pdata = pdata; for (;;) {
.
.
err = OSQQuery(CommQ, &qdata); if (err == OS_NO_ERR) {
nwait = 0; /* Count # tasks waiting on queue */ if (qdata.OSEventGrp != 0x00) {
for (i = 0; i < OS_EVENT_TBL_SIZE; i++) { nwait += OSNBitsTbl[qdata.OSEventTbl[i]];
}
}
}
.
.
}
}
OSSchedLock()
void OSSchedLock(void);
File |
Called from |
Code enabled by |
OS_CORE.C |
Task or ISR |
N/A |
OSSchedLock() is used to prevent task rescheduling until its counterpart, OSSchedUnlock(), is called. The task which calls OSSchedLock() keeps control of the CPU even though other higher priority tasks are ready to run. However, interrupts will still be recognized and serviced (assuming interrupts are enabled). OSSchedLock() and OSSchedUnlock() must be used in pair. µC/OS-II allows OSSchedLock() to be nested up to 254 levels deep. Scheduling is enabled when an equal number of OSSchedUnlock() calls have been made.
Arguments
NONE
Returned Value
NONE
Notes/Warnings
After calling OSSchedLock(), you application must not make any system call which will suspend execution of the current task i.e., your application cannot call OSTimeDly(), OSTimeDlyHMSM(), OSSemPend(), OSMboxPend() or OSQPend(). Since the scheduler is locked out, no other task will be allowed to run and your system will lock up.
Example
void TaskX(void *pdata) |
|
|
{ |
|
|
pdata = pdata; |
|
|
for (;;) { |
|
|
. |
|
|
OSSchedLock(); |
/* Prevent other tasks to run |
*/ |
. |
/* Code protected from context switch */ |
|
. |
||
. |
|
|
OSSchedUnlock(); |
/* Enable other tasks to run |
*/ |
. |
|
|
}
}
OSSchedUnlock()
void OSSchedUnlock(void);
File |
Called from |
Code enabled by |
OS_CORE.C |
Task or ISR |
N/A |
OSSchedUnlock() is used to re -enable task scheduling. OSSchedUnlock() is used with OSSchedLock() in pair. Scheduling is enabled when an equal number of OSSchedUnlock() as OSSchedLock() have been made.
Arguments
NONE
Returned Value
NONE
Notes/Warnings
After calling OSSchedLock(), you application must not make any system call which will suspend execution of the current task i.e., your application cannot call OSTimeDly(), OSTimeDlyHMSM(), OSSemPend(), OSMboxPend() or OSQPend(). Since the scheduler is locked out, no other task will be allowed to run and your system will lock up.
Example
void TaskX(void *pdata) |
|
|
{ |
|
|
pdata = pdata; |
|
|
for (;;) { |
|
|
. |
|
|
OSSchedLock(); |
/* Prevent other tasks to run |
*/ |
. |
|
|
. |
/* Code protected from context switch */ |
|
. |
|
|
OSSchedUnlock(); |
/* Enable other tasks to run |
*/ |
. |
|
|
} |
|
|
} |
|
|