(原創) 如何傳參數到每個task? (SOC) (Nios II) (μC/OS-II) (DE2-70)

Abstract
當我們在μC/OS-II使用Multi Thread時,會將程式包在task內,但要如何將參數傳到task內呢?

Introduction
使用環境:Quartus II 8.1 + Nios II EDS 8.1 + DE2-70(Cyclone II EP2C35F627C6)

當我們想利用μC/OS-II的Multi Thread功能時,我們會使用Nios II EDS內建的Hello MicroC/OS-II project template

task01

他會產生如下的code

hello_ucosii.c / C

1  #include < stdio.h >
2  #include " includes.h "
3 
4  /* Definition of Task Stacks */
5  #define    TASK_STACKSIZE       2048
6  OS_STK    task1_stk[TASK_STACKSIZE];
7  OS_STK    task2_stk[TASK_STACKSIZE];
8 
9  /* Definition of Task Priorities */
10 
11  #define TASK1_PRIORITY      1
12  #define TASK2_PRIORITY      2
13 
14  /* Prints "Hello World" and sleeps for three seconds */
15  void task1( void * pdata)
16  {
17    while ( 1 )
18    {
19      printf( " Hello from task1\n " );
20      OSTimeDlyHMSM( 0 , 0 , 3 , 0 );
21    }
22  }
23  /* Prints "Hello World" and sleeps for three seconds */
24  void task2( void * pdata)
25  {
26    while ( 1 )
27    {
28      printf( " Hello from task2\n " );
29      OSTimeDlyHMSM( 0 , 0 , 3 , 0 );
30    }
31  }
32  /* The main function creates two task and starts multi-tasking */
33  int main( void )
34  {
35   
36    OSTaskCreateExt(task1,
37                    NULL,
38                    ( void   * ) & task1_stk[TASK_STACKSIZE - 1 ],
39                    TASK1_PRIORITY,
40                    TASK1_PRIORITY,
41                    task1_stk,
42                    TASK_STACKSIZE,
43                    NULL,
44                    0 );
45               
46                
47    OSTaskCreateExt(task2,
48                    NULL,
49                    ( void   * ) & task2_stk[TASK_STACKSIZE - 1 ],
50                    TASK2_PRIORITY,
51                    TASK2_PRIORITY,
52                    task2_stk,
53                    TASK_STACKSIZE,
54                    NULL,
55                    0 );
56    OSStart();
57    return   0 ;
58  }


假如我們想從main()傳參數到task1或task2,你可能會發現不知道該怎麼傳,主要task1與task2是個callback,是由μC/OS-II所呼叫,並不是由main()去呼叫,就算你自己替task1增加1個參數如下

void task1( void * pdata, int i)
{
 
while ( 1 )
  {
    printf(
" Hello from task1\n " );
    OSTimeDlyHMSM(
0 , 0 , 3 , 0 );
  }
}


還是會發現這個int i不知道要怎麼傳進去…。

Solution
你可能有發現 void *pdata這個參數,對!!這就是μC/OS-II所留下的後門。

根據http://www.rabbit.com/documentation/docs/modules/ucos2/ModUcos49.htm

OSTaskCreateExt()這個API的定義如下

INT8U OSTaskCreateExt (void (*task)(), void *pdata, INT8U prio, INT16U id, INT16U stk_size, void *pext, INT16U opt);

Description

Creates a task to be managed by µC/OS-II. 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.

 

Parameters
task
Pointer to task's code.
pdata
Pointer to optional data area; used to pass parameters to the task at start of execution.
prio
The task's unique priority number; the lower the number the higher the priority.
id
The task's identification number (0...65535).
stk_size
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
Pointer to a user-supplied Task Control Block (TCB) extension.
opt
The lower 8 bits are reserved by µC/OS-II. The upper 8 bits control application-specific options. Select an option by setting the corresponding bit(s).
Return value
OS_NO_ERR
The call was successful.
OS_PRIO_EXIT
Task priority already exists (each task MUST have a unique priority).
OS_PRIO_INVALID
The priority specified is higher than the maximum allowed (i.e., ≥ OS_LOWEST_PRIO).
Library

