IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> OSEventPendMulti因使用不当导致的软件偶发性监听不到某个事件 -> 正文阅读

[嵌入式]OSEventPendMulti因使用不当导致的软件偶发性监听不到某个事件

前言

公司的一款产品,使用ucosii操作系统,任务间的整体通讯思路是依赖OSEventPendMulti函数完成不同任务之间的消息传递.而某个任务的OSEventPendMulti函数经常性的收不到特定消息.

分析

分析这个OSEventPendMulti函数等待的事件,一共等待4个事件,分别是两个来自其他任务的事件,和systick每隔200ms发出的空消息邮箱事件(做200ms定时器功能), 以及RTC每隔1秒发出的空消息邮箱事件(做1000ms定时器使用). 其中RTC发出的事件,经常性的收不到.对发消息和收消息处展开分析,最终定位到了问题所在.假定有bug的那个任务为任务L,

RTC中断中一共发送3个消息给到不同的任务,任务L的优先级是最低的.由于RTC是在中断中发消息,消息发送后并不会立即产生调度,而是等到中断退出时才会产生调度.所以中断退出时并不会立即调度到任务L,而是调度到其他优先级更高的任务.

给任务L发送消息时,在发送消息函数内部调用OS_EventTaskRdy 其中ptcb->OSTCBEventMultiRdy = (OS_EVENT *)pevent;任务L保存了这个事件,看到这里,一下子想到,OSEventPendMulti不会单次仅返回一个就绪事件吧.

OS_EventTaskRdy函数内部.
#if (OS_EVENT_MULTI_EN > 0u)
    if (ptcb->OSTCBEventMultiPtr != (OS_EVENT **)0) {   /* Remove this task from events' wait lists    */
        OS_EventTaskRemoveMulti(ptcb, ptcb->OSTCBEventMultiPtr);
        ptcb->OSTCBEventMultiPtr  = (OS_EVENT **)0;     /* No longer pending on multi list             */
        ptcb->OSTCBEventMultiRdy  = (OS_EVENT  *)pevent;/* Return event as first multi-pend event ready*/
    }
#endif

经查验果然如此.问题到此逐渐明朗,任务L虽然已就绪,但是还要等待其他高优先级的任务调度完成才能调度.而此时其他高优先级的任务运行又比较耗时.所以任务还没有得到调度时. systick中断中又向任务发送了一个消息, 导致OSTCBCur->OSTCBEventMultiRdy被新的消息覆盖. 等到任务L得以调度时,RTC发出的消息已经被覆盖,所以没有得以运行.

switch (OSTCBCur->OSTCBStatPend) {                  /* Handle event posted, aborted, or timed-out  */
    case OS_STAT_PEND_OK:
    case OS_STAT_PEND_ABORT:
    // 获取到OSTCBEventMultiRdy指向的事件. 
         pevent = OSTCBCur->OSTCBEventMultiRdy; 
         if (pevent != (OS_EVENT *)0) {             /* If task event ptr != NULL, ...              */
            *pevents_rdy++   =  pevent;             /* ... return available event ...              */
            *pevents_rdy     = (OS_EVENT *)0;       /* ... & NULL terminate return event array     */
            events_rdy_nbr =  1;

         } else {                                   /* Else NO event available, handle as timeout  */
             OSTCBCur->OSTCBStatPend = OS_STAT_PEND_TO;
             OS_EventTaskRemoveMulti(OSTCBCur, pevents_pend);
         }
         break;

解决

问题的解决方案有很多,知道了OSEventPendMulti的这个特性,在使用时就要多加注意,在这个项目中因为收到消息处理的事务并不多,我就直接删除了RTC发送的那个消息.让L任务中每隔一秒运行的事件,放在200ms事件中累加5次后运行。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-01-12 00:10:05  更:2022-01-12 00:10:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/9 1:15:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码