安德鲁

[笔记].怎样给μC/OS-II的任务传递参数.[C][μC/OS-II]

0
阅读(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 voidtask1(void* pData);// 任务1:传递整型参数
020 voidtask2(void* pData);// 任务2:传递字符参数
021 voidtask3(void* pData);// 任务3:传递字符串参数
022 voidtask4(void* pData);// 任务4:传递结构体参数
023
024 // 定义结构体
025 typedefstruct
026 {
027 intiA;
028 charcB;
029 charsC[10];
030 }myStruct_t;
031
032 intmain()
033 {
034 //
035 intiA=5;
036 //
037 charcB ='t';
038 //
039 charsC[] ="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 return0;
092 }
093
094 // 任务1:传递整型参数
095 voidtask1(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 voidtask2(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 voidtask3(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 voidtask4(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中所传参数的存储映射

表达式 存储地址 存储长度 存储内容
intiA=5; &iA sizeof(int) 5
void* pData 不变 未知 未知
*((int*)pData) 不变 sizeof(int) 5

任务2的字符参数与任务1的整型参数类似,如表2所示。

表达式 存储地址 存储长度 存储内容
charcB ='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

Baidu
map