ba_wang_mao 发表于 2008-11-10 09:07:15

SMALL RTOS51是,请教中断FIFO插入消息“有关插入位置”的疑问【恢复】

陈明计先生的SMALL RTOS消息队列中(假如用户任务数<9)

   Buf=指示消息队列中消息的数目

   buf=指示消息队列占用的内存空间(包括buf,buf,buf,buf)

   buf=指示出队位置

   buf=消息等待任务列表

 (1)、在任务数<9时,出队位置=4,也就是说从buf开始取出消息。从P94页的图7.1和图7.2也可以看出,第一个装入消息的位置是从buf开始装入的。

 (2)、但是在P103页的“中断中FIFO方式向消息队列发送消息”系统函数中

    计算消息保存位置的代码如下:

     temp=Buf+buf+1  

    即作者为了省去数据结构中队列入队指针,而采用“出队位置+消息数目”来确定入队位置

    假如:目前消息队列刚刚被创建,此时buf=0,buf=4,当收到一个消息后,计算插入位置

              那么temp=4+0+1=5

      显示将第一条消息从buf位置装,不是从buf开始装入的吗?我的理解到底错在哪里?

 

 

lzf713 发表于 2008-12-26 10:57:50

在FIFO方式中,Buf指示下一个消息出队位置,而在取得消息时候,代码是:



                /* 有,消息出队 */

        Buf--;

        Buf++;

        if (Buf>= Buf)

        {

#if OS_MAX_TASKS < 9

            Buf = 4;

#else

            Buf = 5;

#endif

        }

        *Ret = Buf];

也就是说,Buf+1才是真的出队位置,所以消息入队时候应该是:

                /* 使用堆栈是为了使函数具有重入性 */

#ifdef __C51__

        SP++;

        *((uint8 data *)SP) = Data;

#endif

                /* 计算新入队消息存储位置 */

        temp = Buf + Buf + 1;

        if (temp <= Buf || temp>= Buf)

        {

#if OS_MAX_TASKS < 9

            temp = temp - Buf + 4;

#else

            temp = temp - Buf + 5;

#endif

        }

                /* 存储消息 */

#ifdef __C51__

        Buf = *((uint8 data *)SP);

        SP--;

也就是temp = Buf + Buf + 1;中的1来源吧

这样才能吻合。

ba_wang_mao 发表于 2008-11-21 16:40:16

我顶,我顶上去。

ba_wang_mao 发表于 2008-11-15 13:52:38

总之,遇到比较难理解的问题,只有一步一步的分析,就能解决自己的困惑的。

ba_wang_mao 发表于 2008-11-15 13:50:18

(3)任务取走第1条消息后,队列示意图  

    首先执行BUF++《【BUF=7】,由于BUF>=BUF,因此调整出队位置,调整后BUF=4  

    而BUF中存储的消息刚好是第一条插入的消息,然后将该消息(第一条插入的消息)返回给任务。   

    此时消息队列如下:  

    -------------------------------------------------       

       |  0 |  1 |  2  |  3  |    4   |   5    |    6   |       

       |    |    |     |     |        |        |        |---> Buf       

       |    |    |     |     |     |      |        |          

       --------------------------------------------------       

                                  |       

                                  -----> 取出插入第一条消息后的出队位置       

        从上可以看出,消息队列中,目前已经没有消息了  

ba_wang_mao 发表于 2008-11-15 13:48:02

 (1)任务取走第3条消息后,队列示意图 

    首先执行BUF++《【BUF=6】 

    而BUF中存储的消息刚好是第二条插入的消息,然后将该消息(第二条插入的消息)返回给任务。  

    此时消息队列如下: 

    -------------------------------------------------      

       |  0 |  1 |  2  |  3  |    4   |   5    |    6   |      

       |    |    |     |     |        |        |        |---> Buf      

       |    |    |     |     |  消息1 |      |        |         

       --------------------------------------------------      

                                                    |      

                                                     -----> 取出插入第二条消息后的出队位置      

        从上可以看出,消息队列中,目前只有消息1(消息2已经被取走) 

ba_wang_mao 发表于 2008-11-15 13:46:31

下面我们来分析任务等待消息过程。接上图,消息队列中已经插入了三条消息。

  (1)任务取走第3条消息后,队列示意图

    由于插入第三条消息后BUF=4,此时取出消息时,执行BUF++《【BUF=5】

    而BUF中存储的消息刚好是第三条插入的消息,然后将该消息(第三条插入的消息)返回给任务。 

    此时消息队列如下:

    -------------------------------------------------     

       |  0 |  1 |  2  |  3  |    4   |   5    |    6   |     

       |    |    |     |     |        |        |        |---> Buf     

       |    |    |     |     |  消息1 |      |  消息2 |        

       --------------------------------------------------     

                                          |     

                                          -----> 取出最后插入第三条消息后的出队位置     

        从上可以看出,消息队列中,目前只有消息1和消息2(消息3已经被取走)

