您的位置 首页 分销

STM32 uC/OS_II 实践 之 使命调度进程了解及查询式事情

先把入口函数main给贴出来,就从这里开始,来自文件main.c/*******************************************************************

先把进口函数main给贴出来,就从这儿开端,来自文件main.c


/*******************************************************************************
* Function Name : main
* Description : 主函数,对体系以及硬件初始化,树立主函数并敞开体系
* Input : None
* Output : None
* Return : None
*******************************************************************************/
int main(void)
{
CPU_IntDis(); // 制止CPU中止 连接到汇编
OSInit(); // uCOS体系初始化
BSP_Init(); // 硬件初始化

OSTaskCreate //树立主使命, 优先级最高 树立这个使命别的一个用处是为了今后运用计算使命
(
(void (*) (void *)) App_TaskStart, //指向使命代码的指针
(void *) 0,//使命开端履行时,传递给使命的参数的指针
(OS_STK *) &App_TaskStartStk[APP_TASK_START_STK_SIZE – 1], //分配给使命的仓库的栈顶指针,从(INT8U) APP_TASK_START_PRIO //分配给使命的优先级
);

OSTimeSet(0);
OSStart();

return(0);
}

在开端 uC/OS_II 的调度之前,咱们需求调用函数OSInit(),他担任树立使命操控块链表,安排妥当使命表等数据结构,然后初始化全局变量。然后把需求用的外部设备进行初始化,主要是时钟初始化,中止嵌套初始化,端口初始化,调用函数BSP_Init(),uC/OS_II规定在使命调度开端前至少有一个使命现已树立,所以咱们树立一个使命APP_TaskStart,而且给这个使命分配优先级以及仓库等资源这是有必要的啦,然后咱们用OSTimeSet(0)函数初始化体系的时钟节拍数后,就调用OSStart()函数开端使命调度,使命就会从一切树立的使命里最高优先级开端履行。
咱们还记得方才树立了一个APP_TaskStart使命,在体系开端使命调度的时分,体系里除了默许的优先级最低的闲暇使命外只需这一个使命被注册了,天然就会运转这个使命,咱们先来看下他的相关源代码来自文件task.c:


