OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5588|回复: 4

发现UCOSII消息队列的一个BUG,请各位大神分析一下!

[复制链接]

11

主题

80

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4493
金钱
4493
注册时间
2016-8-2
在线时间
51 小时
发表于 2016-8-31 15:07:49 | 显示全部楼层 |阅读模式
最近在测试UCOSII的消息队列的时候发现一个bug。

我定义一个消息指针数据和一个消息队列控制块

#define size  1   消息队列长度为1
void *MsgGrp[size];//定义消息指针数组,长度为1
OS_EVENT *Str_p;//消息队列控制块
在一个任务中创建一个消息队列:
Str_p = OSQCreate (&MsgGrp[0],size);//创建一个消息队列


按照上面的逻辑我创建的消息队列长度应该是1,但是在实际测试过程中发现,实际的消息队列长度是2。
进入OSQCreate ()函数里面查看发现了问题如下图;






虽然这样用不会出现问题,但是我比较担心的是,我定义的void *MsgGrp[size],size长度是1,那么他能够使用的数组元素的应该是MsgGrp[0],而MsgGrp[1]应该是非法的吧?



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

11

主题

80

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4493
金钱
4493
注册时间
2016-8-2
在线时间
51 小时
 楼主| 发表于 2016-8-31 15:08:47 | 显示全部楼层
[mw_shl_code=c,true]OS_EVENT  *OSQCreate (void    **start,
                      INT16U    size)
{
    OS_EVENT  *pevent;
    OS_Q      *pq;
       

#if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
    OS_CPU_SR  cpu_sr = 0u;
#endif



#ifdef OS_SAFETY_CRITICAL_IEC61508
    if (OSSafetyCriticalStartFlag == OS_TRUE) {
        OS_SAFETY_CRITICAL_EXCEPTION();
    }
#endif

    if (OSIntNesting > 0u) {                     /* See if called from ISR ...                         */
        return ((OS_EVENT *)0);                  /* ... can't CREATE from an ISR                       */
    }
    OS_ENTER_CRITICAL();
    pevent = OSEventFreeList;                    /* Get next free event control block                  */
    if (OSEventFreeList != (OS_EVENT *)0) {      /* See if pool of free ECB pool was empty             */
        OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
    }
    OS_EXIT_CRITICAL();
    if (pevent != (OS_EVENT *)0) {               /* See if we have an event control block              */
        OS_ENTER_CRITICAL();
        pq = OSQFreeList;                        /* Get a free queue control block                     */
        if (pq != (OS_Q *)0) {                   /* Were we able to get a queue control block ?        */
            OSQFreeList            = OSQFreeList->OSQPtr; /* Yes, Adjust free list pointer to next free*/
            OS_EXIT_CRITICAL();
            pq->OSQStart           = start;               /*      Initialize the queue                 */
            pq->OSQEnd             = &start[size];
            pq->OSQIn              = start;
            pq->OSQOut             = start;
            pq->OSQSize            = size;
            pq->OSQEntries         = 0u;
            pevent->OSEventType    = OS_EVENT_TYPE_Q;
            pevent->OSEventCnt     = 0u;
            pevent->OSEventPtr     = pq;
#if OS_EVENT_NAME_EN > 0u
            pevent->OSEventName    = (INT8U *)(void *)"?";
#endif
            OS_EventWaitListInit(pevent);                 /*      Initalize the wait list              */
        } else {
            pevent->OSEventPtr = (void *)OSEventFreeList; /* No,  Return event control block on error  */
            OSEventFreeList    = pevent;
            OS_EXIT_CRITICAL();
            pevent = (OS_EVENT *)0;
        }
    }
    return (pevent);
}[/mw_shl_code]
回复 支持 反对

使用道具 举报

11

主题

80

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4493
金钱
4493
注册时间
2016-8-2
在线时间
51 小时
 楼主| 发表于 2016-8-31 15:10:41 | 显示全部楼层
图挂了把OSQCreate 的函数代码贴在下面了,注意第36行是直接使用了size!
回复 支持 反对

使用道具 举报

19

主题

72

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
416
金钱
416
注册时间
2016-4-9
在线时间
123 小时
发表于 2017-6-22 23:46:44 来自手机 | 显示全部楼层
这是不可能的,ucos上过飞机 去过火星 有各种各样的认证
回复 支持 反对

使用道具 举报

17

主题

52

帖子

1

精华

高级会员

Rank: 4

积分
555
金钱
555
注册时间
2015-6-11
在线时间
66 小时
发表于 2020-5-11 10:00:43 | 显示全部楼层
我在使用中也发现有这个问题,只要pend过一次,好像队列就会多出一个空位。我把队列大小定义为0,Q_handle_data = OSQCreate(Q_queue, 0);,也可以传递消息。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 17:31

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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