打印
[AVR单片机]

我发现的uC/OSII中的一个不明之处,请赐教

[复制链接]
1846|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gwsino|  楼主 | 2007-4-18 07:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
下面是OSQCreate()的源代码:
OS_EVENT  *OSQCreate (void **start, INT16U size)
{
#if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
    OS_CPU_SR  cpu_sr;
#endif
    OS_EVENT  *pevent;
    OS_Q      *pq;


    if (OSIntNesting > 0) {                      /* 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];/*Error*/
            pq->OSQIn              = start;
            pq->OSQOut             = start;
            pq->OSQSize            = size;
            pq->OSQEntries         = 0;
            pevent->OSEventType    = OS_EVENT_TYPE_Q;
            pevent->OSEventCnt     = 0;
            pevent->OSEventPtr     = pq;
#if OS_EVENT_NAME_SIZE > 1
            pevent->OSEventName[0] = '?';                  /* Unknown name                             */
            pevent->OSEventName[1] = OS_ASCII_NUL;
#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);
}
下面是邵老师一书中提供的源代码,请问有没有问题
OS_EVENT *CommQ;
void *CommMsgp[10];
void main(void)
{
  OSInit();
 .
 .
 .
 CommQ = OSQCreate(&CommMsg[0],10);/*注此处是否有问题看上面Error标注位置是否会出现数组溢出的问题*/
 OSStart();
}
pq->OSQEnd             = &start[size];/*Error*/
*注此处是否有问题看上面Error标注位置是否会出现数组溢出的问题*/

相关帖子

沙发
John_Lee| | 2007-4-18 20:48 | 只看该作者

没有问题

虽然OSQEnd是指向数组的最后一项+1的位置,貌似越界,但要注意:程序只是用OSQEnd做边界比较,而并不访问其指向的数据,你可以看看OSQPend和OSQPost函数是如何使用OSQEnd的。这样的用法非常普遍,指针除了用来访问数据以外,还可以用来标定一些特殊值,比如NULL之类;OSQEnd就是用来标定消息队列的末尾的,其实,如果不使用指针的方式,而用一个长度值(比如OSQLen)来标定消息队列的长度,也可以达到同样的效果,但效率就要比使用指针的方式低些。

使用特权

评论回复
板凳
gwsino|  楼主 | 2007-4-19 09:57 | 只看该作者

谢谢

感谢二楼兄弟的帮助,让我又上了一课

使用特权

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

本版积分规则

28

主题

73

帖子

1

粉丝