Behavior of xStreamBufferSend / xStreamBufferReceive

Hi, I am not 100% sure how xStreamBufferSend / xStreamBufferReceive works. Is it safe to assume that xDataLengthBytes are guaranteed to be sent / received when portMAX_DELAY is specified when the call is finished? If that is the case, then the following wrapper is not necessary. Is that corret? “`c sizet osstreamwrite(osstreamt *stream, const void *buffer, sizet length) { sizet byteswritten = 0;
while (true)
{
    size_t chunk_length = xStreamBufferSend(stream->_handle, buffer, length, portMAX_DELAY);

    bytes_written += chunk_length;

    length -= chunk_length;

    if (length == 0)
    {
        break;
    }

    buffer = (uint8_t *) buffer + chunk_length;
}

return bytes_written;
} “` Thank you. Cheers, Pavel

Behavior of xStreamBufferSend / xStreamBufferReceive

I am not 100% sure how xStreamBufferSend / xStreamBufferReceive works. Is it safe to assume that xDataLengthBytes are guaranteed to be sent / received when portMAX_DELAY is specified when the call is finished?
You have all the source code, and xStreamBufferSend() is a small function to read. Lines 520 and 549 (at the time of writing) show a loop with the task waiting under the required amount of space is available: https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Source/stream_buffer.c

Behavior of xStreamBufferSend / xStreamBufferReceive

Hi Richard, thank you! Apparently xStreamBufferSend handles that for you inside the do { } while loop, so no wrapper is necessary there. With xStreamBufferReceive, the situation is different though… the call can return without having the desired length available under normal circumstances (as task can get notified from various reasons) – even if portMAX_DELAY has been specified. This is the wrapper (with timeout support) I have been using for reference (feedback is welcome): “`c sizet osstreamtimedread(osstreamt *stream, void *buffer, size_t length, uint32_t milliseconds) { if (milliseconds == 0) { return xStreamBufferReceive(stream->_handle, buffer, length, 0); }
size_t bytes_read = 0;

uint64_t now = os_time_get();

uint64_t timeout = now + milliseconds;

while (now < timeout)
{
    size_t chunk_length = xStreamBufferReceive(stream->_handle, buffer, length, pdMS_TO_TICKS(timeout - now));

    bytes_read += chunk_length;

    length -= chunk_length;

    if (length == 0)
    {
        break;
    }

    buffer = (uint8_t *) buffer + chunk_length;

    now = os_time_get();
}

return bytes_read;
} “` Thank you. Cheers, Pavel

Behavior of xStreamBufferSend / xStreamBufferReceive

Correct, in xStreamBufferReceive() the second parameter is the size of the buffer into which data is to be copied, not the number of bytes to receive, so xSteamBufferRecevie() will return as soon as it has ‘some’ data, the length of the data it receives in one go being capped to the buffer length. See the xBufferLengthBytes description here: https://www.freertos.org/xStreamBufferReceive.html Ref your implementation of osstreamtimedread() – from a brief look it seems you have have an issue if the tick count overflows, the likelihood of which you have avoided by using a uint64t – access to which will probably not be atomic. It may be easier to use code similar to that shown on this page: https://www.freertos.org/xTaskCheckForTimeOut.html which uses FreeRTOS API calls to take possible overflows into account for you.

Behavior of xStreamBufferSend / xStreamBufferReceive

Thank you, Richard. I was not aware of the xTaskCheckForTimeout function and I will look into it. You are correct – I use uint64_t for my application ticks as it will “never” overflow… 🙂 However, I have been trying to make the access to this variable safe. Here is the snippet including the vApplicationTickHook callback implementation: “`c static uint64t _ostime = 0; uint64t ostimeget(void) { taskENTERCRITICAL();
uint64_t ret = _os_time;

taskEXIT_CRITICAL();

return ret;
} void vApplicationTickHook(void) { static TickType_t xTickLast = 0;
TickType_t xTickNow = xTaskGetTickCountFromISR();

_os_time += xTickNow - xTickLast;

xTickLast = xTickNow;
} “` I hope this is sufficient for safe tick counter operation. Thanks! Regards, Pavel