espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.34k stars 7.2k forks source link

UART not detecting missing stop bit (IDFGH-9386) #10760

Open nicksenva opened 1 year ago

nicksenva commented 1 year ago

Answers checklist.

IDF version.

v5.0-3-g2d0d8742b1

Operating System used.

Windows

How did you build your project?

Command line with idf.py

If you are using Windows, please specify command line type.

CMD

Development Kit.

Custom Board

Power Supply used.

External 3.3V

What is the expected behavior?

If UART is configured for two stop bits but only one is received from the peer device, the framing error is detected and the data is discarded.

What is the actual behavior?

The missing stop bit is not detected and the received data is considered valid.

Steps to reproduce.

Run the Modbus master sample code connected to a slave device configured for 1 stop bit.

#include "string.h"
#include "esp_log.h"
#include "mbcontroller.h"
#include "sdkconfig.h"
#include "esp_modbus_common.h"

static const char *TAG = "MASTER_TEST";

#define MB_UART_PORT_NUM 1
#define MB_UART_TXD 32
#define MB_UART_RXD 35
#define MB_UART_RTS 33
#define MB_BAUD 115200
#define MB_STOP_BITS UART_STOP_BITS_2

esp_err_t modbus_get(uint16_t start_reg, uint16_t nRegs, uint16_t reg_type, void* dstBuf) {
    esp_err_t err;
    double slave_addr = 31;
    err = mbc_master_send_request(
        &(mb_param_request_t) {slave_addr, reg_type, start_reg, nRegs}, dstBuf);

    return err;
}

esp_err_t modbus_init() {
    // Initialize and start Modbus controller
    mb_communication_info_t comm = {
            .port = MB_UART_PORT_NUM,
            .mode = MB_MODE_RTU,
            .baudrate = MB_BAUD,
            .parity = UART_PARITY_DISABLE
    };
    void* master_handler = NULL;
    esp_err_t err;

    err = mbc_master_init(MB_PORT_SERIAL_MASTER, &master_handler);
    MB_RETURN_ON_FALSE((master_handler != NULL), ESP_ERR_INVALID_STATE, TAG,
                                "mb controller initialization fail.");
    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
                            "mb controller initialization fail, returns(0x%"PRIu32").",
                            (uint32_t)err);
    err = mbc_master_setup((void*)&comm);
    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
                            "mb controller setup fail, returns(0x%"PRIu32").",
                            (uint32_t)err);
    err = uart_set_pin(MB_UART_PORT_NUM, MB_UART_TXD, MB_UART_RXD,
                         MB_UART_RTS, UART_PIN_NO_CHANGE);
    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
            "mb serial set pin failure, uart_set_pin() returned (0x%"PRIu32").", (uint32_t)err);

    err = mbc_master_start();
    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
                            "mb controller start fail, returns(0x%"PRIu32").",
                            (uint32_t)err);

    // Set driver mode to Half Duplex
    err = uart_set_mode(MB_UART_PORT_NUM, UART_MODE_RS485_HALF_DUPLEX);
    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
            "mb serial set mode failure, uart_set_mode() returned (0x%"PRIu32").", (uint32_t)err);

    ESP_LOGI(TAG, "Modbus master stack initialized...");

    // Set UART stop bits
   err = uart_set_stop_bits(MB_UART_PORT_NUM, MB_STOP_BITS);
   MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
           "mb serial set stop bits failure, uart_set_stop_bits() returned (0x%"PRIu32").", (uint32_t)err);
        return err;

    return err;
}

