mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 17:19:09 -04:00
Merge branch 'bugfix/uart_async_rxtxtasks_example_stack_overflow' into 'master'
fix(uart): enlarged task stack size for uart_async_rxtxtasks example Closes IDFGH-14607, IDF-12230, and IDFGH-12126 See merge request espressif/esp-idf!36903
This commit is contained in:
commit
fd2df5e2fc
@ -23,9 +23,9 @@ Functional Overview
|
|||||||
|
|
||||||
The overview describes how to establish communication between an {IDF_TARGET_NAME} and other UART devices using the functions and data types of the UART driver. A typical programming workflow is broken down into the sections provided below:
|
The overview describes how to establish communication between an {IDF_TARGET_NAME} and other UART devices using the functions and data types of the UART driver. A typical programming workflow is broken down into the sections provided below:
|
||||||
|
|
||||||
1. :ref:`uart-api-setting-communication-parameters` - Setting baud rate, data bits, stop bits, etc.
|
1. :ref:`uart-api-driver-installation` - Allocating {IDF_TARGET_NAME}'s resources for the UART driver
|
||||||
2. :ref:`uart-api-setting-communication-pins` - Assigning pins for connection to a device
|
2. :ref:`uart-api-setting-communication-parameters` - Setting baud rate, data bits, stop bits, etc.
|
||||||
3. :ref:`uart-api-driver-installation` - Allocating {IDF_TARGET_NAME}'s resources for the UART driver
|
3. :ref:`uart-api-setting-communication-pins` - Assigning pins for connection to a device
|
||||||
4. :ref:`uart-api-running-uart-communication` - Sending/receiving data
|
4. :ref:`uart-api-running-uart-communication` - Sending/receiving data
|
||||||
5. :ref:`uart-api-using-interrupts` - Triggering interrupts on specific communication events
|
5. :ref:`uart-api-using-interrupts` - Triggering interrupts on specific communication events
|
||||||
6. :ref:`uart-api-deleting-driver` - Freeing allocated resources if a UART communication is no longer required
|
6. :ref:`uart-api-deleting-driver` - Freeing allocated resources if a UART communication is no longer required
|
||||||
@ -39,13 +39,39 @@ Steps 1 to 3 comprise the configuration stage. Step 4 is where the UART starts o
|
|||||||
The UART driver's functions identify each of the UART controllers using :cpp:type:`uart_port_t`. This identification is needed for all the following function calls.
|
The UART driver's functions identify each of the UART controllers using :cpp:type:`uart_port_t`. This identification is needed for all the following function calls.
|
||||||
|
|
||||||
|
|
||||||
|
.. _uart-api-driver-installation:
|
||||||
|
|
||||||
|
Install Drivers
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
First of all, install the driver by calling :cpp:func:`uart_driver_install` and specify the following parameters:
|
||||||
|
|
||||||
|
- UART port number
|
||||||
|
- Size of RX ring buffer
|
||||||
|
- Size of TX ring buffer
|
||||||
|
- Event queue size
|
||||||
|
- Pointer to store the event queue handle
|
||||||
|
- Flags to allocate an interrupt
|
||||||
|
|
||||||
|
.. _driver-code-snippet:
|
||||||
|
|
||||||
|
The function allocates the required internal resources for the UART driver.
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
// Setup UART buffered IO with event queue
|
||||||
|
const int uart_buffer_size = (1024 * 2);
|
||||||
|
QueueHandle_t uart_queue;
|
||||||
|
// Install UART driver using an event queue here
|
||||||
|
ESP_ERROR_CHECK(uart_driver_install({IDF_TARGET_UART_EXAMPLE_PORT}, uart_buffer_size, uart_buffer_size, 10, &uart_queue, 0));
|
||||||
|
|
||||||
|
|
||||||
.. _uart-api-setting-communication-parameters:
|
.. _uart-api-setting-communication-parameters:
|
||||||
|
|
||||||
Set Communication Parameters
|
Set Communication Parameters
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
UART communication parameters can be configured all in a single step or individually in multiple steps.
|
As the next step, UART communication parameters can be configured all in a single step or individually in multiple steps.
|
||||||
|
|
||||||
|
|
||||||
Single Step
|
Single Step
|
||||||
"""""""""""
|
"""""""""""
|
||||||
@ -113,35 +139,6 @@ The same macro :c:macro:`UART_PIN_NO_CHANGE` should be specified for pins that w
|
|||||||
// Set UART pins(TX: IO4, RX: IO5, RTS: IO18, CTS: IO19)
|
// Set UART pins(TX: IO4, RX: IO5, RTS: IO18, CTS: IO19)
|
||||||
ESP_ERROR_CHECK(uart_set_pin({IDF_TARGET_UART_EXAMPLE_PORT}, 4, 5, 18, 19));
|
ESP_ERROR_CHECK(uart_set_pin({IDF_TARGET_UART_EXAMPLE_PORT}, 4, 5, 18, 19));
|
||||||
|
|
||||||
.. _uart-api-driver-installation:
|
|
||||||
|
|
||||||
Install Drivers
|
|
||||||
^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Once the communication pins are set, install the driver by calling :cpp:func:`uart_driver_install` and specify the following parameters:
|
|
||||||
|
|
||||||
- UART port number
|
|
||||||
- Size of TX ring buffer
|
|
||||||
- Size of RX ring buffer
|
|
||||||
- Pointer to store the event queue handle
|
|
||||||
- Event queue size
|
|
||||||
- Flags to allocate an interrupt
|
|
||||||
|
|
||||||
.. _driver-code-snippet:
|
|
||||||
|
|
||||||
The function allocates the required internal resources for the UART driver.
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
// Setup UART buffered IO with event queue
|
|
||||||
const int uart_buffer_size = (1024 * 2);
|
|
||||||
QueueHandle_t uart_queue;
|
|
||||||
// Install UART driver using an event queue here
|
|
||||||
ESP_ERROR_CHECK(uart_driver_install({IDF_TARGET_UART_EXAMPLE_PORT}, uart_buffer_size, \
|
|
||||||
uart_buffer_size, 10, &uart_queue, 0));
|
|
||||||
|
|
||||||
Once this step is complete, you can connect the external UART device and check the communication.
|
|
||||||
|
|
||||||
|
|
||||||
.. _uart-api-running-uart-communication:
|
.. _uart-api-running-uart-communication:
|
||||||
|
|
||||||
|
@ -23,9 +23,9 @@
|
|||||||
|
|
||||||
下文介绍了如何使用 UART 驱动程序的函数和数据类型在 {IDF_TARGET_NAME} 和其他 UART 设备之间建立通信。基本编程流程分为以下几个步骤:
|
下文介绍了如何使用 UART 驱动程序的函数和数据类型在 {IDF_TARGET_NAME} 和其他 UART 设备之间建立通信。基本编程流程分为以下几个步骤:
|
||||||
|
|
||||||
1. :ref:`uart-api-setting-communication-parameters` - 设置波特率、数据位、停止位等
|
1. :ref:`uart-api-driver-installation` - 为 UART 驱动程序分配 {IDF_TARGET_NAME} 资源
|
||||||
2. :ref:`uart-api-setting-communication-pins` - 分配连接设备的管脚
|
2. :ref:`uart-api-setting-communication-parameters` - 设置波特率、数据位、停止位等
|
||||||
3. :ref:`uart-api-driver-installation` - 为 UART 驱动程序分配 {IDF_TARGET_NAME} 资源
|
3. :ref:`uart-api-setting-communication-pins` - 分配连接设备的管脚
|
||||||
4. :ref:`uart-api-running-uart-communication` - 发送/接收数据
|
4. :ref:`uart-api-running-uart-communication` - 发送/接收数据
|
||||||
5. :ref:`uart-api-using-interrupts` - 触发特定通信事件的中断
|
5. :ref:`uart-api-using-interrupts` - 触发特定通信事件的中断
|
||||||
6. :ref:`uart-api-deleting-driver` - 如无需 UART 通信,则释放已分配的资源
|
6. :ref:`uart-api-deleting-driver` - 如无需 UART 通信,则释放已分配的资源
|
||||||
@ -39,13 +39,39 @@
|
|||||||
UART 驱动程序函数通过 :cpp:type:`uart_port_t` 识别不同的 UART 控制器。调用以下所有函数均需此标识。
|
UART 驱动程序函数通过 :cpp:type:`uart_port_t` 识别不同的 UART 控制器。调用以下所有函数均需此标识。
|
||||||
|
|
||||||
|
|
||||||
|
.. _uart-api-driver-installation:
|
||||||
|
|
||||||
|
安装驱动程序
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
首先,请调用 :cpp:func:`uart_driver_install` 安装驱动程序并指定以下参数:
|
||||||
|
|
||||||
|
- UART 控制器编号
|
||||||
|
- Rx 环形缓冲区的大小
|
||||||
|
- Tx 环形缓冲区的大小
|
||||||
|
- 事件队列大小
|
||||||
|
- 指向事件队列句柄的指针
|
||||||
|
- 分配中断的标志
|
||||||
|
|
||||||
|
.. _driver-code-snippet:
|
||||||
|
|
||||||
|
该函数将为 UART 驱动程序分配所需的内部资源。
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
// Setup UART buffered IO with event queue
|
||||||
|
const int uart_buffer_size = (1024 * 2);
|
||||||
|
QueueHandle_t uart_queue;
|
||||||
|
// Install UART driver using an event queue here
|
||||||
|
ESP_ERROR_CHECK(uart_driver_install({IDF_TARGET_UART_EXAMPLE_PORT}, uart_buffer_size, uart_buffer_size, 10, &uart_queue, 0));
|
||||||
|
|
||||||
|
|
||||||
.. _uart-api-setting-communication-parameters:
|
.. _uart-api-setting-communication-parameters:
|
||||||
|
|
||||||
设置通信参数
|
设置通信参数
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
UART 通信参数可以在一个步骤中完成全部配置,也可以在多个步骤中单独配置。
|
其次,UART 通信参数可以在一个步骤中完成全部配置,也可以在多个步骤中单独配置。
|
||||||
|
|
||||||
|
|
||||||
一次性配置所有参数
|
一次性配置所有参数
|
||||||
""""""""""""""""""""""""""""""""
|
""""""""""""""""""""""""""""""""
|
||||||
@ -113,35 +139,6 @@ UART 通信参数可以在一个步骤中完成全部配置,也可以在多个
|
|||||||
// Set UART pins(TX: IO4, RX: IO5, RTS: IO18, CTS: IO19)
|
// Set UART pins(TX: IO4, RX: IO5, RTS: IO18, CTS: IO19)
|
||||||
ESP_ERROR_CHECK(uart_set_pin({IDF_TARGET_UART_EXAMPLE_PORT}, 4, 5, 18, 19));
|
ESP_ERROR_CHECK(uart_set_pin({IDF_TARGET_UART_EXAMPLE_PORT}, 4, 5, 18, 19));
|
||||||
|
|
||||||
.. _uart-api-driver-installation:
|
|
||||||
|
|
||||||
安装驱动程序
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
通信管脚设置完成后,请调用 :cpp:func:`uart_driver_install` 安装驱动程序并指定以下参数:
|
|
||||||
|
|
||||||
- UART 控制器编号
|
|
||||||
- Tx 环形缓冲区的大小
|
|
||||||
- Rx 环形缓冲区的大小
|
|
||||||
- 指向事件队列句柄的指针
|
|
||||||
- 事件队列大小
|
|
||||||
- 分配中断的标志
|
|
||||||
|
|
||||||
.. _driver-code-snippet:
|
|
||||||
|
|
||||||
该函数将为 UART 驱动程序分配所需的内部资源。
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
// Setup UART buffered IO with event queue
|
|
||||||
const int uart_buffer_size = (1024 * 2);
|
|
||||||
QueueHandle_t uart_queue;
|
|
||||||
// Install UART driver using an event queue here
|
|
||||||
ESP_ERROR_CHECK(uart_driver_install({IDF_TARGET_UART_EXAMPLE_PORT}, uart_buffer_size, \
|
|
||||||
uart_buffer_size, 10, &uart_queue, 0));
|
|
||||||
|
|
||||||
此步骤完成后,可连接外部 UART 设备检查通信。
|
|
||||||
|
|
||||||
|
|
||||||
.. _uart-api-running-uart-communication:
|
.. _uart-api-running-uart-communication:
|
||||||
|
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
menu "Example Configuration"
|
||||||
|
|
||||||
|
orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps"
|
||||||
|
|
||||||
|
config EXAMPLE_UART_BAUD_RATE
|
||||||
|
int "UART communication speed"
|
||||||
|
range 1200 115200
|
||||||
|
default 115200
|
||||||
|
help
|
||||||
|
UART communication speed for the example.
|
||||||
|
|
||||||
|
config EXAMPLE_UART_RXD
|
||||||
|
int "UART RXD pin number"
|
||||||
|
range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
|
||||||
|
default 5
|
||||||
|
help
|
||||||
|
GPIO number for UART RX pin. See UART documentation for more information
|
||||||
|
about available pin numbers for UART.
|
||||||
|
|
||||||
|
config EXAMPLE_UART_TXD
|
||||||
|
int "UART TXD pin number"
|
||||||
|
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
|
||||||
|
default 4
|
||||||
|
help
|
||||||
|
GPIO number for UART TX pin. See UART documentation for more information
|
||||||
|
about available pin numbers for UART.
|
||||||
|
|
||||||
|
config EXAMPLE_TASK_STACK_SIZE
|
||||||
|
int "Example task stack size"
|
||||||
|
range 1024 16384
|
||||||
|
default 3072
|
||||||
|
help
|
||||||
|
Defines stack size for UART TX and RX tasks. Insufficient stack size can cause crash.
|
||||||
|
|
||||||
|
endmenu
|
@ -16,13 +16,13 @@
|
|||||||
|
|
||||||
static const int RX_BUF_SIZE = 1024;
|
static const int RX_BUF_SIZE = 1024;
|
||||||
|
|
||||||
#define TXD_PIN (GPIO_NUM_4)
|
#define TXD_PIN (CONFIG_EXAMPLE_UART_TXD)
|
||||||
#define RXD_PIN (GPIO_NUM_5)
|
#define RXD_PIN (CONFIG_EXAMPLE_UART_RXD)
|
||||||
|
|
||||||
void init(void)
|
void init(void)
|
||||||
{
|
{
|
||||||
const uart_config_t uart_config = {
|
const uart_config_t uart_config = {
|
||||||
.baud_rate = 115200,
|
.baud_rate = CONFIG_EXAMPLE_UART_BAUD_RATE,
|
||||||
.data_bits = UART_DATA_8_BITS,
|
.data_bits = UART_DATA_8_BITS,
|
||||||
.parity = UART_PARITY_DISABLE,
|
.parity = UART_PARITY_DISABLE,
|
||||||
.stop_bits = UART_STOP_BITS_1,
|
.stop_bits = UART_STOP_BITS_1,
|
||||||
@ -72,6 +72,6 @@ static void rx_task(void *arg)
|
|||||||
void app_main(void)
|
void app_main(void)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
xTaskCreate(rx_task, "uart_rx_task", 1024 * 2, NULL, configMAX_PRIORITIES - 1, NULL);
|
xTaskCreate(rx_task, "uart_rx_task", CONFIG_EXAMPLE_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL);
|
||||||
xTaskCreate(tx_task, "uart_tx_task", 1024 * 2, NULL, configMAX_PRIORITIES - 2, NULL);
|
xTaskCreate(tx_task, "uart_tx_task", CONFIG_EXAMPLE_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, NULL);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.supported_targets
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_uart_async_rxtxtasks_example(dut: Dut) -> None:
|
||||||
|
dut.expect_exact('TX_TASK: Wrote 11 bytes')
|
14
examples/peripherals/uart/uart_events/pytest_events.py
Normal file
14
examples/peripherals/uart/uart_events/pytest_events.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.supported_targets
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_uart_events_example(dut: Dut) -> None:
|
||||||
|
dut.expect_exact('Returned from app_main()')
|
||||||
|
dut.write('a')
|
||||||
|
dut.expect_exact('uart_events: [UART DATA]: 2') # dut.write will add an extra '\n'
|
||||||
|
dut.write('HA')
|
||||||
|
dut.expect_exact('uart_events: [UART DATA]: 3') # dut.write will add an extra '\n'
|
12
examples/peripherals/uart/uart_select/pytest_uart_select.py
Normal file
12
examples/peripherals/uart/uart_select/pytest_uart_select.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.supported_targets
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_uart_select_example(dut: Dut) -> None:
|
||||||
|
dut.expect_exact('uart_select_example: Timeout has been reached and nothing has been received')
|
||||||
|
dut.write('a')
|
||||||
|
dut.expect_exact('uart_select_example: Received: a')
|
Loading…
x
Reference in New Issue
Block a user