/* HEX DUMP for BDs !!! Debug code only !!! */ mcpf_res_t report_PrintDump (McpU8 *pData, McpU32 datalen) { #ifdef _DEBUG McpS32 dbuflen=0; McpU32 j; char dbuf[50]; static const char hexdigits[16] = "0123456789ABCDEF"; for(j=0; j < datalen;) { /* Add a byte to the line*/ dbuf[dbuflen] = hexdigits[(pData[j] >> 4)&0x0f]; dbuf[dbuflen+1] = hexdigits[pData[j] & 0x0f]; dbuf[dbuflen+2] = ' '; dbuf[dbuflen+3] = '\0'; dbuflen += 3; j++; if((j % 16) == 0) { /* Dump a line every 16 hex digits*/ MCPF_OS_REPORT(("%04.4x %s\n", j-16, dbuf)); dbuflen = 0; } } /* Flush if something has left in the line*/ if(dbuflen) MCPF_OS_REPORT(("%04.4x %s\n", j & 0xfff0, dbuf)); #else MCP_UNUSED_PARAMETER(pData); MCP_UNUSED_PARAMETER(datalen); #endif return E_COMPLETE; }
/** * \fn que_Create * \brief Create a queue. * * Allocate and init a queue object. * * \note * \param hOs - Handle to Os Abstraction Layer * \param hReport - Handle to report module * \param uLimit - Maximum items to store in queue * \param uNodeHeaderOffset - Offset of NodeHeader field from the entry of the queued item. * \return Handle to the allocated queue * \sa que_Destroy */ handle_t que_Create (handle_t hMcpf, McpU32 uLimit, McpU32 uNodeHeaderOffset) { TQueue *pQue; if(!hMcpf) { MCPF_OS_REPORT (("Mcpf handler is NULL\n")); return NULL; } /* allocate queue module */ pQue = mcpf_mem_alloc (hMcpf, sizeof(TQueue)); if (!pQue) { MCPF_OS_REPORT (("Error allocating the Queue Module\n")); return NULL; } mcpf_mem_zero (hMcpf, pQue, sizeof(TQueue)); MCP_DL_LIST_InitializeHead (&pQue->tHead); /* Set the Queue parameters */ pQue->hMcpf = hMcpf; pQue->uLimit = uLimit; pQue->uNodeHeaderOffset = uNodeHeaderOffset; return (handle_t)pQue; }
void que_Print(handle_t hQue) { TQueue *pQue = (TQueue *)hQue; MCPF_OS_REPORT(("que_Print: Count=%u MaxCount=%u Limit=%u Overflow=%u NodeHeaderOffset=%u Next=0x%x Prev=0x%x\n", pQue->uCount, pQue->uMaxCount, pQue->uLimit, pQue->uOverflow, pQue->uNodeHeaderOffset, (McpU32)pQue->tHead.next, (McpU32)pQue->tHead.prev)); }
/** * \fn mcpf_getCurrentTime_inSec * \brief Return time in seconds * * This function will return the time in seconds from 1.1.1970. * * \note * \param hMcpf - MCPF handler. * \return The time in seconds from 1.1.1970. * \sa mcpf_getCurrentTime_inSec */ McpU32 mcpf_getCurrentTime_inSec(handle_t hMcpf) { if (!hMcpf) { MCPF_OS_REPORT(("Mcpf handler is NULL\n")); return 0; } return (os_get_current_time_inSec(((Tmcpf*)hMcpf)->hPla)); }
static McpS32 mcpf_getExpiryInMilliSecs(handle_t hMcpf, McpU32 uEexpiryAbsoluteTime) { if (!hMcpf) { MCPF_OS_REPORT(("Mcpf handler is NULL\n")); return 0; } return (uEexpiryAbsoluteTime - mcpf_getCurrentTime_InMilliSec(hMcpf)); }
/** * \fn txnQ_Create * \brief Create the module * * Allocate and clear the module's object. * * \note * \param hMcpf - Handle to Os framework * \return Handle of the allocated object, NULL if allocation failed * \sa txnQ_Destroy */ handle_t txnQ_Create (const handle_t hMcpf) { handle_t hTxnQ; TTxnQObj *pTxnQ; McpU32 i; hTxnQ = mcpf_mem_alloc(hMcpf, sizeof(TTxnQObj)); if (hTxnQ == NULL) return NULL; pTxnQ = (TTxnQObj *)hTxnQ; mcpf_mem_zero(hMcpf, hTxnQ, sizeof(TTxnQObj)); pTxnQ->hMcpf = hMcpf; pTxnQ->pCurrTxn = NULL; pTxnQ->uMinFuncId = TXN_MAX_FUNCTIONS; /* Start at maximum and save minimal value in txnQ_Open */ pTxnQ->uMaxFuncId = 0; /* Start at minimum and save maximal value in txnQ_Open */ pTxnQ->bProtectTxnDone = MCP_TRUE; for (i = 0; i < TXN_MAX_FUNCTIONS; i++) { pTxnQ->aFuncInfo[i].eState = FUNC_STATE_NONE; pTxnQ->aFuncInfo[i].uNumPrios = 0; pTxnQ->aFuncInfo[i].pSingleStep = NULL; pTxnQ->aFuncInfo[i].fTxnQueueDoneCb = NULL; pTxnQ->aFuncInfo[i].hCbHandle = NULL; } /* Create the Bus-Driver module */ pTxnQ->hBusDrv = busDrv_Create (hMcpf); if (pTxnQ->hBusDrv == NULL) { MCPF_OS_REPORT(("%s: Error - failed to create BusDrv\n", __FUNCTION__)); txnQ_Destroy (hTxnQ); return NULL; } return pTxnQ; }
/** * \fn mcpf_SLL_Create * \brief Create a sorted linked list * * This function creates a sorted linked list * * \note * \param hMcpf - MCPF handler. * \param uLimit - max list length. * \param uNodeHeaderOffset - Offset of node's header field in stored structure. * \param uSortByFeildOffset - Offset of the field to sort by, in stored structure. * \param tSortType - sort type, UP or DOWN. * \return List handler. * \sa mcpf_SLL_Create */ handle_t mcpf_SLL_Create (handle_t hMcpf, McpU32 uLimit, McpU32 uNodeHeaderOffset, McpU32 uSortByFeildOffset, TSllSortType tSortType) { mcpf_SLL *pSortedList; if (!hMcpf) { MCPF_OS_REPORT(("Mcpf handler is NULL\n")); return NULL; } /* Allocate memory for the sorted Linked List */ pSortedList = mcpf_mem_alloc(hMcpf, sizeof(mcpf_SLL)); if (NULL == pSortedList) { MCPF_REPORT_ERROR(pSortedList->hMcpf, MCPF_MODULE_LOG, ("mcpf_mem_alloc returned NULL\n")); return NULL; } /* Initialize the memory block to zero */ mcpf_mem_zero(hMcpf, pSortedList, sizeof(mcpf_SLL)); /* Initialize the list header */ MCP_DL_LIST_InitializeHead (&pSortedList->tHead); /* Set the List paramaters */ pSortedList->hMcpf = hMcpf; pSortedList->tSortType = tSortType; pSortedList->uSortByFieldOffset = (McpU16)uSortByFeildOffset; pSortedList->uNodeHeaderOffset = (McpU16)uNodeHeaderOffset; pSortedList->uOverflow = 0; pSortedList->uLimit = (McpU16)uLimit; pSortedList->uCount = 0; return (handle_t)pSortedList; }
/** * \fn mcpf_timer_start * \brief Timer Start * * This function will put the 'timer start' request in a sorted list, * and will start an OS timer when necessary. * * \note * \param hMcpf - MCPF handler. * \param uExpiryTime - Requested expiry time in milliseconds (duration time). * \param eTaskId - Source task id. * \param *fCb - Timer expiration Cb. * \param hCaller - Cb's handler. * \return Pointer to the timer handler. * \sa mcpf_timer_start */ handle_t mcpf_timer_start (handle_t hMcpf, McpU32 uExpiryTime, EmcpTaskId eTaskId, mcpf_timer_cb fCb, handle_t hCaller) { Tmcpf *pMcpf; TMcpfTimer *pMcpfTimer, *pFirstTimer; McpU32 uCurrentExpiryTime = 0; McpU32 uListCount; if (!hMcpf) { MCPF_OS_REPORT(("Mcpf handler is NULL\n")); return NULL; } pMcpf = (Tmcpf*)hMcpf; /* Allocate Timer */ pMcpfTimer = (TMcpfTimer*)mcpf_mem_alloc_from_pool(pMcpf, pMcpf->hTimerPool); if(NULL == pMcpfTimer) { MCPF_REPORT_ERROR(hMcpf, MCPF_MODULE_LOG, ("mcpf_timer_start, No memory available in TimerPool\n")); return NULL; } MCPF_ENTER_CRIT_SEC(hMcpf); /* Init Timer Fields */ pMcpfTimer->uEexpiryTime = mcpf_getAbsoluteTime(hMcpf, uExpiryTime); pMcpfTimer->eSource = eTaskId; pMcpfTimer->tCbData.fCb = fCb ; pMcpfTimer->tCbData.hCaller = hCaller; pMcpfTimer->eState = TMR_STATE_ACTIVE; /* if list is not empty get current expiry time(Absolute) */ uListCount = mcpf_SLL_Size(pMcpf->hTimerList); if(uListCount != 0) { /* Get the first timer on the list*/ pFirstTimer = (TMcpfTimer*) mcpf_SLL_Get(pMcpf->hTimerList); uCurrentExpiryTime = pFirstTimer->uEexpiryTime; } /* Insert new Timer to the list */ if (RES_ERROR == mcpf_SLL_Insert(pMcpf->hTimerList, pMcpfTimer)) { MCPF_EXIT_CRIT_SEC(hMcpf); mcpf_mem_free_from_pool(hMcpf, pMcpfTimer); MCPF_REPORT_ERROR(hMcpf, MCPF_MODULE_LOG, ("mcpf_SLL_Insert Failed\n")); return NULL; } /* If list was empty before insertion (first timer on the list) --> Start the OS Timer */ if (uListCount == 0) { pMcpf->uTimerId = os_timer_start(pMcpf->hPla, mcpf_timer_callback, hMcpf, uExpiryTime); } else if ( uCurrentExpiryTime > (pMcpfTimer->uEexpiryTime)) { /* The previous first timer on the list is having greater exp time than the new one. Stop this timer and start the new one.*/ /* Stop the current timer */ if (MCP_FALSE == os_timer_stop(pMcpf->hPla, pMcpf->uTimerId)) { MCPF_EXIT_CRIT_SEC(hMcpf); mcpf_mem_free_from_pool(hMcpf, pMcpfTimer); MCPF_REPORT_ERROR(hMcpf, MCPF_MODULE_LOG, ("os_timer_stop Failed\n")); return NULL; } /* Start the new timer */ pMcpf->uTimerId = os_timer_start(pMcpf->hPla, mcpf_timer_callback, hMcpf, uExpiryTime); } MCPF_EXIT_CRIT_SEC(hMcpf); return ((handle_t)pMcpfTimer); }
/** * \fn mcpf_timer_callback * \brief General Timer Callback * * This function will be called upon expiry time interrupt. * * \note * \param hMcpf - MCPF handler. * \param uTimerId - The timer Id of the expired timer * \return None * \sa mcpf_timer_callback */ static void mcpf_timer_callback(handle_t hMcpf, McpUint uTimerId) { Tmcpf *pMcpf; TMcpfTimer *pMcpfTimer; McpU32 uExpiryTime; TMcpfTimer *pExpiredTimersQ[10]; McpU16 i, counter = 0; if (!hMcpf) { MCPF_OS_REPORT(("Mcpf handler is NULL\n")); return; } pMcpf = (Tmcpf*)hMcpf; MCPF_ENTER_CRIT_SEC(hMcpf); /* Check if expired timer is already handled, and now another OS timer was alreay started */ if(uTimerId != pMcpf->uTimerId) { MCPF_EXIT_CRIT_SEC(hMcpf); return; } do { pMcpfTimer = (TMcpfTimer*)mcpf_SLL_Retrieve(pMcpf->hTimerList); /* This is added to handle race condition between this function and the 'mcpf_timer_stop()' function. This condition can only be valid in the first iteration of the loop. The timer was stopped before the expiration Cb is handled, and the timer is already been removed from the timer's list. */ if(pMcpfTimer == NULL) { MCPF_EXIT_CRIT_SEC(hMcpf); return; } /* Store a copy of the exp time of retrieved timer */ uExpiryTime = pMcpfTimer->uEexpiryTime; pMcpfTimer->eState = TMR_STATE_EXPIRED; /* Save all expired timers, in order to send an experation message outside the critical section. */ pExpiredTimersQ[counter] = pMcpfTimer; counter++; /* Get the Next Timer from the List */ pMcpfTimer = mcpf_SLL_Get(pMcpf->hTimerList); } while( (pMcpfTimer) && (uExpiryTime == pMcpfTimer->uEexpiryTime) ); if(pMcpfTimer) { /* Start the next timer request */ uExpiryTime = mcpf_getExpiryInMilliSecs(hMcpf, pMcpfTimer->uEexpiryTime); pMcpf->uTimerId = os_timer_start(pMcpf->hPla, mcpf_timer_callback, hMcpf, uExpiryTime); } MCPF_EXIT_CRIT_SEC(hMcpf); for(i = 0; i < counter; i++) { pMcpfTimer = pExpiredTimersQ[i]; mcpf_SendMsg(hMcpf, pMcpfTimer->eSource, /* Destination task is the task that started the timer */ 0, /* Timer's Queue Id is alway 0 */ pMcpfTimer->eSource, /* Source task is the task that started the timer */ 0, /* Since in timer queue there will be only message about the timer expiration */ 0, /* opcode */ sizeof(TMcpfTimer), /* Length of the data */ 0, /* User Defined is NOT USED*/ pMcpfTimer); /* The data is the timer structure */ } }
/** * \fn mcpf_timer_stop * \brief Timer Stop * * This function will remove the timer from the list * and will stop the OS timer when necessary. * * \note * \param hMcpf - MCPF handler. * \param hTimer - Timer's handler. * \return Result of operation: OK or ERROR * \sa mcpf_timer_stop */ EMcpfRes mcpf_timer_stop (handle_t hMcpf, handle_t hTimer) { Tmcpf *pMcpf; TMcpfTimer *pMcpfTimer; McpS32 uExpiryTime; TMcpfTimer *pExpiredTimersQ[10]; McpU16 i, counter = 0; McpBool bIsOnlyTimer = MCP_FALSE; McpBool bIsFirstTimer = MCP_FALSE; EMcpfRes eRetVal = RES_OK; if (!hMcpf) { MCPF_OS_REPORT(("Mcpf handler is NULL\n")); return RES_ERROR; } pMcpf = (Tmcpf*)hMcpf; pMcpfTimer = (TMcpfTimer *)hTimer; MCPF_ENTER_CRIT_SEC(hMcpf); /* hTimer has already expired */ if (pMcpfTimer->eState == TMR_STATE_EXPIRED ) { pMcpfTimer->eState = TMR_STATE_DELETED; MCPF_EXIT_CRIT_SEC(hMcpf); MCPF_REPORT_INFORMATION(hMcpf, MCPF_MODULE_LOG, ("mcpf_timer_stop: hTimer has already expired")); return RES_OK; } /* If it is the first/only timer on the list --> need to stop the OS timer */ if(mcpf_SLL_Size(pMcpf->hTimerList) == 1) { bIsOnlyTimer = MCP_TRUE; } else if(mcpf_SLL_Get(pMcpf->hTimerList) == pMcpfTimer) bIsFirstTimer = MCP_TRUE; /* Remove Timer From the List */ if ( (eRetVal = mcpf_SLL_Remove(pMcpf->hTimerList,hTimer)) == RES_OK) { /* If it is the only timer on the list --> need to stop the OS timer */ if(bIsOnlyTimer) { if (MCP_TRUE == os_timer_stop(pMcpf->hPla, pMcpf->uTimerId)) eRetVal = RES_COMPLETE; else eRetVal = RES_ERROR; pMcpf->uTimerId = 0; } else if(bIsFirstTimer) /* It is the First Timer on the list */ { if (MCP_TRUE == os_timer_stop(pMcpf->hPla, pMcpf->uTimerId)) { pMcpf->uTimerId = 0; pMcpfTimer = mcpf_SLL_Get(pMcpf->hTimerList); do { /* Get actual exp time in msecs from absolute exp time in the list */ uExpiryTime = mcpf_getExpiryInMilliSecs(hMcpf,pMcpfTimer->uEexpiryTime); if(uExpiryTime <= 0) { pExpiredTimersQ[counter] = mcpf_SLL_Retrieve(pMcpf->hTimerList); counter++; } else { pMcpf->uTimerId = os_timer_start(pMcpf->hPla, mcpf_timer_callback, hMcpf, (McpU32)uExpiryTime); break; } pMcpfTimer = mcpf_SLL_Get(pMcpf->hTimerList); } while (pMcpfTimer); } else { pMcpf->uTimerId = 0; eRetVal = RES_ERROR; } } } MCPF_EXIT_CRIT_SEC(hMcpf); for(i = 0; i < counter; i++) { pMcpfTimer = pExpiredTimersQ[i]; mcpf_SendMsg(hMcpf, pMcpfTimer->eSource, /* Destination task is the task that started the timer */ 0, /* Timer's Queue Id is alway 0 */ pMcpfTimer->eSource, /* Source task is the task that started the timer */ 0, /* Since in timer queue there will be only message about the timer expiration */ 0, /* opcode */ sizeof(TMcpfTimer), /* Length of the data */ 0, /* User Defined is NOT USED*/ pMcpfTimer); /* The data is the timer structure */ } /* Free Timer */ if (RES_ERROR == mcpf_mem_free_from_pool(pMcpf, (McpU8*) hTimer)) return RES_ERROR; return eRetVal; }