内核实现基本原理

    VxWorks 内核维护三个队列:tick队列、ready 队列、active 队列。另外还有一个队列涉及任务,即任务等待资源时所处的队列,这个队列可以是VxWorks内核提供的,也可以是用户提供的,此处令其为pend队列。
    所谓tick 队列,即当调用taskDelay 函数让任务延迟一段固定的时间时,任务所处的队列,此时任务被设置为Delay状态,无资格竞争使用CPU;ready队列即有资格竞争使用CPU的所有任务,该队列以优先级为序排列任务,队列头部是除了当前运行任务外,系统中最高优先级的任务;active 队列有些误导,实际上称之为task 队列更合适,因为系统中所有的任务无论当前状态如何,都将在这个队列中,这个队列维护着系统中当前所有的任务,即通过该队列可以查找到当前系统中的所有任务,在Shell 下运行“i”命令,显示系统中所有的任务,就是通过遍历active队列完成的;pend队列即当任务竞争使用某资源,而资源当前不可得时,任务就被设置为pend状态,进入pend队列。
    函数taskSpawn 创建一个新的任务。首先,其创建一个任务控制结构,对该结构进行初始化后,将结构加入active队列以作为系统任务管理之用。此时任务仍无资格竞争使用CPU,taskSpawn函数的最后一步就是将这个任务结构再加入到ready队列,此时这个任务才真正可以称为已经在竞争使用CPU了。当系统中所有的优先级高于这个任务的其他任务运行完毕或者由于等待资源而处于阻塞时,这个新创建的任务就将被调度运行。所以,在VxWorks下,如果一个新创建的任务优先级不高,创建后将等待一段时间才能被真正执行。在实际项目中,有时需要一个新的任务被创建后立刻得到执行,那么就需要在创建任务时,指定一个较高的任务优先级。VxWorks
内核将任务分为256个优先级,标号从0到255。其中 0表示最高优先级,255表示最低优先级。任务在调用taskSpawn 函数进行创建时就指定了优先级,当然任务的优先级并非在创建后就无法改变,用户可以通过调用taskPrioritySet函数在任务创建后重新设定优先级,taskPrioritySet专门针对嵌入式平台下不同的情况对同一任务不同运行级别的需求进行设置。值得注意的是,taskPrioritySet函数不同于通用操作系统提供的类似函数,taskPrioritySet函数可以提高或者降低任务的运行级别,而不是通用操作系统下在任务创建后就只能动态地降低任务优先级。
    VxWorks 下对于应用层任务,推荐使用100~250 之间的优先级,驱动层任务可以使用51~99 之间的优先级。要特别注意的是,内核网络数据包收发任务tNetTask的优先级为50,如果使用网口进行调试,则一定注意不要创建任务优先级高于50 的任务,否则tNetTask 任务将无法得到运行,表现形式是死机,因为系统将无法再从网口接收调试命令,无法响应Tornado Shell或者Telnet下输入的任何命令。以上只是推荐值,事实上,由于嵌入式系统下的特殊应用,对于某个任务优先级的设置需要根据该任务完成的具体工作而定,而不可一味地遵循推荐值。要谨记在任务达到某一特殊目的后,必须将任务优先级设置回正常(推荐)值。
    无论何种操作系统,任务在设计中都由一个数据结构表示。这个数据结构包含一个任务运行时需要的所有信息,我们一般将这些信息称为任务上下文。具体的任务上下文(广义上)包括以下内容:
    1)所在平台CPU 内部所有的寄存器值,特别是指令寄存器,这代表了任务当前的执行点。这一般是狭义上的任务上下文。除了寄存器值,每个任务有自己的内存映射空间、任务名称、任务优先级值、任务入口函数地址、打开文件句柄数组、信号量和用于各种目的的队列等。
    2)任务运行时暂时存放函数变量以及函数调用时被传递参数的栈。从操作系统底层实现来看,很多操作系统将表示任务的数据结构和任务栈统一管理,如Linux 下在分配任务结构的同时分配任务的内核栈,这两者作为一个整体进行内存分配,通常将一页(如4KB)的开始部分作为任务结构,用以存储任务关键信息,而将页的末尾作为任务内核栈的顶部。如此,实际上用一页页面的大小(通常为4KB)减去任务信息占据的空间,剩下的空间都作为任务的内核栈在使用。VxWorks 与Linux 在栈的分配和管理上基本类似,不过VxWorks