void app_main(void)
{
    ESP_ERROR_CHECK(modbus_init());
    uint16_t val;
    esp_err_t err;

    uint16_t reg_type = 3;
    uint16_t sta
[sdkconfig.txt](https://github.com/espressif/esp-modbus/files/10572421/sdkconfig.txt)
rt_addr = 1;
    uint16_t nRegs = 1;
    while(1) {
        err = modbus_get(start_addr, nRegs, reg_type, &val);
        if(err == ESP_OK)
            ESP_LOGI(TAG, "Val read: %d", val);
        else
            ESP_LOGE(TAG, "Modbus read failed");

        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }

}

Debug Logs.

I (168) cpu_start: Pro cpu up.
I (168) cpu_start: Starting app cpu, entry point is 0x400813cc
0x400813cc: call_start_cpu1 at C:/Users/user/workspace/git/esp-idf/components/esp_system/port/cpu_start.c:142

I (0) cpu_start: App cpu up.
D (176) clk: RTC_SLOW_CLK calibration value: 3468160
I (187) cpu_start: Pro cpu start user code
I (187) cpu_start: cpu freq: 240000000 Hz
I (187) cpu_start: Application information:
I (192) cpu_start: Project name:     modbus_master
I (197) cpu_start: App version:      3c63b5d-dirty
I (203) cpu_start: Compile time:     Feb 13 2023 14:13:08
I (209) cpu_start: ELF file SHA256:  37cf59fc6795768d...
I (215) cpu_start: ESP-IDF:          v5.0-3-g2d0d8742b1
D (221) memory_layout: Checking 7 reserved memory ranges:
D (226) memory_layout: Reserved memory range 0x3ffae000 - 0x3ffae6e0
D (233) memory_layout: Reserved memory range 0x3ffb0000 - 0x3ffb3bc0
D (239) memory_layout: Reserved memory range 0x3ffe0000 - 0x3ffe0440
D (246) memory_layout: Reserved memory range 0x3ffe3f20 - 0x3ffe4350
D (252) memory_layout: Reserved memory range 0x40070000 - 0x40078000
D (258) memory_layout: Reserved memory range 0x40078000 - 0x40080000
0x40080000: _WindowOverflow4 at C:/Users/user/workspace/git/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/xtensa_vectors.S:1742

D (265) memory_layout: Reserved memory range 0x40080000 - 0x4008ef38
0x40080000: _WindowOverflow4 at C:/Users/user/workspace/git/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/xtensa_vectors.S:1742

D (271) memory_layout: Building list of available memory regions:
D (277) memory_layout: Available memory region 0x3ffae6e0 - 0x3ffb0000
D (284) memory_layout: Available memory region 0x3ffb3bc0 - 0x3ffb8000
D (291) memory_layout: Available memory region 0x3ffb8000 - 0x3ffc0000
D (297) memory_layout: Available memory region 0x3ffc0000 - 0x3ffc2000
D (304) memory_layout: Available memory region 0x3ffc2000 - 0x3ffc4000
D (310) memory_layout: Available memory region 0x3ffc4000 - 0x3ffc6000
D (317) memory_layout: Available memory region 0x3ffc6000 - 0x3ffc8000
D (324) memory_layout: Available memory region 0x3ffc8000 - 0x3ffca000
D (330) memory_layout: Available memory region 0x3ffca000 - 0x3ffcc000
D (337) memory_layout: Available memory region 0x3ffcc000 - 0x3ffce000
D (343) memory_layout: Available memory region 0x3ffce000 - 0x3ffd0000
D (350) memory_layout: Available memory region 0x3ffd0000 - 0x3ffd2000
D (357) memory_layout: Available memory region 0x3ffd2000 - 0x3ffd4000
D (363) memory_layout: Available memory region 0x3ffd4000 - 0x3ffd6000
D (370) memory_layout: Available memory region 0x3ffd6000 - 0x3ffd8000
D (376) memory_layout: Available memory region 0x3ffd8000 - 0x3ffda000
D (383) memory_layout: Available memory region 0x3ffda000 - 0x3ffdc000
D (390) memory_layout: Available memory region 0x3ffdc000 - 0x3ffde000
D (396) memory_layout: Available memory region 0x3ffde000 - 0x3ffe0000
D (403) memory_layout: Available memory region 0x3ffe0440 - 0x3ffe3f20
D (409) memory_layout: Available memory region 0x3ffe4350 - 0x3ffe8000
D (416) memory_layout: Available memory region 0x3ffe8000 - 0x3fff0000
D (423) memory_layout: Available memory region 0x3fff0000 - 0x3fff8000
D (429) memory_layout: Available memory region 0x3fff8000 - 0x3fffc000
D (436) memory_layout: Available memory region 0x3fffc000 - 0x40000000
D (442) memory_layout: Available memory region 0x4008ef38 - 0x40090000
D (449) memory_layout: Available memory region 0x40090000 - 0x40092000
D (456) memory_layout: Available memory region 0x40092000 - 0x40094000
D (462) memory_layout: Available memory region 0x40094000 - 0x40096000
D (469) memory_layout: Available memory region 0x40096000 - 0x40098000
D (475) memory_layout: Available memory region 0x40098000 - 0x4009a000
D (482) memory_layout: Available memory region 0x4009a000 - 0x4009c000
D (489) memory_layout: Available memory region 0x4009c000 - 0x4009e000
D (495) memory_layout: Available memory region 0x4009e000 - 0x400a0000
I (502) heap_init: Initializing. RAM available for dynamic allocation:
D (509) heap_init: New heap initialised at 0x3ffae6e0
I (514) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
D (520) heap_init: New heap initialised at 0x3ffb3bc0
I (525) heap_init: At 3FFB3BC0 len 0002C440 (177 KiB): DRAM
I (532) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (538) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
D (545) heap_init: New heap initialised at 0x4008ef38
I (549) heap_init: At 4008EF38 len 000110C8 (68 KiB): IRAM
D (556) intr_alloc: Connected src 46 to int 2 (cpu 0)
D (562) spi_flash: trying chip: issi
D (564) spi_flash: trying chip: gd
D (568) spi_flash: trying chip: mxic
D (572) spi_flash: trying chip: winbond
D (575) spi_flash: trying chip: generic
I (579) spi_flash: detected chip: generic
I (584) spi_flash: flash io: dio
D (588) efuse: In EFUSE_BLK0__DATA0_REG is used 1 bits starting with 2 bit
D (595) efuse: In EFUSE_BLK0__DATA0_REG is used 7 bits starting with 20 bit
W (602) flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)
D (609) efuse: In EFUSE_BLK0__DATA0_REG is used 1 bits starting with 17 bit
D (616) efuse: In EFUSE_BLK2__DATA0_REG is used 32 bits starting with 0 bit
D (623) efuse: In EFUSE_BLK2__DATA1_REG is used 32 bits starting with 0 bit
D (630) efuse: In EFUSE_BLK2__DATA2_REG is used 32 bits starting with 0 bit
D (637) efuse: In EFUSE_BLK2__DATA3_REG is used 32 bits starting with 0 bit
D (644) efuse: In EFUSE_BLK2__DATA4_REG is used 32 bits starting with 0 bit
D (651) efuse: In EFUSE_BLK2__DATA5_REG is used 32 bits starting with 0 bit
D (658) efuse: In EFUSE_BLK2__DATA6_REG is used 32 bits starting with 0 bit
D (665) efuse: In EFUSE_BLK2__DATA7_REG is used 32 bits starting with 0 bit
D (673) efuse: In EFUSE_BLK0__DATA0_REG is used 1 bits starting with 8 bit
D (679) cpu_start: calling init function: 0x400dc94c
0x400dc94c: esp_ipc_init at C:/Users/user/workspace/git/esp-idf/components/esp_system/esp_ipc.c:115

