This is a followup to the discussion here:
https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1500812/am6422-ipc-delay
Hello,
Regarding the use of rpmsg, there are numerous interrupt disable/enable operations in the library functions. These operations are currently affecting other interrupts in my real-time kernel. Are these interrupt disable/enable operations necessary? Why are they implemented this way?RPMessage_LocalMsg *RPMessage_allocEndPtMsg(uint32_t remoteCoreId)
{
RPMessage_Core *coreObj = &gIpcRpmsgCtrl.coreObj[remoteCoreId];
RPMessage_LocalMsg *pMsg;
uint32_t oldIntState;
oldIntState = HwiP_disable();
pMsg = (RPMessage_LocalMsg*)RPMessage_queueGet(&coreObj->freeQ);
if(pMsg == NULL)
{
coreObj->freeQAllocPending = 1;
}
else
{
coreObj->freeQAllocPending = 0;
}
HwiP_restore(oldIntState);
return pMsg;
}
uint32_t RPMessage_freeEndPtMsg(uint16_t remoteCoreId, RPMessage_LocalMsg *pMsg)
{
RPMessage_Core *coreObj = &gIpcRpmsgCtrl.coreObj[remoteCoreId];
uint32_t oldIntState, isAllocPending;
oldIntState = HwiP_disable();
isAllocPending = coreObj->freeQAllocPending;
RPMessage_queuePut(&coreObj->freeQ, &pMsg->elem);
HwiP_restore(oldIntState);
return isAllocPending;
}
void RPMessage_putEndPtMsg(RPMessage_Struct *obj, RPMessage_LocalMsg *pMsg)
{
uint32_t oldIntState;
oldIntState = HwiP_disable();
RPMessage_queuePut(&obj->endPtQ, &pMsg->elem);
HwiP_restore(oldIntState);
SemaphoreP_post(&obj->newEndPtMsgSem);
}
int32_t RPMessage_getEndPtMsg(RPMessage_Struct *obj, RPMessage_LocalMsg **pMsg, uint32_t timeout)
{
uint32_t oldIntState, done;
int32_t status = SystemP_TIMEOUT;
done = 0;
do {
oldIntState = HwiP_disable();
*pMsg = (RPMessage_LocalMsg*)RPMessage_queueGet(&obj->endPtQ);
HwiP_restore(oldIntState);
if(*pMsg==NULL)
{
status = SemaphoreP_pend(&obj->newEndPtMsgSem, timeout);
if(status == SystemP_TIMEOUT)
{
done = 1;
}
if(status == SystemP_SUCCESS && obj->doRecvUnblock)
{
status = SystemP_TIMEOUT;
done = 1;
}
}
else
{
status = SystemP_SUCCESS;
done = 1;
}
} while( ! done );
return status;
}
int32_t RPMessage_vringGetEmptyTxBuf(uint16_t remoteCoreId, uint16_t *vringBufId, uint32_t timeout)
{
RPMessage_Core *coreObj = &gIpcRpmsgCtrl.coreObj[remoteCoreId];
RPMessage_Vring *vringObj = &coreObj->vringTxObj;
uint32_t oldIntState;
uint16_t head;
int32_t status = SystemP_FAILURE;
uint32_t done = 0;
oldIntState = HwiP_disable();
do
{
/* There's nothing available */
if (vringObj->lastAvailIdx == vringObj->avail->idx)
{
/* We need to know about added buffers */
vringObj->used->flags &= (uint16_t)~VRING_USED_F_NO_NOTIFY;
HwiP_restore(oldIntState);
status = SemaphoreP_pend(&coreObj->newEmptyVringBufSem, timeout);
if(status==SystemP_TIMEOUT)
{
done = 1;
}
oldIntState = HwiP_disable();
}
else
{
head = vringObj->avail->ring[vringObj->lastAvailIdx % vringObj->vringNumBuf];
vringObj->lastAvailIdx++;
*vringBufId = head;
done = 1;
status = SystemP_SUCCESS;
}
} while( ! done );
HwiP_restore(oldIntState);
return status;
}
void RPMessage_vringPutFullTxBuf(uint16_t remoteCoreId, uint16_t vringBufId, uint16_t dataLen)
{
RPMessage_Core *coreObj = &gIpcRpmsgCtrl.coreObj[remoteCoreId];
RPMessage_Vring *vringObj = &coreObj->vringTxObj;
struct vring_used_elem *used;
uint32_t oldIntState;
uint32_t txMsgValue = RPMESSAGE_MSG_VRING_NEW_FULL;
if(RPMessage_isLinuxCore(remoteCoreId))
{
/* for linux we need to send the TX VRING ID in the mailbox message */
txMsgValue = RPMESSAGE_LINUX_TX_VRING_ID;
}
oldIntState = HwiP_disable();
used = &vringObj->used->ring[vringObj->used->idx % vringObj->vringNumBuf];
used->id = vringBufId;
used->len = dataLen;
vringObj->used->idx++;
#if defined(__aarch64__) || defined(__arm__)
__asm__ __volatile__ ( "dsb sy" "\n\t": : : "memory");
__asm__ __volatile__ ( "isb sy" "\n\t": : : "memory");
#endif
#if defined(_TMS320C6X)
_mfence();
_mfence();
#endif
HwiP_restore(oldIntState);
IpcNotify_sendMsg(remoteCoreId,
IPC_NOTIFY_CLIENT_ID_RPMSG,
txMsgValue,
1 /* wait for message to be posted */
);
}
void RPMessage_vringCheckEmptyTxBuf(uint16_t remoteCoreId)
{
RPMessage_Core *coreObj = &gIpcRpmsgCtrl.coreObj[remoteCoreId];
RPMessage_Vring *vringObj = &coreObj->vringTxObj;
uint32_t isNewEmptyBuf = 1;
uint32_t oldIntState;
oldIntState = HwiP_disable();
if (vringObj->lastAvailIdx == vringObj->avail->idx)
{
isNewEmptyBuf = 0;
}
HwiP_restore(oldIntState);
if(isNewEmptyBuf)
{
SemaphoreP_post(&coreObj->newEmptyVringBufSem);
}
}