/*******************************************************************************
* Function Name : App_TaskStart
* Description : 主使命
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void App_TaskStart(void* p_arg)
{
(void) p_arg;

OS_CPU_SysTickInit(); // 初始化体系心跳

#if (OS_TASK_STAT_EN > 0)
OSStatInit(); // 计算使命初始化函数
#endif

App_TaskCreate(); // 创立新的用户使命

while(1)
{
LED4_HIGH;
OSTimeDlyHMSM(0,0,1,0);
LED4_LOW;
OSTimeDlyHMSM(0,0,1,0);
}

}

/*******************************************************************************
* Function Name : App_TaskCreate
* Description : 树立用户使命
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void App_TaskCreate(void)
{
//===================================================================// 测验使命1
OSTaskCreateExt(
Task_Test1,// 指向使命代码的指针,也便是使命函数名
(void *)0,// 使命开端履行时传递给使命的参数
(OS_STK *)&Task_Test1Stk[Task_Test1_STK_SIZE-1],//分配给使命仓库的栈顶指针,自顶向下
Task_Test1_PRIO,// 分配给使命的优先级
Task_Test1_PRIO,// 准备给今后版别的标识符,现在同使命优先级
(OS_STK *)&Task_Test1Stk[0], // 指向使命仓库的栈底指针,用于仓库的查验
Task_Test1_STK_SIZE, // 指定仓库的容量,用于仓库查验
(void *)0, // 指向用户附加数据域的指针,用来扩展使命操控块
OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR // 使命选项:使能仓库检测 和 创立使命时清空仓库
);
//===================================================================// 测验使命2
OSTaskCreateExt(
Task_Test2,
(void *)0,
(OS_STK *)&Task_Test2Stk[Task_Test2_STK_SIZE-1],
Task_Test2_PRIO,
Task_Test2_PRIO,
(OS_STK *)&Task_Test2Stk[0],
Task_Test2_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR
);
//===================================================================// 测验使命3
OSTaskCreateExt(
Task_Test3,
(void *)0,
(OS_STK *)&Task_Test3Stk[Task_Test3_STK_SIZE-1],
Task_Test3_PRIO,
Task_Test3_PRIO,
(OS_STK *)&Task_Test3Stk[0],
Task_Test3_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR
);
}

一起给出使命的优先级及仓库巨细等信息来自文件app_cfg.h


//使命优先级
#define APP_TASK_START_PRIO 10

#define Task_Test1_PRIO 7
#define Task_Test2_PRIO 8
#define Task_Test3_PRIO 9

//使命仓库巨细
#define APP_TASK_START_STK_SIZE 64

#define Task_Test1_STK_SIZE 128
#define Task_Test2_STK_SIZE 128
#define Task_Test3_STK_SIZE 128

能够看到,使命APP_TaskStart的优先级最低,所以在这个使命里创立其他的使命的时分他就会被更高优先级的使命把CPU的占有权抢去,在uC/OS_II里每树立一个使命后都会发生一次使命的调度,假如这个树立的使命优先级更高,则体系就会去履行这个刚创立的使命,假如低就只能等着了。所以在树立Task_Test1使命后,就会跳转履行此使命,现在咱们来看下这三个测验使命的源代码来自文件app.c    


/*******************************************************************************
* Function Name : Task_Test1
* Description : 使命1
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void Task_Test1(void* p_arg)
{
(void) p_arg ;
while(1)
{
if(KEY_WKUP == 0)
{
LED1_HIGH;
}
else
{
LED1_LOW;
}
OSTimeDlyHMSM(0,0,0,100); // 延时,为其他低优先级的使命履行留有空间
}
}
/*******************************************************************************
* Function Name : Task_Test2
* Description : 使命2
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void Task_Test2(void* p_arg)
{
(void) p_arg ;
while(1)
{
LED2_HIGH;
OSTimeDlyHMSM(0,0,0,500);
LED2_LOW;
OSTimeDlyHMSM(0,0,0,500);
}
}
/*******************************************************************************
* Function Name : Task_Test3
* Description : 使命3
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void Task_Test3(void* p_arg)
{
(void) p_arg ;
while(1)
{
LED3_HIGH;
OSTimeDlyHMSM(0,0,0,500);
LED3_LOW;
OSTimeDlyHMSM(0,0,0,500);
}
}

方才提到哪里了?对,现在开端履行Task_Test1的使命了,很显然,这个使命是对一个按键的检测,检测完成后进入一个100ms的延时函数,在uC/OS_II里延时函数的作用要比曾经的大得多,在uC/OS_II里使命中调用了延时函数时,该使命就被退出了使命安排妥当表,然后调用一次体系调度OS_Sched(),从头寻觅最高优先级的使命去履行,这个时分咱们的体系只注册了两个使命,这样就只能持续履行使命APP_TaskStart了,方才在这个函数里树立第一个测验使命就被抢去了CPU的占用权,现在回来持续创立Task_Test2第二个测验使命,这第二个测验使命优先级也比开端使命高,所以天然的它又被人抢去了CPU的占用权,在第二个测验使命里咱们又会看到有延时函数,功用肯定是相同的,以此类推第三个测验使命也就明晰的多了。这时还有一个问题便是延时完毕后体系操作,方才测验使命1进入延时后,不会被体系调用,他的延时变量OSTCBDly是跟着体系的心跳进行递减的,假如有两个使命一起在延时中只需他们的使命操控块里的延时变量不是0就会在心跳中止服务函数里减1,比及他被减为0,体系会把这个使命从头放到使命安排妥当表里,而且运转一次体系调度函数OS_Sched(),经过这种机制来确保体系一向在运转着最高优先级的使命。这样体系的调度问题就解说完了,在后边关于中止和信号量运用时,他们对体系的履行次序也是有影响的,他们是怎么参加到体系的调度里,就看后边的讲解了。


方才咱们说了延时函数的作用,假如我把上面的代码里黄色高亮的部分凝视掉会有什么样的作用,成果便是其他的3个使命都无法运转了,体系将一向处理使命Task_Test1,再参加咱们假如把黄色高亮部分的延时参数调大一些,调整到1s,成果也不令人满意,尽管我给了提起使命足够的运转时刻,可是因为每检测一次我都会等候很长时刻,导致我的检测精度大大下降,按键变的极为难用。这时分咱们就应该考虑,在uC/OS_II这样一个实时的嵌入式操作体系里边,最可怕的便是无目的的等候,所以咱们尽量运用中止这样方法去处理接口信息,中止和实时体系是相辅相成的。


声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/bandaoti/fenxiao/252245.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部