D (685) cpu_start: calling init function: 0x400d1cec
0x400d1cec: esp_reset_reason_init at C:/Users/user/workspace/git/esp-idf/components/esp_system/port/soc/esp32/reset_reason.c:68

D (690) cpu_start: calling init function: 0x400d139c
0x400d139c: esp_init_app_elf_sha256 at C:/Users/user/workspace/git/esp-idf/components/esp_app_format/esp_app_desc.c:69

D (695) cpu_start: calling init function: 0x400d4124 on core: 0
0x400d4124: __esp_system_init_fn_esp_timer_startup_init at C:/Users/user/workspace/git/esp-idf/components/esp_timer/src/esp_timer.c:464

D (701) intr_alloc: Connected src 17 to int 3 (cpu 0)
D (706) cpu_start: calling init function: 0x400ec1ec on core: 0
0x400ec1ec: __esp_system_init_fn_init_components0 at C:/Users/user/workspace/git/esp-idf/components/esp_system/startup.c:477

D (712) intr_alloc: Connected src 24 to int 9 (cpu 0)
I (717) cpu_start: Starting scheduler on PRO CPU.
D (0) intr_alloc: Connected src 25 to int 2 (cpu 1)
I (0) cpu_start: Starting scheduler on APP CPU.
D (732) heap_init: New heap initialised at 0x3ffe0440
D (742) heap_init: New heap initialised at 0x3ffe4350
D (752) intr_alloc: Connected src 16 to int 12 (cpu 0)
D (752) MB_PORT_COMMON: vMBPortSetMode: Port enter critical.
D (762) MB_PORT_COMMON: vMBPortSetMode: Port exit critical
D (762) MB_PORT_COMMON: eMBMasterRTUInit: Port enter critical.
I (772) uart: queue free spaces: 20
D (772) intr_alloc: Connected src 35 to int 13 (cpu 0)
D (782) MB_PORT_COMMON: xMBMasterPortSerialInit Init serial.
D (782) MB_PORT_COMMON: eMBMasterRTUInit: Port exit critical
D (792) MB_PORT_COMMON: eMBMasterRTUStart: Port enter critical.
D (792) MB_PORT_COMMON: eMBMasterRTUStart: Port exit critical
I (802) MASTER_TEST: Modbus master stack initialized...
D (812) MB_PORT_COMMON: xMBMasterRunResTake:Take resource (80) (101 ticks).
D (812) MB_PORT_COMMON: eMBMasterPoll:EV_MASTER_FRAME_TRANSMIT
D (822) POLL transmit buffer: 03 00 01 00 01
D (822) MB_PORT_COMMON: eMBMasterRTUSend: Port enter critical.
D (832) MB_PORT_COMMON: eMBMasterRTUSend: Port exit critical
D (832) MB_PORT_COMMON: xMBMasterPortSerialSendRequest default
D (842) MB_PORT_COMMON: vMBMasterPortTimersRespondTimeoutEnable Respond enable timeout.
D (852) MB_MASTER_SERIAL: MB_TX_buffer sent: (9) bytes.
D (852) MB_PORT_COMMON: vMBMasterRxSemaRelease:RX semaphore is free.
D (862) MB_PORT_COMMON: xMBPortSerialWaitEvent, UART event: 1
D (872) MB_MASTER_SERIAL: MB_uart[1] event:
D (872) MB_MASTER_SERIAL: uart rx break.
D (872) MB_PORT_COMMON: xMBPortSerialWaitEvent, UART event: 1
D (882) MB_MASTER_SERIAL: MB_uart[1] event:
D (892) MB_MASTER_SERIAL: uart rx break.
D (892) MB_PORT_COMMON: xMBPortSerialWaitEvent, UART event: 0
D (892) MB_MASTER_SERIAL: MB_uart[1] event:
D (902) MB_MASTER_SERIAL: Data event, len: 7.
D (902) MB_MASTER_SERIAL: Received data: 8(bytes in buffer)

