harden USB telemetry transport
This commit is contained in:
+39
-15
@@ -14,6 +14,8 @@
|
||||
#include "freertos/task.h"
|
||||
#include "l3g4200d.h"
|
||||
#include "trikke_protocol.h"
|
||||
#include "trikke_transport.h"
|
||||
#include "trikke_usb_transport.h"
|
||||
|
||||
// Seeed Studio XIAO ESP32-C3: D4/SDA = GPIO6, D5/SCL = GPIO7.
|
||||
#define TRIKKE_I2C_PORT I2C_NUM_0
|
||||
@@ -54,6 +56,8 @@ typedef struct {
|
||||
QueueHandle_t sample_queue;
|
||||
atomic_uint_least32_t dropped_sample_count;
|
||||
atomic_uint_least32_t loop_overrun_count;
|
||||
trikke_transport_t transport;
|
||||
trikke_usb_transport_t usb_transport;
|
||||
} trikke_context_t;
|
||||
|
||||
static trikke_context_t s_context;
|
||||
@@ -157,22 +161,26 @@ static void acquisition_task(void *argument)
|
||||
}
|
||||
}
|
||||
|
||||
static bool write_binary_packet(const uint8_t *packet, size_t packet_size)
|
||||
{
|
||||
const size_t written = fwrite(packet, 1, packet_size, stdout);
|
||||
const int flush_result = fflush(stdout);
|
||||
const bool complete = written == packet_size && flush_result == 0;
|
||||
if (!complete) {
|
||||
clearerr(stdout);
|
||||
}
|
||||
return complete;
|
||||
}
|
||||
|
||||
static void write_binary_packet_until_sent(
|
||||
trikke_context_t *context,
|
||||
trikke_transport_sender_t *sender,
|
||||
const uint8_t *packet,
|
||||
size_t packet_size)
|
||||
{
|
||||
while (!write_binary_packet(packet, packet_size)) {
|
||||
while (true) {
|
||||
const trikke_transport_status_t status =
|
||||
trikke_transport_sender_step(
|
||||
sender, &context->transport, packet, packet_size);
|
||||
if (status == TRIKKE_TRANSPORT_COMPLETE) {
|
||||
return;
|
||||
}
|
||||
if (status == TRIKKE_TRANSPORT_FATAL) {
|
||||
// Preserve the in-flight packet and stop consuming the queue. A
|
||||
// fatal backend invariant is not safely recoverable or retryable.
|
||||
while (true) {
|
||||
vTaskDelay(portMAX_DELAY);
|
||||
}
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(TRIKKE_TRANSPORT_RETRY_DELAY_MS));
|
||||
}
|
||||
}
|
||||
@@ -185,12 +193,14 @@ static void output_task(void *argument)
|
||||
uint8_t packet[TRIKKE_WIRE_MAX_PACKET_SIZE] = {0};
|
||||
uint32_t packet_sequence = 0;
|
||||
uint32_t sample_packet_count = 0;
|
||||
trikke_transport_sender_t sender;
|
||||
trikke_transport_sender_init(&sender);
|
||||
|
||||
size_t packet_size = trikke_encode_metadata_packet(
|
||||
packet, sizeof(packet), packet_sequence++, esp_timer_get_time(),
|
||||
atomic_load(&context->dropped_sample_count),
|
||||
atomic_load(&context->loop_overrun_count), &TRIKKE_METADATA);
|
||||
write_binary_packet_until_sent(packet, packet_size);
|
||||
write_binary_packet_until_sent(context, &sender, packet, packet_size);
|
||||
|
||||
while (true) {
|
||||
trikke_wire_sample_t samples[TRIKKE_WIRE_MAX_RECORDS] = {0};
|
||||
@@ -227,14 +237,15 @@ static void output_task(void *argument)
|
||||
packet, sizeof(packet), packet_sequence++, esp_timer_get_time(),
|
||||
atomic_load(&context->dropped_sample_count),
|
||||
atomic_load(&context->loop_overrun_count), &TRIKKE_METADATA);
|
||||
write_binary_packet_until_sent(packet, packet_size);
|
||||
write_binary_packet_until_sent(
|
||||
context, &sender, packet, packet_size);
|
||||
}
|
||||
|
||||
packet_size = trikke_encode_sample_packet(
|
||||
packet, sizeof(packet), packet_sequence++,
|
||||
atomic_load(&context->dropped_sample_count),
|
||||
atomic_load(&context->loop_overrun_count), samples, sample_count);
|
||||
write_binary_packet_until_sent(packet, packet_size);
|
||||
write_binary_packet_until_sent(context, &sender, packet, packet_size);
|
||||
++sample_packet_count;
|
||||
}
|
||||
}
|
||||
@@ -324,6 +335,17 @@ void app_main(void)
|
||||
// binary frames whenever a payload byte equals LF.
|
||||
usb_serial_jtag_vfs_set_tx_line_endings(ESP_LINE_ENDINGS_LF);
|
||||
|
||||
err = trikke_usb_transport_init(
|
||||
&s_context.usb_transport, &s_context.transport);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "USB transport initialization failed: %s",
|
||||
esp_err_to_name(err));
|
||||
l3g4200d_deinit(&s_context.gyroscope);
|
||||
adxl345_deinit(&s_context.accelerometer);
|
||||
i2c_del_master_bus(bus);
|
||||
return;
|
||||
}
|
||||
|
||||
s_context.sample_queue =
|
||||
xQueueCreate(TRIKKE_SAMPLE_QUEUE_DEPTH, sizeof(trikke_wire_sample_t));
|
||||
if (s_context.sample_queue == NULL) {
|
||||
@@ -331,6 +353,7 @@ void app_main(void)
|
||||
l3g4200d_deinit(&s_context.gyroscope);
|
||||
adxl345_deinit(&s_context.accelerometer);
|
||||
i2c_del_master_bus(bus);
|
||||
trikke_usb_transport_deinit(&s_context.usb_transport);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -351,6 +374,7 @@ void app_main(void)
|
||||
l3g4200d_deinit(&s_context.gyroscope);
|
||||
adxl345_deinit(&s_context.accelerometer);
|
||||
i2c_del_master_bus(bus);
|
||||
trikke_usb_transport_deinit(&s_context.usb_transport);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user