OS_TASK.C

第二個參數是個void *,讓你可以傳各種參數的pointer進去,但也由於是void *,所以在使用時,必須自己轉型回來。

以下的範例實際傳入int, char *與struct *,示範怎麼將值傳進task內。

hello_ucosii.c / C

1  #include < stdio.h >
2  #include < string .h >
3  #include " includes.h "
4 
5  /* Definition of Task Stacks */
6  #define    TASK_STACKSIZE       2048
7  OS_STK    task1_stk[TASK_STACKSIZE];
8  OS_STK    task2_stk[TASK_STACKSIZE];
9  OS_STK    task3_stk[TASK_STACKSIZE];
10 
11  /* Definition of Task Priorities */
12 
13  #define TASK1_PRIORITY      1
14  #define TASK2_PRIORITY      2
15  #define TASK3_PRIORITY      3
16 
17  typedef struct people {
18    int no;
19    char name[ 20 ];
20  } student, * pstudent;
21 
22  /* Prints "Hello World" and sleeps for three seconds */
23  void task1( void * pdata)
24  {
25    while ( 1 )
26    {
27      printf( " task1 is %s\n " , ( char   * )pdata);
28      OSTimeDlyHMSM( 0 , 0 , 3 , 0 );
29    }
30  }
31  /* Prints "Hello World" and sleeps for three seconds */
32  void task2( void * pdata)
33  {
34    while ( 1 )
35    {
36      printf( " task2 is %d\n " , * (( int   * )pdata));
37      OSTimeDlyHMSM( 0 , 0 , 3 , 0 );
38    }
39  }
40 
41  /* Prints "Hello World" and sleeps for three seconds */
42  void task3( void * pdata)
43  {
44    while ( 1 )
45    {
46      printf( " task3 is %d\n " , ((pstudent)pdata) -> no);
47      printf( " task3 is %s\n " , ((pstudent)pdata) -> name);
48      OSTimeDlyHMSM( 0 , 0 , 3 , 0 );
49    }
50  }
51  /* The main function creates two task and starts multi-tasking */
52  int main( void )
53  {
54    char str[] =   " Hello World " ;
55    int i =   10 ;
56    student p;
57    p.no =   1 ;
58    strcpy(p.name, " oomusou " );
59   
60   
61    OSTaskCreateExt(task1,
62                    str,
63                    ( void   * ) & task1_stk[TASK_STACKSIZE - 1 ],
64                    TASK1_PRIORITY,
65                    TASK1_PRIORITY,
66                    task1_stk,
67                    TASK_STACKSIZE,
68                    NULL,
69                    0 );
70               
71                
72    OSTaskCreateExt(task2,
73                    & i,
74                    ( void   * ) & task2_stk[TASK_STACKSIZE - 1 ],
75                    TASK2_PRIORITY,
76                    TASK2_PRIORITY,
77                    task2_stk,
78                    TASK_STACKSIZE,
79                    NULL,
80                    0 );
81                   
82                 
83    OSTaskCreateExt(task3,
84                    & p,
85                    ( void   * ) & task3_stk[TASK_STACKSIZE - 1 ],
86                    TASK3_PRIORITY,
87                    TASK3_PRIORITY,
88                    task3_stk,
89                    TASK_STACKSIZE,
90                    NULL,
91                    0 );                 
92    OSStart();
93    return   0 ;
94  }


執行結果

task02

task1示範怎麼傳遞字串,由於字串本身就是pointer,所以比較單純。task2示範如何傳遞int,task3示範如何傳struct,這兩個都必須另外使用&取pointer值。

傳進去後,由於接的是void *pdata,要另外轉型成各自型別的pointer,才能夠繼續使用。

完整程式碼下載
DE2_70_NIOS_pass_data_to_task.7z

Conclusion
這是C語言比較進階的部分,用到了callback、function pointer與void *等概念,也學到了若要使用callback時,可以設計void *的方式,讓各種型別的參數都能傳進去。

Reference
http://www.rabbit.com/documentation/docs/modules/ucos2/ModUcos49.htm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值