art Number: TDA2HG
Hello:
Description
visionSDK 3.05
Linux+RTOS
IPU2 overview
ssue description
in our case, when apps.out startup, the display will stop working after several seconds, and report " UTILS: MBX: Utils_mbxSendCmd(): Msg Alloc Failed (0)!!! "after debug, we found the display link stop working that block on
Vps_printf("DisplayLink_tsk instance=%d DisplayLink_tskRun Utils_tskRecvMsg mbx= %p rcvque= %p \n", pObj->displayInstId,&pTsk->mbx,&pTsk->mbx.recvQue); status = Utils_tskRecvMsg(pTsk, &pRunMsg, BSP_OSAL_WAIT_FOREVER); if (status != SYSTEM_LINK_STATUS_SOK) { Vps_printf("DisplayLink_tskRun error %d \n",runDone); break; }
we add kinds of trace into
Int32 Utils_quePut(Utils_QueHandle * handle, Ptr data, UInt32 timeout) { Int32 status = SYSTEM_LINK_STATUS_EFAIL;/* init status to error */ UInt32 cookie; volatile Bool doBreak = FALSE; UInt32 curSafetyMode = BspSafetyOsal_getSafetyMode(); BspSafetyOsal_setSafetyMode(BSP_SAFETY_OSAL_MODE_ASIL); do { /* * disable interrupts */ cookie = Hwi_disable(); if (handle->count < handle->maxElements) { /* * free space available in que */ /* MISRA.PTR.ARITH * MISRAC_2004_Rule_11.1 * MISRAC_WAIVER: * Pointer is accessed as an array. * Queue user always allocates queue of size maxElements, queue * will not be accessed out of bound. */ /* * insert element */ handle->queue[handle->curWr] = data; /* * increment put pointer */ handle->curWr = (handle->curWr + 1) % handle->maxElements; /* * increment count of number element in que */ handle->count++; /* * restore interrupts */ Hwi_restore(cookie); /* * mark status as success */ status = SYSTEM_LINK_STATUS_SOK; if (handle->flags & UTILS_QUE_FLAG_BLOCK_QUE_GET) { /* * blocking on que get enabled */ /* * post semaphore to unblock, blocked tasks */ Vps_printf("sempost to wakeup %p ",handle); BspOsal_semPost(handle->semRd); } /* * exit, with success */ doBreak = (Bool)TRUE; } else { /* * que is full */ /* * restore interrupts */ Hwi_restore(cookie); if (timeout == BSP_OSAL_NO_WAIT) { doBreak = (Bool)TRUE; /* non-blocking * function call, * exit with error */ } else if (handle->flags & UTILS_QUE_FLAG_BLOCK_QUE_PUT) { Bool semPendStatus; /* * blocking on que put enabled */ /* * take semaphore and block until timeout occurs or * semaphore is posted */ handle->blockedOnPut = (Bool)TRUE; semPendStatus = BspOsal_semWait(handle->semWr, timeout); handle->blockedOnPut = (Bool)FALSE; if (!semPendStatus) { /* UNREACH.GEN : MISRAC_2004_Rule_14.1 * Unreachable Code * MISRAC_WAIVER: * Value in the if condition is dependent on the * return of a function BspOsal_semWait and * this function is implemented when OS BIOS is * included/defined. */ handle->forceUnblockPut = (Bool)FALSE; doBreak = (Bool)TRUE; /* timeout * happend, exit * with error */ } else if (handle->forceUnblockPut) { handle->forceUnblockPut = (Bool)FALSE; doBreak = (Bool)TRUE; /* timeout * happend, exit * with error */ } else { doBreak = (Bool)FALSE; } /* * received semaphore, recheck for available space in the que */ } else { /* * blocking on que put disabled */ /* * exit with error */ doBreak = (Bool)TRUE; } } if ((Bool)TRUE == doBreak) { break; } } while (1); BspSafetyOsal_setSafetyMode(curSafetyMode); return status; } Int32 Utils_queGet(Utils_QueHandle * handle, Ptr * data, UInt32 minCount, UInt32 timeout) { Int32 status = SYSTEM_LINK_STATUS_EFAIL;/* init status to error */ UInt32 cookie; volatile Bool doBreak = (Bool)FALSE; UInt32 curSafetyMode = BspSafetyOsal_getSafetyMode(); BspSafetyOsal_setSafetyMode(BSP_SAFETY_OSAL_MODE_ASIL); /* * adjust minCount between 1 and handle->maxElements */ if (0U == minCount) { minCount = 1U; } if (minCount > handle->maxElements) { minCount = handle->maxElements; } do { /* * disable interrupts */ cookie = Hwi_disable(); if (handle->count >= minCount) { /* * data elements available in que is >= * minimum data elements requested by user */ /* * extract the element */ *data = handle->queue[handle->curRd]; Vps_printf("que handle %p que count=%d max %d curRd %d minCount %d",handle,handle->count,handle->maxElements,handle->curRd,minCount); /* * increment get pointer */ handle->curRd = (handle->curRd + 1) % handle->maxElements; /* * decrmeent number of elements in que */ handle->count--; /* * restore interrupts */ Hwi_restore(cookie); /* * set status as success */ status = SYSTEM_LINK_STATUS_SOK; if (handle->flags & UTILS_QUE_FLAG_BLOCK_QUE_PUT) { /* * blocking on que put enabled */ if ((handle->count + 1U) == handle->maxElements) { /* * post semaphore to unblock, blocked tasks */ BspOsal_semPost(handle->semWr); } } /* * exit with success */ doBreak = (Bool)TRUE; } else { Vps_printf("not enough que handle %p count=%d max %d curRd %d minCount %d",handle, handle->count,handle->maxElements,handle->curRd,minCount); /* * no elements or not enough element (minCount) in que to extract */ /* * restore interrupts */ Hwi_restore(cookie); if (timeout == BSP_OSAL_NO_WAIT) { doBreak = (Bool)TRUE; /* non-blocking * function call, * exit with error */ status = SYSTEM_LINK_STATUS_EFAIL; } else if (handle->flags & UTILS_QUE_FLAG_BLOCK_QUE_GET) { Bool semPendStatus; /* * blocking on que get enabled */ /* * take semaphore and block until timeout occurs or * semaphore is posted */ handle->blockedOnGet = (Bool)TRUE; Vps_printf("not enough que handle %p wait sem",handle); semPendStatus = BspOsal_semWait(handle->semRd, timeout); Vps_printf("not enough que handle %p wait sem ok",handle); handle->blockedOnGet = (Bool)FALSE; if (!semPendStatus) { /* UNREACH.GEN : MISRAC_2004_Rule_14.1 * Unreachable Code * MISRAC_WAIVER: * Value in the if condition is dependent on the * return of a function BspOsal_semWait and * this function is implemented when OS BIOS is * included/defined. */ handle->forceUnblockGet = (Bool)FALSE; doBreak = (Bool)TRUE; /* timeout * happened, exit * with error */ Vps_printf("not enough que handle %p ETIMEOUT ",handle); status = SYSTEM_LINK_STATUS_ETIMEOUT; } else if (handle->forceUnblockGet == (Bool)TRUE) { handle->forceUnblockGet = (Bool)FALSE; doBreak = (Bool)TRUE; /* timeout * happened, exit * with error */ Vps_printf("not enough que handle %p ETIMEOUT break",handle); status = SYSTEM_LINK_STATUS_ETIMEOUT; } else { doBreak = (Bool)FALSE; } /* * received semaphore, check que again */ } else { /* * blocking on que get disabled */ /* * exit with error */ Vps_printf("not enough que handle %p error ",handle); doBreak = (Bool)TRUE; } } if ((Bool)TRUE == doBreak) { break; } } while (1); BspSafetyOsal_setSafetyMode(curSafetyMode); return status; }
please check the trace in attchament serial-enable msg-15.log
line 112259 t0 112264
display Link is blocked to wait for the message
line 112392
previous link has send a new message to this message que and call semaphorepost(), but semaphorewait() is not be waken up.
actually, all link on IPU2 stop working.
Extra Testing 1:
we create two tasks to test the semaphore as following:
BspOsal_SemHandle TestSemHandle =NULL; BspOsal_TaskHandle Testtsk; #pragma DATA_ALIGN(gTest_tskStack, 32) #pragma DATA_SECTION(gTest_tskStack, ".bss:taskStackSection") UInt8 gTest_tskStack[DISPLAY_LINK_TSK_STACK_SIZE]; static Int16 FirstFlag = 0; Void Test_tskMain(UArg arg0, UArg arg1) { while(1){ Vps_printf("Test_tskMain wait post\n"); BspOsal_semWait(TestSemHandle,BSP_OSAL_WAIT_FOREVER); Vps_printf("TestSemHandle wait ok\n"); } } BspOsal_TaskHandle Testtsk1; #pragma DATA_ALIGN(gTest_tskStack1, 32) #pragma DATA_SECTION(gTest_tskStack1, ".bss:taskStackSection") UInt8 gTest_tskStack1[DISPLAY_LINK_TSK_STACK_SIZE]; Void Test_tskMain1(UArg arg0, UArg arg1) { while(1){ Vps_printf("Test_tskMain1 TestSemHandle post\n"); BspOsal_sleep(1000); Vps_printf("TestSemHandle post\n"); BspOsal_semPost(TestSemHandle); } }
we found, when it happened,
- this test semaphore also did not work that we can not see the trace"
- the test tasks also not run again(scheduled)
Extra Testing 2
- Move dup1 to DSP, issue remains.
- Comment out process code in EVE, issue remain
- Do not active pushpsld data flow, issue disappeared.
- Move the EVE code to DSP, issue remain