当前位置:首页 > 嵌入式 > 嵌入式教程
[导读]深入探讨《Small RTOS51中消息队列的一处隐患》

摘要:Small RTOS51是一款重要的小型实时内核,消息队列是其提供的重要任务间通信的机制。针对其消息队列实现代码中的缺陷以及可能导致的消息丢失这一严重问题,从操作系统等待与唤醒机制理论的角度出发,剖析Small RTOS51内核在消息队列甚至互斥型信号量等实现机制上的漏洞所在;进一步指出原内核实现方式的修改方法,以及《Small RTOS51中消息队列的一处隐患》作者提出的第2种修改方法的完美实现。

关键词:Small RTOS51 消息队列 唤醒模型 隐患分析

引言

  贵刊2005年第7期《Small RTOS51中消息队列的一处隐患》一文,对Small RTOS51V1.12.1版本的消息队列机制进行了周密的分析,不但找出了问题所在,也提出了相应的两种解决方法[1]。实时嵌入式系统对于安全性有很高的要求,作为实时嵌入式系统的内核,不但要求精简高效,更要加强安全,防止因操作系统出错而在应用领域导致灾难性的后果。因此原文作者所做的工作极有价值,同时也感谢贵刊对这一领域的高度重视。

  因为这一问题涉及到内核的等待与唤醒机制,并且正是由于对内核的等待与唤醒机制的理解与运用不同,才导致了问题的出现,所以本文从操作系统理论的高度以及目前主流的实时内核的实现方法两方面入手论述这一问题,并揭示如何才能完美实现原文的第2种方法。

1 内核唤醒机制的三种模型

  当利用系统调用接口获取资源时,如果资源不满足,系统调用可以返回错误,也可以根据选项悬挂等待;当有任务释放资源从而资源可以满足时,就要将资源等待队列中的相关任务唤醒。唤醒模型有三种[2]:
第1种,将该资源等待队列中的任务全部唤醒,让这些任务与系统中的其他任务平等竟争资源。这种策略会使系统在一段时间内繁忙,因为最终只有一个任务获取到资源,其他任务可能将经历一个从就绪态到运行态再到阻塞态的过程。这种现象在操作系统理论上称为“千军万马奔腾”。就目前的一些主流实时内核VxWorks、Nucleus、uC/OS?II等来讲,都没有采用这种策略。

  第2种,将该资源等待队列中的一个任务唤醒,依据所采用的策略不同,可以是等待任务中优先级最高的,也可以是第1个进入等待队列中的任务。这个任务被唤醒后将和系统中的其他任务一起竞争这个资源。如果这个任务最终没有竞争到这个资源,它将再次进入该资源的等待队列并进行任务调度。

  第3种,将该资源等待队列中的一个任务唤醒,依据所采用的策略不同,可以是等待任务中优先级最高的,也可以是第1个进入等待队列中的任务,这点和第2种方法是一样的。和第2种情况不同的是,这个任务被指定为资源的获得者。主流实时内核VxWorks、Nucleus、uC/OS?II等都采用这种策略。以VxWorks为例,其内核文档指出[3]:“任务或ISR调用msgQSend()向消息队列发送消息。此时如果没有任务在等待该队列中的消息,那么该消息进入消息队列的缓冲;如果有任务等待该队列的消息,那么这个消息立即提交给第1个等待的任务。”这段话有两方面的含义:① 明确指出第1个等待的任务获得资源;② 第1个等待的任务获得资源的方式是直接从消息的发送者那里获得,也就是说这个消息将不进入消息队列进行缓冲,消息在发送者和接收者之间进行手把手的传递。对于这种机制的实现,可以以著名的源代码公开的实时嵌入式操作系统Nucleus为例。下面是Nucleus内核关于接收消息的一段精彩的代码:
