微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > Nut/OS和μC/OS—II的实时调度算法比较

Nut/OS和μC/OS—II的实时调度算法比较

时间:04-07 来源:单片机及嵌入式系统应用 点击:

所示。

  如果创建成功,NutThreadCreate()将返回一个指向新创建的线程控制块的指针,新创建的线程控制块将放置在线程控制块链表前面,nutThreadList指针总是指向这个链表的第一个控制快。现在假设某一个应用中只有3个线程,1个隐藏线程、1个主线程和1个应用线程。其中隐藏线程(threads3)中创建了主线程(Threads2),主线程中又创建了应用线程(Threadsl)。由于一开始只有一个隐藏线程,因此nutThreadList链表指向了隐藏线程。当隐藏线程创建了主线程时,主线程控制块添加在隐藏线程控制快链表的前面,因此nutThreadList链表指向主线程。当主线程创建了应用线程,应用线程控制块添加在主线程控制块的前面,因此nutThreadList链表改为指向应用线程。这就组成了一个如图2所示的链表。

  由图2可知,Nut/OS采用4个链表来管理系统中的全部线程,其中runQuene总是指向全部就绪线程链表,这个链表由td_qnxt指针链成。td_qnxt链表与td_next链表形成机制不同。在td_next链表中,新创建的线程总是简单地放在链表的前面,这个链表包括所有的线程控制块;而td_q
nxt链表是根据优先级顺序排序的,一个线程只有处于就绪态(TDs_READY)或者运态(TDS_RUNNING)才能包括在这个链表中。

  隐藏线程的优先级为254,并且总是将该线程的td_next和td_qnxt设为空指针。线程的退出机制就是将要退出的线程的优先级设为255。由于这个线程的优先级比隐藏线程还低,而隐藏线程又没有指向该线程的指针,因此这个退出线程永远也不可能被运行。

  按优先级调度是通过mnQuene链表来实现的。Nut/OS提供了2个API来操作这个链表,其中插入操作的代码如下:

  该API函数表明,runQuene链表是一个按优先级排序的链表,优先级高的线程控制块总是在最前面,当发现有相同优先级的线程控制快时,总是把后来的插到相同优先级线程控制块的最后面。这就自然实现了对相同优先级线程按先来先服务的算法进行调度。

  当就绪进程集合发生变动时,则调用NutThreadRemoveQueue()、NutThreadAddPriQueue()完成链表的更新让runQuene指向更新后的链表头。接下来的事就是上下文切换了。

  通过链表这个简单的数据结构,Nut/OS也很简洁地实现了实时调度算法。阅读过Linux源代码的人对链表的重要性可能更是感同身受,虽然Linux操作系统堪称完美,但源代码却并不怎么规范,事实上造成了Linux源代码复杂难懂;而同是开源的Nut/OS,代码却相当规范,给我们提供了非常好的学习资料。笔者在这里感谢该系统的开发人员Harald Kipp和沈文先生等,以及那些热爱开源并热心奉献的工程师。

  结语

  μC/OS-II的实时性已经通过了非常严格的测试,事实上成了笔者比较其他系统实时性能的一个基准。在这次毕业设计工作中,采用Nut/OS实现8位机接入以太网,运行良好。不妨推测,在一些商品实时操作系统里,对优先级调度算法的实现采用的机制和Nut/OS是类似的。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top