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.

AM4379: ARM加载PRU RPMsg测试程序出错

Part Number: AM4379


依据pru-icss-5.1.0 SDK内例程,创建了一个pru CCS测试工程,主要功能如下

void main(void)
{
    struct pru_rpmsg_transport transport;
    uint16_t src, dst, len;
    volatile uint8_t *status;
    int delay_cnt;

    /* Allow OCP master port access by the PRU so the PRU can read external memories */
    CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;

    /* Clear the status of the PRU-ICSS system event that the ARM will use to 'kick' us */
    CT_INTC.SICR_bit.STATUS_CLR_INDEX = FROM_ARM_HOST;

    /* Make sure the Linux drivers are ready for RPMsg communication */
    status = &resourceTable.rpmsg_vdev.status;
    while (!(*status & VIRTIO_CONFIG_S_DRIVER_OK));

    /* Initialize the RPMsg transport structure */
    pru_rpmsg_init(&transport, &resourceTable.rpmsg_vring0, &resourceTable.rpmsg_vring1, TO_ARM_HOST, FROM_ARM_HOST);

    /* Create the RPMsg channel between the PRU and ARM user space using the transport structure. */
    while (pru_rpmsg_channel(RPMSG_NS_CREATE, &transport, CHAN_NAME, CHAN_DESC, CHAN_PORT) != PRU_RPMSG_SUCCESS);

    gpio_dir_set_addr = GPIO3_BASE_ADDR + GPIO_SETDATAOUT_OFFSET;
    gpio_dir_clr_addr = GPIO3_BASE_ADDR + GPIO_CLRDATAOUT_OFFSET;

    gpio_pul_set_addr = GPIO2_BASE_ADDR + GPIO_SETDATAOUT_OFFSET;
    gpio_pul_clr_addr = GPIO2_BASE_ADDR + GPIO_CLRDATAOUT_OFFSET;

    /* pulse motor control signal initialization */
    /* set pulse motor reverse rotation & power up PUL */
    *(uint32_t*)gpio_dir_set_addr |= MOTOR_CTL_DIR;

    *(uint32_t*)gpio_pul_set_addr |= MOTOR_CTL_PUL;

    /* if default pul_freq = 20Khz , pul_low_delay_cnt = DEF_DELAY_CNT / DELAY_CALIB_FACTOR - PUL_HIGH_DELAY_CNT*/
    pul_low_delay_cnt = DEF_DELAY_CNT;

    while (1) {
        /* Pulse signal control of pulse motor */
        if(pul_low_delay_cnt == DEF_DELAY_CNT) {

            /* Set MOTOR_CTL_PUL to low level*/
            *(uint32_t*)gpio_pul_clr_addr |= MOTOR_CTL_PUL;

        } else {

            /* Set MOTOR_CTL_PUL to low level*/
            *(uint32_t*)gpio_pul_clr_addr |= MOTOR_CTL_PUL;

            /* delay cnt form ARM set pulse motor frequency */
            delay_cnt = pul_low_delay_cnt;
            while (delay_cnt--);

            /* Set MOTOR_CTL_PUL to high level*/
            *(uint32_t*)gpio_pul_set_addr |= MOTOR_CTL_PUL;

            /* The minimum pulse width is 500ns */
            delay_cnt = PUL_HIGH_DELAY_CNT;
            while (delay_cnt--);

        }

        /* Check bit 30 of register R31 to see if the ARM has kicked us */
        if (__R31 & HOST_INT) {
            /* Clear the event status */
            CT_INTC.SICR_bit.STATUS_CLR_INDEX = FROM_ARM_HOST;

            /* Receive all available messages, multiple messages can be sent per kick */
            while (pru_rpmsg_receive(&transport, &src, &dst, payload, &len) == PRU_RPMSG_SUCCESS) {
                rpmsg_response(len);
            }
        }
    }
}


/* rpmsg response function, make corresponding actions according to the received MSG */
void rpmsg_response(uint16_t len)
{
    uint32_t rpmsg_pul_freq = 0;

    if (payload[0] == 'F' && payload[1] == 'W' && payload[2] == 'D') {
        /* if rpmsg = "FWD", set pulse motor forward rotation */
        *(uint32_t*)gpio_dir_clr_addr |= MOTOR_CTL_DIR;
    } else if (payload[0] == 'R' && payload[1] == 'E' && payload[2] == 'V') {
        /* if rpmsg = "REV", set pulse motor reverse rotation */
        *(uint32_t*)gpio_dir_set_addr |= MOTOR_CTL_DIR;
    } else {
        /* get pulse frequency(Hz) */
        rpmsg_pul_freq = atoi((const char *)payload);

        /* Convert pul low level time count value */
        if (rpmsg_pul_freq > PUL_MOTOR_MIN_FREQ && rpmsg_pul_freq <= PUL_MOTOR_MAX_FREQ)
            pul_low_delay_cnt = (int)(PRU_FREQ * 1.0 / rpmsg_pul_freq / DELAY_CALIB_FACTOR - PUL_HIGH_DELAY_CNT);
        else if(rpmsg_pul_freq == PUL_MOTOR_MIN_FREQ)
            pul_low_delay_cnt = DEF_DELAY_CNT;
    }
}

将编译生成的.out文件在ARM加载时报错。

当我如下删减代码后,可以正常加载。

while (pru_rpmsg_receive(&transport, &src, &dst, payload, &len) == PRU_RPMSG_SUCCESS) {
//rpmsg_response(len);
}

这看起来像是内存分配问题,0x1368为工程CMD文件PRU_IMEM段使用大小。我不太清楚需要修改那些地方去解决这个问题,在工程resource_table文件中没有找到有相关定义。