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.

[参考译文] AM3358:PRU 行为不一致

Guru**** 2574125 points
Other Parts Discussed in Thread: AM3358

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/629947/am3358-pru-inconsistent-behavior

器件型号:AM3358

您好!



我在 AM3358上、特别是在 BeagleBone Black 上运行 PRU 时遇到一些问题。 我从 https://github.com/beagleboard/am335x_pru_package 运行了"PRU_memAccess_DDR_PRUsharedRAM"示例 、没有问题。 然后、在开发在 PRU 上运行的我自己的代码的过程中、PRU 在尝试写入 DDR 存储器时开始挂起。 请注意、OCP 主端口已启用。

然后、我发现有时、重启后、PRU 在运行其他已知不挂起的代码时仍会挂起!

附件是我的代码。 我已经注释了一些应该写入 DDR 存储器进行测试的器件。 请告诉我如何读写 PRU 中的 DDR 存储器、而不会使其挂起!



谢谢、

William Kalfus

ddrmemtest.c:

#include  
#include "prussdrv.h"
#include  
#include  
#include  
#include  

#define PRU_CODE_FILE "additiontest.bin"

int main() {

    int mem_fd = open ("/dev/mem、 O_RDWR);
    if (mem_fd < 0) {
        printf ("  打开 /dev/mem 失败");
        返回 -1;
    }

    void* DDR_mem = mmap (0、0xFFFFFFF、PROT_WRITE|PROT_READ、MAP_SHARED、mem_FD、 0x8000000);
    if (DDR_mem = NULL) {
        printf ("  映射 设备失败");
        Close (mem_fd);
        返回 -1;
    }

    void* DDR = DDR_mem;

    // 获取     要存储的值
    printf ("输入    要存储的值: ");
    scanf("%d", (unsigned int*)DDR);

    // 初始化  PRU
    printf ("正在初始 化 PRU...\n");
    prussdrv_init();

    int ret = prussdrv_open (PRU_EVTOUT_0);
    if (ret) {
        printf ("打开 PRU 失败\n");
        回程;  
    }

    // 配置  PRU 中断
    tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
    prussdrv_pruintc_init (&pruss_intc_initdata);

    // 将    addend1 和 addend2的地址写入  PRU 数据 存储器
    printf ("将 数据加载 到 PRU 存储器...\n");

    void* pru0_datamem;
    prussdrv_map_prumem (PRUSS0_PRU0_DataRAM、 &pru0_datamem);
    unsigned int* pru0_datamem_int = (unsigned int*) pru0_datamem;
    printf ("地址 %d\n"、 (unsigned int) DDR);
    pru0_datamem_int[0] = (unsigned int) DDR;

    // 现在 加载  并   运行 PRU 代码  
    printf ("加载 PRU 代码 并 执行...\n");
    prussdrv_exec_program (0 /* PRU0 */、 PRU_code_file);

    // 等待   PRU  完成   代码执行
    printf ("正在等待  PRU  停止...\n");
    prussdrv_PRU_WAIT_EVENT (PRU_EVTOUT_0);
    printf ("PRU 暂停。\n");
    prussdrv_PRU_CLEAR_EVENT (PRU_EVTOUT_0、 PRU0_ARM_INTERRUPT);

    void* sharedMem;
    prussdrv_map_prumem (PRUSS0_SHARGE_DataRAM、 &sharedMem);
    unsigned int* sharedMem_int = (unsigned int*) sharedMem;
        // PRU 将将值存储在0x0001_2000处,即0x2000字节
        // 存储到  共享 存储器中、 因此  它的索引 为0x2000/4 = 0x800
    unsigned int res = sharedMem_int[0x800];

    // 读取  结果
    printf ("结果: %d\n"、 res);

    // 关闭  PRU
    prussdrv_PRU_disable (0);
    prussdrv_exit();

    munmap (DDR_mem、 0x0FFFFFFF);
    Close (mem_fd);

    返回 0;

ddrmemtest.p:

// PRU 加法 测试
// addend 1的地址存储在数据 RAM 地址0中,addend 2存储在1中,
// 结果   为 3

.origin 0
.entrypoint 加法

#define CONST_PRUCFG C4
#define CTPPR_0 0x22028
#define CTPPR_1 0x2202C

添加:
        // 启用 OCP 主 端口
        LBCO    R0、 CONST_PRUCFG、 4、 4
        CLR     R0、 R0、 4
        SBCO    R0、 CONST_PRUCFG、 4、 4

        // 将 C28设置  为0x0001_2000
        MOV     R0 、0x00000120
        MOV     R1、 CTPPR_0
        SBBO    R0、 R1、 0、 4

        MOV R0 、0x00100000
        MOV R1、 CTPPR_1
        SBBO R0、 R1、 0、 4

        LDI R0 、0x7
        //SBCO R0、 C31、0、 4

        // 将  值 地址读 入 R0
        //LBCO    R0、 C24、 0、 4

        // 现在 将  值 本身加载 到 R1中
        //LBBO    R1、 R0、 0、 4

        //   将结果存储 在 共享 存储器中
        SBCO    R1、 C28、 0、 4

        // 完成, 通知  主机 并 停止
        // 记住: R31  是特殊 的- 写入  它 会生成 中断
        //  要解码   写入的值:
        //  主机  正在等待  PRU_EVTOUT0
        //在 pruss_intc_mapping.h (第101行)中,PRU_EVTOUT0被映射到 CHANNEL2
        //在同一文件(第100行)中,CHANNEL2被映射到 PRU0_ARM_INTERRUPT
        //在同一个文件(第52行) 中,我们可以看到这是数字19
        //查看 PRU 参考指南(第7节),我们可以看到 int 19
        // 对应  于 pr1_PRU_mst_intr[3]_intr_req
        //根据 TRM 的第4.4.1.2.2节,触发中断位
        // R31的5必须为1,位3:0必须为值3 (因为
        //      中断方括号中的值)
        // 因此、 我们 写入  R31 (1 << 5) + 3 = 35
        MOV     R31.b0、 35
        停止