·嵌入式实时操作系统uC/OS-II中的任务管理

ucos-ii 的任务调度原理和实现 ucosii 的任务控制块是任务中很重要,它记录了任务的信息,包括优先级、延时时间、状态等信息。 阅读详情

http://blog.sina.com.cn/s/blog_7f6468bb0100str7.html

uC/OS-II简介

    uC/OS是一种公开源代码、结构小巧、具有可剥夺实时内核的实时操作系统。用户只要有标准的ANSI的C交叉编译器,有汇编器、连接器等软件工具,就可以将uC/OS嵌入到开发的产品中。uC/OS-II具有执行效率高、占用空间小、实时性能优良和可扩展性强等优点,最小内核可编译至2KB。uC/OS-II已移植到几乎所有知名的CPU上。

    严格地说,uC/OS-II只是一个实时操作系统内核,它仅仅包含了任务调度,任务管理,时间管理,内存管理和任务间的通信和同步等基本功能。没有提供输入输出管理,文件系统,网络等额外的服务。但由于uC/OS-II良好的可扩展性和源码开放,这些非必须的功能完全可以由用户根据自己需要分别实现

    uC/OS-II工作原理

    uC/OS-II是一种基于优先级的可抢先的硬实时内核。

  要实现多任务机制,那么目标CPU必须具备一种在运行期更改PC的途径,否则无法做到切换。不幸的是,直接设置PC指针,目前还没有哪个CPU支持这样的指令。但是一般CPU都允许通过类似JMP,CALL这样的指令来间接的修改PC。我们的多任务机制的实现也正是基于这个出发点。事实上,我们使用CALL指令或者软中断指令来修改PC,主要是软中断。但在一些CPU上,并不存在软中断这样的概念,所以,我们在那些CPU上,使用几条PUSH指令加上一条CALL指令来模拟一次软中断的发生。

  在uC/OS-II里,每个任务都有一个任务控制块(Task Control Block),这是一个比较复杂的数据结构。在任务控制快的偏移为0的地方,存储着一个指针,它记录了所属任务的专用堆栈地址。事实上,再uC/OS-II内,每个任务都有自己的专用堆栈,彼此之间不能侵犯。这点要求程序员再他们的程序中保证。一般的做法是把他们申明成静态数组。而且要申明成OS_STK类型。当任务有了自己的堆栈,那么就可以将每一个任务堆栈再那里记录到前面谈到的任务控制快偏移为0的地方。以后每当发生任务切换,系统必然会先进入一个中断,这一般是通过软中断或者时钟中断实现。然后系统会先把当前任务的堆栈地址保存起来,仅接着恢复要切换的任务的堆栈地址。由于哪个任务的堆栈里一定也存的是地址(还记得我们前面说过的,每当发生任务切换,系统必然会先进入一个中断,而一旦中断CPU就会把地址压入堆栈),这样,就达到了修改PC为下一个任务的地址的目的。

    uC/OS-II的任务管理

    1、单道程序设计和多道程序设计:嵌入式操作系统可以分为单道程序设计和多道程序设计两种类型。采用单道程序设计的操作系统在任何时候只能有一个程序在运行。采用多道程序设计的操作系统允许多个程序同时存在并运行,采用多道程序设计技术可以有效提高系统资源利用率。

    2、进程、线程和任务

      进程:进程是在描述多道系统中并发活动过程引入的一个概念。进程和程序是两个既有联系又有区别的概念,两者不能混为一谈。程序是静态的,而进程是动态的、变化的。进程和程序之间并不是一一对应的。一个进程在运行的时候可以启动一个或多个程序,同一个程序也可能由多个进程同时执行。程序可以以文件的形式存放在硬盘或光盘上,作为一种软件资源长期保存。而进程只是一次执行过程,它是暂时的,是动态地产生和终止的。

     一个进程通常包含以下几个方面的内容:

     相应的程序:进程是一个正在运行的程序,有相应程序的代码和数据。

     CPU 上下文:程序在运行时,CPU中含有PC、PSW、通用寄存器、段寄存器、栈指针寄存器等各种寄存器的当前值内容,例如:在PC中记录的将要取出的指令的地址,在PSW中用于记录处理器的运行状态信息,通用寄存器存放的数据或地址;段寄存器存放的程序中各个段的地址;栈指针寄存器记录的栈顶的当前位置。

     一组系统资源:包括操作系统用来管理进程的数据结构、进程的内存地址空间、进程正在使用的文件等。

     线程:线程是一个比进程更小的能独立运行的基本单位。所谓的线程,就是进程当中的一条执行流程。

     从资源组合的角度来看,进程把一组相关的资源组合起来,构成了一个资源平台,其中包括运行上下文、内存地址空间、打开的文件等。从程序运行的角度来看,进程就是一个正在运行的程序。可以把进程看成是程序代码在这个资源平台上的一条执行流程(线程),也就是可以认为进程等于线程加上资源平台。

     在一个进程当中,或者说在一个资源平台上,可以同时存在多个线程。可以用线程来作为CPU的基本调度单位,使得各个线程之间可以并发执行。对于同一个进程当中的各个线程来说,运行在相同的资源平台上,可以共享该进程的大部分资源(如内存地址空间、代码、数据、文件等),但也有一小部分资源是不能共享的,每个线程都必须拥有各自独立的一份,如CPU运行上下文和栈。

     任务:在一些嵌入式系统中,把能够独立运行的实体称为“任务”,并没有使用“进程”或“线程”这两个概念。任务到底是进程还是线程,在研究一个具体的嵌入式操作系统的时候,要加以区分。

     在任务的创建过程需要定义的主要参数有任务的优先级、栈空间的大小和函数名。任务具有独立的优先级和栈空间,CPU上下文一般也是存放在栈空间中。对于不同的任务,它们也能够访问相同的全局变量,在这些任务之间,可以很方便地、直接地去使用共享的内存,而不需要经过系统内核来进行通信。

     通常认为,在嵌入式操作系统中“任务”就是线程,如在 linux、uC/OS等嵌入式操作系统中。

    3、任务的状态及其转换

  嵌入式实时操作系统uC/OS-II中的任务管理    

    睡眠状态:人物在没有被配备任务控制块或被剥夺了任务控制块时的状态。任务驻留在内存中,但还没交给内核管理。通过调用任务创建函数把任务交给内核。就绪状态:系统为任务配备了任务控制块且在任务就绪表中进行了就绪登记,这时任务的状态。任务已经准备好,且可运行,但由于优先级比正在运行的任务的优先级低,所以还暂时不能运行。

    运行状态:处于就绪状态的任务如果经调度器判断获得了CPU 的使用权,则任务就进入运行状态。得到了CPU 的控制权正在运行之中的任务状态。中断服务状态:一个正在运行的任务一旦响应中断申请就会中止运行而去执行中断服务程序,这时任务的状态。发生中断时CPU 提供相应的中断服务,原来正在运行的任务暂时停止运行,进入了被中断状态。

    等待状态:正在运行的任务,需要等待一段时间或需要等待一事件发生在运行时,该任务就会把CPU 的使用权让给别的任务而使任务进入等待状态。正在运行的任务由于调用延时函数OSTimeDly(),或等待事件信号量而将自身挂起。

    4、任务控制块 

     任务控制块——任务在系统中的身份证(系统中的所有资源都应该有身份证),一个任务的任务控制块的主要作用就是保存该任务的虚拟处理器的堆栈指针寄存器SP。其实,随着任务管理工作的复杂性的提高,它还应该保存一些其他信息。由于系统存在着多个任务,于是系统如何识别并管理一个任务就是一个需要解决的问题。识

