Issue in UART ESP32 with interrupt

Ashvajit.P
Posts: 34
Joined: Fri Feb 26, 2021 9:03 am

Issue in UART ESP32 with interrupt

Postby Ashvajit.P » Mon Jun 07, 2021 9:44 am

Hello,
I am trying to use UART in interrupt mode but when I am receiving anything, the controller keeps on resetting.
I am using Visual studio 2015 with GCC version 8.4.0, GDB version 8.1.0 and esp-idf v4.3.
At first uart_reg.h file was not inlcuded but when I added the header it flagged pop-up attached in image.
Initialization for UART

Code: Select all

void uart_Init(void)
{
	uart_config_t uart1_conf;
	uart1_conf.baud_rate = 115200;
	uart1_conf.data_bits = UART_DATA_8_BITS;
	uart1_conf.parity = UART_PARITY_DISABLE;
	uart1_conf.stop_bits = UART_STOP_BITS_1;
	uart1_conf.flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
	uart1_conf.source_clk = UART_SCLK_APB;

	ESP_ERROR_CHECK(uart_driver_install(UART_NUM_1, BUF_SIZE * 2, 0, 0, NULL, 0));
	ESP_ERROR_CHECK(uart_param_config(UART_NUM_1, &uart1_conf));
	ESP_ERROR_CHECK(uart_set_pin(UART_NUM_1, GPIO_NUM_21, GPIO_NUM_22, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
	esp_log_level_set(RX_TASK_TAG, ESP_LOG_INFO);
	ESP_ERROR_CHECK(uart_isr_free(UART_NUM_1));

	
	ESP_ERROR_CHECK(uart_isr_register(UART_NUM_1, uart_intr_handle, NULL, ESP_INTR_FLAG_IRAM, &handle_console)); // register new UART subroutine
	ESP_ERROR_CHECK(uart_enable_rx_intr(UART_NUM_1)); // enable RX interrupt
}
The UART transmit function is same as in uart async task example in esp-idf.

UART RX ISR handle code :

Code: Select all

 void uart_intr_handle(void *arg)
{
	 data = (uint8_t*) malloc(BUF_SIZE + 1);
	
	int rxBytes = uart_read_bytes(UART_NUM_1, data, BUF_SIZE, 1000 / portTICK_RATE_MS);
	if (rxBytes > 0) {
		data[rxBytes] = 0;
		ESP_LOGI(RX_TASK_TAG, "Read %d bytes: '%s'", rxBytes, data);
		ESP_LOG_BUFFER_HEXDUMP(RX_TASK_TAG, data, rxBytes, ESP_LOG_INFO);
	}
		free(data);
	// after reading bytes from buffer clear UART interrupt status
	uart_clear_intr_status(UART_NUM_1, UART_RXFIFO_FULL_INT_CLR | UART_RXFIFO_TOUT_INT_CLR);

}
Attachments
Capture.PNG
Capture.PNG (25.77 KiB) Viewed 4923 times

ESP_alisitsyn
Posts: 211
Joined: Fri Feb 01, 2019 4:02 pm
Contact:

Re: Issue in UART ESP32 with interrupt

Postby ESP_alisitsyn » Mon Jun 07, 2021 3:02 pm

Hello Ashvajit.P,

Unfortunately your interrupt handling code will not work because:
1. When you setup interrupt you allocate the IRAM-Safe Interrupt Handler but do not add the `IRAM_ATTR` attribute to the handler function.
Refer: https://docs.espressif.com/projects/esp ... t-handlers
2. There are some constraints of using IRAM-Safe Interrupts. It is not possible to use the `uart_read_bytes(), malloc(), free()` and ESP_LOGI() macro inside the interrupt handler because it can call only the RTOS functions with prefix `XXXFromISR()` and functions that are located in IRAM and can correctly access the data in DRAM segment, RTC memory only.
3. In case of IRAM-safe interrupt you should use the HAL functions to read/write data from UART FIFO or directly read/write data to peripheral registers.
4. It is possible to implement non IRAM-Safe Interrupt and place ISR handler into flash memory but it might be interrupt latency when flash access functions are used (disable CPU cache).

I modified your code to use the custom ISR handler and buffer received data using ring buffer.
The code is published here:
https://github.com/alisitsyn/modbus_sup ... al_example
The code might be with some mistakes but it works. The static variables are placed into DRAM by default and it uses the HAL macro which exist starting from (ESP-IDF v4.1). If you need to implement the same on version v4.0 or less it requires to implement similar code with direct access to registers.

Hope it helps. Let me know if you have any questions.

Ashvajit.P
Posts: 34
Joined: Fri Feb 26, 2021 9:03 am

Re: Issue in UART ESP32 with interrupt

Postby Ashvajit.P » Tue Nov 01, 2022 11:19 am

Hi,
In the above shared code if, I want to receive data that with length not fixed.
I want to generate interrupt at first byte I receive and wait for a timeout, if consecutive bytes are not received within that time then my buffer will return data at that time( to receive data till line is idle).then fill that data into buffer.
In the given code it It will wait till FIFO is filled up to 15 bytes as given by RXFIFO_FULL_THRD OR will wait till Timeout given by TEST_RX_TIMEOUT_MS.
What are the changes that I need to make if I want to generate an interrupt in following cases :
  • When receive line is idle after receiving some bytes
  • When buffer is full with 1024 bytes

Who is online

Users browsing this forum: MicroController and 94 guests