ba_wang_mao 发表于 2008-11-14 11:41:04

  明天,此时请看任务等待消息过程的示意图。

ba_wang_mao 发表于 2008-11-14 11:39:53

 (5)向消息队列插入第四条消息后,示意图如下:   

    -------------------------------------------------    

       |  0 |  1 |  2  |  3  |    4   |   5    |    6   |    

       |    |    |     |     |        |        |        |---> Buf    

       |    |    |     |     |  消息1 |  消息3 |  消息2 |       

       --------------------------------------------------    

                                  |    

                                  -----> 插入第三条消息后的出队位置    



          由于消息队列已经满(Buf>=Buf-4),无法插入第四条消息。             

  

ba_wang_mao 发表于 2008-11-14 11:37:28

  (3)向消息队列插入第二条消息后,示意图如下: 

    -------------------------------------------------  

       |  0 |  1 |  2  |  3  |    4   |   5    |    6   |  

       |    |    |     |     |        |        |        |---> Buf  

       |    |    |     |     |  消息1 |        |  消息2 |     

       --------------------------------------------------  

                                          |  

                                           -----> 插入第二条消息后的出队位置  



          buf=2  消息数目           

          buf=5  出队位置  

ba_wang_mao 发表于 2008-11-14 11:38:17

 (4)向消息队列插入第三条消息后,示意图如下:  

    -------------------------------------------------   

       |  0 |  1 |  2  |  3  |    4   |   5    |    6   |   

       |    |    |     |     |        |        |        |---> Buf   

       |    |    |     |     |  消息1 |  消息3 |  消息2 |      

       --------------------------------------------------   

                                  |   

                                  -----> 插入第三条消息后的出队位置   



          buf=3  消息数目            

          buf=4  出队位置   

ba_wang_mao 发表于 2008-11-14 11:35:30

   其中Buf和buf前后紧挨着,构成环形队列。

  (2)向消息队列插入第一条消息后,示意图如下:

    ------------------------------------------------- 

       |  0 |  1 |  2  |  3  |    4   |   5    |    6   | 

       |    |    |     |     |        |        |        |---> Buf 

       |    |    |     |     |  消息1 |        |        |    

       -------------------------------------------------- 

                                                     | 

                                                     -----> 插入第一条消息后的出队位置 



          buf=1  消息数目          

          buf=6  出队位置 

ba_wang_mao 发表于 2008-11-14 11:32:30

下面我们来分析一下LOFI(后进先出)方式,向消息队列发送消息

  (a)假设任务数<9

  (b)消息队列尺寸=7

 (1)消息队列初始化后,示意图  如下:



    -------------------------------------------------

       |  0 |  1 |  2  |  3  |    4   |   5    |    6   |

       |    |    |     |     |        |        |        |---> Buf

       |    |    |     |     |        |        |        |   

       --------------------------------------------------

                                  |

                                  -----> 初始化后的出队位置



          buf=0  消息数目         

          Buf=7 消息队列尺寸

          buf=4  出队位置

          buf=消息等待任务列表 

ba_wang_mao 发表于 2008-11-14 11:15:06

昨天晚上仔细分析了一下,终于把

  (1)、任务等待消息

  (2)、LIFO发送消息

 搞清楚了,目前还剩下FIFO方式,怎么FIFO方式发送消息,不修正出队指针(Buf)呢?

    唉,陈明计先生,为了节省一个入队指针Front,把程序代码搞得太难懂了。如果是一对Front(入队指针),

Rear(出队指针),程序代码就非常清楚了。

 

ba_wang_mao 发表于 2008-11-13 17:57:23

我顶!

ba_wang_mao 发表于 2008-11-13 10:25:04

没人帮我吗?

ba_wang_mao 发表于 2008-11-12 08:37:18

在普通的队列结构中。定义了队头指针QUEUE.Front和队尾指针QUEUE.Rear

同时为了达到环形缓冲区的效果,定义的队列长度=可以使用队列长度+1。

也就是说空闲一个单元,用于判断队列是否已满。

  陈明计先生P94页的图7.1和图7.2很容易让人勿导



  

ba_wang_mao 发表于 2008-11-11 18:58:18

P94页的图7.1和图7.2也可以看出,第一个装入消息的位置是从buf开始装入的。 

  为什么取消息不从buf开始取,而是从buf取呢? 

ba_wang_mao 发表于 2008-11-11 09:29:56

P94页的图7.1和图7.2也可以看出,第一个装入消息的位置是从buf开始装入的。

  为什么取消息不从buf开始取,而是从buf取呢?

ba_wang_mao 发表于 2008-11-11 08:34:42

 (3)在等待消息系统函数OSQPend()中,当等到消息后,为什么先出队指针buf先加一,然后从Buf]中取出消息呢?

ba_wang_mao 发表于 2008-11-10 16:43:36

我顶!

xuetingxun2010 发表于 2010-4-14 12:15:16

受教了
页: [1]
查看完整版本: SMALL RTOS51是,请教中断FIFO插入消息“有关插入位置”的疑问【恢复】