嵌入式上UC/OS - II使用注意点------任务调度

前段时间在ARM9 平台上作基于 UC/OS-II的应用开发,遇到一个比较重要的问题,现在总结一下,便于日后回顾
关注点 : 多任务调度的方式区别 (查询+OSTimeDly 还是 基于事件驱动的方式,比如smei,flag等)
平台设施: ARM9 + UC/OS-II
背景介绍: 首先有个引擎需要移植到我的系统中,下面简称该引擎为emo,
emo需要有2个任务支持,简称任务T2,任务T2。 T1负责从一个buffer中获取数据,
当获取到的数据达到一定阈值m时,把获取到的数据一下全部塞进emo中,
同时T2任务负责运算处理emo中的数据。但是T2该任务运行要求实时性比较高,
运算比较复杂,所以在应用设计的时候尽量不要去经常打断 T2任务。

出题发生: 一开始T1任务设计方式是 采用查询+OSTimeDly,结构如下
//T1 task ......
while(1)
{
    while(1)
    {
        if 获取数据达到阈值m
          break
        else
          OSTimeDly(10)
    }
    append_data() //把数据塞进emo中
    if 有其他任务需要删除T1
       删除自己
    else OSTimeDly(10)
}
解释---整个task结构是通过不断查询+dly方式,这就存在一个问题,T1在没有获取到足够的数据时
会不断的Dly,在获取到一定数据后,还是要不断的Dly(除非要删除自己了),但是在这过程中,
T2一直要跑的,而且需要实时性很高,那么频繁的Dly操作导致UC/OS调度很多次,这多少会影响到T2的执行,
同是当前系统做了一个频率自动调节技术PM,即根据Dly的次数(大概是这样)通过某算法可以得知当前需要
多大的频率可以满足应用程序。因为频繁的Dly造成PM上计算结果和实际情况相差较大,导致分配给应用的
频率不够,这2种情况共同导致了T2运行很不顺畅,因为T2运行受到阻碍,导致T1中取到的很多数据被丢失,
而T1数据的丢失更导致T2运算得到的结果错误,恶性循环了

现在换了写法,采取事件方式,设置了一个Flag,
当buffer中数据达到m时,通过一个回调函数post该flag,T1中首先是pend该Flag如果err,则无限等待知道该flag被post,
什么时候能等到从而使T1继续往下运行呢,只能是buffer中数据达到m。当pend到有效的flag之后,T1再把获取到的数据塞到emo中,
T2则计算处理emo中的数据,这样写不需要频繁的查询频繁的Dly。T2的实时性也可以很好的保证,塞到emo中的数据也可以及时处理完,
不至于丢失有效数据。

... post flag //第一次时flag是有效的
while(1)
{
    pend the flag //等待该flag,如果无效则一直等待下去
    while(get_data(阈值,回调))
    {
        append_data //向emo中塞数据,供T2处理
    }
   if 有其他任务要删除T1
      删除自己
   else
      OSTimeDly(10)
}

你可能感兴趣的:(嵌入式硬件,嵌入式软件)