I'm developing a program, which receives commands via UART. My idea was to create a FreeRTOS Task, which runs during the complete program lifecycle and is responsible only for receiving uart messages, interprets them and sends a command into a queue.
I tested this with the built-in Serial functions, before writing my own UART functions.
/*========== Static Function Implementations ================================*/
static void uartControllerTaskLoop(void *pvParameters)
{
Serial.begin(115200);
Serial.println("Start Task");
for (;;)
{
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > interval)
{
Serial.println("Start Task loop");
previousMillis = currentMillis;
}
}
}
/*========== Extern Function Implementations ================================*/
extern void uartControllerCreateTask()
{
xTaskCreate(uartControllerTaskLoop, "uartControllerTask", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
}
When running this code I get the following error:
Guru Meditation Error: Core 1 panic'ed (InstrFetchProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x800d0eee PS : 0x00050a33 A0 : 0x800d0eee A1 : 0x3ffb2780
A2 : 0x3ffb27c0 A3 : 0x3ffb9818 A4 : 0x00000158 A5 : 0x00000000
A6 : 0x3ffb89dc A7 : 0x400d0ef4 A8 : 0x00000000 A9 : 0x800d1209
A10 : 0x3ffb2800 A11 : 0x00000000 A12 : 0x00000000 A13 : 0x3ffb9818
A14 : 0x00000001 A15 : 0x00000000 SAR : 0x00000000 EXCCAUSE: 0x00000014
EXCVADDR: 0x800d0eec LBEG : 0x3ffb9408 LEND : 0x00000400 LCOUNT : 0x3ffc155c
When I start the Serial communication with Serial.begin()
from outside the Task the program works fine. For me this is a little bit ugly, because I wanted to have all UART dependend stuff within the Task.
What are here the best practices? Leave the setup of the UART outside the Task or find a way to set up the UART within the task?
Thanks!
I switched from the Arduino framwork to the espidf framework.
Using then the uart driver from espressif let's me install the uart driver within a task.
#include "driver/uart.h"
#include "esp_log.h"
static const char *TAG = "example";
static void uartController(void *pvParameters)
{
int64_t previousMillis = 0UL;
int64_t interval = 1000000UL;
// configure the UART peripheral
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,
};
uart_param_config(UART_NUM_0, &uart_config);
uart_set_pin(UART_NUM_0, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
uart_driver_install(UART_NUM_0, 256, 0, 0, NULL, 0);
for (;;)
{
int64_t currentMillis = esp_timer_get_time();
// print messages to the serial monitor
if (currentMillis - previousMillis > interval)
{
char my_char_array[20];
snprintf(my_char_array, sizeof(my_char_array), "%lld", currentMillis);
ESP_LOGI(TAG, "%s", my_char_array);
ESP_LOGI(TAG, "This is an informational message.");
ESP_LOGW(TAG, "This is a warning message.");
ESP_LOGE(TAG, "This is an error message.");
previousMillis = currentMillis;
}
vTaskDelay(1);
}
}
void app_main()
{
xTaskCreate(uartController, "uartController", 4096, NULL, 1, NULL);
}