ESP32. Multitasking with WiFiClient. Test fill state of TX buffer.

Hi everybody

I'm using the WiFiClient class in a multitasking environment. I can't let my "sendData" task loop in a "flush()" function, waiting for all bytes in the TX buffer to have been sent, to make a safe "write()".
So I would like to find a way to test the amount of space available in the TX buffer, without blocking my task in a software loop.

Assuming that there existe somewhere a circular buffer, with "BufferSize" value, and pointers like "BufferHead" and "BufferTail", I would like to write a function like :

unsigned long TxBufferAvailableSpace () {
unsigned long room ;
if (bufferHead >= bufferTail) room = bufferHead - bufferTail ;
else room = bufferSize + bufferHead - bufferTail ;
return room ;
}

Does anybody have a solution, tested with ESP32, to solve this problem ? This function does it exist somewhere, or what is the exact syntax to write it ?

I have some buffered client output classes for the ESP32 and ESP8266
and a general BufferedOutput class that includes availableForWrite()
See Text I/O for the Real World
but neither of these are designed for multitasking
Are you actually writing from two threads (or cores)?

I use a simple round robin scheduler. In the loop() section of the code, I call all tasks once, and each task manages to take a small amount of cpu time. Works fine with minimum overhead. So on the ESP32 I use only the application core, but I think that the WiFiClient write functions possibly use the other one. This could be a problem if bufferHead and bufferTail are shared beetween the two cores. The sequence of the shown function being very short, I could mask interrupts during it.

drmpf:
I have some buffered client output classes for the ESP32 and ESP8266
and a general BufferedOutput class that includes availableForWrite()
See Text I/O for the Real World
but neither of these are designed for multitasking
Are you actually writing from two threads (or cores)?

I see that in the code of the following function :
size_t pfodESP32BufferedClient::_write(uint8_t c) {...
You push the bytes to write in a buffer and when the buffer is full you call the client.write (buf, bufsize) function. You comment this line with "this call may block if last packet not ACKed yet".
This is precisely what I want to avoid. So I don't think that your library can help in my multitasking context.

int socket_async_send(SOCKET_ASYNC_HANDLE sock, const void* buffer, size_t size, size_t* sent_count)

seems to be what you want, I have not used it. Looks like it is used in Azure IoT code
so you might be able to hack that, but you will have to throw away a lot of code

/**

  • @brief Send a message on the specified socket.
  • @param sock The socket to be used.
  • @param buffer The buffer containing the message to transmit.
  • @param size The number of bytes to transmit.
  • @param sent_count Receives the number of bytes transmitted. The N == 0
  • case means normal operation but the socket’s outgoing buffer was full.
  • @return @c 0 if successful.
  • FAILURE means an unexpected error has occurred and the socket must be destroyed.

JiPe38:
I use a simple round robin scheduler. In the loop() section of the code, I call all tasks once, and each task manages to take a small amount of cpu time.

Why don't you use the real multi-tasking capabilities that FreeRTOS (which is already running on the ESP32) provides for you?

gfvalvo:
Why don't you use the real multi-tasking capabilities that FreeRTOS (which is already running on the ESP32) provides for you?

Simpler, faster. I have only three tasks. And I used that already many times, so I am used to do this way; each of my task is a class which inherits of a "task" class, with the bases of a state machine. I don't need preemptive scheduling and, when I did it in some cases in the past I have another solution.

drmpf:

int socket_async_send(SOCKET_ASYNC_HANDLE sock, const void* buffer, size_t size, size_t* sent_count)

seems to be what you want, I have not used it. Looks like it is used in Azure IoT code
so you might be able to hack that, but you will have to throw away a lot of code

My esp32 implements a web server, in http protocol, and communicates with a browser. I would need to add the http capsule before sending it to a socket. And I am not sure that this async-send would solve the problem of blocking "write" on an ESP32. Do you have an example of it's use in a server context to serve a connected client ?

BTW, I see that my function in the first post doesn't give the available space but the current number of bytes in the buffer :slight_smile: you changed the name of the function by yourself...

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.