簡體   English   中英

xQueue ESP32 無法發送兩個命令

[英]xQueue ESP32 can't send two command

我正在尋求幫助,因為我被這個問題困擾了很長時間。 我在家里有一個 ESP32 wrover 套件,我已通過 uart 將其連接到 Zigbee 網關模塊。 我想通過 uart 向模塊發送一些命令,因為我將命令放在 xQueue 中,然后我進入一個線程發送到 uart。 在另一個線程中,我通過 uart 得到了答案。 第一條消息一切順利,然后在閱讀第二條消息時我崩潰了。 我認為這是因為我的 tx_msg 不再存在於 memory 中,但我無法解決問題。 而且我認為還有一個同步問題。 我受到這個例子的啟發,但它不起作用https://www.freertos.org/a00118.html

這是我的代碼,如果您知道我必須修改什么,或者您可以解釋我如何解決它,謝謝!

代碼編輯:

#include <stdio.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/queue.h>
#include <esp_system.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
//#include <driver/gpio.h>
#include <driver/uart.h>
#include <pthread.h>

typedef unsigned char byte;

// Setup UART buffered IO with event queue
const int uart_buffer_size = 1024;
// Queue used to send and receive complete struct message structures. 
QueueHandle_t uart_queue = NULL;
const int uart_num = UART_NUM_2;

struct message{
    char cmd[128];
    int len;
}tx_msg;

pthread_t zigbee_thread_id;
pthread_t zigbee_send_thread_id;
pthread_t zigbee_receive_thread_id;

/**
 * @brief Configuraiton of UART and set pin that uart use.
 * 
 * @return [int] 0 if is successed
 */