别一个任务的最直接的办法是为每一个任务起一个名称。由于 uC/OS-II 中的任务都有一个唯一的优先级别,因此uC/OS-II 是用任务的优先级来作为任务的标识。所以,任务控制块还要来保存该任务的优先级别。另外,前面也谈到,一个任务在不同的时刻还处于不同的状态,显然,记录了任务状态的数据也应该保存到任务控制块中。 

     基于上述原因,系统必须为每个任务创建一个保存与该任务有关的相关信息的数据结构,这个数据结构就叫做该任务的任务控制块(TCB)。

  嵌入式实时操作系统uC/OS-II中的任务管理

     任务控制块完整的定义:

     typedef struct os_tcb {

     OS_STK *OSTCBStkPtr;

     #if OS_TASK_CREATE_EXT_EN

     void *OSTCBExtPtr;

     O_STK *OSTCBStkBottom;

     INT32U OSTCBStkSize;

     INT16U OSTCBOpt;

     INT16U OSTCBId;

     #endif

     struct os_tcb *OSTCBNext;

     struct os_tcb *OSTCBPrev;

     #if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN || OS_SEM_EN

     OS_EVENT *OSTCBEventPtr;

     #endif

     #if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN

     void *OSTCBMsg;

     #endif

     INT16U OSTCBDly;

     INT8U OSTCBStat;

     INT8U OSTCBPrio;

     INT8U OSTCBX;

     INT8U OSTCBY;

     INT8U OSTCBBitX;

     INT8U OSTCBBitY;

     #if OS_TASK_DEL_EN

     BOOLEAN OSTCBDelReq;

     #endif

     } OS_TCB;

 

    任务在内存中的结构:

