Merge branch 'feature/freertos_api_doc' into 'master'

Add FreeRTOS API documentation

See merge request !1634
This commit is contained in:
Ivan Grokhotkov 2017-12-07 13:50:10 +08:00
commit b46d4ab632
11 changed files with 2481 additions and 2688 deletions

View file

@ -104,7 +104,6 @@ extern "C" {
* used to create a synchronisation point between multiple tasks (a
* 'rendezvous').
*
* \defgroup EventGroup
*/
@ -116,7 +115,6 @@ extern "C" {
* xEventGroupCreate() returns an EventGroupHandle_t variable that can then
* be used as a parameter to other event group functions.
*
* \defgroup EventGroupHandle_t EventGroupHandle_t
* \ingroup EventGroup
*/
typedef void * EventGroupHandle_t;
@ -126,17 +124,11 @@ typedef void * EventGroupHandle_t;
* number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1,
* 32 bits if set to 0.
*
* \defgroup EventBits_t EventBits_t
* \ingroup EventGroup
*/
typedef TickType_t EventBits_t;
/**
* event_groups.h
*<pre>
EventGroupHandle_t xEventGroupCreate( void );
</pre>
*
* Create a new event group.
*
* Internally, within the FreeRTOS implementation, event groups use a [small]
@ -162,25 +154,24 @@ typedef TickType_t EventBits_t;
* event group then NULL is returned. See http://www.freertos.org/a00111.html
*
* Example usage:
<pre>
// Declare a variable to hold the created event group.
EventGroupHandle_t xCreatedEventGroup;
// Attempt to create the event group.
xCreatedEventGroup = xEventGroupCreate();
// Was the event group created successfully?
if( xCreatedEventGroup == NULL )
{
// The event group was not created because there was insufficient
// FreeRTOS heap available.
}
else
{
// The event group was created.
}
</pre>
* \defgroup xEventGroupCreate xEventGroupCreate
* @code{c}
* // Declare a variable to hold the created event group.
* EventGroupHandle_t xCreatedEventGroup;
*
* // Attempt to create the event group.
* xCreatedEventGroup = xEventGroupCreate();
*
* // Was the event group created successfully?
* if( xCreatedEventGroup == NULL )
* {
* // The event group was not created because there was insufficient
* // FreeRTOS heap available.
* }
* else
* {
* // The event group was created.
* }
* @endcode
* \ingroup EventGroup
*/
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
@ -188,11 +179,6 @@ typedef TickType_t EventBits_t;
#endif
/**
* event_groups.h
*<pre>
EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
</pre>
*
* Create a new event group.
*
* Internally, within the FreeRTOS implementation, event groups use a [small]
@ -221,35 +207,26 @@ typedef TickType_t EventBits_t;
* returned. If pxEventGroupBuffer was NULL then NULL is returned.
*
* Example usage:
<pre>
// StaticEventGroup_t is a publicly accessible structure that has the same
// size and alignment requirements as the real event group structure. It is
// provided as a mechanism for applications to know the size of the event
// group (which is dependent on the architecture and configuration file
// settings) without breaking the strict data hiding policy by exposing the
// real event group internals. This StaticEventGroup_t variable is passed
// into the xSemaphoreCreateEventGroupStatic() function and is used to store
// the event group's data structures
StaticEventGroup_t xEventGroupBuffer;
// Create the event group without dynamically allocating any memory.
xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
</pre>
* @code{c}
* // StaticEventGroup_t is a publicly accessible structure that has the same
* // size and alignment requirements as the real event group structure. It is
* // provided as a mechanism for applications to know the size of the event
* // group (which is dependent on the architecture and configuration file
* // settings) without breaking the strict data hiding policy by exposing the
* // real event group internals. This StaticEventGroup_t variable is passed
* // into the xSemaphoreCreateEventGroupStatic() function and is used to store
* // the event group's data structures
* StaticEventGroup_t xEventGroupBuffer;
*
* // Create the event group without dynamically allocating any memory.
* xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
* @endcode
*/
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) PRIVILEGED_FUNCTION;
#endif
/**
* event_groups.h
*<pre>
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits,
const TickType_t xTicksToWait );
</pre>
*
* [Potentially] block to wait for one or more bits to be set within a
* previously created event group.
*
@ -292,54 +269,48 @@ typedef TickType_t EventBits_t;
* pdTRUE.
*
* Example usage:
<pre>
#define BIT_0 ( 1 << 0 )
#define BIT_4 ( 1 << 4 )
void aFunction( EventGroupHandle_t xEventGroup )
{
EventBits_t uxBits;
const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
// Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
// the event group. Clear the bits before exiting.
uxBits = xEventGroupWaitBits(
xEventGroup, // The event group being tested.
BIT_0 | BIT_4, // The bits within the event group to wait for.
pdTRUE, // BIT_0 and BIT_4 should be cleared before returning.
pdFALSE, // Don't wait for both bits, either bit will do.
xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
{
// xEventGroupWaitBits() returned because both bits were set.
}
else if( ( uxBits & BIT_0 ) != 0 )
{
// xEventGroupWaitBits() returned because just BIT_0 was set.
}
else if( ( uxBits & BIT_4 ) != 0 )
{
// xEventGroupWaitBits() returned because just BIT_4 was set.
}
else
{
// xEventGroupWaitBits() returned because xTicksToWait ticks passed
// without either BIT_0 or BIT_4 becoming set.
}
}
</pre>
* \defgroup xEventGroupWaitBits xEventGroupWaitBits
* @code{c}
* #define BIT_0 ( 1 << 0 )
* #define BIT_4 ( 1 << 4 )
*
* void aFunction( EventGroupHandle_t xEventGroup )
* {
* EventBits_t uxBits;
* const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
*
* // Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
* // the event group. Clear the bits before exiting.
* uxBits = xEventGroupWaitBits(
* xEventGroup, // The event group being tested.
* BIT_0 | BIT_4, // The bits within the event group to wait for.
* pdTRUE, // BIT_0 and BIT_4 should be cleared before returning.
* pdFALSE, // Don't wait for both bits, either bit will do.
* xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.
*
* if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
* {
* // xEventGroupWaitBits() returned because both bits were set.
* }
* else if( ( uxBits & BIT_0 ) != 0 )
* {
* // xEventGroupWaitBits() returned because just BIT_0 was set.
* }
* else if( ( uxBits & BIT_4 ) != 0 )
* {
* // xEventGroupWaitBits() returned because just BIT_4 was set.
* }
* else
* {
* // xEventGroupWaitBits() returned because xTicksToWait ticks passed
* // without either BIT_0 or BIT_4 becoming set.
* }
* }
* @endcode{c}
* \ingroup EventGroup
*/
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
/**
* event_groups.h
*<pre>
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
</pre>
*
* Clear bits within an event group. This function cannot be called from an
* interrupt.
*
@ -352,51 +323,45 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits
* @return The value of the event group before the specified bits were cleared.
*
* Example usage:
<pre>
#define BIT_0 ( 1 << 0 )
#define BIT_4 ( 1 << 4 )
void aFunction( EventGroupHandle_t xEventGroup )
{
EventBits_t uxBits;
// Clear bit 0 and bit 4 in xEventGroup.
uxBits = xEventGroupClearBits(
xEventGroup, // The event group being updated.
BIT_0 | BIT_4 );// The bits being cleared.
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
{
// Both bit 0 and bit 4 were set before xEventGroupClearBits() was
// called. Both will now be clear (not set).
}
else if( ( uxBits & BIT_0 ) != 0 )
{
// Bit 0 was set before xEventGroupClearBits() was called. It will
// now be clear.
}
else if( ( uxBits & BIT_4 ) != 0 )
{
// Bit 4 was set before xEventGroupClearBits() was called. It will
// now be clear.
}
else
{
// Neither bit 0 nor bit 4 were set in the first place.
}
}
</pre>
* \defgroup xEventGroupClearBits xEventGroupClearBits
* @code{c}
* #define BIT_0 ( 1 << 0 )
* #define BIT_4 ( 1 << 4 )
*
* void aFunction( EventGroupHandle_t xEventGroup )
* {
* EventBits_t uxBits;
*
* // Clear bit 0 and bit 4 in xEventGroup.
* uxBits = xEventGroupClearBits(
* xEventGroup, // The event group being updated.
* BIT_0 | BIT_4 );// The bits being cleared.
*
* if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
* {
* // Both bit 0 and bit 4 were set before xEventGroupClearBits() was
* // called. Both will now be clear (not set).
* }
* else if( ( uxBits & BIT_0 ) != 0 )
* {
* // Bit 0 was set before xEventGroupClearBits() was called. It will
* // now be clear.
* }
* else if( ( uxBits & BIT_4 ) != 0 )
* {
* // Bit 4 was set before xEventGroupClearBits() was called. It will
* // now be clear.
* }
* else
* {
* // Neither bit 0 nor bit 4 were set in the first place.
* }
* }
* @endcode
* \ingroup EventGroup
*/
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
/**
* event_groups.h
*<pre>
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
</pre>
*
* A version of xEventGroupClearBits() that can be called from an interrupt.
*
* Setting bits in an event group is not a deterministic operation because there
@ -420,28 +385,27 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBit
* if the timer service queue was full.
*
* Example usage:
<pre>
#define BIT_0 ( 1 << 0 )
#define BIT_4 ( 1 << 4 )
// An event group which it is assumed has already been created by a call to
// xEventGroupCreate().
EventGroupHandle_t xEventGroup;
void anInterruptHandler( void )
{
// Clear bit 0 and bit 4 in xEventGroup.
xResult = xEventGroupClearBitsFromISR(
xEventGroup, // The event group being updated.
BIT_0 | BIT_4 ); // The bits being set.
if( xResult == pdPASS )
{
// The message was posted successfully.
}
}
</pre>
* \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR
* @code{c}
* #define BIT_0 ( 1 << 0 )
* #define BIT_4 ( 1 << 4 )
*
* // An event group which it is assumed has already been created by a call to
* // xEventGroupCreate().
* EventGroupHandle_t xEventGroup;
*
* void anInterruptHandler( void )
* {
* // Clear bit 0 and bit 4 in xEventGroup.
* xResult = xEventGroupClearBitsFromISR(
* xEventGroup, // The event group being updated.
* BIT_0 | BIT_4 ); // The bits being set.
*
* if( xResult == pdPASS )
* {
* // The message was posted successfully.
* }
* }
* @endcode
* \ingroup EventGroup
*/
#if( configUSE_TRACE_FACILITY == 1 )
@ -451,11 +415,6 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBit
#endif
/**
* event_groups.h
*<pre>
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
</pre>
*
* Set bits within an event group.
* This function cannot be called from an interrupt. xEventGroupSetBitsFromISR()
* is a version that can be called from an interrupt.
@ -480,56 +439,50 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBit
* event group value before the call to xEventGroupSetBits() returns.
*
* Example usage:
<pre>
#define BIT_0 ( 1 << 0 )
#define BIT_4 ( 1 << 4 )
void aFunction( EventGroupHandle_t xEventGroup )
{
EventBits_t uxBits;
// Set bit 0 and bit 4 in xEventGroup.
uxBits = xEventGroupSetBits(
xEventGroup, // The event group being updated.
BIT_0 | BIT_4 );// The bits being set.
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
{
// Both bit 0 and bit 4 remained set when the function returned.
}
else if( ( uxBits & BIT_0 ) != 0 )
{
// Bit 0 remained set when the function returned, but bit 4 was
// cleared. It might be that bit 4 was cleared automatically as a
// task that was waiting for bit 4 was removed from the Blocked
// state.
}
else if( ( uxBits & BIT_4 ) != 0 )
{
// Bit 4 remained set when the function returned, but bit 0 was
// cleared. It might be that bit 0 was cleared automatically as a
// task that was waiting for bit 0 was removed from the Blocked
// state.
}
else
{
// Neither bit 0 nor bit 4 remained set. It might be that a task
// was waiting for both of the bits to be set, and the bits were
// cleared as the task left the Blocked state.
}
}
</pre>
* \defgroup xEventGroupSetBits xEventGroupSetBits
* @code{c}
* #define BIT_0 ( 1 << 0 )
* #define BIT_4 ( 1 << 4 )
*
* void aFunction( EventGroupHandle_t xEventGroup )
* {
* EventBits_t uxBits;
*
* // Set bit 0 and bit 4 in xEventGroup.
* uxBits = xEventGroupSetBits(
* xEventGroup, // The event group being updated.
* BIT_0 | BIT_4 );// The bits being set.
*
* if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
* {
* // Both bit 0 and bit 4 remained set when the function returned.
* }
* else if( ( uxBits & BIT_0 ) != 0 )
* {
* // Bit 0 remained set when the function returned, but bit 4 was
* // cleared. It might be that bit 4 was cleared automatically as a
* // task that was waiting for bit 4 was removed from the Blocked
* // state.
* }
* else if( ( uxBits & BIT_4 ) != 0 )
* {
* // Bit 4 remained set when the function returned, but bit 0 was
* // cleared. It might be that bit 0 was cleared automatically as a
* // task that was waiting for bit 0 was removed from the Blocked
* // state.
* }
* else
* {
* // Neither bit 0 nor bit 4 remained set. It might be that a task
* // was waiting for both of the bits to be set, and the bits were
* // cleared as the task left the Blocked state.
* }
* }
* @endcode{c}
* \ingroup EventGroup
*/
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
/**
* event_groups.h
*<pre>
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
</pre>
*
* A version of xEventGroupSetBits() that can be called from an interrupt.
*
* Setting bits in an event group is not a deterministic operation because there
@ -561,39 +514,38 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_
* if the timer service queue was full.
*
* Example usage:
<pre>
#define BIT_0 ( 1 << 0 )
#define BIT_4 ( 1 << 4 )
// An event group which it is assumed has already been created by a call to
// xEventGroupCreate().
EventGroupHandle_t xEventGroup;
void anInterruptHandler( void )
{
BaseType_t xHigherPriorityTaskWoken, xResult;
// xHigherPriorityTaskWoken must be initialised to pdFALSE.
xHigherPriorityTaskWoken = pdFALSE;
// Set bit 0 and bit 4 in xEventGroup.
xResult = xEventGroupSetBitsFromISR(
xEventGroup, // The event group being updated.
BIT_0 | BIT_4 // The bits being set.
&xHigherPriorityTaskWoken );
// Was the message posted successfully?
if( xResult == pdPASS )
{
// If xHigherPriorityTaskWoken is now set to pdTRUE then a context
// switch should be requested. The macro used is port specific and
// will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
// refer to the documentation page for the port being used.
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
}
</pre>
* \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR
* @code{c}
* #define BIT_0 ( 1 << 0 )
* #define BIT_4 ( 1 << 4 )
*
* // An event group which it is assumed has already been created by a call to
* // xEventGroupCreate().
* EventGroupHandle_t xEventGroup;
*
* void anInterruptHandler( void )
* {
* BaseType_t xHigherPriorityTaskWoken, xResult;
*
* // xHigherPriorityTaskWoken must be initialised to pdFALSE.
* xHigherPriorityTaskWoken = pdFALSE;
*
* // Set bit 0 and bit 4 in xEventGroup.
* xResult = xEventGroupSetBitsFromISR(
* xEventGroup, // The event group being updated.
* BIT_0 | BIT_4 // The bits being set.
* &xHigherPriorityTaskWoken );
*
* // Was the message posted successfully?
* if( xResult == pdPASS )
* {
* // If xHigherPriorityTaskWoken is now set to pdTRUE then a context
* // switch should be requested. The macro used is port specific and
* // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
* // refer to the documentation page for the port being used.
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
* }
* }
* @endcode
* \ingroup EventGroup
*/
#if( configUSE_TRACE_FACILITY == 1 )
@ -603,14 +555,6 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_
#endif
/**
* event_groups.h
*<pre>
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
const EventBits_t uxBitsToWaitFor,
TickType_t xTicksToWait );
</pre>
*
* Atomically set bits within an event group, then wait for a combination of
* bits to be set within the same event group. This functionality is typically
* used to synchronise multiple tasks, where each task has to wait for the other
@ -648,93 +592,87 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_
* automatically cleared.
*
* Example usage:
<pre>
// Bits used by the three tasks.
#define TASK_0_BIT ( 1 << 0 )
#define TASK_1_BIT ( 1 << 1 )
#define TASK_2_BIT ( 1 << 2 )
#define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
// Use an event group to synchronise three tasks. It is assumed this event
// group has already been created elsewhere.
EventGroupHandle_t xEventBits;
void vTask0( void *pvParameters )
{
EventBits_t uxReturn;
TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
for( ;; )
{
// Perform task functionality here.
// Set bit 0 in the event flag to note this task has reached the
// sync point. The other two tasks will set the other two bits defined
// by ALL_SYNC_BITS. All three tasks have reached the synchronisation
// point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms
// for this to happen.
uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
{
// All three tasks reached the synchronisation point before the call
// to xEventGroupSync() timed out.
}
}
}
void vTask1( void *pvParameters )
{
for( ;; )
{
// Perform task functionality here.
// Set bit 1 in the event flag to note this task has reached the
// synchronisation point. The other two tasks will set the other two
// bits defined by ALL_SYNC_BITS. All three tasks have reached the
// synchronisation point when all the ALL_SYNC_BITS are set. Wait
// indefinitely for this to happen.
xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
// xEventGroupSync() was called with an indefinite block time, so
// this task will only reach here if the syncrhonisation was made by all
// three tasks, so there is no need to test the return value.
}
}
void vTask2( void *pvParameters )
{
for( ;; )
{
// Perform task functionality here.
// Set bit 2 in the event flag to note this task has reached the
// synchronisation point. The other two tasks will set the other two
// bits defined by ALL_SYNC_BITS. All three tasks have reached the
// synchronisation point when all the ALL_SYNC_BITS are set. Wait
// indefinitely for this to happen.
xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
// xEventGroupSync() was called with an indefinite block time, so
// this task will only reach here if the syncrhonisation was made by all
// three tasks, so there is no need to test the return value.
}
}
</pre>
* \defgroup xEventGroupSync xEventGroupSync
* @code{c}
* // Bits used by the three tasks.
* #define TASK_0_BIT ( 1 << 0 )
* #define TASK_1_BIT ( 1 << 1 )
* #define TASK_2_BIT ( 1 << 2 )
*
* #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
*
* // Use an event group to synchronise three tasks. It is assumed this event
* // group has already been created elsewhere.
* EventGroupHandle_t xEventBits;
*
* void vTask0( void *pvParameters )
* {
* EventBits_t uxReturn;
* TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
*
* for( ;; )
* {
* // Perform task functionality here.
*
* // Set bit 0 in the event flag to note this task has reached the
* // sync point. The other two tasks will set the other two bits defined
* // by ALL_SYNC_BITS. All three tasks have reached the synchronisation
* // point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms
* // for this to happen.
* uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
*
* if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
* {
* // All three tasks reached the synchronisation point before the call
* // to xEventGroupSync() timed out.
* }
* }
* }
*
* void vTask1( void *pvParameters )
* {
* for( ;; )
* {
* // Perform task functionality here.
*
* // Set bit 1 in the event flag to note this task has reached the
* // synchronisation point. The other two tasks will set the other two
* // bits defined by ALL_SYNC_BITS. All three tasks have reached the
* // synchronisation point when all the ALL_SYNC_BITS are set. Wait
* // indefinitely for this to happen.
* xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
*
* // xEventGroupSync() was called with an indefinite block time, so
* // this task will only reach here if the syncrhonisation was made by all
* // three tasks, so there is no need to test the return value.
* }
* }
*
* void vTask2( void *pvParameters )
* {
* for( ;; )
* {
* // Perform task functionality here.
*
* // Set bit 2 in the event flag to note this task has reached the
* // synchronisation point. The other two tasks will set the other two
* // bits defined by ALL_SYNC_BITS. All three tasks have reached the
* // synchronisation point when all the ALL_SYNC_BITS are set. Wait
* // indefinitely for this to happen.
* xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
*
* // xEventGroupSync() was called with an indefinite block time, so
* // this task will only reach here if the syncrhonisation was made by all
* // three tasks, so there is no need to test the return value.
* }
* }
*
* @endcode
* \ingroup EventGroup
*/
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
/**
* event_groups.h
*<pre>
EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
</pre>
*
* Returns the current value of the bits in an event group. This function
* cannot be used from an interrupt.
*
@ -742,33 +680,22 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t u
*
* @return The event group bits at the time xEventGroupGetBits() was called.
*
* \defgroup xEventGroupGetBits xEventGroupGetBits
* \ingroup EventGroup
*/
#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 )
/**
* event_groups.h
*<pre>
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
</pre>
*
* A version of xEventGroupGetBits() that can be called from an ISR.
*
* @param xEventGroup The event group being queried.
*
* @return The event group bits at the time xEventGroupGetBitsFromISR() was called.
*
* \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR
* \ingroup EventGroup
*/
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
/**
* event_groups.h
*<pre>
void xEventGroupDelete( EventGroupHandle_t xEventGroup );
</pre>
*
* Delete an event group that was previously created by a call to
* xEventGroupCreate(). Tasks that are blocked on the event group will be
@ -778,6 +705,8 @@ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
*/
void vEventGroupDelete( EventGroupHandle_t xEventGroup );
/** @cond */
/* For internal use only. */
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet );
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear );
@ -786,6 +715,8 @@ void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToCl
UBaseType_t uxEventGroupGetNumber( void* xEventGroup );
#endif
/** @endcond */
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -9,50 +9,58 @@
extern "C" {
#endif
/*
Header definitions for a FreeRTOS ringbuffer object
A ringbuffer instantiated by these functions essentially acts like a FreeRTOS queue, with the
difference that it's strictly FIFO and with the main advantage that you can put in randomly-sized
items. The capacity, accordingly, isn't measured in the amount of items, but the amount of memory
that is used for storing the items. Dependent on the size of the items, more or less of them will
fit in the ring buffer.
This ringbuffer tries to be efficient with memory: when inserting an item, the item data will
be copied to the ringbuffer memory. When retrieving an item, however, a reference to ringbuffer
memory will be returned. The returned memory is guaranteed to be 32-bit aligned and contiguous.
The application can use this memory, but as long as it does, ringbuffer writes that would write
to this bit of memory will block.
The requirement for items to be contiguous is slightly problematic when the only way to place
the next item would involve a wraparound from the end to the beginning of the ringbuffer. This can
be solved (or not) in a few ways:
- type = RINGBUF_TYPE_ALLOWSPLIT: The insertion code will split the item in two items; one which fits
in the space left at the end of the ringbuffer, one that contains the remaining data which is placed
in the beginning. Two xRingbufferReceive calls will be needed to retrieve the data.
- type = RINGBUF_TYPE_NOSPLIT: The insertion code will leave the room at the end of the ringbuffer
unused and instead will put the entire item at the start of the ringbuffer, as soon as there is
enough free space.
- type = RINGBUF_TYPE_BYTEBUF: This is your conventional byte-based ringbuffer. It does have no
overhead, but it has no item contiguousness either: a read will just give you the entire written
buffer space, or the space up to the end of the buffer, and writes can be broken up in any way
possible. Note that this type cannot do a 2nd read before returning the memory of the 1st.
The maximum size of an item will be affected by this decision. When split items are allowed, it's
acceptable to push items of (buffer_size)-16 bytes into the buffer. When it's not allowed, the
maximum size is (buffer_size/2)-8 bytes. The bytebuf can fill the entire buffer with data, it has
no overhead.
*/
#include <freertos/queue.h>
//An opaque handle for a ringbuff object.
typedef void * RingbufHandle_t;
//The various types of buffer
/**
* @brief The various types of buffer
*
* A ringbuffer instantiated by these functions essentially acts like a
* FreeRTOS queue, with the difference that it's strictly FIFO and with
* the main advantage that you can put in randomly-sized items. The capacity,
* accordingly, isn't measured in the amount of items, but the amount of
* memory that is used for storing the items. Dependent on the size of
* the items, more or less of them will fit in the ring buffer.
*
* This ringbuffer tries to be efficient with memory: when inserting an item,
* the item data will be copied to the ringbuffer memory. When retrieving
* an item, however, a reference to ringbuffer memory will be returned.
* The returned memory is guaranteed to be 32-bit aligned and contiguous.
* The application can use this memory, but as long as it does, ringbuffer
* writes that would write to this bit of memory will block.
*
* The requirement for items to be contiguous is slightly problematic when
* the only way to place the next item would involve a wraparound from the end
* to the beginning of the ringbuffer. This can be solved (or not) in a few ways,
* see descriptions of possible ringbuf_type_t types below.
*
* The maximum size of an item will be affected by ringbuffer type.
* When split items are allowed, it is acceptable to push items of
* (buffer_size)-16 bytes into the buffer.
* When it's not allowed, the maximum size is (buffer_size/2)-8 bytes.
* The bytebuf can fill the entire buffer with data, it has no overhead.
*/
typedef enum {
/** The insertion code will leave the room at the end of the ringbuffer
* unused and instead will put the entire item at the start of the ringbuffer,
* as soon as there is enough free space.
*/
RINGBUF_TYPE_NOSPLIT = 0,
/** The insertion code will split the item in two items; one which fits
* in the space left at the end of the ringbuffer, one that contains
* the remaining data which is placed in the beginning.
* Two xRingbufferReceive calls will be needed to retrieve the data.
*/
RINGBUF_TYPE_ALLOWSPLIT,
/** This is your conventional byte-based ringbuffer. It does have no
* overhead, but it has no item contiguousness either: a read will just
* give you the entire written buffer space, or the space up to the end
* of the buffer, and writes can be broken up in any way possible.
* Note that this type cannot do a 2nd read before returning the memory
* of the 1st.
*/
RINGBUF_TYPE_BYTEBUF
} ringbuf_type_t;
@ -60,22 +68,19 @@ typedef enum {
/**
* @brief Create a ring buffer
*
* @param buf_length : Length of circular buffer, in bytes. Each entry will take up its own length, plus a header
* that at the moment is equal to sizeof(size_t).
* @param allow_split_items : pdTRUE if it is acceptable that item data is inserted as two
* items instead of one.
* @param buf_length Length of circular buffer, in bytes. Each entry will
* take up its own length, plus a header that at the moment
* is equal to sizeof(size_t).
* @param type Type of ring buffer, see ringbuf_type_t.
*
* @return A RingbufHandle_t handle to the created ringbuffer, or NULL in case of error.
*/
RingbufHandle_t xRingbufferCreate(size_t buf_length, ringbuf_type_t type);
/**
* @brief Delete a ring buffer
*
* @param ringbuf - Ring buffer to delete
*
* @return void
* @param ringbuf Ring buffer to delete
*/
void vRingbufferDelete(RingbufHandle_t ringbuf);
@ -83,7 +88,7 @@ void vRingbufferDelete(RingbufHandle_t ringbuf);
/**
* @brief Get maximum size of an item that can be placed in the ring buffer
*
* @param ringbuf - Ring buffer to query
* @param ringbuf Ring buffer to query
*
* @return Maximum size, in bytes, of an item that can be placed in a ring buffer.
*/
@ -93,13 +98,15 @@ size_t xRingbufferGetMaxItemSize(RingbufHandle_t ringbuf);
/**
* @brief Insert an item into the ring buffer
*
* @param ringbuf - Ring buffer to insert the item into
* @param data - Pointer to data to insert. NULL is allowed if data_size is 0.
* @param data_size - Size of data to insert. A value of 0 is allowed.
* @param xTicksToWait - Ticks to wait for room in the ringbuffer.
* @param ringbuf Ring buffer to insert the item into
* @param data Pointer to data to insert. NULL is allowed if data_size is 0.
* @param data_size Size of data to insert. A value of 0 is allowed.
* @param ticks_to_wait Ticks to wait for room in the ringbuffer.
*
* @return pdTRUE if succeeded, pdFALSE on time-out or when the buffer is larger
* than indicated by xRingbufferGetMaxItemSize(ringbuf).
* @return
* - pdTRUE if succeeded
* - pdFALSE on time-out or when the buffer is larger than indicated
* by xRingbufferGetMaxItemSize(ringbuf).
*/
BaseType_t xRingbufferSend(RingbufHandle_t ringbuf, void *data, size_t data_size, TickType_t ticks_to_wait);
@ -107,11 +114,11 @@ BaseType_t xRingbufferSend(RingbufHandle_t ringbuf, void *data, size_t data_size
/**
* @brief Insert an item into the ring buffer from an ISR
*
* @param ringbuf - Ring buffer to insert the item into
* @param data - Pointer to data to insert. NULL is allowed if data_size is 0.
* @param data_size - Size of data to insert. A value of 0 is allowed.
* @param higher_prio_task_awoken - Value pointed to will be set to pdTRUE if the push woke up a higher
* priority task.
* @param ringbuf Ring buffer to insert the item into
* @param data Pointer to data to insert. NULL is allowed if data_size is 0.
* @param data_size Size of data to insert. A value of 0 is allowed.
* @param[out] higher_prio_task_awoken Value pointed to will be set to pdTRUE
* if the push woke up a higher priority task.
*
* @return pdTRUE if succeeded, pdFALSE when the ring buffer does not have space.
*/
@ -120,14 +127,18 @@ BaseType_t xRingbufferSendFromISR(RingbufHandle_t ringbuf, void *data, size_t da
/**
* @brief Retrieve an item from the ring buffer
*
* @note A call to vRingbufferReturnItem() is required after this to free up the data received.
* @note A call to vRingbufferReturnItem() is required after this to free up
* the data received.
*
* @param ringbuf - Ring buffer to retrieve the item from
* @param item_size - Pointer to a variable to which the size of the retrieved item will be written.
* @param xTicksToWait - Ticks to wait for items in the ringbuffer.
* @param ringbuf Ring buffer to retrieve the item from
* @param[out] item_size Pointer to a variable to which the size of the
* retrieved item will be written.
* @param ticks_to_wait Ticks to wait for items in the ringbuffer.
*
* @return Pointer to the retrieved item on success; *item_size filled with the length of the
* item. NULL on timeout, *item_size is untouched in that case.
* @return
* - pointer to the retrieved item on success; *item_size filled with
* the length of the item.
* - NULL on timeout, *item_size is untouched in that case.
*/
void *xRingbufferReceive(RingbufHandle_t ringbuf, size_t *item_size, TickType_t ticks_to_wait);
@ -135,44 +146,58 @@ void *xRingbufferReceive(RingbufHandle_t ringbuf, size_t *item_size, TickType_t
/**
* @brief Retrieve an item from the ring buffer from an ISR
*
* @note A call to vRingbufferReturnItemFromISR() is required after this to free up the data received
* @note A call to vRingbufferReturnItemFromISR() is required after this to
* free up the data received
*
* @param ringbuf - Ring buffer to retrieve the item from
* @param item_size - Pointer to a variable to which the size of the retrieved item will be written.
* @param ringbuf Ring buffer to retrieve the item from
* @param[out] item_size Pointer to a variable to which the size of the
* retrieved item will be written.
*
* @return Pointer to the retrieved item on success; *item_size filled with the length of the
* item. NULL when the ringbuffer is empty, *item_size is untouched in that case.
* @return
* - Pointer to the retrieved item on success; *item_size filled with
* the length of the item.
* - NULL when the ringbuffer is empty, *item_size is untouched in that case.
*/
void *xRingbufferReceiveFromISR(RingbufHandle_t ringbuf, size_t *item_size);
/**
* @brief Retrieve bytes from a ByteBuf type of ring buffer, specifying the maximum amount of bytes
* to return
* @note A call to vRingbufferReturnItem() is required after this to free up the data received.
* @brief Retrieve bytes from a ByteBuf type of ring buffer,
* specifying the maximum amount of bytes to return
*
* @param ringbuf - Ring buffer to retrieve the item from
* @param item_size - Pointer to a variable to which the size of the retrieved item will be written.
* @param xTicksToWait - Ticks to wait for items in the ringbuffer.
* @note A call to vRingbufferReturnItem() is required after this to free up
* the data received.
*
* @return Pointer to the retrieved item on success; *item_size filled with the length of the
* item. NULL on timeout, *item_size is untouched in that case.
* @param ringbuf Ring buffer to retrieve the item from
* @param[out] item_size Pointer to a variable to which the size
* of the retrieved item will be written.
* @param ticks_to_wait Ticks to wait for items in the ringbuffer.
* @param wanted_size Maximum number of bytes to return.
*
* @return
* - Pointer to the retrieved item on success; *item_size filled with
* the length of the item.
* - NULL on timeout, *item_size is untouched in that case.
*/
void *xRingbufferReceiveUpTo(RingbufHandle_t ringbuf, size_t *item_size, TickType_t ticks_to_wait, size_t wanted_size);
/**
* @brief Retrieve bytes from a ByteBuf type of ring buffer, specifying the maximum amount of bytes
* to return. Call this from an ISR.
* @brief Retrieve bytes from a ByteBuf type of ring buffer,
* specifying the maximum amount of bytes to return. Call this from an ISR.
*
* @note A call to vRingbufferReturnItemFromISR() is required after this to free up the data received
* @note A call to vRingbufferReturnItemFromISR() is required after this
* to free up the data received.
*
* @param ringbuf - Ring buffer to retrieve the item from
* @param item_size - Pointer to a variable to which the size of the retrieved item will be written.
* @param ringbuf Ring buffer to retrieve the item from
* @param[out] item_size Pointer to a variable to which the size of the
* retrieved item will be written.
* @param wanted_size Maximum number of bytes to return.
*
* @return Pointer to the retrieved item on success; *item_size filled with the length of the
* item. NULL when the ringbuffer is empty, *item_size is untouched in that case.
* @return
* - Pointer to the retrieved item on success; *item_size filled with
* the length of the item.
* - NULL when the ringbuffer is empty, *item_size is untouched in that case.
*/
void *xRingbufferReceiveUpToFromISR(RingbufHandle_t ringbuf, size_t *item_size, size_t wanted_size);
@ -181,10 +206,8 @@ void *xRingbufferReceiveUpToFromISR(RingbufHandle_t ringbuf, size_t *item_size,
/**
* @brief Return a previously-retrieved item to the ringbuffer
*
* @param ringbuf - Ring buffer the item was retrieved from
* @param item - Item that was received earlier
*
* @return void
* @param ringbuf Ring buffer the item was retrieved from
* @param item Item that was received earlier
*/
void vRingbufferReturnItem(RingbufHandle_t ringbuf, void *item);
@ -193,34 +216,37 @@ void vRingbufferReturnItem(RingbufHandle_t ringbuf, void *item);
/**
* @brief Return a previously-retrieved item to the ringbuffer from an ISR
*
* @param ringbuf - Ring buffer the item was retrieved from
* @param item - Item that was received earlier
* @param higher_prio_task_awoken - Value pointed to will be set to pdTRUE if the push woke up a higher
* priority task.
*
* @return void
* @param ringbuf Ring buffer the item was retrieved from
* @param item Item that was received earlier
* @param[out] higher_prio_task_awoken Value pointed to will be set to pdTRUE
* if the push woke up a higher priority task.
*/
void vRingbufferReturnItemFromISR(RingbufHandle_t ringbuf, void *item, BaseType_t *higher_prio_task_awoken);
/**
* @brief Add the ringbuffer to a queue set. This specifically adds the semaphore that indicates
* more space has become available in the ringbuffer.
* @brief Add the ringbuffer to a queue set.
*
* @param ringbuf - Ring buffer to add to the queue set
* @param xQueueSet - Queue set to add the ringbuffer to
* This specifically adds the semaphore that indicates more space
* has become available in the ringbuffer.
*
* @return pdTRUE on success, pdFALSE otherwise
* @param ringbuf Ring buffer to add to the queue set
* @param xQueueSet Queue set to add the ringbuffer to
*
* @return
* - pdTRUE on success, pdFALSE otherwise
*/
BaseType_t xRingbufferAddToQueueSetRead(RingbufHandle_t ringbuf, QueueSetHandle_t xQueueSet);
/**
* @brief Add the ringbuffer to a queue set. This specifically adds the semaphore that indicates
* something has been written into the ringbuffer.
* @brief Add the ringbuffer to a queue set.
*
* @param ringbuf - Ring buffer to add to the queue set
* @param xQueueSet - Queue set to add the ringbuffer to
* This specifically adds the semaphore that indicates something has been
* written into the ringbuffer.
*
* @param ringbuf Ring buffer to add to the queue set
* @param xQueueSet Queue set to add the ringbuffer to
*
* @return pdTRUE on success, pdFALSE otherwise
*/
@ -228,11 +254,13 @@ BaseType_t xRingbufferAddToQueueSetWrite(RingbufHandle_t ringbuf, QueueSetHandle
/**
* @brief Remove the ringbuffer from a queue set. This specifically removes the semaphore that indicates
* more space has become available in the ringbuffer.
* @brief Remove the ringbuffer from a queue set.
*
* @param ringbuf - Ring buffer to remove from the queue set
* @param xQueueSet - Queue set to remove the ringbuffer from
* This specifically removes the semaphore that indicates more space
* has become available in the ringbuffer.
*
* @param ringbuf Ring buffer to remove from the queue set
* @param xQueueSet Queue set to remove the ringbuffer from
*
* @return pdTRUE on success, pdFALSE otherwise
*/
@ -240,11 +268,13 @@ BaseType_t xRingbufferRemoveFromQueueSetRead(RingbufHandle_t ringbuf, QueueSetHa
/**
* @brief Remove the ringbuffer from a queue set. This specifically removes the semaphore that indicates
* something has been written to the ringbuffer.
* @brief Remove the ringbuffer from a queue set.
*
* @param ringbuf - Ring buffer to remove from the queue set
* @param xQueueSet - Queue set to remove the ringbuffer from
* This specifically removes the semaphore that indicates something
* has been written to the ringbuffer.
*
* @param ringbuf Ring buffer to remove from the queue set
* @param xQueueSet Queue set to remove the ringbuffer from
*
* @return pdTRUE on success, pdFALSE otherwise
*/
@ -254,9 +284,7 @@ BaseType_t xRingbufferRemoveFromQueueSetWrite(RingbufHandle_t ringbuf, QueueSetH
/**
* @brief Debugging function to print the internal pointers in the ring buffer
*
* @param ringbuf - Ring buffer to show
*
* @return void
* @param ringbuf Ring buffer to show
*/
void xRingbufferPrintInfo(RingbufHandle_t ringbuf);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -117,24 +117,18 @@ or interrupt version of the queue send function should be used. */
*/
typedef void * TimerHandle_t;
/*
/**
* Defines the prototype to which timer callback functions must conform.
*/
typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer );
/*
/**
* Defines the prototype to which functions used with the
* xTimerPendFunctionCallFromISR() function must conform.
*/
typedef void (*PendedFunction_t)( void *, uint32_t );
/**
* TimerHandle_t xTimerCreate( const char * const pcTimerName,
* TickType_t xTimerPeriodInTicks,
* UBaseType_t uxAutoReload,
* void * pvTimerID,
* TimerCallbackFunction_t pxCallbackFunction );
*
* Creates a new software timer instance, and returns a handle by which the
* created software timer can be referenced.
*
@ -184,7 +178,7 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
* structures, or the timer period was set to 0) then NULL is returned.
*
* Example usage:
* @verbatim
* @code{c}
* #define NUM_TIMERS 5
*
* // An array to hold handles to the created timers.
@ -263,7 +257,7 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
* // Should not reach here.
* for( ;; );
* }
* @endverbatim
* @endcode
*/
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
TimerHandle_t xTimerCreate( const char * const pcTimerName,
@ -274,13 +268,6 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
#endif
/**
* TimerHandle_t xTimerCreateStatic(const char * const pcTimerName,
* TickType_t xTimerPeriodInTicks,
* UBaseType_t uxAutoReload,
* void * pvTimerID,
* TimerCallbackFunction_t pxCallbackFunction,
* StaticTimer_t *pxTimerBuffer );
*
* Creates a new software timer instance, and returns a handle by which the
* created software timer can be referenced.
*
@ -332,7 +319,7 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
* returned. If pxTimerBuffer was NULL then NULL is returned.
*
* Example usage:
* @verbatim
* @code{c}
*
* // The buffer used to hold the software timer's data structure.
* static StaticTimer_t xTimerBuffer;
@ -393,7 +380,7 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
* // Should not reach here.
* for( ;; );
* }
* @endverbatim
* @endcode
*/
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
TimerHandle_t xTimerCreateStatic( const char * const pcTimerName,
@ -405,8 +392,6 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
#endif /* configSUPPORT_STATIC_ALLOCATION */
/**
* void *pvTimerGetTimerID( TimerHandle_t xTimer );
*
* Returns the ID assigned to the timer.
*
* IDs are assigned to timers using the pvTimerID parameter of the call to
@ -427,8 +412,6 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
void *pvTimerGetTimerID( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
/**
* void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID );
*
* Sets the ID assigned to the timer.
*
* IDs are assigned to timers using the pvTimerID parameter of the call to
@ -448,12 +431,12 @@ void *pvTimerGetTimerID( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) PRIVILEGED_FUNCTION;
/**
* BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer );
*
* Queries a timer to see if it is active or dormant.
*
* A timer will be dormant if:
*
* 1) It has been created but not started, or
*
* 2) It is an expired one-shot timer that has not been restarted.
*
* Timers are created in the dormant state. The xTimerStart(), xTimerReset(),
@ -467,7 +450,7 @@ void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) PRIVILEGED_FUNCTION
* pdFALSE will be returned if the timer is active.
*
* Example usage:
* @verbatim
* @code{c}
* // This function assumes xTimer has already been created.
* void vAFunction( TimerHandle_t xTimer )
* {
@ -480,13 +463,11 @@ void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) PRIVILEGED_FUNCTION
* // xTimer is not active, do something else.
* }
* }
* @endverbatim
* @endcode
*/
BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
/**
* TaskHandle_t xTimerGetTimerDaemonTaskHandle( void );
*
* xTimerGetTimerDaemonTaskHandle() is only available if
* INCLUDE_xTimerGetTimerDaemonTaskHandle is set to 1 in FreeRTOSConfig.h.
*
@ -496,8 +477,6 @@ BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
TaskHandle_t xTimerGetTimerDaemonTaskHandle( void );
/**
* TickType_t xTimerGetPeriod( TimerHandle_t xTimer );
*
* Returns the period of a timer.
*
* @param xTimer The handle of the timer being queried.
@ -507,8 +486,6 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void );
TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
/**
* TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer );
*
* Returns the time in ticks at which the timer will expire. If this is less
* than the current tick count then the expiry time has overflowed from the
* current time.
@ -522,8 +499,6 @@ TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
/**
* BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait );
*
* Timer functionality is provided by a timer service/daemon task. Many of the
* public FreeRTOS timer API functions send commands to the timer service task
* through a queue called the timer command queue. The timer command queue is
@ -574,8 +549,6 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
#define xTimerStart( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )
/**
* BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait );
*
* Timer functionality is provided by a timer service/daemon task. Many of the
* public FreeRTOS timer API functions send commands to the timer service task
* through a queue called the timer command queue. The timer command queue is
@ -616,10 +589,6 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
#define xTimerStop( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) )
/**
* BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,
* TickType_t xNewPeriod,
* TickType_t xTicksToWait );
*
* Timer functionality is provided by a timer service/daemon task. Many of the
* public FreeRTOS timer API functions send commands to the timer service task
* through a queue called the timer command queue. The timer command queue is
@ -661,7 +630,7 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
* configTIMER_TASK_PRIORITY configuration constant.
*
* Example usage:
* @verbatim
* @code{c}
* // This function assumes xTimer has already been created. If the timer
* // referenced by xTimer is already active when it is called, then the timer
* // is deleted. If the timer referenced by xTimer is not active when it is
@ -691,13 +660,11 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
* }
* }
* }
* @endverbatim
* @endcode
*/
#define xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xTicksToWait ) )
/**
* BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait );
*
* Timer functionality is provided by a timer service/daemon task. Many of the
* public FreeRTOS timer API functions send commands to the timer service task
* through a queue called the timer command queue. The timer command queue is
@ -734,8 +701,6 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
#define xTimerDelete( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) )
/**
* BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait );
*
* Timer functionality is provided by a timer service/daemon task. Many of the
* public FreeRTOS timer API functions send commands to the timer service task
* through a queue called the timer command queue. The timer command queue is
@ -781,7 +746,7 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
* configuration constant.
*
* Example usage:
* @verbatim
* @code{c}
* // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass
* // without a key being pressed, then the LCD back-light is switched off. In
* // this case, the timer is a one-shot timer.
@ -853,14 +818,11 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
* // Should not reach here.
* for( ;; );
* }
* @endverbatim
* @endcode
*/
#define xTimerReset( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )
/**
* BaseType_t xTimerStartFromISR( TimerHandle_t xTimer,
* BaseType_t *pxHigherPriorityTaskWoken );
*
* A version of xTimerStart() that can be called from an interrupt service
* routine.
*
@ -888,7 +850,7 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
* configuration constant.
*
* Example usage:
* @verbatim
* @code{c}
* // This scenario assumes xBacklightTimer has already been created. When a
* // key is pressed, an LCD back-light is switched on. If 5 seconds pass
* // without a key being pressed, then the LCD back-light is switched off. In
@ -939,14 +901,11 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
* // depends on the FreeRTOS port being used).
* }
* }
* @endverbatim
* @endcode
*/
#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
/**
* BaseType_t xTimerStopFromISR( TimerHandle_t xTimer,
* BaseType_t *pxHigherPriorityTaskWoken );
*
* A version of xTimerStop() that can be called from an interrupt service
* routine.
*
@ -972,7 +931,7 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
* priority is set by the configTIMER_TASK_PRIORITY configuration constant.
*
* Example usage:
* @verbatim
* @code{c}
* // This scenario assumes xTimer has already been created and started. When
* // an interrupt occurs, the timer should be simply stopped.
*
@ -1002,15 +961,11 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
* // depends on the FreeRTOS port being used).
* }
* }
* @endverbatim
* @endcode
*/
#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP_FROM_ISR, 0, ( pxHigherPriorityTaskWoken ), 0U )
/**
* BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer,
* TickType_t xNewPeriod,
* BaseType_t *pxHigherPriorityTaskWoken );
*
* A version of xTimerChangePeriod() that can be called from an interrupt
* service routine.
*
@ -1045,7 +1000,7 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
* priority is set by the configTIMER_TASK_PRIORITY configuration constant.
*
* Example usage:
* @verbatim
* @code{c}
* // This scenario assumes xTimer has already been created and started. When
* // an interrupt occurs, the period of xTimer should be changed to 500ms.
*
@ -1075,14 +1030,11 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
* // depends on the FreeRTOS port being used).
* }
* }
* @endverbatim
* @endcode
*/
#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD_FROM_ISR, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U )
/**
* BaseType_t xTimerResetFromISR( TimerHandle_t xTimer,
* BaseType_t *pxHigherPriorityTaskWoken );
*
* A version of xTimerReset() that can be called from an interrupt service
* routine.
*
@ -1110,7 +1062,7 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
* task priority is set by the configTIMER_TASK_PRIORITY configuration constant.
*
* Example usage:
* @verbatim
* @code{c}
* // This scenario assumes xBacklightTimer has already been created. When a
* // key is pressed, an LCD back-light is switched on. If 5 seconds pass
* // without a key being pressed, then the LCD back-light is switched off. In
@ -1161,18 +1113,12 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
* // depends on the FreeRTOS port being used).
* }
* }
* @endverbatim
* @endcode
*/
#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
/**
* BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend,
* void *pvParameter1,
* uint32_t ulParameter2,
* BaseType_t *pxHigherPriorityTaskWoken );
*
*
* Used from application interrupt service routines to defer the execution of a
* function to the RTOS daemon task (the timer service task, hence this function
* is implemented in timers.c and is prefixed with 'Timer').
@ -1214,7 +1160,7 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
* timer daemon task, otherwise pdFALSE is returned.
*
* Example usage:
* @verbatim
* @code{c}
*
* // The callback function that will execute in the context of the daemon task.
* // Note callback functions must all use this same prototype.
@ -1252,17 +1198,11 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
*
* }
* @endverbatim
* @endcode
*/
BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken );
/**
* BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
* void *pvParameter1,
* uint32_t ulParameter2,
* TickType_t xTicksToWait );
*
*
* Used to defer the execution of a function to the RTOS daemon task (the timer
* service task, hence this function is implemented in timers.c and is prefixed
* with 'Timer').
@ -1291,8 +1231,6 @@ BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void
BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait );
/**
* const char * const pcTimerGetTimerName( TimerHandle_t xTimer );
*
* Returns the name that was assigned to a timer when the timer was created.
*
* @param xTimer The handle of the timer being queried.
@ -1301,6 +1239,7 @@ BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvPar
*/
const char * pcTimerGetTimerName( TimerHandle_t xTimer ); /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
/** @cond */
/*
* Functions beyond this part are not part of the public API and are intended
* for use by the kernel only.
@ -1308,6 +1247,8 @@ const char * pcTimerGetTimerName( TimerHandle_t xTimer ); /*lint !e971 Unqualifi
BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
/** @endcond */
#ifdef __cplusplus
}
#endif

View file

@ -153,7 +153,17 @@ INPUT = \
../components/esp32/include/esp_pm.h \
../components/esp32/include/esp32/pm.h \
### esp_timer, High Resolution Timer
../components/esp32/include/esp_timer.h
../components/esp32/include/esp_timer.h \
###
### FreeRTOS
###
../components/freertos/include/freertos/task.h \
../components/freertos/include/freertos/queue.h \
../components/freertos/include/freertos/semphr.h \
../components/freertos/include/freertos/timers.h \
../components/freertos/include/freertos/event_groups.h \
../components/freertos/include/freertos/ringbuf.h
## Get warnings for functions that have no documentation for their parameters or return value
@ -165,7 +175,16 @@ WARN_NO_PARAMDOC = YES
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
PREDEFINED = __attribute__(x)=
PREDEFINED = \
__attribute__(x)= \
IRAM_ATTR= \
configSUPPORT_DYNAMIC_ALLOCATION=1 \
configSUPPORT_STATIC_ALLOCATION=1 \
configQUEUE_REGISTRY_SIZE=1 \
configUSE_RECURSIVE_MUTEXES=1 \
configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS=1 \
configNUM_THREAD_LOCAL_STORAGE_POINTERS=1 \
configUSE_APPLICATION_TASK_TAG=1
## Do not complain about not having dot
##

View file

@ -20,8 +20,8 @@ found via http://www.freertos.org/a00106.html
port of FreeRTOS v8.2.0, a number of FreeRTOS v9.0.0 features have been backported
to ESP-IDF.
:ref:`tasks-and-task-creation`: Use ``xTaskCreatePinnedToCore()`` or
``xTaskCreateStaticPinnedToCore()`` to create tasks in ESP-IDF FreeRTOS. The
:ref:`tasks-and-task-creation`: Use :cpp:func:`xTaskCreatePinnedToCore` or
:cpp:func:`xTaskCreateStaticPinnedToCore` to create tasks in ESP-IDF FreeRTOS. The
last parameter of the two functions is ``xCoreID``. This parameter specifies
which core the task is pinned to. Acceptable values are ``0`` for **PRO_CPU**,
``1`` for **APP_CPU**, or ``tskNO_AFFINITY`` which allows the task to run on
@ -34,13 +34,13 @@ enter a blocked state, or are distributed across a wider range of priorities.
:ref:`scheduler-suspension`: Suspending the scheduler in ESP-IDF FreeRTOS will only
affect the scheduler on the the calling core. In other words, calling
``vTaskSuspendAll()`` on **PRO_CPU** will not prevent **APP_CPU** from scheduling, and
:cpp:func:`vTaskSuspendAll` on **PRO_CPU** will not prevent **APP_CPU** from scheduling, and
vice versa. Use critical sections or semaphores instead for simultaneous
access protection.
:ref:`tick-interrupt-synchronicity`: Tick interrupts of **PRO_CPU** and **APP_CPU**
are not synchronized. Do not expect to use ``vTaskDelay`` or
``vTaskDelayUntil`` as an accurate method of synchronizing task execution
are not synchronized. Do not expect to use :cpp:func:`vTaskDelay` or
:cpp:func:`vTaskDelayUntil` as an accurate method of synchronizing task execution
between the two cores. Use a counting semaphore instead as their context
switches are not tied to tick interrupts due to preemption.
@ -51,15 +51,15 @@ unaffected. If the other core attemps to take same mutex, it will spin until
the calling core has released the mutex by exiting the critical section.
:ref:`floating-points`: The ESP32 supports hardware acceleration of single
precision floating point arithmetic (`float`). However the use of hardware
precision floating point arithmetic (``float``). However the use of hardware
acceleration leads to some behavioral restrictions in ESP-IDF FreeRTOS.
Therefore, tasks that utilize `float` will automatically be pinned to a core if
not done so already. Furthermore, `float` cannot be used in interrupt service
Therefore, tasks that utilize ``float`` will automatically be pinned to a core if
not done so already. Furthermore, ``float`` cannot be used in interrupt service
routines.
:ref:`task-deletion`: Task deletion behavior has been backported from FreeRTOS
v9.0.0 and modified to be SMP compatible. Task memory will be freed immediately
when `vTaskDelete()` is called to delete a task that is not currently running
when :cpp:func:`vTaskDelete` is called to delete a task that is not currently running
and not pinned to the other core. Otherwise, freeing of task memory will still
be delegated to the Idle Task.
@ -67,7 +67,7 @@ be delegated to the Idle Task.
Storage Pointers (TLSP) feature. However the extra feature of Deletion Callbacks has been
added. Deletion callbacks are called automatically during task deletion and are
used to free memory pointed to by TLSP. Call
``vTaskSetThreadLocalStoragePointerAndDelCallback()`` to set TLSP and Deletion
:cpp:func:`vTaskSetThreadLocalStoragePointerAndDelCallback()` to set TLSP and Deletion
Callbacks.
:ref:`FreeRTOS Hooks<hooks_api_reference>`: Vanilla FreeRTOS Hooks were not designed for SMP.
@ -94,34 +94,34 @@ This feature has been backported from FreeRTOS v9.0.0 to ESP-IDF. The
in order for static allocation functions to be available. Once enabled, the
following functions can be called...
- ``xTaskCreateStatic()`` See :ref:`backporting-notes` below
- ``xQueueCreateStatic()``
- ``xSemaphoreCreateBinaryStatic()``
- ``xSemaphoreCreateCountingStatic()``
- ``xSemaphoreCreateMutexStatic()``
- ``xSemaphoreCreateRecursiveMutexStatic()``
- ``xTimerCreateStatic()`` See :ref:`backporting-notes` below
- ``xEventGroupCreateStatic()``
- :cpp:func:`xTaskCreateStatic` (see :ref:`backporting-notes` below)
- :c:macro:`xQueueCreateStatic`
- :c:macro:`xSemaphoreCreateBinaryStatic`
- :c:macro:`xSemaphoreCreateCountingStatic`
- :c:macro:`xSemaphoreCreateMutexStatic`
- :c:macro:`xSemaphoreCreateRecursiveMutexStatic`
- :cpp:func:`xTimerCreateStatic` (see :ref:`backporting-notes` below)
- :cpp:func:`xEventGroupCreateStatic`
Other Features
^^^^^^^^^^^^^^
- ``vTaskSetThreadLocalStoragePointer()`` See :ref:`backporting-notes` below
- ``pvTaskGetThreadLocalStoragePointer()`` See :ref:`backporting-notes` below
- ``vTimerSetTimerID()``
- ``xTimerGetPeriod()``
- ``xTimerGetExpiryTime()``
- ``pcQueueGetName()``
- ``uxSemaphoreGetCount()``
- :cpp:func:`vTaskSetThreadLocalStoragePointer` (see :ref:`backporting-notes` below)
- :cpp:func:`pvTaskGetThreadLocalStoragePointer` (see :ref:`backporting-notes` below)
- :cpp:func:`vTimerSetTimerID`
- :cpp:func:`xTimerGetPeriod`
- :cpp:func:`xTimerGetExpiryTime`
- :cpp:func:`pcQueueGetName`
- :c:macro:`uxSemaphoreGetCount`
.. _backporting-notes:
Backporting Notes
^^^^^^^^^^^^^^^^^
**1)** ``xTaskCreateStatic`` has been made SMP compatible in a similar
fashion to ``xTaskCreate`` (see :ref:`tasks-and-task-creation`). Therefore
``xTaskCreateStaticPinnedToCore()`` can also be called.
**1)** :cpp:func:`xTaskCreateStatic` has been made SMP compatible in a similar
fashion to :cpp:func:`xTaskCreate` (see :ref:`tasks-and-task-creation`). Therefore
:cpp:func:`xTaskCreateStaticPinnedToCore` can also be called.
**2)** Although vanilla FreeRTOS allows the Timer feature's daemon task to
be statically allocated, the daemon task is always dynamically allocated in
@ -130,7 +130,7 @@ defined when using statically allocated timers in ESP-IDF FreeRTOS.
**3)** The Thread Local Storage Pointer feature has been modified in ESP-IDF
FreeRTOS to include Deletion Callbacks (see :ref:`deletion-callbacks`). Therefore
the function ``vTaskSetThreadLocalStoragePointerAndDelCallback()`` can also be
the function :cpp:func:`vTaskSetThreadLocalStoragePointerAndDelCallback` can also be
called.
@ -142,9 +142,9 @@ Tasks and Task Creation
Tasks in ESP-IDF FreeRTOS are designed to run on a particular core, therefore
two new task creation functions have been added to ESP-IDF FreeRTOS by
appending ``PinnedToCore`` to the names of the task creation functions in
vanilla FreeRTOS. The vanilla FreeRTOS functions of ``xTaskCreate()``
and ``xTaskCreateStatic()`` have led to the addition of
``xTaskCreatePinnedToCore()`` and ``xTaskCreateStaticPinnedToCore()`` in
vanilla FreeRTOS. The vanilla FreeRTOS functions of :cpp:func:`xTaskCreate`
and :cpp:func:`xTaskCreateStatic` have led to the addition of
:cpp:func:`xTaskCreatePinnedToCore` and :cpp:func:`xTaskCreateStaticPinnedToCore` in
ESP-IDF FreeRTOS (see :ref:`backported-features`).
For more details see :component_file:`freertos/task.c`
@ -164,9 +164,9 @@ of 1000 bytes. It should be noted that the ``uxStackDepth`` parameter in
vanilla FreeRTOS specifies a tasks stack depth in terms of the number of
words, whereas ESP-IDF FreeRTOS specifies the stack depth in terms of bytes.
Note that the vanilla FreeRTOS functions ``xTaskCreate`` and
``xTaskCreateStatic`` have been macro defined in ESP-IDF FreeRTOS to call
``xTaskCreatePinnedToCore()`` and ``xTaskCreateStaticPinnedToCore()``
Note that the vanilla FreeRTOS functions :cpp:func:`xTaskCreate` and
:cpp:func:`xTaskCreateStatic` have been defined in ESP-IDF FreeRTOS as inline functions which call
:cpp:func:`xTaskCreatePinnedToCore` and :cpp:func:`xTaskCreateStaticPinnedToCore`
respectively with ``tskNO_AFFINITY`` as the ``xCoreID`` value.
Each Task Control Block (TCB) in ESP-IDF stores the ``xCoreID`` as a member.
@ -283,18 +283,18 @@ different cores.
Scheduler Suspension
^^^^^^^^^^^^^^^^^^^^
In vanilla FreeRTOS, suspending the scheduler via ``vTaskSuspendAll()`` will
prevent calls of ``vTaskSwitchContext()`` from context switching until the
scheduler has been resumed with ``vTaskResumeAll()``. However servicing ISRs
In vanilla FreeRTOS, suspending the scheduler via :cpp:func:`vTaskSuspendAll` will
prevent calls of ``vTaskSwitchContext`` from context switching until the
scheduler has been resumed with :cpp:func:`xTaskResumeAll`. However servicing ISRs
are still permitted. Therefore any changes in task states as a result from the
current running task or ISRSs will not be executed until the scheduler is
resumed. Scheduler suspension in vanilla FreeRTOS is a common protection method
against simultaneous access of data shared between tasks, whilst still allowing
ISRs to be serviced.
In ESP-IDF FreeRTOS, ``vTaskSuspendAll()`` will only prevent calls of
In ESP-IDF FreeRTOS, :cpp:func:`xTaskResumeAll` will only prevent calls of
``vTaskSwitchContext()`` from switching contexts on the core that called for the
suspension. Hence if **PRO_CPU** calls ``vTaskSuspendAll()``, **APP_CPU** will
suspension. Hence if **PRO_CPU** calls :cpp:func:`vTaskSuspendAll`, **APP_CPU** will
still be able to switch contexts. If data is shared between tasks that are
pinned to different cores, scheduler suspension is **NOT** a valid method of
protection against simultaneous access. Consider using critical sections
@ -302,7 +302,7 @@ protection against simultaneous access. Consider using critical sections
protecting shared resources in ESP-IDF FreeRTOS.
In general, it's better to use other RTOS primitives like mutex semaphores to protect
against data shared between tasks, rather than ``vTaskSuspendAll()``.
against data shared between tasks, rather than :cpp:func:`vTaskSuspendAll`.
.. _tick-interrupt-synchronicity:
@ -316,8 +316,8 @@ each core being independent, and the tick interrupts to each core being
unsynchronized.
In vanilla FreeRTOS the tick interrupt triggers a call to
``xTaskIncrementTick()`` which is responsible for incrementing the tick
counter, checking if tasks which have called ``vTaskDelay()`` have fulfilled
:cpp:func:`xTaskIncrementTick` which is responsible for incrementing the tick
counter, checking if tasks which have called :cpp:func:`vTaskDelay` have fulfilled
their delay period, and moving those tasks from the Delayed Task List to the
Ready Task List. The tick interrupt will then call the scheduler if a context
switch is necessary.
@ -372,11 +372,11 @@ The ESP-IDF FreeRTOS critical section functions have been modified as follows…
- ``taskENTER_CRITICAL(mux)``, ``taskENTER_CRITICAL_ISR(mux)``,
``portENTER_CRITICAL(mux)``, ``portENTER_CRITICAL_ISR(mux)`` are all macro
defined to call ``vTaskEnterCritical()``
defined to call :cpp:func:`vTaskEnterCritical`
- ``taskEXIT_CRITICAL(mux)``, ``taskEXIT_CRITICAL_ISR(mux)``,
``portEXIT_CRITICAL(mux)``, ``portEXIT_CRITICAL_ISR(mux)`` are all macro
defined to call ``vTaskExitCritical()``
defined to call :cpp:func:`vTaskExitCritical`
For more details see :component_file:`freertos/include/freertos/portmacro.h`
and :component_file:`freertos/task.c`
@ -394,23 +394,23 @@ Floating Point Aritmetic
------------------------
The ESP32 supports hardware acceleration of single precision floating point
arithmetic (`float`) via Floating Point Units (FPU, also known as coprocessors)
arithmetic (``float``) via Floating Point Units (FPU, also known as coprocessors)
attached to each core. The use of the FPUs imposes some behavioral restrictions
on ESP-IDF FreeRTOS.
ESP-IDF FreeRTOS implements Lazy Context Switching for FPUs. In other words,
the state of a core's FPU registers are not immediately saved when a context
switch occurs. Therefore, tasks that utilize `float` must be pinned to a
switch occurs. Therefore, tasks that utilize ``float`` must be pinned to a
particular core upon creation. If not, ESP-IDF FreeRTOS will automatically pin
the task in question to whichever core the task was running on upon the task's
first use of `float`. Likewise due to Lazy Context Switching, interrupt service
routines must also not use `float`.
first use of ``float``. Likewise due to Lazy Context Switching, interrupt service
routines must also not use ``float``.
ESP32 does not support hardware acceleration for double precision floating point
arithmetic (`double`). Instead `double` is implemented via software hence the
behavioral restrictions with regards to `float` do not apply to `double`. Note
that due to the lack of hardware acceleration, `double` operations may consume
significantly larger amount of CPU time in comparison to `float`.
arithmetic (``double``). Instead ``double`` is implemented via software hence the
behavioral restrictions with regards to ``float`` do not apply to ``double``. Note
that due to the lack of hardware acceleration, ``double`` operations may consume
significantly larger amount of CPU time in comparison to ``float``.
.. _task-deletion:
@ -420,12 +420,12 @@ Task Deletion
FreeRTOS task deletion prior to v9.0.0 delegated the freeing of task memory
entirely to the Idle Task. Currently, the freeing of task memory will occur
immediately (within `vTaskDelete()`) if the task being deleted is not currently
immediately (within :cpp:func:`vTaskDelete`) if the task being deleted is not currently
running or is not pinned to the other core (with respect to the core
`vTaskDelete()` is called on). TLSP deletion callbacks will also run immediately
:cpp:func:`vTaskDelete` is called on). TLSP deletion callbacks will also run immediately
if the same conditions are met.
However, calling `vTaskDelete()` to delete a task that is either currently
However, calling :cpp:func:`vTaskDelete` to delete a task that is either currently
running or pinned to the other core will still result in the freeing of memory
being delegated to the Idle Task.
@ -456,8 +456,8 @@ is the index number of the associated TLSP, and the second parameter is the
TLSP itself.
Deletion callbacks are set alongside TLSP by calling
``vTaskSetThreadLocalStoragePointerAndDelCallback()``. Calling the vanilla
FreeRTOS function ``vTaskSetThreadLocalStoragePointer()`` will simply set the
:cpp:func:`vTaskSetThreadLocalStoragePointerAndDelCallback`. Calling the vanilla
FreeRTOS function :cpp:func:`vTaskSetThreadLocalStoragePointer` will simply set the
TLSP's associated Deletion Callback to `NULL` meaning that no callback will be
called for that TLSP during task deletion. If a deletion callback is `NULL`,
users should manually free the memory pointed to by the associated TLSP before
@ -466,7 +466,7 @@ task deletion in order to avoid memory leak.
:ref:`CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS` in menuconfig can be used
to configure the number TLSP and Deletion Callbacks a TCB will have.
For more details see :component_file:`freertos/include/freertos/task.h`
For more details see :doc:`FreeRTOS API reference<../api-reference/system/freertos>`.
.. _esp-idf-freertos-configuration:
@ -491,7 +491,7 @@ number of Thread Local Storage Pointers each task will have in ESP-IDF
FreeRTOS.
:ref:`CONFIG_SUPPORT_STATIC_ALLOCATION` will enable the backported
functionality of ``xTaskCreateStaticPinnedToCore()`` in ESP-IDF FreeRTOS
functionality of :cpp:func:`xTaskCreateStaticPinnedToCore` in ESP-IDF FreeRTOS
:ref:`CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION` will trigger a halt in
particular functions in ESP-IDF FreeRTOS which have not been fully tested

View file

@ -0,0 +1,42 @@
FreeRTOS
========
Overview
--------
This section contains documentation of FreeRTOS types, functions, and macros. It is automatically generated from FreeRTOS header files.
For more information about FreeRTOS features specific to ESP-IDF, see :doc:`ESP-IDF FreeRTOS SMP Changes<../../api-guides/freertos-smp>`.
Task API
--------
.. include:: /_build/inc/task.inc
Queue API
---------
.. include:: /_build/inc/queue.inc
Semaphore API
-------------
.. include:: /_build/inc/semphr.inc
Timer API
---------
.. include:: /_build/inc/timers.inc
Event Group API
---------------
.. include:: /_build/inc/event_groups.inc
Ringbuffer API
--------------
.. include:: /_build/inc/ringbuf.inc

View file

@ -1,7 +1,7 @@
.. _hooks_api_reference:
ESP-IDF FreeRTOS Hooks
======================
FreeRTOS Hooks
==============
Overview
--------

View file

@ -4,19 +4,20 @@ System API
.. toctree::
:maxdepth: 1
FreeRTOS <freertos>
FreeRTOS Hooks <hooks>
Heap Memory Allocation <mem_alloc>
Heap Memory Debugging <heap_debug>
Interrupt Allocation <intr_alloc>
Watchdogs <wdts>
Hooks <hooks>
Inter-Processor Call <ipc>
High Resolution Timer <esp_timer>
Over The Air Updates (OTA) <ota>
Sleep Modes <sleep_modes>
Power Management <power_management>
Logging <log>
Base MAC address <base_mac_address>
Application Level Tracing <app_trace>
Power Management <power_management>
Sleep Modes <sleep_modes>
Base MAC address <base_mac_address>
Over The Air Updates (OTA) <ota>
Example code for this API section is provided in :example:`system` directory of ESP-IDF examples.