Skip to content

Commit 661b3c9

Browse files
fix: param config via bluetooth
1 parent b338e4c commit 661b3c9

6 files changed

Lines changed: 140 additions & 76 deletions

File tree

src/context/GlobalData.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ enum class MessageType { LOG };
1919
#define MESSAGE_LOG_NAME_SIZE 32
2020
#define MESSAGE_LOG_MESSAGE_SIZE 2048
2121

22+
#define RECEIVED_UART_MESSAGE_SIZE 256
23+
24+
// Line received from BLE UART (copied off the GATT callback into this queue).
25+
struct ReceivedUartMessage {
26+
char text[RECEIVED_UART_MESSAGE_SIZE];
27+
};
28+
2229
// Message structure for queue
2330
struct Message {
2431
struct {
@@ -52,6 +59,9 @@ struct GlobalData {
5259
// FreeRTOS queue for inter-task communication
5360
QueueHandle_t communicationQueue;
5461

62+
// Raw lines from BLE RX; processed in CommunicationTask (not in NimBLE callback).
63+
QueueHandle_t receivedUartMessages;
64+
5565

5666
/* Communication should only write on the variables below when the robot is in
5767
* IDLE mode */

src/main.cpp

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,12 @@ void app_main() {
2828
return;
2929
}
3030

31-
// globalData.ledCommandQueue = xQueueCreate(10, sizeof(LedCommand));
32-
// if(globalData.ledCommandQueue == NULL) {
33-
// ESP_LOGE("Main", "Failed to create LED command queue");
34-
// return;
35-
// }
36-
37-
// Storage::write(globalData.randomNumber.load(std::memory_order_relaxed));
38-
// Storage::write(globalData.randomChar.load(std::memory_order_relaxed));
39-
// Storage::write(globalData.randomFloat.load(std::memory_order_relaxed));
40-
// Storage::write(globalData.randomBool.load(std::memory_order_relaxed));
41-
31+
globalData.receivedUartMessages =
32+
xQueueCreate(10, sizeof(ReceivedUartMessage));
33+
if(globalData.receivedUartMessages == NULL) {
34+
ESP_LOGE("Main", "Failed to create receivedUartMessages queue");
35+
return;
36+
}
4237

4338
// Task
4439
// 1 word = 4 bytes

src/storage/storage.hpp

Lines changed: 63 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
#define STORAGE_HPP
33

44
#include <atomic>
5+
#include <cerrno>
56
#include <cstdio>
67
#include <cstdlib>
8+
#include <cstring>
79
#include <dirent.h>
810
#include <iostream>
911
#include <mutex>
@@ -36,7 +38,8 @@ class Storage {
3638
};
3739

3840
esp_err_t mount_storage(std::string mount_path) {
39-
if(is_mounted()) {
41+
std::lock_guard<std::mutex> lock(fs_mutex);
42+
if(mount_status) {
4043
ESP_LOGE(logger_tag.c_str(),
4144
"FATFS already mounted at %s. To mount at %s, first unmount the "
4245
"previous path.",
@@ -54,16 +57,19 @@ class Storage {
5457
esp_err_to_name(mount_result));
5558
mount_status = false;
5659
return ESP_FAIL;
57-
} else {
58-
ESP_LOGI(logger_tag.c_str(), "FATFS mounted successfully at %s",
59-
mount_point.c_str());
60-
mount_status = true;
61-
return ESP_OK;
6260
}
61+
ESP_LOGI(logger_tag.c_str(), "FATFS mounted successfully at %s",
62+
mount_point.c_str());
63+
mount_status = true;
64+
return ESP_OK;
6365
}
6466

6567
esp_err_t list_files() {
66-
if(!is_mounted()) return ESP_FAIL;
68+
std::lock_guard<std::mutex> lock(fs_mutex);
69+
if(!mount_status) {
70+
ESP_LOGD(logger_tag.c_str(), "FATFS not mounted.");
71+
return ESP_FAIL;
72+
}
6773

6874
DIR *directory_handle;
6975
struct dirent *directory_entry;
@@ -83,14 +89,19 @@ class Storage {
8389

8490
esp_err_t save_data(std::string file_path, char *data_buffer,
8591
size_t data_size, const char *mode = "wb") {
86-
if(!is_mounted()) return ESP_FAIL;
92+
std::lock_guard<std::mutex> lock(fs_mutex);
93+
if(!mount_status) {
94+
ESP_LOGD(logger_tag.c_str(), "FATFS not mounted.");
95+
return ESP_FAIL;
96+
}
8797

8898
std::string full_path = mount_point + "/" + file_path;
8999
FILE *file_handle = fopen(full_path.c_str(), mode);
90100

91101
if(file_handle == NULL) {
92-
ESP_LOGE(logger_tag.c_str(), "Failed to open file %s for writing",
93-
file_path.c_str());
102+
ESP_LOGE(logger_tag.c_str(),
103+
"Failed to open file %s for writing: %s (%s)", file_path.c_str(),
104+
full_path.c_str(), strerror(errno));
94105
return ESP_FAIL;
95106
}
96107

@@ -105,14 +116,19 @@ class Storage {
105116

106117
esp_err_t load_data(std::string file_path, char *data_buffer,
107118
size_t data_size) {
108-
if(!is_mounted()) return ESP_FAIL;
119+
std::lock_guard<std::mutex> lock(fs_mutex);
120+
if(!mount_status) {
121+
ESP_LOGD(logger_tag.c_str(), "FATFS not mounted.");
122+
return ESP_FAIL;
123+
}
109124

110125
std::string full_path = mount_point + "/" + file_path;
111126
FILE *file_handle = fopen(full_path.c_str(), "r");
112127

113128
if(file_handle == NULL) {
114-
ESP_LOGE(logger_tag.c_str(), "Failed to open file %s for reading",
115-
file_path.c_str());
129+
ESP_LOGE(logger_tag.c_str(),
130+
"Failed to open file %s for reading: %s (%s)", file_path.c_str(),
131+
full_path.c_str(), strerror(errno));
116132
return ESP_FAIL;
117133
}
118134

@@ -128,14 +144,19 @@ class Storage {
128144

129145
esp_err_t load_data(std::string file_path, char **data_buffer,
130146
size_t *file_size) {
131-
if(!is_mounted()) return ESP_FAIL;
147+
std::lock_guard<std::mutex> lock(fs_mutex);
148+
if(!mount_status) {
149+
ESP_LOGD(logger_tag.c_str(), "FATFS not mounted.");
150+
return ESP_FAIL;
151+
}
132152

133153
std::string full_path = mount_point + "/" + file_path;
134154
FILE *file_handle = fopen(full_path.c_str(), "rb");
135155

136156
if(file_handle == NULL) {
137-
ESP_LOGE(logger_tag.c_str(), "Failed to open file %s for reading",
138-
file_path.c_str());
157+
ESP_LOGE(logger_tag.c_str(),
158+
"Failed to open file %s for reading: %s (%s)", file_path.c_str(),
159+
full_path.c_str(), strerror(errno));
139160
return ESP_FAIL;
140161
}
141162

@@ -158,7 +179,11 @@ class Storage {
158179
}
159180

160181
esp_err_t delete_data(std::string file_path) {
161-
if(!is_mounted()) return ESP_FAIL;
182+
std::lock_guard<std::mutex> lock(fs_mutex);
183+
if(!mount_status) {
184+
ESP_LOGD(logger_tag.c_str(), "FATFS not mounted.");
185+
return ESP_FAIL;
186+
}
162187

163188
std::string full_path = mount_point + "/" + file_path;
164189
if(remove(full_path.c_str()) != 0) {
@@ -187,15 +212,20 @@ class Storage {
187212
// Vector serialization helpers
188213
template <typename ElementType>
189214
esp_err_t write_vector(const std::vector<ElementType> &vector_data,
190-
std::string file_path) {
191-
if(!is_mounted()) return ESP_FAIL;
215+
std::string file_path) {
216+
std::lock_guard<std::mutex> lock(fs_mutex);
217+
if(!mount_status) {
218+
ESP_LOGD(logger_tag.c_str(), "FATFS not mounted.");
219+
return ESP_FAIL;
220+
}
192221

193222
std::string full_path = mount_point + "/" + file_path;
194223
FILE *file_handle = fopen(full_path.c_str(), "wb");
195224

196225
if(file_handle == NULL) {
197-
ESP_LOGE(logger_tag.c_str(), "Failed to open file %s for writing",
198-
file_path.c_str());
226+
ESP_LOGE(logger_tag.c_str(),
227+
"Failed to open file %s for writing: %s (%s)", file_path.c_str(),
228+
full_path.c_str(), strerror(errno));
199229
return ESP_FAIL;
200230
}
201231

@@ -214,8 +244,12 @@ class Storage {
214244

215245
template <typename ElementType>
216246
esp_err_t read_vector(std::vector<ElementType> &vector_data,
217-
std::string file_path) {
218-
if(!is_mounted()) return ESP_FAIL;
247+
std::string file_path) {
248+
std::lock_guard<std::mutex> lock(fs_mutex);
249+
if(!mount_status) {
250+
ESP_LOGD(logger_tag.c_str(), "FATFS not mounted.");
251+
return ESP_FAIL;
252+
}
219253

220254
std::string full_path = mount_point + "/" + file_path;
221255
FILE *file_handle = fopen(full_path.c_str(), "rb");
@@ -245,7 +279,10 @@ class Storage {
245279

246280
// Check if file exists
247281
bool file_exists(std::string file_path) {
248-
if(!is_mounted()) return false;
282+
std::lock_guard<std::mutex> lock(fs_mutex);
283+
if(!mount_status) {
284+
return false;
285+
}
249286

250287
std::string full_path = mount_point + "/" + file_path;
251288
FILE *file_handle = fopen(full_path.c_str(), "r");
@@ -265,25 +302,18 @@ class Storage {
265302
std::string mount_point;
266303
esp_vfs_fat_sdmmc_mount_config_t fat_mount_config;
267304
bool mount_status;
305+
mutable std::mutex fs_mutex;
268306

269307
Storage() {
270308
wear_leveling_handle = WL_INVALID_HANDLE;
271309
mount_point = "/data";
272310
logger_tag = "Storage";
273311

274312
fat_mount_config.format_if_mount_failed = true;
275-
fat_mount_config.max_files = 5;
313+
fat_mount_config.max_files = 16;
276314
fat_mount_config.allocation_unit_size = CONFIG_WL_SECTOR_SIZE;
277315
mount_status = false;
278316
}
279-
280-
bool is_mounted() {
281-
if(!mount_status) {
282-
ESP_LOGD(logger_tag.c_str(), "FATFS not mounted.");
283-
}
284-
285-
return mount_status;
286-
}
287317
};
288318

289319
// Static member definitions

src/tasks/CommunicationTask/CommunicationTask.hpp

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include <cstring>
77
#include <string>
88

9+
#include "esp_log.h"
10+
911
#include "nimble-nordic-uart/nimble-nordic-uart.h"
1012

1113
#include "cli/cli.hpp"
@@ -23,25 +25,27 @@ void uartStatusChangeCallback(enum nordic_uart_callback_type callback_type) {
2325
}
2426
}
2527

26-
// Callback para receber dados da UART BLE
28+
// NimBLE GATT callback: only enqueue — CLI runs in communicationTaskLoop.
2729
void uartReceiveCallback(struct ble_gatt_access_ctxt *ctxt) {
28-
// Get the actual data length from the mbuf
2930
uint16_t data_len = ctxt->om->om_len;
3031

31-
// Create a null-terminated buffer to safely handle the data
32-
char buffer[256];
33-
size_t copy_len =
34-
(data_len < sizeof(buffer) - 1) ? data_len : sizeof(buffer) - 1;
35-
memcpy(buffer, ctxt->om->om_data, copy_len);
36-
buffer[copy_len] = '\0';
37-
38-
ESP_LOGI("CommunicationTask", "BLE UART received data: %s (len: %d)", buffer,
39-
data_len);
32+
ReceivedUartMessage uartMsg{};
33+
size_t copy_len = (data_len < RECEIVED_UART_MESSAGE_SIZE - 1)
34+
? data_len
35+
: RECEIVED_UART_MESSAGE_SIZE - 1;
36+
memcpy(uartMsg.text, ctxt->om->om_data, copy_len);
37+
uartMsg.text[copy_len] = '\0';
38+
39+
if(xQueueSend(globalData.receivedUartMessages, &uartMsg, 0) != pdTRUE) {
40+
ESP_LOGW("CommunicationTask",
41+
"receivedUartMessages full, dropping (len=%u)",
42+
static_cast<unsigned>(data_len));
43+
}
44+
}
4045

41-
// Execute CLI command and check return value
46+
static void processReceivedUartLine(char *buffer) {
4247
int cliResult = cli(buffer);
4348

44-
// If CLI returned an error, log and push error message to queue
4549
if(cliResult != CLI_SUCCESS) {
4650
switch(cliResult) {
4751
case CLI_ERROR_EMPTY_COMMAND:
@@ -80,17 +84,37 @@ void processMessage(const Message &msg) {
8084
}
8185
}
8286

87+
static void drainOutgoingMessages() {
88+
Message receivedMessage;
89+
while(xQueueReceive(globalData.communicationQueue, &receivedMessage, 0) ==
90+
pdTRUE) {
91+
processMessage(receivedMessage);
92+
}
93+
}
94+
8395
void communicationTaskLoop(void *params) {
8496
(void)params;
8597
nordic_uart_start("TT_SEMREH", uartStatusChangeCallback);
8698
nordic_uart_yield(uartReceiveCallback);
8799

88-
Message receivedMessage;
100+
Message receivedMessage;
101+
ReceivedUartMessage uartMsg;
89102

90103
for(;;) {
104+
while(xQueueReceive(globalData.receivedUartMessages, &uartMsg, 0) ==
105+
pdTRUE) {
106+
ESP_LOGI("CommunicationTask", "BLE UART received data: %s", uartMsg.text);
107+
processReceivedUartLine(uartMsg.text);
108+
drainOutgoingMessages();
109+
}
110+
91111
if(xQueueReceive(globalData.communicationQueue, &receivedMessage,
92112
pdMS_TO_TICKS(100)) == pdTRUE) {
93113
processMessage(receivedMessage);
114+
while(xQueueReceive(globalData.communicationQueue, &receivedMessage, 0) ==
115+
pdTRUE) {
116+
processMessage(receivedMessage);
117+
}
94118
}
95119

96120
vTaskDelay(pdMS_TO_TICKS(10));

0 commit comments

Comments
 (0)