发新帖我要提问
123
返回列表
打印

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

[复制链接]
楼主: Swd21ic
手机看帖
扫描二维码
随时随地手机跟帖
41
stone.csz| | 2008-12-25 22:13 | 只看该作者 回帖奖励 |倒序浏览

Ucos

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

使用特权

评论回复
42
新闻局| | 2008-12-25 22:16 | 只看该作者

LS错误。。。

全局变量 != 消息邮箱

使用特权

评论回复
43
stone.csz| | 2008-12-25 22:45 | 只看该作者

LS错误。。。

我没有讨论消息邮箱是否是全局变量,而是消息邮箱传递的内容是什么!说白了,就是你去邮局寄信时,我们讨论你寄的是平信还是挂号信,而不是讨论你去的那个邮局是民营还是国营的问题!!

使用特权

评论回复
44
machunshui| | 2008-12-25 23:14 | 只看该作者

很多人对OS的概念不清

很多人对OS的概念不清.

使用特权

评论回复
45
gouki_s| | 2008-12-26 10:57 | 只看该作者

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

使用特权

评论回复
46
zbo210| | 2008-12-26 20:33 | 只看该作者

9楼回答正确!!

9楼回答正确!!

使用特权

评论回复
47
anzil| | 2010-3-26 10:22 | 只看该作者
在ISR中要想将数据通过邮箱发送出来,需要在变量定义前面添加 static,声明为静态,就可以正确的接收了,否则,接收到的可能是随机的数。

使用特权

评论回复
48
qustjinxin| | 2010-7-20 18:06 | 只看该作者
学习

使用特权

评论回复
49
香如故| | 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文件里定义,如果有更高优先级的任务就绪了,则执行一次任务切换   
}

使用特权

评论回复
50
香如故| | 2012-9-19 07:15 | 只看该作者
从上面可以看出,在ISR中要想将局部变量通过邮箱发送出来,也可以不加static的:)

使用特权

评论回复
51
香如故| | 2012-9-22 07:59 | 只看该作者
调试中发现还是加static接收的数据可靠些:P,没有static的话,发的数据快了就有错误情况发生

使用特权

评论回复
52
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;否则,得到正确的键值。       }
}

从而说明:在一个任务中,若将局部变量值用邮箱发出时,邮箱存的是变量指针,若在此任务发出邮箱消息后,又将该变量值变更,则接收邮箱的另一个任务将得不到正确的值。因邮箱的变量指针所指的值已经变更了。

使用特权

评论回复
53
gaofeisz_sibet| | 2013-6-7 14:30 | 只看该作者
本帖最后由 gaofeisz_sibet 于 2013-6-7 14:34 编辑
void USART3_IRQHandler(void)
{
        
        static INT8U RecvData;//中断处理函数结束,该静态变量的值不会被销毁,非常重要!

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

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

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

                OSMboxPost(gp_MBox_USART, (void*)(&RecvData));
        }

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

/*USART处理任务*/
static void TASK_USART(void *p_arg)
{
        INT8U err;
        INT8U *msg;
               
        p_arg = p_arg;//防止编译器产生警告

        while(1)
        {
                msg = (INT8U *)OSMboxPend(gp_MBox_USART, 0, &err);
               
                //USART_ClearFlag(USART3,USART_FLAG_TC);
                USART_SendData(USART3, *msg);
                while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET){}

                if (((*msg)&0x80) == 0x00)
                        g_ms1 = ((*msg)&0x7f) * 10;
                else
                        g_ms2 = ((*msg)&0x7f) * 10;
        }
}//不加static结果肯定是不可预见的,ISR中的RecvData地址在中断返回后已经被释放了,等收消息的时候值自然就不同了。

使用特权

评论回复
54
gaofeisz_sibet| | 2013-6-7 14:32 | 只看该作者
不加static结果肯定是不可预见的,ISR中的RecvData地址在中断返回后已经被释放了,等收消息的时候值自然就不同了。

使用特权

评论回复
55
仙帝将王| | 2014-4-11 17:39 | 只看该作者
楼主讨论的内容很好,正是因为这个原因,我才遇到了问题。请楼主转到我的帖子,请帮忙出出主义。https://bbs.21ic.com/forum.php?mod=viewthread&tid=713066&page=1#pid4132512

使用特权

评论回复
56
仙帝将王| | 2014-4-11 17:45 | 只看该作者
CSMJMCC 发表于 2013-1-10 09:53
我是刚用到UCOS写项目,遇见此问题才找到此帖。我的验证:
void Task_Key(void *pdata)
{                  

是的,传变量指针的方法也是不可靠的。请问还有什么办法,难道还要定义一个指针数组,还要对该指针数组进行管理?一方面占内存,另一方面不符合消息邮箱的初衷啊,请问有什么好的解决方案。https://bbs.21ic.com/forum.php?mod=viewthread&tid=713066&page=1#pid4132512请转到我的帖子,帮帮出出主意,谢谢。

使用特权

评论回复
57
仙帝将王| | 2014-4-11 17:50 | 只看该作者
anzil 发表于 2010-3-26 10:22
在ISR中要想将数据通过邮箱发送出来,需要在变量定义前面添加 static,声明为静态,就可以正确的接收了,否 ...

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

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则