嵌入式实时操作系统uC/OS-II中的任务管理

     多个任务靠任务控制块组成一个任务链表:

    嵌入式实时操作系统uC/OS-II中的任务管理
     用户代码的一般结构:

    嵌入式实时操作系统uC/OS-II中的任务管理
      uC/OS-II的代码结构是一个可以带有临界段的无限循环。   

     系统提供的空闲任务:

     在多任务系统运行时,系统经常会在某个时间内无用户任务可运行而处于所谓的空闲状态,为了使CPU 在没有用户任务可执行的时候有事可做,uC/OS-II 提供了一个叫做空闲任务

    OSTaskldle()的系统任务。

    void OSTaskldle(void* pdata)

    {

    #if OS_CRITICAL_METHOD==0;

    OS_CPU_SR cpu_sr;

    #endif

    pdata=pdata;//防止某些编译器报错

    for(;;)

    {

    OS_ENTER_CRITICAL();//关闭中断

    OSdleCtr++;

    OS_EXIT_CRITICAL();//开放中断

    }

    }

     uC/OS-II 规定,一个用户应用程序必须使用这个空闲任务,而且这个任务是不能用软件来删除的。

     系统提供的另一个任务——统计任务

     uC/OS-II 提供的另一个系统任务是统计任务OSTaskStat()。这个统计任务每秒计算一次CPU在单位时间内的时间,并把计算结果以百分比的形式存放在变量OSCPUsage 中,以便应用程序通过访问它来了解CPU 的利用率,所以这个系统任务OSTaskStat()叫做统计任务。

    任务的优先权及优先级别

     uC/OS-II 把任务的优先权分为64 个优先级别,每一个级别都用一个数字来表示。数字0 表示任务的优先级别最高,数字越大则表示任务的优先级别越低。用户可以根据应用程序的需要,在文件OS_CFG.H 中通过给表示最低优先级别的常数OS_LOWEST_PRIO 赋值的方法,来说明应用程序中任务优先级别的数目。该常数一旦被定

义,则意味着系统中可供使用的优先级别为:0,1,2,……,OS_LOWEST_PRIO,共OS_LOWEST_PRIO+1 个。

     固定地,系统总是把最低优先级别 OS_LOWEST_PRIO 自动赋给空闲任务。如果应用程序中还是用了统计任务,系统则会把优先级别OS_LOWEST_PRIO-1 自动赋给统计任务,因此用户任务可以使用的优先级别:0,1,2…OS_LOWEST_PRIO-2,共OS_LOWEST_PRIO-1。

     任务堆栈

     保存 CPU 寄存器中的内容及存储任务私有数据的需要,每个任务都应该配有自己的堆栈,任务堆栈是任务的重要的组成部分。在应用程序定义任务堆栈的栈区非常简单,即定义一个 OS_STK 类型的一个数组并在创建一个任务时把这个数组的地址赋给该任务就可以了。

     例如:

     //定义堆栈的长度

     #define TASK_STK_SIZE 512

    //定义一个数组来作为任务堆栈

    OS_STK TaskStk[TASK_STK_SIZE];/系统定义的一个数据类型OS_STK

    void main(void)

    {

    ……

    OSTaskCreate(

    MyTask,

    &MyTaskAgu,

    &MyTaskStk[MyTaskStkN-1],

    20

    );

    ……

    }

     在创建任务时,要传递任务的堆栈指针和任务优先级别。就是函数OSTaskCreate()的形参。使用 OSTaskCreate()创建任务时,一定要注意所使用的处理器对堆栈增长方向的支持是向上还是向下的。

     任务堆栈的初始化

     应用程序创建一个新任务的时候,必须把在系统启动这个任务时 CPU 各寄存器所需要的初始数据(任务指针、任务堆栈指针、程序状态字等等),事先存放在任务的堆栈中。uC/OS-II 在创建任务函数OSTaskCreate()中通过调用任务堆栈初始化函数OSTaskStklnit()来完成任务堆栈初始化工作的。

     OS_STK *OSTaskStklnit(

     void(*task)(void *pd),

     void *pdata,

     OS_STK *ptos,

     INT16U opt

     );

     由于各种处理器的寄存器及对堆栈的操作方式不尽相同,因此该函数需要用户在进行uC/OS-II 的移植时,安所使用的处理器由用户来编写。

     其实,任务堆栈的初始化就是对该任务的虚拟处理器的初始化(复位)。

     任务控制块(OS_TCB)及任务控制块链表

     uC/OS-II 用来记录任务的堆栈指针、任务的当前状态、任务的优先级别等一些与任务管理有关的属性的表就叫做任务控制块。任务控制块就相当于是一个任务的身份证,没有任务控制块的任务是不能被系统承认和管理

