You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32MP157-DK2开发板A7端无法读取M4端RPMSG消息求助

STM32MP157-DK2 RPMSG虚拟UART:A7无法读取M4发送的消息

问题根源分析

  1. 频繁开关设备:每次读写都重新打开/dev/ttyRPMSG0,破坏了RPMSG会话状态,无法保证M4的回复能被当前文件描述符捕获。
  2. 非阻塞模式无错误区分:同时使用等效的O_NONBLOCK和O_NDELAY,发送请求后立即调用read,此时M4回复尚未到达,非阻塞模式下read直接返回-1(错误码EAGAIN),但代码未区分该临时错误与真正的读取失败。
  3. 缓冲区未初始化:读取失败时直接使用未初始化的data数组,导致输出垃圾内容。
  4. M4发送长度可能错误:若SendMsgVirt0Size为固定值而非实际消息长度,会导致发送不完整或冗余数据。

解决方案代码修改

1. A7端:持久化设备文件描述符

将设备打开操作移到程序初始化阶段,避免频繁开关:

#include <errno.h>

static int rpmsg_fd = -1;

// 程序启动时调用初始化
void rpmsg_init(void) {
    // 可选:使用阻塞模式(去掉O_NONBLOCK)简化逻辑;若保留非阻塞需后续处理EAGAIN
    rpmsg_fd = open("/dev/ttyRPMSG0", O_RDWR | O_NOCTTY);
    if (rpmsg_fd < 0) {
        g_print("CA7: Failed to open /dev/ttyRPMSG0, errno: %d\n", errno);
    }
}

// 程序退出时调用清理
void rpmsg_cleanup(void) {
    if (rpmsg_fd != -1) {
        close(rpmsg_fd);
        rpmsg_fd = -1;
    }
}

2. A7端:修改读取函数逻辑

static gboolean update_M4_variable(gpointer user_data) {
    char data[32] = {0}; // 初始化缓冲区,避免垃圾值
    char msg[128];

    if (rpmsg_fd < 0) {
        gtk_label_set_text(GTK_LABEL(text_status), "RPMSG device not initialized");
        return TRUE;
    }

    // 发送请求
    ssize_t write_ret = write(rpmsg_fd, "xValue", 6);
    if (write_ret < 0) {
        snprintf(msg, sizeof(msg), "Send failed: errno %d", errno);
        gtk_label_set_text(GTK_LABEL(text_status), msg);
        return TRUE;
    }

    // 读取回复
    int read_ret = read(rpmsg_fd, data, sizeof(data) - 1); // 留位置给字符串结束符
    data[sizeof(data)-1] = '\0'; // 强制保证字符串终止

    if (read_ret < 0) {
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
            snprintf(msg, sizeof(msg), "No data yet, retrying...");
        } else {
            snprintf(msg, sizeof(msg), "Read error: errno %d", errno);
        }
    } else if (read_ret == 0) {
        snprintf(msg, sizeof(msg), "Remote connection closed");
    } else {
        snprintf(msg, sizeof(msg), "Received: %s", data);
    }

    gtk_label_set_text(GTK_LABEL(text_status), msg);
    return TRUE;
}

3. M4端:修正发送长度

确保发送的是实际消息长度,而非固定值:

// 替换原VIRT_UART_Transmit调用
uint16_t send_len = strlen((char*)SendMsgVirt0);
VIRT_UART_Transmit(&huart0, SendMsgVirt0, send_len);

额外注意事项

  • 检查设备节点权限:执行sudo chmod 666 /dev/ttyRPMSG0测试是否因权限导致读取失败。
  • 非阻塞模式优化:若坚持使用非阻塞,建议用poll()或select()等待数据就绪后再调用read,避免无效重试。
  • 验证RPMSG驱动:确认rpmsg_char驱动已正确加载,可通过lsmod | grep rpmsg查看。

内容的提问来源于stack exchange,提问作者Telmo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 06:20:23