ludocode / mpack

MPack - A C encoder/decoder for the MessagePack serialization format / msgpack.org[C]
MIT License
521 stars 82 forks source link

ESP32-C3 rebooting when executing functions from the MPack library #104

Open marco711 opened 1 year ago

marco711 commented 1 year ago

Hello, I'm testing the MPack library in an ESP32-C3 microcontroller. Below the code I'm using for testing (I added the MPack functions in the app_main function):

#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>

#include "esp_wifi.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "esp_netif.h"
#include "protocol_examples_common.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"

#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"

#include "esp_log.h"
#include "mqtt_client.h"

#include "mpack.h"

void print_data(char [], size_t);

static const char *TAG = "MQTT_EXAMPLE";

static void log_error_if_nonzero(const char *message, int error_code)
{
    if (error_code != 0) {
        ESP_LOGE(TAG, "Last error %s: 0x%x", message, error_code);
    }
}

/*
 * @brief Event handler registered to receive MQTT events
 *
 *  This function is called by the MQTT client event loop.
 *
 * @param handler_args user data registered to the event.
 * @param base Event base for the handler(always MQTT Base in this example).
 * @param event_id The id for the received event.
 * @param event_data The data for the event, esp_mqtt_event_handle_t.
 */
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
    ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id);
    esp_mqtt_event_handle_t event = event_data;
    esp_mqtt_client_handle_t client = event->client;
    int msg_id;
    switch ((esp_mqtt_event_id_t)event_id) {
    case MQTT_EVENT_CONNECTED:
        ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
        msg_id = esp_mqtt_client_publish(client, "/topic/qos1", "data_3", 0, 1, 0);
        ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);

        msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);
        ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

        msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
        ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

        msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
        ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
        break;
    case MQTT_EVENT_DISCONNECTED:
        ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
        break;

    case MQTT_EVENT_SUBSCRIBED:
        ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
        msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
        ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
        break;
    case MQTT_EVENT_UNSUBSCRIBED:
        ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
        break;
    case MQTT_EVENT_PUBLISHED:
        ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
        break;
    case MQTT_EVENT_DATA:
        ESP_LOGI(TAG, "MQTT_EVENT_DATA");
        printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
        printf("DATA=%.*s\r\n", event->data_len, event->data);
        break;
    case MQTT_EVENT_ERROR:
        ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
        if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
            log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
            log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
            log_error_if_nonzero("captured as transport's socket errno",  event->error_handle->esp_transport_sock_errno);
            ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));

        }
        break;
    default:
        ESP_LOGI(TAG, "Other event id:%d", event->event_id);
        break;
    }
}

static void mqtt_app_start(void)
{
    esp_mqtt_client_config_t mqtt_cfg = {
        .uri = CONFIG_BROKER_URL,
    };
#if CONFIG_BROKER_URL_FROM_STDIN
    char line[128];

    if (strcmp(mqtt_cfg.uri, "FROM_STDIN") == 0) {
        int count = 0;
        printf("Please enter url of mqtt broker\n");
        while (count < 128) {
            int c = fgetc(stdin);
            if (c == '\n') {
                line[count] = '\0';
                break;
            } else if (c > 0 && c < 127) {
                line[count] = c;
                ++count;
            }
            vTaskDelay(10 / portTICK_PERIOD_MS);
        }
        mqtt_cfg.uri = line;
        printf("Broker url: %s\n", line);
    } else {
        ESP_LOGE(TAG, "Configuration mismatch: wrong broker url");
        abort();
    }
#endif /* CONFIG_BROKER_URL_FROM_STDIN */

    esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
    /* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
    esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
    esp_mqtt_client_start(client);
}

void app_main(void)
{
    ESP_ERROR_CHECK(nvs_flash_init());
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
     * Read "Establishing Wi-Fi or Ethernet Connection" section in
     * examples/protocols/README.md for more information about this function.
     */
    //ESP_ERROR_CHECK(example_connect());

    mqtt_app_start();

    // encode to memory buffer
    char *data;
    char data_r[256] = {0};
    size_t size;
    int len = 0;
    mpack_writer_t writer;
    mpack_writer_init_growable(&writer, &data, &size);

    // write the example on the msgpack homepage
    mpack_build_map(&writer);
    mpack_write_cstr(&writer, "compact");
    mpack_write_bool(&writer, true);
    mpack_write_cstr(&writer, "schemaaaaa");
    mpack_write_uint(&writer, 7);
    mpack_complete_map(&writer);

        len = writer.position;

    printf("Print 1: %u %u\n", len, (*writer.end));
    printf("Print 2: %u %u\n", data[1], data[2]);

    // finish writing
    if (mpack_writer_destroy(&writer) != mpack_ok) {
          fprintf(stderr, "An error occurred encoding the data!\n");
          return;
    }
    else
    {

    }

    // use the data

    free(data);
}

