搜索
bottom↓
回复: 21

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

[复制链接]

出0入0汤圆

发表于 2008-11-10 09:07:15 | 显示全部楼层 |阅读模式
陈明计先生的SMALL RTOS消息队列中(假如用户任务数<9)

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

   buf[1]=指示消息队列占用的内存空间(包括buf[0],buf[1],buf[2],buf[3])

   buf[2]=指示出队位置

   buf[3]=消息等待任务列表

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

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

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

     temp=Buf[2]+buf[0]+1  

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

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

              那么temp=4+0+1=5

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

 

 

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

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

出0入0汤圆

发表于 2008-12-26 10:57:50 | 显示全部楼层
在FIFO方式中,Buf[2]指示下一个消息出队位置,而在取得消息时候,代码是:



                /* 有,消息出队 */

        Buf[0]--;

        Buf[2]++;

        if (Buf[2]>= Buf[1])

        {

#if OS_MAX_TASKS < 9

            Buf[2] = 4;

#else

            Buf[2] = 5;

#endif

        }

        *Ret = Buf[Buf[2]];

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

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

#ifdef __C51__

        SP++;

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

#endif

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

        temp = Buf[2] + Buf[0] + 1;

        if (temp <= Buf[0] || temp>= Buf[1])

        {

#if OS_MAX_TASKS < 9

            temp = temp - Buf[1] + 4;

#else

            temp = temp - Buf[1] + 5;

#endif

        }

                /* 存储消息 */

#ifdef __C51__

        Buf[temp] = *((uint8 data *)SP);

        SP--;

也就是temp = Buf[2] + Buf[0] + 1;中的1来源吧

这样才能吻合。

出0入0汤圆

 楼主| 发表于 2008-11-21 16:40:16 | 显示全部楼层
我顶,我顶上去。

出0入0汤圆

 楼主| 发表于 2008-11-15 13:52:38 | 显示全部楼层
总之,遇到比较难理解的问题,只有一步一步的分析,就能解决自己的困惑的。

出0入0汤圆

 楼主| 发表于 2008-11-15 13:50:18 | 显示全部楼层
(3)任务取走第1条消息后,队列示意图  

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

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

    此时消息队列如下:  

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

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

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

       |    |    |     |     |     |      |        |          

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

                                  |       

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

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

出0入0汤圆

 楼主| 发表于 2008-11-15 13:48:02 | 显示全部楼层
 (1)任务取走第3条消息后,队列示意图 

    首先执行BUF[2]++《【BUF[2]=6】 

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

    此时消息队列如下: 

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

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

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

       |    |    |     |     |  消息1 |      |        |         

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

                                                    |      

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

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

出0入0汤圆

 楼主| 发表于 2008-11-15 13:46:31 | 显示全部楼层
下面我们来分析任务等待消息过程。接上图,消息队列中已经插入了三条消息。

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

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

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

    此时消息队列如下:

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

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

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

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

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

                                          |     

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

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

出0入0汤圆

 楼主| 发表于 2008-11-14 11:41:04 | 显示全部楼层
  明天,此时请看任务等待消息过程的示意图。

出0入0汤圆

 楼主| 发表于 2008-11-14 11:39:53 | 显示全部楼层
 (5)向消息队列插入第四条消息后,示意图如下:   

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

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

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

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

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

                                  |    

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



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

  

出0入0汤圆

 楼主| 发表于 2008-11-14 11:37:28 | 显示全部楼层
  (3)向消息队列插入第二条消息后,示意图如下: 

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

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

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

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

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

                                          |  

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



          buf[0]=2  消息数目           

          buf[2]=5  出队位置  

出0入0汤圆

 楼主| 发表于 2008-11-14 11:38:17 | 显示全部楼层
 (4)向消息队列插入第三条消息后,示意图如下:  

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

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

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

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

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

                                  |   

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



          buf[0]=3  消息数目            

          buf[2]=4  出队位置   

出0入0汤圆

 楼主| 发表于 2008-11-14 11:35:30 | 显示全部楼层
   其中Buf[0]和buf[6]前后紧挨着,构成环形队列。

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

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

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

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

       |    |    |     |     |  消息1 |        |        |    

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

                                                     | 

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



          buf[0]=1  消息数目          

          buf[2]=6  出队位置 

出0入0汤圆

 楼主| 发表于 2008-11-14 11:32:30 | 显示全部楼层
下面我们来分析一下LOFI(后进先出)方式,向消息队列发送消息

  (a)假设任务数<9

  (b)消息队列尺寸=7

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



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

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

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

       |    |    |     |     |        |        |        |   

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

                                  |

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



          buf[0]=0  消息数目         

          Buf[1]=7 消息队列尺寸

          buf[2]=4  出队位置

          buf[3]=消息等待任务列表 

出0入0汤圆

 楼主| 发表于 2008-11-14 11:15:06 | 显示全部楼层
昨天晚上仔细分析了一下,终于把

  (1)、任务等待消息

  (2)、LIFO发送消息

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

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

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

 

出0入0汤圆

 楼主| 发表于 2008-11-13 17:57:23 | 显示全部楼层
我顶!

出0入0汤圆

 楼主| 发表于 2008-11-13 10:25:04 | 显示全部楼层
没人帮我吗?

出0入0汤圆

 楼主| 发表于 2008-11-12 08:37:18 | 显示全部楼层
在普通的队列结构中。定义了队头指针QUEUE.Front和队尾指针QUEUE.Rear

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

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

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



  

出0入0汤圆

 楼主| 发表于 2008-11-11 18:58:18 | 显示全部楼层
P94页的图7.1和图7.2也可以看出,第一个装入消息的位置是从buf[4]开始装入的。 

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

出0入0汤圆

 楼主| 发表于 2008-11-11 09:29:56 | 显示全部楼层
P94页的图7.1和图7.2也可以看出,第一个装入消息的位置是从buf[4]开始装入的。

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

出0入0汤圆

 楼主| 发表于 2008-11-11 08:34:42 | 显示全部楼层
 (3)在等待消息系统函数OSQPend()中,当等到消息后,为什么先出队指针buf[2]先加一,然后从Buf[Buf[2]]中取出消息呢?

出0入0汤圆

 楼主| 发表于 2008-11-10 16:43:36 | 显示全部楼层
我顶!

出0入0汤圆

发表于 2010-4-14 12:15:16 | 显示全部楼层
受教了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-20 12:53

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

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