mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Better support for task blocking ring buffer reads and writes (#7390)
This commit is contained in:
		| @@ -20,13 +20,20 @@ std::unique_ptr<RingBuffer> RingBuffer::create(size_t len) { | |||||||
|     return nullptr; |     return nullptr; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   rb->handle_ = xStreamBufferCreateStatic(len + 1, 0, rb->storage_, &rb->structure_); |   rb->handle_ = xStreamBufferCreateStatic(len + 1, 1, rb->storage_, &rb->structure_); | ||||||
|   ESP_LOGD(TAG, "Created ring buffer with size %u", len); |   ESP_LOGD(TAG, "Created ring buffer with size %u", len); | ||||||
|   return rb; |   return rb; | ||||||
| } | } | ||||||
|  |  | ||||||
| size_t RingBuffer::read(void *data, size_t len, TickType_t ticks_to_wait) { | size_t RingBuffer::read(void *data, size_t len, TickType_t ticks_to_wait) { | ||||||
|   return xStreamBufferReceive(this->handle_, data, len, ticks_to_wait); |   if (ticks_to_wait > 0) | ||||||
|  |     xStreamBufferSetTriggerLevel(this->handle_, len); | ||||||
|  |  | ||||||
|  |   size_t bytes_read = xStreamBufferReceive(this->handle_, data, len, ticks_to_wait); | ||||||
|  |  | ||||||
|  |   xStreamBufferSetTriggerLevel(this->handle_, 1); | ||||||
|  |  | ||||||
|  |   return bytes_read; | ||||||
| } | } | ||||||
|  |  | ||||||
| size_t RingBuffer::write(void *data, size_t len) { | size_t RingBuffer::write(void *data, size_t len) { | ||||||
| @@ -39,6 +46,10 @@ size_t RingBuffer::write(void *data, size_t len) { | |||||||
|   return xStreamBufferSend(this->handle_, data, len, 0); |   return xStreamBufferSend(this->handle_, data, len, 0); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | size_t RingBuffer::write_without_replacement(void *data, size_t len, TickType_t ticks_to_wait) { | ||||||
|  |   return xStreamBufferSend(this->handle_, data, len, ticks_to_wait); | ||||||
|  | } | ||||||
|  |  | ||||||
| size_t RingBuffer::available() const { return xStreamBufferBytesAvailable(this->handle_); } | size_t RingBuffer::available() const { return xStreamBufferBytesAvailable(this->handle_); } | ||||||
|  |  | ||||||
| size_t RingBuffer::free() const { return xStreamBufferSpacesAvailable(this->handle_); } | size_t RingBuffer::free() const { return xStreamBufferSpacesAvailable(this->handle_); } | ||||||
|   | |||||||
| @@ -12,13 +12,69 @@ namespace esphome { | |||||||
|  |  | ||||||
| class RingBuffer { | class RingBuffer { | ||||||
|  public: |  public: | ||||||
|  |   /** | ||||||
|  |    * @brief Reads from the ring buffer, waiting up to a specified number of ticks if necessary. | ||||||
|  |    * | ||||||
|  |    * Available bytes are read into the provided data pointer. If not enough bytes are available, | ||||||
|  |    * the function will wait up to `ticks_to_wait` FreeRTOS ticks before reading what is available. | ||||||
|  |    * | ||||||
|  |    * @param data Pointer to copy read data into | ||||||
|  |    * @param len Number of bytes to read | ||||||
|  |    * @param ticks_to_wait Maximum number of FreeRTOS ticks to wait (default: 0) | ||||||
|  |    * @return Number of bytes read | ||||||
|  |    */ | ||||||
|   size_t read(void *data, size_t len, TickType_t ticks_to_wait = 0); |   size_t read(void *data, size_t len, TickType_t ticks_to_wait = 0); | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * @brief Writes to the ring buffer, overwriting oldest data if necessary. | ||||||
|  |    * | ||||||
|  |    * The provided data is written to the ring buffer. If not enough space is available, | ||||||
|  |    * the function will overwrite the oldest data in the ring buffer. | ||||||
|  |    * | ||||||
|  |    * @param data Pointer to data for writing | ||||||
|  |    * @param len Number of bytes to write | ||||||
|  |    * @return Number of bytes written | ||||||
|  |    */ | ||||||
|   size_t write(void *data, size_t len); |   size_t write(void *data, size_t len); | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * @brief Writes to the ring buffer without overwriting oldest data. | ||||||
|  |    * | ||||||
|  |    * The provided data is written to the ring buffer. If not enough space is available, | ||||||
|  |    * the function will wait up to `ticks_to_wait` FreeRTOS ticks before writing as much as possible. | ||||||
|  |    * | ||||||
|  |    * @param data Pointer to data for writing | ||||||
|  |    * @param len Number of bytes to write | ||||||
|  |    * @param ticks_to_wait Maximum number of FreeRTOS ticks to wait (default: 0) | ||||||
|  |    * @return Number of bytes written | ||||||
|  |    */ | ||||||
|  |   size_t write_without_replacement(void *data, size_t len, TickType_t ticks_to_wait = 0); | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * @brief Returns the number of available bytes in the ring buffer. | ||||||
|  |    * | ||||||
|  |    * This function provides the number of bytes that can be read from the ring buffer | ||||||
|  |    * without blocking the calling FreeRTOS task. | ||||||
|  |    * | ||||||
|  |    * @return Number of available bytes | ||||||
|  |    */ | ||||||
|   size_t available() const; |   size_t available() const; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * @brief Returns the number of free bytes in the ring buffer. | ||||||
|  |    * | ||||||
|  |    * This function provides the number of bytes that can be written to the ring buffer | ||||||
|  |    * without overwriting data or blocking the calling FreeRTOS task. | ||||||
|  |    * | ||||||
|  |    * @return Number of free bytes | ||||||
|  |    */ | ||||||
|   size_t free() const; |   size_t free() const; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * @brief Resets the ring buffer, discarding all stored data. | ||||||
|  |    * | ||||||
|  |    * @return pdPASS if successful, pdFAIL otherwise | ||||||
|  |    */ | ||||||
|   BaseType_t reset(); |   BaseType_t reset(); | ||||||
|  |  | ||||||
|   static std::unique_ptr<RingBuffer> create(size_t len); |   static std::unique_ptr<RingBuffer> create(size_t len); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user