区分于Linux 的一个最大不同是VxWorks 下所有的代码都运行在一个状态下,不区分内核态和用户
态。VxWorks下的任务自始至终都在使用同一个栈,不论这个任务在运行过程中调用了任何VxWorks内核函数,都不存在栈的切换。正因如此,VxWorks对栈的大小无法预先进行把握,栈的大小将由被创建的任务决定,而且不同于通用操作系统,VxWorks下任务栈在任务创建时就被确定,而且此后不可以改变栈的大小。所以,对于一个存在很多递归调用的任务,必须在任务创建时指定一个较大的任务栈,防止在后续的运行中造成栈的溢出,导致任务异常退出。
    3)各种定时信息。这些信息实际上都作为任务结构中的一个字段而存在。任何操作系统都必须有一个系统时钟进行驱动,该系统时钟通常称为系统的脉搏。系统时钟一定与一个高优先级的中断联系,这样,每当时钟前进一个滴答(Tick),操作系统就会响应一次中断,该中断通常就被作为操作系统进程调度的触发点。每次滴答,操作系统都会增加内核维护的一个全局变量(如VxWorks操作系统维护的vxTick变量),通过该变量为系统各种定时器提供定时依据。每个任务都有一个内部固定的定时器,用于任务内部特定的需求,每次系统时钟产生一个中断,操作系统都会对当前系统内所有需要关注的任务定时器进行处理,从而完成任务定时器特殊的用途。定时器的一个特殊变相应用即Round-Robin
任务调度(简称RR 调度)。RR 调度实际上对每个支持RR 调度的任务内部都维护有一个定时器。当一个支持RR调度的任务被调度进入运行状态时,在任务运行期间,每次系统时钟前进一个滴答时,该定时器指针都会前进一个单位。当到达预定的值时,该任务就要主动让出CPU,以便让相同优先级的其他任务运行。定时器可以以加法或者减法运算运行。对于减法运算,一般根据定时时间计算出一个Tick数,每次系统前进一个滴答,Tick数减一,当到达0 时,表示定时器到期。而对于加法运算,则一般需要使用操作系统维护的全局Tick变量。VxWorks下,如设置
定时时间间隔为N,则定时器到期时间为vxTick+N=T0,每次系统前进一个滴答,操作系统会对当前系统内维护的所有定时器进行检查,判断T0是否大于vxTick,一旦T0小于或等于vxTick,则表示该定时器到期,此时将根据定时器的目的做出相应的响应。
    4)信号处理函数。事实上,操作系统的每个信号都有一个默认的响应方式,如用户在命令行       按“Ctrl+C”组合键时,则系统默认响应方式是中止当前前台任务。每个任务可以根据自身情况定制对某个信号的响应方式。如一个任务可以将用户的“Ctrl+C”组合键操作响应为打印输出当前任务中某个变量的值。每个任务内部对每个信号都维护一个响应函数句柄,操作系统在创建任务时已经将所有的句柄设置为系统默认方式,用户在创建任务后,可以针对某个信号安装自己的信号响应句柄。
    5)其他辅助信息。这些信息包括统计上的一些数据,如任务运行总时间、任务最终返回值等。

阅读(1069) | 评论(0) | 转发(5) |