int uart_setup()
{
    uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
    };
    // Configure UART parameters
    ESP_ERROR_CHECK(uart_param_config(uart_num, &uart_config));
    ESP_ERROR_CHECK(uart_set_pin(UART_NUM_2, 18, 19, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
    // Install UART driver using an event queue here
    ESP_ERROR_CHECK(uart_driver_install(UART_NUM_2, uart_buffer_size, \
                                        uart_buffer_size, 10, &uart_queue, 0));
    return 0;
}

void translate_hexa_to_string(char* data,int len){

    for (int i=0; i<len;i++)
    {
        if (data[i]==2)
            {
                i++;
                data[i]^=0x10;
                printf("%02x ",data[i]);
                    
            }else if (data[i]==3)
            {
                printf("%02x \n",data[i]);
            }else{
                printf("%02x ",data[i]);
            }
            
        }
        printf("\n");
}

/**
 * @brief [Thread]Send commande to Zigbee module by UART
 * 
 */
void * send_cmd(void * arg){
    struct message rx_msg;
    int err;
    while(1){
        if (xQueueReceive(uart_queue, &rx_msg, portMAX_DELAY) == pdPASS){
            printf("len : %d\n",rx_msg.len);
            for(int i=0;i<rx_msg.len;i++){
                printf("%02x \n",rx_msg.cmd[i]);
            }
            printf("\n");
            err = uart_write_bytes(uart_num, (const char *)rx_msg.cmd, rx_msg.len); // Write data to UART.
            if(err != rx_msg.len){
                printf("Err, not all bytes send : %d/%d\n",err,rx_msg.len);
            }
            vTaskDelay(1000 / portTICK_RATE_MS);
        }
    }
    return NULL;
}

/**
 * @brief [Thread]Read response from UART
 * 
 */
void * read_cmd(void * arg){
    char data[512];
    int length = 0;
    while(1){
        if(uxQueueMessagesWaiting(uart_queue) >= 1){
            ESP_ERROR_CHECK(uart_get_buffered_data_len(uart_num, (size_t*)&length));
            length = uart_read_bytes(uart_num, (uint8_t*)data, length, 100);
            if (length > 0){
                printf("[R] len : %d\n",length);
                translate_hexa_to_string(data,length);
                printf("%c",data[6]);
                if(strcmp(data[6],"00")!=0){
                    printf("[R] Command failed\n");
                }
            }
            ESP_ERROR_CHECK(uart_flush(uart_num));
        }
        vTaskDelay(1000 / portTICK_RATE_MS);
    }
    return NULL;
}

/**
 * @brief Configuration of Zigbee module (channel,type) and start network
 * 
 */
void zigbee_config(){
    struct message *ptx_msg;
    //Set Channel
    sprintf(tx_msg.cmd,"%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",0x01, 0x02, 0x10, 0x21, 0x02, 0x10, 0x02, 0x14, 0x2D, 0x02, 0x10, 0x02, 0x10, 0x02, 0x18, 0x02, 0x10, 0x03);
    tx_msg.len =strlen(tx_msg.cmd);
    ptx_msg = &tx_msg;
    xQueueSend(uart_queue, (void*)ptx_msg, portMAX_DELAY);
    printf("[S] Set channel to 11\n");
    vTaskDelay(100 / portTICK_RATE_MS);/*
    //Set Type
    sprintf(tx_msg.cmd,"%c%c%c%c%c%c%c%c%c%c%c%c\n",0x01, 0x02, 0x10, 0x23, 0x02, 0x10, 0x02, 0x11, 0x22, 0x02, 0x10, 0x03);
    tx_msg.len =strlen(tx_msg.cmd);
    xQueueSend(uart_queue, (void*)&tx_msg, portMAX_DELAY);
    printf("[S] Set as Coordinator\n");
    vTaskDelay(100 / portTICK_RATE_MS);
    //Start Network
    sprintf(tx_msg.cmd,"%c%c%c%c%c%c%c%c%c%c\n",0x01, 0x02, 0x10, 0x24, 0x02, 0x10, 0x02, 0x10, 0x24, 0x03);
    tx_msg.len =strlen(tx_msg.cmd);
    xQueueSend(uart_queue, (void*)&tx_msg, portMAX_DELAY);
    printf("[S] Start Network\n");*/
}

void * ZIGBEE_thread(void * arg){

    /* Create the queue used to send complete struct message structures. */
    uart_queue = xQueueCreate(20, sizeof(struct message));
    if (uart_setup() == -1){
        printf("Err during uart setup\n");
    }
    zigbee_config();
    while(1){
        vTaskDelay(100000 / portTICK_RATE_MS);
    }
    return 0;
    
}

int app_main() {
    
    err += pthread_create(&zigbee_thread_id, NULL, &ZIGBEE_thread, NULL);
    err += pthread_create(&zigbee_send_thread_id, NULL, &send_cmd, NULL);
    err += pthread_create(&zigbee_receive_thread_id, NULL, &read_cmd, NULL);
    // Check if thread is created sucessfuly
    if (err > 0)
    {
        printf("Thread creation failed : %s \n",strerror(err));
        return err;
    }
    pthread_join(zigbee_thread_id, NULL);
    pthread_join(zigbee_send_thread_id, NULL);
    pthread_join(zigbee_receive_thread_id, NULL);
    return 0;
    
}




結果:[S] 將頻道設置為 11 hh 01 02 10 21 02 10 02 14 2d 02 10 02 10 02 18 02 10 03 0a [S] 設置為協調員 [S] 啟動網絡 hh Guru Meditation Error: Core 0 panic'ed (禁止加載)。 異常未處理。

核心 0 寄存器轉儲:PC:0x400014fd PS:0x00060130 A0:0x800d34d1 A1:0x3ffba280
A2:0x00000000 A3:0xfffffffc A4:0x000000ff A5:0x0000ff00
A6:0x00ff0000 A7:0xff000000 A8:0x00000000 A9:0x3ffba230
A10: 0x0000000a A11: 0x3ffae920 A12: 0x00000013 A13: 0x00000013 A14: 0x00000000 A15: 0x00000013 SAR: 0x00000000 EXCCAUSE: 0x0000001c EXCVADDR: 0x00000000 LBEG: 0x400014fd LEND: 0x4000150d LCOUNT: 0xffffffff

Backtrace:0x400014fa:0x3ffba280 0x400d34ce:0x3ffba290 0x400d1bad:0x3ffba2c0 0x40085339:0x3ffba2e0 0x400d34ce: send_cmd at C:\Users\tgasser\Documents\ESP32\template-app\fibonacci-app\build/../main/main.c:97

0x400d1bad: pthread_task_func 在 C:/Users/tgasser/esp/esp-idf/components/pthread/pthread.c:209(鑒別器 15)

0x40085339: vPortTaskWrapper 在 C:/Users/tgasser/esp/esp-idf/components/freertos/xtensa/port.c:143

您誤解了隊列的接口。 xQueueReceive希望您提供實際的 memory 來存儲其有效負載。 在 function send_cmd ,您傳遞給xQueueReceive一個指向另一個未初始化指針的指針:

    struct message *rx_msg;
...
        if (xQueueReceive( uart_queue, &rx_msg, portMAX_DELAY) == pdPASS && uart_queue != NULL){
...

相反,您需要創建一個預期類型的變量並將指針傳遞給該變量。

    struct message rx_msg;
...
        if (xQueueReceive( uart_queue, &rx_msg, portMAX_DELAY) == pdPASS && uart_queue != NULL){
...

發布到隊列也是不正確的。 你給它一個指向tx_msg的指針,但它只需要指向tx_msg的指針。

錯誤的:

xQueueSend(uart_queue, (void*)&ptx_msg, portMAX_DELAY);

正確的:

xQueueSend(uart_queue, (void*)ptx_msg, portMAX_DELAY);

作為 FreeRTOS 的優秀資源,我推薦他們 web 站點上的書/教程: 掌握 FreeRTOS 實時 Kernel - 動手教程指南

旁注:請將控制台 output 作為文本發布,而不是屏幕截圖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM