DSP

TI C66x DSP QM queue的reserve方法

2019-07-13 11:13发布

        TI C66x DSP 的queue manager 硬件可以管理8192个queue(如 Nyquist有8192个queue,实际上每个queue就是一系列的地址,每个地址表示对queue的一种操作),这些queue分为很多类,各有不同的用处,但也不一定按照下图描述的用途来使用,例如,系统如果没有使用0~511作为low priority queue的时候,0~511的queue可以作为general purpose queue来使用,协处理器(如AIF2,FFTC,SRIO,BCP etc)的Tx queue也可以作为general purpose queue来使用,只要该Tx queue对应的Tx channel被禁掉(禁掉后,就不会驱动AIF2硬件工作了)。         在开发过程中,APP申请了一个queue来使用,那么怎样记录该queue已经被reserve了,从而不会被重复使用,下面介绍一种比较好的方法,QmQueueReserve函数来实现。 EQmRetVal QmQueueReserve(const u32queue, TQmQueueHnd * constqueueHndPtr) * @param[in]  queue        The queue id which will be reserved. *                          Value range is: 0 to 8190 excluding 4095. *                          Can also be set to one of the following setting, when *                          there is no need to reserve some specific queue. *                       四种类型的queue *                           QM_RESERVE_NEXT_FREE_GEN_PURPOSE_QUEUE - 用于表示要reserve general purpose queue  *                          QM_RESERVE_NEXT_FREE_HIGHPRIO_ACC_QUEUE -用于表示要reserve high proiority queue(704~735) *                           QM_RESERVE_NEXT_FREE_LOWPRIO_ACC_QUEUE - 用于表示要reserve low proiority queue *                           QM_RESERVE_NEXT_FREE_STARVATION_QUEUE     - 用于表示要reserve low proiority queue * @param[out] queueHndPtr  Handle to the queue which was reserved. * @return     EQmRetVal    EQmRetVal_NoError in case of no errors occurred.       假设QmQueueReserve的传入参数是QM_RESERVE_NEXT_FREE_HIGHPRIO_ACC_QUEUE,即要从highpriority aueuereserve一个queue,因为一个dspqmss管理了8192queue,这8192queue 是怎么记录表示他已经reserve呢?是用gPdb.qmInfo.qmDb.queues[row]记录的,queues[256]是个256元素u32的数组,因为一个u3232位,每一位可以表示一个queue,所以一个u32表示32queue所以queues[256]可以表示256*32=8192queue,即每32queue分为一组,共256组。对于high priority queue,下面代码计算的startRow=22maxRows=23,表示high priority queue(有32queue)是用queues[22]这个元素(32位)表示的。上面计算maxRows是:maxRows =(maxRows + 31) / 32.因为queue的编号是0~8191,所以,上面if语句得到的maxRows的范围是0~8191,所以计算maxRows+31再除32.           u32 temQueue = queue // QmQueueReserve函数的第一个参数           else if( tmpQueue == QM_RESERVE_NEXT_FREE_HIGHPRIO_ACC_QUEUE )
          {
            startRow =  QM_QM1_QUEUE_HIGHPRIO_ACC_FIRST; // = 704
            maxRows = QM_QM1_QUEUE_HIGHPRIO_ACC_LAST; //=735           }           startRow /= 32;   //=22
          maxRows = (maxRows + 31) / 32; //=23           for( row = startRow; row < maxRows; row++ )
          {
                 for( bit = 0; bit < 32; bit++ )
                 {
                          if( (gPdb.qmInfo.qmDb.queues[row] & (1<                            {
                                    tmpQueue = row * 32+ bit;  // 转化为真正的queue number = 22*32+bit,这样tmpQueue还原为了0~8191的编号。
                                    if( (tmpQueue & QM_QUEUE_NOT_SUPPORTED_MASK) <  QM_QUEUE_NOT_SUPPORTED_MASK )
                                    {
                                            freeQueueFound = 1; // 找到
                                           /* Reserve selected queue */
                                           gPdb.qmInfo.qmDb.queues[row] |= (1<设置bit位,reserve该queue
                                           queueHndValue = QmHndCreateQueue(tmpQueue); //作为返回值
                                           break;
                                   }
                          }
                 }           }