This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] AM625:需要帮助了解__sin ()和_XOUT ()的使用和操作

Guru**** 2468510 points
Other Parts Discussed in Thread: AM625

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1463115/am625-need-help-understanding-__xin-and-__xout-usage-and-operation

器件型号:AM625

工具与软件:

大家好!

我想使用 AM625上的 XFR2VBUS、并使用 AM62 TRM 来尝试和理解、以及以下链接中问题的一些见解:

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1169066/sk-am64-follow-up-question-how-to-read-write-data-with-the-pru_icssg-xfr2vbus-hardware-accelerator/4401798?tisearch=e2e-sitesearch&keymatch=PRU%252520__xin#4401798

根据上述内容、我创建了此样例程序:

/*
 * Copyright (c) 2015, 2016, 2022, 2024 Vorne Industries, Inc.
 * All rights reserved.
 */

#include <stdint.h>
#include <pru_cfg.h>
#include <pru_ctrl.h>
#include <pru_iep.h>
#include <pru_intc.h>

volatile register uint32_t __R30;

#define BIT(n) (1u<<n)

static inline void set_clk_l()
{
    __R30 &= ~BIT(6); // shows up on pin #3 of LGS on the EVK
}

static inline void set_clk_h()
{
    __R30 |= BIT(6); // shows up on pin #3 of LGS on the EVK
}


static inline void nop1()
{
    __R30 |= BIT(31);
}

static inline void nop10()
{
    nop1();
    nop1();
    nop1();
    nop1();
    nop1();
    nop1();
    nop1();
    nop1();
    nop1();
    nop1();
}


static inline void nop30()
{
    nop10();
    nop10();
    nop10();
}


#define XFR_RD_ID0  0x60
#define XFR_RD_ID1  0x61
#define XFR_WR_ID0  0x62


#define XFR_SIZE_4B (0)
#define XFR_SIZE_32B (2<<1)
#define XFR_SIZE_64B (3<<1)

#define XFR_REG_RD_BUSY 18
#define XFR_REG_WR_BUSY 20
#define XFR_REG_DATA    2

#define XFR_MASK_RD_BUSY 0x1
#define XFR_MASK_WR_BUSY 0x1

#define NO_REMAPPING 0

#define DDR_ADDR_IN (0x9c600000ull)
#define DDR_ADDR_OUT (0x9c600020ull)

typedef union {
    uint8_t byte[32];
    struct {
        uint64_t r2r3;
        uint64_t r4r5;
        uint64_t r6r7;
        uint64_t r8r9;
    } regs;
} PAYLOAD;

typedef struct {
    PAYLOAD data;
    uint64_t addr; // R10, R11
} DATA_PACKET;

DATA_PACKET pkt_tmp;
PAYLOAD data;

void test_xfr()
{
    nop30();
    nop30();
    nop30();
    uint32_t busy_status;

    busy_status = 1;
    // This loop seems to hang forever
    while ( (busy_status&XFR_MASK_RD_BUSY)==XFR_MASK_RD_BUSY ) {
        __xin(XFR_RD_ID0,XFR_REG_RD_BUSY,NO_REMAPPING,busy_status);
    }

    uint64_t cmd = (DDR_ADDR_IN<<32) | XFR_SIZE_32B;
    __xout(XFR_RD_ID0,XFR_REG_RD_BUSY,NO_REMAPPING,cmd);

    do {
        __xin(XFR_RD_ID0, XFR_REG_RD_BUSY, NO_REMAPPING, busy_status );
    } while ( !(busy_status&BIT(0)) || busy_status&BIT(2) );

    __xin(XFR_RD_ID0, XFR_REG_DATA, NO_REMAPPING, data );

    pkt_tmp.data.regs = data.regs;
    pkt_tmp.addr = DDR_ADDR_OUT;
    do {
        __xout(XFR_WR_ID0, XFR_REG_WR_BUSY, NO_REMAPPING, busy_status);
    } while ( busy_status&BIT(0) );

    __xout(XFR_WR_ID0, XFR_REG_DATA, NO_REMAPPING, pkt_tmp);

    do {
        __xout(XFR_WR_ID0, XFR_REG_WR_BUSY, NO_REMAPPING, busy_status);
    }  while ( busy_status&BIT(0) );
}

int main()
{
    while(1) {
        set_clk_h();
        test_xfr();
        set_clk_l();
        test_xfr();
    }
}

