任务的创建与运行
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验 3. 任务的创建与运行
一,实验目的:
1.观察和理解uC/OS-II启动的过程、任务的运行;
2.学习并理解uC/OS-II的两个任务创建函数的使用;
3.初步理解钩子(Hook)函数的作用;
二,任务函数
uC/OS-II提供的任务创建函数uC/OS-II中任务的主体是任务函数。为了让任务运行,必须首先在系统中创建它。uC/OS-II提供了两个创建任务的函数,
OSTaskCreate()和OSTaskCreateExt()。
1.OSTaskCreate()函数
函数原型:
INT8U OSTaskCreate( void (*task)(void *pd),
void*pdata, OS_STK *ptos, INT8U
prio);
参数的含义:
void (void *pd) 指向任务体函数的指针
数据指针,指向传给任务的数据区。通过这个指针任务函数可以从void *pada外部获
取数据。
OS_STK *ptos指向任务堆栈的栈顶(top of )的指针。
INT8U prio任务的优先级。
2.OSTaskCreateExt()函数
函数原型
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);
参数的意义:
INT16U id 任务的ID号。在uC/OS-II中并没有真正被使用到。因为每个优先级的
任务只有一个,优先级号就成了实际的任务号。但在实际工程编程时最好填上合适的标记,为以后的升级做好准备。
OS_STK *pbos指向任务堆栈的栈底(bottom of stack)的指针。
INT32U stk_size堆栈的大小。以堆栈宽度为单位。 void
*pext指向扩展数据区的指针。
注:尽量使用OSCreateTaskExt()函数来创建任务,因为这个函数具有更强的灵活性。
3.任务的堆栈
任务的所有变量都是建立在其堆栈上的。在创建任务时,设计者要对任务的内存消耗做出
充分的估计,并以此为依据为任务分配适当大小的堆栈。堆栈不足将导致任务奔溃。
在使用堆栈时,必须考虑堆栈的增长方向和栈顶是否已经保存了数据。对于不同的CPU,
其堆栈使用的策略是不同的。软件设计者要特别注意这一点。对于大部分情况,例如在我
们实验中采用的是Windows环境下的模拟或者以ARM为内核的CPU,堆栈策略是满减栈
(Full Descending)。假设我们为任务分配数组Stack[STK_SIZE]作为其堆栈,那么
初始时,其栈顶位置为&Stack[STK_SIZE-1],栈底位置为&Stack[0]。
三,任务的创建在创建任务时,要按照创建函数的要求,为任务设立各种工作条件,包括
指定任务体函数,设计堆栈,指定任务优先级等等。
本实验中包含两个任务,Task1和Task2,他们的函数体如下:
void Task1 (void *para)
{
INT8U id;
for (;;) {
OS_Printf("This is task 1.\n");
OSTimeDly(50);
}
}
void Task2 (void *para)
{
INT8U id;
for (;;) {
OS_Printf("This is task 2.\n");
OSTimeDly(70);
}
}
使用OSTaskCreateExt()创建任务的方法示例:
err = OSTaskCreateExt((void (*)(void *)) Task1,
(void *) 0,
(OS_STK *) &TaskStk1[TASK_STK_SIZE-1], (INT8U) TASK1_PRIO,
(INT16U) TASK1_PRIO,
(OS_STK *) &TaskStk1[0],
(INT32U) TASK_STK_SIZE,
(void *) 0,
(INT16U) (OS_TASK_OPT_STK_CHK |
OS_TASK_OPT_STK_CLR) );
if(err) OS_Printf(”Task creates error !\n”);
使用OSTaskCreate()创建任务的方法示例:
err = OSTaskCreate((void (*)(void *)) Task1,
(void *) 0,
(OS_STK *) &TaskStk1[TASK_STK_SIZE-1],
(INT8U) TASK1_PRIO);
if(err) OS_Printf(”Task creates error !\n”);
四,实验代码:
main.c
#include "includes.h"
# define TASK_STK_SIZE 20
# define TASK2_STK_SIZE 20
# define TASK_USERTASK_TASK_SIZE 20
//定义用户任务发生任务、任务1,2的堆栈大小全为20
# define Task2_Prio 8 //任务2优先级为8
# define Task_Prio 6 //任务1优先级为6
# define UserTask_Prio 4 //usertask优先级为4
static char *a="AAA"; //定义两个静态字符指并赋值
static char *b="BBB";
OS_STK TaskStk[TASK_STK_SIZE]; //引入堆栈
OS_STK Task2Stk[TASK2_STK_SIZE];
OS_STK UserTaskStk[TASK_USERTASK_TASK_SIZE];
void Task1(void *pParam);
void Task2(void *pParam);
void UserTask(void *pParam);//声明函数
int main(intargc,char **argv)
{
O SInit();//内核初始化
O STaskCreate(
(void (*)(void*)) UserTask,
(void*) 0,
(OS_STK *) &UserTaskStk[TASK_USERTASK_TASK_SIZE-1], (INT8U) UserTask_Prio);//创建用户任务
O SStart();//启动内核
r eturn(0);
}
void UserTask(void *pParam)//用户任务中创建两个task
{
I NT8U err1;//定义两个变量用来判断是否创建任务成功
I NT8U err2;