当前位置:首页 > 嵌入式 > 嵌入式教程
[导读]嵌入式Linux系统实时进程调度算法改进

1  嵌入式Linux系统分析
1.1  嵌入式系统
    嵌入式系统(Embedded Systems)是以应用为中心,以计算机技术为基础,软件硬件可剪裁(可编程、可重构),适用于应用系统对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。它一般由嵌入式微处理器、外围硬件设备、嵌入式操作系统以及用户的应用程序等四个部分组成,用于实现对其它设备的控制、监视或管理等功能。其中,嵌入式处理器是嵌入式系统中的核心部件。
1.2 实时操作系统
    实时操作系统(RTOS,Real-Time Operation System)是指一个能够在指定的时间范围内完成特定的功能或者对外部的异步时间做出响应的操作系统[3]。其操作的正确性不仅依赖于逻辑判断和逻辑设计的正确程度,而且跟这些操作进行的时间有关。“在指定的时间范围内”是这个定义的核心,也就是说,实时系统是对响应时间有严格要求的。这个定义要求了:系统应该有在事先定义的时间范围内识别和处理离散事件的能力;系统能够处理和存储控制系统所需要的大量的数据。
1.3 嵌入式实时操作系统
    由嵌入式系统的概念和特点可以看出,一个嵌入式系统对操作系统的可靠性、实时性都有很高的要求。尤其在嵌入式技术广泛应用的工业控制、航空军事等领域,对嵌入式操作系统的实时响应能力提出了非常严格的要求,哪怕出现很小的时间偏差,都有可能造成无法挽回的损失。这便是为何绝大多数嵌入式操作系统都采用实时操作系统的主要原因。实时操作系统应用到嵌入式领域,便出现了嵌入式实时操作系统,它是实时操作系统与嵌入式系统相结合的产物,具有实时性的同时又具有嵌入式系统的特点。
2 实时进程调度算法分析
2.1 Linux进程调度相关概念
    进程调度分成两个部分,一个是调度的时机,即什么时候调度;一个是调度的算法,即如何调度和调度哪个进程。
    Linux进程调度时机[1]:
    调度时机是指在什么情况下运行调度程序来选择进程运行。在Linux系统中调度程序是通过函数schedule()来实现的,这个函数被调用的频率很高,由它来决定要运行的进程。
    Linux调度时机主要分两种情况[2]:主动调度和被动调度。主动调度是指当进程状态发生变化时直接调用schedule()来实现调度。被动调度是指当一个进程运行时间片到或就绪队列中增加了一个进程,此时系统并不立即进行调度,而仅仅是将当前进程的调度标志位置1,当系统由核心态向用户态转变之前检查当前进程的调度标志是否为1,若为1,则调用schedule()进行调度。
2.2 进程调度的原理
    进程调度分成两个部分,一个是调度的时机,即什么时候调度;一个是调度的算法,即如何调度和调度哪个进程。
    调度程序运行时,要在所有可运行的进程中选择最值得运行的进程。选择进程的依据主要有进程的调度策略(policy)、静态优先级(priority)、动态优先级(counter)、以及实时优先级(rt-priority)四个部分。首先,Linux从整体上区分为实时进程和普通进程,二者调度算法不同,实时进程优先于普通进程运行。进程依照优先级的高低被依次调用,实时优先级级别最高[3]。
2.3 实时调度算法及缺陷
    目前,实时调度算法主要可以分为三大类:时间驱动调度、优先级驱动调度、比例共享调度。三者各有优缺点,时间驱动调度、优先级驱动调度侧重于硬实时任务,比例共享调度更为适合于软实时任务,在网络系统中应用较多。比例共享调度基本思想就是按照一定的权重比例对一组需要调度的任务进行调度,让它们的执行时间与它们的权重成正比,是一种加权轮转调度[4]。
    Linux进程采用的是多级轮转调度算法,尽管Linux通过将进程划分为实时进程和普通进程,按照优先级进行调度来实现实时的特性,但是仅能获得秒级响应时间,Linux虽然给实时进程提供了较高的优先级,但是没有加入时间限制,在高实时响应情况下还不能满足要求。当进程进入核心态时,其它进程不管优先级多高也必须等待。