D (912) MB_MASTER_SERIAL: Timeout occured, processed: 8 bytes
D (922) MB_PORT_COMMON: eMBMasterPoll:EV_MASTER_FRAME_SENT
D (922) POLL sent buffer: 03 00 01 00 01
D (922) MB_PORT_COMMON:  xMBMasterPortSerialGetResponse default
D (932) MB_PORT_COMMON: eMBMasterRTUReceive: Port enter critical.
D (942) MB_PORT_COMMON: eMBMasterRTUReceive: Port exit critical
D (942) MB_PORT_COMMON: eMBMasterPoll: Packet data received successfully (0).
D (952) POLL receive buffer: 03 02 02 e0
D (952) MB_PORT_COMMON: eMBMasterPoll:EV_MASTER_EXECUTE
D (962) MB_PORT_COMMON: eMBMasterPoll: set event EV_ERROR_OK
D (972) MB_PORT_COMMON: eMBMasterPoll:EV_MASTER_ERROR_PROCESS
D (972) MB_PORT_COMMON: vMBMasterCBRequestSuccess: Callback request success.
D (982) MB_PORT_COMMON: eMBMasterWaitRequestFinish: returned event = 0x40
I (992) MASTER_TEST: Val read: 736

More Information.

I initially mentioned this issue on a separate Modbus post here. The UART driver returned an error when the parity check failed, but the corresponding mechanism for stop bits does not appear to be working. We understand that this may still work in most situations, but ideally we want any mismatch in the communication configuration to be detected and to return an error.

alisitsyn commented 1 week ago

@ nicksenva,

Sorry for the late answer. Unfortunately, this issue can not be easily resolved for now because of HW aspects. This issue will be propagated to HW team and added to the list.