的。

     任务控制块结构的主要成员

    嵌入式实时操作系统uC/OS-II中的任务管理

      空任务控制块链表

    嵌入式实时操作系统uC/OS-II中的任务管理

     当进行系统初始化时,初始化函数会按用户提供的任务数为系统创建具体相应数量的任务控制块并把它们链接为一个链表。由于这些任务控制块还没有对应的任务,故这个链表叫做空任务块链表,即相当于是一些空

白的身份证。

     任务控制块链表和空任务控制链表

嵌入式实时操作系统uC/OS-II中的任务管理

     当应用程序调用函数 OSTaskCreate()创建一个任务时,这个函数会调用系统函数OSTCBlnit()来为任务控制块进行初始化。这个函数首先为被创建任务从空任务控制块链表获得一个任务控制块,然后用任务的属性对任务控制块各个成员进行赋值,最后再把这个任务控制块链入任务控制块链表的头部。

     加速任务位置计算
     OSTCBX,OSTCBY,OSTCBBitX,OSTCBBitY 四个变量用于加速任务进入就绪状态的过程或进入等待事件发生状态的过程。
     根据任务的优先级 OSTCBPrio 计算得出,计算公式如下
     OSTCBY = OSTCBPrio >> 3;
     OSTCBBitY = OSMapTbl[OSTCBY];
     OSTCBX = OSTCBPrio & 0x07;
     OSTCBBitX = OSMapTbl[OSTCBX];

     任务就绪表及任务调度
     多任务操作系统的核心工作就是任务调度。
     所谓调度,就是通过一个算法在多个任务确定该运行的任务,做这项工作的函数就叫做调度器。uC/OS-II 进行任务调度的思想是“近似地每时每刻总是让优先级最高的就绪任务处于运行状态”。为了保证这一点,它在系统或用户任务调用系统函数及执行中断服务程序结束时总是调用调度器,来确定应该运行的任务并运行它。uC/OS-II 进行任务调度的依据就是任务就绪表。为了能够使系统清楚地知道,系统中那些任务已经就绪,那些还没有就绪,uC/OS-II 在RAM中设立了一个记录表,系统中的每个任务都在这个表中占据一个位置,并用这个位置的状态(0 或者1)来表示任务是否处于就绪状态,这个表就叫做任务就绪状态表,简称任务就绪表。

     任务就绪表

嵌入式实时操作系统uC/OS-II中的任务管理
    

      变量 OSRdyGrp 的格式及含义

 

嵌入式实时操作系统uC/OS-II中的任务管理
    

     任务就绪表的示意图

嵌入式实时操作系统uC/OS-II中的任务管理      绪状态位置
    
  嵌入式实时操作系统uC/OS-II中的任务管理

          在程序中,可以用类似下面的代码把优先级别为 prio 的任务置为就绪状态:
     OSRdyGrp | =OSMapTbl[prio>>3];
     OSRdyTbl[prio>>3] | = OSMapTbl[prio&0x07];
     如果要使一个优先级别为 prio 的任务脱离就绪状态则可使用如下类似代码:
     if((OSRdyTbl[prio>>3]&=-OSMapTbl[prio&0x07])==0)
     OSRdyGrp&=-OSMapTbl[prio>>3];
     绪表中找最高优先级别任务过程 

嵌入式实时操作系统uC/OS-II中的任务管理
     从任务就绪表中获取优先级别最高的就绪任务可用如下类似的代码:
     y = OSUnMapTal[OSRdyGrp]; //D5、D4、D3 位
     x = OSUnMapTal[OSRdyTbl[y]]; //D2、D1、D0 位
     prio = (y<<3)+x; //优先级别
     或
     y = OSUnMapTbl[OSRdyGrp];
     prio = (INT8U)((y << 3)
     + OSUnMapTbl[OSRdyTbl[y]]);

     小结:
     系统通过查找任务就绪表来获取待运行任务的优先级。
     任务切换过程
     如何获得待运行任务的任务控制块?
     根据就绪表获取待运行任务的任务控制块指针。

嵌入式实时操作系统uC/OS-II中的任务管理
嵌入式实时操作系统uC/OS-II中的任务管理
     任务切换宏 OS_TASK_SW()
     任务切换就是中止正在运行的任务(当前任务),转而去运行另外一个任务的操作,当然这个

     任务应该是就绪任务中优先级别最高的那个任务。
     任务切换断点保护
嵌入式实时操作系统uC/OS-II中的任务管理
     调度器进行任务切换的动作

