📄 os_task.c
字号:
/*********************************************************************************************************** uC/OS-II* The Real-Time Kernel* TASK MANAGEMENT** (c) Copyright 1992-2001, Jean J. Labrosse, Weston, FL* All Rights Reserved** File : OS_TASK.C* By : Jean J. Labrosse**********************************************************************************************************/#ifndef OS_MASTER_FILE#include "includes.h"#endif/*********************************************************************************************************** CHANGE PRIORITY OF A TASK** Description: This function allows you to change the priority of a task dynamically. Note that the new* priority MUST be available.** Arguments : oldp is the old priority** newp is the new priority** Returns : OS_NO_ERR is the call was successful* OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed* (i.e. >= OS_LOWEST_PRIO)* OS_PRIO_EXIST if the new priority already exist.* OS_PRIO_ERR there is no task with the specified OLD priority (i.e. the OLD task does* not exist.**********************************************************************************************************/#if OS_TASK_CHANGE_PRIO_EN > 0INT8U OSTaskChangePrio (INT8U oldprio, INT8U newprio){#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr;#endif#if OS_EVENT_EN > 0 OS_EVENT *pevent;#endif OS_TCB *ptcb; INT8U x; INT8U y; INT8U bitx; INT8U bity;#if OS_ARG_CHK_EN > 0 if ((oldprio >= OS_LOWEST_PRIO && oldprio != OS_PRIO_SELF) || newprio >= OS_LOWEST_PRIO) { return (OS_PRIO_INVALID); }#endif OS_ENTER_CRITICAL(); if (OSTCBPrioTbl[newprio] != (OS_TCB *)0) { /* New priority must not already exist */ OS_EXIT_CRITICAL(); return (OS_PRIO_EXIST); } else { OSTCBPrioTbl[newprio] = (OS_TCB *)1; /* Reserve the entry to prevent others */ OS_EXIT_CRITICAL(); y = newprio >> 3; /* Precompute to reduce INT. latency */ bity = OSMapTbl[y]; x = newprio & 0x07; bitx = OSMapTbl[x]; OS_ENTER_CRITICAL(); if (oldprio == OS_PRIO_SELF) { /* See if changing self */ oldprio = OSTCBCur->OSTCBPrio; /* Yes, get priority */ } if ((ptcb = OSTCBPrioTbl[oldprio]) != (OS_TCB *)0) { /* Task to change must exist */ OSTCBPrioTbl[oldprio] = (OS_TCB *)0; /* Remove TCB from old priority */ if ((OSRdyTbl[ptcb->OSTCBY] & ptcb->OSTCBBitX) != 0x00) { /* If task is ready make it not */ if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) { OSRdyGrp &= ~ptcb->OSTCBBitY; } OSRdyGrp |= bity; /* Make new priority ready to run */ OSRdyTbl[y] |= bitx;#if OS_EVENT_EN > 0 } else { if ((pevent = ptcb->OSTCBEventPtr) != (OS_EVENT *)0) { /* Remove from event wait list */ if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) { pevent->OSEventGrp &= ~ptcb->OSTCBBitY; } pevent->OSEventGrp |= bity; /* Add new priority to wait list */ pevent->OSEventTbl[y] |= bitx; }#endif } OSTCBPrioTbl[newprio] = ptcb; /* Place pointer to TCB @ new priority */ ptcb->OSTCBPrio = newprio; /* Set new task priority */ ptcb->OSTCBY = y; ptcb->OSTCBX = x; ptcb->OSTCBBitY = bity; ptcb->OSTCBBitX = bitx; OS_EXIT_CRITICAL(); OS_Sched(); /* Run highest priority task ready */ return (OS_NO_ERR); } else { OSTCBPrioTbl[newprio] = (OS_TCB *)0; /* Release the reserved prio. */ OS_EXIT_CRITICAL(); return (OS_PRIO_ERR); /* Task to change didn't exist */ } }}#endif/*$PAGE*//*********************************************************************************************************** CREATE A TASK** Description: This function is used to have uC/OS-II manage the execution of a task. Tasks can either* be created prior to the start of multitasking or by a running task. A task cannot be* created by an ISR.** Arguments : task is a pointer to the task's code** pdata is a pointer to an optional data area which can be used to pass parameters to* the task when the task first executes. Where the task is concerned it thinks* it was invoked and passed the argument 'pdata' as follows:** void Task (void *pdata)* {* for (;;) {* Task code;* }* }** ptos is a pointer to the task's top of stack. If the configuration constant* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high* memory to low memory). 'pstk' will thus point to the highest (valid) memory* location of the stack. If OS_STK_GROWTH is set to 0, 'pstk' will point to the* lowest memory location of the stack and the stack will grow with increasing* memory locations.** prio is the task's priority. A unique priority MUST be assigned to each task and the* lower the number, the higher the priority.** Returns : OS_NO_ERR if the function was successful.* OS_PRIO_EXIT if the task priority already exist* (each task MUST have a unique priority).* OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed* (i.e. >= OS_LOWEST_PRIO)**********************************************************************************************************/#if OS_TASK_CREATE_EN > 0INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio){#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr;#endif OS_STK *psp; INT8U err;#if OS_ARG_CHK_EN > 0 if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */ return (OS_PRIO_INVALID); }#endif 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 = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0); /* Initialize the task's stack */ err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0); if (err == OS_NO_ERR) { OS_ENTER_CRITICAL(); OSTaskCtr++; /* Increment the #tasks counter */ OS_EXIT_CRITICAL(); if (OSRunning == TRUE) { /* Find highest priority task if multitasking has started */ OS_Sched(); } } else { OS_ENTER_CRITICAL(); OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others */ OS_EXIT_CRITICAL(); } return (err); } OS_EXIT_CRITICAL(); return (OS_PRIO_EXIST);}#endif/*$PAGE*//*********************************************************************************************************** CREATE A TASK (Extended Version)** Description: This function is used to have uC/OS-II manage the execution of a task. Tasks can either* be created prior to the start of multitasking or by a running task. A task cannot be* created by an ISR. This function is similar to OSTaskCreate() except that it allows* additional information about a task to be specified.** Arguments : task is a pointer to the task's code** pdata is a pointer to an optional data area which can be used to pass parameters to* the task when the task first executes. Where the task is concerned it thinks* it was invoked and passed the argument 'pdata' as follows:** void Task (void *pdata)* {* for (;;) {* Task code;* }* }** ptos is a pointer to the task's top of stack. If the configuration constant* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high* memory to low memory). 'pstk' will thus point to the highest (valid) memory* location of the stack. If OS_STK_GROWTH is set to 0, 'pstk' will point to the* lowest memory location of the stack and the stack will grow with increasing* memory locations. 'pstk' MUST point to a valid 'free' data item.** prio is the task's priority. A unique priority MUST be assigned to each task and the* lower the number, the higher the priority.** id is the task's ID (0..65535)** pbos is a pointer to the task's bottom of stack. If the configuration constant* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high* memory to low memory). 'pbos' will thus point to the LOWEST (valid) memory* location of the stack. If OS_STK_GROWTH is set to 0, 'pbos' will point to the* HIGHEST memory location of the stack and the stack will grow with increasing* memory locations. 'pbos' MUST point to a valid 'free' data item.** stk_size is the size of the stack in number of elements. If OS_STK is set to INT8U,* 'stk_size' corresponds to the number of bytes available. If OS_STK is set to* INT16U, 'stk_size' contains the number of 16-bit entries available. Finally, if* OS_STK is set to INT32U, 'stk_size' contains the number of 32-bit entries* available on the stack.** pext is a pointer to a user supplied memory location which is used as a TCB extension.* For example, this user memory can hold the contents of floating-point registers* during a context switch, the time each task takes to execute, the number of times* the task has been switched-in, etc.** opt contains additional information (or options) about the behavior of the task. The* LOWER 8-bits are reserved by uC/OS-II while the upper 8 bits can be application
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -