RTU/mimo/plan/libcomm修补计划.md

4.2 KiB
Raw Blame History

libcomm 修补计划

目标: 修复 UART send 不完整、TCP 空轮询、无 destroy 接口、stru_comm 冗余函数指针 四个问题

涉及文件:

  • 修改: src/public/libcomm/src/comm_uart.cpp — 恢复注释掉的成熟实现
  • 修改: src/public/libcomm/src/comm_tcp.cpp — TCP client select 去掉 100ms 空轮询
  • 修改: src/public/libcomm/src/comm.cpp — 添加 comm_destroy
  • 修改: src/public/libcomm/inc/comm.h — 清理 stru_comm 冗余字段 + 声明 comm_destroy
  • 修改: release/inc/myComm.h — 声明 comm_destroy
  • 更新: mimo/工程/libcomm模块分析.md

Task 1: 恢复 UART 成熟实现

文件: src/public/libcomm/src/comm_uart.cpp

注释掉的版本(行 361-692比当前活跃代码更完整

差异 当前活跃 注释版本
open O_RDWR | O_NOCTTY | O_NDELAY O_RDWR | O_NOCTTY(阻塞模式,由 VTIME 控制超时)
原始模式 ~ICANON | ~ECHO | ~ECHOE | ~ISIG
输出处理 ~OPOST
输入处理 ~IXON | ~IXOFF | ~IXANY | ~ICRNL | ~INLCR | ~IGNCR
VTIME 0 1100ms 读超时)
VMIN 0 0

操作: 删除当前活跃代码 + 注释代码(行 69-692写入新实现。

uart_send 封装 tcflush + write + tcdrain,确保发送完整性:

static int uart_send(void *p_this, const uint8_t *tx, uint16_t tx_len)
{
    stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
    if(NULL == p_uart || NULL == tx || 0 == tx_len)
    {
        return -1;
    }

    tcflush(p_uart->uart_fd, TCOFLUSH);

    int total = 0;
    while(total < tx_len)
    {
        int ret = write(p_uart->uart_fd, tx + total, tx_len - total);
        if(ret < 0)
        {
            LOG_E("write failed, errno:%d", errno);
            return -1;
        }
        total += ret;
    }

    tcdrain(p_uart->uart_fd);

    if(p_uart->debug_show_cb && p_uart->debug_show == CommDebugShow::on)
    {
        p_uart->debug_show_cb(p_uart->p_para->device.c_str(), CommDir::dir_send, tx, tx_len);
    }

    return 0;
}

Task 2: TCP client 去掉 100ms select 空轮询

文件: src/public/libcomm/src/comm_tcp.cpp:245-246

当前:

struct timeval tmval = {0, 100000};
int ret = select(p_tcp->sockfd + 1, &recvfdset, NULL, NULL, &tmval);

改为:

int ret = select(p_tcp->sockfd + 1, &recvfdset, NULL, NULL, NULL);

去掉 tmval 变量声明。TCP client 线程专用此连接,阻塞 select 零 CPU 空转。


Task 3: 添加 comm_destroy

文件: src/public/libcomm/src/comm.cpp

comm_state_register 之后新增:

int comm_destroy(int id)
{
    auto it = g_comm_map.find(id);
    if(it == g_comm_map.end())
    {
        LOG_E("comm id:%d not exist", id);
        return -1;
    }
    stru_comm &comm = it->second;

    switch(comm.type)
    {
        case CommType::tcp_client:
        case CommType::tcp_server:
            free(comm.p_comm);
            break;
        case CommType::udp_client:
        case CommType::udp_server:
            free(comm.p_comm);
            break;
        case CommType::uart:
            free(comm.p_comm);
            break;
        default:
            break;
    }

    g_comm_map.erase(it);
    return 0;
}

Task 4: 清理 stru_comm 冗余函数指针

文件: src/public/libcomm/inc/comm.h

stru_comm 中 6 个函数指针字段从未被填充,所有分派走 switch(type)。删除:

int (*comm_connect)(int id);
int (*comm_disconnect)(int id);
int (*comm_run)(int id);
int (*comm_state_register)(int id, comm_state_cb cb);
int (*comm_recv_register)(int id, comm_recv_cb cb);
int (*comm_send)(int id, const char *data, uint16_t len);

Task 5: 头文件声明 comm_destroy

文件: release/inc/myComm.h

comm_state_register 声明后新增:

int comm_destroy(int id);

Task 6: 编译 + 更新文档

  1. ./release/build.sh 编译零错误零警告
  2. 更新 mimo/工程/libcomm模块分析.md 缺点表
  3. 追加到 mimo/问题处理文档.md

验证

步骤 命令 预期
全量编译 ./release/build.sh Build complete,零错误零警告