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 aueue中reserve一个queue,因为一个dsp的qmss管理了8192个queue,这8192个queue 是怎么记录表示他已经reserve呢?是用gPdb.qmInfo.qmDb.queues[row]记录的,queues[256]是个256元素的u32的数组,因为一个u32是32位,每一位可以表示一个queue,所以一个u32表示32个queue,所以queues[256]可以表示256*32=8192个queue,即每32个queue分为一组,共256组。对于high priority queue,下面代码计算的startRow=22,maxRows=23,表示high priority queue(有32个queue)是用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<<bit)) == 0 )
{
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); //设置bit位,reserve该queue
queueHndValue = QmHndCreateQueue(tmpQueue); //作为返回值
break;
}
}
}
}