3 实时调度算法的改进
3.1 实时模型
    作为实时系统调度算法应综合考虑进程的价值和截止两个概念,以保证实时进程在截止期内尽可能多地完成,在这里提出新的调度算法,改进Linux的实时性。
    即:进程的优先级数(Vi)=该进程重要程度(Wi)+其紧迫度(pi/(d-Ti))*系数k。紧迫度的值越大,说明从时间上看这个任务越紧迫。优化后调度算法仍以进程的价值为基础,同时也关注了完成进程的紧迫度,对于优先级相同的进程,采用FIFO调度策略。进程的价值越大说明该进程越重要,CPU越应完成它。
    优化后调度算法仍以进程的价值为基础,同时也关注了完成进程的紧迫度,对于优先级相同的进程,采用FIFO调度策略。进程的价值越大说明该进程越重要,CPU越应完成它,可是对一些价值和它相差不多,而紧迫度要比它大得多的进程来说,就不公平了。例如,有两个进程A,B同时提交,A的价值是1001,估计执行时间是1ms,相对截止期是5ms,B的价值是1000,估计执行时间是1ms,相对截止期是2ms,假设这里的系数因子k是10,则更应该执行进程B。这是因为进程A,B的价值相近,而B的紧迫度要比A的大一些,A的优先级=1001+1/5*10=1003,B的优先级=1000+1/2*10=1005,因此选择B先运行,以防止B的夭折(注:Linux中实时进程的值设为从1000到1099,非实时进程的值设为从1到99,因此选择系数因子k为10)优化后的调度算法依然采用时间片轮转策略,依照Linux分配给进程的时间片为20次时钟滴哒,也就是200ms =20*10ms[5]。
3.2 结构定义
    本文给出实时进程的结构定义,非实时进程依然采用原有的动态优先级调度策略,其结构定义略去。
    #define SCHED RR
    typedef struct TaskNode {
      int dtime; //进程的截止期
      int T;//进程提交时间
      int ptime;//进程尚未完成时间,初值等于任务的执行时间估计
      int flag; //其值为1时说明是实时进程,为0时说明是非实时进程
      int v;//进程的优先级数
      int w;//进程的价值
        struct TaskNode *next
    }TaskNode *prior,*next;
3.3 链表定义
    整个调度算法可以用双链表来描述,即两级队列,分别用两个指针指向。最初,这两部分的头指针都指向“0”,表明这两个队列均为空。其中实时进程的就绪等待队列用一个循环单链表完成。
    开始时的一级队列,是新到的比当前运行进程优先级低的实时进程。如果一个进程由于时间片到时或被更高优先级任务抢占,根据它的优先级将其插入到第二级队列。
    若当前进程的时间片到时,CPU便选择当前队列中第二个节点的进程来判断,如果它的紧迫度大于1的话,说明这个进程在规定时间内不能完成,它必定夭折,将其放入普通进程队列中,再选择链表的第三个节点判断,如果紧迫度小于等于1便运行它,情况如图1所示。

图1 优化后调度算法的实时进程优先级表


    当一级队列为空时,二级队列便升成一级队列。
    普通进程的调度通过单链表来实现。如果新来的进程属于普通进程,则根据优先级高低插入普通队列。只有实时队列(一级和二级队列)为空时,普通队列才能被调度。
3.4 实时进程的调度策略算法描述
    1)实时就绪队列的初始化
      #define LEN sizeof(TaskNode)
创建空链表:
      TaskNode*creat new line()
        {
          TaskNode* head;
        head=(TaskNode))malloc(LEN);
          head->w=-1;
            Head1=Head2=head:
            Head1->next=Head2->next=head;
            return head;
          }
    2) 实时进程接收策略
  #define K 10
  void* pnow;
