uCOS-II中消息邮箱中消息的为局部变量讨论

[复制链接]
stone.csz 发表于 2008-12-25 22:13 | 显示全部楼层

Ucos

对于任何变量,不管是全局变量还是局部变量,我们都可以使用邮箱进行传递。当然对于全局变量如果使用邮箱传递那就有点多此一举乐,因为全变对于任何任务都是可见的。所以通常用邮箱传递的都是局部变量,而且放入邮箱中的也只是一个指向局部变量的指针,并不是其内容哦!!
新闻局 发表于 2008-12-25 22:16 | 显示全部楼层

LS错误。。。

全局变量 != 消息邮箱
stone.csz 发表于 2008-12-25 22:45 | 显示全部楼层

LS错误。。。

我没有讨论消息邮箱是否是全局变量,而是消息邮箱传递的内容是什么!说白了,就是你去邮局寄信时,我们讨论你寄的是平信还是挂号信,而不是讨论你去的那个邮局是民营还是国营的问题!!
machunshui 发表于 2008-12-25 23:14 | 显示全部楼层

很多人对OS的概念不清

很多人对OS的概念不清.
gouki_s 发表于 2008-12-26 10:57 | 显示全部楼层

任务的堆栈空间是互相分隔的

zbo210 发表于 2008-12-26 20:33 | 显示全部楼层

9楼回答正确!!

9楼回答正确!!
anzil 发表于 2010-3-26 10:22 | 显示全部楼层
在ISR中要想将数据通过邮箱发送出来,需要在变量定义前面添加 static,声明为静态,就可以正确的接收了,否则,接收到的可能是随机的数。
qustjinxin 发表于 2010-7-20 18:06 | 显示全部楼层
学习
香如故 发表于 2012-9-18 18:36 | 显示全部楼层
本帖最后由 香如故 于 2012-9-19 07:11 编辑

