Пример #1
0
static void prvExerciseSemaphoreAPI( void )
{
SemaphoreHandle_t xSemaphore;
const UBaseType_t uxMaxCount = 5, uxInitialCount = 0;

	/* Most of the semaphore API is common to the queue API and is already being
	used.  This function uses a few semaphore functions that are unique to the
	RTOS objects, rather than generic and used by queues also.

	First create and use a counting semaphore. */
	xSemaphore = xSemaphoreCreateCounting( uxMaxCount, uxInitialCount );
	configASSERT( xSemaphore );

	/* Give the semaphore a couple of times and ensure the count is returned
	correctly. */
	xSemaphoreGive( xSemaphore );
	xSemaphoreGive( xSemaphore );
	configASSERT( uxSemaphoreGetCount( xSemaphore ) == 2 );
	vSemaphoreDelete( xSemaphore );

	/* Create a recursive mutex, and ensure the mutex holder and count are
	returned returned correctly. */
	xSemaphore = xSemaphoreCreateRecursiveMutex();
	configASSERT( uxSemaphoreGetCount( xSemaphore ) == 1 );
	configASSERT( xSemaphore );
	xSemaphoreTakeRecursive( xSemaphore, mainDONT_BLOCK );
	xSemaphoreTakeRecursive( xSemaphore, mainDONT_BLOCK );
	configASSERT( xSemaphoreGetMutexHolder( xSemaphore ) == xTaskGetCurrentTaskHandle() );
	configASSERT( xSemaphoreGetMutexHolder( xSemaphore ) == xTaskGetHandle( mainTASK_TO_DELETE_NAME ) );
	xSemaphoreGiveRecursive( xSemaphore );
	configASSERT( uxSemaphoreGetCount( xSemaphore ) == 0 );
	xSemaphoreGiveRecursive( xSemaphore );
	configASSERT( uxSemaphoreGetCount( xSemaphore ) == 1 );
	configASSERT( xSemaphoreGetMutexHolder( xSemaphore ) == NULL );
	vSemaphoreDelete( xSemaphore );

	/* Create a normal mutex, and sure the mutex holder and count are returned
	returned correctly. */
	xSemaphore = xSemaphoreCreateMutex();
	configASSERT( xSemaphore );
	xSemaphoreTake( xSemaphore, mainDONT_BLOCK );
	xSemaphoreTake( xSemaphore, mainDONT_BLOCK );
	configASSERT( uxSemaphoreGetCount( xSemaphore ) == 0 ); /* Not recursive so can only be 1. */
	configASSERT( xSemaphoreGetMutexHolder( xSemaphore ) == xTaskGetCurrentTaskHandle() );
	xSemaphoreGive( xSemaphore );
	configASSERT( uxSemaphoreGetCount( xSemaphore ) == 1 );
	configASSERT( xSemaphoreGetMutexHolder( xSemaphore ) == NULL );
	vSemaphoreDelete( xSemaphore );
}
/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_MutexLock
 * Description   : This function checks the mutex's status, if it is unlocked,
 * lock it and returns kStatus_OSA_Success, otherwise, timeout will be used for
 * wait. The parameter timeout indicates how long should wait in milliseconds.
 * Pass OSA_WAIT_FOREVER to wait indefinitely, pass 0 will return the value
 * kStatus_OSA_Timeout immediately if mutex is locked.
 * This function returns kStatus_OSA_Success if the mutex is obtained, returns
 * kStatus_OSA_Timeout if the mutex is not obtained within the specified
 * 'timeout', returns kStatus_OSA_Error if any errors occur during waiting.
 *
 *END**************************************************************************/
osa_status_t OSA_MutexLock(mutex_t *pMutex, uint32_t timeout)
{
    uint32_t timeoutTicks;

    assert(pMutex);

    /* If pMutex has been locked by current task, return error. */
    if (xSemaphoreGetMutexHolder(*pMutex) == xTaskGetCurrentTaskHandle())
    {
        return kStatus_OSA_Error;
    }

    /* Convert timeout from millisecond to tick. */
    if (timeout == OSA_WAIT_FOREVER)
    {
        timeoutTicks = portMAX_DELAY;
    }
    else
    {
        timeoutTicks = MSEC_TO_TICK(timeout);
    }

    if (xSemaphoreTake(*pMutex, timeoutTicks)==pdFALSE)
    {
        return kStatus_OSA_Timeout; /* timeout */
    }
    else
    {
        return kStatus_OSA_Success; /* semaphore taken */
    }
}
Пример #3
0
/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_MutexUnlock
 * Description   : This function is used to unlock a mutex.
 *
 *END**************************************************************************/