嵌入式实时操作系统uC/OS-II中的任务管理


     不要企图用PUSH 和POP 指令来使程序计数器PC 压栈和出栈,因为没有这样的指令。
     中断动作和过程调用指令可以使 PC 压栈;
     中断返回指令可以使 PC 出栈。
     因此任务切换 OSCtxSw()必定是一个中断服务程序。
     需要由宏 OS_TASK_SW()来引发一次中断或者一次调度来使OSCtxSw()执行任务切换工作。
     对于实时系统来说,应该尽可能地实现即时调度。
     用函数 OSTaskCreate()创建任务
     应用程序通过调用 OSTaskCreate( ) 函数来创建一个任务,OSTaskCreate( )函数的原型如下:
     INT8U OSTaskCreate (
     void (*task)(void *pd),//指向任务的指针
     void *pdata, //传递给任务的参数
     OS_STK *ptos, //指向任务堆栈栈顶的指针
     INT8U prio //任务的优先级
     )
     创建任务的一般方法:
     一般来说,任务可以在调用函数OSStart()启动任务调度之前来创建,也可以在任务中来创建。但是,uC/OS-II 有一个规定:在调用启动任务函数OSStart()之前,必须已经创建了至少一个任务。因此,人们习惯上在调用函数OSStart()之前先创建一个任务,并赋予它最高的优先级别,从而使它成为起始任务。然后在这个起始任务中,在创建其他个任务。如果要使用系统提供的统计任务,则统计任务的初始化函数也必须在这个起始任务中来调用。
     void main(void)
     { ……
     OSInit( ); //对μC/OS-II 进行初始化
     ……
     OSTaskCreate (TaskStart,……);//创建任务TaskStart
     OSStart( ); //开始多任务调度
     }
     void TaskStart(void*pdata)
     {
     ……//在这个位置安装并启动μC/OS-II 的时钟
     OSStatInit( ); //初始化统计任务
     ……//在这个位置创建其他任务
     for(;;)

     {
     起始任务 TaskStart 的代码
     }
     }

     ARM7 中的应用例子LPC2124,创建两个任务,LED1、LED2。实现代码和仿真电路如下:
     1. 对应的Proteus 仿真图:

嵌入式实时操作系统uC/OS-II中的任务管理
     2.实现代码
    
     #include "config.h"
     #include "stdlib.h"
     #define LED1 (1<<18)
     #define LED2 (1<<19)
     #define TaskLED1StkSize 128
     #define TaskLED2StkSize 128
     #define Task0StkLengh 64
    
     OS_STK Task0Stk [Task0StkLengh];
     OS_STK TaskLED1Stk[TaskLED1StkSize];
     OS_STK TaskLED2Stk[TaskLED2StkSize];
     void Task0(void *pdata);
     void TaskLED1(void *pdata);

     void TaskLED2(void *pdata);
    
     int main (void)
     {
    
     OSInit ();
    
    
     OSTaskCreate (Task0,(void *)0, &Task0Stk[Task0StkLengh - 1], 2);
    
     OSStart ();
     return 0;
     }
    
     void Task0 (void *pdata)
     {
     pdata = pdata;
    
     TargetInit ();
    
     OSTaskCreate(TaskLED1,(void*)0,&TaskLED1Stk[TaskLED1StkSize-1],3);
    
     OSTaskCreate(TaskLED2,(void*)0,&TaskLED2Stk[TaskLED2StkSize-1],4);
    
     while(1)
     {
      OSTimeDly(10);
     }
     }
    
     void TaskLED1(void *pdata)
     {
     pdata=pdata;
     PINSEL2=PINSEL2&(~0x04);
     IO1DIR=LED1;
     IO1SET=LED1;

     for(;;)
     {
     IO1CLR=LED1;
     OSTimeDly(OS_TICKS_PER_SEC/100);
     IO1SET=LED1;
     OSTimeDly(OS_TICKS_PER_SEC/100);
     }
     }
     void TaskLED2(void *pdata)
     {
     pdata=pdata;
     PINSEL2=PINSEL2&(~0x08);
     IO1DIR|=LED2;
     IO1SET=LED2;
     for(;;)
     {
     IO1CLR=LED2;
     OSTimeDly(OS_TICKS_PER_SEC/1);
     IO1SET=LED2;
     OSTimeDly(OS_TICKS_PER_SEC/1);
     }
     }
     uC/OS-II 初始化
     在使用 uC/OS-II 的所有服务之前,必须要调用uC/OS-II 的初始化函数OSInit()对uC/OS-II
自身的运行环境进行初始化。
     函数 OSInit()将对uC/OS-II 的所有全局变量和数据结构进行初始化,同时创建空闲任务OSTaskldle,并赋之以最低优先级别和永远的就绪状态。如果用户应用程序还要使用统计任务的话(常数OS_TASK_STAT_EN=1),则OSInit()还要以优先级别为OS_LOWEST_PRIO-1;来创建统计任务。
     初始化函数 OSInit()对数据结构进行初始化时,主要要创建包括空任务控制块链表在内的5个空数据缓冲区。同时,为了可以快速地查询任务控制块链表中的各个元素,初始化函数OSInit()还要创建一个数组OSTCBPrioTbl[OS_LOWEST_PRIO+1],在这里数组中,按任务的优先级别的顺序把任务控制块的指针存放在了对应的元素中。
     uC/OS-II 初始化后的数据结构