vxWorks内核实现基本原理的更多相关文章

  1. VxWorks 6.9 内核编程指导之读书笔记 -- Singnals

    Signals 信号是操作系统用于异常处理和异步控制流的关键.在很多方面,信号相当于软件方面的硬件中的中断.操作系统产生的信号包括总线错误和浮点处理异常.信号也提供了API来管理和产生信号.在应用程序 ...

  2. VxWorks 6.9 内核编程指导之读书笔记 -- C++开发

    5.1 介绍 针对C++的VxWorks配置 C++头文件 使用C++启动任务 C和C++之前调用代码 C++编译器说明 在信号处理和ISR中使用C++ 下载C++编写的内核模块 C++编译器的不同 ...

  3. VxWorks 6.9 内核编程指导之读书笔记 -- VxWorks kernel application (一)

    #1 什么是内核应用程序? #2 开发内核应用程序注意事项 什么是内核应用程序? 内核应用程序不同于RTP程序,它允许在内核态,与操作系统使用相同的地址空间.因此,它与操作系统会相互干扰.它可以编译成 ...

  4. 如何参与Linux内核开发(转)

    本文来源于linux内核代码的Document文件夹下的Hoto文件.Chinese translated version of Documentation/HOWTO If you have any ...

  5. 如何参与linux 内核开发

    如果想评论或更新本文的内容,请直接联系原文档的维护者.如果你使用英文 交流有困难的话,也可以向中文版维护者求助.如果本翻译更新不及时或者翻 译存在问题,请联系中文版维护者.   英文版维护者: Gre ...

  6. 基于嵌入式操作系统VxWorks的多任务并发程序设计(1)――基本概念

    1引言 嵌入式系统定义义为:嵌入到对象体系中的专用计算机系统."嵌入性"."专用性"与"计算机系统"是嵌入式统的三个基本要素,对象系统则是指 ...

  7. VxWorks 基本启动方式

    VxWorks 基本启动方式     按VxWorks内核的下载形式,VxWorks启动总体上分为两种方式:下载型和ROM 型.     @下载型启动方式:bootrom+VxWorks.此时boot ...

  8. vxWorks驱动架构

    Vxworks内核驱动基本结构: 三张表:1. 系统设备表  2. 系统驱动表 3. 文件描述符表     Vxworks 内部对每个设备使用DEV_HDR 数据结构进行表示: Typedef str ...

  9. VxWorks 操作系统内存布局

    在VxWorks操作系统过程中可能使用到的BootRom和VxWorks内核映像本身都可以存在两种方式:压缩的和非压缩的. 1.非压缩形式 如果没有进行压缩,则只有一次重定位,即从ROM到RAM只存在 ...

随机推荐

  1. Cypher查询语言--Neo4j 入门 (一)

    目录 操作符 参数 标识符 注解 Start 通过id绑定点 通过id绑定关系 通过id绑定多个节点 所有节点 通过索引查询获取节点 通过索引查询获取关系 多个开始点  Cypher是一个描述性的图形 ...

  2. javascript中的BOM对象

    1.window对象 所有的浏览器都支持window对象 概念上讲,一个html文档对应一个window对象 功能上讲,控制浏览器窗口 使用上讲,window对象不需要创建对象,直接使用 2.wind ...

  3. K-means聚类的Python实现

    生物信息学原理作业第五弹:K-means聚类的实现. 转载请保留出处! K-means聚类的Python实现 原理参考:K-means聚类(上) 数据是老师给的,二维,2 * 3800的数据.plot ...

  4. log4cpp退出时内存泄露的修复方案

    1.缘由 一直对log4cpp非常有好感,就在自己的项目中集成了log4cpp1.1.1版本,并围绕着它建立了一系列的封装函数方便外部调用.写完了一个测试代码后,忽然想看看自己写的程序有没有内存泄露问 ...

  5. 嵌入式linux系统的构建

    前期工作:a.配置好tftp服务器:在嵌入式的童年中有介绍 b.开发板可以pc,linux 三者可以互相ping通 c.配置好nfs服务器:同样在嵌入式的童年中有介绍 一.嵌入式linux内核的制作( ...

  6. nodejs事件循环

    1. 只有一个主线程,node开始执行脚本时,会先进事件循环初始化(同步任务,发出异步请求,规划定时器生效时间,执行promise.nextTick等),这是事件循环还未开始. 2. nodejs每一 ...

  7. 解决angularjs 在ie8上面 ng-repeat的select控件兼容性问题

    问题描述: 在ie8下生成select的option时候使用ng-repeat,会造成下拉列表的列表显示值为{{x.displayname}}的形式,但是选中之后,选中值却又是正确的,此问题不在chr ...

  8. python装饰器探究与参数的领取

    首先上原文, 现在,假设我们要增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为"装饰器" ...

  9. [Codeforces]817F. MEX Queries 离散化+线段树维护

    [Codeforces]817F. MEX Queries You are given a set of integer numbers, initially it is empty. You sho ...

  10. 【HTTP协议】---TCP三次握手和四次挥手

    TCP三次握手和四次挥手 首先我们知道HTTP协议通常承载于TCP协议之上,HTTPS承载于TLS或SSL协议层之上 通过上面这张图我们能够知道.     在Http工作之前,Web浏览器通过网络和W ...