pnew指向新来的实时进程,pnow指向当前运行的实时进程。
新来的进程是实时进程:
  if((*pnew).flag ==1)
  {
当前运行的进程是实时进程:
      if ((*pnow).flag ==1)
        {
        W =(*pnew).v+(*pnew).ptime)/((*pnew).dtime-(*pnew).T))*K;
        if(w>(*pnow).v+((*pnow).ptime/((*pnow).dtime-(*pnow).T))*K))
        {
当前运行进程插入二级队列:
        move last runqueue(Head2,pnow);
新来的进程抢占CPU:
        pnow=pnew;
        }
        else
将新来的进程插入到等待链表的一级队列:
            move last runqueue(Head1,pnow);
        }
        Else
当前运行的进程是非实时进程,将当前进程插入非实时队列,非实时进程的插入算法:
          move last(pnow);
 move last略
  }
  else//新来的进程是非实时进程
    move last(pnew);//将新来的非实时进程插入非实时队列插入算法略
    3)实时进程插入策略
  move last runqueue(h,p);
  TaskNode*h,*p;
  {
    TaskNode*p1,*p2,*t;
    P1=h;
    P2=pl->next;
    if (h==Head1)//插入一级队列
    while((*p).w<=(*p2).w&&pl!=Head2)//优先级相同的进程采用FIFO调度策略
    {
      pl=p2;
      p2=(*p2).next;
      }
      (*p).next=p2;
      (*p1).next=P;
      if(P1==Head2)//该节点插入到一级队列的末尾,则该节点便成了一级队列的末尾
          Head2=P;
        else
        {
          While((*p).w<=(*p2).w)  //插入二级队列
          {
            P1=p2;
            p2=(*p2).next;
            (*p).next=p2;
          (*p1).next=P;
            }
        }
  }
    说明:根据传来的h值,决定在一级队列h的值是Headl时还是在二级队列h的值是Head2时中查找插入的合适位置。
    当P是新来的任务时,h的值是Head1,p被括入一级队列。p2是p1的后继节点。在循环体中,当新来的进程P高于一级队列的进程p2时,停止循环,将P插入到p1的后面;当p1等于Head2时,说明一级队列的节点的优先级都比P节点的高,停止循环,把P插在p1的后面,则该节点便成了一级队列的末尾。
    当P是被抢占的任务时,h的值是Head2,p被插入二级队列。在循环体中,当P的优先级高于二级队列的进程p2时,停止循环,将P插入到p1的后面;如果P高于二级队列的所有进程时,也会在p2指向Head时,因(*p).w<=(*p2) .w而停止,则该节点便成了二级队列的末尾。因为((head1).w=-1,而任何进程的优先级数都不会小于1因此当p1,p2在这二级队列中遍历时,一定能有机会停止。
    4) 调度等待链表中的一级队列
    当前进程完成或时间片到时,调度等待链表中的一级队列中最前面的实时进程:
