Reduce heap allocations by getting rid of temporary std::list and std::string

This commit is contained in:
2023-12-19 15:07:53 +01:00
parent b8cdd373f4
commit 1d49013fc6
10 changed files with 44 additions and 40 deletions

View File

@@ -42,7 +42,7 @@ idf_component_register(SRCS "${srcs}"
set_target_properties(${COMPONENT_LIB} PROPERTIES set_target_properties(${COMPONENT_LIB} PROPERTIES
CXX_STANDARD 17 CXX_STANDARD 23
CXX_STANDARD_REQUIRED ON CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS ON CXX_EXTENSIONS ON
) )

View File

@@ -28,9 +28,9 @@ namespace dce_commands {
* @param fail_phrase String to be present in the reply to fail this command * @param fail_phrase String to be present in the reply to fail this command
* @param timeout_ms Timeout in ms * @param timeout_ms Timeout in ms
*/ */
command_result generic_command(CommandableIf *t, const std::string &command, command_result generic_command(CommandableIf *t, std::string_view command,
const std::string &pass_phrase, std::string_view pass_phrase,
const std::string &fail_phrase, uint32_t timeout_ms); std::string_view fail_phrase, uint32_t timeout_ms);
/** /**
* @brief Declaration of all commands is generated from esp_modem_command_declare.inc * @brief Declaration of all commands is generated from esp_modem_command_declare.inc
*/ */

View File

@@ -496,8 +496,8 @@ command_result SQNGM02S::connect(PdpContext &pdp)
return res; return res;
} }
//wait for +CEREG: 5 or +CEREG: 1. //wait for +CEREG: 5 or +CEREG: 1.
const auto pass = std::list<std::string_view>({"+CEREG: 1", "+CEREG: 5"}); const std::string_view pass[] {"+CEREG: 1", "+CEREG: 5"};
const auto fail = std::list<std::string_view>({"ERROR"}); const std::string_view fail[] {"ERROR"};
res = esp_modem::dce_commands::generic_command(dte.get(), "", pass, fail, 1200000); res = esp_modem::dce_commands::generic_command(dte.get(), "", pass, fail, 1200000);
if (res != command_result::OK) { if (res != command_result::OK) {
config_network_registration_urc(0); config_network_registration_urc(0);

View File

@@ -31,9 +31,9 @@ namespace dce_commands {
* @param fail_phrase String to be present in the reply to fail this command * @param fail_phrase String to be present in the reply to fail this command
* @param timeout_ms Timeout in ms * @param timeout_ms Timeout in ms
*/ */
command_result generic_command(CommandableIf *t, const std::string &command, command_result generic_command(CommandableIf *t, std::string_view command,
const std::string &pass_phrase, std::string_view pass_phrase,
const std::string &fail_phrase, uint32_t timeout_ms); std::string_view fail_phrase, uint32_t timeout_ms);
/** /**
* @brief Declaration of all commands is generated from esp_modem_command_declare.inc * @brief Declaration of all commands is generated from esp_modem_command_declare.inc

View File

@@ -10,8 +10,8 @@
#include "cxx_include/esp_modem_dce_module.hpp" #include "cxx_include/esp_modem_dce_module.hpp"
namespace esp_modem::dce_commands { namespace esp_modem::dce_commands {
command_result generic_command(CommandableIf *t, const std::string &command, command_result generic_command(CommandableIf *t, std::string_view command,
const std::list<std::string_view> &pass_phrase, std::span<const std::string_view> pass_phrase,
const std::list<std::string_view> &fail_phrase, std::span<const std::string_view> fail_phrase,
uint32_t timeout_ms); uint32_t timeout_ms);
} }

View File

@@ -6,6 +6,9 @@
#pragma once #pragma once
#include <string_view>
#include <span>
namespace esp_modem::dce_commands { namespace esp_modem::dce_commands {
/** /**
@@ -17,9 +20,9 @@ namespace esp_modem::dce_commands {
* @param timeout_ms Command timeout in ms * @param timeout_ms Command timeout in ms
* @return Generic command return type (OK, FAIL, TIMEOUT) * @return Generic command return type (OK, FAIL, TIMEOUT)
*/ */
command_result generic_command(CommandableIf *t, const std::string &command, command_result generic_command(CommandableIf *t, std::string_view command,
const std::string &pass_phrase, std::string_view pass_phrase,
const std::string &fail_phrase, uint32_t timeout_ms); std::string_view fail_phrase, uint32_t timeout_ms);
/** /**
* @brief Utility command to send command and return reply (after DCE says OK) * @brief Utility command to send command and return reply (after DCE says OK)
@@ -29,7 +32,7 @@ command_result generic_command(CommandableIf *t, const std::string &command,
* @param timeout_ms Command timeout in ms * @param timeout_ms Command timeout in ms
* @return Generic command return type (OK, FAIL, TIMEOUT) * @return Generic command return type (OK, FAIL, TIMEOUT)
*/ */
template <typename T> command_result generic_get_string(CommandableIf *t, const std::string &command, T &output, uint32_t timeout_ms = 500); template <typename T> command_result generic_get_string(CommandableIf *t, std::string_view command, T &output, uint32_t timeout_ms = 500);
/** /**
* @brief Generic command that passes on "OK" and fails on "ERROR" * @brief Generic command that passes on "OK" and fails on "ERROR"
@@ -38,6 +41,6 @@ template <typename T> command_result generic_get_string(CommandableIf *t, const
* @param timeout_ms Command timeout in ms * @param timeout_ms Command timeout in ms
* @return Generic command return type (OK, FAIL, TIMEOUT) * @return Generic command return type (OK, FAIL, TIMEOUT)
*/ */
command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout_ms = 500); command_result generic_command_common(CommandableIf *t, std::string_view command, uint32_t timeout_ms = 500);
} // esp_modem::dce_commands } // esp_modem::dce_commands

View File

@@ -131,12 +131,12 @@ public:
* @param time_ms Time in ms to wait for the answer * @param time_ms Time in ms to wait for the answer
* @return OK, FAIL, TIMEOUT * @return OK, FAIL, TIMEOUT
*/ */
command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms) override; command_result command(std::string_view command, got_line_cb got_line, uint32_t time_ms) override;
/** /**
* @brief Sends the command (same as above) but with a specific separator * @brief Sends the command (same as above) but with a specific separator
*/ */
command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms, char separator) override; command_result command(std::string_view command, got_line_cb got_line, uint32_t time_ms, char separator) override;
/** /**
* @brief Allows this DTE to recover from a generic connection issue * @brief Allows this DTE to recover from a generic connection issue

View File

@@ -90,8 +90,8 @@ public:
* @param separator Character treated as a line separator, typically '\n' * @param separator Character treated as a line separator, typically '\n'
* @return OK, FAIL or TIMEOUT * @return OK, FAIL or TIMEOUT
*/ */
virtual command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms, const char separator) = 0; virtual command_result command(std::string_view command, got_line_cb got_line, uint32_t time_ms, const char separator) = 0;
virtual command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms) = 0; virtual command_result command(std::string_view command, got_line_cb got_line, uint32_t time_ms) = 0;
virtual int write(uint8_t *data, size_t len) = 0; virtual int write(uint8_t *data, size_t len) = 0;
virtual void on_read(got_line_cb on_data) = 0; virtual void on_read(got_line_cb on_data) = 0;