osaStatus_t OSA_MutexUnlock(osaMutexId_t mutexId)
{
#if osNumberOfMutexes  
  mutex_t mutex = (mutex_t)mutexId;
  if(mutexId == NULL)
  {
    return osaStatus_Error;
  }
  /* If pMutex is not locked by current task, return error. */
  if (xSemaphoreGetMutexHolder(mutex) != xTaskGetCurrentTaskHandle())
  {
    return osaStatus_Error;
  }
  
  if (xSemaphoreGive(mutex)==pdPASS)
  {
    return osaStatus_Success;
  }
  else
  {
    return osaStatus_Error;
  }
#else
  (void)mutexId;
  return osaStatus_Error;  
#endif  
}
/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_MutexUnlock
 * Description   : This function is used to unlock a mutex.
 *
 *END**************************************************************************/
osa_status_t OSA_MutexUnlock(mutex_t *pMutex)
{
    assert(pMutex);

    /* If pMutex is not locked by current task, return error. */
    if (xSemaphoreGetMutexHolder(*pMutex) != xTaskGetCurrentTaskHandle())
    {
        return kStatus_OSA_Error;
    }

    if (xSemaphoreGive(*pMutex)==pdPASS)
    {
        return kStatus_OSA_Success;
    }
    else
    {
        return kStatus_OSA_Error;
    }
}
Пример #5
0
/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_MutexLock
 * Description   : This function checks the mutex's status, if it is unlocked,
 * lock it and returns osaStatus_Success, otherwise, wait for the mutex.
 * This function returns osaStatus_Success if the mutex is obtained, returns
 * osaStatus_Error if any errors occur during waiting. If the mutex has been
 * locked, pass 0 as timeout will return osaStatus_Timeout immediately.
 *
 *END**************************************************************************/
osaStatus_t OSA_MutexLock(osaMutexId_t mutexId, uint32_t millisec)
{
#if osNumberOfMutexes    
    uint32_t timeoutTicks;
    mutex_t mutex = (mutex_t)mutexId;
    if(mutexId == NULL)
    {
     return osaStatus_Error;
    }
    /* If pMutex has been locked by current task, return error. */
    if (xSemaphoreGetMutexHolder(mutex) == xTaskGetCurrentTaskHandle())
    {
        return osaStatus_Error;
    }

    /* Convert timeout from millisecond to tick. */
    if (millisec == osaWaitForever_c)
    {
        timeoutTicks = portMAX_DELAY;
    }
    else
    {
        timeoutTicks = MSEC_TO_TICK(millisec);
    }

    if (xSemaphoreTake(mutex, timeoutTicks)==pdFALSE)
    {
        return osaStatus_Timeout; /* timeout */
    }
    else
    {
        return osaStatus_Success; /* semaphore taken */
    }
#else
    (void)mutexId;
    (void)millisec;  
    return osaStatus_Error;
#endif  
}
Пример #6
0
/**
 * @brief mmem_check checks the memory system for consistency
 */
void
mmem_check(void)
{
	if (mutex == NULL) {
		/* initalization not done,
		 * so data could be wrong
		 */
		return;
	}

	/* In ISR the mutex state could not be checked,
	 * therefore cancle when called from ISR.
	 */
	const uint16_t irq_nr = (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk);
	if (irq_nr > 0) {
		return;
	}

	/* mutex check is only needed, if the scheduler is running */
	if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) {
		/* do not check, if any function is in the critical region */
		if (xSemaphoreGetMutexHolder(mutex) != NULL) {
			return;
		}

		/* enter the critical section */
		if ( !xSemaphoreTake(mutex, portMAX_DELAY) ) {
			return;
		}
	} else {
		return;
	}


	if (avail_memory > MMEM_SIZE) {
		/* only last two entries needed.
		 * On first check was successfully and on
		 * second entry check fails
		 */
		print_stack_trace_part(2);
	}


	const struct mmem* const first = list_head(mmemlist);
	if (first != NULL) {
		/* only check the list, if there is an element */
		const struct mmem* m = first;
		for (; m->next != NULL; m = m->next) {
			if (m->real_size < m->size) {
				/* only last two entries needed.
				 * On first check was successfully and on
				 * second entry check fails
				 */
				print_stack_trace_part(2);
			}

			const size_t offset = m->next->ptr - m->ptr;
			if (offset != m->real_size) {
				/* only last two entries needed.
				 * On first check was successfully and on
				 * second entry check fails
				 */
				print_stack_trace_part(2);
			}

		}

		/* last element uses different checks */
		if (m->real_size < m->size) {
			/* only last two entries needed.
			 * On first check was successfully and on
			 * second entry check fails
			 */
			print_stack_trace_part(2);
		}

		const size_t offset = &memory[MMEM_SIZE - avail_memory] - (char*)m->ptr;
		if (offset != m->real_size) {
			/* only last two entries needed.
			 * On first check was successfully and on
			 * second entry check fails
			 */
			print_stack_trace_part(2);
		}
	}

	xSemaphoreGive(mutex);
}