Queue block time not work as desired

Hi all, currently using FreeRTOS V8.2.3, ported for Cortex-M4. The porting has been done by one of my ex-collegue and works well in one of the product, display unit as Master. Now I am using the same hardware platform, the same porting for the sensor unit as Slave. Basically, the sensor measure flow rate, display unit sends out commands via SPI to retrieve measurement value such as velocity, flow rate, temperature, as well as some basic settings as diameter. In sensor unit, while (1) { Rev = SPIRx((INT08U)&RxChar, 1, 5); //see below the definition
if (Rev == NON_ERROR) { /
Handler*/ } } INT32U SPIRx(INT08U *buf, INT32U num, INT32U ms) { INT32U i;
for (i = 0; i < num; i++) {
    if (xQueueReceive(SPI_RXQueue, &buf[i], ms) == pdTRUE) {   // SPI_RXQueue sent out in SPI_ISR
        continue;
    } else {
        return ERROR_SPI_TIMEOUT;
    }
}

return NON_ERROR;
} Firstly, the master side works well with other slaves. Secondly, for (xQueueReceive(SPI_RXQueue, &buf[i], ms) , here what i first set the block time is 100ms, which i think is not important, because ISR can send out the value to Queue und unblock the task. However, I can only set this block time to 5ms, and very important thing is, i need to modify the master, DELAY 6ms before send out every commands. If i set this block time more, the master should delay more, otherwise, slave can not successfully received. Thirdly, this block time also true in UART situation, the master need delay(20) more than slave, and the block time in slave need to adjust 18ms, thus, communication works. This is a compromise solution. not know what the root cause is. Last, the usb task(which the coding is totally the same as in master, well-tested), if i comment other tasks, the PC can detect the slave, if SPI or UART task exists, than PC says unknown device, not connected. even if I set the blocktime of USB to 5ms Rev = USBRead((INT08U)&RxChar, 1, 5); before Rev = USBRead((INT08U)&RxChar, 1, 100); INT32U USBRead(INT08U *buf, INT32U num, INT32U ms) { INT32U i;
for (i = 0; i < num; i++) {
    if (xQueueReceive(USB_RXQueue, &buf[i], ms) == pdTRUE) {
        continue;
    } else {
        return ERROR_USB_COMM_TIMEOUT;
    }
}

return NON_ERROR;
} I have totally no idea why this would happen.. confused me a lot. I hope someone can give me some hints. very appreciate that..

Queue block time not work as desired

Sorry – I’m very confused as to what your question is. Are you saying that when you call xQueueReceive() the block time you specify is not the block time you get? Or something else? If your question is imply that the block time you specify is not the block time you get, then how are you calculating the time in milliseconds? Are you using the pdMSTOTICKS() macro, and if so, is your configTICKRATEMS setting at or below 1 KHz, as the macro will not work with a tick frequency above 1KHz.

Queue block time not work as desired

hi, thanks for the quick reply. The delay time as in vTaskDelay(10) is accurate. The problem is that I can not set the block time longer than the certain value. Actually, what i consider is, i can set the block time to max value(0xFFFFFFFF), as long as i send data to the queue from ISR. Once interrupt, data sent to the queue, task unblocked. the real situation is, it seems that the task is not unblocked by xQueueSendFromISR(); at the end of ISR also with portENDSWITCHINGISR(xHigherPriorityTaskWoken); the reason that i say this is: I have a master to send out commands(100khz bit rate), a. if i set the block time in slave to 100ms as in my last post, slave can not receive, b. if i set the block time to 5ms, can not receive c. if i set the delay time in master to 6ms before sending out commands, the block time to 5ms, ok. based on the above, the slave polls the queue, and block certain ms if not available. it seems that if the master send data quicker than block time, the queue is not unblocked. void DSPIDRVSlaveIRQHandler(uint32t instance) { signed portBASETYPE xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE;
SPI_Type *base = g_dspiBase[instance];

INT08U RxBuf, *TxBufPtr ;
static INT08U TxBuf;
static INT08U TxIndex;

TxBufPtr = ((INT08U*)TKDisplayGetSPIMessage());
while (DSPI_HAL_GetStatusFlag(base, kDspiRxFifoDrainRequest))
{
    RxBuf = (INT08U)DSPI_HAL_ReadData(base);

    DSPI_HAL_SetFlushFifoCmd(base, true, true); //  enableFlushTxFifo, enableFlushRxFifo
    DSPI_HAL_ClearStatusFlag(base, kDspiRxFifoDrainRequest);

    /*if something to send, otherwise send dummy*/
    if( SPI_Instance[0].size){          
        TxBuf = (INT32U)TxBufPtr[TxIndex++];
        SPI_Instance[0].size--;
    } else {
        TxBuf = (INT32U)0xff;
        TxIndex = 0;
    }

    /* Write the data to the DSPI data register */  
    DSPI_HAL_WriteDataSlavemode(base, TxBuf);

    /* try to clear TFFF by writing a one to it; it will not clear if TX FIFO not full */
    DSPI_HAL_ClearStatusFlag(base, kDspiTxFifoFillRequest);
    xQueueSendFromISR(SPI_RXQueue, (INT08U *)&RxBuf, &xHigherPriorityTaskWoken);
    portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
} Jason

Queue block time not work as desired

based on the above, the slave polls the queue, and block certain ms if not available. it seems that if the master send data quicker than block time, the queue is not unblocked.
Sounds like you are just saying you can poll the queue but you cannot unblock the task waiting on the queue. Have you checked how long you are staying inside the ISR? I has a loop in it, maybe you stay in it for a very long time. Also, move the portENDSWITCHINGISR() call outside the loop, you only need to call it once and can use the same xHigherPriorityTaskWoken variable without having to re init the variable because it can only get set from 0 to 1.

Queue block time not work as desired

hi MEdwards, thanks for the reply. I didn’t check the time inside the ISR, but it suppose fast, i enter the ISR, check if it’s rx interrupt and if data in the rx register, receive, clear the interrupt flag. get the data, send queue, portENDSWITCHINGISR() in order to jump out immediatly. if more bytes are avaiblable, then triggers another interrupt. in UART rx callback, not such while() function, the similar problem also exists. which is simply UART comm,8N1 the reason that i say this is: I have a master to send out commands(1200bps baudrate, very slow), a. if i set the block time in slave to 100ms as in my last post, slave can not receive, b. if i set the delay time in master to 20ms before sending out commands, the block time remains 100ms not ok c.if i set the block time to 18ms, ok. static void UARTRxCallback(uint32t instance, void *uartState) {
signed portBASE_TYPE xHigherPriorityTaskWoken;
uart_state_t* obj = (uart_state_t*)uartState; 

xHigherPriorityTaskWoken = pdFALSE;
xQueueSendFromISR(UART_RXQueue, (INT08U *)(obj->rxBuff), &xHigherPriorityTaskWoken);
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
} the main loop is the same as in my first post. Jason

Queue block time not work as desired

hi could someone give more hints? how this would happen, how can i test and debug thanks so much

Queue block time not work as desired

step thru xQueueSendFromISR() in debugger to see if it unblocks the task. maybe the task is not blocked when called.