else {
  /* 消息队列为空,决定是否悬挂等待*/
  if (suspend) {
    /* 增加等待该消息队列的任务数量 */
    queue -> qu_tasks_waiting++;
    /* 填充悬挂块数据结构并且悬挂该任务*/
    suspend_ptr =&suspend_block;
    suspend_ptr -> qu_queue=queue;
    suspend_ptr -> qu_suspend_link.cs_next=NU_NULL;
    suspend_ptr -> qu_suspend_link.cs_previous=NU_NULL;
    suspend_ptr -> qu_message_area=
              (UNSIGNED_PTR) message;
    suspend_ptr -> qu_message_size=size;
    task=(TC_TCB *) TCT_Current_Thread();
    suspend_ptr -> qu_suspended_task=task;
    /* 判断该消息队列的等待方式是先进先出还是按任务
    的优先级 */
    if (queue -> qu_fifo_suspend) {
      /* 是先进先出等待方式,将悬挂块链入消息队列
      的等待链表 */
      CSC_Place_On_List((CS_NODE **)
          &(queue -> qu_suspension_list),
          &(suspend_ptr -> qu_suspend_link));
    }
    else {
      /* 按优先级方式将悬挂块链入任务等待链表的
      合适位置 */
      suspend_ptr -> qu_suspend_link.cs_priority =
              TCC_Task_Priority(task);
      CSC_Priority_Place_On_List((CS_NODE **)
            &(queue -> qu_suspension_list),
            &(suspend_ptr -> qu_suspend_link));
    }
    /* 悬挂调用任务,并自动取消该消息队列的临界区
    保护 */
    TCC_Suspend_Task((NU_TASK *) task,
            NU_QUEUE_SUSPEND,
            QUC_Cleanup, suspend_ptr, suspend);
    /* 获取该系统调用要求的返回状态以及返回值*/
    status =suspend_ptr -> qu_return_status;
    *actual_size =suspend_ptr -> qu_actual_size;
    }
    else
    /* 在消息队列为空以及不等待的方式下,返回状态
    指示消息队列为空*/
    status =NU_QUEUE_EMPTY;
}

  这段代码是处理消息队列中没有消息时的情况的,并且在不进行悬挂等待时返回码是NU_QUEUE_EMPTY,提示队列为空。我们注意到在选择悬挂等待的情况下,填充了suspend_ptr指针所指的一个悬挂块结构,suspend_ptr -> qu_message_area填充的是接收任务指定的接收缓冲区指针,suspend_ptr -> qu_message_size填充的是接收任务指定的接收消息长度。接下来依据不同的等待策略(任务优先级或FIFO),将填充好的消息队列悬挂块链入该消息队列的悬挂等待链表中,进行任务调度。正是有了这个消息队列悬挂块数据结构,将来发送消息的任务依据这个悬挂块中指定的接收消息缓冲区指针,把消息从发送任务直接复制到接收任务。当接收消息的任务被唤醒并获得执行权后,只是简单地依据悬挂块中的相关域的内容返回系统调用而已。从上述分析可以看出,悬挂块数据结构起着重要的作用,它不仅标明了是哪个任务在等待,也标明了等待任务的一些详细信息,同时也有结果状态域。通过对Nucleus内核定时器机制的分析得知,在任务等待资源超时的情况下,悬挂等待块的结果状态域将被填充NU_TIMEOUT。

2 针对Small RTOS51消息队列的分析


  有了上述三种模型的分析,很容易看出Small RTOS51V1.12.1版消息队列所采用的是第2种模型,只是在实现时出现重大遗漏,被唤醒的任务没有竞争到资源时应重新进入等待表,而其内核代码却没有体现到这一点。这一点《Small RTOS51中消息队列的一处隐患》的作者已经分析得很清楚,其提出的第1种解决方案也很正确。重点是第2种解决方案。第2种解决方案属于第3种模型,但其实现技术欠佳。正如原文作者所指出的那样,第2种方案具有其自身不可调和的矛盾:“在发送消息的OSQIntPost()函数中,如果检测到有任务正在等待此消息,则并不把消息数(buf[0])加1”,但这个消息毕竟进入消息队列了,这就造成了一种矛盾状态,消息数与消息队列中的实际消息不相符。为了实现第3种模型的效果,即被唤醒的等待任务获取资源,在消息数为0的情况下,原文作者通过进一步判断该任务是否还处在消息队列的等待任务表中,来决定该任务是否从消息队列中获取消息;但消息数为0而消息队列中还有消息却为发送消息带来隐患。要想解决这一矛盾,OSQIntPost()在唤醒等待任务的同时就应该将该消息传递给这个任务,这样消息数仍然为0才不留隐患。uC/OS?II实现这一策略的技术是任务被唤醒后检查任务控制块中的OSTCBCur->OSTCBMsg这一数据域[4,5],获取到的消息指针在此。注意,OSQPost()在有等待任务的情况下,如下处理:
  if (pevent->OSEventGrp != 0x00) { /* 判断是否有任务悬挂在消息队列的等待表中            */28OS_EventTaskRdy(pevent, msg,OS_STAT_Q); /*将等待表中最高优先级任务唤醒*/
    OS_EXIT_CRITICAL();
    OS_Sched(); /* 进行任务调度,运行最高优先级任务*/
    return (OS_NO_ERR);
  }

  即消息指针没有进消息队列并且消息指针通过OS_EventTaskRdy(pevent, msg, OS_STAT_Q)传给被唤醒的任务。这一作法符合第3种模型。

  由此可见,Small RTOS51V1.12.1要想实现第3种模型,其内核的数据结构需要有一些变化,像原文第2种方案那样修改代码,是不能最终解决问题的。同Nucleus相比,实现消息队列时,uC/OS?II虽然没有引入悬挂等待块的概念,但其通过在任务控制块中引入相应数据项来最终实现第3种模型,并且结果是在任务被唤醒后进行判断的。

3 结论

  虽然各种各样的实时嵌入式操作系统千差万别,但从操作系统理论的角度分析,很容易将它们纳入到某一具体的模型;实现细节有很大的不同,但其实现的功能应符合通用原理。在操作系统理论的指导下,结合具体的实例源代码分析、理解和应用,才能有更大的把握。

                 参考文献

1 陈皓. Small RTOS51中消息队列的一处隐患. 单片机与嵌入式系统应用,2005(7)
2 Jim Mauro,Richard McDougall.Solaris内核结构.北京:机械工业出版社,2001
3 孔祥营,等. 嵌入式实时操作系统VxWorks及其开发环境Tornado. 北京:中国电力出版社,2001
4 Labrosse Jean J.uC/OS?II——源码公开的实时嵌入式操作系统.北京:中国电力出版社,2001
5 Labrosse Jean J.嵌入式实时操作系统uC/OS?II.北京:北京航空航天大学出版社,2003

韩明峰:硕士,主要研究方向为实时嵌入式系统。

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

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