PnowTime;//当前的时间
    run list(pnow);
    TaskNode*pnow;
    {
      if(*pnow).ptime!=0)//该进程未完成
        {
          if(*pnow).flag==1)
            if(PnowTime-(*pnow).T>=(*pnow).dtime)
              move-last-runqueue(head2,now);//将未完成的进程插入到              二级队列
                  else
                  pnow; //被夭折
              else
            move last(pnow); //将未完成的非实时进程插入到非实时队列
            }
        p=get node( );从就绪链表中获得优先级最大的进程
          while(1)
          {
              if (p! =NULL)
                {
                if ((*p).time <= (*p).dtime-PnowTime)) //实时进程并且没超过截止期
pnow=P;
break;
else//该进程己经不能完成,所以重新从就绪链表中获得优先级最大的进程
                  p=get node;
                  }
          else//实时就绪链表中无等待的进程调用非实时就绪队列
                  return p;
        }
    5)实时进程删除策略
    //curtime是当前的时间
    get node()
    {
      p=(Headl).next;
      while(1)
      if (Head1).next!= Head1)//有进程就绪等待
        {
          p=(Headl).next;
          if((*p).ptime>((*p).dtime-Pnowllme)) //进程未完成的时间大于相对截止期,该进程夭折
          {
              (Head1).next=(*p).next;
            if(p= =Head2)//删除的节点是一级队列的尾节点时
              {
                Head2=Head3;//二级队列荣升为一级队列
                  Head3=Head2;//新二级队列为空
              }
}
else
else      //p进程可以在规定时间完成
return p;  //无进程等待
return NULL;
    针对目前Linux实时系统调度算法中仅用进程的价值来确定优先级的现象,本文提出了综合考虑进程的重要性和紧迫度来决定优先级的调度算法。算法将进程的截止期和价值两个不相关的概念,通过公式结合在一起,用来计算就绪等待队列中进程的优先级数。
    该算法通过双链表来实现。在CPU正常负载的情况下,优化后的调度算法体现了更优的实时性能。

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

上海2023年9月19日 /美通社/ -- 近日,上海浦东新区举行2023年经济突出贡献企业表彰活动,向企业颁出经济特别贡献、科技创新突出贡献、先进制造业突出贡献、民营企业突出贡献等九大奖项。活动上,波士顿科学获得“20...

关键字: 医疗器械 进程 内窥镜 医疗技术

上海2023年9月12日 /美通社/ -- 近日,由SGS通标标准技术服务有限公司主办、同济大学张存满教授联合发起的"SGS中国制氢行业高峰论坛"于成都圆满闭幕。本次会议得到了上级单位中国标准化研究院...

关键字: AN 进程 NI 测试

北京2023年9月8日 /美通社/ -- 近日,浪潮信息与连用科技达成合作,双方将充分发挥各自行业领域内的专业优势和资源,在产品、技术、解决方案、市场营销等方面进行深度合作,共同推动企业内容管理的数智化转型进程。...

关键字: 软硬件 智能化 大数据 进程

深圳2023年8月31日 /美通社/ -- 2023年8月30日,德国莱茵TÜV(以下简称"TÜV莱茵")集团首席执行官、管理执行董事...

关键字: MICHAEL 新能源 进程 智能制造

(全球TMT2023年8月29日讯)优克联集团宣布与MAYA Net Solution Co., Ltd (MAYA)和NTT Media Supply Co., Ltd.(日本电信电话株式会社旗下子公司)共同启动物联...

关键字: 进程 物联网 MEDIA COO

杭州2023年8月24日 /美通社/ -- 近日,趣链科技成功通过联合国全球契约办公室审核,正式加入联合国全球契约组织(UNGC)。这不仅是对公司多年来践行社会责任的充分肯定,同时也代表着趣链科技以中国区块链领军企业的身...

关键字: 可持续发展 智慧城市 进程 APP

上海2023年8月23日 /美通社/ -- 2023年8月23日,时值全球领先的实时3D引擎Unity在华设立合资公司Unity中国一周年之际,担负着赋能本土开发者、服务国内...

关键字: UNITY 开发者 微信小游戏 进程

北京2023年8月21日 /美通社/ -- 8月18日,用友网络主办的"2023全球商业创新大会"在上海隆重召开。本次大会以"数据驱动 智能运营"为主题,汇聚优秀企业代表、技术大咖...

关键字: 数字化 网络 AI 进程

刚入门嵌入式,选入门级RZ/G2L开发板,采用邮票孔形式封装了RZ/G2L核心板。

关键字: 开发板 嵌入式LINUX 嵌入式系统

深圳2023年3月14日 /美通社/ -- 当地时间3月10日,理邦秘鲁办事处在利马圣伊西德罗正式设立,理邦全球化战略再上新台阶,将为拉丁美洲,尤其是为安第斯地区的客户提供更适宜当地需求的解决方案,成为助推拉美市场实现跨...

关键字: 仪器 医疗器械 超声 进程
关闭
关闭