[笔记].怎样给μC/OS-II的任务传递参数.[C][μC/OS-II]
0赞
发表于 2010/6/21 15:19:41
阅读(2285)
0 引子
近日,我在萧大哥的博客里闲逛,渐知μC/OS-II用途甚广,使用方便;于是 就照虎画猫,写几篇博文。
1 范例
(1) ucos_ii_test.c
001 |
#include |
002 |
#include |
003 |
#include "includes.h" |
004 |
005 |
// 定义任务的栈 |
006 |
#define TASK_STACKSIZE 2048 |
007 |
OS_STK task1_stk[TASK_STACKSIZE]; |
008 |
OS_STK task2_stk[TASK_STACKSIZE]; |
009 |
OS_STK task3_stk[TASK_STACKSIZE]; |
010 |
OS_STK task4_stk[TASK_STACKSIZE]; |
011 |
012 |
// 定义任务的优先级 |
013 |
#define TASK1_PRIORITY 1 |
014 |
#define TASK2_PRIORITY 2 |
015 |
#define TASK3_PRIORITY 3 |
016 |
#define TASK4_PRIORITY 4 |
017 |
018 |
// 声明任务 |
019 |
void task1( void * pData); // 任务1:传递整型参数 |
020 |
void task2( void * pData); // 任务2:传递字符参数 |
021 |
void task3( void * pData); // 任务3:传递字符串参数 |
022 |
void task4( void * pData); // 任务4:传递结构体参数 |
023 |
024 |
// 定义结构体 |
025 |
typedef struct |
026 |
{ |
027 |
int iA; |
028 |
char cB; |
029 |
char sC[10]; |
030 |
}myStruct_t; |
031 |
032 |
int main() |
033 |
{ |
034 |
// |
035 |
int iA=5; |
036 |
// |
037 |
char cB = 't' ; |
038 |
// |
039 |
char sC[] = "test" ; |
040 |
// |
041 |
myStruct_t pStr; |
042 |
pStr.iA = 5; |
043 |
pStr.cB = 't' ; |
044 |
strcpy (pStr.sC, "test" ); |
045 |
046 |
// 任务1:传递整型参数 |
047 |
OSTaskCreateExt(task1, |
048 |
&iA, |
049 |
( void *)&task1_stk[TASK_STACKSIZE-1], |
050 |
TASK1_PRIORITY, |
051 |
TASK1_PRIORITY, |
052 |
task1_stk, |
053 |
TASK_STACKSIZE, |
054 |
NULL, |
055 |
0); |
056 |
057 |
// 任务2:传递字符参数 |
058 |
OSTaskCreateExt(task2, |
059 |
&cB, |
060 |
( void *)&task2_stk[TASK_STACKSIZE-1], |
061 |
TASK2_PRIORITY, |
062 |
TASK2_PRIORITY, |
063 |
task2_stk, |
064 |
TASK_STACKSIZE, |
065 |
NULL, |
066 |
0); |
067 |
068 |
// 任务3:传递字符串参数 |
069 |
OSTaskCreateExt(task3, |
070 |
sC, |
071 |
( void *)&task3_stk[TASK_STACKSIZE-1], |
072 |
TASK3_PRIORITY, |
073 |
TASK3_PRIORITY, |
074 |
task3_stk, |
075 |
TASK_STACKSIZE, |
076 |
NULL, |
077 |
0); |
078 |
079 |
// 任务4:传到结构体参数 |
080 |
OSTaskCreateExt(task4, |
081 |
&pStr, |
082 |
( void *)&task4_stk[TASK_STACKSIZE-1], |
083 |
TASK4_PRIORITY, |
084 |
TASK4_PRIORITY, |
085 |
task4_stk, |
086 |
TASK_STACKSIZE, |
087 |
NULL, |
088 |
0); |
089 |
090 |
OSStart(); |
091 |
return 0; |
092 |
} |
093 |
094 |
// 任务1:传递整型参数 |
095 |
void task1( void * pData) |
096 |
{ |
097 |
while (1) |
098 |
{ |
099 |
printf ( "task1, iA = %d\n" , *(( int *)pData)); |
100 |
OSTimeDlyHMSM(0, 0, 1, 0); |
101 |
} |
102 |
} |
103 |
104 |
// 任务2:传递字符参数 |
105 |
void task2( void * pData) |
106 |
{ |
107 |
while (1) |
108 |
{ |
109 |
printf ( "task2, cB = %c\n" , *(( char *)pData)); |
110 |
OSTimeDlyHMSM(0, 0, 1, 0); |
111 |
} |
112 |
} |
113 |
114 |
// 任务3:传递字符串参数 |
115 |
void task3( void * pData) |
116 |
{ |
117 |
while (1) |
118 |
{ |
119 |
printf ( "task3, sC = %s\n" , ( char *)pData); |
120 |
OSTimeDlyHMSM(0, 0, 1, 0); |
121 |
} |
122 |
} |
123 |
124 |
// 任务4:传递结构体参数 |
125 |
void task4( void * pData) |
126 |
{ |
127 |
while (1) |
128 |
{ |
129 |
printf ( "task4, iA = %i\n" , ((myStruct_t *)pData)->iA); |
130 |
printf ( "task4, cB = %c\n" , ((myStruct_t *)pData)->cB); |
131 |
printf ( "task4, sC = %s\n" , ((myStruct_t *)pData)->sC); |
132 |
OSTimeDlyHMSM(0, 0, 1, 0); |
133 |
} |
134 |
} |
(2)运行结果
2 解析
从OSTaskCreateExt()的源代码中,可知pData就是所能传递的参数。
第48行,传递整型变量iA的地址;但是pdata却是空型指针。为了匹配存储内容,在第99行,将从&iA开始的存储区域强制转化为整型 指针,故有(
int
*)pData;使用(*)访问内容即可,如
*((
int
*)pData)
。如表1所示。
表1 task1中所传参数的存储映射
表达式 | 存储地址 | 存储长度 | 存储内容 |
int iA=5; |
&iA | sizeof(int) | 5 |
void * pData |
不变 | 未知 | 未知 |
*(( int *)pData) |
不变 | sizeof(int) | 5 |
任务2的字符参数与任务1的整型参数类似,如表2所示。
表达式 | 存储地址 | 存储长度 | 存储内容 |
char cB = 't' ; |
&cB | sizeof(char) | t |
void * pData |
不变 | 未知 | 未知 |
*(( char *)pData) |
不变 | sizeof(char) | t |
任务3中%s本身只需传入参数的地址即可,故使用(
char
*)pData将 从*pData开始的存储区域强制转化为char型指针即可。
任务4中,传入的参数是结构体,另写博文浅析。
总之,以上所谓传递的四种参数类型,皆是在在传递地址,以准确映射所在地址的存储内容。
3 附录
(1)INT8U OSTaskCreateExt() 源代码
001 |
/* |
002 |
********************************************************************************************************* |
003 |
* CREATE A TASK (Extended Version) |
004 |
* |
005 |
* Description: This function is used to have uC/OS-II manage the execution of a task. Tasks can either |
006 |
* be created prior to the start of multitasking or by a running task. A task cannot be |
007 |
* created by an ISR. This function is similar to OSTaskCreate() except that it allows |
008 |
* additional information about a task to be specified. |
009 |
* |
010 |
* Arguments : task is a pointer to the task's code |
011 |
* |
012 |
* pdata is a pointer to an optional data area which can be used to pass parameters to |
013 |
* the task when the task first executes. Where the task is concerned it thinks |
014 |
* it was invoked and passed the argument 'pdata' as follows: |
015 |
* |
016 |
* void Task (void *pdata) |
017 |
* { |
018 |
* for (;;) { |
019 |
* Task code; |
020 |
* } |
021 |
* } |
022 |
* |
023 |
* ptos is a pointer to the task's top of stack. If the configuration constant |
024 |
* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high |
025 |
* memory to low memory). 'pstk' will thus point to the highest (valid) memory |
026 |
* location of the stack. If OS_STK_GROWTH is set to 0, 'pstk' will point to the |
027 |
* lowest memory location of the stack and the stack will grow with increasing |
028 |
* memory locations. 'pstk' MUST point to a valid 'free' data item. |
029 |
* |
030 |
* prio is the task's priority. A unique priority MUST be assigned to each task and the |
031 |
* lower the number, the higher the priority. |
032 |
* |
033 |
* id is the task's ID (0..65535) |
034 |
* |
035 |
* pbos is a pointer to the task's bottom of stack. If the configuration constant |
036 |
* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high |
037 |
* memory to low memory). 'pbos' will thus point to the LOWEST (valid) memory |
038 |
* location of the stack. If OS_STK_GROWTH is set to 0, 'pbos' will point to the |
039 |
* HIGHEST memory location of the stack and the stack will grow with increasing |
040 |
* memory locations. 'pbos' MUST point to a valid 'free' data item. |
041 |
* |
042 |
* stk_size is the size of the stack in number of elements. If OS_STK is set to INT8U, |
043 |
* 'stk_size' corresponds to the number of bytes available. If OS_STK is set to |
044 |
* INT16U, 'stk_size' contains the number of 16-bit entries available. Finally, if |
045 |
* OS_STK is set to INT32U, 'stk_size' contains the number of 32-bit entries |
046 |
* available on the stack. |
047 |
* |
048 |
* pext is a pointer to a user supplied memory location which is used as a TCB extension. |
049 |
* For example, this user memory can hold the contents of floating-point registers |
050 |
* during a context switch, the time each task takes to execute, the number of times |
051 |
* the task has been switched-in, etc. |
052 |
* |
053 |
* opt contains additional information (or options) about the behavior of the task. The |
054 |
* LOWER 8-bits are reserved by uC/OS-II while the upper 8 bits can be application |
055 |
* specific. See OS_TASK_OPT_??? in uCOS-II.H. |
056 |
* |
057 |
* Returns : OS_NO_ERR if the function was successful. |
058 |
* OS_PRIO_EXIT if the task priority already exist |
059 |
* (each task MUST have a unique priority). |
060 |
* OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed |
061 |
* (i.e. > OS_LOWEST_PRIO) |
062 |
********************************************************************************************************* |
063 |
*/ |
064 |
INT8U OSTaskCreateExt ( void (*task)( void *pd), |
065 |
void *pdata, |
066 |
OS_STK *ptos, |
067 |
INT8U prio, |
068 |
INT16U id, |
069 |
OS_STK *pbos, |
070 |
INT32U stk_size, |
071 |
void *pext, |
072 |
INT16U opt) |
073 |
{ |
074 |
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ |
075 |
OS_CPU_SR cpu_sr; |
076 |
#endif |
077 |
OS_STK *psp; |
078 |
INT8U err; |
079 |
080 |
081 |
#if OS_ARG_CHK_EN > 0 |
082 |
if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */ |
083 |
return (OS_PRIO_INVALID); |
084 |
} |
085 |
#endif |
086 |
OS_ENTER_CRITICAL(); |
087 |
if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */ |
088 |
OSTCBPrioTbl[prio] = (OS_TCB *)1; /* Reserve the priority to prevent others from doing ... */ |
089 |
/* ... the same thing until task is created. */ |
090 |
OS_EXIT_CRITICAL(); |
091 |
092 |
if (((opt & OS_TASK_OPT_STK_CHK) != 0x0000) || /* See if stack checking has been enabled */ |
093 |
((opt & OS_TASK_OPT_STK_CLR) != 0x0000)) { /* See if stack needs to be cleared */ |
094 |
#if OS_STK_GROWTH == 1 |
095 |
( void ) memset (pbos, 0, stk_size * sizeof (OS_STK)); |
096 |
#else |
097 |
( void ) memset (ptos, 0, stk_size * sizeof (OS_STK)); |
098 |
#endif |
099 |
} |
100 |
101 |
psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, opt); /* Initialize the task's stack */ |
102 |
err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt); |
103 |
if (err == OS_NO_ERR) { |
104 |
OS_ENTER_CRITICAL(); |
105 |
OSTaskCtr++; /* Increment the #tasks counter */ |
106 |
OS_EXIT_CRITICAL(); |
107 |
if (OSRunning == TRUE) { /* Find HPT if multitasking has started */ |
108 |
OS_Sched(); |
109 |
} |
110 |
} else { |
111 |
OS_ENTER_CRITICAL(); |
112 |
OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Make this priority avail. to others */ |
113 |
OS_EXIT_CRITICAL(); |
114 |
} |
115 |
return (err); |
116 |
} |
117 |
OS_EXIT_CRITICAL(); |
118 |
return (OS_PRIO_EXIST); |
119 |
} |
4 参考
1.真 OO無雙.(原 創) 如何傳參數到每個task? (SOC) (Nios II) (μC/OS-II) (DE2-70)
2. Micrium.Micrium-uCOS-II-V286.ZIP\Micrium\SOFTWARE\uCOS-II\Source\os_task.c