[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

@@ -1,6 +1,5 @@
#include "usb_uart_bridge.h"
#include "furi_hal.h"
#include <stream_buffer.h>
#include <furi_hal_usb_cdc.h>
#include "usb_cdc.h"
#include "cli/cli_vcp.h"
@@ -43,7 +42,7 @@ struct UsbUartBridge {
FuriThread* thread;
FuriThread* tx_thread;
StreamBufferHandle_t rx_stream;
FuriStreamBuffer* rx_stream;
FuriMutex* usb_mutex;
@@ -74,12 +73,10 @@ static int32_t usb_uart_tx_thread(void* context);
static void usb_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
UsbUartBridge* usb_uart = (UsbUartBridge*)context;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if(ev == UartIrqEventRXNE) {
xStreamBufferSendFromISR(usb_uart->rx_stream, &data, 1, &xHigherPriorityTaskWoken);
furi_stream_buffer_send(usb_uart->rx_stream, &data, 1, 0);
furi_thread_flags_set(furi_thread_get_id(usb_uart->thread), WorkerEvtRxDone);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
@@ -156,7 +153,7 @@ static int32_t usb_uart_worker(void* context) {
memcpy(&usb_uart->cfg, &usb_uart->cfg_new, sizeof(UsbUartConfig));
usb_uart->rx_stream = xStreamBufferCreate(USB_UART_RX_BUF_SIZE, 1);
usb_uart->rx_stream = furi_stream_buffer_alloc(USB_UART_RX_BUF_SIZE, 1);
usb_uart->tx_sem = furi_semaphore_alloc(1, 1);
usb_uart->usb_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
@@ -189,8 +186,8 @@ static int32_t usb_uart_worker(void* context) {
furi_check((events & FuriFlagError) == 0);
if(events & WorkerEvtStop) break;
if(events & WorkerEvtRxDone) {
size_t len =
xStreamBufferReceive(usb_uart->rx_stream, usb_uart->rx_buf, USB_CDC_PKT_LEN, 0);
size_t len = furi_stream_buffer_receive(
usb_uart->rx_stream, usb_uart->rx_buf, USB_CDC_PKT_LEN, 0);
if(len > 0) {
if(furi_semaphore_acquire(usb_uart->tx_sem, 100) == FuriStatusOk) {
usb_uart->st.rx_cnt += len;
@@ -199,7 +196,7 @@ static int32_t usb_uart_worker(void* context) {
furi_hal_cdc_send(usb_uart->cfg.vcp_ch, usb_uart->rx_buf, len);
furi_check(furi_mutex_release(usb_uart->usb_mutex) == FuriStatusOk);
} else {
xStreamBufferReset(usb_uart->rx_stream);
furi_stream_buffer_reset(usb_uart->rx_stream);
}
}
}
@@ -270,7 +267,7 @@ static int32_t usb_uart_worker(void* context) {
furi_thread_join(usb_uart->tx_thread);
furi_thread_free(usb_uart->tx_thread);
vStreamBufferDelete(usb_uart->rx_stream);
furi_stream_buffer_free(usb_uart->rx_stream);
furi_mutex_free(usb_uart->usb_mutex);
furi_semaphore_free(usb_uart->tx_sem);

View File

@@ -2,7 +2,6 @@
#include <furi.h>
#include <furi_hal.h>
#include <stream_buffer.h>
#include <lib/toolbox/args.h>
#include <lib/subghz/subghz_keystore.h>
@@ -194,23 +193,21 @@ void subghz_cli_command_tx(Cli* cli, FuriString* args, void* context) {
typedef struct {
volatile bool overrun;
StreamBufferHandle_t stream;
FuriStreamBuffer* stream;
size_t packet_count;
} SubGhzCliCommandRx;
static void subghz_cli_command_rx_capture_callback(bool level, uint32_t duration, void* context) {
SubGhzCliCommandRx* instance = context;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
LevelDuration level_duration = level_duration_make(level, duration);
if(instance->overrun) {
instance->overrun = false;
level_duration = level_duration_reset();
}
size_t ret = xStreamBufferSendFromISR(
instance->stream, &level_duration, sizeof(LevelDuration), &xHigherPriorityTaskWoken);
size_t ret =
furi_stream_buffer_send(instance->stream, &level_duration, sizeof(LevelDuration), 0);
if(sizeof(LevelDuration) != ret) instance->overrun = true;
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
static void subghz_cli_command_rx_callback(
@@ -249,7 +246,8 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) {
// Allocate context and buffers
SubGhzCliCommandRx* instance = malloc(sizeof(SubGhzCliCommandRx));
instance->stream = xStreamBufferCreate(sizeof(LevelDuration) * 1024, sizeof(LevelDuration));
instance->stream =
furi_stream_buffer_alloc(sizeof(LevelDuration) * 1024, sizeof(LevelDuration));
furi_check(instance->stream);
SubGhzEnvironment* environment = subghz_environment_alloc();
@@ -279,8 +277,8 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) {
printf("Listening at %lu. Press CTRL+C to stop\r\n", frequency);
LevelDuration level_duration;
while(!cli_cmd_interrupt_received(cli)) {
int ret =
xStreamBufferReceive(instance->stream, &level_duration, sizeof(LevelDuration), 10);
int ret = furi_stream_buffer_receive(
instance->stream, &level_duration, sizeof(LevelDuration), 10);
if(ret == sizeof(LevelDuration)) {
if(level_duration_is_reset(level_duration)) {
printf(".");
@@ -304,7 +302,7 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) {
// Cleanup
subghz_receiver_free(receiver);
subghz_environment_free(environment);
vStreamBufferDelete(instance->stream);
furi_stream_buffer_free(instance->stream);
free(instance);
}