nxp-mcuxpresso / rpmsg-lite

RPMsg implementation for small MCUs
BSD 3-Clause "New" or "Revised" License
228 stars 73 forks source link

Address translation is required if the shared memory space is differently mapped by the two cores #9

Closed kpapak77 closed 3 years ago

kpapak77 commented 3 years ago

Hello,

I got a hardfault while implementing a ping-pong example between a CM33 (configured as the rpsmg-lite master) and a CM0+ (configured as the rpmsg-lite remote) core in a multicore chip. The hardfault happened on the CM0+, because the shared space memory is differently mapped by the two cores. The shared memory space starts from SH_MEM_MASTER_BASE_ADDRESS for the CM33 side and from SH_MEM_REMOTE_BASE_ADDRESS for the CM0+ side.

I added the following workaround to rpmsg-lite.c, implementing the shared memory address translation from master to remote addresses:

.........
    /* Process the received data from remote node */
    rpmsg_msg = (struct rpmsg_std_msg *)rpmsg_lite_dev->vq_ops->vq_rx(rpmsg_lite_dev->rvq, &len, &idx);

#if (REMOTE_PROCESSOR)
    if (rpmsg_msg != RL_NULL)
    {
        rpmsg_msg = (struct rpmsg_std_msg *) (SH_MEM_REMOTE_BASE_ADRRESS + (uint32_t) rpmsg_msg - SH_MEM_MASTER_BASE_ADDRESS);
    }
#endif

    while (rpmsg_msg != RL_NULL)
    {
        node = rpmsg_lite_get_endpoint_from_addr(rpmsg_lite_dev, rpmsg_msg->hdr.dst);
.........

#if (REMOTE_PROCESSOR)
    if (rpmsg_msg != RL_NULL)
    {
        rpmsg_msg = (struct rpmsg_std_msg *) (SH_MEM_REMOTE_BASE_ADRRESS + (uint32_t) rpmsg_msg - SH_MEM_MASTER_BASE_ADDRESS);
    }
#endif
    }

#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
    env_unlock_mutex(rpmsg_lite_dev->lock);
#endif
}

and

.....
    /* Get rpmsg buffer for sending message. */
    buffer = rpmsg_lite_dev->vq_ops->vq_tx_alloc(rpmsg_lite_dev->tvq, &buff_len, &idx);
#if (REMOTE_PROCESSOR)
    if (buffer != RL_NULL)
    {
        rpmsg_msg = (struct rpmsg_std_msg *) (SH_MEM_REMOTE_BASE_ADRRESS + (uint32_t) rpmsg_msg - SH_MEM_MASTER_BASE_ADDRESS);
    }
#endif
 .....
    while (buffer == RL_NULL)
    {
        env_sleep_msec(RL_MS_PER_INTERVAL);
        env_lock_mutex(rpmsg_lite_dev->lock);
        buffer = rpmsg_lite_dev->vq_ops->vq_tx_alloc(rpmsg_lite_dev->tvq, &buff_len, &idx);
#if (REMOTE_PROCESSOR)
        if (buffer != RL_NULL)
        {
            rpmsg_msg = (struct rpmsg_std_msg *) (SH_MEM_REMOTE_BASE_ADRRESS + (uint32_t) rpmsg_msg - SH_MEM_MASTER_BASE_ADDRESS);
        }
#endif
.......

Best Regards, Kostas

MichalPrincNXP commented 3 years ago

Hello @kpapak77 this address translation issue should be handled by platform_patova() and platform_vatopa() functions implementation in rpmsg_platform.c source file (like this)

BTW, what SoC are you using? Have you created/ported the platform layer (rpmsg_platform.[c|h]) for this device?

Regards Michal

kpapak77 commented 3 years ago

Hello Michal, I transferred my logic to platform_patova()/vatopa(). I am not using any known SoC. It is a system under development and I am investigating the rpmsg-lite framework.

Best Regards, Kostas