我有一个 ESP32-S3,与加速度计 ADXL355 和 LoRa 模块 RYLR998 一起使用。我正在使用 UART 事件来处理从 LoRa 模块接收到的内容。
按照这个示例https://github.com/espressif/esp-idf/blob/v5.2.1/examples/peripherals/uart/uart_events/main/uart_events_example_main.c,我获取了代码并适应了我的项目。
这是一段 main.c 代码
顶部:
...
QueueHandle_t uart_queue;
...
在app_main内部,调用'init_uart'函数:
...
init_uart(uart_queue);
ESP_LOGI(TAG, "Waiting 50 ms");
vTaskDelay(pdMS_TO_TICKS(50));
xTaskCreate(uart_task, "uart_task", TASK_MEMORY * 2, NULL, 12, NULL);
ESP_LOGI(TAG, "Task 'uart_task' !!!CREATED!!!");
ESP_LOGW(TAG, "*********************************************************");
ESP_LOGW(TAG, "After 'uart_task' created");
ESP_LOGW(TAG, "Free heap memmory (bytes): <%lu>", xPortGetFreeHeapSize());
ESP_LOGW(TAG, "*********************************************************");
...
main.c 中的‘uart_task’
void uart_task(void *pvParameters) {
uart_event_t event;
// data received in uart port which is what we receive from LoRa
uint8_t *incoming_uart_data = (uint8_t *)malloc(BUF_SIZE);
ESP_LOGW(TAG, "!!!DEBUGGING!!! ENTERING 'uart_task'");
while (1) {
// waiting for UART event
if (xQueueReceive(uart_queue, (void *)&event, (TickType_t)portMAX_DELAY)) {
ESP_LOGW(TAG, "!!!DEBUGGING!!! ENTERING 'xQueueReceive'");
bzero(incoming_uart_data, BUF_SIZE);
// Print out remaining task stack memory (words)
ESP_LOGW(TAG, "uart_task high water mark (words): %d",
uxTaskGetStackHighWaterMark(NULL));
switch (event.type) {
case UART_DATA:
uart_read_bytes(UART_NUM, incoming_uart_data, event.size,
pdMS_TO_TICKS(100));
ESP_ERROR_CHECK(uart_flush(UART_NUM));
ESP_LOGI(TAG, "Data received from LoRa module: %s", incoming_uart_data);
///// if the module answers +OK and we are sending data /////
// so we wait the ack message
if ((strncmp((const char *)incoming_uart_data, "+OK", 3) == 0) &&
(strncmp((const char *)is_sending_data, "Y", 1) == 0)) {
// we successfully sent the message
// and waiting for the ack
is_data_sent_ok = "+OK";
is_sending_data = "N";
rcv_ack = "N";
///// start timer /////
xTimerStart(resendTimer, 0);
///// start timer /////
}
///// if the module answers +OK and we are sending data /////
///// if the module is receiving data, we proccess it /////
// +RCV=22,length,data,RSSI,SNR
// extract the components of the received message
if (strncmp((const char *)incoming_uart_data, "+RCV=", 5) == 0) {
char *token = strtok((char *)incoming_uart_data, "=");
// loop through the string to extract all other tokens
uint8_t count_token = 0;
while (token != NULL) {
token = strtok(NULL, ",");
count_token++;
switch (count_token) {
case 1:
Lora_data.Address = token;
break;
case 2:
Lora_data.DataLength = token;
break;
case 3:
Lora_data.Data = token;
break;
case 4:
Lora_data.SignalStrength = token;
break;
case 5:
Lora_data.SignalNoise = token;
// Send a notification to check_ack_task(), bringing it out of the
// Blocked state
vTaskDelay(pdMS_TO_TICKS(DELAY / 50));
xTaskNotifyGive(check_ack_task_handle);
break;
default:
break;
}
}
}
///// if the module is receiving data, we proccess it /////
break;
default:
ESP_LOGI(TAG, "UART event type: %d", event.type);
break;
}
}
}
free(incoming_uart_data);
incoming_uart_data = NULL;
vTaskDelete(NULL);
}
'init_uart'函数位于rylr998.c中:
void init_uart(QueueHandle_t uart_queue) {
uart_config_t uart_config = {
.baud_rate = RYLR998_UART_BAUD_RATE,
.data_bits = RYLR998_UART_DATA_BITS,
.parity = RYLR998_UART_PARITY,
.stop_bits = RYLR998_UART_STOP_BITS,
.flow_ctrl = RYLR998_UART_FLOW_CTRL,
.source_clk = RYLR998_UART_SOURCE_CLK,
};
// Install UART driver
// uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int
// tx_buffer_size, int queue_size, QueueHandle_t* uart_queue, int
// intr_alloc_flags);
ESP_ERROR_CHECK(
uart_driver_install(UART_NUM, BUF_SIZE, BUF_SIZE, 20, &uart_queue, 0));
// Configure UART parameters
// uart_param_config(uart_port_t uart_num, const uart_config_t
// *uart_config);
ESP_ERROR_CHECK(uart_param_config(UART_NUM, &uart_config));
// Set UART pins
// uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num,
// int rts_io_num, int cts_io_num);
// When calling 'uart_set_pin', instead of GPIO number, `UART_PIN_NO_CHANGE`
// can be provided to keep the currently allocated pin.
ESP_ERROR_CHECK(uart_set_pin(UART_NUM, RYLR998_UART_TX_GPIO_NUM,
RYLR998_UART_RX_GPIO_NUM, UART_PIN_NO_CHANGE,
UART_PIN_NO_CHANGE));
ESP_LOGI(TAG, "UART Interface Configuration !!!COMPLETED!!!");
}
运行程序时,这是 ESP-IDF Monitor 的一些输出
`2024-04-03 10:12:08 I (312) !!!SENSING NODE TX!!!: Init LED !!!COMPLETED!!!
2024-04-03 10:12:08 I (322) !!!SENSING NODE TX!!!: Waiting 50 ms
2024-04-03 10:12:08 I (382) !!!SENSING NODE TX!!!: Initializing file system...
2024-04-03 10:12:08 I (742) !!!SENSING NODE TX!!!: Partition size: total: 3848081, used: 2646544
2024-04-03 10:12:09 I (742) !!!SENSING NODE TX!!!: Waiting 50 ms
2024-04-03 10:12:09 I (792) uart: queue free spaces: 20
2024-04-03 10:12:09 I (792) RYLR998 TX: UART Interface Configuration !!!COMPLETED!!!
2024-04-03 10:12:09 I (792) !!!SENSING NODE TX!!!: Waiting 500 ms
2024-04-03 10:12:09 I (1292) !!!SENSING NODE TX!!!: Task 'uart_task' !!!CREATED!!!
2024-04-03 10:12:09 W (1292) !!!SENSING NODE TX!!!: !!!DEBUGGING!!! ENTERING 'uart_task'
2024-04-03 10:12:09
2024-04-03 10:12:09 assert failed: xQueueReceive queue.c:1389 (( pxQueue ))`
“if (xQueueReceive(uart_queue, (void *)&event, (TickType_t)portMAX_DELAY))”线上存在一些问题,也许这是我将队列句柄传递给“init_uart(QueueHandle_t uart_queue)”的方式功能,但我在那里迷路了:(
有什么帮助吗???
我希望解决我的问题...
使用
xQueueCreate
创建的 uart_queue 在哪里?
如果您使用
uart_driver_install
进行队列创建,请确保您的任务大小大于您的 BUF_SIZE
验证它(UART)在您创建它之前是否未被创建。 例如:
if(!uart_is_driver_installed(UART_NUM)) {
// init here
}
下面是使用队列的简单代码
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#define QUEUE_LENGTH 5
#define ITEM_SIZE sizeof(int)
QueueHandle_t xQueue; // Declare a queue handle
void sender_task(void *pvParameters) {
int item = 0;
while(1) {
// Send an item to the queue
xQueueSend(xQueue, &item, portMAX_DELAY);
printf("Sent: %d\n", item);
// Increment the item for the next iteration
item++;
// Delay for some time before sending the next item
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void receiver_task(void *pvParameters) {
int received_item;
while(1) {
// Receive an item from the queue
if(xQueueReceive(xQueue, &received_item, portMAX_DELAY) == pdTRUE) {
printf("Received: %d\n", received_item);
}
}
}
void app_main() {
// Create a queue
xQueue = xQueueCreate(QUEUE_LENGTH, ITEM_SIZE);
// Create sender and receiver tasks
xTaskCreate(sender_task, "sender_task", 2048, NULL, 1, NULL);
xTaskCreate(receiver_task, "receiver_task", 2048, NULL, 1, NULL);
}