安德鲁

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

0
阅读(2454)

0 引子

近日,我在萧大哥的博客里闲逛,渐知μC/OS-II用途甚广,使用方便;于是 就照虎画猫,写几篇博文。

 

1 范例

(1) ucos_ii_test.c

001 #include <stdio.h>
002 #include <string.h>
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