[FL-2839] Furi stream buffer (#1834)

* Core: stream buffer
* stream buffer: API and usage
* stream buffer: documentation
* stream buffer: more documentation
* Furi: fix spelling

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
Sergey Gavrilov
2022-10-07 22:27:11 +10:00
committed by GitHub
parent d1843c0094
commit 38a82a1907
21 changed files with 403 additions and 208 deletions

View File

@@ -7,7 +7,6 @@
#include <time.h>
#include <notification/notification_messages.h>
#include <loader/loader.h>
#include <stream_buffer.h>
// Close to ISO, `date +'%Y-%m-%d %H:%M:%S %u'`
#define CLI_DATE_FORMAT "%.4d-%.2d-%.2d %.2d:%.2d:%.2d %d"
@@ -140,7 +139,7 @@ void cli_command_date(Cli* cli, FuriString* args, void* context) {
#define CLI_COMMAND_LOG_BUFFER_SIZE 64
void cli_command_log_tx_callback(const uint8_t* buffer, size_t size, void* context) {
xStreamBufferSend(context, buffer, size, 0);
furi_stream_buffer_send(context, buffer, size, 0);
}
void cli_command_log_level_set_from_string(FuriString* level) {
@@ -165,7 +164,7 @@ void cli_command_log_level_set_from_string(FuriString* level) {
void cli_command_log(Cli* cli, FuriString* args, void* context) {
UNUSED(context);
StreamBufferHandle_t ring = xStreamBufferCreate(CLI_COMMAND_LOG_RING_SIZE, 1);
FuriStreamBuffer* ring = furi_stream_buffer_alloc(CLI_COMMAND_LOG_RING_SIZE, 1);
uint8_t buffer[CLI_COMMAND_LOG_BUFFER_SIZE];
FuriLogLevel previous_level = furi_log_get_level();
bool restore_log_level = false;
@@ -179,7 +178,7 @@ void cli_command_log(Cli* cli, FuriString* args, void* context) {
printf("Press CTRL+C to stop...\r\n");
while(!cli_cmd_interrupt_received(cli)) {
size_t ret = xStreamBufferReceive(ring, buffer, CLI_COMMAND_LOG_BUFFER_SIZE, 50);
size_t ret = furi_stream_buffer_receive(ring, buffer, CLI_COMMAND_LOG_BUFFER_SIZE, 50);
cli_write(cli, buffer, ret);
}
@@ -190,7 +189,7 @@ void cli_command_log(Cli* cli, FuriString* args, void* context) {
furi_log_set_level(previous_level);
}
vStreamBufferDelete(ring);
furi_stream_buffer_free(ring);
}
void cli_command_vibro(Cli* cli, FuriString* args, void* context) {

View File

@@ -1,7 +1,6 @@
#include <furi_hal_usb_cdc.h>
#include <furi_hal.h>
#include <furi.h>
#include <stream_buffer.h>
#include "cli_i.h"
#define TAG "CliVcp"
@@ -29,8 +28,8 @@ typedef enum {
typedef struct {
FuriThread* thread;
StreamBufferHandle_t tx_stream;
StreamBufferHandle_t rx_stream;
FuriStreamBuffer* tx_stream;
FuriStreamBuffer* rx_stream;
volatile bool connected;
volatile bool running;
@@ -62,8 +61,8 @@ static const uint8_t ascii_eot = 0x04;
static void cli_vcp_init() {
if(vcp == NULL) {
vcp = malloc(sizeof(CliVcp));
vcp->tx_stream = xStreamBufferCreate(VCP_TX_BUF_SIZE, 1);
vcp->rx_stream = xStreamBufferCreate(VCP_RX_BUF_SIZE, 1);
vcp->tx_stream = furi_stream_buffer_alloc(VCP_TX_BUF_SIZE, 1);
vcp->rx_stream = furi_stream_buffer_alloc(VCP_RX_BUF_SIZE, 1);
}
furi_assert(vcp->thread == NULL);
@@ -113,7 +112,7 @@ static int32_t vcp_worker(void* context) {
#endif
if(vcp->connected == false) {
vcp->connected = true;
xStreamBufferSend(vcp->rx_stream, &ascii_soh, 1, FuriWaitForever);
furi_stream_buffer_send(vcp->rx_stream, &ascii_soh, 1, FuriWaitForever);
}
}
@@ -124,8 +123,8 @@ static int32_t vcp_worker(void* context) {
#endif
if(vcp->connected == true) {
vcp->connected = false;
xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0);
xStreamBufferSend(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever);
furi_stream_buffer_receive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0);
furi_stream_buffer_send(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever);
}
}
@@ -134,7 +133,7 @@ static int32_t vcp_worker(void* context) {
#ifdef CLI_VCP_DEBUG
FURI_LOG_D(TAG, "StreamRx");
#endif
if(xStreamBufferSpacesAvailable(vcp->rx_stream) >= USB_CDC_PKT_LEN) {
if(furi_stream_buffer_spaces_available(vcp->rx_stream) >= USB_CDC_PKT_LEN) {
flags |= VcpEvtRx;
missed_rx--;
}
@@ -142,14 +141,15 @@ static int32_t vcp_worker(void* context) {
// New data received
if(flags & VcpEvtRx) {
if(xStreamBufferSpacesAvailable(vcp->rx_stream) >= USB_CDC_PKT_LEN) {
if(furi_stream_buffer_spaces_available(vcp->rx_stream) >= USB_CDC_PKT_LEN) {
int32_t len = furi_hal_cdc_receive(VCP_IF_NUM, vcp->data_buffer, USB_CDC_PKT_LEN);
#ifdef CLI_VCP_DEBUG
FURI_LOG_D(TAG, "Rx %d", len);
#endif
if(len > 0) {
furi_check(
xStreamBufferSend(vcp->rx_stream, vcp->data_buffer, len, FuriWaitForever) ==
furi_stream_buffer_send(
vcp->rx_stream, vcp->data_buffer, len, FuriWaitForever) ==
(size_t)len);
}
} else {
@@ -173,7 +173,7 @@ static int32_t vcp_worker(void* context) {
// CDC write transfer done
if(flags & VcpEvtTx) {
size_t len =
xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0);
furi_stream_buffer_receive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0);
#ifdef CLI_VCP_DEBUG
FURI_LOG_D(TAG, "Tx %d", len);
#endif
@@ -202,8 +202,8 @@ static int32_t vcp_worker(void* context) {
furi_hal_usb_unlock();
furi_hal_usb_set_config(vcp->usb_if_prev, NULL);
}
xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0);
xStreamBufferSend(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever);
furi_stream_buffer_receive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0);
furi_stream_buffer_send(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever);
break;
}
}
@@ -229,7 +229,7 @@ static size_t cli_vcp_rx(uint8_t* buffer, size_t size, uint32_t timeout) {
size_t batch_size = size;
if(batch_size > VCP_RX_BUF_SIZE) batch_size = VCP_RX_BUF_SIZE;
size_t len = xStreamBufferReceive(vcp->rx_stream, buffer, batch_size, timeout);
size_t len = furi_stream_buffer_receive(vcp->rx_stream, buffer, batch_size, timeout);
#ifdef CLI_VCP_DEBUG
FURI_LOG_D(TAG, "rx %u ", batch_size);
#endif
@@ -262,7 +262,7 @@ static void cli_vcp_tx(const uint8_t* buffer, size_t size) {
size_t batch_size = size;
if(batch_size > USB_CDC_PKT_LEN) batch_size = USB_CDC_PKT_LEN;
xStreamBufferSend(vcp->tx_stream, buffer, batch_size, FuriWaitForever);
furi_stream_buffer_send(vcp->tx_stream, buffer, batch_size, FuriWaitForever);
furi_thread_flags_set(furi_thread_get_id(vcp->thread), VcpEvtStreamTx);
#ifdef CLI_VCP_DEBUG
FURI_LOG_D(TAG, "tx %u", batch_size);

View File

@@ -13,7 +13,6 @@
#include <cli/cli.h>
#include <stdint.h>
#include <stdio.h>
#include <stream_buffer.h>
#include <m-dict.h>
#define TAG "RpcSrv"
@@ -61,7 +60,7 @@ struct RpcSession {
FuriThread* thread;
RpcHandlerDict_t handlers;
StreamBufferHandle_t stream;
FuriStreamBuffer* stream;
PB_Main* decoded_message;
bool terminate;
void** system_contexts;
@@ -151,7 +150,7 @@ size_t
furi_assert(encoded_bytes);
furi_assert(size > 0);
size_t bytes_sent = xStreamBufferSend(session->stream, encoded_bytes, size, timeout);
size_t bytes_sent = furi_stream_buffer_send(session->stream, encoded_bytes, size, timeout);
furi_thread_flags_set(furi_thread_get_id(session->thread), RpcEvtNewData);
@@ -160,7 +159,7 @@ size_t
size_t rpc_session_get_available_size(RpcSession* session) {
furi_assert(session);
return xStreamBufferSpacesAvailable(session->stream);
return furi_stream_buffer_spaces_available(session->stream);
}
bool rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) {
@@ -174,9 +173,9 @@ bool rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) {
size_t bytes_received = 0;
while(1) {
bytes_received +=
xStreamBufferReceive(session->stream, buf + bytes_received, count - bytes_received, 0);
if(xStreamBufferIsEmpty(session->stream)) {
bytes_received += furi_stream_buffer_receive(
session->stream, buf + bytes_received, count - bytes_received, 0);
if(furi_stream_buffer_is_empty(session->stream)) {
if(session->buffer_is_empty_callback) {
session->buffer_is_empty_callback(session->context);
}
@@ -190,7 +189,7 @@ bool rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) {
} else {
flags = furi_thread_flags_wait(RPC_ALL_EVENTS, FuriFlagWaitAny, FuriWaitForever);
if(flags & RpcEvtDisconnect) {
if(xStreamBufferIsEmpty(session->stream)) {
if(furi_stream_buffer_is_empty(session->stream)) {
session->terminate = true;
istream->bytes_left = 0;
bytes_received = 0;
@@ -279,7 +278,7 @@ static int32_t rpc_session_worker(void* context) {
}
if(message_decode_failed) {
xStreamBufferReset(session->stream);
furi_stream_buffer_reset(session->stream);
if(!session->terminate) {
/* Protobuf can't determine start and end of message.
* Handle this by adding varint at beginning
@@ -329,7 +328,7 @@ static void rpc_session_free_callback(FuriThreadState thread_state, void* contex
free(session->system_contexts);
free(session->decoded_message);
RpcHandlerDict_clear(session->handlers);
vStreamBufferDelete(session->stream);
furi_stream_buffer_free(session->stream);
furi_mutex_acquire(session->callbacks_mutex, FuriWaitForever);
if(session->terminated_callback) {
@@ -348,7 +347,7 @@ RpcSession* rpc_session_open(Rpc* rpc) {
RpcSession* session = malloc(sizeof(RpcSession));
session->callbacks_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
session->stream = xStreamBufferCreate(RPC_BUFFER_SIZE, 1);
session->stream = furi_stream_buffer_alloc(RPC_BUFFER_SIZE, 1);
session->rpc = rpc;
session->terminate = false;
session->decode_error = false;