Skip to content

MQTT/Protobuf Middleware API#390

Draft
bjackson312006 wants to merge 11 commits intomqtt-ethernetfrom
mqtt-ethernet.protobuf-driver
Draft

MQTT/Protobuf Middleware API#390
bjackson312006 wants to merge 11 commits intomqtt-ethernetfrom
mqtt-ethernet.protobuf-driver

Conversation

@bjackson312006
Copy link
Copy Markdown
Collaborator

@bjackson312006 bjackson312006 commented Apr 1, 2026

This PR implements a lightweight wrapper layer for message encoding that sits on top of the lower-level Ethernet/MQTT drivers. It's meant to provide a simple API that automatically handles encoding messages in the ServerData schema. This should ideally make it easier to set up Ethernet/MQTT/Protobuf in different repos.

The first function (technically a macro) in this API is nx_protobuf_mqtt_message_create(topic, unit, ...), which returns a message of type ethernet_mqtt_message_t. This function allows you to pass in a topic string literal, a unit string literal, and however many float datapoints you want (provided it doesn't exceed the maximum allowed). The lengths of the topic and unit strings, as well as the number of datapoints you pass into ..., are calculated automatically for you at compile time, so there's no risk of weird caller errors (i.e, forgetting to include a null terminator in the string size or something). The max/min length settings for the parameters (configured via PB_MAX_TOPIC_LENGTH, PB_MAX_UNIT_LENGTH, PB_MIN_DATAPOINTS, PB_MAX_DATAPOINTS) are also validated at compile-time, so if you violate any of the settings there, you will get a nice _Static_assert compiler error telling you exactly what rule you violated. TLDR the compiler will ensure you call this function correctly unless there's something I've forgotten about.

The second function in this API is nx_protobuf_mqtt_message_send(ethernet_mqtt_message_t* message), which dispatches a ethernet_mqtt_message_t object. If MQTT isn't connected, this function will try to reconnect indefinitely until MQTT has successfully been reconnected, either by this function directly or by another function/thread.

The intended application-layer workflow for this API looks kinda like this:
First, create a queue:

void vEthernet1Manager(ULONG thread_input) {

    ethernet_mqtt_message_t message = { 0 };

    while(1) {

        /* Send outgoing messages, recieve incoming messages */
        while(queue_receive(&eth_manager, &message, TX_WAIT_FOREVER) == U_SUCCESS) {
            int status = nx_protobuf_mqtt_message_send(&message);
            if(status != U_SUCCESS) {
                PRINTLN_ERROR("Failed to send outgoing mqtt ethernet message (Status: %d).", status);
            }
        }

        /* No sleep. Thread timing is controlled completely by the queue timeout. */
    }
}

Then, other threads can create messages and queue them, like this:

void vTest(ULONG thread_input) {

    while(1) {

        ethernet_mqtt_message_t message = nx_protobuf_mqtt_message_create("VCU_Ethernet/IMU/Acceleration", "unit", acceleration.x, acceleration.y, acceleration.z);
        queue_send(&eth_manager, &message, TX_NO_WAIT);

        tx_thread_sleep(test_thread.sleep);
    }
}

Some things of note:

  • I tested this on Cerberus-2.0, and everything worked except for PTP stuff. During my testing, ethernet_get_time() seemed to hang (right before the nx_ptp_client_time_get() call). The hanging did not occur for messages getting created in vTest, but did for messages getting created in vPeripherals. Kind of weird. I ended up commenting out the call to ethernet_get_time() within nx_protobuf_mqtt_message_create(), and just have time_us set to 10 (random number I chose).

@bjackson312006 bjackson312006 self-assigned this Apr 1, 2026
@bjackson312006 bjackson312006 changed the title experimenting with adding nanopb to embedded-base MQTT/Protobuf Middleware API Apr 2, 2026
@bjackson312006 bjackson312006 requested review from jr1221 and removed request for jr1221 April 2, 2026 02:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant