mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-19 17:48:33 -04:00
Counting semaphore demo added.
This commit is contained in:
parent
a8eabeabbb
commit
d69d2df8d6
11 changed files with 581 additions and 202 deletions
|
@ -116,6 +116,10 @@
|
|||
#define configUSE_MUTEXES 0
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_COUNTING_SEMAPHORES
|
||||
#define configUSE_COUNTING_SEMAPHORES 0
|
||||
#endif
|
||||
|
||||
#if ( configUSE_MUTEXES == 1 )
|
||||
/* xTaskGetCurrentTaskHandle is used by the priority inheritance mechanism
|
||||
within the mutex implementation so must be available if mutexes are used. */
|
||||
|
|
|
@ -1175,10 +1175,11 @@ signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQue
|
|||
signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait );
|
||||
|
||||
/*
|
||||
* For internal use only. Use xSemaphoreCreateMutex() instead of calling
|
||||
* this function directly.
|
||||
* For internal use only. Use xSemaphoreCreateMutex() or
|
||||
* xSemaphoreCreateCounting() instead of calling these functions directly.
|
||||
*/
|
||||
xQueueHandle xQueueCreateMutex( void );
|
||||
xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -34,11 +34,11 @@
|
|||
***************************************************************************
|
||||
*/
|
||||
|
||||
#include "queue.h"
|
||||
|
||||
#ifndef SEMAPHORE_H
|
||||
#define SEMAPHORE_H
|
||||
|
||||
#include "queue.h"
|
||||
|
||||
typedef xQueueHandle xSemaphoreHandle;
|
||||
|
||||
#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned portCHAR ) 1 )
|
||||
|
@ -84,12 +84,12 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
#define vSemaphoreCreateBinary( xSemaphore ) { \
|
||||
xSemaphore = xQueueCreate( ( unsigned portCHAR ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \
|
||||
if( xSemaphore != NULL ) \
|
||||
{ \
|
||||
xSemaphoreGive( xSemaphore ); \
|
||||
} \
|
||||
#define vSemaphoreCreateBinary( xSemaphore ) { \
|
||||
xSemaphore = xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \
|
||||
if( xSemaphore != NULL ) \
|
||||
{ \
|
||||
xSemaphoreGive( xSemaphore ); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -341,6 +341,66 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||
*/
|
||||
#define xSemaphoreCreateMutex() xQueueCreateMutex()
|
||||
|
||||
/**
|
||||
* semphr. h
|
||||
* <pre>vSemaphoreCreateCounting( xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE uxMaxCount )</pre>
|
||||
*
|
||||
* <i>Macro</i> that creates a counting semaphore by using the existing
|
||||
* queue mechanism. The queue length is used as the maximum count. The data
|
||||
* size is 0 as we don't want to actually store any data - we just want to
|
||||
* know if the queue is empty or full.
|
||||
*
|
||||
* Counting semaphores are typically used for two things:
|
||||
*
|
||||
* 1) Counting events.
|
||||
*
|
||||
* In this usage scenario an event handler will 'give' a semphore each time
|
||||
* an event occurs (incrementing the semaphore count value), and a handler
|
||||
* task will 'take' a semaphore each time it processes an event
|
||||
* (decrementing the semaphore count value). The count value is therefore
|
||||
* the difference between the number of events that have occurred and the
|
||||
* number that have been processed. In this case it is desirable for the
|
||||
* initial count value to be zero.
|
||||
*
|
||||
* 2) Resource management.
|
||||
*
|
||||
* In this usage scenario the count value indicates the number of resources
|
||||
* available. To obtain control of a resource a task must first obtain a
|
||||
* semphoare - decrementing the semaphore count value. When the count value
|
||||
* reaches zero there are no free resources. When a task finishes with the
|
||||
* resource it 'gives' the semahore back - incrementing the semaphore count
|
||||
* value. In this case it is desirable for the initial count value to be
|
||||
* equal to the maximum count value, indicating that all resources are free.
|
||||
*
|
||||
* @param uxMaxCount The maximum count value that can be reached. When the
|
||||
* semaphore reaches this value it can nolonger be 'given'.
|
||||
* @param uxInitialCount
|
||||
*
|
||||
* @return Handle to the created semaphore. Should be of type xSemaphoreHandle.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
xSemaphoreHandle xSemaphore;
|
||||
|
||||
void vATask( void * pvParameters )
|
||||
{
|
||||
xSemaphoreHandle xSemaphore = NULL;
|
||||
|
||||
// Semaphore cannot be used before a call to vSemaphoreCreateCounting().
|
||||
// This is a macro so pass the variable in directly.
|
||||
vSemaphoreCreateBinary( xSemaphore, );
|
||||
|
||||
if( xSemaphore != NULL )
|
||||
{
|
||||
// The semaphore was created successfully.
|
||||
// The semaphore can now be used.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
#define xSemaphoreCreateCounting( uxCountValue, uxInitialCount ) xQueueCreateCountingSemaphore( uxCountValue, uxInitialCount )
|
||||
|
||||
#endif /* SEMAPHORE_H */
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ portSTACK_TYPE *pxOriginalTOS;
|
|||
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa; /* R14 */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x00000000; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||
pxTopOfStack--;
|
||||
|
|
|
@ -34,49 +34,6 @@
|
|||
***************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
Changes from V1.01
|
||||
|
||||
+ More use of 8bit data types.
|
||||
+ Function name prefixes changed where the data type returned has changed.
|
||||
|
||||
Changed from V2.0.0
|
||||
|
||||
+ Added the queue locking mechanism and make more use of the scheduler
|
||||
suspension feature to minimise the time interrupts have to be disabled
|
||||
when accessing a queue.
|
||||
|
||||
Changed from V2.2.0
|
||||
|
||||
+ Explicit use of 'signed' qualifier on portCHAR types added.
|
||||
|
||||
Changes from V3.0.0
|
||||
|
||||
+ API changes as described on the FreeRTOS.org WEB site.
|
||||
|
||||
Changes from V3.2.3
|
||||
|
||||
+ Added the queue functions that can be used from co-routines.
|
||||
|
||||
Changes from V4.0.5
|
||||
|
||||
+ Added a loop within xQueueSend() and xQueueReceive() to prevent the
|
||||
functions exiting when a block time remains and the function has
|
||||
not completed.
|
||||
|
||||
Changes from V4.1.2:
|
||||
|
||||
+ BUG FIX: Removed the call to prvIsQueueEmpty from within xQueueCRReceive
|
||||
as it exited with interrupts enabled. Thanks Paul Katz.
|
||||
|
||||
Changes from V4.1.3:
|
||||
|
||||
+ Modified xQueueSend() and xQueueReceive() to handle the (very unlikely)
|
||||
case whereby a task unblocking due to a temporal event can remove/send an
|
||||
item from/to a queue when a higher priority task is still blocked on the
|
||||
queue. This modification is a result of the SafeRTOS testing.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "FreeRTOS.h"
|
||||
|
@ -100,6 +57,11 @@ Changes from V4.1.3:
|
|||
#define uxQueueType pcHead
|
||||
#define queueQUEUE_IS_MUTEX NULL
|
||||
|
||||
/* Semaphores do not actually store or copy data, so have an items size of
|
||||
zero. */
|
||||
#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( 0 )
|
||||
#define queueDONT_BLOCK ( ( portTickType ) 0 )
|
||||
|
||||
/*
|
||||
* Definition of the queue used by the scheduler.
|
||||
* Items are queued by copy, not reference.
|
||||
|
@ -144,6 +106,7 @@ signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void
|
|||
signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );
|
||||
signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, const void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken );
|
||||
xQueueHandle xQueueCreateMutex( void );
|
||||
xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount );
|
||||
|
||||
#if configUSE_CO_ROUTINES == 1
|
||||
signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken );
|
||||
|
@ -296,6 +259,25 @@ size_t xQueueSizeInBytes;
|
|||
#endif /* configUSE_MUTEXES */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if configUSE_COUNTING_SEMAPHORES == 1
|
||||
|
||||
xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount )
|
||||
{
|
||||
xQueueHandle pxHandle;
|
||||
|
||||
pxHandle = xQueueCreate( ( unsigned portBASE_TYPE ) uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH );
|
||||
|
||||
if( pxHandle != NULL )
|
||||
{
|
||||
pxHandle->uxMessagesWaiting = uxInitialCount;
|
||||
}
|
||||
|
||||
return pxHandle;
|
||||
}
|
||||
|
||||
#endif /* configUSE_COUNTING_SEMAPHORES */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
|
||||
{
|
||||
signed portBASE_TYPE xReturn = pdPASS;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue