zoukankan      html  css  js  c++  java
  • [笔记].怎样给μC/OSII的任务传递参数

    0 引子

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

    1 范例

    (1) ucos_ii_test.c

    #include <stdio.h>
    #include <string.h>
    #include "includes.h"
    
    // 定义任务的栈
    #define   TASK_STACKSIZE       2048
    OS_STK    task1_stk[TASK_STACKSIZE];
    OS_STK    task2_stk[TASK_STACKSIZE];
    OS_STK    task3_stk[TASK_STACKSIZE];
    OS_STK    task4_stk[TASK_STACKSIZE];
    
    // 定义任务的优先级
    #define TASK1_PRIORITY      1
    #define TASK2_PRIORITY      2
    #define TASK3_PRIORITY      3
    #define TASK4_PRIORITY      4
    
    // 声明任务
    void task1(void* pData);                // 任务1:传递整型参数
    void task2(void* pData);                // 任务2:传递字符参数
    void task3(void* pData);                // 任务3:传递字符串参数
    void task4(void* pData);                // 任务4:传递结构体参数
    
    // 定义结构体
    typedef struct
    {
      int  iA;
      char cB;
      char sC[10];
    }myStruct_t;
    
    int main()
    {
      //
      int iA=5;
      //
      char cB = 't';
      //
      char sC[] = "test";
      //
      myStruct_t pStr;
      pStr.iA = 5;
      pStr.cB = 't';
      strcpy(pStr.sC, "test");
    
      // 任务1:传递整型参数
      OSTaskCreateExt(task1,
                      &iA,
                      (void *)&task1_stk[TASK_STACKSIZE-1],
                      TASK1_PRIORITY,
                      TASK1_PRIORITY,
                      task1_stk,
                      TASK_STACKSIZE,
                      NULL,
                      0);
    
      // 任务2:传递字符参数
      OSTaskCreateExt(task2,
                      &cB,
                      (void *)&task2_stk[TASK_STACKSIZE-1],
                      TASK2_PRIORITY,
                      TASK2_PRIORITY,
                      task2_stk,
                      TASK_STACKSIZE,
                      NULL,
                      0);
    
      // 任务3:传递字符串参数
      OSTaskCreateExt(task3,
                      sC,
                      (void *)&task3_stk[TASK_STACKSIZE-1],
                      TASK3_PRIORITY,
                      TASK3_PRIORITY,
                      task3_stk,
                      TASK_STACKSIZE,
                      NULL,
                      0);
    
      // 任务4:传到结构体参数
      OSTaskCreateExt(task4,
                      &pStr,
                      (void *)&task4_stk[TASK_STACKSIZE-1],
                      TASK4_PRIORITY,
                      TASK4_PRIORITY,
                      task4_stk,
                      TASK_STACKSIZE,
                      NULL,
                      0);
    
      OSStart();
      return 0;
    }
    
    // 任务1:传递整型参数
    void task1(void* pData)
    {
      while (1)
      {
        printf("task1, iA = %d\n", *((int *)pData));
        OSTimeDlyHMSM(0, 0, 1, 0);
      }
    }
    
    // 任务2:传递字符参数
    void task2(void* pData)
    {
      while (1)
      {
        printf("task2, cB = %c\n", *((char *)pData));
        OSTimeDlyHMSM(0, 0, 1, 0);
      }
    }
    
    // 任务3:传递字符串参数
    void task3(void* pData)
    {
      while (1)
      {
        printf("task3, sC = %s\n", (char *)pData);
        OSTimeDlyHMSM(0, 0, 1, 0);
      }
    }
    
    // 任务4:传递结构体参数
    void task4(void* pData)
    {
      while (1)
      {
        printf("task4, iA = %i\n", ((myStruct_t *)pData)->iA);
        printf("task4, cB = %c\n", ((myStruct_t *)pData)->cB);
        printf("task4, sC = %s\n", ((myStruct_t *)pData)->sC);
        OSTimeDlyHMSM(0, 0, 1, 0);
      }
    }

    (2)运行结果

    image

    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() 源代码

    /*
    *********************************************************************************************************
    *                                     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
    *                       specific.  See OS_TASK_OPT_??? in uCOS-II.H.
    *
    * 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)
    *********************************************************************************************************
    */
    INT8U  OSTaskCreateExt (void   (*task)(void *pd),
                            void    *pdata,
                            OS_STK  *ptos,
                            INT8U    prio,
                            INT16U   id,
                            OS_STK  *pbos,
                            INT32U   stk_size,
                            void    *pext,
                            INT16U   opt)
    {
    #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();
    
            if (((opt & OS_TASK_OPT_STK_CHK) != 0x0000) ||   /* See if stack checking has been enabled     */
                ((opt & OS_TASK_OPT_STK_CLR) != 0x0000)) {   /* See if stack needs to be cleared           */
                #if OS_STK_GROWTH == 1
                (void)memset(pbos, 0, stk_size * sizeof(OS_STK));
                #else
                (void)memset(ptos, 0, stk_size * sizeof(OS_STK));
                #endif
            }
    
            psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, opt); /* Initialize the task's stack          */
            err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt);
            if (err == OS_NO_ERR) {
                OS_ENTER_CRITICAL();
                OSTaskCtr++;                                       /* Increment the #tasks counter         */
                OS_EXIT_CRITICAL();
                if (OSRunning == TRUE) {                           /* Find HPT if multitasking has started */
                    OS_Sched();
                }
            } else {
                OS_ENTER_CRITICAL();
                OSTCBPrioTbl[prio] = (OS_TCB *)0;                  /* Make this priority avail. to others  */
                OS_EXIT_CRITICAL();
            }
            return (err);
        }
        OS_EXIT_CRITICAL();
        return (OS_PRIO_EXIST);
    }

     

    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

  • 相关阅读:
    window下安装jupyter,ipython的方法
    虚拟机中,安装VM tools的小发现
    Perl 与 Python 之间的一些异同
    perl中的grep函数介绍
    基因芯片(Affymetrix)分析1:芯片质量分析
    议员是如何投票的?
    社会网络分析:探索人人网好友推荐系统
    支持向量机(一)
    主成分分析(Principal components analysis)-最小平方误差解释
    因子分析(Factor Analysis)
  • 原文地址:https://www.cnblogs.com/yuphone/p/1731532.html
Copyright © 2011-2022 走看看