示例#1
0
/*******************************************************************************
* Function Name: Cy_IPC_Sema_Status
****************************************************************************//**
*
* This function returns the status of the semaphore.
*
* \param semaNumber
*  The index of the semaphore to return status.
*
* \return Status of the operation
*     \retval CY_IPC_SEMA_STATUS_LOCKED:    The semaphore is in the set state.
*     \retval CY_IPC_SEMA_STATUS_UNLOCKED:  The semaphore is in the cleared state.
*     \retval CY_IPC_SEMA_OUT_OF_RANGE:     The semaphore number is not valid
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Sema_Status
*
*******************************************************************************/
cy_en_ipcsema_status_t Cy_IPC_Sema_Status(uint32_t semaNumber)
{
    cy_en_ipcsema_status_t   retStatus;
    uint32_t semaIndex;
    uint32_t semaMask;
    cy_stc_ipc_sema_t      *semaStruct;

    /* Get pointer to structure */
    semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);

    if (semaNumber < semaStruct->maxSema)
    {
        /* Get the index into the semaphore array and calculate the mask */
        semaIndex = semaNumber / CY_IPC_SEMA_PER_WORD;
        semaMask = (uint32_t)(1ul << (semaNumber - (semaIndex * CY_IPC_SEMA_PER_WORD) ));

        if((semaStruct->arrayPtr[semaIndex] & semaMask) != 0ul)
        {
            retStatus =  CY_IPC_SEMA_STATUS_LOCKED;
        }
        else
        {
            retStatus =  CY_IPC_SEMA_STATUS_UNLOCKED;
        }
    }
    else
    {
        retStatus = CY_IPC_SEMA_OUT_OF_RANGE;
    }
    return(retStatus);
}
示例#2
0
/*******************************************************************************
* Function Name: Cy_IPC_Sema_GetMaxSems
****************************************************************************//**
*
* This function returns the number of semaphores in the semaphores subsystem.
*
* \return
*     Returns the semaphores quantity.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Sema_GetMaxSems
*
*******************************************************************************/
uint32_t Cy_IPC_Sema_GetMaxSems(void)
{
    cy_stc_ipc_sema_t      *semaStruct;

    /* Get pointer to structure */
    semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);

    return (semaStruct->maxSema);
}
示例#3
0
/*******************************************************************************
* Function Name: Cy_IPC_Sema_Set
****************************************************************************//**
*
* This function tries to acquire a semaphore. If the
* semaphore is not available, this function returns immediately with
* CY_IPC_SEMA_LOCKED.
*
* It first acquires the IPC channel that is used for all the semaphores, sets
* the semaphore if it is cleared, then releases the IPC channel used for the
* semaphore.
*
* \param semaNumber
*  The semaphore number to acquire.
*
* \param preemptable
*  When this parameter is enabled the function can be preempted by another
*  task or other forms of context switching in an RTOS environment.
*
* \note
*  If <b>preemptable</b> is enabled (true), the user must ensure that there are
*  no deadlocks in the system, which can be caused by an interrupt that occurs
*  after the IPC channel is locked. Unless the user is ready to handle IPC
*  channel locks correctly at the application level, set <b>premptable</b> to
*  false.
*
* \return Status of the operation
*    \retval CY_IPC_SEMA_SUCCESS:      The semaphore was set successfully
*    \retval CY_IPC_SEMA_LOCKED:       The semaphore channel is busy or locked
*                              by another process
*    \retval CY_IPC_SEMA_NOT_ACQUIRED: Semaphore was already set
*    \retval CY_IPC_SEMA_OUT_OF_RANGE: The semaphore number is not valid
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Sema_Set
*
*******************************************************************************/
cy_en_ipcsema_status_t Cy_IPC_Sema_Set(uint32_t semaNumber, bool preemptable)
{
    uint32_t semaIndex;
    uint32_t semaMask;
    uint32_t interruptState = 0ul;

    cy_stc_ipc_sema_t      *semaStruct;
    cy_en_ipcsema_status_t  retStatus = CY_IPC_SEMA_LOCKED;

    /* Get pointer to structure */
    semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);

    if (semaNumber < semaStruct->maxSema)
    {
        semaIndex = semaNumber / CY_IPC_SEMA_PER_WORD;
        semaMask = (uint32_t)(1ul << (semaNumber - (semaIndex * CY_IPC_SEMA_PER_WORD) ));

        if (!preemptable)
        {
            interruptState = Cy_SysLib_EnterCriticalSection();
        }

        /* Check to make sure the IPC channel is released
           If so, check if specific channel can be locked. */
        if(CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire (cy_semaIpcStruct))
        {
            if((semaStruct->arrayPtr[semaIndex] & semaMask) == 0ul)
            {
                semaStruct->arrayPtr[semaIndex] |= semaMask;
                retStatus = CY_IPC_SEMA_SUCCESS;
            }
            else
            {
                retStatus = CY_IPC_SEMA_NOT_ACQUIRED;
            }

            /* Release, but do not trigger a release event */
            (void) Cy_IPC_Drv_LockRelease (cy_semaIpcStruct, CY_IPC_NO_NOTIFICATION);
        }

        if (!preemptable)
        {
            Cy_SysLib_ExitCriticalSection(interruptState);
        }
    }
    else
    {
        retStatus = CY_IPC_SEMA_OUT_OF_RANGE;
    }

    return(retStatus);
}
示例#4
0
/*******************************************************************************
* Function Name: Cy_IPC_Drv_ReadMsgWord
****************************************************************************//**
*
* This function is used to read a 32-bit word message through an IPC channel.
* This function assumes that the channel is locked (for a valid message).
* If the channel is not locked, the message is invalid.  The user must call
* Cy_IPC_Drv_Release() function after reading the message to release the
* IPC channel.
*
* \param base
* This parameter is a handle that represents the base address of the registers
* of the IPC channel.
* The parameter is generally returned from a call to the \ref
* Cy_IPC_Drv_GetIpcBaseAddress.
*
* \param message
*  A variable where the read data is copied.
*
* \return  Status of the operation
*   \retval CY_IPC_DRV_SUCCESS: The function executed successfully and the IPC
*                       was acquired.
*   \retval CY_IPC_DRV_ERROR:   The function encountered an error because the IPC
*                       channel was already in a released state, meaning the data
*                       may be invalid.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_ReadMsgWord
*
*******************************************************************************/
cy_en_ipcdrv_status_t  Cy_IPC_Drv_ReadMsgWord (IPC_STRUCT_Type const * base, uint32_t * message)
{
    cy_en_ipcdrv_status_t retStatus;

    CY_ASSERT_L1(NULL != message);

    if ( Cy_IPC_Drv_IsLockAcquired(base) )
    {
        /* The channel is locked; message is valid. */
        *message = Cy_IPC_Drv_ReadDataValue(base);

        retStatus = CY_IPC_DRV_SUCCESS;
    }
    else
    {
        /* The channel is not locked so channel is invalid. */
        retStatus = CY_IPC_DRV_ERROR;
    }
    return(retStatus);
}