isr中也可以用局部变量啊,局部变量做为邮箱的内容发送.下面程序能正常得到运行效果 msg[50]就是中断的局部变量
<<嵌入式实时操作系统μC/OS-Ⅱ经典实例:基于STM32处理器>>
这本书里的,这样的例子很多,呵呵*******************************************************************************
* Function Name  : USART1_IRQHandler
* Description    : This function handles USART1 global interrupt request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void USART1_IRQHandler(void)
{
        unsigned int i;
    unsigned char msg[50];
        OS_CPU_SR  cpu_sr;
         
        OS_ENTER_CRITICAL();  //保存全局中断标志,关总中断// Tell uC/OS-II that we are starting an ISR
          OSIntNesting++;
        
          OS_EXIT_CRITICAL();          //恢复全局中断标志
        
          //OSTimeTick();     // Call uC/OS-II's OSTimeTick(),在os_core.c文件里定义,主要判断延时的任务是否计时到

           if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)           //判断读寄存器是否非空
          {        
                    // Read one byte from the receive data register
            
                        msg[RxCounter1++]= USART_ReceiveData(USART1);   //将读寄存器的数据缓存到接收缓冲区里
               
                    if(msg[RxCounter1-1]=='L'){msg[0]='L'; RxCounter1=1;}     //判断起始标志
                        if(msg[RxCounter1-1]=='F')                  //判断结束标志是否是"F"
               
                    {
                                  for(i=0; i< RxCounter1; i++){
                                        TxBuffer1        =msg;              //将接收缓冲器的数据转到发送缓冲区,准备转发
                          
                                }
                                                  
                                TxBuffer1[RxCounter1]=0;                                //接收缓冲区终止符
                                  RxCounter1=0;                                                
                                //OSSemPost(Com1_SEM);           
                                OSMboxPost(Com1_MBOX,(void *)&msg);                           
                    }
          }
          if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)                     //
          {
             USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
          }        
    OSIntExit();  //在os_core.c文件里定义,如果有更高优先级的任务就绪了,则执行一次任务切换   
}
香如故 发表于 2012-9-19 07:15 | 显示全部楼层
从上面可以看出,在ISR中要想将局部变量通过邮箱发送出来,也可以不加static的:)
香如故 发表于 2012-9-22 07:59 | 显示全部楼层
调试中发现还是加static接收的数据可靠些:P,没有static的话,发的数据快了就有错误情况发生
CSMJMCC 发表于 2013-1-10 09:53 | 显示全部楼层
我是刚用到UCOS写项目,遇见此问题才找到此帖。我的验证:
void Task_Key(void *pdata)
{                  
    uint8 key_val;        
    pdata = pdata;                                                     
    while(1)
   {         
      OSTimeDly(10);
       
       key_val = 0xdb;
       if(key_val != 0)
      {
           OSMboxPost(KeyQEvent, (void *)&key_val);
           //key_val = 0;           //这里若不屏蔽此行,您的另一个任务将得到邮箱键值均为0;否则,得到正确的键值。       }
}

从而说明:在一个任务中,若将局部变量值用邮箱发出时,邮箱存的是变量指针,若在此任务发出邮箱消息后,又将该变量值变更,则接收邮箱的另一个任务将得不到正确的值。因邮箱的变量指针所指的值已经变更了。
gaofeisz_sibet 发表于 2013-6-7 14:30 | 显示全部楼层
本帖最后由 gaofeisz_sibet 于 2013-6-7 14:34 编辑
  1. void USART3_IRQHandler(void)
  2. {
  3.         
  4.         static INT8U RecvData;//中断处理函数结束,该静态变量的值不会被销毁,非常重要!

  5.         #ifdef OS_TICKS_PER_SEC//如果时钟节拍数定义了,说明要使用UCOSII了。
  6.                 OSIntEnter();     
  7.         #endif

  8.         if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
  9.         {
  10.                
  11.                 /* Read one byte from the receive data register */
  12.                 RecvData = USART_ReceiveData(USART3);

  13.                 //USART_ClearFlag(USART3,USART_FLAG_TC);
  14.                 USART_SendData(USART3, RecvData);
  15.                 while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET){}

  16.                 OSMboxPost(gp_MBox_USART, (void*)(&RecvData));
  17.         }

  18.         #ifdef OS_TICKS_PER_SEC//如果时钟节拍数定义了,说明要使用UCOSII了。
  19.                 OSIntExit();            
  20.         #endif
  21. }

  22. /*USART处理任务*/
  23. static void TASK_USART(void *p_arg)
  24. {
  25.         INT8U err;
  26.         INT8U *msg;
  27.                
  28.         p_arg = p_arg;//防止编译器产生警告

  29.         while(1)
  30.         {
  31.                 msg = (INT8U *)OSMboxPend(gp_MBox_USART, 0, &err);
  32.                
  33.                 //USART_ClearFlag(USART3,USART_FLAG_TC);
  34.                 USART_SendData(USART3, *msg);
  35.                 while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET){}

  36.                 if (((*msg)&0x80) == 0x00)
  37.                         g_ms1 = ((*msg)&0x7f) * 10;
  38.                 else
  39.                         g_ms2 = ((*msg)&0x7f) * 10;
  40.         }
  41. }//不加static结果肯定是不可预见的,ISR中的RecvData地址在中断返回后已经被释放了,等收消息的时候值自然就不同了。
gaofeisz_sibet 发表于 2013-6-7 14:32 | 显示全部楼层
不加static结果肯定是不可预见的,ISR中的RecvData地址在中断返回后已经被释放了,等收消息的时候值自然就不同了。
仙帝将王 发表于 2014-4-11 17:39 | 显示全部楼层
楼主讨论的内容很好,正是因为这个原因,我才遇到了问题。请楼主转到我的帖子,请帮忙出出主义。http://bbs.21ic.com/forum.php?mod=viewthread&tid=713066&page=1#pid4132512
仙帝将王 发表于 2014-4-11 17:45 | 显示全部楼层
CSMJMCC 发表于 2013-1-10 09:53
我是刚用到UCOS写项目,遇见此问题才找到此帖。我的验证:
void Task_Key(void *pdata)
{                  

是的,传变量指针的方法也是不可靠的。请问还有什么办法,难道还要定义一个指针数组,还要对该指针数组进行管理?一方面占内存,另一方面不符合消息邮箱的初衷啊,请问有什么好的解决方案。http://bbs.21ic.com/forum.php?mod=viewthread&tid=713066&page=1#pid4132512请转到我的帖子,帮帮出出主意,谢谢。
仙帝将王 发表于 2014-4-11 17:50 | 显示全部楼层
anzil 发表于 2010-3-26 10:22
在ISR中要想将数据通过邮箱发送出来,需要在变量定义前面添加 static,声明为静态,就可以正确的接收了,否 ...

这是一个解决思路,但是好像也有问题。如果下一次中断马上来临,把变量修改了。这时才从消息邮箱中取出消息,那不是得不到正确的传递了?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部
快速回复 在线客服 返回列表 返回顶部