搜索
bottom↓
回复: 5

请教:uC/OS-II“周期性执行任务”中,如何考虑特殊情况(事件触发及连续执行)?

[复制链接]

出0入0汤圆

发表于 2010-12-27 11:30:33 | 显示全部楼层 |阅读模式
uC/OS-II中,任务有三种类型:

     (1)、单次执行的任务
            此类任务在创建后只执行一次,执行结束后即自行删除
            void  MyTask (void *pdata)          //单次执行的任务函数  
           {  
              进行准备工作的代码;  
              任务实体代码;  
              调用任务删除函数;   //调用 OSTaskDel(OS_PRIO_SELF)  
            }

     (2)、周期性执行任务
           此类任务在创建后按一个固定的周期来执行,其任务函数的结构如下:
           void  MyTask (void *pdata)          //周期性执行的任务函数  
          {  
               进行准备工作的代码;  
               for (;;)      //无限循环,也可用 while (1)  
               {  
                  任务实体代码;  
                  调用系统延时函数;  //调用 OSTimeDly( )或 OSTimeDlyHMSM( )  
               }  
           }

     (3)、事件触发执行的任务
            相关事件发生一次,该任务实体代码就执行一次,故该类型任务称为事件触发执行的任务,其任务函数的结构如下
            void  MyTask (void *pdata)          //事件触发执行的任务函数  
           {  
              进行准备工作的代码;  
              for (;;)      //无限循环,也可用 while (1)  
              {  
                  调用获取事件的函数;  //如:等待信号量、等待邮箱中的消息等等。
                  任务实体代码;  
               }  
           }  





  我现在遇到一个问题,想把前后台这样在段代码移植到uC/OS-II中。

      在前后台中,有三个函数,分别实现“输出指令”的计算。

           (1)、函数1
                  用于控制器正常调节时,通过PID控制,计算阀门的输出指令,去控制阀门的开度。
           (2)、函数2  
                  当出现异常情况时(检测到某一个开关量信号),立即紧急关闭阀门,即:强制输出指令等于0
                  同时,必须要强制“输出指令=0”连续维持3秒,才能确保管道中的蒸汽压力不会继续升高。
           (3)、函数3
                  处理报警和报警回差
                  当(管道中的蒸汽压力 > 报警值),立即紧急关闭阀门,即:强制输出指令等于0
                  同时,只要(管道中的蒸汽压力 > 报警值),就一直关闭阀门(强制输出指令等于0)
                  当检测到(管道中的蒸汽压力 < 回差值),就恢复正常调节。

       我想把上述前后台三个函数,写到一个任务中,但是好象感觉有点困难, 困惑如下:

            (A)、由于正常调节时,需要不停的计算阀门的开度,这时应该使用“周期性执行任务”
            
             但是如何在这个周期性执行任务中如何体现如下两种特殊情况:

            (B)、当出现异常情况时(检测到某一个开关量信号),立即紧急关闭阀门,即:强制输出指令等于0 同时,必须要强制“输出指令=0”连续维持3秒。
                  此时不知道该如何处理。
                  
            (C)、 当(管道中的蒸汽压力 > 报警值),立即紧急关闭阀门,即:强制输出指令等于0 ,  同时,只要(管道中的蒸汽压力 > 报警值),就一直关闭阀门(强制输出指令等于0)  当检测到(管道中的蒸汽压力 < 回差值),就放弃特殊情况的执行,开始执行函数1.
                  此时不知道该如何处理。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2010-12-27 18:59:05 | 显示全部楼层
不是很了解你的硬件情况,仅供参考啊:
1,对于B函数,能不能用中断啊,只要中断产生,先挂起函数,延时,然后恢复函数。
2,对于c函数,也是在不断的查询中,发现,处理,延时,后面返回。if(条件成立){do{处理}while(条件成立)};
我凭空想的,不知道对不对,希望对你有帮助。

出0入0汤圆

发表于 2010-12-27 20:35:46 | 显示全部楼层
请问你响应时间最小是多少啊,这个很重要,时间是MS级别的直接轮询就可以了,没那么复杂

出0入0汤圆

发表于 2010-12-28 02:24:12 | 显示全部楼层
没必要为了多任务而多任务。你的这些个全部在一个任务里面就好了。如果采用了多任务那你的输出得做资源保护。你的上面逻辑其实可以采用plc的工作原理来实现,输入 逻辑运算 输出,这样不是很好吗?

出0入0汤圆

发表于 2010-12-28 02:36:12 | 显示全部楼层
你的这个应用在50毫秒内能响应就可以了。毕竟开入量还需要防抖滤波,否则万一有干扰,你这个乱关阀门,也不妥。至于你的那个脉充型开出其实可以用定时器来实现。这个地方可以采用多任务的方式实现,每个开出配一个定时计数,在定时器任务中对开出进行计时,在主任务中判断每个开出的标志,如果复归时间到则自动复归之。这不是很简单嘛。

出0入0汤圆

发表于 2010-12-28 12:28:13 | 显示全部楼层
easy

while (1) {
  uintptr_t msg = (uintptr_t)OSMboxPend(... , TIMEOUT); // TIMEOUT为周期性任务的周期。
  if (msg == 0) {                // 超时,执行周期性任务。
    取采样值;
    if (采样值 < 报警值) {
      PID计算;                   // 函数1
      输出;
    } else {
      输出0;                     // 函数3
    }
  } else if (msg == 1) {         // 异常处理
    输出0;                       // 函数2
    延时3秒;
    等待恢复指令;
  }
}
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-19 14:37

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表