并编译出来。 `是将`0x9c600000 μ s `32个字节的块复制到` 0x9c600020 μ s 中、可通过器件树将其配置为 DDR 中的保留存储器区域。

我希望在每次执行此测试时都有一个 GPO 切换、但信号完全不会切换。

出于好奇心、我在第一个__sin 循环之前立即添加了一个无限循环(SET_H/SET_L)(代替`//这个循环似乎一直挂起`注释)。 完成这一更改后、我可以看到输出信号切换。

看来有些东西会导致 PRU 挂起、或者如果允许它从该点向前继续、就会进入无限循环。

clpru 编译标记为:`-O0 --opt_for_speed=1 --auto_inline -v3`。

上述某些操作是从链接的问题推断得出的、因为 AM62 TRM 似乎没有包含与表6-73 (读取命令)等效的用于描述写入命令。 这些在 AM62 PRU 上极有可能不受支持吗?

如果您能为本代码的运行提供任何帮助、我们将不胜感激。

此致、

António μ A

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、 António

    我最后还有些奇怪、因此、我正在将您的主题传递给另一位团队成员、与您一起处理此主题。

    同时、我们还开展了 其他 有关在 AM243x/AM64x 上使用宽边接口的培训。 您可以像我们为即将到来的 PRU 学院所做的内容的"草稿"那样看待这种情况: https://git.ti.com/cgit/pru-software-support-package/pru-software-support-package/tree/examples/am243x

    我能否让您看一看、并告知我们它是否有帮助? 除了 Ultrafast_broadside 示例项目外、还有一个 PDF 文档。

    除了迁移现有的 AM243x/AM64x 文档之外、我们还想添加 AM62x 特定宽边文档、因此、非常感谢您提供任何反馈。 我们已经将您的 PRU 内核时钟线程列为内核频率部分的参考。

    此致、

    Nick

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Nick。

    很抱歉耽误了时间、今天我才有机会查看您链接到的材料。 我曾看过 PDF 和汇编示例、但我不确定 "对于使用宽边加速器的 C 代码实现、 需要寄存器上下文保存和恢复"该怎么做。  

    不过、这个主题似乎非常相关、我想要找到一些内容、例如:

    • TRM 中列出了 SoC 上可用的宽边 ID。  您提到的 PDF 上的某种与宽边函数表的行类似的内容
    • 有关如何使用 C 代码中的 XFR2VBUS 加速器以加速向/从 DDR 传输的示例

    PRU 有其复杂性、但如果我们有示例可供借鉴并快速提出一些在没有大量阅读和试错的情况下有效的东西、那么 PRU 会非常有用。 不幸的是, TRM 和 PRU-c 编译器(或汇编器)的组合,最经常不,带我们到兔子洞的试错,因为有些事情是不明显和困难猜测(我的意见,无论如何:)))

    是否有可能有一个想法为什么我的例子似乎永远在第一个  ___ xin ? 我尝试把它设置在一对之间  set_clk_h/set_clk_l 如果我运行该代码、我的 GPO 完全不会切换 [编辑:这不是真的。 它**做**切换!] . 它确实会在循环之前立即切换。

    从最初的问题来看、这种代码似乎有发挥作用的潜力、但我却漏掉了一些可导致测试失败的东西。

    感谢您提供的投入。 如果您需要我更具体的信息、请告诉我。

    此致、

    António μ A

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、 António

    您是否可以了解为什么我的示例一开始似乎一直存在  ___ xin ? 我尝试把它设置在一对之间  set_clk_h/set_clk_l 如果我运行该代码、我的 GPO 完全不会切换。 它确实会在循环前立即切换。

    您是说在进行这种修改的情况下运行代码时、您会看到信号变为高电平但不会变为低电平吗?   刚好在第一个_xin 之后放置无限循环(SET_H/SET_L)是否会导致该循环根本无法执行?

    根据 TRM、您用于执行读取操作的代码似乎是正确的、因此我不希望它卡在第一个__sin 循环中。

    但是、TRM 中确实提到了只有 2个 XFR2VBUS RX 线程可用、这可能会导致代码中的写入操作出现问题。 我将在内部与团队仔细核实这一点、然后回复给您。

      

    此致、

    Nitika

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的反馈。

    哎呀、很高兴您提出了这个问题  

    我一定错过了一些时光...  事实上、如果我在 set_clk_h/set_clk_l 调用之间放置__xin()、则 GPO **会进行切换。 对不起我的误导信息。

        // This loop seems to hang forever
        while ( (busy_status&XFR_MASK_RD_BUSY)==XFR_MASK_RD_BUSY ) {
            set_clk_h();
            __xin(XFR_RD_ID0,XFR_REG_RD_BUSY,NO_REMAPPING,busy_status);
            set_clk_l();
        }

    PRU 正在运行、GPO 正在切换、但 BUSY 标志似乎永远不会清除、或者我的代码存在错误。

    Nick 链接的 PDF 表明、使用 C 的宽边在某些寄存器上存在冲突:

     C 编译程序使用 R2、R14、R15作为栈指针和函数调用参数、因此会发生冲突。 因此、这些 示例使用了汇编器编码。 对于使用宽边加速器的 C 代码实施、 需要寄存器上下文保存和恢复。

    我想这与我的问题在某种程度上相关。

    我也不确定我使用的宽边 ID 是否错误。 在这方面、在 AM62 TRM 上很难遵循这些信息。

    第二个 PRU 已停止、因此我非常确信只有一个 XFR 处于活动状态。 至少、如果我们能够执行以超过第一次读取、那么我就会很高兴、然后可以专注于调试后续写入中的任何潜在问题。

    此致、

    António μ A

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、 António

    根据 TRM、您使用的 ID 和寄存器是正确的。

    我在我的设置中使用 SBL_NULL 尝试了以下简化版本的代码、并通过 CCS 加载进行测试。 我相信它按预期工作。   

    /*
     * Copyright (C) 2025 Texas Instruments Incorporated - http://www.ti.com/
     *
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     *  * Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     *  * Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the
     *    distribution.
     *
     *  * Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    
    /*
     * main.c
     */
    
    #include <stdint.h>
    
    volatile register uint32_t __R30;
    volatile register uint32_t __R31;
    
    #define BIT(n) (1u<<n)
    
    #define XFR_RD_ID0  0x60
    #define XFR_RD_ID1  0x61
    
    #define XFR_SIZE_32B (2<<1)
    #define XFR_SIZE_64B (3<<1)
    
    #define XFR_MASK_RD_BUSY 0x1
    #define XFR_REG_RD_BUSY 18
    #define XFR_REG_DATA    2
    
    #define NO_REMAPPING 0
    
    #define DDR_ADDR_IN (0x9c600000ull)
    #define DDR_ADDR_OUT (0x9c600020ull)
    
    /*
     * These structs (datagram_type) and (container_type) force the compiler to align data 64bit-wise.
     * This is necessary in order to use it with the xfr2vbus
     * accelerators
     *  */
    
    struct datagram_type{
        uint64_t r2and3; //data
        uint64_t r4and5; //data
        uint64_t r6and7; //data
        uint64_t r8and9; //data
        uint64_t r10and11; //addr
    };
    
    struct container_type{
        uint64_t r2and3; //data
        uint64_t r4and5; //data
        uint64_t r6and7; //data
        uint64_t r8and9; //data
      };
    
    typedef union package{
        struct datagram_type datagram;
        uint8_t bytes[sizeof(struct datagram_type)];
    }frame;
    
    typedef union package_wo_addr{
        struct container_type datagram;
        uint8_t bytes[sizeof(struct container_type)];
    }frame_wo_addr;
    frame_wo_addr data_2_read;
    
    static inline void nop1()
    {
        __R30 |= BIT(31);
    }
    
    void main(void)
    {
        uint32_t busy_status;
    
        busy_status = 1;
        /* Wait RD_BUSY = 0h */
        while ( (busy_status&XFR_MASK_RD_BUSY)== XFR_MASK_RD_BUSY) {
            __xin(XFR_RD_ID0,XFR_REG_RD_BUSY,NO_REMAPPING,busy_status);
        }
    
        /* XOUT R18 (configure RD_AUTO/ RD_SIZE); */
        uint64_t cmd = (DDR_ADDR_IN<<32) | XFR_SIZE_32B;
        __xout(XFR_RD_ID0,XFR_REG_RD_BUSY,NO_REMAPPING,cmd);
    
        /* Wait WR_BUSY = 0h OR RD_DATA_FL = 1h */
        busy_status  = 1;
        while((busy_status & 0xF) != 0x05)
        {
            __xin(XFR_RD_ID0, XFR_REG_RD_BUSY, NO_REMAPPING, busy_status);
        }
    
        /* XIN RD_DATA */
        __xin(XFR_RD_ID0, XFR_REG_DATA, NO_REMAPPING, data_2_read );
        /* end read procedure */
    
        while(1) {
            nop1();
        }
    
    }
    

    存储器位置(通过 CCS 手动修改值):

    读取后的 R2-R9 PRU 寄存器值:

    目前我还没有回答为什么它不能为你工作。 您能否查看上述信息、并在有任何帮助时告诉我。

    此致、

    Nitika

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗡嗡声,谢谢你通过所有的麻烦,自己测试它.

    我将很快返回到该设置、然后执行另一个 GO。 我想知道,如果,类似于 GPO 什么不切换,我可能在我测试该固件时遗漏了一些东西。

    此致、

    António μ A

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗯、这对我没有效果。 从我的观察来看,我正在驾驶的 GPO 只是不断切换,这意味着我们不会超过第一个检查忙标志.

    我之前在这个项目中对这个进行了探索、结果放弃了使用 XFR2VBUS 的需要。 因此、虽然我没有让它发挥作用并不是什么大问题、但我肯定希望它能够在行动中发挥作用、即使是为了了解如何通过 C 与 clpru 来实现它。

    我会看看我是否能找到一些时间来创建一个最小的示例,我可以在这里分享(来源, Makefile 等),这可能会帮助任何人更容易地发现遗漏的东西。

    另外、我想知道在主机处理器方面是否需要确保以便运行此测试、无论是在器件树级别、内核配置等方面。

    祝你一切顺利!

    António μ A

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

     下面是我目前所知道的:

    即使不是我想要的、下面的代码似乎执行了_something_:

    /*
     * Copyright (c) 2015, 2016, 2022, 2024 Vorne Industries, Inc.
     * All rights reserved.
     */
    
    #include <stdint.h>
    #include <pru_cfg.h>
    #include <pru_ctrl.h>
    #include <pru_intc.h>
    
    volatile register uint32_t __R30;
    
    #define BIT(n) (1u<<n)
    
    static inline void set_clk_l()
    {
        __R30 &= ~BIT(6); // shows up on pin #3 of LGS on the EVK
    }
    
    static inline void set_clk_h()
    {
        __R30 |= BIT(6); // shows up on pin #3 of LGS on the EVK
    }
    
    static inline void toggle_clk()
    {
        __R30 ^= BIT(6);
    }
    
    #define XFR_RD_ID0  0x60
    #define XFR_RD_ID1  0x61
    #define XFR_WR_ID0  0x62
    #define XFR_WR_ID1  0x63
    
    
    #define XFR_SIZE_4B (0)
    #define XFR_SIZE_32B (2<<1)
    #define XFR_SIZE_64B (3<<1)
    
    #define XFR_REG_RD_BUSY 18
    #define XFR_REG_WR_BUSY 20
    #define XFR_REG_DATA    2
    
    #define XFR_MASK_RD_BUSY 0x1
    #define XFR_MASK_WR_BUSY 0x1
    
    #define NO_REMAPPING 0
    
    #define DDR_ADDR_IN (0x9c600000ull)
    #define DDR_ADDR_OUT (0x9c600020ull)
    
    typedef union {
        uint8_t byte[32];
        struct {
            uint64_t r2r3;
            uint64_t r4r5;
            uint64_t r6r7;
            uint64_t r8r9;
        } regs;
    } PAYLOAD;
    
    typedef struct {
        PAYLOAD data;
        uint64_t addr; // R10, R11
    } DATA_PACKET;
    
    DATA_PACKET pkt_tmp;
    PAYLOAD data;
    
    
    int main()
    {
        set_clk_l();
    
        uint32_t busy_status;
    
        busy_status = 1;
        // This loop seems to hang forever
        while ( (busy_status&XFR_MASK_RD_BUSY)==XFR_MASK_RD_BUSY ) {
            toggle_clk();
            __xin(XFR_RD_ID0,XFR_REG_RD_BUSY,NO_REMAPPING,busy_status);
        }
    
        set_clk_h();
        set_clk_h();
        set_clk_l();
        set_clk_l();
    
        uint64_t cmd = (DDR_ADDR_IN<<32) | XFR_SIZE_32B;
        __xout(XFR_RD_ID0,XFR_REG_RD_BUSY,NO_REMAPPING,cmd);
    
        set_clk_h();
        set_clk_h();
        set_clk_l();
        set_clk_l();
    
        do {
            __xin(XFR_RD_ID0, XFR_REG_RD_BUSY, NO_REMAPPING, busy_status );
        } while ( !(busy_status&BIT(0)) );
    
        set_clk_h();
        set_clk_h();
        set_clk_l();
        set_clk_l();
    
        __xin(XFR_RD_ID0, XFR_REG_DATA, NO_REMAPPING, data );
    
        do {
            __xin(XFR_RD_ID0, XFR_REG_RD_BUSY, NO_REMAPPING, busy_status );
        } while ( !(busy_status&BIT(0)) || busy_status&BIT(2) );
    
        set_clk_h();
        set_clk_h();
        set_clk_l();
        set_clk_l();
    
        uint32_t *dest = (uint32_t *)DDR_ADDR_OUT;
        dest[0] = data.regs.r2r3>>32;
        dest[1] = data.regs.r2r3&0xffffffff;
        dest[2] = data.regs.r4r5>>32;
        dest[3] = data.regs.r4r5&0xffffffff;
        dest[4] = data.regs.r6r7>>32;
        dest[5] = data.regs.r6r7&0xffffffff;
        dest[6] = data.regs.r8r9>>32;
        dest[7] = data.regs.r8r9&0xffffffff;
    }

     同时我发现:

    *如果我的电路板通过重启或重启,那么代码运行,我可以在示波器上看到4个脉冲。

    *如果在运行代码之前将某些数据放置在0x9c600000至0x9c60001f 存储器区域中(它通过 devicetre 保留的存储器)、我希望某些数据类似于0x9c600020到0x9c60003f 上会弹出的原始数据、但我得到的只是0。

    *如果我尝试在没有重启电源或重启的情况下再次运行相同的代码, PRU 似乎停留在第一个等待循环( GPO 不断切换)。

    因此、我似乎所做的事情与数据移动本身以及 XFR2VBUS 的运行相关。

    作为参考、我是如何构建固件的:

    clpru --define=AM62X --include_path=/home/amsobr/Apps/pru-bsp//include/am62x --include_path=/home/amsobr/Apps/ti-cgt-pru-2.3.3//include -O0 --opt_for_speed=0 --auto_inline -v3 --endian=little --hardware_mac=on xfr-test.c
    clpru --run_linker --rom_model -i/home/amsobr/Apps/ti-cgt-pru-2.3.3//lib --reread_libs -oxfr-test.bin xfr-test.obj

    链接器 scipt:

    -cr
    -stack 0x400
    -heap 0x200
    
    MEMORY
    {
    	PAGE 0:
    	PRUIMEM		: org = 0x00000000 len = 0x00004000  /* 16kB PRU Instruction RAM */
    
    	PAGE 1:
    	PRUDMEM		: org = 0x00000000 len = 0x00002000  /* 8kB PRU Data RAM 0 */
    
    	PAGE 2:
    	SHAREDMEM	: org = 0x00010000 len = 0x00008000  /* 32kB Shared RAM */
    	PRU0_CTRL	: org = 0x00022000 len = 0x00000030
    	PRU1_CTRL	: org = 0x00024000 len = 0x00000030
    
    	/* Constant Table Memory directives. */
    
    	PRU_INTC	: org = 0x00020000 len = 0x00001504	CREGISTER=0
    	DMTIMER2	: org = 0x48040000 len = 0x00000100	CREGISTER=1
    	I2C1		: org = 0x4802A000 len = 0x00000100	CREGISTER=2
    	PRU_ECAP	: org = 0x00030000 len = 0x00000100	CREGISTER=3
    	PRU_CFG		: org = 0x00026000 len = 0x00000100	CREGISTER=4
    	MMCHS0		: org = 0x48060000 len = 0x00000100	CREGISTER=5
    	MCSPI0		: org = 0x48030000 len = 0x00000100	CREGISTER=6
    	PRU_UART0	: org = 0x00028000 len = 0x00000100	CREGISTER=7
    	MCASP0_DMA	: org = 0x46000000 len = 0x00000100	CREGISTER=8
    	GEMAC		: org = 0x4A100000 len = 0x00000100	CREGISTER=9
    	RSVD10		: org = 0x48318000 len = 0x00000100	CREGISTER=10
    	UART1		: org = 0x48022000 len = 0x00000100	CREGISTER=11
    	UART2		: org = 0x48024000 len = 0x00000100	CREGISTER=12
    	RSVD13		: org = 0x48310000 len = 0x00000100	CREGISTER=13
    	DCAN0		: org = 0x481CC000 len = 0x00000100	CREGISTER=14
    	DCAN1		: org = 0x481D0000 len = 0x00000100	CREGISTER=15
    	MCSPI1		: org = 0x481A0000 len = 0x00000100	CREGISTER=16
    	I2C2		: org = 0x4819C000 len = 0x00000100	CREGISTER=17
    	EHRPWM1		: org = 0x48300000 len = 0x00000100	CREGISTER=18
    	EHRPWM2		: org = 0x48302000 len = 0x00000100	CREGISTER=19
    	EHRPWM3		: org = 0x48304000 len = 0x00000100	CREGISTER=20
    	MDIO		: org = 0x00032400 len = 0x00000100	CREGISTER=21
    	MBX0		: org = 0x480C8000 len = 0x00000100	CREGISTER=22
    	SPINLOCK	: org = 0x480CA000 len = 0x00000100	CREGISTER=23
    	PRU_IEP		: org = 0x0002E000 len = 0x0000031C	CREGISTER=26
    	TPCC		: org = 0x49000000 len = 0x000010A0	CREGISTER=29
    	L3OCMC		: org = 0x40000000 len = 0x00010000	CREGISTER=30
    	DDR			: org = 0x80000000 len = 0x00010000	CREGISTER=31
    }
    
    SECTIONS {
    	.text		>  PRUIMEM, PAGE 0
    
    	.stack		>  PRUDMEM, PAGE 1
    	.bss		>  PRUDMEM, PAGE 1
    	.cio		>  PRUDMEM, PAGE 1
    	.data		>  PRUDMEM, PAGE 1
    	.switch		>  PRUDMEM, PAGE 1
    	.sysmem		>  PRUDMEM, PAGE 1
    	.cinit		>  PRUDMEM, PAGE 1
    	.rodata		>  PRUDMEM, PAGE 1
    	.rofardata	>  PRUDMEM, PAGE 1
    	.farbss		>  PRUDMEM, PAGE 1
    	.fardata	>  PRUDMEM, PAGE 1
    	.resource_table >  PRUDMEM, PAGE 1
    	.FRAME_BUFFER > SHAREDMEM, PAGE 2
    	.PRU0_CTRL	>  PRU0_CTRL, PAGE 2
    	.PRU1_CTRL	>  PRU1_CTRL, PAGE 2
    }
    

    和器件树上的保留存储器块:

    	reserved-memory {
    		#address-cells = <2>;
    		#size-cells = <2>;
    		ranges;
    
    		rsvd-pru@0x9c600000 {
    			reg = <0x00000000 0x9c600000 0x000000 0x00100000>;
    		};
        };

    感谢您的耐心、尽管我们不太可能在我们的固件中使用 XFR2VBUS、但了解如何根据 C 代码使用 XFR2VBUS 可能会有所帮助、并希望将其作为一个示例集成到 PRU-support-package 示例中。

    清楚地说、这目前不是一个紧急的主题、为了更好地理解这些东西的工作原理、我可以帮助尝试我设置中的不同东西来找出这个问题。

    此致、

    António μ A

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、 António

    我认为在您的情况下、第一次读取是成功的、在第一次迭代中读取的值应该在寄存器 R2-R9中更新。

    我希望0x9c600020到0x9c60003f
    中会出现类似原始数据的情况

    如上所述、AM62x TRM 提到只有 2个 XFR2VBUS RX 线程可用、这可能是您没有看到写入反映在存储器中的原因。

    我将就其背后的原因向设计团队进行跟进。

    此致、

    Nitika

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、 António

    设计团队确认 AM62x PRUSS 仅支持 RX XFR2VBUS。 在写入方面、您无法使用 XFR2VBUS 小工具。

    此致、

    Nitika

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Nikita:  

    感谢您花时间对此进行深入了解。

    此致、

    António μ A