嵌入式实时操作系统uC/OS-II中的任务管理
     uC/OS-II 的启动:
     uC/OS-II 进行任务的管理是从调用启动函数OSStart()开始的,当然其前提条件是在调用该函数之前至少创建了一个用户任务。

嵌入式实时操作系统uC/OS-II中的任务管理

     以上就是对嵌入式实时操作系统uC/OS-II任务管理的一些学习总结。

嵌入式实时操作系统uC/OS-II概述  嵌入式实时操作系统uC/OS-II概述一、            uC/OS-II是一种小型的嵌入式操作系统,它只提供了任务管理,任务通信同步和简单的存储管理三项基本功能。二、            uC/OS-II作为一个微内核,它只对计算机的处理器和硬件时钟进行了抽象和封装,而没有提供其他的硬件抽象层(HAL)。在移植uC/OS-II时,其主要工作就是根据具体硬件换一个或添加一个 阅读详情

相关推荐

【01 uC/OS-II】

uC/OS-II是基于C语言开发的实时操作系统内核,专为设计。该系统采用抢占式优先级调度机制,支持最多64个任务管理(含用户可用56个),每个任务拥有独立堆栈和任务控制块,通过OSSched()函数实现恒定时间复杂度的任务切换。内核提供、邮箱等通信机制,采用分区内存管理防止碎片化并优化资源争抢导致的优先级翻转问题。该内核90%以上代码采用编写,仅需200行汇编代码完成处理器适配移植,核心可裁剪至2.7KB 。

aniywn的博客 643

关于ucosii操作系统原理---(一)任务调度

因此,ucosii也是借助这一思想,模仿刚被中断时,断点数据入栈,然后在中断程序执行完返回恢复断点数据时,此时把另一个任务的堆栈指针来替换掉当前需要返回的断点任务堆栈指针,不返回断点处继续执行,这样就发生了任务切换。在这个表中,给每一个任务安排了一个二进制位,1代表就绪,否则不就绪。这实际上是用一个U8类型的数组OSRdyTb1[]来充当这个任务就绪表,如下图所示,这是一个可以记录32个任务就绪状态的任务就绪表,这个数组一个元素可以代表8个任务的就绪状态,4个元素就可以代表32个任务的就绪状态。

weixin_52247452的博客 3039

uC/OS_II操作系统移植,亲测可用

uC/OS-II操作系统移植标准步骤,采用官方源码,保证每个人都能轻松以移植成功

qq_44971108的博客 2307

详解操作系统的调度

多道程序系统中,进程的数量往往多于处理器的数量,这样会遇到多个进程或线程同时争用处理器的情况,,即从就绪队列中按调度算法选择一个进程并将处理器分配给它运行,以实现进程或线程并发地执行。

叫好与叫座虽然不是对立面,但想在同一个作品中达到双重效果很难。 2073

UCOSII实时操作系统任务调度深入解析

本文还有配套的精品资源,点击获取 简介:μC/OS-II(UCOSII)是一个广泛应用于嵌入式系统的实时操作系统,其核心功能之一为任务调度。本文详细介绍了UCOSII的任务调度机制,包括任务与优先级的关系、任务状态转换、任务调度原理、任务创建与切换机制、优先级反转问题及解决方案、信号量与互斥量的应用、时间片轮转配置以及中断服务程序对任务调度的影响。此外,还包括了任务管理功能...

weixin_35756637的博客 1592

嵌入式实时操作系统UC/OS-II实战例题源码精讲

UC/OS-II(MicroC/OS-II)是一种专为嵌入式系统设计的可裁剪、抢占式实时操作系统(RTOS),由Jean J. Labrosse开发,具备高度可移植性和确定性行为。其内核精简高效,代码完全用C语言编写,便于在不同架构的微控制器(如ARM Cortex-M、8051、PIC等)上移植。系统支持最多64个任务,其中用户可用任务通常为56个,其余保留给系统内部使用。该操作系统广泛应用于对实时性要求严苛的工业控制、医疗设备、汽车电子和消费类电子产品中。

weixin_42513209的博客 1042

操作系统实验六——调度器(详细解析)

操作系统实验六——调度器一、 实验目的二、 实验任务三、 实验准备(一) 数据结构1.调度器框架shed_class2. 运行队列描述run_queue3. 四个调度函数(二) 相关函数改进1. proc_struct 函数2. alloc_proc()函数3. trap_dispatch()函数四、 实验步骤(一) 练习0:填写已有实验(二) 练习1: 使用Round Robin调度算法1. RR调度算法分析2. 问题分析(三) 练习2: 实现Stride Scheduling调度算法1. 简单分析2.

