mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-18 13:02:21 +02:00
Corrections on fragmenting/buffering for vfs/cmux
This commit is contained in:
@ -12,15 +12,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include "cxx_include/esp_modem_dte.hpp"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/uart.h"
|
||||
#include "esp_modem_config.h"
|
||||
#include "exception_stub.hpp"
|
||||
#include "esp_vfs_dev.h"
|
||||
|
||||
static const char *TAG = "fs_terminal";
|
||||
|
||||
@ -33,68 +31,16 @@ struct uart_resource {
|
||||
int fd;
|
||||
};
|
||||
|
||||
struct vfs_task {
|
||||
explicit vfs_task(size_t stack_size, size_t priority, void *task_param, TaskFunction_t task_function) :
|
||||
task_handle(nullptr) {
|
||||
BaseType_t ret = xTaskCreate(task_function, "vfs_task"
|
||||
"", stack_size, task_param, priority, &task_handle);
|
||||
throw_if_false(ret == pdTRUE, "create uart event task failed");
|
||||
}
|
||||
|
||||
~vfs_task() {
|
||||
if (task_handle) vTaskDelete(task_handle);
|
||||
}
|
||||
|
||||
TaskHandle_t task_handle; /*!< UART event task handle */
|
||||
};
|
||||
|
||||
uart_resource::~uart_resource()
|
||||
{
|
||||
if (port >= UART_NUM_0 && port < UART_NUM_MAX) {
|
||||
uart_driver_delete(port);
|
||||
}
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
uart_resource::uart_resource(const esp_modem_dte_config *config) :
|
||||
port(-1), fd(-1)
|
||||
{
|
||||
/* Config UART */
|
||||
uart_config_t uart_config = {};
|
||||
uart_config.baud_rate = config->vfs_config.baud_rate;
|
||||
uart_config.data_bits = UART_DATA_8_BITS;
|
||||
uart_config.parity = UART_PARITY_DISABLE;
|
||||
uart_config.stop_bits = UART_STOP_BITS_1;
|
||||
uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
|
||||
uart_config.source_clk = UART_SCLK_REF_TICK;
|
||||
|
||||
throw_if_esp_fail(uart_param_config(config->vfs_config.port_num, &uart_config), "config uart parameter failed");
|
||||
|
||||
throw_if_esp_fail(uart_set_pin(config->vfs_config.port_num, config->vfs_config.tx_io_num, config->vfs_config.rx_io_num,
|
||||
UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE), "config uart gpio failed");
|
||||
|
||||
throw_if_esp_fail(uart_driver_install(config->vfs_config.port_num, config->vfs_config.rx_buffer_size, config->vfs_config.tx_buffer_size,
|
||||
0, nullptr, 0), "install uart driver failed");
|
||||
|
||||
throw_if_esp_fail(uart_set_rx_timeout(config->vfs_config.port_num, 1), "set rx timeout failed");
|
||||
|
||||
throw_if_esp_fail(uart_set_rx_full_threshold(config->uart_config.port_num, 64), "config rx full threshold failed");
|
||||
|
||||
/* mark UART as initialized */
|
||||
port = config->vfs_config.port_num;
|
||||
|
||||
fd = open(config->vfs_config.dev_name, O_RDWR);
|
||||
|
||||
throw_if_false(fd >= 0, "Cannot open the fd");
|
||||
}
|
||||
|
||||
class vfs_terminal : public Terminal {
|
||||
public:
|
||||
explicit vfs_terminal(const esp_modem_dte_config *config) :
|
||||
uart(config), signal(),
|
||||
task_handle(config->vfs_config.task_stack_size, config->vfs_config.task_prio, this, s_task) {}
|
||||
task_handle(config->vfs_config.task_stack_size, config->vfs_config.task_prio, this, [](void* p){
|
||||
auto t = static_cast<vfs_terminal *>(p);
|
||||
t->task();
|
||||
Task::Delete();
|
||||
}) {}
|
||||
|
||||
~vfs_terminal() override = default;
|
||||
|
||||
@ -116,22 +62,16 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static void s_task(void *task_param) {
|
||||
auto t = static_cast<vfs_terminal *>(task_param);
|
||||
t->task();
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void task();
|
||||
|
||||
static const size_t TASK_INIT = BIT0;
|
||||
static const size_t TASK_START = BIT1;
|
||||
static const size_t TASK_STOP = BIT2;
|
||||
static const size_t TASK_PARAMS = BIT3;
|
||||
static const size_t TASK_INIT = SignalGroup::bit0;
|
||||
static const size_t TASK_START = SignalGroup::bit1;
|
||||
static const size_t TASK_STOP = SignalGroup::bit2;
|
||||
static const size_t TASK_PARAMS = SignalGroup::bit3;
|
||||
|
||||
uart_resource uart;
|
||||
signal_group signal;
|
||||
vfs_task task_handle;
|
||||
SignalGroup signal;
|
||||
Task task_handle;
|
||||
};
|
||||
|
||||
std::unique_ptr<Terminal> create_vfs_terminal(const esp_modem_dte_config *config) {
|
||||
@ -144,13 +84,15 @@ std::unique_ptr<Terminal> create_vfs_terminal(const esp_modem_dte_config *config
|
||||
|
||||
void vfs_terminal::task() {
|
||||
std::function<bool(uint8_t *data, size_t len)> on_data_priv = nullptr;
|
||||
size_t len;
|
||||
// size_t len;
|
||||
signal.set(TASK_INIT);
|
||||
signal.wait_any(TASK_START | TASK_STOP, portMAX_DELAY);
|
||||
if (signal.is_any(TASK_STOP)) {
|
||||
return; // exits to the static method where the task gets deleted
|
||||
}
|
||||
esp_vfs_dev_uart_use_driver(uart.port);
|
||||
// esp_vfs_dev_uart_use_driver(uart.port);
|
||||
int flags = fcntl(uart.fd, F_GETFL, NULL) | O_NONBLOCK;
|
||||
fcntl(uart.fd, F_SETFL, flags);
|
||||
|
||||
while (signal.is_any(TASK_START)) {
|
||||
int s;
|
||||
@ -163,35 +105,36 @@ void vfs_terminal::task() {
|
||||
FD_SET(uart.fd, &rfds);
|
||||
|
||||
s = select(uart.fd + 1, &rfds, NULL, NULL, &tv);
|
||||
// if (signal.is_any(TASK_PARAMS)) {
|
||||
if (signal.is_any(TASK_PARAMS)) {
|
||||
on_data_priv = on_data;
|
||||
// signal.clear(TASK_PARAMS);
|
||||
// }
|
||||
signal.clear(TASK_PARAMS);
|
||||
}
|
||||
|
||||
if (s < 0) {
|
||||
ESP_LOGE(TAG, "Select failed: errno %d", errno);
|
||||
break;
|
||||
} else if (s == 0) {
|
||||
ESP_LOGI(TAG, "Timeout has been reached and nothing has been received");
|
||||
|
||||
} else {
|
||||
if (FD_ISSET(uart.fd, &rfds)) {
|
||||
uart_get_buffered_data_len(uart.port, &len);
|
||||
if (len && on_data_priv) {
|
||||
if (on_data_priv(nullptr, len)) {
|
||||
// uart_get_buffered_data_len(uart.port, &len);
|
||||
if (on_data_priv) {
|
||||
if (on_data_priv(nullptr, 0)) {
|
||||
on_data_priv = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
vTaskDelay(1);
|
||||
Task::Relinquish();
|
||||
}
|
||||
}
|
||||
|
||||
int vfs_terminal::read(uint8_t *data, size_t len) {
|
||||
int vfs_terminal::read(uint8_t *data, size_t len)
|
||||
{
|
||||
return ::read(uart.fd, data, len);
|
||||
}
|
||||
|
||||
int vfs_terminal::write(uint8_t *data, size_t len) {
|
||||
int vfs_terminal::write(uint8_t *data, size_t len)
|
||||
{
|
||||
return ::write(uart.fd, data, len);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user