- •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()
pdata is a pointer to a variable of type OS_STK_DATA which contains the following fields.
INT32U |
OSFree; |
/* |
Number |
of |
bytes |
free |
on |
the |
stack |
*/ |
INT32U |
OSUsed; |
/* |
Number |
of |
bytes |
used |
on |
the |
stack |
*/ |
Returned Value
OSTaskStkChk() returns one of the following error codes:
1)OS_NO_ERR, if you specified valid arguments and the call was successful.
2)OS_PRIO_INVALID, if you specified a task priority higher than OS_LOWEST_PRIO, or you didn’t specify OS_PRIO_SELF.
3)OS_TASK_NOT_EXIST, if the specified task does not exist.
4)OS_TASK_OPT_ERR, if you did not specify OS_TASK_OPT_STK_CHK when the task was created by
OSTaskCreateExt() or, you created the task by using OSTaskCreate().
Notes/Warnings
Execution time of this task depends on the size of the task’s stack and is thus non -deterministic.
Your application can determine the total task stack space (in number of bytes) by adding the two fields .OSFree and .OSUsed.
Technically, this function can be called by an ISR but, because of the possibly long execution time, it is not advisable.
Example
void Task (void *pdata)
{
OS_STK_DATA stk_data; INT32U stk_size;
for (;;) {
.
.
err = OSTaskStkChk(10, &stk_data); if (err == OS_NO_ERR) {
stk_size = stk_data.OSFree + stk_data.OSUsed;
}
.
.
}
}
OSTaskSuspend()
INT8U OSTaskSuspend(INT8U prio);
File |
Called from |
Code enabled by |
OS_TASK.C |
Task only |
OS_TASK_SUSPEND_EN |
OSTaskSuspend() allows your application to suspend (or block) execution of a task unconditionally. The calling task can be suspended by specifying its own priority number or OS_PRIO_SELF if the task doesn't know its own priority number. In this case, another task will need to resume the suspended task. If the current task is suspended, rescheduling will occur and µC/OS-II will run the next highest priority task ready to run. The only way to resume a suspended task is to call OSTaskResume().
Task suspension is additive. This means that if the task being suspended is delayed until ‘n’ticks expire then the task will be resumed only when both the time expires and the suspension is removed. Also, if the suspended task is waiting for a semaphore and the semaphore is signaled then the task will be removed from the semaphore wait list (if it was the highest priority task waiting for the semaphore) but execution will not be resumed until the suspension is removed.
Arguments
prio specifies the priority of the task to suspend. You can suspend the calling task by passing OS_PRIO_SELF in which case, the next highest priority task will be executed.
Returned Value
OSTaskSuspend() returns one of the following error codes:
1)OS_NO_ERR, if the call was successful.
2)OS_TASK_SUSPEND_IDLE, if you attempted to suspend µC/OS-II’s idle task. This is of course not allowed.
3)OS_PRIO_INVALID, if you specified a priority higher than the maximum allowed (i.e. you specified a priority >= OS_LOWEST_PRIO) or, you didn't specify OS_PRIO_SELF.
4)OS_TASK_SUSPEND_PRIO, if the task you are attempting to suspend does not exist.
Notes/Warnings
OSTaskSuspend() and OSTaskResume() must be used in pair.
A suspended task can only be resumed by OSTaskResume().
Example
void TaskX(void *pdata)
{
INT8U err; |
|
|
|
for (;;) { |
|
|
|
. |
|
|
|
. |
|
|
|
err = OSTaskSuspend(OS_PRIO_SELF); |
/* Suspend current task |
*/ |
|
. |
/* Execution continues when ANOTHER task .. |
*/ |
|
. |
/* .. explicitly resumes this task. |
*/ |
|
. |
|
|
|
}
}
OSTaskQuery()
INT8U OSTaskQuery(INT8U prio, OS_TCB *pdata);
File |
Called from |
Code enabled by |
OS_TASK.C |
Task or ISR |
N/A |
OSTaskQuery() allows your application to obtain information about a task. Your application must allocate an OS_TCB data structure that will be used to receive a ‘snapshot’of the desired task’s control block. Your copy will contain every field in the OS_TCB structure. You should be careful when accessing the contents of the OS_TCB structure, especially OSTCBNext and OSTCBPrev because they will point to the next and previous OS_TCB in the chain of created tasks, respectively.
Arguments
prio is the priority of the task you wish to obtain data from. You can obtain information about the calling task by specifying OS_PRIO_SELF.
pdata is a pointer to a structure of type OS_TCB which will contain a copy of the task’s control block.
Returned Value
OSTaskQuery() returns one of these two error codes:
1)OS_NO_ERR, if the call was successful.
2)OS_PRIO_ERR, if you are trying to obtain information from an invalid task.
Notes/Warnings
The available fields in the task control block depends on the following configuration options (see OS_CFG.H):
OS_TASK_CREATE_EN
OS_Q_EN
OS_MBOX_EN
OS_SEM_EN
OS_TASK_DEL_EN
Example
void Task (void *pdata)
{
OS_TCB task_data; INT8U err;
void *pext; INT8U status;
pdata = pdata; for (;;) {
.
.
err = OSTaskQuery(OS_PRIO_SELF, &task_data);
if (err == OS_NO_ERR) { |
|
|
|
pext |
= task_data.OSTCBExtPtr; /* Get TCB extension pointer |
*/ |
|
status = task_data.OSTCBStat; |
/* Get task status |
*/ |
|
. |
|
|
|
. |
|
|
|
} |
|
|
|
. |
|
|
|
. |
|
|
|
} |
|
|
|
} |
|
|
|
OSTimeDly()
void OSTimeDly(INT16U ticks);
File |
Called from |
Code enabled by |
OS_TIME.C |
Task only |
N/A |
OSTimeDly() allows a task to delay itself for a number of clock ticks. Rescheduling always occurs when the number of clock ticks is greater than zero. Valid delays range from 0 to 65535 ticks. A delay of 0 means that the task will not be delayed and OSTimeDly() will return immediately to the caller. The actual delay time depends on the tick rate (see OS_TICKS_PER_SEC in the configuration file OS_CFG.H).
Arguments
ticks is the number of clock ticks to delay the current task.
Returned Value
NONE
Notes/Warnings
Note that calling this function with a delay of 0 results in no delay and thus the function returns immediately to the caller. To ensure that a task delays for the specified number of ticks, you should consider using a delay value that is one tick higher. For example, to delay a task for at least 10 ticks, you should specify a value of 11.
Example
void TaskX(void *pdata) |
|
{ |
|
for (;;) { |
|
. |
|
. |
|
OSTimeDly(10); |
/* Delay task for 10 clock ticks */ |
. |
|
. |
|