weixin_43973089的博客 1983

深入理解及应用嵌入式实时操作系统uc/os-ii

实时操作系统(RTOS)专为满足实时处理的需求而设计,其核心特性体现在对时间的精确控制和快速响应能力。实时性的定义是指系统对输入数据做出响应的时间要求。为了准确评估实时性,系统通常采用以下几个关键指标:响应时间(Response Time)- 指从事件发生到系统开始处理该事件所需的时间。处理时间(Processing Time)- 指系统从开始处理事件到处理完毕所需的时间。延迟时间(Latency)- 指系统对一个输入的总响应时间,包括响应时间和处理时间。

weixin_42153793的博客 576

uC/OS II 学习笔记

uC/OS II 提供给用户通用接口函数都在Ucos_ii.h中【uC/GUI 提供给用户通用接口函数都在INC包含的各个头文件中,使用时参考官方的手册用就好了,有中文版的】; INT8U  const  OSUnMapTbl[256] = {     0u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u,

liyaoyao_yy的专栏 952

AVR ATmega16与uC/OS-II的综合应用指南

选取一个具有代表性的嵌入式系统项目,描述项目背景、硬件平台、软件框架以及面临的挑战。

weixin_29607511的博客 1050

0032期基于深度学习的大米识别-含数据集

083基于深度学习的手势识别小程序版本_含10多种模型包括alexnet、DenseNet、DLA、GoogleNet、Mobilenet、ResNet、ResNeXt、ShuffleNet、VGG、EfficientNet和Swin transformer等10多种模型。117nlp自然语言处理-文本情感分类-joy-sadness-anger-fear-love-surprise。运行02深度学习模型训练.py就会将txt文本中记录的训练集和验证集进行读取训练,训练好后会保存模型在本地。

grehtsfrs的博客 1507

uC/OS-II 一些函数简介

获得更多资料欢迎进入我的网站或者 csdn或者博客园 以前搞硬件的经验,最近突然翻出来了。分享给大家;主要讲解uC/OS-II常用函数;虽说现在转行软件了,但是感觉之前搞硬件的经验还真是很有用对于理解底层等很有帮助。比如这里对于操作系统还是有点用的;好了,开始唠叨下。 ucos ii介绍 μC/OS-II由Micrium公司提供,是一个可移植、可固化的、可裁剪的、占先式多任务实时内核,它适用...

weixin_30715523的博客 216

S4-FPGA-K7板级原理图硬件实战

xilinx K7板级硬件实战

weixin_66510961的博客 6152

移植µC/OS-Ⅱ

http://www.embeddedlinux.org.cn/uCOSII/chapter8.htm

Amao_come_on 的专栏 752

别再死磕U-Net了!用PyTorch手把手教你搭建ResUnet,搞定医学图像分割(附完整代码)

本文详细介绍了如何利用PyTorch搭建ResUnet模型,通过引入残差连接解决医学图像分割中的梯度消失、特征退化和细节丢失问题。与传统U-Net相比,ResUnet在Dice系数和收敛速度上均有显著提升,特别适合处理脑部MRI等复杂医学图像。文章还提供了完整的代码实现和关键训练技巧,帮助开发者快速掌握这一先进技术。

weixin_42552637的博客 327

图信号处理中的多尺度分析:图小波变换与图傅里叶变换的对比与应用

本文深入探讨了图信号处理中的多尺度分析方法,重点对比了图小波变换(GWT)与图傅里叶变换(GFT)的技术特点与应用场景。通过分析图的拓扑结构,GWT展现出强大的局部洞察力,适用于异常检测和社区发现;而GFT则擅长全局频率分析,适合趋势分析和信号去噪。文章结合实战案例,为读者提供了方法选型指南和前沿进展,帮助开发者在生物信息学、社交网络分析等领域高效应用这些技术。

weixin_30369041的博客 406

【嵌入式系统—实时操作系统】uC/OS-II 及其STM32F103移植

☞ STM32F107——uC/OS-II 源码包的下载 一、微内核 uC/OS-II 的构成 实时微内核 uC/OS-II ,由 Jean J. Labrosse 在 1992 年编写发行,代码开源,如下图所示。 uC/OS-II内核结构 2、对各部分的进一步解释: 第一部分 (1):与硬件无关的高层的操作系统部分 大部分是关于任务的创建、信号量的创建、邮箱和队列的创建,以...

夜半少年的博客 2218

C# NX二次开发:两种过滤器设置方案的实战解析与场景适配

本文深入解析C# NX二次开发中的两种过滤器设置方案:AddFilterHandler回调与MaskTriple属性设置。通过实战案例对比其性能差异与适用场景,帮助开发者根据需求选择最优方案,提升NX插件开发效率与交互体验。特别针对BlockStyler集成场景提供专业建议,是NX二次开发者的实用指南。

weixin_33739646的博客 844

uC/OS-II中的任务管理

uC/OS-II简介     uC/OS是一种公开源代码、结构小巧、具有可剥夺实时内核的实时操作系统。用户只要有标准的ANSI的C交叉编译器,有汇编器、连接器等软件工具,就可以将uC/OS嵌入到开发的产品中。uC/OS-II具有执行效率高、占用空间小、实时性能优良和可扩展性强等优点,最小内核可编译至2KB。uC/OS-II已移植到几乎所有知名的CPU上。     严格地说,uC/O

liyaoyao_yy的专栏 1707

Logstash安装部署

1. 部署及安装所用的用户不能是root。

lmj3732018的博客 4294

人群仿真软件:AnyLogic_(12).AnyLogic高级功能应用

在AnyLogic中,自定义行人行为是通过编写Java代码来实现的。行人行为的自定义可以包括行走路径的选择、速度变化、交互行为等。这使得仿真模型更加灵活和真实。

kkchenjj的博客 1060

《嵌入式实时操作系统uC/OS-II》学习摘要

二、 实时系统概念 1.实时系统的特点 如果逻辑和时序出现了偏差,将会引起严重后果。有两种类型的实时系统:软实时系统和硬实时系统。 在软实时系统系统中,系统的宗旨是指各个任务尽快地运行,而不要求限定某一任务在多长时间内完成;在硬实时系统中,各任务不仅须执行无误,而且要做到准时。 大多数实时系统是二者的结合。 2.前/后台系统 可称为前/后台系统或超循环系统。应用程序是一个无限的循环,循环中调用相应的函数完成相应的操作,这部分可以看成后台行为。中断服务程序处理异步时间,这部分可以看成是前台行为。 后台也可以叫

lvturancao的博客 1198

MIT液态神经网络(LNN)深度研究:原理、应用与未来

液态神经网络(Liquid Neural Networks, LNNs)代表了人工智能领域,特别是神经网络架构设计中的一次范式转移。它从根本上挑战了传统深度学习模型依赖大规模参数和静态架构的惯例,转而寻求一种更为动态、高效且受生物神经系统启发的计算范式。LNN的核心创新在于其将神经网络的计算过程从离散的、基于时间步的更新,转变为连续的、由微分方程驱动的动态系统演化。这种转变不仅赋予了模型前所未有的适应性和鲁棒性,还使其在处理复杂的时序数据和因果推断任务时表现出色。本章节将深入剖析LNN的技术原理,从其核心的

步子哥的博客 2590

《嵌入式实时操作系统uC/OS-II》第2部分:uC/OS-II内核

每个任务都被分配一个唯一的优先级,数值越低优先级越高。当一个更高优先级的任务进入就绪状态时,调度器会立即暂停当前正在运行的低优先级任务,将CPU资源分配给高优先级任务。以上代码示例和注释详细阐述了uC/OS-II中任务管理部分的关键概念和操作,希望能帮助你更好地理解uC/OS-II的任务管理机制。请注意,实际的uC/OS-II代码可能更为复杂,包含更多的错误处理和优化逻辑。任务控制块(TCB)是uC/OS-II中用于管理任务的数据结构,它包含了任务的所有相关信息,以便操作系统对任务进行调度、控制和管理。

qq_40844444的博客 836

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

如何快速上手uC/OS-II:嵌入式实时操作系统的终极指南

uC/OS-II是一款抢占式、高度可移植且可扩展的实时操作系统内核,专为在大量CPU架构上轻松使用而设计。这款嵌入式实时操作系统在工业控制、医疗设备和航空航天等领域有着广泛应用,是嵌入式开发者的重要工具。 ## 🚀 什么是uC/OS-II实时操作系统? uC/OS-II是一个完整的嵌入式实时操作系统,具有以下核心特性: - **抢占式调度**:高优先级任务可以抢占低优先级任务的执行 - *

gitblog_00076的博客 519

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

【嵌入式系统—实时操作系统】RTOS

一、RTOS中的基本概念 背景 OS(操作系统,operating system),是嵌入式系统中的灵魂,是其软件系统中的重要组成部分。 目前,嵌入式系统的智能化程度越来越高,而智能化主要是靠软件部分实现,其中,OS部分则起到关键、重要作用。 取决于嵌入式系统的应用领域,其操作系统可以分为实时操作系统(RTOS)和非实时操作系统(NRTOS)。 例如,用于航空航天的机载设备,鉴于实...

夜半少年的博客 3995

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

上一篇: ARM地址重映射的通俗解释
下一篇: 对uC/OS-II任务调度过程的一点粗浅理解
makebuaa
博客等级 码龄16年 135粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值