当前位置:首页 > 单片机 > 单片机
[导读]直接开始说明ucos创建任务时的步骤:1, 初始化任务堆栈2, 初始化任务控制块3, 把刚创建的任务设置为就绪态(即置位就绪表)上面提到的任务堆栈,控制块,就绪表我们前面已经说过了,下面就直接看代码。INT8U OSTa

直接开始说明ucos创建任务时的步骤:

1, 初始化任务堆栈

2, 初始化任务控制块

3, 把刚创建的任务设置为就绪态(即置位就绪表)

上面提到的任务堆栈,控制块,就绪表我们前面已经说过了,下面就直接看代码。

INT8U OSTaskCreate (void (*task)(void *pd), void *p_arg, OS_STK *ptos, INT8U prio)

{

OS_STK *psp;

INT8U err;

#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */

OS_CPU_SR cpu_sr;

cpu_sr = 0; /* Prevent compiler warning */

#endif

#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 (OSIntNesting > 0) { /* Make sure we don't create the task from within an ISR */

OS_EXIT_CRITICAL();

return (OS_ERR_TASK_CREATE_ISR);

}

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();

psp = (OS_STK *)OSTaskStkInit(task, p_arg, ptos, 0); /* Initialize the task's stack *///初始化任务的堆栈

err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0);

if (err == OS_NO_ERR) {

if (OSRunning == TRUE) { /* Find highest priority task if multitasking has started */

OS_Sched(); //如果创建任务时ucos已经开始任务调度,那么创建完任务后需要进行任务调度

}

} else {

OS_ENTER_CRITICAL();

OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others */

OS_EXIT_CRITICAL();

}

return (err);

}

OS_EXIT_CRITICAL();

return (OS_PRIO_EXIST);

}

下面是初始化堆栈的函数:

OS_STK * OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)

{//函数需要4个参数,一个指向任务函数的指针,任务运行时需要的参数,堆栈指针,扩展参数

unsigned int * stk;

stk = (unsigned int *)ptos; /* Load stack pointer */

//USE_ARG(opt);

opt++;

/* build a stack for the new task */

*--stk = (unsigned int) task; /* pc */

*--stk = (unsigned int) task; /* lr */

*--stk = 12; /* r12 */

*--stk = 11; /* r11 */

*--stk = 10; /* r10 */

*--stk = 9; /* r9 */

*--stk = 8; /* r8 */

*--stk = 7; /* r7 */

*--stk = 6; /* r6 */

*--stk = 5; /* r5 */

*--stk = 4; /* r4 */

*--stk = 3; /* r3 */

*--stk = 2; /* r2 */

*--stk = 1; /* r1 */

*--stk = (unsigned int) pdata; /* r0 */

*--stk = (SUPMODE); /* cpsr */

*--stk = (SUPMODE); /* spsr */

return ((OS_STK *)stk);

}

关于堆栈,我们前面已经讲过,这里用的即递减的满堆栈。

对于任务,其实就是一个无限循环的函数,那怎么控制它的运行那,这就是操作系统要干的活,操作系统根据调度算法实现对任务的调度以及任务的切换。实现了多个任务共享cpu。

我们已经知道,堆栈对任务的重要性,一:c语言执行需要堆栈空间。二:当发生任务切换时需要把程序运行的现场保存到任务的堆栈中。

也就是说,任务堆栈中应该保存的是任务运行时函数调用的情况以及被打断时的状态信息,可是问题来了,我们刚创建一个任务时,这个任务并没有运行过呀。这个好办,我们就模拟这个任务被打断过的迹象,任务没执行过,那么这个函数调用栈帧就不复存在。我们只模拟函数运行环境的保存。看上面代码,我们首先保存的是PC和LR,因为任务函数还没有执行过,因此这个PC和LR就应该是函数的首地址,也就是函数的名称指针。比如说你定义了一个任务函数

void Task1(void *Id)

{

for(;;){

printf("run task1n");

OSTimeDly(1000);

}

}

那就把Task1这个函数指针赋给PC和LR。接着是R1~R12这些通用寄存器,由于函数还没有执行过,这些通用寄存器的值是什么就不太重要,可以随便赋值,你看,这里就是给R1赋值1,给R2赋值2 ………… 给R12赋值12。当然你也可以给这些寄存器赋其他值,这些无关紧要,但当任务运行过后,那再保存程序执行现场时就要按章程来了,即这些寄存器被切换的时候里面的值是什么就应该保存什么。下面就要初始化CPSR和SPSR了,这两个值要根据你的操作系统要运行在处理器的那种模式下,任务运行时应该开中断的。你像我们这个把CPSR的值赋成SUPMODE(这个宏的值是0x13),就是说这个任务运行时在SVC模式下并且开中断。咱们原来说过ucos初始化过程CPSR的中断一直是关着的,CPSR的中断位就是当最高优先级任务运行时就已经开中断了。

一句话说那,现

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