void print_data(char data_in[], size_t length)
{
    for (size_t i = 0; i < length; i++)
    {
        printf("%X ", data_in[i]);
    }
}

When I try to print the data in line printf("Print 2: %u %u\n", data[1], data[2]); I the microcontroller reboots:

Print 1: 0 249
Guru Meditation Error: Core  0 panic'ed (Load access fault). Exception was unhandled.

Stack dump detected
Core  0 register dump:
MEPC    : 0x42007944  RA      : 0x42007942  SP      : 0x3fc91b90  GP      : 0x3fc8be00  
0x42007944: app_main at /home/msurca/esp/IoTliftv1_0_3/tcp/build/../main/app_main.c:196 (discriminator 2)

0x42007942: app_main at /home/msurca/esp/IoTliftv1_0_3/tcp/build/../main/app_main.c:196 (discriminator 2)

TP      : 0x3fc7513c  T0      : 0x4005890e  T1      : 0x20000000  T2      : 0x3fc68a28  
S0/FP   : 0x00000000  S1      : 0x00000000  A0      : 0x0000000f  A1      : 0x3fc917c8  
A2      : 0x00000000  A3      : 0x00000001  A4      : 0x3fc8e000  A5      : 0x00000000  
A6      : 0x42005cf4  A7      : 0x0000000a  S2      : 0x00000000  S3      : 0x00000000  
0x42005cf4: console_write at /home/msurca/esp/esp-idf/components/vfs/vfs_console.c:71

S4      : 0x00000000  S5      : 0x00000000  S6      : 0x00000000  S7      : 0x00000000  
S8      : 0x00000000  S9      : 0x00000000  S10     : 0x00000000  S11     : 0x00000000  
T3      : 0x00000000  T4      : 0x3ff00000  T5      : 0x00000000  T6      : 0x3fd34413  
MSTATUS : 0x00001881  MTVEC   : 0x40380001  MCAUSE  : 0x00000005  MTVAL   : 0x00000002  
0x40380001: _vector_table at ??:?

MHARTID : 0x00000000  

Backtrace:

0x42007944 in app_main () at ../main/app_main.c:196
196     printf("Print 2: %u %u\n", data[1], data[2]);
#0  0x42007944 in app_main () at ../main/app_main.c:196
#1  0x4205e806 in main_task (args=<optimized out>) at /home/msurca/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/port_common.c:124
#2  0x40387226 in prvTaskExitError () at /home/msurca/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c:132
Backtrace stopped: frame did not save the PC
ELF file SHA256: a7c731be59522570

Rebooting...

Also, if I change the content of "schema" by "schema12345" the end of the string is also 249. So, I am not sure if this is the function I should use to get the length of the data in the buffer. If I use the mpack_writer_buffer_used function the length I always get is 0.

Finally, if I comment the line mpack_write_cstr(&writer, "compact");the program crashes and the microcontroller restarts. If the line mpack_build_map(&writer); is followed by the function mpack_write_cstr the program can be executed without crashing.

Which could be the reason of these problems?