View File

@@ -5,7 +5,8 @@
*/ */
#include <charconv> #include <charconv>
#include <list> #include <span>
#include "esp_log.h" #include "esp_log.h"
#include "cxx_include/esp_modem_dte.hpp" #include "cxx_include/esp_modem_dte.hpp"
#include "cxx_include/esp_modem_dce_module.hpp" #include "cxx_include/esp_modem_dce_module.hpp"
@@ -18,12 +19,12 @@ namespace esp_modem::dce_commands {
static const char *TAG = "command_lib"; static const char *TAG = "command_lib";
command_result generic_command(CommandableIf *t, const std::string &command, command_result generic_command(CommandableIf *t, std::string_view command,
const std::list<std::string_view> &pass_phrase, std::span<const std::string_view> pass_phrase,
const std::list<std::string_view> &fail_phrase, std::span<const std::string_view> fail_phrase,
uint32_t timeout_ms) uint32_t timeout_ms)
{ {
ESP_LOGD(TAG, "%s command %s\n", __func__, command.c_str()); ESP_LOGD(TAG, "%s command %.*s\n", __func__, command.size(), command.data());
return t->command(command, [&](uint8_t *data, size_t len) { return t->command(command, [&](uint8_t *data, size_t len) {
std::string_view response((char *)data, len); std::string_view response((char *)data, len);
if (data == nullptr || len == 0 || response.empty()) { if (data == nullptr || len == 0 || response.empty()) {
@@ -43,13 +44,13 @@ command_result generic_command(CommandableIf *t, const std::string &command,
} }
command_result generic_command(CommandableIf *t, const std::string &command, command_result generic_command(CommandableIf *t, std::string_view command,
const std::string &pass_phrase, std::string_view pass_phrase,
const std::string &fail_phrase, uint32_t timeout_ms) std::string_view fail_phrase, uint32_t timeout_ms)
{ {
ESP_LOGV(TAG, "%s", __func__ ); ESP_LOGV(TAG, "%s", __func__ );
const auto pass = std::list<std::string_view>({pass_phrase}); const std::string_view pass[] {pass_phrase};
const auto fail = std::list<std::string_view>({fail_phrase}); const std::string_view fail[] {fail_phrase};
return generic_command(t, command, pass, fail, timeout_ms); return generic_command(t, command, pass, fail, timeout_ms);
} }
@@ -81,7 +82,7 @@ bool set(std::span<char> &dest, std::string_view &src)
} // str_copy } // str_copy
template <typename T> command_result generic_get_string(CommandableIf *t, const std::string &command, T &output, uint32_t timeout_ms) template <typename T> command_result generic_get_string(CommandableIf *t, std::string_view command, T &output, uint32_t timeout_ms)
{ {
ESP_LOGV(TAG, "%s", __func__); ESP_LOGV(TAG, "%s", __func__);
return t->command(command, [&](uint8_t *data, size_t len) { return t->command(command, [&](uint8_t *data, size_t len) {
@@ -110,7 +111,7 @@ template <typename T> command_result generic_get_string(CommandableIf *t, const
}, timeout_ms); }, timeout_ms);
} }
command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout_ms) command_result generic_command_common(CommandableIf *t, std::string_view command, uint32_t timeout_ms)
{ {
ESP_LOGV(TAG, "%s", __func__); ESP_LOGV(TAG, "%s", __func__);
return generic_command(t, command, "OK", "ERROR", timeout_ms); return generic_command(t, command, "OK", "ERROR", timeout_ms);
@@ -315,8 +316,8 @@ command_result resume_data_mode(CommandableIf *t)
command_result set_command_mode(CommandableIf *t) command_result set_command_mode(CommandableIf *t)
{ {
ESP_LOGV(TAG, "%s", __func__ ); ESP_LOGV(TAG, "%s", __func__ );
const auto pass = std::list<std::string_view>({"NO CARRIER", "OK"}); const std::string_view pass[] {"NO CARRIER", "OK"};
const auto fail = std::list<std::string_view>({"ERROR"}); const std::string_view fail[] {"ERROR"};
return generic_command(t, "+++", pass, fail, 5000); return generic_command(t, "+++", pass, fail, 5000);
} }

View File

@@ -147,11 +147,11 @@ void DTE::set_command_callbacks()
} }
command_result DTE::command(const std::string &command, got_line_cb got_line, uint32_t time_ms, const char separator) command_result DTE::command(std::string_view command, got_line_cb got_line, uint32_t time_ms, const char separator)
{ {
Scoped<Lock> l1(internal_lock); Scoped<Lock> l1(internal_lock);
command_cb.set(got_line, separator); command_cb.set(got_line, separator);
primary_term->write((uint8_t *)command.c_str(), command.length()); primary_term->write((uint8_t *)command.data(), command.length());
command_cb.wait_for_line(time_ms); command_cb.wait_for_line(time_ms);
command_cb.set(nullptr); command_cb.set(nullptr);
buffer.consumed = 0; buffer.consumed = 0;
@@ -161,7 +161,7 @@ command_result DTE::command(const std::string &command, got_line_cb got_line, ui
return command_cb.result; return command_cb.result;
} }
command_result DTE::command(const std::string &cmd, got_line_cb got_line, uint32_t time_ms) command_result DTE::command(std::string_view cmd, got_line_cb got_line, uint32_t time_ms)
{ {
return command(cmd, got_line, time_ms, '\n'); return command(cmd, got_line, time_ms, '\n');
} }