From 260d144b4535c55c33b9ce9a194ff60537ab6295 Mon Sep 17 00:00:00 2001 From: Haolan Date: Tue, 8 Jul 2025 18:26:53 +0800 Subject: [PATCH] feat: add FreeRTOS Release-as: freertos/v1.0.0 --- freertos/FreeRTOS.go | 193 +++ freertos/atomic.go | 3 + freertos/deprecated_definitions.go | 3 + freertos/event_groups.go | 496 +++++++ freertos/freertos_autogen_link.go | 3 + freertos/go.mod | 5 + freertos/go.sum | 2 + freertos/list.go | 116 ++ freertos/llcppg.cfg | 30 + freertos/llcppg.pub | 65 + freertos/llpkg.cfg | 8 + freertos/message_buffer.go | 5 + freertos/mpu_prototypes.go | 352 +++++ freertos/mpu_wrappers.go | 3 + freertos/portable.go | 96 ++ freertos/portmacro.go | 228 +++ freertos/projdefs.go | 52 + freertos/queue.go | 763 ++++++++++ freertos/reent.go | 11 + freertos/semphr.go | 5 + freertos/spinlock.go | 16 + freertos/stack_macros.go | 5 + freertos/stream_buffer.go | 579 ++++++++ freertos/task.go | 2179 ++++++++++++++++++++++++++++ freertos/timers.go | 604 ++++++++ 25 files changed, 5822 insertions(+) create mode 100644 freertos/FreeRTOS.go create mode 100644 freertos/atomic.go create mode 100644 freertos/deprecated_definitions.go create mode 100644 freertos/event_groups.go create mode 100644 freertos/freertos_autogen_link.go create mode 100644 freertos/go.mod create mode 100644 freertos/go.sum create mode 100644 freertos/list.go create mode 100644 freertos/llcppg.cfg create mode 100644 freertos/llcppg.pub create mode 100644 freertos/llpkg.cfg create mode 100644 freertos/message_buffer.go create mode 100644 freertos/mpu_prototypes.go create mode 100644 freertos/mpu_wrappers.go create mode 100644 freertos/portable.go create mode 100644 freertos/portmacro.go create mode 100644 freertos/projdefs.go create mode 100644 freertos/queue.go create mode 100644 freertos/reent.go create mode 100644 freertos/semphr.go create mode 100644 freertos/spinlock.go create mode 100644 freertos/stack_macros.go create mode 100644 freertos/stream_buffer.go create mode 100644 freertos/task.go create mode 100644 freertos/timers.go diff --git a/freertos/FreeRTOS.go b/freertos/FreeRTOS.go new file mode 100644 index 00000000..3770f4fd --- /dev/null +++ b/freertos/FreeRTOS.go @@ -0,0 +1,193 @@ +package freertos + +import ( + "github.com/goplus/lib/c" + _ "unsafe" +) + +const ConfigUSE_C_RUNTIME_TLS_SUPPORT = 1 +const INCLUDE_xQueueGetMutexHolder = 0 +const ConfigUSE_DAEMON_TASK_STARTUP_HOOK = 0 +const ConfigUSE_APPLICATION_TASK_TAG = 0 +const ConfigUSE_ALTERNATIVE_API = 0 +const ConfigASSERT_DEFINED = 1 +const ConfigPRECONDITION_DEFINED = 0 +const ConfigUSE_MINI_LIST_ITEM = 1 +const ConfigGENERATE_RUN_TIME_STATS = 0 +const ConfigUSE_MALLOC_FAILED_HOOK = 0 +const ConfigEXPECTED_IDLE_TIME_BEFORE_SLEEP = 2 +const ConfigINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS = 0 +const ConfigUSE_STATS_FORMATTING_FUNCTIONS = 0 +const ConfigUSE_TRACE_FACILITY = 0 +const ConfigUSE_POSIX_ERRNO = 0 +const ConfigUSE_SB_COMPLETED_CALLBACK = 0 +const ConfigINITIAL_TICK_COUNT = 0 +const ConfigUSE_TASK_FPU_SUPPORT = 1 +const ConfigENABLE_MPU = 0 +const ConfigENABLE_FPU = 1 +const ConfigENABLE_MVE = 0 +const ConfigENABLE_TRUSTZONE = 1 +const ConfigRUN_FREERTOS_SECURE_ONLY = 0 +const ConfigRUN_ADDITIONAL_TESTS = 0 + +/* + * In line with software engineering best practice, FreeRTOS implements a strict + * data hiding policy, so the real structures used by FreeRTOS to maintain the + * state of tasks, queues, semaphores, etc. are not accessible to the application + * code. However, if the application writer wants to statically allocate such + * an object then the size of the object needs to be known. Dummy structures + * that are guaranteed to have the same size and alignment requirements of the + * real objects are used for this purpose. The dummy list and list item + * structures below are used for inclusion in such a dummy structure. + */ +type XSTATICLISTITEM struct { + XDummy2 TickTypeT + PvDummy3 [4]c.Pointer +} +type StaticListItemT XSTATICLISTITEM + +/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ + +type XSTATICMINILISTITEM struct { + XDummy2 TickTypeT + PvDummy3 [2]c.Pointer +} +type StaticMiniListItemT XSTATICMINILISTITEM + +/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ + +type XSTATICLIST struct { + UxDummy2 UBaseTypeT + PvDummy3 c.Pointer + XDummy4 StaticMiniListItemT +} +type StaticListT XSTATICLIST + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the Task structure used internally by + * FreeRTOS is not accessible to application code. However, if the application + * writer wants to statically allocate the memory required to create a task then + * the size of the task object needs to be known. The StaticTask_t structure + * below is provided for this purpose. Its sizes and alignment requirements are + * guaranteed to match those of the genuine structure, no matter which + * architecture is being used, and no matter how the values in FreeRTOSConfig.h + * are set. Its contents are somewhat obfuscated in the hope users will + * recognise that it would be unwise to make direct use of the structure members. + */ +type XSTATICTCB struct { + PxDummy1 c.Pointer + XDummy3 [2]StaticListItemT + UxDummy5 UBaseTypeT + PxDummy6 c.Pointer + UcDummy7 [16]c.Uint8T + XDummyCoreID BaseTypeT + PxDummy8 c.Pointer + UxDummy12 [2]UBaseTypeT + PvDummy15 [2]c.Pointer + XDummy17 X_reent + UlDummy18 [1]c.Uint32T + UcDummy19 [1]c.Uint8T + UxDummy20 c.Uint8T + UcDummy21 c.Uint8T +} +type StaticTaskT XSTATICTCB + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the Queue structure used internally by + * FreeRTOS is not accessible to application code. However, if the application + * writer wants to statically allocate the memory required to create a queue + * then the size of the queue object needs to be known. The StaticQueue_t + * structure below is provided for this purpose. Its sizes and alignment + * requirements are guaranteed to match those of the genuine structure, no + * matter which architecture is being used, and no matter how the values in + * FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in the hope + * users will recognise that it would be unwise to make direct use of the + * structure members. + */ +type XSTATICQUEUE struct { + PvDummy1 [3]c.Pointer + U struct { + PvDummy2 c.Pointer + } + XDummy3 [2]StaticListT + UxDummy4 [3]UBaseTypeT + UcDummy5 [2]c.Uint8T + UcDummy6 c.Uint8T + PvDummy7 c.Pointer + XDummyQueueLock PortMUXTYPE +} +type StaticQueueT XSTATICQUEUE +type StaticSemaphoreT StaticQueueT + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the event group structure used + * internally by FreeRTOS is not accessible to application code. However, if + * the application writer wants to statically allocate the memory required to + * create an event group then the size of the event group object needs to be + * know. The StaticEventGroup_t structure below is provided for this purpose. + * Its sizes and alignment requirements are guaranteed to match those of the + * genuine structure, no matter which architecture is being used, and no matter + * how the values in FreeRTOSConfig.h are set. Its contents are somewhat + * obfuscated in the hope users will recognise that it would be unwise to make + * direct use of the structure members. + */ +type XSTATICEVENTGROUP struct { + XDummy1 TickTypeT + XDummy2 StaticListT + UcDummy4 c.Uint8T + XDummyEventGroupLock PortMUXTYPE +} +type StaticEventGroupT XSTATICEVENTGROUP + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the software timer structure used + * internally by FreeRTOS is not accessible to application code. However, if + * the application writer wants to statically allocate the memory required to + * create a software timer then the size of the queue object needs to be known. + * The StaticTimer_t structure below is provided for this purpose. Its sizes + * and alignment requirements are guaranteed to match those of the genuine + * structure, no matter which architecture is being used, and no matter how the + * values in FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in + * the hope users will recognise that it would be unwise to make direct use of + * the structure members. + */ +type XSTATICTIMER struct { + PvDummy1 c.Pointer + XDummy2 StaticListItemT + XDummy3 TickTypeT + PvDummy5 c.Pointer + PvDummy6 TaskFunctionT + UcDummy8 c.Uint8T +} +type StaticTimerT XSTATICTIMER + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the stream buffer structure used + * internally by FreeRTOS is not accessible to application code. However, if + * the application writer wants to statically allocate the memory required to + * create a stream buffer then the size of the stream buffer object needs to be + * known. The StaticStreamBuffer_t structure below is provided for this + * purpose. Its size and alignment requirements are guaranteed to match those + * of the genuine structure, no matter which architecture is being used, and + * no matter how the values in FreeRTOSConfig.h are set. Its contents are + * somewhat obfuscated in the hope users will recognise that it would be unwise + * to make direct use of the structure members. + */ +type XSTATICSTREAMBUFFER struct { + UxDummy1 [4]c.SizeT + PvDummy2 [3]c.Pointer + UcDummy3 c.Uint8T + XDummyStreamBufferLock PortMUXTYPE +} +type StaticStreamBufferT XSTATICSTREAMBUFFER +type StaticMessageBufferT StaticStreamBufferT diff --git a/freertos/atomic.go b/freertos/atomic.go new file mode 100644 index 00000000..f68c4eee --- /dev/null +++ b/freertos/atomic.go @@ -0,0 +1,3 @@ +package freertos + +import _ "unsafe" diff --git a/freertos/deprecated_definitions.go b/freertos/deprecated_definitions.go new file mode 100644 index 00000000..f68c4eee --- /dev/null +++ b/freertos/deprecated_definitions.go @@ -0,0 +1,3 @@ +package freertos + +import _ "unsafe" diff --git a/freertos/event_groups.go b/freertos/event_groups.go new file mode 100644 index 00000000..ab132e51 --- /dev/null +++ b/freertos/event_groups.go @@ -0,0 +1,496 @@ +package freertos + +import ( + "github.com/goplus/lib/c" + _ "unsafe" +) + +/** + * + * Type by which event groups are referenced. For example, a call to + * xEventGroupCreate() returns an EventGroupHandle_t variable that can then + * be used as a parameter to other event group functions. + * + * \ingroup EventGroup + */ + +type EventGroupDefT struct { + Unused [8]uint8 +} +type EventGroupHandleT *EventGroupDefT +type EventBitsT TickTypeT + +/** + * + * Create a new event group. + * + * Internally, within the FreeRTOS implementation, event groups use a [small] + * block of memory, in which the event group's structure is stored. If an event + * groups is created using xEventGroupCreate() then the required memory is + * automatically dynamically allocated inside the xEventGroupCreate() function. + * (see https://www.FreeRTOS.org/a00111.html). If an event group is created + * using xEventGroupCreateStatic() then the application writer must instead + * provide the memory that will get used by the event group. + * xEventGroupCreateStatic() therefore allows an event group to be created + * without using any dynamic memory allocation. + * + * Although event groups are not related to ticks, for internal implementation + * reasons the number of bits available for use in an event group is dependent + * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If + * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit + * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has + * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store + * event bits within an event group. + * + * @return If the event group was created then a handle to the event group is + * returned. If there was insufficient FreeRTOS heap available to create the + * event group then NULL is returned. See https://www.FreeRTOS.org/a00111.html + * + * Example usage: + * @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 + */ +//go:linkname XEventGroupCreate C.xEventGroupCreate +func XEventGroupCreate() EventGroupHandleT + +/** + * + * Create a new event group. + * + * Internally, within the FreeRTOS implementation, event groups use a [small] + * block of memory, in which the event group's structure is stored. If an event + * groups is created using xEventGroupCreate() then the required memory is + * automatically dynamically allocated inside the xEventGroupCreate() function. + * (see https://www.FreeRTOS.org/a00111.html). If an event group is created + * using xEventGroupCreateStatic() then the application writer must instead + * provide the memory that will get used by the event group. + * xEventGroupCreateStatic() therefore allows an event group to be created + * without using any dynamic memory allocation. + * + * Although event groups are not related to ticks, for internal implementation + * reasons the number of bits available for use in an event group is dependent + * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If + * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit + * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has + * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store + * event bits within an event group. + * + * @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type + * StaticEventGroup_t, which will be then be used to hold the event group's data + * structures, removing the need for the memory to be allocated dynamically. + * + * @return If the event group was created then a handle to the event group is + * returned. If pxEventGroupBuffer was NULL then NULL is returned. + * + * Example usage: + * @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 + */ +// llgo:link (*StaticEventGroupT).XEventGroupCreateStatic C.xEventGroupCreateStatic +func (recv_ *StaticEventGroupT) XEventGroupCreateStatic() EventGroupHandleT { + return nil +} + +/** + * + * [Potentially] block to wait for one or more bits to be set within a + * previously created event group. + * + * This function cannot be called from an interrupt. + * + * @param xEventGroup The event group in which the bits are being tested. The + * event group must have previously been created using a call to + * xEventGroupCreate(). + * + * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test + * inside the event group. For example, to wait for bit 0 and/or bit 2 set + * uxBitsToWaitFor to 0x05. To wait for bits 0 and/or bit 1 and/or bit 2 set + * uxBitsToWaitFor to 0x07. Etc. + * + * @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within + * uxBitsToWaitFor that are set within the event group will be cleared before + * xEventGroupWaitBits() returns if the wait condition was met (if the function + * returns for a reason other than a timeout). If xClearOnExit is set to + * pdFALSE then the bits set in the event group are not altered when the call to + * xEventGroupWaitBits() returns. + * + * @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then + * xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor + * are set or the specified block time expires. If xWaitForAllBits is set to + * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set + * in uxBitsToWaitFor is set or the specified block time expires. The block + * time is specified by the xTicksToWait parameter. + * + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait + * for one/all (depending on the xWaitForAllBits value) of the bits specified by + * uxBitsToWaitFor to become set. A value of portMAX_DELAY can be used to block + * indefinitely (provided INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h). + * + * @return The value of the event group at the time either the bits being waited + * for became set, or the block time expired. Test the return value to know + * which bits were set. If xEventGroupWaitBits() returned because its timeout + * expired then not all the bits being waited for will be set. If + * xEventGroupWaitBits() returned because the bits it was waiting for were set + * then the returned value is the event group value before any bits were + * automatically cleared in the case that xClearOnExit parameter was set to + * pdTRUE. + * + * Example usage: + * @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 + * \ingroup EventGroup + */ +//go:linkname XEventGroupWaitBits C.xEventGroupWaitBits +func XEventGroupWaitBits(xEventGroup EventGroupHandleT, uxBitsToWaitFor EventBitsT, xClearOnExit BaseTypeT, xWaitForAllBits BaseTypeT, xTicksToWait TickTypeT) EventBitsT + +/** + * + * Clear bits within an event group. This function cannot be called from an + * interrupt. + * + * @param xEventGroup The event group in which the bits are to be cleared. + * + * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear + * in the event group. For example, to clear bit 3 only, set uxBitsToClear to + * 0x08. To clear bit 3 and bit 0 set uxBitsToClear to 0x09. + * + * @return The value of the event group before the specified bits were cleared. + * + * Example usage: + * @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 + */ +//go:linkname XEventGroupClearBits C.xEventGroupClearBits +func XEventGroupClearBits(xEventGroup EventGroupHandleT, uxBitsToClear EventBitsT) EventBitsT + +/** + * + * 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. + * + * Setting bits in an event group will automatically unblock tasks that are + * blocked waiting for the bits. + * + * @param xEventGroup The event group in which the bits are to be set. + * + * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. + * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 + * and bit 0 set uxBitsToSet to 0x09. + * + * @return The value of the event group at the time the call to + * xEventGroupSetBits() returns. There are two reasons why the returned value + * might have the bits specified by the uxBitsToSet parameter cleared. First, + * if setting a bit results in a task that was waiting for the bit leaving the + * blocked state then it is possible the bit will be cleared automatically + * (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any + * unblocked (or otherwise Ready state) task that has a priority above that of + * the task that called xEventGroupSetBits() will execute and may change the + * event group value before the call to xEventGroupSetBits() returns. + * + * Example usage: + * @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 + * \ingroup EventGroup + */ +//go:linkname XEventGroupSetBits C.xEventGroupSetBits +func XEventGroupSetBits(xEventGroup EventGroupHandleT, uxBitsToSet EventBitsT) EventBitsT + +/** + * + * 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 + * tasks to reach a synchronisation point before proceeding. + * + * This function cannot be used from an interrupt. + * + * The function will return before its block time expires if the bits specified + * by the uxBitsToWait parameter are set, or become set within that time. In + * this case all the bits specified by uxBitsToWait will be automatically + * cleared before the function returns. + * + * @param xEventGroup The event group in which the bits are being tested. The + * event group must have previously been created using a call to + * xEventGroupCreate(). + * + * @param uxBitsToSet The bits to set in the event group before determining + * if, and possibly waiting for, all the bits specified by the uxBitsToWait + * parameter are set. + * + * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test + * inside the event group. For example, to wait for bit 0 and bit 2 set + * uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set + * uxBitsToWaitFor to 0x07. Etc. + * + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait + * for all of the bits specified by uxBitsToWaitFor to become set. + * + * @return The value of the event group at the time either the bits being waited + * for became set, or the block time expired. Test the return value to know + * which bits were set. If xEventGroupSync() returned because its timeout + * expired then not all the bits being waited for will be set. If + * xEventGroupSync() returned because all the bits it was waiting for were + * set then the returned value is the event group value before any bits were + * automatically cleared. + * + * Example usage: + * @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 synchronisation 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 synchronisation was made by all + * // three tasks, so there is no need to test the return value. + * } + * } + * + * @endcode + * \ingroup EventGroup + */ +//go:linkname XEventGroupSync C.xEventGroupSync +func XEventGroupSync(xEventGroup EventGroupHandleT, uxBitsToSet EventBitsT, uxBitsToWaitFor EventBitsT, xTicksToWait TickTypeT) EventBitsT + +/** + * + * 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. + * + * \ingroup EventGroup + */ +//go:linkname XEventGroupGetBitsFromISR C.xEventGroupGetBitsFromISR +func XEventGroupGetBitsFromISR(xEventGroup EventGroupHandleT) EventBitsT + +/** + * + * Delete an event group that was previously created by a call to + * xEventGroupCreate(). Tasks that are blocked on the event group will be + * unblocked and obtain 0 as the event group's value. + * + * @param xEventGroup The event group being deleted. + */ +//go:linkname VEventGroupDelete C.vEventGroupDelete +func VEventGroupDelete(xEventGroup EventGroupHandleT) + +/** + * + * Retrieve a pointer to a statically created event groups's data structure + * buffer. It is the same buffer that is supplied at the time of creation. + * + * @param xEventGroup The event group for which to retrieve the buffer. + * + * @param ppxEventGroupBuffer Used to return a pointer to the event groups's + * data structure buffer. + * + * @return pdTRUE if the buffer was retrieved, pdFALSE otherwise. + */ +//go:linkname XEventGroupGetStaticBuffer C.xEventGroupGetStaticBuffer +func XEventGroupGetStaticBuffer(xEventGroup EventGroupHandleT, ppxEventGroupBuffer **StaticEventGroupT) BaseTypeT + +/* For internal use only. */ +//go:linkname VEventGroupSetBitsCallback C.vEventGroupSetBitsCallback +func VEventGroupSetBitsCallback(pvEventGroup c.Pointer, ulBitsToSet c.Uint32T) + +//go:linkname VEventGroupClearBitsCallback C.vEventGroupClearBitsCallback +func VEventGroupClearBitsCallback(pvEventGroup c.Pointer, ulBitsToClear c.Uint32T) diff --git a/freertos/freertos_autogen_link.go b/freertos/freertos_autogen_link.go new file mode 100644 index 00000000..614876e2 --- /dev/null +++ b/freertos/freertos_autogen_link.go @@ -0,0 +1,3 @@ +package freertos + +import _ "github.com/goplus/lib/c" diff --git a/freertos/go.mod b/freertos/go.mod new file mode 100644 index 00000000..7af4ef71 --- /dev/null +++ b/freertos/go.mod @@ -0,0 +1,5 @@ +module freertos + +go 1.20 + +require github.com/goplus/lib v0.2.0 diff --git a/freertos/go.sum b/freertos/go.sum new file mode 100644 index 00000000..512980a5 --- /dev/null +++ b/freertos/go.sum @@ -0,0 +1,2 @@ +github.com/goplus/lib v0.2.0 h1:AjqkN1XK5H23wZMMlpaUYAMCDAdSBQ2NMFrLtSh7W4g= +github.com/goplus/lib v0.2.0/go.mod h1:SgJv3oPqLLHCu0gcL46ejOP3x7/2ry2Jtxu7ta32kp0= diff --git a/freertos/list.go b/freertos/list.go new file mode 100644 index 00000000..572dbfd7 --- /dev/null +++ b/freertos/list.go @@ -0,0 +1,116 @@ +package freertos + +import ( + "github.com/goplus/lib/c" + _ "unsafe" +) + +/* + * Definition of the only type of object that a list can contain. + */ + +type XLIST struct { + UxNumberOfItems UBaseTypeT + PxIndex *ListItemT + XListEnd MiniListItemT +} + +type XLISTITEM struct { + XItemValue TickTypeT + PxNext *XLISTITEM + PxPrevious *XLISTITEM + PvOwner c.Pointer + PxContainer *XLIST +} +type ListItemT XLISTITEM + +type XMINILISTITEM struct { + XItemValue TickTypeT + PxNext *XLISTITEM + PxPrevious *XLISTITEM +} +type MiniListItemT XMINILISTITEM +type ListT XLIST + +/* + * Must be called before a list is used! This initialises all the members + * of the list structure and inserts the xListEnd item into the list as a + * marker to the back of the list. + * + * @param pxList Pointer to the list being initialised. + * + * \page vListInitialise vListInitialise + * \ingroup LinkedList + */ +// llgo:link (*ListT).VListInitialise C.vListInitialise +func (recv_ *ListT) VListInitialise() { +} + +/* + * Must be called before a list item is used. This sets the list container to + * null so the item does not think that it is already contained in a list. + * + * @param pxItem Pointer to the list item being initialised. + * + * \page vListInitialiseItem vListInitialiseItem + * \ingroup LinkedList + */ +// llgo:link (*ListItemT).VListInitialiseItem C.vListInitialiseItem +func (recv_ *ListItemT) VListInitialiseItem() { +} + +/* + * Insert a list item into a list. The item will be inserted into the list in + * a position determined by its item value (ascending item value order). + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The item that is to be placed in the list. + * + * \page vListInsert vListInsert + * \ingroup LinkedList + */ +// llgo:link (*ListT).VListInsert C.vListInsert +func (recv_ *ListT) VListInsert(pxNewListItem *ListItemT) { +} + +/* + * Insert a list item into a list. The item will be inserted in a position + * such that it will be the last item within the list returned by multiple + * calls to listGET_OWNER_OF_NEXT_ENTRY. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list. + * Placing an item in a list using vListInsertEnd effectively places the item + * in the list position pointed to by pxIndex. This means that every other + * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before + * the pxIndex parameter again points to the item being inserted. + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The list item to be inserted into the list. + * + * \page vListInsertEnd vListInsertEnd + * \ingroup LinkedList + */ +// llgo:link (*ListT).VListInsertEnd C.vListInsertEnd +func (recv_ *ListT) VListInsertEnd(pxNewListItem *ListItemT) { +} + +/* + * Remove an item from a list. The list item has a pointer to the list that + * it is in, so only the list item need be passed into the function. + * + * @param uxListRemove The item to be removed. The item will remove itself from + * the list pointed to by it's pxContainer parameter. + * + * @return The number of items that remain in the list after the list item has + * been removed. + * + * \page uxListRemove uxListRemove + * \ingroup LinkedList + */ +// llgo:link (*ListItemT).UxListRemove C.uxListRemove +func (recv_ *ListItemT) UxListRemove() UBaseTypeT { + return 0 +} diff --git a/freertos/llcppg.cfg b/freertos/llcppg.cfg new file mode 100644 index 00000000..e0f28a67 --- /dev/null +++ b/freertos/llcppg.cfg @@ -0,0 +1,30 @@ +{ + "name": "freertos", + "cflags": "-I/Users/haolan/esp/esp-idf/examples/get-started/blink/build/bootloader/config -I/Users/haolan/esp/esp-idf/components/freertos/config/include/freertos -I/Users/haolan/esp/esp-idf/components/freertos/config/xtensa/include -I/Users/haolan/esp/esp-idf/components/xtensa/include -I/Users/haolan/esp/esp-idf/components/xtensa/include/xtensa -I/Users/haolan/esp/esp-idf/components/xtensa/esp32s3/include -I/Users/haolan/esp/esp-idf/components/newlib/platform_include -I/Users/haolan/esp/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos -I/Users/haolan/esp/esp-idf/examples/get-started/blink/config -I/Users/haolan/esp/esp-idf/components/freertos/config/include -I/Users/haolan/esp/esp-idf/components/freertos/config/include/freertos -I/Users/haolan/esp/esp-idf/components/freertos/config/xtensa/include -I/Users/haolan/esp/esp-idf/components/freertos/FreeRTOS-Kernel/include -I/Users/haolan/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/include -I/Users/haolan/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos -I/Users/haolan/esp/esp-idf/components/freertos/esp_additions/include -I/Users/haolan/esp/esp-idf/components/freertos -I/Users/haolan/esp/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos -I/Users/haolan/esp/esp-idf/components/freertos/esp_additions -I/Users/haolan/esp/esp-idf/components/newlib/platform_include -I/Users/haolan/esp/esp-idf/components/esp_hw_support/include -I/Users/haolan/esp/esp-idf/components/esp_hw_support/include/soc -I/Users/haolan/esp/esp-idf/components/esp_hw_support/include/soc/esp32s3 -I/Users/haolan/esp/esp-idf/components/esp_hw_support/dma/include -I/Users/haolan/esp/esp-idf/components/esp_hw_support/ldo/include -I/Users/haolan/esp/esp-idf/components/esp_hw_support/debug_probe/include -I/Users/haolan/esp/esp-idf/components/esp_hw_support/port/esp32s3/. -I/Users/haolan/esp/esp-idf/components/esp_hw_support/port/esp32s3/include -I/Users/haolan/esp/esp-idf/components/heap/include -I/Users/haolan/esp/esp-idf/components/heap/tlsf -I/Users/haolan/esp/esp-idf/components/log/include -I/Users/haolan/esp/esp-idf/components/soc/include -I/Users/haolan/esp/esp-idf/components/soc/esp32s3 -I/Users/haolan/esp/esp-idf/components/soc/esp32s3/include -I/Users/haolan/esp/esp-idf/components/soc/esp32s3/register -I/Users/haolan/esp/esp-idf/components/hal/platform_port/include -I/Users/haolan/esp/esp-idf/components/hal/esp32s3/include -I/Users/haolan/esp/esp-idf/components/hal/include -I/Users/haolan/esp/esp-idf/components/esp_rom/include -I/Users/haolan/esp/esp-idf/components/esp_rom/esp32s3/include -I/Users/haolan/esp/esp-idf/components/esp_rom/esp32s3/include/esp32s3 -I/Users/haolan/esp/esp-idf/components/esp_rom/esp32s3 -I/Users/haolan/esp/esp-idf/components/esp_common/include -I/Users/haolan/esp/esp-idf/components/esp_system/include -I/Users/haolan/esp/esp-idf/components/esp_system/port/soc -I/Users/haolan/esp/esp-idf/components/esp_system/port/include/private -I/Users/haolan/esp/esp-idf/components/xtensa/esp32s3/include -I/Users/haolan/esp/esp-idf/components/xtensa/include -I/Users/haolan/esp/esp-idf/components/xtensa/deprecated_include -I/Users/haolan/esp/esp-idf/components/lwip/include -I/Users/haolan/esp/esp-idf/components/lwip/include/apps -I/Users/haolan/esp/esp-idf/components/lwip/include/apps/sntp -I/Users/haolan/esp/esp-idf/components/lwip/lwip/src/include -I/Users/haolan/esp/esp-idf/components/lwip/port/include -I/Users/haolan/esp/esp-idf/components/lwip/port/freertos/include -I/Users/haolan/esp/esp-idf/components/lwip/port/esp32xx/include -I/Users/haolan/esp/esp-idf/components/lwip/port/esp32xx/include/arch -I/Users/haolan/esp/esp-idf/components/lwip/port/esp32xx/include/sys", + "include": [ + "FreeRTOS.h", + "StackMacros.h", + "atomic.h", + "deprecated_definitions.h", + "event_groups.h", + "list.h", + "message_buffer.h", + "mpu_prototypes.h", + "mpu_wrappers.h", + "portable.h", + "projdefs.h", + "queue.h", + "semphr.h", + "stack_macros.h", + "stream_buffer.h", + "task.h", + "timers.h", + "portmacro.h", + "spinlock.h", + "sys/reent.h" + ], + "headerOnly": true, + "symMap": { + "__sinit": "-" + } +} diff --git a/freertos/llcppg.pub b/freertos/llcppg.pub new file mode 100644 index 00000000..5f52f103 --- /dev/null +++ b/freertos/llcppg.pub @@ -0,0 +1,65 @@ +BaseType_t BaseTypeT +EventBits_t EventBitsT +EventGroupDef_t EventGroupDefT +EventGroupHandle_t EventGroupHandleT +HeapRegion +HeapRegion_t HeapRegionT +HeapStats_t HeapStatsT +ListItem_t ListItemT +List_t ListT +MemoryRegion_t MemoryRegionT +MessageBufferHandle_t MessageBufferHandleT +MiniListItem_t MiniListItemT +PendedFunction_t PendedFunctionT +QueueDefinition +QueueHandle_t QueueHandleT +QueueSetHandle_t QueueSetHandleT +QueueSetMemberHandle_t QueueSetMemberHandleT +SemaphoreHandle_t SemaphoreHandleT +StackType_t StackTypeT +StaticEventGroup_t StaticEventGroupT +StaticListItem_t StaticListItemT +StaticList_t StaticListT +StaticMessageBuffer_t StaticMessageBufferT +StaticMiniListItem_t StaticMiniListItemT +StaticQueue_t StaticQueueT +StaticSemaphore_t StaticSemaphoreT +StaticStreamBuffer_t StaticStreamBufferT +StaticTask_t StaticTaskT +StaticTimer_t StaticTimerT +StreamBufferCallbackFunction_t StreamBufferCallbackFunctionT +StreamBufferDef_t StreamBufferDefT +StreamBufferHandle_t StreamBufferHandleT +TaskFunction_t TaskFunctionT +TaskHandle_t TaskHandleT +TaskHookFunction_t TaskHookFunctionT +TaskParameters_t TaskParametersT +TaskStatus_t TaskStatusT +TickType_t TickTypeT +TimeOut_t TimeOutT +TimerCallbackFunction_t TimerCallbackFunctionT +TimerHandle_t TimerHandleT +UBaseType_t UBaseTypeT +eNotifyAction ENotifyAction +eSleepModeStatus ESleepModeStatus +eTaskState ETaskState +portMUX_TYPE PortMUXTYPE +spinlock_t SpinlockT +tmrTimerControl TmrTimerControl +tskTaskControlBlock TskTaskControlBlock +xHeapStats XHeapStats +xLIST XLIST +xLIST_ITEM XLISTITEM +xMEMORY_REGION XMEMORYREGION +xMINI_LIST_ITEM XMINILISTITEM +xSTATIC_EVENT_GROUP XSTATICEVENTGROUP +xSTATIC_LIST XSTATICLIST +xSTATIC_LIST_ITEM XSTATICLISTITEM +xSTATIC_MINI_LIST_ITEM XSTATICMINILISTITEM +xSTATIC_QUEUE XSTATICQUEUE +xSTATIC_STREAM_BUFFER XSTATICSTREAMBUFFER +xSTATIC_TCB XSTATICTCB +xSTATIC_TIMER XSTATICTIMER +xTASK_PARAMETERS XTASKPARAMETERS +xTASK_STATUS XTASKSTATUS +xTIME_OUT XTIMEOUT \ No newline at end of file diff --git a/freertos/llpkg.cfg b/freertos/llpkg.cfg new file mode 100644 index 00000000..66b54ed3 --- /dev/null +++ b/freertos/llpkg.cfg @@ -0,0 +1,8 @@ +{ + "upstream": { + "package": { + "name": "freertos", + "version": "10.5.1" + } + } +} diff --git a/freertos/message_buffer.go b/freertos/message_buffer.go new file mode 100644 index 00000000..72ee83f1 --- /dev/null +++ b/freertos/message_buffer.go @@ -0,0 +1,5 @@ +package freertos + +import _ "unsafe" + +type MessageBufferHandleT StreamBufferHandleT diff --git a/freertos/mpu_prototypes.go b/freertos/mpu_prototypes.go new file mode 100644 index 00000000..82f7c01c --- /dev/null +++ b/freertos/mpu_prototypes.go @@ -0,0 +1,352 @@ +package freertos + +import ( + "github.com/goplus/lib/c" + _ "unsafe" +) + +/* MPU versions of task.h API functions. */ +//go:linkname MPUXTaskCreate C.MPU_xTaskCreate +func MPUXTaskCreate(pxTaskCode TaskFunctionT, pcName *c.Char, usStackDepth c.Uint16T, pvParameters c.Pointer, uxPriority UBaseTypeT, pxCreatedTask *TaskHandleT) BaseTypeT + +//go:linkname MPUXTaskCreateStatic C.MPU_xTaskCreateStatic +func MPUXTaskCreateStatic(pxTaskCode TaskFunctionT, pcName *c.Char, ulStackDepth c.Uint32T, pvParameters c.Pointer, uxPriority UBaseTypeT, puxStackBuffer *StackTypeT, pxTaskBuffer *StaticTaskT) TaskHandleT + +//go:linkname MPUVTaskDelete C.MPU_vTaskDelete +func MPUVTaskDelete(xTaskToDelete TaskHandleT) + +// llgo:link TickTypeT.MPUVTaskDelay C.MPU_vTaskDelay +func (recv_ TickTypeT) MPUVTaskDelay() { +} + +// llgo:link (*TickTypeT).MPUXTaskDelayUntil C.MPU_xTaskDelayUntil +func (recv_ *TickTypeT) MPUXTaskDelayUntil(xTimeIncrement TickTypeT) BaseTypeT { + return 0 +} + +//go:linkname MPUXTaskAbortDelay C.MPU_xTaskAbortDelay +func MPUXTaskAbortDelay(xTask TaskHandleT) BaseTypeT + +//go:linkname MPUUxTaskPriorityGet C.MPU_uxTaskPriorityGet +func MPUUxTaskPriorityGet(xTask TaskHandleT) UBaseTypeT + +//go:linkname MPUETaskGetState C.MPU_eTaskGetState +func MPUETaskGetState(xTask TaskHandleT) ETaskState + +//go:linkname MPUVTaskGetInfo C.MPU_vTaskGetInfo +func MPUVTaskGetInfo(xTask TaskHandleT, pxTaskStatus *TaskStatusT, xGetFreeStackSpace BaseTypeT, eState ETaskState) + +//go:linkname MPUVTaskPrioritySet C.MPU_vTaskPrioritySet +func MPUVTaskPrioritySet(xTask TaskHandleT, uxNewPriority UBaseTypeT) + +//go:linkname MPUVTaskSuspend C.MPU_vTaskSuspend +func MPUVTaskSuspend(xTaskToSuspend TaskHandleT) + +//go:linkname MPUVTaskResume C.MPU_vTaskResume +func MPUVTaskResume(xTaskToResume TaskHandleT) + +//go:linkname MPUVTaskStartScheduler C.MPU_vTaskStartScheduler +func MPUVTaskStartScheduler() + +//go:linkname MPUVTaskSuspendAll C.MPU_vTaskSuspendAll +func MPUVTaskSuspendAll() + +//go:linkname MPUXTaskResumeAll C.MPU_xTaskResumeAll +func MPUXTaskResumeAll() BaseTypeT + +//go:linkname MPUXTaskGetTickCount C.MPU_xTaskGetTickCount +func MPUXTaskGetTickCount() TickTypeT + +//go:linkname MPUUxTaskGetNumberOfTasks C.MPU_uxTaskGetNumberOfTasks +func MPUUxTaskGetNumberOfTasks() UBaseTypeT + +//go:linkname MPUPcTaskGetName C.MPU_pcTaskGetName +func MPUPcTaskGetName(xTaskToQuery TaskHandleT) *c.Char + +//go:linkname MPUXTaskGetHandle C.MPU_xTaskGetHandle +func MPUXTaskGetHandle(pcNameToQuery *c.Char) TaskHandleT + +//go:linkname MPUUxTaskGetStackHighWaterMark C.MPU_uxTaskGetStackHighWaterMark +func MPUUxTaskGetStackHighWaterMark(xTask TaskHandleT) UBaseTypeT + +//go:linkname MPUUxTaskGetStackHighWaterMark2 C.MPU_uxTaskGetStackHighWaterMark2 +func MPUUxTaskGetStackHighWaterMark2(xTask TaskHandleT) c.Uint32T + +//go:linkname MPUVTaskSetApplicationTaskTag C.MPU_vTaskSetApplicationTaskTag +func MPUVTaskSetApplicationTaskTag(xTask TaskHandleT, pxHookFunction TaskHookFunctionT) + +//go:linkname MPUXTaskGetApplicationTaskTag C.MPU_xTaskGetApplicationTaskTag +func MPUXTaskGetApplicationTaskTag(xTask TaskHandleT) TaskHookFunctionT + +//go:linkname MPUVTaskSetThreadLocalStoragePointer C.MPU_vTaskSetThreadLocalStoragePointer +func MPUVTaskSetThreadLocalStoragePointer(xTaskToSet TaskHandleT, xIndex BaseTypeT, pvValue c.Pointer) + +//go:linkname MPUPvTaskGetThreadLocalStoragePointer C.MPU_pvTaskGetThreadLocalStoragePointer +func MPUPvTaskGetThreadLocalStoragePointer(xTaskToQuery TaskHandleT, xIndex BaseTypeT) c.Pointer + +//go:linkname MPUXTaskCallApplicationTaskHook C.MPU_xTaskCallApplicationTaskHook +func MPUXTaskCallApplicationTaskHook(xTask TaskHandleT, pvParameter c.Pointer) BaseTypeT + +//go:linkname MPUXTaskGetIdleTaskHandle C.MPU_xTaskGetIdleTaskHandle +func MPUXTaskGetIdleTaskHandle() TaskHandleT + +// llgo:link (*TaskStatusT).MPUUxTaskGetSystemState C.MPU_uxTaskGetSystemState +func (recv_ *TaskStatusT) MPUUxTaskGetSystemState(uxArraySize UBaseTypeT, pulTotalRunTime *c.Uint32T) UBaseTypeT { + return 0 +} + +//go:linkname MPUUlTaskGetIdleRunTimeCounter C.MPU_ulTaskGetIdleRunTimeCounter +func MPUUlTaskGetIdleRunTimeCounter() c.Uint32T + +//go:linkname MPUUlTaskGetIdleRunTimePercent C.MPU_ulTaskGetIdleRunTimePercent +func MPUUlTaskGetIdleRunTimePercent() c.Uint32T + +//go:linkname MPUVTaskList C.MPU_vTaskList +func MPUVTaskList(pcWriteBuffer *c.Char) + +//go:linkname MPUVTaskGetRunTimeStats C.MPU_vTaskGetRunTimeStats +func MPUVTaskGetRunTimeStats(pcWriteBuffer *c.Char) + +//go:linkname MPUXTaskGenericNotify C.MPU_xTaskGenericNotify +func MPUXTaskGenericNotify(xTaskToNotify TaskHandleT, uxIndexToNotify UBaseTypeT, ulValue c.Uint32T, eAction ENotifyAction, pulPreviousNotificationValue *c.Uint32T) BaseTypeT + +// llgo:link UBaseTypeT.MPUXTaskGenericNotifyWait C.MPU_xTaskGenericNotifyWait +func (recv_ UBaseTypeT) MPUXTaskGenericNotifyWait(ulBitsToClearOnEntry c.Uint32T, ulBitsToClearOnExit c.Uint32T, pulNotificationValue *c.Uint32T, xTicksToWait TickTypeT) BaseTypeT { + return 0 +} + +// llgo:link UBaseTypeT.MPUUlTaskGenericNotifyTake C.MPU_ulTaskGenericNotifyTake +func (recv_ UBaseTypeT) MPUUlTaskGenericNotifyTake(xClearCountOnExit BaseTypeT, xTicksToWait TickTypeT) c.Uint32T { + return 0 +} + +//go:linkname MPUXTaskGenericNotifyStateClear C.MPU_xTaskGenericNotifyStateClear +func MPUXTaskGenericNotifyStateClear(xTask TaskHandleT, uxIndexToClear UBaseTypeT) BaseTypeT + +//go:linkname MPUUlTaskGenericNotifyValueClear C.MPU_ulTaskGenericNotifyValueClear +func MPUUlTaskGenericNotifyValueClear(xTask TaskHandleT, uxIndexToClear UBaseTypeT, ulBitsToClear c.Uint32T) c.Uint32T + +//go:linkname MPUXTaskIncrementTick C.MPU_xTaskIncrementTick +func MPUXTaskIncrementTick() BaseTypeT + +//go:linkname MPUXTaskGetCurrentTaskHandle C.MPU_xTaskGetCurrentTaskHandle +func MPUXTaskGetCurrentTaskHandle() TaskHandleT + +// llgo:link (*TimeOutT).MPUVTaskSetTimeOutState C.MPU_vTaskSetTimeOutState +func (recv_ *TimeOutT) MPUVTaskSetTimeOutState() { +} + +// llgo:link (*TimeOutT).MPUXTaskCheckForTimeOut C.MPU_xTaskCheckForTimeOut +func (recv_ *TimeOutT) MPUXTaskCheckForTimeOut(pxTicksToWait *TickTypeT) BaseTypeT { + return 0 +} + +//go:linkname MPUVTaskMissedYield C.MPU_vTaskMissedYield +func MPUVTaskMissedYield() + +//go:linkname MPUXTaskGetSchedulerState C.MPU_xTaskGetSchedulerState +func MPUXTaskGetSchedulerState() BaseTypeT + +// llgo:link TickTypeT.MPUXTaskCatchUpTicks C.MPU_xTaskCatchUpTicks +func (recv_ TickTypeT) MPUXTaskCatchUpTicks() BaseTypeT { + return 0 +} + +/* MPU versions of queue.h API functions. */ +//go:linkname MPUXQueueGenericSend C.MPU_xQueueGenericSend +func MPUXQueueGenericSend(xQueue c.Int, pvItemToQueue c.Pointer, xTicksToWait TickTypeT, xCopyPosition BaseTypeT) BaseTypeT + +//go:linkname MPUXQueueReceive C.MPU_xQueueReceive +func MPUXQueueReceive(xQueue c.Int, pvBuffer c.Pointer, xTicksToWait TickTypeT) BaseTypeT + +//go:linkname MPUXQueuePeek C.MPU_xQueuePeek +func MPUXQueuePeek(xQueue c.Int, pvBuffer c.Pointer, xTicksToWait TickTypeT) BaseTypeT + +//go:linkname MPUXQueueSemaphoreTake C.MPU_xQueueSemaphoreTake +func MPUXQueueSemaphoreTake(xQueue c.Int, xTicksToWait TickTypeT) BaseTypeT + +//go:linkname MPUUxQueueMessagesWaiting C.MPU_uxQueueMessagesWaiting +func MPUUxQueueMessagesWaiting(xQueue c.Int) UBaseTypeT + +//go:linkname MPUUxQueueSpacesAvailable C.MPU_uxQueueSpacesAvailable +func MPUUxQueueSpacesAvailable(xQueue c.Int) UBaseTypeT + +//go:linkname MPUVQueueDelete C.MPU_vQueueDelete +func MPUVQueueDelete(xQueue c.Int) + +//go:linkname MPUXQueueCreateMutex C.MPU_xQueueCreateMutex +func MPUXQueueCreateMutex(ucQueueType c.Uint8T) c.Int + +//go:linkname MPUXQueueCreateMutexStatic C.MPU_xQueueCreateMutexStatic +func MPUXQueueCreateMutexStatic(ucQueueType c.Uint8T, pxStaticQueue *StaticQueueT) c.Int + +// llgo:link UBaseTypeT.MPUXQueueCreateCountingSemaphore C.MPU_xQueueCreateCountingSemaphore +func (recv_ UBaseTypeT) MPUXQueueCreateCountingSemaphore(uxInitialCount UBaseTypeT) c.Int { + return 0 +} + +// llgo:link UBaseTypeT.MPUXQueueCreateCountingSemaphoreStatic C.MPU_xQueueCreateCountingSemaphoreStatic +func (recv_ UBaseTypeT) MPUXQueueCreateCountingSemaphoreStatic(uxInitialCount UBaseTypeT, pxStaticQueue *StaticQueueT) c.Int { + return 0 +} + +//go:linkname MPUXQueueGetMutexHolder C.MPU_xQueueGetMutexHolder +func MPUXQueueGetMutexHolder(xSemaphore c.Int) TaskHandleT + +//go:linkname MPUXQueueTakeMutexRecursive C.MPU_xQueueTakeMutexRecursive +func MPUXQueueTakeMutexRecursive(xMutex c.Int, xTicksToWait TickTypeT) BaseTypeT + +//go:linkname MPUXQueueGiveMutexRecursive C.MPU_xQueueGiveMutexRecursive +func MPUXQueueGiveMutexRecursive(pxMutex c.Int) BaseTypeT + +//go:linkname MPUVQueueAddToRegistry C.MPU_vQueueAddToRegistry +func MPUVQueueAddToRegistry(xQueue c.Int, pcName *c.Char) + +//go:linkname MPUVQueueUnregisterQueue C.MPU_vQueueUnregisterQueue +func MPUVQueueUnregisterQueue(xQueue c.Int) + +//go:linkname MPUPcQueueGetName C.MPU_pcQueueGetName +func MPUPcQueueGetName(xQueue c.Int) *c.Char + +// llgo:link UBaseTypeT.MPUXQueueGenericCreate C.MPU_xQueueGenericCreate +func (recv_ UBaseTypeT) MPUXQueueGenericCreate(uxItemSize UBaseTypeT, ucQueueType c.Uint8T) c.Int { + return 0 +} + +// llgo:link UBaseTypeT.MPUXQueueGenericCreateStatic C.MPU_xQueueGenericCreateStatic +func (recv_ UBaseTypeT) MPUXQueueGenericCreateStatic(uxItemSize UBaseTypeT, pucQueueStorage *c.Uint8T, pxStaticQueue *StaticQueueT, ucQueueType c.Uint8T) c.Int { + return 0 +} + +// llgo:link UBaseTypeT.MPUXQueueCreateSet C.MPU_xQueueCreateSet +func (recv_ UBaseTypeT) MPUXQueueCreateSet() c.Int { + return 0 +} + +//go:linkname MPUXQueueAddToSet C.MPU_xQueueAddToSet +func MPUXQueueAddToSet(xQueueOrSemaphore c.Int, xQueueSet c.Int) BaseTypeT + +//go:linkname MPUXQueueRemoveFromSet C.MPU_xQueueRemoveFromSet +func MPUXQueueRemoveFromSet(xQueueOrSemaphore c.Int, xQueueSet c.Int) BaseTypeT + +//go:linkname MPUXQueueSelectFromSet C.MPU_xQueueSelectFromSet +func MPUXQueueSelectFromSet(xQueueSet c.Int, xTicksToWait TickTypeT) c.Int + +//go:linkname MPUXQueueGenericReset C.MPU_xQueueGenericReset +func MPUXQueueGenericReset(xQueue c.Int, xNewQueue BaseTypeT) BaseTypeT + +//go:linkname MPUVQueueSetQueueNumber C.MPU_vQueueSetQueueNumber +func MPUVQueueSetQueueNumber(xQueue c.Int, uxQueueNumber UBaseTypeT) + +//go:linkname MPUUxQueueGetQueueNumber C.MPU_uxQueueGetQueueNumber +func MPUUxQueueGetQueueNumber(xQueue c.Int) UBaseTypeT + +//go:linkname MPUUcQueueGetQueueType C.MPU_ucQueueGetQueueType +func MPUUcQueueGetQueueType(xQueue c.Int) c.Uint8T + +/* MPU versions of timers.h API functions. */ +//go:linkname MPUXTimerCreate C.MPU_xTimerCreate +func MPUXTimerCreate(pcTimerName *c.Char, xTimerPeriodInTicks TickTypeT, uxAutoReload UBaseTypeT, pvTimerID c.Pointer, pxCallbackFunction TimerCallbackFunctionT) TimerHandleT + +//go:linkname MPUXTimerCreateStatic C.MPU_xTimerCreateStatic +func MPUXTimerCreateStatic(pcTimerName *c.Char, xTimerPeriodInTicks TickTypeT, uxAutoReload UBaseTypeT, pvTimerID c.Pointer, pxCallbackFunction TimerCallbackFunctionT, pxTimerBuffer *StaticTimerT) TimerHandleT + +//go:linkname MPUPvTimerGetTimerID C.MPU_pvTimerGetTimerID +func MPUPvTimerGetTimerID(xTimer TimerHandleT) c.Pointer + +//go:linkname MPUVTimerSetTimerID C.MPU_vTimerSetTimerID +func MPUVTimerSetTimerID(xTimer TimerHandleT, pvNewID c.Pointer) + +//go:linkname MPUXTimerIsTimerActive C.MPU_xTimerIsTimerActive +func MPUXTimerIsTimerActive(xTimer TimerHandleT) BaseTypeT + +//go:linkname MPUXTimerGetTimerDaemonTaskHandle C.MPU_xTimerGetTimerDaemonTaskHandle +func MPUXTimerGetTimerDaemonTaskHandle() TaskHandleT + +//go:linkname MPUXTimerPendFunctionCall C.MPU_xTimerPendFunctionCall +func MPUXTimerPendFunctionCall(xFunctionToPend PendedFunctionT, pvParameter1 c.Pointer, ulParameter2 c.Uint32T, xTicksToWait TickTypeT) BaseTypeT + +//go:linkname MPUPcTimerGetName C.MPU_pcTimerGetName +func MPUPcTimerGetName(xTimer TimerHandleT) *c.Char + +//go:linkname MPUVTimerSetReloadMode C.MPU_vTimerSetReloadMode +func MPUVTimerSetReloadMode(xTimer TimerHandleT, uxAutoReload UBaseTypeT) + +//go:linkname MPUUxTimerGetReloadMode C.MPU_uxTimerGetReloadMode +func MPUUxTimerGetReloadMode(xTimer TimerHandleT) UBaseTypeT + +//go:linkname MPUXTimerGetPeriod C.MPU_xTimerGetPeriod +func MPUXTimerGetPeriod(xTimer TimerHandleT) TickTypeT + +//go:linkname MPUXTimerGetExpiryTime C.MPU_xTimerGetExpiryTime +func MPUXTimerGetExpiryTime(xTimer TimerHandleT) TickTypeT + +//go:linkname MPUXTimerCreateTimerTask C.MPU_xTimerCreateTimerTask +func MPUXTimerCreateTimerTask() BaseTypeT + +//go:linkname MPUXTimerGenericCommand C.MPU_xTimerGenericCommand +func MPUXTimerGenericCommand(xTimer TimerHandleT, xCommandID BaseTypeT, xOptionalValue TickTypeT, pxHigherPriorityTaskWoken *BaseTypeT, xTicksToWait TickTypeT) BaseTypeT + +/* MPU versions of event_group.h API functions. */ +//go:linkname MPUXEventGroupCreate C.MPU_xEventGroupCreate +func MPUXEventGroupCreate() EventGroupHandleT + +// llgo:link (*StaticEventGroupT).MPUXEventGroupCreateStatic C.MPU_xEventGroupCreateStatic +func (recv_ *StaticEventGroupT) MPUXEventGroupCreateStatic() EventGroupHandleT { + return nil +} + +//go:linkname MPUXEventGroupWaitBits C.MPU_xEventGroupWaitBits +func MPUXEventGroupWaitBits(xEventGroup EventGroupHandleT, uxBitsToWaitFor EventBitsT, xClearOnExit BaseTypeT, xWaitForAllBits BaseTypeT, xTicksToWait TickTypeT) EventBitsT + +//go:linkname MPUXEventGroupClearBits C.MPU_xEventGroupClearBits +func MPUXEventGroupClearBits(xEventGroup EventGroupHandleT, uxBitsToClear EventBitsT) EventBitsT + +//go:linkname MPUXEventGroupSetBits C.MPU_xEventGroupSetBits +func MPUXEventGroupSetBits(xEventGroup EventGroupHandleT, uxBitsToSet EventBitsT) EventBitsT + +//go:linkname MPUXEventGroupSync C.MPU_xEventGroupSync +func MPUXEventGroupSync(xEventGroup EventGroupHandleT, uxBitsToSet EventBitsT, uxBitsToWaitFor EventBitsT, xTicksToWait TickTypeT) EventBitsT + +//go:linkname MPUVEventGroupDelete C.MPU_vEventGroupDelete +func MPUVEventGroupDelete(xEventGroup EventGroupHandleT) + +//go:linkname MPUUxEventGroupGetNumber C.MPU_uxEventGroupGetNumber +func MPUUxEventGroupGetNumber(xEventGroup c.Pointer) UBaseTypeT + +/* MPU versions of message/stream_buffer.h API functions. */ +//go:linkname MPUXStreamBufferSend C.MPU_xStreamBufferSend +func MPUXStreamBufferSend(xStreamBuffer StreamBufferHandleT, pvTxData c.Pointer, xDataLengthBytes c.SizeT, xTicksToWait TickTypeT) c.SizeT + +//go:linkname MPUXStreamBufferReceive C.MPU_xStreamBufferReceive +func MPUXStreamBufferReceive(xStreamBuffer StreamBufferHandleT, pvRxData c.Pointer, xBufferLengthBytes c.SizeT, xTicksToWait TickTypeT) c.SizeT + +//go:linkname MPUXStreamBufferNextMessageLengthBytes C.MPU_xStreamBufferNextMessageLengthBytes +func MPUXStreamBufferNextMessageLengthBytes(xStreamBuffer StreamBufferHandleT) c.SizeT + +//go:linkname MPUVStreamBufferDelete C.MPU_vStreamBufferDelete +func MPUVStreamBufferDelete(xStreamBuffer StreamBufferHandleT) + +//go:linkname MPUXStreamBufferIsFull C.MPU_xStreamBufferIsFull +func MPUXStreamBufferIsFull(xStreamBuffer StreamBufferHandleT) BaseTypeT + +//go:linkname MPUXStreamBufferIsEmpty C.MPU_xStreamBufferIsEmpty +func MPUXStreamBufferIsEmpty(xStreamBuffer StreamBufferHandleT) BaseTypeT + +//go:linkname MPUXStreamBufferReset C.MPU_xStreamBufferReset +func MPUXStreamBufferReset(xStreamBuffer StreamBufferHandleT) BaseTypeT + +//go:linkname MPUXStreamBufferSpacesAvailable C.MPU_xStreamBufferSpacesAvailable +func MPUXStreamBufferSpacesAvailable(xStreamBuffer StreamBufferHandleT) c.SizeT + +//go:linkname MPUXStreamBufferBytesAvailable C.MPU_xStreamBufferBytesAvailable +func MPUXStreamBufferBytesAvailable(xStreamBuffer StreamBufferHandleT) c.SizeT + +//go:linkname MPUXStreamBufferSetTriggerLevel C.MPU_xStreamBufferSetTriggerLevel +func MPUXStreamBufferSetTriggerLevel(xStreamBuffer StreamBufferHandleT, xTriggerLevel c.SizeT) BaseTypeT + +//go:linkname MPUXStreamBufferGenericCreate C.MPU_xStreamBufferGenericCreate +func MPUXStreamBufferGenericCreate(xBufferSizeBytes c.SizeT, xTriggerLevelBytes c.SizeT, xIsMessageBuffer BaseTypeT, pxSendCompletedCallback StreamBufferCallbackFunctionT, pxReceiveCompletedCallback StreamBufferCallbackFunctionT) StreamBufferHandleT + +//go:linkname MPUXStreamBufferGenericCreateStatic C.MPU_xStreamBufferGenericCreateStatic +func MPUXStreamBufferGenericCreateStatic(xBufferSizeBytes c.SizeT, xTriggerLevelBytes c.SizeT, xIsMessageBuffer BaseTypeT, pucStreamBufferStorageArea *c.Uint8T, pxStaticStreamBuffer *StaticStreamBufferT, pxSendCompletedCallback StreamBufferCallbackFunctionT, pxReceiveCompletedCallback StreamBufferCallbackFunctionT) StreamBufferHandleT diff --git a/freertos/mpu_wrappers.go b/freertos/mpu_wrappers.go new file mode 100644 index 00000000..f68c4eee --- /dev/null +++ b/freertos/mpu_wrappers.go @@ -0,0 +1,3 @@ +package freertos + +import _ "unsafe" diff --git a/freertos/portable.go b/freertos/portable.go new file mode 100644 index 00000000..e5f32df7 --- /dev/null +++ b/freertos/portable.go @@ -0,0 +1,96 @@ +package freertos + +import ( + "github.com/goplus/lib/c" + _ "unsafe" +) + +const PortUSING_MPU_WRAPPERS = 0 +const PortNUM_CONFIGURABLE_REGIONS = 1 +const PortHAS_STACK_OVERFLOW_CHECKING = 0 + +// llgo:link (*StackTypeT).PxPortInitialiseStack C.pxPortInitialiseStack +func (recv_ *StackTypeT) PxPortInitialiseStack(pxCode TaskFunctionT, pvParameters c.Pointer) *StackTypeT { + return nil +} + +/* Used by heap_5.c to define the start address and size of each memory region + * that together comprise the total FreeRTOS heap space. */ + +type HeapRegion struct { + PucStartAddress *c.Uint8T + XSizeInBytes c.SizeT +} +type HeapRegionT HeapRegion + +/* Used to pass information about the heap out of vPortGetHeapStats(). */ + +type XHeapStats struct { + XAvailableHeapSpaceInBytes c.SizeT + XSizeOfLargestFreeBlockInBytes c.SizeT + XSizeOfSmallestFreeBlockInBytes c.SizeT + XNumberOfFreeBlocks c.SizeT + XMinimumEverFreeBytesRemaining c.SizeT + XNumberOfSuccessfulAllocations c.SizeT + XNumberOfSuccessfulFrees c.SizeT +} +type HeapStatsT XHeapStats + +/* + * Used to define multiple heap regions for use by heap_5.c. This function + * must be called before any calls to pvPortMalloc() - not creating a task, + * queue, semaphore, mutex, software timer, event group, etc. will result in + * pvPortMalloc being called. + * + * pxHeapRegions passes in an array of HeapRegion_t structures - each of which + * defines a region of memory that can be used as the heap. The array is + * terminated by a HeapRegions_t structure that has a size of 0. The region + * with the lowest start address must appear first in the array. + */ +// llgo:link (*HeapRegionT).VPortDefineHeapRegions C.vPortDefineHeapRegions +func (recv_ *HeapRegionT) VPortDefineHeapRegions() { +} + +/* + * Returns a HeapStats_t structure filled with information about the current + * heap state. + */ +// llgo:link (*HeapStatsT).VPortGetHeapStats C.vPortGetHeapStats +func (recv_ *HeapStatsT) VPortGetHeapStats() { +} + +/* + * Map to the memory management routines required for the port. + */ +//go:linkname PvPortMalloc C.pvPortMalloc +func PvPortMalloc(xSize c.SizeT) c.Pointer + +//go:linkname PvPortCalloc C.pvPortCalloc +func PvPortCalloc(xNum c.SizeT, xSize c.SizeT) c.Pointer + +//go:linkname VPortFree C.vPortFree +func VPortFree(pv c.Pointer) + +//go:linkname VPortInitialiseBlocks C.vPortInitialiseBlocks +func VPortInitialiseBlocks() + +//go:linkname XPortGetFreeHeapSize C.xPortGetFreeHeapSize +func XPortGetFreeHeapSize() c.SizeT + +//go:linkname XPortGetMinimumEverFreeHeapSize C.xPortGetMinimumEverFreeHeapSize +func XPortGetMinimumEverFreeHeapSize() c.SizeT + +/* + * Setup the hardware ready for the scheduler to take control. This generally + * sets up a tick interrupt and sets timers for the correct tick frequency. + */ +//go:linkname XPortStartScheduler C.xPortStartScheduler +func XPortStartScheduler() BaseTypeT + +/* + * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so + * the hardware is left in its original condition after the scheduler stops + * executing. + */ +//go:linkname VPortEndScheduler C.vPortEndScheduler +func VPortEndScheduler() diff --git a/freertos/portmacro.go b/freertos/portmacro.go new file mode 100644 index 00000000..fbe6d445 --- /dev/null +++ b/freertos/portmacro.go @@ -0,0 +1,228 @@ +package freertos + +import ( + _ "unsafe" + + "github.com/goplus/lib/c" +) + +const PortCRITICAL_NESTING_IN_TCB = 0 +const PortBYTE_ALIGNMENT = 16 +const PortTICK_TYPE_IS_ATOMIC = 1 + +type StackTypeT c.Uint8T +type BaseTypeT c.Int +type UBaseTypeT c.Uint +type TickTypeT c.Uint32T + +/** + * @brief Checks if the current core is in an ISR context + * + * - ISR context consist of Low/Mid priority ISR, or time tick ISR + * - High priority ISRs aren't detected here, but they normally cannot call C code, so that should not be an issue anyway. + * + * @note [refactor-todo] Check if this should be inlined + * @return + * - pdTRUE if in ISR + * - pdFALSE otherwise + */ +//go:linkname XPortInIsrContext C.xPortInIsrContext +func XPortInIsrContext() BaseTypeT + +/** + * @brief Assert if in ISR context + * + * - Asserts on xPortInIsrContext() internally + */ +//go:linkname VPortAssertIfInISR C.vPortAssertIfInISR +func VPortAssertIfInISR() + +/** + * @brief Check if in ISR context from High priority ISRs + * + * - Called from High priority ISR + * - Checks if the previous context (before high priority interrupt) was in ISR context (meaning low/med priority) + * + * @note [refactor-todo] Check if this should be inlined + * @return + * - pdTRUE if in previous in ISR context + * - pdFALSE otherwise + */ +//go:linkname XPortInterruptedFromISRContext C.xPortInterruptedFromISRContext +func XPortInterruptedFromISRContext() BaseTypeT + +type PortMUXTYPE SpinlockT + +/** + * @brief Enter a SMP critical section with a timeout + * + * This function enters an SMP critical section by disabling interrupts then + * taking a spinlock with a specified timeout. + * + * This function can be called in a nested manner. + * + * @note This function is made non-inline on purpose to reduce code size + * @param mux Spinlock + * @param timeout Timeout to wait for spinlock in number of CPU cycles. + * Use portMUX_NO_TIMEOUT to wait indefinitely + * Use portMUX_TRY_LOCK to only getting the spinlock a single time + * @retval pdPASS Critical section entered (spinlock taken) + * @retval pdFAIL If timed out waiting for spinlock (will not occur if using portMUX_NO_TIMEOUT) + */ +// llgo:link (*PortMUXTYPE).XPortEnterCriticalTimeout C.xPortEnterCriticalTimeout +func (recv_ *PortMUXTYPE) XPortEnterCriticalTimeout(timeout BaseTypeT) BaseTypeT { + return 0 +} + +/** + * @brief Exit a SMP critical section + * + * This function can be called in a nested manner. On the outer most level of nesting, this function will: + * + * - Release the spinlock + * - Restore the previous interrupt level before the critical section was entered + * + * If still nesting, this function simply decrements a critical nesting count + * + * @note This function is made non-inline on purpose to reduce code size + * @param[in] mux Spinlock + */ +// llgo:link (*PortMUXTYPE).VPortExitCritical C.vPortExitCritical +func (recv_ *PortMUXTYPE) VPortExitCritical() { +} + +/** + * @brief FreeRTOS Compliant version of xPortEnterCriticalTimeout() + * + * Compliant version of xPortEnterCriticalTimeout() will ensure that this is + * called from a task context only. An abort is called otherwise. + * + * @note This function is made non-inline on purpose to reduce code size + * + * @param mux Spinlock + * @param timeout Timeout + * @return BaseType_t + */ +// llgo:link (*PortMUXTYPE).XPortEnterCriticalTimeoutCompliance C.xPortEnterCriticalTimeoutCompliance +func (recv_ *PortMUXTYPE) XPortEnterCriticalTimeoutCompliance(timeout BaseTypeT) BaseTypeT { + return 0 +} + +/** + * @brief FreeRTOS compliant version of vPortExitCritical() + * + * Compliant version of vPortExitCritical() will ensure that this is + * called from a task context only. An abort is called otherwise. + * + * @note This function is made non-inline on purpose to reduce code size + * @param[in] mux Spinlock + */ +// llgo:link (*PortMUXTYPE).VPortExitCriticalCompliance C.vPortExitCriticalCompliance +func (recv_ *PortMUXTYPE) VPortExitCriticalCompliance() { +} + +/** + * @brief Perform a solicited context switch + * + * - Defined in portasm.S + * + * @note [refactor-todo] The rest of ESP-IDF should call taskYield() instead + */ +//go:linkname VPortYield C.vPortYield +func VPortYield() + +/** + * @brief Yields the other core + * + * - Send an interrupt to another core in order to make the task running on it yield for a higher-priority task. + * - Can be used to yield current core as well + * + * @note [refactor-todo] Put this into private macros as its only called from task.c and is not public API + * @param coreid ID of core to yield + */ +// llgo:link BaseTypeT.VPortYieldOtherCore C.vPortYieldOtherCore +func (recv_ BaseTypeT) VPortYieldOtherCore() { +} + +/** + * @brief Hook function called on entry to tickless idle + * + * - Implemented in pm_impl.c + * + * @param xExpectedIdleTime Expected idle time + */ +// llgo:link TickTypeT.VApplicationSleep C.vApplicationSleep +func (recv_ TickTypeT) VApplicationSleep() { +} + +/** + * @brief Get the tick rate per second + * + * @note [refactor-todo] make this inline + * @return uint32_t Tick rate in Hz + */ +//go:linkname XPortGetTickRateHz C.xPortGetTickRateHz +func XPortGetTickRateHz() c.Uint32T + +/** + * @brief Set a watchpoint to watch the last 32 bytes of the stack + * + * Callback to set a watchpoint on the end of the stack. Called every context switch to change the stack watchpoint + * around. + * + * @param pxStackStart Pointer to the start of the stack + */ +//go:linkname VPortSetStackWatchpoint C.vPortSetStackWatchpoint +func VPortSetStackWatchpoint(pxStackStart c.Pointer) + +/** + * @brief TCB cleanup hook + * + * The portCLEAN_UP_TCB() macro is called in prvDeleteTCB() right before a + * deleted task's memory is freed. We map that macro to this internal function + * so that IDF FreeRTOS ports can inject some task pre-deletion operations. + * + * @note We can't use vPortCleanUpTCB() due to API compatibility issues. See + * CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP. Todo: IDF-8097 + */ +//go:linkname VPortTCBPreDeleteHook C.vPortTCBPreDeleteHook +func VPortTCBPreDeleteHook(pxTCB c.Pointer) + +//go:linkname X_frxtSetupSwitch C._frxt_setup_switch +func X_frxtSetupSwitch() + +/** + * @brief Checks if a given piece of memory can be used to store a FreeRTOS list + * + * - Defined in heap_idf.c + * + * @param ptr Pointer to memory + * @return true Memory can be used to store a List + * @return false Otherwise + */ +//go:linkname XPortCheckValidListMem C.xPortCheckValidListMem +func XPortCheckValidListMem(ptr c.Pointer) bool + +/** + * @brief Checks if a given piece of memory can be used to store a task's TCB + * + * - Defined in heap_idf.c + * + * @param ptr Pointer to memory + * @return true Memory can be used to store a TCB + * @return false Otherwise + */ +//go:linkname XPortCheckValidTCBMem C.xPortCheckValidTCBMem +func XPortCheckValidTCBMem(ptr c.Pointer) bool + +/** + * @brief Checks if a given piece of memory can be used to store a task's stack + * + * - Defined in heap_idf.c + * + * @param ptr Pointer to memory + * @return true Memory can be used to store a task stack + * @return false Otherwise + */ +//go:linkname XPortcheckValidStackMem C.xPortcheckValidStackMem +func XPortcheckValidStackMem(ptr c.Pointer) bool diff --git a/freertos/projdefs.go b/freertos/projdefs.go new file mode 100644 index 00000000..3188081d --- /dev/null +++ b/freertos/projdefs.go @@ -0,0 +1,52 @@ +package freertos + +import ( + "github.com/goplus/lib/c" + _ "unsafe" +) + +const PdFREERTOS_ERRNO_NONE = 0 +const PdFREERTOS_ERRNO_ENOENT = 2 +const PdFREERTOS_ERRNO_EINTR = 4 +const PdFREERTOS_ERRNO_EIO = 5 +const PdFREERTOS_ERRNO_ENXIO = 6 +const PdFREERTOS_ERRNO_EBADF = 9 +const PdFREERTOS_ERRNO_EAGAIN = 11 +const PdFREERTOS_ERRNO_EWOULDBLOCK = 11 +const PdFREERTOS_ERRNO_ENOMEM = 12 +const PdFREERTOS_ERRNO_EACCES = 13 +const PdFREERTOS_ERRNO_EFAULT = 14 +const PdFREERTOS_ERRNO_EBUSY = 16 +const PdFREERTOS_ERRNO_EEXIST = 17 +const PdFREERTOS_ERRNO_EXDEV = 18 +const PdFREERTOS_ERRNO_ENODEV = 19 +const PdFREERTOS_ERRNO_ENOTDIR = 20 +const PdFREERTOS_ERRNO_EISDIR = 21 +const PdFREERTOS_ERRNO_EINVAL = 22 +const PdFREERTOS_ERRNO_ENOSPC = 28 +const PdFREERTOS_ERRNO_ESPIPE = 29 +const PdFREERTOS_ERRNO_EROFS = 30 +const PdFREERTOS_ERRNO_EUNATCH = 42 +const PdFREERTOS_ERRNO_EBADE = 50 +const PdFREERTOS_ERRNO_EFTYPE = 79 +const PdFREERTOS_ERRNO_ENMFILE = 89 +const PdFREERTOS_ERRNO_ENOTEMPTY = 90 +const PdFREERTOS_ERRNO_ENAMETOOLONG = 91 +const PdFREERTOS_ERRNO_EOPNOTSUPP = 95 +const PdFREERTOS_ERRNO_ENOBUFS = 105 +const PdFREERTOS_ERRNO_ENOPROTOOPT = 109 +const PdFREERTOS_ERRNO_EADDRINUSE = 112 +const PdFREERTOS_ERRNO_ETIMEDOUT = 116 +const PdFREERTOS_ERRNO_EINPROGRESS = 119 +const PdFREERTOS_ERRNO_EALREADY = 120 +const PdFREERTOS_ERRNO_EADDRNOTAVAIL = 125 +const PdFREERTOS_ERRNO_EISCONN = 127 +const PdFREERTOS_ERRNO_ENOTCONN = 128 +const PdFREERTOS_ERRNO_ENOMEDIUM = 135 +const PdFREERTOS_ERRNO_EILSEQ = 138 +const PdFREERTOS_ERRNO_ECANCELED = 140 +const PdFREERTOS_LITTLE_ENDIAN = 0 +const PdFREERTOS_BIG_ENDIAN = 1 + +// llgo:type C +type TaskFunctionT func(c.Pointer) diff --git a/freertos/queue.go b/freertos/queue.go new file mode 100644 index 00000000..1a7f254d --- /dev/null +++ b/freertos/queue.go @@ -0,0 +1,763 @@ +package freertos + +import ( + "github.com/goplus/lib/c" + _ "unsafe" +) + +/** + * Type by which queues are referenced. For example, a call to xQueueCreate() + * returns an QueueHandle_t variable that can then be used as a parameter to + * xQueueSend(), xQueueReceive(), etc. + */ + +type QueueDefinition struct { + Unused [8]uint8 +} +type QueueHandleT *QueueDefinition +type QueueSetHandleT *QueueDefinition +type QueueSetMemberHandleT *QueueDefinition + +/** + * + * It is preferred that the macros xQueueSend(), xQueueSendToFront() and + * xQueueSendToBack() are used in place of calling this function directly. + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: + * @code{c} + * struct AMessage + * { + * char ucMessageID; + * char ucData[ 20 ]; + * } xMessage; + * + * uint32_t ulVar = 10UL; + * + * void vATask( void *pvParameters ) + * { + * QueueHandle_t xQueue1, xQueue2; + * struct AMessage *pxMessage; + * + * // Create a queue capable of containing 10 uint32_t values. + * xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) ); + * + * // Create a queue capable of containing 10 pointers to AMessage structures. + * // These should be passed by pointer as they contain a lot of data. + * xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) ); + * + * // ... + * + * if( xQueue1 != 0 ) + * { + * // Send an uint32_t. Wait for 10 ticks for space to become + * // available if necessary. + * if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10, queueSEND_TO_BACK ) != pdPASS ) + * { + * // Failed to post the message, even after 10 ticks. + * } + * } + * + * if( xQueue2 != 0 ) + * { + * // Send a pointer to a struct AMessage object. Don't block if the + * // queue is already full. + * pxMessage = & xMessage; + * xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0, queueSEND_TO_BACK ); + * } + * + * // ... Rest of task code. + * } + * @endcode + * \ingroup QueueManagement + */ +//go:linkname XQueueGenericSend C.xQueueGenericSend +func XQueueGenericSend(xQueue QueueHandleT, pvItemToQueue c.Pointer, xTicksToWait TickTypeT, xCopyPosition BaseTypeT) BaseTypeT + +/** + * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * This macro must not be used in an interrupt service routine. See + * xQueuePeekFromISR() for an alternative that can be called from an interrupt + * service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue + * is empty. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: + * @code{c} + * struct AMessage + * { + * char ucMessageID; + * char ucData[ 20 ]; + * } xMessage; + * + * QueueHandle_t xQueue; + * + * // Task to create a queue and post a value. + * void vATask( void *pvParameters ) + * { + * struct AMessage *pxMessage; + * + * // Create a queue capable of containing 10 pointers to AMessage structures. + * // These should be passed by pointer as they contain a lot of data. + * xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) ); + * if( xQueue == 0 ) + * { + * // Failed to create the queue. + * } + * + * // ... + * + * // Send a pointer to a struct AMessage object. Don't block if the + * // queue is already full. + * pxMessage = & xMessage; + * xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 ); + * + * // ... Rest of task code. + * } + * + * // Task to peek the data from the queue. + * void vADifferentTask( void *pvParameters ) + * { + * struct AMessage *pxRxedMessage; + * + * if( xQueue != 0 ) + * { + * // Peek a message on the created queue. Block for 10 ticks if a + * // message is not immediately available. + * if( xQueuePeek( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) ) + * { + * // pcRxedMessage now points to the struct AMessage variable posted + * // by vATask, but the item still remains on the queue. + * } + * } + * + * // ... Rest of task code. + * } + * @endcode + * \ingroup QueueManagement + */ +//go:linkname XQueuePeek C.xQueuePeek +func XQueuePeek(xQueue QueueHandleT, pvBuffer c.Pointer, xTicksToWait TickTypeT) BaseTypeT + +/** + * + * A version of xQueuePeek() that can be called from an interrupt service + * routine (ISR). + * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * \ingroup QueueManagement + */ +//go:linkname XQueuePeekFromISR C.xQueuePeekFromISR +func XQueuePeekFromISR(xQueue QueueHandleT, pvBuffer c.Pointer) BaseTypeT + +/** + * + * Receive an item from a queue. The item is received by copy so a buffer of + * adequate size must be provided. The number of bytes copied into the buffer + * was defined when the queue was created. + * + * Successfully received items are removed from the queue. + * + * This function must not be used in an interrupt service routine. See + * xQueueReceiveFromISR for an alternative that can. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. xQueueReceive() will return immediately if xTicksToWait + * is zero and the queue is empty. The time is defined in tick periods so the + * constant portTICK_PERIOD_MS should be used to convert to real time if this is + * required. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: + * @code{c} + * struct AMessage + * { + * char ucMessageID; + * char ucData[ 20 ]; + * } xMessage; + * + * QueueHandle_t xQueue; + * + * // Task to create a queue and post a value. + * void vATask( void *pvParameters ) + * { + * struct AMessage *pxMessage; + * + * // Create a queue capable of containing 10 pointers to AMessage structures. + * // These should be passed by pointer as they contain a lot of data. + * xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) ); + * if( xQueue == 0 ) + * { + * // Failed to create the queue. + * } + * + * // ... + * + * // Send a pointer to a struct AMessage object. Don't block if the + * // queue is already full. + * pxMessage = & xMessage; + * xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 ); + * + * // ... Rest of task code. + * } + * + * // Task to receive from the queue. + * void vADifferentTask( void *pvParameters ) + * { + * struct AMessage *pxRxedMessage; + * + * if( xQueue != 0 ) + * { + * // Receive a message on the created queue. Block for 10 ticks if a + * // message is not immediately available. + * if( xQueueReceive( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) ) + * { + * // pcRxedMessage now points to the struct AMessage variable posted + * // by vATask. + * } + * } + * + * // ... Rest of task code. + * } + * @endcode + * \ingroup QueueManagement + */ +//go:linkname XQueueReceive C.xQueueReceive +func XQueueReceive(xQueue QueueHandleT, pvBuffer c.Pointer, xTicksToWait TickTypeT) BaseTypeT + +/** + * + * Return the number of messages stored in a queue. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of messages available in the queue. + * + * \ingroup QueueManagement + */ +//go:linkname UxQueueMessagesWaiting C.uxQueueMessagesWaiting +func UxQueueMessagesWaiting(xQueue QueueHandleT) UBaseTypeT + +/** + * + * Return the number of free spaces available in a queue. This is equal to the + * number of items that can be sent to the queue before the queue becomes full + * if no items are removed. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of spaces available in the queue. + * + * \ingroup QueueManagement + */ +//go:linkname UxQueueSpacesAvailable C.uxQueueSpacesAvailable +func UxQueueSpacesAvailable(xQueue QueueHandleT) UBaseTypeT + +/** + * + * Delete a queue - freeing all the memory allocated for storing of items + * placed on the queue. + * + * @param xQueue A handle to the queue to be deleted. + * + * \ingroup QueueManagement + */ +//go:linkname VQueueDelete C.vQueueDelete +func VQueueDelete(xQueue QueueHandleT) + +/** + * + * It is preferred that the macros xQueueSendFromISR(), + * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place + * of calling this function directly. xQueueGiveFromISR() is an + * equivalent for use by semaphores that don't actually copy any data. + * + * Post an item on a queue. It is safe to use this function from within an + * interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): + * @code{c} + * void vBufferISR( void ) + * { + * char cIn; + * BaseType_t xHigherPriorityTaskWokenByPost; + * + * // We have not woken a task at the start of the ISR. + * xHigherPriorityTaskWokenByPost = pdFALSE; + * + * // Loop until the buffer is empty. + * do + * { + * // Obtain a byte from the buffer. + * cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS ); + * + * // Post each byte. + * xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK ); + * + * } while( portINPUT_BYTE( BUFFER_COUNT ) ); + * + * // Now the buffer is empty we can switch context if necessary. Note that the + * // name of the yield function required is port specific. + * if( xHigherPriorityTaskWokenByPost ) + * { + * portYIELD_FROM_ISR(); + * } + * } + * @endcode + * + * \ingroup QueueManagement + */ +//go:linkname XQueueGenericSendFromISR C.xQueueGenericSendFromISR +func XQueueGenericSendFromISR(xQueue QueueHandleT, pvItemToQueue c.Pointer, pxHigherPriorityTaskWoken *BaseTypeT, xCopyPosition BaseTypeT) BaseTypeT + +//go:linkname XQueueGiveFromISR C.xQueueGiveFromISR +func XQueueGiveFromISR(xQueue QueueHandleT, pxHigherPriorityTaskWoken *BaseTypeT) BaseTypeT + +/** + * + * Receive an item from a queue. It is safe to use this function from within an + * interrupt service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param pxHigherPriorityTaskWoken A task may be blocked waiting for space to + * become available on the queue. If xQueueReceiveFromISR causes such a task to + * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will + * remain unchanged. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: + * @code{c} + * + * QueueHandle_t xQueue; + * + * // Function to create a queue and post some values. + * void vAFunction( void *pvParameters ) + * { + * char cValueToPost; + * const TickType_t xTicksToWait = ( TickType_t )0xff; + * + * // Create a queue capable of containing 10 characters. + * xQueue = xQueueCreate( 10, sizeof( char ) ); + * if( xQueue == 0 ) + * { + * // Failed to create the queue. + * } + * + * // ... + * + * // Post some characters that will be used within an ISR. If the queue + * // is full then this task will block for xTicksToWait ticks. + * cValueToPost = 'a'; + * xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait ); + * cValueToPost = 'b'; + * xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait ); + * + * // ... keep posting characters ... this task may block when the queue + * // becomes full. + * + * cValueToPost = 'c'; + * xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait ); + * } + * + * // ISR that outputs all the characters received on the queue. + * void vISR_Routine( void ) + * { + * BaseType_t xTaskWokenByReceive = pdFALSE; + * char cRxedChar; + * + * while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) ) + * { + * // A character was received. Output the character now. + * vOutputCharacter( cRxedChar ); + * + * // If removing the character from the queue woke the task that was + * // posting onto the queue xTaskWokenByReceive will have been set to + * // pdTRUE. No matter how many times this loop iterates only one + * // task will be woken. + * } + * + * if( xTaskWokenByReceive != ( char ) pdFALSE; + * { + * taskYIELD (); + * } + * } + * @endcode + * \ingroup QueueManagement + */ +//go:linkname XQueueReceiveFromISR C.xQueueReceiveFromISR +func XQueueReceiveFromISR(xQueue QueueHandleT, pvBuffer c.Pointer, pxHigherPriorityTaskWoken *BaseTypeT) BaseTypeT + +/** + * Queries a queue to determine if the queue is empty. This function should only be used in an ISR. + * + * @param xQueue The handle of the queue being queried + * @return pdFALSE if the queue is not empty, or pdTRUE if the queue is empty. + */ +//go:linkname XQueueIsQueueEmptyFromISR C.xQueueIsQueueEmptyFromISR +func XQueueIsQueueEmptyFromISR(xQueue QueueHandleT) BaseTypeT + +/** + * Queries a queue to determine if the queue is full. This function should only be used in an ISR. + * + * @param xQueue The handle of the queue being queried + * @return pdFALSE if the queue is not full, or pdTRUE if the queue is full. + */ +//go:linkname XQueueIsQueueFullFromISR C.xQueueIsQueueFullFromISR +func XQueueIsQueueFullFromISR(xQueue QueueHandleT) BaseTypeT + +/** + * A version of uxQueueMessagesWaiting() that can be called from an ISR. Return the number of messages stored in a queue. + * + * @param xQueue A handle to the queue being queried. + * @return The number of messages available in the queue. + */ +//go:linkname UxQueueMessagesWaitingFromISR C.uxQueueMessagesWaitingFromISR +func UxQueueMessagesWaitingFromISR(xQueue QueueHandleT) UBaseTypeT + +/* + * The functions defined above are for passing data to and from tasks. The + * functions below are the equivalents for passing data to and from + * co-routines. + * + * These functions are called from the co-routine macro implementation and + * should not be called directly from application code. Instead use the macro + * wrappers defined within croutine.h. + */ +//go:linkname XQueueCRSendFromISR C.xQueueCRSendFromISR +func XQueueCRSendFromISR(xQueue QueueHandleT, pvItemToQueue c.Pointer, xCoRoutinePreviouslyWoken BaseTypeT) BaseTypeT + +//go:linkname XQueueCRReceiveFromISR C.xQueueCRReceiveFromISR +func XQueueCRReceiveFromISR(xQueue QueueHandleT, pvBuffer c.Pointer, pxTaskWoken *BaseTypeT) BaseTypeT + +//go:linkname XQueueCRSend C.xQueueCRSend +func XQueueCRSend(xQueue QueueHandleT, pvItemToQueue c.Pointer, xTicksToWait TickTypeT) BaseTypeT + +//go:linkname XQueueCRReceive C.xQueueCRReceive +func XQueueCRReceive(xQueue QueueHandleT, pvBuffer c.Pointer, xTicksToWait TickTypeT) BaseTypeT + +/* + * For internal use only. Use xSemaphoreCreateMutex(), + * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling + * these functions directly. + */ +//go:linkname XQueueCreateMutex C.xQueueCreateMutex +func XQueueCreateMutex(ucQueueType c.Uint8T) QueueHandleT + +//go:linkname XQueueCreateMutexStatic C.xQueueCreateMutexStatic +func XQueueCreateMutexStatic(ucQueueType c.Uint8T, pxStaticQueue *StaticQueueT) QueueHandleT + +// llgo:link UBaseTypeT.XQueueCreateCountingSemaphore C.xQueueCreateCountingSemaphore +func (recv_ UBaseTypeT) XQueueCreateCountingSemaphore(uxInitialCount UBaseTypeT) QueueHandleT { + return nil +} + +// llgo:link UBaseTypeT.XQueueCreateCountingSemaphoreStatic C.xQueueCreateCountingSemaphoreStatic +func (recv_ UBaseTypeT) XQueueCreateCountingSemaphoreStatic(uxInitialCount UBaseTypeT, pxStaticQueue *StaticQueueT) QueueHandleT { + return nil +} + +//go:linkname XQueueSemaphoreTake C.xQueueSemaphoreTake +func XQueueSemaphoreTake(xQueue QueueHandleT, xTicksToWait TickTypeT) BaseTypeT + +//go:linkname XQueueGetMutexHolder C.xQueueGetMutexHolder +func XQueueGetMutexHolder(xSemaphore QueueHandleT) TaskHandleT + +//go:linkname XQueueGetMutexHolderFromISR C.xQueueGetMutexHolderFromISR +func XQueueGetMutexHolderFromISR(xSemaphore QueueHandleT) TaskHandleT + +/* + * For internal use only. Use xSemaphoreTakeMutexRecursive() or + * xSemaphoreGiveMutexRecursive() instead of calling these functions directly. + */ +//go:linkname XQueueTakeMutexRecursive C.xQueueTakeMutexRecursive +func XQueueTakeMutexRecursive(xMutex QueueHandleT, xTicksToWait TickTypeT) BaseTypeT + +//go:linkname XQueueGiveMutexRecursive C.xQueueGiveMutexRecursive +func XQueueGiveMutexRecursive(xMutex QueueHandleT) BaseTypeT + +/* + * Generic version of the function used to create a queue using dynamic memory + * allocation. This is called by other functions and macros that create other + * RTOS objects that use the queue structure as their base. + */ +// llgo:link UBaseTypeT.XQueueGenericCreate C.xQueueGenericCreate +func (recv_ UBaseTypeT) XQueueGenericCreate(uxItemSize UBaseTypeT, ucQueueType c.Uint8T) QueueHandleT { + return nil +} + +/* + * Generic version of the function used to create a queue using dynamic memory + * allocation. This is called by other functions and macros that create other + * RTOS objects that use the queue structure as their base. + */ +// llgo:link UBaseTypeT.XQueueGenericCreateStatic C.xQueueGenericCreateStatic +func (recv_ UBaseTypeT) XQueueGenericCreateStatic(uxItemSize UBaseTypeT, pucQueueStorage *c.Uint8T, pxStaticQueue *StaticQueueT, ucQueueType c.Uint8T) QueueHandleT { + return nil +} + +/* + * Generic version of the function used to retrieve the buffers of statically + * created queues. This is called by other functions and macros that retrieve + * the buffers of other statically created RTOS objects that use the queue + * structure as their base. + */ +//go:linkname XQueueGenericGetStaticBuffers C.xQueueGenericGetStaticBuffers +func XQueueGenericGetStaticBuffers(xQueue QueueHandleT, ppucQueueStorage **c.Uint8T, ppxStaticQueue **StaticQueueT) BaseTypeT + +/** + * Queue sets provide a mechanism to allow a task to block (pend) on a read + * operation from multiple queues or semaphores simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * A queue set must be explicitly created using a call to xQueueCreateSet() + * before it can be used. Once created, standard FreeRTOS queues and semaphores + * can be added to the set using calls to xQueueAddToSet(). + * xQueueSelectFromSet() is then used to determine which, if any, of the queues + * or semaphores contained in the set is in a state where a queue read or + * semaphore take operation would be successful. + * + * Note 1: See the documentation on https://www.FreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: An additional 4 bytes of RAM is required for each space in a every + * queue added to a queue set. Therefore counting semaphores that have a high + * maximum count value should not be added to a queue set. + * + * Note 4: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param uxEventQueueLength Queue sets store events that occur on + * the queues and semaphores contained in the set. uxEventQueueLength specifies + * the maximum number of events that can be queued at once. To be absolutely + * certain that events are not lost uxEventQueueLength should be set to the + * total sum of the length of the queues added to the set, where binary + * semaphores and mutexes have a length of 1, and counting semaphores have a + * length set by their maximum count value. Examples: + * + If a queue set is to hold a queue of length 5, another queue of length 12, + * and a binary semaphore, then uxEventQueueLength should be set to + * (5 + 12 + 1), or 18. + * + If a queue set is to hold three binary semaphores then uxEventQueueLength + * should be set to (1 + 1 + 1 ), or 3. + * + If a queue set is to hold a counting semaphore that has a maximum count of + * 5, and a counting semaphore that has a maximum count of 3, then + * uxEventQueueLength should be set to (5 + 3), or 8. + * + * @return If the queue set is created successfully then a handle to the created + * queue set is returned. Otherwise NULL is returned. + */ +// llgo:link UBaseTypeT.XQueueCreateSet C.xQueueCreateSet +func (recv_ UBaseTypeT) XQueueCreateSet() QueueSetHandleT { + return nil +} + +/** + * Adds a queue or semaphore to a queue set that was previously created by a + * call to xQueueCreateSet(). + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being added to + * the queue set (cast to an QueueSetMemberHandle_t type). + * + * @param xQueueSet The handle of the queue set to which the queue or semaphore + * is being added. + * + * @return If the queue or semaphore was successfully added to the queue set + * then pdPASS is returned. If the queue could not be successfully added to the + * queue set because it is already a member of a different queue set then pdFAIL + * is returned. + */ +//go:linkname XQueueAddToSet C.xQueueAddToSet +func XQueueAddToSet(xQueueOrSemaphore QueueSetMemberHandleT, xQueueSet QueueSetHandleT) BaseTypeT + +/** + * Removes a queue or semaphore from a queue set. A queue or semaphore can only + * be removed from a set if the queue or semaphore is empty. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being removed + * from the queue set (cast to an QueueSetMemberHandle_t type). + * + * @param xQueueSet The handle of the queue set in which the queue or semaphore + * is included. + * + * @return If the queue or semaphore was successfully removed from the queue set + * then pdPASS is returned. If the queue was not in the queue set, or the + * queue (or semaphore) was not empty, then pdFAIL is returned. + */ +//go:linkname XQueueRemoveFromSet C.xQueueRemoveFromSet +func XQueueRemoveFromSet(xQueueOrSemaphore QueueSetMemberHandleT, xQueueSet QueueSetHandleT) BaseTypeT + +/** + * xQueueSelectFromSet() selects from the members of a queue set a queue or + * semaphore that either contains data (in the case of a queue) or is available + * to take (in the case of a semaphore). xQueueSelectFromSet() effectively + * allows a task to block (pend) on a read operation on all the queues and + * semaphores in a queue set simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: See the documentation on https://www.FreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueSet The queue set on which the task will (potentially) block. + * + * @param xTicksToWait The maximum time, in ticks, that the calling task will + * remain in the Blocked state (with other tasks executing) to wait for a member + * of the queue set to be ready for a successful queue read or semaphore take + * operation. + * + * @return xQueueSelectFromSet() will return the handle of a queue (cast to + * a QueueSetMemberHandle_t type) contained in the queue set that contains data, + * or the handle of a semaphore (cast to a QueueSetMemberHandle_t type) contained + * in the queue set that is available, or NULL if no such queue or semaphore + * exists before before the specified block time expires. + */ +//go:linkname XQueueSelectFromSet C.xQueueSelectFromSet +func XQueueSelectFromSet(xQueueSet QueueSetHandleT, xTicksToWait TickTypeT) QueueSetMemberHandleT + +/** + * A version of xQueueSelectFromSet() that can be used from an ISR. + */ +//go:linkname XQueueSelectFromSetFromISR C.xQueueSelectFromSetFromISR +func XQueueSelectFromSetFromISR(xQueueSet QueueSetHandleT) QueueSetMemberHandleT + +/* Not public API functions. */ +//go:linkname VQueueWaitForMessageRestricted C.vQueueWaitForMessageRestricted +func VQueueWaitForMessageRestricted(xQueue QueueHandleT, xTicksToWait TickTypeT, xWaitIndefinitely BaseTypeT) + +//go:linkname XQueueGenericReset C.xQueueGenericReset +func XQueueGenericReset(xQueue QueueHandleT, xNewQueue BaseTypeT) BaseTypeT + +//go:linkname VQueueSetQueueNumber C.vQueueSetQueueNumber +func VQueueSetQueueNumber(xQueue QueueHandleT, uxQueueNumber UBaseTypeT) + +//go:linkname UxQueueGetQueueNumber C.uxQueueGetQueueNumber +func UxQueueGetQueueNumber(xQueue QueueHandleT) UBaseTypeT + +//go:linkname UcQueueGetQueueType C.ucQueueGetQueueType +func UcQueueGetQueueType(xQueue QueueHandleT) c.Uint8T diff --git a/freertos/reent.go b/freertos/reent.go new file mode 100644 index 00000000..38613276 --- /dev/null +++ b/freertos/reent.go @@ -0,0 +1,11 @@ +package freertos + +import _ "unsafe" + +type X_glue struct { + Unused [8]uint8 +} + +type X_reent struct { + Unused [8]uint8 +} diff --git a/freertos/semphr.go b/freertos/semphr.go new file mode 100644 index 00000000..0c16a44b --- /dev/null +++ b/freertos/semphr.go @@ -0,0 +1,5 @@ +package freertos + +import _ "unsafe" + +type SemaphoreHandleT QueueHandleT diff --git a/freertos/spinlock.go b/freertos/spinlock.go new file mode 100644 index 00000000..1b494791 --- /dev/null +++ b/freertos/spinlock.go @@ -0,0 +1,16 @@ +package freertos + +import ( + "github.com/goplus/lib/c" + _ "unsafe" +) + +const SPINLOCK_FREE = 0xB33FFFFF +const SPINLOCK_NO_WAIT = 0 +const SPINLOCK_OWNER_ID_0 = 0xCDCD +const SPINLOCK_OWNER_ID_1 = 0xABAB + +type SpinlockT struct { + Owner c.Uint32T + Count c.Uint32T +} diff --git a/freertos/stack_macros.go b/freertos/stack_macros.go new file mode 100644 index 00000000..5cf341ab --- /dev/null +++ b/freertos/stack_macros.go @@ -0,0 +1,5 @@ +package freertos + +import _ "unsafe" + +const PortSTACK_LIMIT_PADDING = 0 diff --git a/freertos/stream_buffer.go b/freertos/stream_buffer.go new file mode 100644 index 00000000..c9829449 --- /dev/null +++ b/freertos/stream_buffer.go @@ -0,0 +1,579 @@ +package freertos + +import ( + "github.com/goplus/lib/c" + _ "unsafe" +) + +/** + * Type by which stream buffers are referenced. For example, a call to + * xStreamBufferCreate() returns an StreamBufferHandle_t variable that can + * then be used as a parameter to xStreamBufferSend(), xStreamBufferReceive(), + * etc. + */ + +type StreamBufferDefT struct { + Unused [8]uint8 +} +type StreamBufferHandleT *StreamBufferDefT + +// llgo:type C +type StreamBufferCallbackFunctionT func(StreamBufferHandleT, BaseTypeT, *BaseTypeT) + +/** + * + * Retrieve pointers to a statically created stream buffer's data structure + * buffer and storage area buffer. These are the same buffers that are supplied + * at the time of creation. + * + * @param xStreamBuffer The stream buffer for which to retrieve the buffers. + * + * @param ppucStreamBufferStorageArea Used to return a pointer to the stream + * buffer's storage area buffer. + * + * @param ppxStaticStreamBuffer Used to return a pointer to the stream + * buffer's data structure buffer. + * + * @return pdTRUE if buffers were retrieved, pdFALSE otherwise. + * + * \ingroup StreamBufferManagement + */ +//go:linkname XStreamBufferGetStaticBuffers C.xStreamBufferGetStaticBuffers +func XStreamBufferGetStaticBuffers(xStreamBuffer StreamBufferHandleT, ppucStreamBufferStorageArea **c.Uint8T, ppxStaticStreamBuffer **StaticStreamBufferT) BaseTypeT + +/** + * + * Sends bytes to a stream buffer. The bytes are copied into the stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferReceive()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferSend() to write to a stream buffer from a task. Use + * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt + * service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer to which a stream is + * being sent. + * + * @param pvTxData A pointer to the buffer that holds the bytes to be copied + * into the stream buffer. + * + * @param xDataLengthBytes The maximum number of bytes to copy from pvTxData + * into the stream buffer. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for enough space to become available in the stream + * buffer, should the stream buffer contain too little space to hold the + * another xDataLengthBytes bytes. The block time is specified in tick periods, + * so the absolute time it represents is dependent on the tick frequency. The + * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds + * into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will + * cause the task to wait indefinitely (without timing out), provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. If a task times out + * before it can write all xDataLengthBytes into the buffer it will still write + * as many bytes as possible. A task does not use any CPU time when it is in + * the blocked state. + * + * @return The number of bytes written to the stream buffer. If a task times + * out before it can write all xDataLengthBytes into the buffer it will still + * write as many bytes as possible. + * + * Example use: + * @code{c} + * void vAFunction( StreamBufferHandle_t xStreamBuffer ) + * { + * size_t xBytesSent; + * uint8_t ucArrayToSend[] = { 0, 1, 2, 3 }; + * char *pcStringToSend = "String to send"; + * const TickType_t x100ms = pdMS_TO_TICKS( 100 ); + * + * // Send an array to the stream buffer, blocking for a maximum of 100ms to + * // wait for enough space to be available in the stream buffer. + * xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms ); + * + * if( xBytesSent != sizeof( ucArrayToSend ) ) + * { + * // The call to xStreamBufferSend() times out before there was enough + * // space in the buffer for the data to be written, but it did + * // successfully write xBytesSent bytes. + * } + * + * // Send the string to the stream buffer. Return immediately if there is not + * // enough space in the buffer. + * xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 ); + * + * if( xBytesSent != strlen( pcStringToSend ) ) + * { + * // The entire string could not be added to the stream buffer because + * // there was not enough free space in the buffer, but xBytesSent bytes + * // were sent. Could try again to send the remaining bytes. + * } + * } + * @endcode + * \ingroup StreamBufferManagement + */ +//go:linkname XStreamBufferSend C.xStreamBufferSend +func XStreamBufferSend(xStreamBuffer StreamBufferHandleT, pvTxData c.Pointer, xDataLengthBytes c.SizeT, xTicksToWait TickTypeT) c.SizeT + +/** + * + * Interrupt safe version of the API function that sends a stream of bytes to + * the stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferReceive()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferSend() to write to a stream buffer from a task. Use + * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt + * service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer to which a stream is + * being sent. + * + * @param pvTxData A pointer to the data that is to be copied into the stream + * buffer. + * + * @param xDataLengthBytes The maximum number of bytes to copy from pvTxData + * into the stream buffer. + * + * @param pxHigherPriorityTaskWoken It is possible that a stream buffer will + * have a task blocked on it waiting for data. Calling + * xStreamBufferSendFromISR() can make data available, and so cause a task that + * was waiting for data to leave the Blocked state. If calling + * xStreamBufferSendFromISR() causes a task to leave the Blocked state, and the + * unblocked task has a priority higher than the currently executing task (the + * task that was interrupted), then, internally, xStreamBufferSendFromISR() + * will set *pxHigherPriorityTaskWoken to pdTRUE. If + * xStreamBufferSendFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. This will + * ensure that the interrupt returns directly to the highest priority Ready + * state task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it + * is passed into the function. See the example code below for an example. + * + * @return The number of bytes actually written to the stream buffer, which will + * be less than xDataLengthBytes if the stream buffer didn't have enough free + * space for all the bytes to be written. + * + * Example use: + * @code{c} + * // A stream buffer that has already been created. + * StreamBufferHandle_t xStreamBuffer; + * + * void vAnInterruptServiceRoutine( void ) + * { + * size_t xBytesSent; + * char *pcStringToSend = "String to send"; + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. + * + * // Attempt to send the string to the stream buffer. + * xBytesSent = xStreamBufferSendFromISR( xStreamBuffer, + * ( void * ) pcStringToSend, + * strlen( pcStringToSend ), + * &xHigherPriorityTaskWoken ); + * + * if( xBytesSent != strlen( pcStringToSend ) ) + * { + * // There was not enough free space in the stream buffer for the entire + * // string to be written, ut xBytesSent bytes were written. + * } + * + * // If xHigherPriorityTaskWoken was set to pdTRUE inside + * // xStreamBufferSendFromISR() then a task that has a priority above the + * // priority of the currently executing task was unblocked and a context + * // switch should be performed to ensure the ISR returns to the unblocked + * // task. In most FreeRTOS ports this is done by simply passing + * // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the + * // variables value, and perform the context switch if necessary. Check the + * // documentation for the port in use for port specific instructions. + * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + * } + * @endcode + * \ingroup StreamBufferManagement + */ +//go:linkname XStreamBufferSendFromISR C.xStreamBufferSendFromISR +func XStreamBufferSendFromISR(xStreamBuffer StreamBufferHandleT, pvTxData c.Pointer, xDataLengthBytes c.SizeT, pxHigherPriorityTaskWoken *BaseTypeT) c.SizeT + +/** + * + * Receives bytes from a stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferReceive()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferReceive() to read from a stream buffer from a task. Use + * xStreamBufferReceiveFromISR() to read from a stream buffer from an + * interrupt service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer from which bytes are to + * be received. + * + * @param pvRxData A pointer to the buffer into which the received bytes will be + * copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the + * pvRxData parameter. This sets the maximum number of bytes to receive in one + * call. xStreamBufferReceive will return as many bytes as possible up to a + * maximum set by xBufferLengthBytes. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for data to become available if the stream buffer is + * empty. xStreamBufferReceive() will return immediately if xTicksToWait is + * zero. The block time is specified in tick periods, so the absolute time it + * represents is dependent on the tick frequency. The macro pdMS_TO_TICKS() can + * be used to convert a time specified in milliseconds into a time specified in + * ticks. Setting xTicksToWait to portMAX_DELAY will cause the task to wait + * indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1 + * in FreeRTOSConfig.h. A task does not use any CPU time when it is in the + * Blocked state. + * + * @return The number of bytes actually read from the stream buffer, which will + * be less than xBufferLengthBytes if the call to xStreamBufferReceive() timed + * out before xBufferLengthBytes were available. + * + * Example use: + * @code{c} + * void vAFunction( StreamBuffer_t xStreamBuffer ) + * { + * uint8_t ucRxData[ 20 ]; + * size_t xReceivedBytes; + * const TickType_t xBlockTime = pdMS_TO_TICKS( 20 ); + * + * // Receive up to another sizeof( ucRxData ) bytes from the stream buffer. + * // Wait in the Blocked state (so not using any CPU processing time) for a + * // maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be + * // available. + * xReceivedBytes = xStreamBufferReceive( xStreamBuffer, + * ( void * ) ucRxData, + * sizeof( ucRxData ), + * xBlockTime ); + * + * if( xReceivedBytes > 0 ) + * { + * // A ucRxData contains another xReceivedBytes bytes of data, which can + * // be processed here.... + * } + * } + * @endcode + * \ingroup StreamBufferManagement + */ +//go:linkname XStreamBufferReceive C.xStreamBufferReceive +func XStreamBufferReceive(xStreamBuffer StreamBufferHandleT, pvRxData c.Pointer, xBufferLengthBytes c.SizeT, xTicksToWait TickTypeT) c.SizeT + +/** + * + * An interrupt safe version of the API function that receives bytes from a + * stream buffer. + * + * Use xStreamBufferReceive() to read bytes from a stream buffer from a task. + * Use xStreamBufferReceiveFromISR() to read bytes from a stream buffer from an + * interrupt service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer from which a stream + * is being received. + * + * @param pvRxData A pointer to the buffer into which the received bytes are + * copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the + * pvRxData parameter. This sets the maximum number of bytes to receive in one + * call. xStreamBufferReceive will return as many bytes as possible up to a + * maximum set by xBufferLengthBytes. + * + * @param pxHigherPriorityTaskWoken It is possible that a stream buffer will + * have a task blocked on it waiting for space to become available. Calling + * xStreamBufferReceiveFromISR() can make space available, and so cause a task + * that is waiting for space to leave the Blocked state. If calling + * xStreamBufferReceiveFromISR() causes a task to leave the Blocked state, and + * the unblocked task has a priority higher than the currently executing task + * (the task that was interrupted), then, internally, + * xStreamBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE. + * If xStreamBufferReceiveFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. That will + * ensure the interrupt returns directly to the highest priority Ready state + * task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is + * passed into the function. See the code example below for an example. + * + * @return The number of bytes read from the stream buffer, if any. + * + * Example use: + * @code{c} + * // A stream buffer that has already been created. + * StreamBuffer_t xStreamBuffer; + * + * void vAnInterruptServiceRoutine( void ) + * { + * uint8_t ucRxData[ 20 ]; + * size_t xReceivedBytes; + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. + * + * // Receive the next stream from the stream buffer. + * xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer, + * ( void * ) ucRxData, + * sizeof( ucRxData ), + * &xHigherPriorityTaskWoken ); + * + * if( xReceivedBytes > 0 ) + * { + * // ucRxData contains xReceivedBytes read from the stream buffer. + * // Process the stream here.... + * } + * + * // If xHigherPriorityTaskWoken was set to pdTRUE inside + * // xStreamBufferReceiveFromISR() then a task that has a priority above the + * // priority of the currently executing task was unblocked and a context + * // switch should be performed to ensure the ISR returns to the unblocked + * // task. In most FreeRTOS ports this is done by simply passing + * // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the + * // variables value, and perform the context switch if necessary. Check the + * // documentation for the port in use for port specific instructions. + * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + * } + * @endcode + * \ingroup StreamBufferManagement + */ +//go:linkname XStreamBufferReceiveFromISR C.xStreamBufferReceiveFromISR +func XStreamBufferReceiveFromISR(xStreamBuffer StreamBufferHandleT, pvRxData c.Pointer, xBufferLengthBytes c.SizeT, pxHigherPriorityTaskWoken *BaseTypeT) c.SizeT + +/** + * + * Deletes a stream buffer that was previously created using a call to + * xStreamBufferCreate() or xStreamBufferCreateStatic(). If the stream + * buffer was created using dynamic memory (that is, by xStreamBufferCreate()), + * then the allocated memory is freed. + * + * A stream buffer handle must not be used after the stream buffer has been + * deleted. + * + * @param xStreamBuffer The handle of the stream buffer to be deleted. + * + * \ingroup StreamBufferManagement + */ +//go:linkname VStreamBufferDelete C.vStreamBufferDelete +func VStreamBufferDelete(xStreamBuffer StreamBufferHandleT) + +/** + * + * Queries a stream buffer to see if it is full. A stream buffer is full if it + * does not have any free space, and therefore cannot accept any more data. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return If the stream buffer is full then pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \ingroup StreamBufferManagement + */ +//go:linkname XStreamBufferIsFull C.xStreamBufferIsFull +func XStreamBufferIsFull(xStreamBuffer StreamBufferHandleT) BaseTypeT + +/** + * + * Queries a stream buffer to see if it is empty. A stream buffer is empty if + * it does not contain any data. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return If the stream buffer is empty then pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \ingroup StreamBufferManagement + */ +//go:linkname XStreamBufferIsEmpty C.xStreamBufferIsEmpty +func XStreamBufferIsEmpty(xStreamBuffer StreamBufferHandleT) BaseTypeT + +/** + * + * Resets a stream buffer to its initial, empty, state. Any data that was in + * the stream buffer is discarded. A stream buffer can only be reset if there + * are no tasks blocked waiting to either send to or receive from the stream + * buffer. + * + * @param xStreamBuffer The handle of the stream buffer being reset. + * + * @return If the stream buffer is reset then pdPASS is returned. If there was + * a task blocked waiting to send to or read from the stream buffer then the + * stream buffer is not reset and pdFAIL is returned. + * + * \ingroup StreamBufferManagement + */ +//go:linkname XStreamBufferReset C.xStreamBufferReset +func XStreamBufferReset(xStreamBuffer StreamBufferHandleT) BaseTypeT + +/** + * + * Queries a stream buffer to see how much free space it contains, which is + * equal to the amount of data that can be sent to the stream buffer before it + * is full. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return The number of bytes that can be written to the stream buffer before + * the stream buffer would be full. + * + * \ingroup StreamBufferManagement + */ +//go:linkname XStreamBufferSpacesAvailable C.xStreamBufferSpacesAvailable +func XStreamBufferSpacesAvailable(xStreamBuffer StreamBufferHandleT) c.SizeT + +/** + * + * Queries a stream buffer to see how much data it contains, which is equal to + * the number of bytes that can be read from the stream buffer before the stream + * buffer would be empty. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return The number of bytes that can be read from the stream buffer before + * the stream buffer would be empty. + * + * \ingroup StreamBufferManagement + */ +//go:linkname XStreamBufferBytesAvailable C.xStreamBufferBytesAvailable +func XStreamBufferBytesAvailable(xStreamBuffer StreamBufferHandleT) c.SizeT + +/** + * + * A stream buffer's trigger level is the number of bytes that must be in the + * stream buffer before a task that is blocked on the stream buffer to + * wait for data is moved out of the blocked state. For example, if a task is + * blocked on a read of an empty stream buffer that has a trigger level of 1 + * then the task will be unblocked when a single byte is written to the buffer + * or the task's block time expires. As another example, if a task is blocked + * on a read of an empty stream buffer that has a trigger level of 10 then the + * task will not be unblocked until the stream buffer contains at least 10 bytes + * or the task's block time expires. If a reading task's block time expires + * before the trigger level is reached then the task will still receive however + * many bytes are actually available. Setting a trigger level of 0 will result + * in a trigger level of 1 being used. It is not valid to specify a trigger + * level that is greater than the buffer size. + * + * A trigger level is set when the stream buffer is created, and can be modified + * using xStreamBufferSetTriggerLevel(). + * + * @param xStreamBuffer The handle of the stream buffer being updated. + * + * @param xTriggerLevel The new trigger level for the stream buffer. + * + * @return If xTriggerLevel was less than or equal to the stream buffer's length + * then the trigger level will be updated and pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \ingroup StreamBufferManagement + */ +//go:linkname XStreamBufferSetTriggerLevel C.xStreamBufferSetTriggerLevel +func XStreamBufferSetTriggerLevel(xStreamBuffer StreamBufferHandleT, xTriggerLevel c.SizeT) BaseTypeT + +/** + * + * For advanced users only. + * + * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is sent to a message buffer or stream buffer. If there was a task that + * was blocked on the message or stream buffer waiting for data to arrive then + * the sbSEND_COMPLETED() macro sends a notification to the task to remove it + * from the Blocked state. xStreamBufferSendCompletedFromISR() does the same + * thing. It is provided to enable application writers to implement their own + * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer to which data was + * written. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xStreamBufferSendCompletedFromISR(). If calling + * xStreamBufferSendCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \ingroup StreamBufferManagement + */ +//go:linkname XStreamBufferSendCompletedFromISR C.xStreamBufferSendCompletedFromISR +func XStreamBufferSendCompletedFromISR(xStreamBuffer StreamBufferHandleT, pxHigherPriorityTaskWoken *BaseTypeT) BaseTypeT + +/** + * + * For advanced users only. + * + * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is read out of a message buffer or stream buffer. If there was a task + * that was blocked on the message or stream buffer waiting for data to arrive + * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to + * remove it from the Blocked state. xStreamBufferReceiveCompletedFromISR() + * does the same thing. It is provided to enable application writers to + * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT + * ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer from which data was + * read. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xStreamBufferReceiveCompletedFromISR(). If calling + * xStreamBufferReceiveCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \ingroup StreamBufferManagement + */ +//go:linkname XStreamBufferReceiveCompletedFromISR C.xStreamBufferReceiveCompletedFromISR +func XStreamBufferReceiveCompletedFromISR(xStreamBuffer StreamBufferHandleT, pxHigherPriorityTaskWoken *BaseTypeT) BaseTypeT + +/* Functions below here are not part of the public API. */ +//go:linkname XStreamBufferGenericCreate C.xStreamBufferGenericCreate +func XStreamBufferGenericCreate(xBufferSizeBytes c.SizeT, xTriggerLevelBytes c.SizeT, xIsMessageBuffer BaseTypeT, pxSendCompletedCallback StreamBufferCallbackFunctionT, pxReceiveCompletedCallback StreamBufferCallbackFunctionT) StreamBufferHandleT + +//go:linkname XStreamBufferGenericCreateStatic C.xStreamBufferGenericCreateStatic +func XStreamBufferGenericCreateStatic(xBufferSizeBytes c.SizeT, xTriggerLevelBytes c.SizeT, xIsMessageBuffer BaseTypeT, pucStreamBufferStorageArea *c.Uint8T, pxStaticStreamBuffer *StaticStreamBufferT, pxSendCompletedCallback StreamBufferCallbackFunctionT, pxReceiveCompletedCallback StreamBufferCallbackFunctionT) StreamBufferHandleT + +//go:linkname XStreamBufferNextMessageLengthBytes C.xStreamBufferNextMessageLengthBytes +func XStreamBufferNextMessageLengthBytes(xStreamBuffer StreamBufferHandleT) c.SizeT diff --git a/freertos/task.go b/freertos/task.go new file mode 100644 index 00000000..a0ea0f2b --- /dev/null +++ b/freertos/task.go @@ -0,0 +1,2179 @@ +package freertos + +import ( + "github.com/goplus/lib/c" + _ "unsafe" +) + +const TskKERNEL_VERSION_NUMBER = "V10.5.1" +const TskKERNEL_VERSION_MAJOR = 10 +const TskKERNEL_VERSION_MINOR = 5 +const TskKERNEL_VERSION_BUILD = 1 + +/** + * + * Type by which tasks are referenced. For example, a call to xTaskCreate + * returns (via a pointer parameter) an TaskHandle_t variable that can then + * be used as a parameter to vTaskDelete to delete the task. + * + * \ingroup Tasks + */ + +type TskTaskControlBlock struct { + Unused [8]uint8 +} +type TaskHandleT *TskTaskControlBlock + +// llgo:type C +type TaskHookFunctionT func(c.Pointer) BaseTypeT +type ETaskState c.Int + +const ( + ERunning ETaskState = 0 + EReady ETaskState = 1 + EBlocked ETaskState = 2 + ESuspended ETaskState = 3 + EDeleted ETaskState = 4 + EInvalid ETaskState = 5 +) + +type ENotifyAction c.Int + +const ( + ENoAction ENotifyAction = 0 + ESetBits ENotifyAction = 1 + EIncrement ENotifyAction = 2 + ESetValueWithOverwrite ENotifyAction = 3 + ESetValueWithoutOverwrite ENotifyAction = 4 +) + +/* + * Used internally only. + */ + +type XTIMEOUT struct { + XOverflowCount BaseTypeT + XTimeOnEntering TickTypeT +} +type TimeOutT XTIMEOUT + +/* + * Defines the memory ranges allocated to the task when an MPU is used. + */ + +type XMEMORYREGION struct { + PvBaseAddress c.Pointer + UlLengthInBytes c.Uint32T + UlParameters c.Uint32T +} +type MemoryRegionT XMEMORYREGION + +/* + * Parameters required to create an MPU protected task. + */ + +type XTASKPARAMETERS struct { + PvTaskCode TaskFunctionT + PcName *c.Char + UsStackDepth c.Uint32T + PvParameters c.Pointer + UxPriority UBaseTypeT + PuxStackBuffer *StackTypeT + XRegions [1]MemoryRegionT +} +type TaskParametersT XTASKPARAMETERS + +/** Used with the uxTaskGetSystemState() function to return the state of each task + * in the system. */ + +type XTASKSTATUS struct { + XHandle TaskHandleT + PcTaskName *c.Char + XTaskNumber UBaseTypeT + ECurrentState ETaskState + UxCurrentPriority UBaseTypeT + UxBasePriority UBaseTypeT + UlRunTimeCounter c.Uint32T + PxStackBase *StackTypeT + UsStackHighWaterMark c.Uint32T +} +type TaskStatusT XTASKSTATUS +type ESleepModeStatus c.Int + +const ( + EAbortSleep ESleepModeStatus = 0 + EStandardSleep ESleepModeStatus = 1 + ENoTasksWaitingTimeout ESleepModeStatus = 2 +) + +/** + * + * Memory regions are assigned to a restricted task when the task is created by + * a call to xTaskCreateRestricted(). These regions can be redefined using + * vTaskAllocateMPURegions(). + * + * @param xTask The handle of the task being updated. + * + * @param pxRegions A pointer to a MemoryRegion_t structure that contains the + * new memory region definitions. + * + * Example usage: + * @code{c} + * // Define an array of MemoryRegion_t structures that configures an MPU region + * // allowing read/write access for 1024 bytes starting at the beginning of the + * // ucOneKByte array. The other two of the maximum 3 definable regions are + * // unused so set to zero. + * static const MemoryRegion_t xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] = + * { + * // Base address Length Parameters + * { ucOneKByte, 1024, portMPU_REGION_READ_WRITE }, + * { 0, 0, 0 }, + * { 0, 0, 0 } + * }; + * + * void vATask( void *pvParameters ) + * { + * // This task was created such that it has access to certain regions of + * // memory as defined by the MPU configuration. At some point it is + * // desired that these MPU regions are replaced with that defined in the + * // xAltRegions const struct above. Use a call to vTaskAllocateMPURegions() + * // for this purpose. NULL is used as the task handle to indicate that this + * // function should modify the MPU regions of the calling task. + * vTaskAllocateMPURegions( NULL, xAltRegions ); + * + * // Now the task can continue its function, but from this point on can only + * // access its stack and the ucOneKByte array (unless any other statically + * // defined or shared regions have been declared elsewhere). + * } + * @endcode + * \ingroup Tasks + */ +//go:linkname VTaskAllocateMPURegions C.vTaskAllocateMPURegions +func VTaskAllocateMPURegions(xTask TaskHandleT, pxRegions *MemoryRegionT) + +/** + * + * INCLUDE_vTaskDelete must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Remove a task from the RTOS real time kernel's management. The task being + * deleted will be removed from all ready, blocked, suspended and event lists. + * + * NOTE: The idle task is responsible for freeing the kernel allocated + * memory from tasks that have been deleted. It is therefore important that + * the idle task is not starved of microcontroller processing time if your + * application makes any calls to vTaskDelete (). Memory allocated by the + * task code is not automatically freed, and should be freed before the task + * is deleted. + * + * See the demo application file death.c for sample code that utilises + * vTaskDelete (). + * + * @param xTaskToDelete The handle of the task to be deleted. Passing NULL will + * cause the calling task to be deleted. + * + * Example usage: + * @code{c} + * void vOtherFunction( void ) + * { + * TaskHandle_t xHandle; + * + * // Create the task, storing the handle. + * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); + * + * // Use the handle to delete the task. + * vTaskDelete( xHandle ); + * } + * @endcode + * \ingroup Tasks + */ +//go:linkname VTaskDelete C.vTaskDelete +func VTaskDelete(xTaskToDelete TaskHandleT) + +/** + * + * Delay a task for a given number of ticks. The actual time that the + * task remains blocked depends on the tick rate. The constant + * portTICK_PERIOD_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * INCLUDE_vTaskDelay must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * + * vTaskDelay() specifies a time at which the task wishes to unblock relative to + * the time at which vTaskDelay() is called. For example, specifying a block + * period of 100 ticks will cause the task to unblock 100 ticks after + * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method + * of controlling the frequency of a periodic task as the path taken through the + * code, as well as other task and interrupt activity, will affect the frequency + * at which vTaskDelay() gets called and therefore the time at which the task + * next executes. See xTaskDelayUntil() for an alternative API function designed + * to facilitate fixed frequency execution. It does this by specifying an + * absolute time (rather than a relative time) at which the calling task should + * unblock. + * + * @param xTicksToDelay The amount of time, in tick periods, that + * the calling task should block. + * + * Example usage: + * @code{c} + * void vTaskFunction( void * pvParameters ) + * { + * // Block for 500ms. + * const TickType_t xDelay = 500 / portTICK_PERIOD_MS; + * + * for( ;; ) + * { + * // Simply toggle the LED every 500ms, blocking between each toggle. + * vToggleLED(); + * vTaskDelay( xDelay ); + * } + * } + * @endcode + * \ingroup TaskCtrl + */ +// llgo:link TickTypeT.VTaskDelay C.vTaskDelay +func (recv_ TickTypeT) VTaskDelay() { +} + +/** + * + * INCLUDE_xTaskDelayUntil must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Delay a task until a specified time. This function can be used by periodic + * tasks to ensure a constant execution frequency. + * + * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will + * cause a task to block for the specified number of ticks from the time vTaskDelay () is + * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed + * execution frequency as the time between a task starting to execute and that task + * calling vTaskDelay () may not be fixed [the task may take a different path though the + * code between calls, or may get interrupted or preempted a different number of times + * each time it executes]. + * + * Whereas vTaskDelay () specifies a wake time relative to the time at which the function + * is called, xTaskDelayUntil () specifies the absolute (exact) time at which it wishes to + * unblock. + * + * The macro pdMS_TO_TICKS() can be used to calculate the number of ticks from a + * time specified in milliseconds with a resolution of one tick period. + * + * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the + * task was last unblocked. The variable must be initialised with the current time + * prior to its first use (see the example below). Following this the variable is + * automatically updated within xTaskDelayUntil (). + * + * @param xTimeIncrement The cycle time period. The task will be unblocked at + * time *pxPreviousWakeTime + xTimeIncrement. Calling xTaskDelayUntil with the + * same xTimeIncrement parameter value will cause the task to execute with + * a fixed interface period. + * + * @return Value which can be used to check whether the task was actually delayed. + * Will be pdTRUE if the task way delayed and pdFALSE otherwise. A task will not + * be delayed if the next expected wake time is in the past. + * + * Example usage: + * @code{c} + * // Perform an action every 10 ticks. + * void vTaskFunction( void * pvParameters ) + * { + * TickType_t xLastWakeTime; + * const TickType_t xFrequency = 10; + * BaseType_t xWasDelayed; + * + * // Initialise the xLastWakeTime variable with the current time. + * xLastWakeTime = xTaskGetTickCount (); + * for( ;; ) + * { + * // Wait for the next cycle. + * xWasDelayed = xTaskDelayUntil( &xLastWakeTime, xFrequency ); + * + * // Perform action here. xWasDelayed value can be used to determine + * // whether a deadline was missed if the code here took too long. + * } + * } + * @endcode + * \ingroup TaskCtrl + */ +// llgo:link (*TickTypeT).XTaskDelayUntil C.xTaskDelayUntil +func (recv_ *TickTypeT) XTaskDelayUntil(xTimeIncrement TickTypeT) BaseTypeT { + return 0 +} + +/** + * + * INCLUDE_xTaskAbortDelay must be defined as 1 in FreeRTOSConfig.h for this + * function to be available. + * + * A task will enter the Blocked state when it is waiting for an event. The + * event it is waiting for can be a temporal event (waiting for a time), such + * as when vTaskDelay() is called, or an event on an object, such as when + * xQueueReceive() or ulTaskNotifyTake() is called. If the handle of a task + * that is in the Blocked state is used in a call to xTaskAbortDelay() then the + * task will leave the Blocked state, and return from whichever function call + * placed the task into the Blocked state. + * + * There is no 'FromISR' version of this function as an interrupt would need to + * know which object a task was blocked on in order to know which actions to + * take. For example, if the task was blocked on a queue the interrupt handler + * would then need to know if the queue was locked. + * + * @param xTask The handle of the task to remove from the Blocked state. + * + * @return If the task referenced by xTask was not in the Blocked state then + * pdFAIL is returned. Otherwise pdPASS is returned. + * + * \ingroup TaskCtrl + */ +//go:linkname XTaskAbortDelay C.xTaskAbortDelay +func XTaskAbortDelay(xTask TaskHandleT) BaseTypeT + +/** + * + * INCLUDE_uxTaskPriorityGet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the priority of any task. + * + * @param xTask Handle of the task to be queried. Passing a NULL + * handle results in the priority of the calling task being returned. + * + * @return The priority of xTask. + * + * Example usage: + * @code{c} + * void vAFunction( void ) + * { + * TaskHandle_t xHandle; + * + * // Create a task, storing the handle. + * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); + * + * // ... + * + * // Use the handle to obtain the priority of the created task. + * // It was created with tskIDLE_PRIORITY, but may have changed + * // it itself. + * if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY ) + * { + * // The task has changed it's priority. + * } + * + * // ... + * + * // Is our priority higher than the created task? + * if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) ) + * { + * // Our priority (obtained using NULL handle) is higher. + * } + * } + * @endcode + * \ingroup TaskCtrl + */ +//go:linkname UxTaskPriorityGet C.uxTaskPriorityGet +func UxTaskPriorityGet(xTask TaskHandleT) UBaseTypeT + +/** + * + * A version of uxTaskPriorityGet() that can be used from an ISR. + */ +//go:linkname UxTaskPriorityGetFromISR C.uxTaskPriorityGetFromISR +func UxTaskPriorityGetFromISR(xTask TaskHandleT) UBaseTypeT + +/** + * + * INCLUDE_eTaskGetState must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the state of any task. States are encoded by the eTaskState + * enumerated type. + * + * @param xTask Handle of the task to be queried. + * + * @return The state of xTask at the time the function was called. Note the + * state of the task might change between the function being called, and the + * functions return value being tested by the calling task. + */ +//go:linkname ETaskGetState C.eTaskGetState +func ETaskGetState(xTask TaskHandleT) ETaskState + +/** + * + * configUSE_TRACE_FACILITY must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * Populates a TaskStatus_t structure with information about a task. + * + * @param xTask Handle of the task being queried. If xTask is NULL then + * information will be returned about the calling task. + * + * @param pxTaskStatus A pointer to the TaskStatus_t structure that will be + * filled with information about the task referenced by the handle passed using + * the xTask parameter. + * + * @param xGetFreeStackSpace The TaskStatus_t structure contains a member to report + * the stack high water mark of the task being queried. Calculating the stack + * high water mark takes a relatively long time, and can make the system + * temporarily unresponsive - so the xGetFreeStackSpace parameter is provided to + * allow the high water mark checking to be skipped. The high watermark value + * will only be written to the TaskStatus_t structure if xGetFreeStackSpace is + * not set to pdFALSE; + * + * @param eState The TaskStatus_t structure contains a member to report the + * state of the task being queried. Obtaining the task state is not as fast as + * a simple assignment - so the eState parameter is provided to allow the state + * information to be omitted from the TaskStatus_t structure. To obtain state + * information then set eState to eInvalid - otherwise the value passed in + * eState will be reported as the task state in the TaskStatus_t structure. + * + * Example usage: + * @code{c} + * void vAFunction( void ) + * { + * TaskHandle_t xHandle; + * TaskStatus_t xTaskDetails; + * + * // Obtain the handle of a task from its name. + * xHandle = xTaskGetHandle( "Task_Name" ); + * + * // Check the handle is not NULL. + * configASSERT( xHandle ); + * + * // Use the handle to obtain further information about the task. + * vTaskGetInfo( xHandle, + * &xTaskDetails, + * pdTRUE, // Include the high water mark in xTaskDetails. + * eInvalid ); // Include the task state in xTaskDetails. + * } + * @endcode + * \ingroup TaskCtrl + */ +//go:linkname VTaskGetInfo C.vTaskGetInfo +func VTaskGetInfo(xTask TaskHandleT, pxTaskStatus *TaskStatusT, xGetFreeStackSpace BaseTypeT, eState ETaskState) + +/** + * + * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Set the priority of any task. + * + * A context switch will occur before the function returns if the priority + * being set is higher than the currently executing task. + * + * @param xTask Handle to the task for which the priority is being set. + * Passing a NULL handle results in the priority of the calling task being set. + * + * @param uxNewPriority The priority to which the task will be set. + * + * Example usage: + * @code{c} + * void vAFunction( void ) + * { + * TaskHandle_t xHandle; + * + * // Create a task, storing the handle. + * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); + * + * // ... + * + * // Use the handle to raise the priority of the created task. + * vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 ); + * + * // ... + * + * // Use a NULL handle to raise our priority to the same value. + * vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 ); + * } + * @endcode + * \ingroup TaskCtrl + */ +//go:linkname VTaskPrioritySet C.vTaskPrioritySet +func VTaskPrioritySet(xTask TaskHandleT, uxNewPriority UBaseTypeT) + +/** + * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Suspend any task. When suspended a task will never get any microcontroller + * processing time, no matter what its priority. + * + * Calls to vTaskSuspend are not accumulative - + * i.e. calling vTaskSuspend () twice on the same task still only requires one + * call to vTaskResume () to ready the suspended task. + * + * @param xTaskToSuspend Handle to the task being suspended. Passing a NULL + * handle will cause the calling task to be suspended. + * + * Example usage: + * @code{c} + * void vAFunction( void ) + * { + * TaskHandle_t xHandle; + * + * // Create a task, storing the handle. + * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); + * + * // ... + * + * // Use the handle to suspend the created task. + * vTaskSuspend( xHandle ); + * + * // ... + * + * // The created task will not run during this period, unless + * // another task calls vTaskResume( xHandle ). + * + * //... + * + * + * // Suspend ourselves. + * vTaskSuspend( NULL ); + * + * // We cannot get here unless another task calls vTaskResume + * // with our handle as the parameter. + * } + * @endcode + * \ingroup TaskCtrl + */ +//go:linkname VTaskSuspend C.vTaskSuspend +func VTaskSuspend(xTaskToSuspend TaskHandleT) + +/** + * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Resumes a suspended task. + * + * A task that has been suspended by one or more calls to vTaskSuspend () + * will be made available for running again by a single call to + * vTaskResume (). + * + * @param xTaskToResume Handle to the task being readied. + * + * Example usage: + * @code{c} + * void vAFunction( void ) + * { + * TaskHandle_t xHandle; + * + * // Create a task, storing the handle. + * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); + * + * // ... + * + * // Use the handle to suspend the created task. + * vTaskSuspend( xHandle ); + * + * // ... + * + * // The created task will not run during this period, unless + * // another task calls vTaskResume( xHandle ). + * + * //... + * + * + * // Resume the suspended task ourselves. + * vTaskResume( xHandle ); + * + * // The created task will once again get microcontroller processing + * // time in accordance with its priority within the system. + * } + * @endcode + * \ingroup TaskCtrl + */ +//go:linkname VTaskResume C.vTaskResume +func VTaskResume(xTaskToResume TaskHandleT) + +/** + * + * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * An implementation of vTaskResume() that can be called from within an ISR. + * + * A task that has been suspended by one or more calls to vTaskSuspend () + * will be made available for running again by a single call to + * xTaskResumeFromISR (). + * + * xTaskResumeFromISR() should not be used to synchronise a task with an + * interrupt if there is a chance that the interrupt could arrive prior to the + * task being suspended - as this can lead to interrupts being missed. Use of a + * semaphore as a synchronisation mechanism would avoid this eventuality. + * + * @param xTaskToResume Handle to the task being readied. + * + * @return pdTRUE if resuming the task should result in a context switch, + * otherwise pdFALSE. This is used by the ISR to determine if a context switch + * may be required following the ISR. + * + * \ingroup TaskCtrl + */ +//go:linkname XTaskResumeFromISR C.xTaskResumeFromISR +func XTaskResumeFromISR(xTaskToResume TaskHandleT) BaseTypeT + +/** + * + * Starts the real time kernel tick processing. After calling the kernel + * has control over which tasks are executed and when. + * + * See the demo application file main.c for an example of creating + * tasks and starting the kernel. + * + * Example usage: + * @code{c} + * void vAFunction( void ) + * { + * // Create at least one task before starting the kernel. + * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + * + * // Start the real time kernel with preemption. + * vTaskStartScheduler (); + * + * // Will not get here unless a task calls vTaskEndScheduler () + * } + * @endcode + * + * \ingroup SchedulerControl + */ +//go:linkname VTaskStartScheduler C.vTaskStartScheduler +func VTaskStartScheduler() + +/** + * + * NOTE: At the time of writing only the x86 real mode port, which runs on a PC + * in place of DOS, implements this function. + * + * Stops the real time kernel tick. All created tasks will be automatically + * deleted and multitasking (either preemptive or cooperative) will + * stop. Execution then resumes from the point where vTaskStartScheduler () + * was called, as if vTaskStartScheduler () had just returned. + * + * See the demo application file main. c in the demo/PC directory for an + * example that uses vTaskEndScheduler (). + * + * vTaskEndScheduler () requires an exit function to be defined within the + * portable layer (see vPortEndScheduler () in port. c for the PC port). This + * performs hardware specific operations such as stopping the kernel tick. + * + * vTaskEndScheduler () will cause all of the resources allocated by the + * kernel to be freed - but will not free resources allocated by application + * tasks. + * + * Example usage: + * @code{c} + * void vTaskCode( void * pvParameters ) + * { + * for( ;; ) + * { + * // Task code goes here. + * + * // At some point we want to end the real time kernel processing + * // so call ... + * vTaskEndScheduler (); + * } + * } + * + * void vAFunction( void ) + * { + * // Create at least one task before starting the kernel. + * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + * + * // Start the real time kernel with preemption. + * vTaskStartScheduler (); + * + * // Will only get here when the vTaskCode () task has called + * // vTaskEndScheduler (). When we get here we are back to single task + * // execution. + * } + * @endcode + * + * \ingroup SchedulerControl + */ +//go:linkname VTaskEndScheduler C.vTaskEndScheduler +func VTaskEndScheduler() + +/** + * + * Suspends the scheduler without disabling interrupts. Context switches will + * not occur while the scheduler is suspended. + * + * After calling vTaskSuspendAll () the calling task will continue to execute + * without risk of being swapped out until a call to xTaskResumeAll () has been + * made. + * + * API functions that have the potential to cause a context switch (for example, + * xTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler + * is suspended. + * + * Example usage: + * @code{c} + * void vTask1( void * pvParameters ) + * { + * for( ;; ) + * { + * // Task code goes here. + * + * // ... + * + * // At some point the task wants to perform a long operation during + * // which it does not want to get swapped out. It cannot use + * // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the + * // operation may cause interrupts to be missed - including the + * // ticks. + * + * // Prevent the real time kernel swapping out the task. + * vTaskSuspendAll (); + * + * // Perform the operation here. There is no need to use critical + * // sections as we have all the microcontroller processing time. + * // During this time interrupts will still operate and the kernel + * // tick count will be maintained. + * + * // ... + * + * // The operation is complete. Restart the kernel. + * xTaskResumeAll (); + * } + * } + * @endcode + * \ingroup SchedulerControl + */ +//go:linkname VTaskSuspendAll C.vTaskSuspendAll +func VTaskSuspendAll() + +/** + * + * Resumes scheduler activity after it was suspended by a call to + * vTaskSuspendAll(). + * + * xTaskResumeAll() only resumes the scheduler. It does not unsuspend tasks + * that were previously suspended by a call to vTaskSuspend(). + * + * @return If resuming the scheduler caused a context switch then pdTRUE is + * returned, otherwise pdFALSE is returned. + * + * Example usage: + * @code{c} + * void vTask1( void * pvParameters ) + * { + * for( ;; ) + * { + * // Task code goes here. + * + * // ... + * + * // At some point the task wants to perform a long operation during + * // which it does not want to get swapped out. It cannot use + * // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the + * // operation may cause interrupts to be missed - including the + * // ticks. + * + * // Prevent the real time kernel swapping out the task. + * vTaskSuspendAll (); + * + * // Perform the operation here. There is no need to use critical + * // sections as we have all the microcontroller processing time. + * // During this time interrupts will still operate and the real + * // time kernel tick count will be maintained. + * + * // ... + * + * // The operation is complete. Restart the kernel. We want to force + * // a context switch - but there is no point if resuming the scheduler + * // caused a context switch already. + * if( !xTaskResumeAll () ) + * { + * taskYIELD (); + * } + * } + * } + * @endcode + * \ingroup SchedulerControl + */ +//go:linkname XTaskResumeAll C.xTaskResumeAll +func XTaskResumeAll() BaseTypeT + +/** + * + * @return The count of ticks since vTaskStartScheduler was called. + * + * \ingroup TaskUtils + */ +//go:linkname XTaskGetTickCount C.xTaskGetTickCount +func XTaskGetTickCount() TickTypeT + +/** + * + * @return The count of ticks since vTaskStartScheduler was called. + * + * This is a version of xTaskGetTickCount() that is safe to be called from an + * ISR - provided that TickType_t is the natural word size of the + * microcontroller being used or interrupt nesting is either not supported or + * not being used. + * + * \ingroup TaskUtils + */ +//go:linkname XTaskGetTickCountFromISR C.xTaskGetTickCountFromISR +func XTaskGetTickCountFromISR() TickTypeT + +/** + * + * @return The number of tasks that the real time kernel is currently managing. + * This includes all ready, blocked and suspended tasks. A task that + * has been deleted but not yet freed by the idle task will also be + * included in the count. + * + * \ingroup TaskUtils + */ +//go:linkname UxTaskGetNumberOfTasks C.uxTaskGetNumberOfTasks +func UxTaskGetNumberOfTasks() UBaseTypeT + +/** + * + * @return The text (human readable) name of the task referenced by the handle + * xTaskToQuery. A task can query its own name by either passing in its own + * handle, or by setting xTaskToQuery to NULL. + * + * \ingroup TaskUtils + */ +//go:linkname PcTaskGetName C.pcTaskGetName +func PcTaskGetName(xTaskToQuery TaskHandleT) *c.Char + +/** + * + * NOTE: This function takes a relatively long time to complete and should be + * used sparingly. + * + * @return The handle of the task that has the human readable name pcNameToQuery. + * NULL is returned if no matching name is found. INCLUDE_xTaskGetHandle + * must be set to 1 in FreeRTOSConfig.h for pcTaskGetHandle() to be available. + * + * \ingroup TaskUtils + */ +//go:linkname XTaskGetHandle C.xTaskGetHandle +func XTaskGetHandle(pcNameToQuery *c.Char) TaskHandleT + +/** + * + * Retrieve pointers to a statically created task's data structure + * buffer and stack buffer. These are the same buffers that are supplied + * at the time of creation. + * + * @param xTask The task for which to retrieve the buffers. + * + * @param ppuxStackBuffer Used to return a pointer to the task's stack buffer. + * + * @param ppxTaskBuffer Used to return a pointer to the task's data structure + * buffer. + * + * @return pdTRUE if buffers were retrieved, pdFALSE otherwise. + * + * \ingroup TaskUtils + */ +//go:linkname XTaskGetStaticBuffers C.xTaskGetStaticBuffers +func XTaskGetStaticBuffers(xTask TaskHandleT, ppuxStackBuffer **StackTypeT, ppxTaskBuffer **StaticTaskT) BaseTypeT + +/** + * + * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in words, so on a 32 bit machine + * a value of 1 means 4 bytes) since the task started. The smaller the returned + * number the closer the task has come to overflowing its stack. + * + * uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the + * same except for their return type. Using configSTACK_DEPTH_TYPE allows the + * user to determine the return type. It gets around the problem of the value + * overflowing on 8-bit types without breaking backward compatibility for + * applications that expect an 8-bit return type. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in words, so + * actual spaces on the stack rather than bytes) since the task referenced by + * xTask was created. + */ +//go:linkname UxTaskGetStackHighWaterMark C.uxTaskGetStackHighWaterMark +func UxTaskGetStackHighWaterMark(xTask TaskHandleT) UBaseTypeT + +/** + * + * INCLUDE_uxTaskGetStackHighWaterMark2 must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in words, so on a 32 bit machine + * a value of 1 means 4 bytes) since the task started. The smaller the returned + * number the closer the task has come to overflowing its stack. + * + * uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the + * same except for their return type. Using configSTACK_DEPTH_TYPE allows the + * user to determine the return type. It gets around the problem of the value + * overflowing on 8-bit types without breaking backward compatibility for + * applications that expect an 8-bit return type. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in words, so + * actual spaces on the stack rather than bytes) since the task referenced by + * xTask was created. + */ +//go:linkname UxTaskGetStackHighWaterMark2 C.uxTaskGetStackHighWaterMark2 +func UxTaskGetStackHighWaterMark2(xTask TaskHandleT) c.Uint32T + +/** Each task contains an array of pointers that is dimensioned by the + * configNUM_THREAD_LOCAL_STORAGE_POINTERS setting in FreeRTOSConfig.h. The + * kernel does not use the pointers itself, so the application writer can use + * the pointers for any purpose they wish. The following two functions are + * used to set and query a pointer respectively. */ +//go:linkname VTaskSetThreadLocalStoragePointer C.vTaskSetThreadLocalStoragePointer +func VTaskSetThreadLocalStoragePointer(xTaskToSet TaskHandleT, xIndex BaseTypeT, pvValue c.Pointer) + +//go:linkname PvTaskGetThreadLocalStoragePointer C.pvTaskGetThreadLocalStoragePointer +func PvTaskGetThreadLocalStoragePointer(xTaskToQuery TaskHandleT, xIndex BaseTypeT) c.Pointer + +/** + * + * The application stack overflow hook is called when a stack overflow is detected for a task. + * + * Details on stack overflow detection can be found here: https://www.FreeRTOS.org/Stacks-and-stack-overflow-checking.html + * + * @param xTask the task that just exceeded its stack boundaries. + * @param pcTaskName A character string containing the name of the offending task. + */ +//go:linkname VApplicationStackOverflowHook C.vApplicationStackOverflowHook +func VApplicationStackOverflowHook(xTask TaskHandleT, pcTaskName *c.Char) + +/** + * + * This function is used to provide a statically allocated block of memory to FreeRTOS to hold the Idle Task TCB. This function is required when + * configSUPPORT_STATIC_ALLOCATION is set. For more information see this URI: https://www.FreeRTOS.org/a00110.html#configSUPPORT_STATIC_ALLOCATION + * + * @param ppxIdleTaskTCBBuffer A handle to a statically allocated TCB buffer + * @param ppxIdleTaskStackBuffer A handle to a statically allocated Stack buffer for the idle task + * @param pulIdleTaskStackSize A pointer to the number of elements that will fit in the allocated stack buffer + */ +//go:linkname VApplicationGetIdleTaskMemory C.vApplicationGetIdleTaskMemory +func VApplicationGetIdleTaskMemory(ppxIdleTaskTCBBuffer **StaticTaskT, ppxIdleTaskStackBuffer **StackTypeT, pulIdleTaskStackSize *c.Uint32T) + +/** + * + * Calls the hook function associated with xTask. Passing xTask as NULL has + * the effect of calling the Running tasks (the calling task) hook function. + * + * pvParameter is passed to the hook function for the task to interpret as it + * wants. The return value is the value returned by the task hook function + * registered by the user. + */ +//go:linkname XTaskCallApplicationTaskHook C.xTaskCallApplicationTaskHook +func XTaskCallApplicationTaskHook(xTask TaskHandleT, pvParameter c.Pointer) BaseTypeT + +/** + * xTaskGetIdleTaskHandle() is only available if + * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h. + * + * Simply returns the handle of the idle task of the current core. It is not + * valid to call xTaskGetIdleTaskHandle() before the scheduler has been started. + */ +//go:linkname XTaskGetIdleTaskHandle C.xTaskGetIdleTaskHandle +func XTaskGetIdleTaskHandle() TaskHandleT + +/** + * configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for + * uxTaskGetSystemState() to be available. + * + * uxTaskGetSystemState() populates an TaskStatus_t structure for each task in + * the system. TaskStatus_t structures contain, among other things, members + * for the task handle, task name, task priority, task state, and total amount + * of run time consumed by the task. See the TaskStatus_t structure + * definition in this file for the full member list. + * + * NOTE: This function is intended for debugging use only as its use results in + * the scheduler remaining suspended for an extended period. + * + * @param pxTaskStatusArray A pointer to an array of TaskStatus_t structures. + * The array must contain at least one TaskStatus_t structure for each task + * that is under the control of the RTOS. The number of tasks under the control + * of the RTOS can be determined using the uxTaskGetNumberOfTasks() API function. + * + * @param uxArraySize The size of the array pointed to by the pxTaskStatusArray + * parameter. The size is specified as the number of indexes in the array, or + * the number of TaskStatus_t structures contained in the array, not by the + * number of bytes in the array. + * + * @param pulTotalRunTime If configGENERATE_RUN_TIME_STATS is set to 1 in + * FreeRTOSConfig.h then *pulTotalRunTime is set by uxTaskGetSystemState() to the + * total run time (as defined by the run time stats clock, see + * https://www.FreeRTOS.org/rtos-run-time-stats.html) since the target booted. + * pulTotalRunTime can be set to NULL to omit the total run time information. + * + * @return The number of TaskStatus_t structures that were populated by + * uxTaskGetSystemState(). This should equal the number returned by the + * uxTaskGetNumberOfTasks() API function, but will be zero if the value passed + * in the uxArraySize parameter was too small. + * + * Example usage: + * @code{c} + * // This example demonstrates how a human readable table of run time stats + * // information is generated from raw data provided by uxTaskGetSystemState(). + * // The human readable table is written to pcWriteBuffer + * void vTaskGetRunTimeStats( char *pcWriteBuffer ) + * { + * TaskStatus_t *pxTaskStatusArray; + * volatile UBaseType_t uxArraySize, x; + * configRUN_TIME_COUNTER_TYPE ulTotalRunTime, ulStatsAsPercentage; + * + * // Make sure the write buffer does not contain a string. + * pcWriteBuffer = 0x00; + * + * // Take a snapshot of the number of tasks in case it changes while this + * // function is executing. + * uxArraySize = uxTaskGetNumberOfTasks(); + * + * // Allocate a TaskStatus_t structure for each task. An array could be + * // allocated statically at compile time. + * pxTaskStatusArray = pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ) ); + * + * if( pxTaskStatusArray != NULL ) + * { + * // Generate raw status information about each task. + * uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalRunTime ); + * + * // For percentage calculations. + * ulTotalRunTime /= 100UL; + * + * // Avoid divide by zero errors. + * if( ulTotalRunTime > 0 ) + * { + * // For each populated position in the pxTaskStatusArray array, + * // format the raw data as human readable ASCII data + * for( x = 0; x < uxArraySize; x++ ) + * { + * // What percentage of the total run time has the task used? + * // This will always be rounded down to the nearest integer. + * // ulTotalRunTimeDiv100 has already been divided by 100. + * ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime; + * + * if( ulStatsAsPercentage > 0UL ) + * { + * sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage ); + * } + * else + * { + * // If the percentage is zero here then the task has + * // consumed less than 1% of the total run time. + * sprintf( pcWriteBuffer, "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter ); + * } + * + * pcWriteBuffer += strlen( ( char * ) pcWriteBuffer ); + * } + * } + * + * // The array is no longer needed, free the memory it consumes. + * vPortFree( pxTaskStatusArray ); + * } + * } + * @endcode + */ +// llgo:link (*TaskStatusT).UxTaskGetSystemState C.uxTaskGetSystemState +func (recv_ *TaskStatusT) UxTaskGetSystemState(uxArraySize UBaseTypeT, pulTotalRunTime *c.Uint32T) UBaseTypeT { + return 0 +} + +/** + * + * configUSE_TRACE_FACILITY and configUSE_STATS_FORMATTING_FUNCTIONS must + * both be defined as 1 for this function to be available. See the + * configuration section of the FreeRTOS.org website for more information. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Lists all the current tasks, along with their current state and stack + * usage high water mark. + * + * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or + * suspended ('S'). + * + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskList() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays task: + * names, states, priority, stack usage and task number. + * Stack usage specified as the number of unused StackType_t words stack can hold + * on top of stack - not the number of bytes. + * + * vTaskList() has a dependency on the sprintf() C library function that might + * bloat the code size, use a lot of stack, and provide different results on + * different platforms. An alternative, tiny, third party, and limited + * functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly through a + * call to vTaskList(). + * + * @param pcWriteBuffer A buffer into which the above mentioned details + * will be written, in ASCII form. This buffer is assumed to be large + * enough to contain the generated report. Approximately 40 bytes per + * task should be sufficient. + * + * \ingroup TaskUtils + */ +//go:linkname VTaskList C.vTaskList +func VTaskList(pcWriteBuffer *c.Char) + +/** + * + * configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS + * must both be defined as 1 for this function to be available. The application + * must also then provide definitions for + * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE() + * to configure a peripheral timer/counter and return the timers current count + * value respectively. The counter should be at least 10 times the frequency of + * the tick count. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total + * accumulated execution time being stored for each task. The resolution + * of the accumulated time value depends on the frequency of the timer + * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. + * Calling vTaskGetRunTimeStats() writes the total execution time of each + * task into a buffer, both as an absolute count value and as a percentage + * of the total system execution time. + * + * NOTE 2: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays the + * amount of time each task has spent in the Running state in both absolute and + * percentage terms. + * + * vTaskGetRunTimeStats() has a dependency on the sprintf() C library function + * that might bloat the code size, use a lot of stack, and provide different + * results on different platforms. An alternative, tiny, third party, and + * limited functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() directly + * to get access to raw stats data, rather than indirectly through a call to + * vTaskGetRunTimeStats(). + * + * @param pcWriteBuffer A buffer into which the execution times will be + * written, in ASCII form. This buffer is assumed to be large enough to + * contain the generated report. Approximately 40 bytes per task should + * be sufficient. + * + * \ingroup TaskUtils + */ +//go:linkname VTaskGetRunTimeStats C.vTaskGetRunTimeStats +func VTaskGetRunTimeStats(pcWriteBuffer *c.Char) + +/** + * + * configGENERATE_RUN_TIME_STATS, configUSE_STATS_FORMATTING_FUNCTIONS and + * INCLUDE_xTaskGetIdleTaskHandle must all be defined as 1 for these functions + * to be available. The application must also then provide definitions for + * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE() + * to configure a peripheral timer/counter and return the timers current count + * value respectively. The counter should be at least 10 times the frequency of + * the tick count. + * + * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total + * accumulated execution time being stored for each task. The resolution + * of the accumulated time value depends on the frequency of the timer + * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. + * While uxTaskGetSystemState() and vTaskGetRunTimeStats() writes the total + * execution time of each task into a buffer, ulTaskGetIdleRunTimeCounter() + * returns the total execution time of just the idle task and + * ulTaskGetIdleRunTimePercent() returns the percentage of the CPU time used by + * just the idle task. + * + * Note the amount of idle time is only a good measure of the slack time in a + * system if there are no other tasks executing at the idle priority, tickless + * idle is not used, and configIDLE_SHOULD_YIELD is set to 0. + * + * @note If configNUMBER_OF_CORES > 1, calling this function will query the idle + * task of the current core. + * + * @return The total run time of the idle task or the percentage of the total + * run time consumed by the idle task. This is the amount of time the + * idle task has actually been executing. The unit of time is dependent on the + * frequency configured using the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and + * portGET_RUN_TIME_COUNTER_VALUE() macros. + * + * \ingroup TaskUtils + */ +//go:linkname UlTaskGetIdleRunTimeCounter C.ulTaskGetIdleRunTimeCounter +func UlTaskGetIdleRunTimeCounter() c.Uint32T + +//go:linkname UlTaskGetIdleRunTimePercent C.ulTaskGetIdleRunTimePercent +func UlTaskGetIdleRunTimePercent() c.Uint32T + +/** + * + * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these + * functions to be available. + * + * Sends a direct to task notification to a task, with an optional value and + * action. + * + * Each task has a private array of "notification values" (or 'notifications'), + * each of which is a 32-bit unsigned integer (uint32_t). The constant + * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the + * array, and (for backward compatibility) defaults to 1 if left undefined. + * Prior to FreeRTOS V10.4.0 there was only one notification value per task. + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment one of the task's notification values. In + * that way task notifications can be used to send data to a task, or be used as + * light weight and fast binary or counting semaphores. + * + * A task can use xTaskNotifyWaitIndexed() or ulTaskNotifyTakeIndexed() to + * [optionally] block to wait for a notification to be pending. The task does + * not consume any CPU time while it is in the Blocked state. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWaitIndexed() or ulTaskNotifyTakeIndexed() (or their + * un-indexed equivalents). If the task was already in the Blocked state to + * wait for a notification when the notification arrives then the task will + * automatically be removed from the Blocked state (unblocked) and the + * notification cleared. + * + * **NOTE** Each notification within the array operates independently - a task + * can only block on one notification within the array at a time and will not be + * unblocked by a notification sent to any other array index. + * + * Backward compatibility information: + * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and + * all task notification API functions operated on that value. Replacing the + * single notification value with an array of notification values necessitated a + * new set of API functions that could address specific notifications within the + * array. xTaskNotify() is the original API function, and remains backward + * compatible by always operating on the notification value at index 0 in the + * array. Calling xTaskNotify() is equivalent to calling xTaskNotifyIndexed() + * with the uxIndexToNotify parameter set to 0. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @param uxIndexToNotify The index within the target task's array of + * notification values to which the notification is to be sent. uxIndexToNotify + * must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. xTaskNotify() does + * not have this parameter and always sends notifications to index 0. + * + * @param ulValue Data that can be sent with the notification. How the data is + * used depends on the value of the eAction parameter. + * + * @param eAction Specifies how the notification updates the task's notification + * value, if at all. Valid values for eAction are as follows: + * + * eSetBits - + * The target notification value is bitwise ORed with ulValue. + * xTaskNotifyIndexed() always returns pdPASS in this case. + * + * eIncrement - + * The target notification value is incremented. ulValue is not used and + * xTaskNotifyIndexed() always returns pdPASS in this case. + * + * eSetValueWithOverwrite - + * The target notification value is set to the value of ulValue, even if the + * task being notified had not yet processed the previous notification at the + * same array index (the task already had a notification pending at that index). + * xTaskNotifyIndexed() always returns pdPASS in this case. + * + * eSetValueWithoutOverwrite - + * If the task being notified did not already have a notification pending at the + * same array index then the target notification value is set to ulValue and + * xTaskNotifyIndexed() will return pdPASS. If the task being notified already + * had a notification pending at the same array index then no action is + * performed and pdFAIL is returned. + * + * eNoAction - + * The task receives a notification at the specified array index without the + * notification value at that index being updated. ulValue is not used and + * xTaskNotifyIndexed() always returns pdPASS in this case. + * + * pulPreviousNotificationValue - + * Can be used to pass out the subject task's notification value before any + * bits are modified by the notify function. + * + * @return Dependent on the value of eAction. See the description of the + * eAction parameter. + * + * \ingroup TaskNotifications + */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ +//go:linkname XTaskGenericNotify C.xTaskGenericNotify +func XTaskGenericNotify(xTaskToNotify TaskHandleT, uxIndexToNotify UBaseTypeT, ulValue c.Uint32T, eAction ENotifyAction, pulPreviousNotificationValue *c.Uint32T) BaseTypeT + +/** + * + * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these + * functions to be available. + * + * A version of xTaskNotifyIndexed() that can be used from an interrupt service + * routine (ISR). + * + * Each task has a private array of "notification values" (or 'notifications'), + * each of which is a 32-bit unsigned integer (uint32_t). The constant + * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the + * array, and (for backward compatibility) defaults to 1 if left undefined. + * Prior to FreeRTOS V10.4.0 there was only one notification value per task. + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment one of the task's notification values. In + * that way task notifications can be used to send data to a task, or be used as + * light weight and fast binary or counting semaphores. + * + * A task can use xTaskNotifyWaitIndexed() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTakeIndexed() to [optionally] block + * to wait for a notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWaitIndexed() or ulTaskNotifyTakeIndexed() (or their + * un-indexed equivalents). If the task was already in the Blocked state to + * wait for a notification when the notification arrives then the task will + * automatically be removed from the Blocked state (unblocked) and the + * notification cleared. + * + * **NOTE** Each notification within the array operates independently - a task + * can only block on one notification within the array at a time and will not be + * unblocked by a notification sent to any other array index. + * + * Backward compatibility information: + * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and + * all task notification API functions operated on that value. Replacing the + * single notification value with an array of notification values necessitated a + * new set of API functions that could address specific notifications within the + * array. xTaskNotifyFromISR() is the original API function, and remains + * backward compatible by always operating on the notification value at index 0 + * within the array. Calling xTaskNotifyFromISR() is equivalent to calling + * xTaskNotifyIndexedFromISR() with the uxIndexToNotify parameter set to 0. + * + * @param uxIndexToNotify The index within the target task's array of + * notification values to which the notification is to be sent. uxIndexToNotify + * must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. xTaskNotifyFromISR() + * does not have this parameter and always sends notifications to index 0. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @param ulValue Data that can be sent with the notification. How the data is + * used depends on the value of the eAction parameter. + * + * @param eAction Specifies how the notification updates the task's notification + * value, if at all. Valid values for eAction are as follows: + * + * eSetBits - + * The task's notification value is bitwise ORed with ulValue. xTaskNotify() + * always returns pdPASS in this case. + * + * eIncrement - + * The task's notification value is incremented. ulValue is not used and + * xTaskNotify() always returns pdPASS in this case. + * + * eSetValueWithOverwrite - + * The task's notification value is set to the value of ulValue, even if the + * task being notified had not yet processed the previous notification (the + * task already had a notification pending). xTaskNotify() always returns + * pdPASS in this case. + * + * eSetValueWithoutOverwrite - + * If the task being notified did not already have a notification pending then + * the task's notification value is set to ulValue and xTaskNotify() will + * return pdPASS. If the task being notified already had a notification + * pending then no action is performed and pdFAIL is returned. + * + * eNoAction - + * The task receives a notification without its notification value being + * updated. ulValue is not used and xTaskNotify() always returns pdPASS in + * this case. + * + * @param pxHigherPriorityTaskWoken xTaskNotifyFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the + * task to which the notification was sent to leave the Blocked state, and the + * unblocked task has a priority higher than the currently running task. If + * xTaskNotifyFromISR() sets this value to pdTRUE then a context switch should + * be requested before the interrupt is exited. How a context switch is + * requested from an ISR is dependent on the port - see the documentation page + * for the port in use. + * + * @return Dependent on the value of eAction. See the description of the + * eAction parameter. + * + * \ingroup TaskNotifications + */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ +//go:linkname XTaskGenericNotifyFromISR C.xTaskGenericNotifyFromISR +func XTaskGenericNotifyFromISR(xTaskToNotify TaskHandleT, uxIndexToNotify UBaseTypeT, ulValue c.Uint32T, eAction ENotifyAction, pulPreviousNotificationValue *c.Uint32T, pxHigherPriorityTaskWoken *BaseTypeT) BaseTypeT + +/** + * + * Waits for a direct to task notification to be pending at a given index within + * an array of direct to task notifications. + * + * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * Each task has a private array of "notification values" (or 'notifications'), + * each of which is a 32-bit unsigned integer (uint32_t). The constant + * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the + * array, and (for backward compatibility) defaults to 1 if left undefined. + * Prior to FreeRTOS V10.4.0 there was only one notification value per task. + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment one of the task's notification values. In + * that way task notifications can be used to send data to a task, or be used as + * light weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWaitIndexed() or ulTaskNotifyTakeIndexed() (or their + * un-indexed equivalents). If the task was already in the Blocked state to + * wait for a notification when the notification arrives then the task will + * automatically be removed from the Blocked state (unblocked) and the + * notification cleared. + * + * A task can use xTaskNotifyWaitIndexed() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTakeIndexed() to [optionally] block + * to wait for a notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * **NOTE** Each notification within the array operates independently - a task + * can only block on one notification within the array at a time and will not be + * unblocked by a notification sent to any other array index. + * + * Backward compatibility information: + * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and + * all task notification API functions operated on that value. Replacing the + * single notification value with an array of notification values necessitated a + * new set of API functions that could address specific notifications within the + * array. xTaskNotifyWait() is the original API function, and remains backward + * compatible by always operating on the notification value at index 0 in the + * array. Calling xTaskNotifyWait() is equivalent to calling + * xTaskNotifyWaitIndexed() with the uxIndexToWaitOn parameter set to 0. + * + * @param uxIndexToWaitOn The index within the calling task's array of + * notification values on which the calling task will wait for a notification to + * be received. uxIndexToWaitOn must be less than + * configTASK_NOTIFICATION_ARRAY_ENTRIES. xTaskNotifyWait() does + * not have this parameter and always waits for notifications on index 0. + * + * @param ulBitsToClearOnEntry Bits that are set in ulBitsToClearOnEntry value + * will be cleared in the calling task's notification value before the task + * checks to see if any notifications are pending, and optionally blocks if no + * notifications are pending. Setting ulBitsToClearOnEntry to ULONG_MAX (if + * limits.h is included) or 0xffffffffUL (if limits.h is not included) will have + * the effect of resetting the task's notification value to 0. Setting + * ulBitsToClearOnEntry to 0 will leave the task's notification value unchanged. + * + * @param ulBitsToClearOnExit If a notification is pending or received before + * the calling task exits the xTaskNotifyWait() function then the task's + * notification value (see the xTaskNotify() API function) is passed out using + * the pulNotificationValue parameter. Then any bits that are set in + * ulBitsToClearOnExit will be cleared in the task's notification value (note + * *pulNotificationValue is set before any bits are cleared). Setting + * ulBitsToClearOnExit to ULONG_MAX (if limits.h is included) or 0xffffffffUL + * (if limits.h is not included) will have the effect of resetting the task's + * notification value to 0 before the function exits. Setting + * ulBitsToClearOnExit to 0 will leave the task's notification value unchanged + * when the function exits (in which case the value passed out in + * pulNotificationValue will match the task's notification value). + * + * @param pulNotificationValue Used to pass the task's notification value out + * of the function. Note the value passed out will not be effected by the + * clearing of any bits caused by ulBitsToClearOnExit being non-zero. + * + * @param xTicksToWait The maximum amount of time that the task should wait in + * the Blocked state for a notification to be received, should a notification + * not already be pending when xTaskNotifyWait() was called. The task + * will not consume any processing time while it is in the Blocked state. This + * is specified in kernel ticks, the macro pdMS_TO_TICKS( value_in_ms ) can be + * used to convert a time specified in milliseconds to a time specified in + * ticks. + * + * @return If a notification was received (including notifications that were + * already pending when xTaskNotifyWait was called) then pdPASS is + * returned. Otherwise pdFAIL is returned. + * + * \ingroup TaskNotifications + */ +// llgo:link UBaseTypeT.XTaskGenericNotifyWait C.xTaskGenericNotifyWait +func (recv_ UBaseTypeT) XTaskGenericNotifyWait(ulBitsToClearOnEntry c.Uint32T, ulBitsToClearOnExit c.Uint32T, pulNotificationValue *c.Uint32T, xTicksToWait TickTypeT) BaseTypeT { + return 0 +} + +/** + * + * A version of xTaskNotifyGiveIndexed() that can be called from an interrupt + * service routine (ISR). + * + * See https://www.FreeRTOS.org/RTOS-task-notifications.html for more details. + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro + * to be available. + * + * Each task has a private array of "notification values" (or 'notifications'), + * each of which is a 32-bit unsigned integer (uint32_t). The constant + * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the + * array, and (for backward compatibility) defaults to 1 if left undefined. + * Prior to FreeRTOS V10.4.0 there was only one notification value per task. + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment one of the task's notification values. In + * that way task notifications can be used to send data to a task, or be used as + * light weight and fast binary or counting semaphores. + * + * vTaskNotifyGiveIndexedFromISR() is intended for use when task notifications + * are used as light weight and faster binary or counting semaphore equivalents. + * Actual FreeRTOS semaphores are given from an ISR using the + * xSemaphoreGiveFromISR() API function, the equivalent action that instead uses + * a task notification is vTaskNotifyGiveIndexedFromISR(). + * + * When task notifications are being used as a binary or counting semaphore + * equivalent then the task being notified should wait for the notification + * using the ulTaskNotifyTakeIndexed() API function rather than the + * xTaskNotifyWaitIndexed() API function. + * + * **NOTE** Each notification within the array operates independently - a task + * can only block on one notification within the array at a time and will not be + * unblocked by a notification sent to any other array index. + * + * Backward compatibility information: + * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and + * all task notification API functions operated on that value. Replacing the + * single notification value with an array of notification values necessitated a + * new set of API functions that could address specific notifications within the + * array. xTaskNotifyFromISR() is the original API function, and remains + * backward compatible by always operating on the notification value at index 0 + * within the array. Calling xTaskNotifyGiveFromISR() is equivalent to calling + * xTaskNotifyGiveIndexedFromISR() with the uxIndexToNotify parameter set to 0. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @param uxIndexToNotify The index within the target task's array of + * notification values to which the notification is to be sent. uxIndexToNotify + * must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. + * xTaskNotifyGiveFromISR() does not have this parameter and always sends + * notifications to index 0. + * + * @param pxHigherPriorityTaskWoken vTaskNotifyGiveFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the + * task to which the notification was sent to leave the Blocked state, and the + * unblocked task has a priority higher than the currently running task. If + * vTaskNotifyGiveFromISR() sets this value to pdTRUE then a context switch + * should be requested before the interrupt is exited. How a context switch is + * requested from an ISR is dependent on the port - see the documentation page + * for the port in use. + * + * \ingroup TaskNotifications + */ +//go:linkname VTaskGenericNotifyGiveFromISR C.vTaskGenericNotifyGiveFromISR +func VTaskGenericNotifyGiveFromISR(xTaskToNotify TaskHandleT, uxIndexToNotify UBaseTypeT, pxHigherPriorityTaskWoken *BaseTypeT) + +/** + * + * Waits for a direct to task notification on a particular index in the calling + * task's notification array in a manner similar to taking a counting semaphore. + * + * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * Each task has a private array of "notification values" (or 'notifications'), + * each of which is a 32-bit unsigned integer (uint32_t). The constant + * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the + * array, and (for backward compatibility) defaults to 1 if left undefined. + * Prior to FreeRTOS V10.4.0 there was only one notification value per task. + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment one of the task's notification values. In + * that way task notifications can be used to send data to a task, or be used as + * light weight and fast binary or counting semaphores. + * + * ulTaskNotifyTakeIndexed() is intended for use when a task notification is + * used as a faster and lighter weight binary or counting semaphore alternative. + * Actual FreeRTOS semaphores are taken using the xSemaphoreTake() API function, + * the equivalent action that instead uses a task notification is + * ulTaskNotifyTakeIndexed(). + * + * When a task is using its notification value as a binary or counting semaphore + * other tasks should send notifications to it using the xTaskNotifyGiveIndexed() + * macro, or xTaskNotifyIndex() function with the eAction parameter set to + * eIncrement. + * + * ulTaskNotifyTakeIndexed() can either clear the task's notification value at + * the array index specified by the uxIndexToWaitOn parameter to zero on exit, + * in which case the notification value acts like a binary semaphore, or + * decrement the notification value on exit, in which case the notification + * value acts like a counting semaphore. + * + * A task can use ulTaskNotifyTakeIndexed() to [optionally] block to wait for + * a notification. The task does not consume any CPU time while it is in the + * Blocked state. + * + * Where as xTaskNotifyWaitIndexed() will return when a notification is pending, + * ulTaskNotifyTakeIndexed() will return when the task's notification value is + * not zero. + * + * **NOTE** Each notification within the array operates independently - a task + * can only block on one notification within the array at a time and will not be + * unblocked by a notification sent to any other array index. + * + * Backward compatibility information: + * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and + * all task notification API functions operated on that value. Replacing the + * single notification value with an array of notification values necessitated a + * new set of API functions that could address specific notifications within the + * array. ulTaskNotifyTake() is the original API function, and remains backward + * compatible by always operating on the notification value at index 0 in the + * array. Calling ulTaskNotifyTake() is equivalent to calling + * ulTaskNotifyTakeIndexed() with the uxIndexToWaitOn parameter set to 0. + * + * @param uxIndexToWaitOn The index within the calling task's array of + * notification values on which the calling task will wait for a notification to + * be non-zero. uxIndexToWaitOn must be less than + * configTASK_NOTIFICATION_ARRAY_ENTRIES. xTaskNotifyTake() does + * not have this parameter and always waits for notifications on index 0. + * + * @param xClearCountOnExit if xClearCountOnExit is pdFALSE then the task's + * notification value is decremented when the function exits. In this way the + * notification value acts like a counting semaphore. If xClearCountOnExit is + * not pdFALSE then the task's notification value is cleared to zero when the + * function exits. In this way the notification value acts like a binary + * semaphore. + * + * @param xTicksToWait The maximum amount of time that the task should wait in + * the Blocked state for the task's notification value to be greater than zero, + * should the count not already be greater than zero when + * ulTaskNotifyTake() was called. The task will not consume any processing + * time while it is in the Blocked state. This is specified in kernel ticks, + * the macro pdMS_TO_TICKS( value_in_ms ) can be used to convert a time + * specified in milliseconds to a time specified in ticks. + * + * @return The task's notification count before it is either cleared to zero or + * decremented (see the xClearCountOnExit parameter). + * + * \ingroup TaskNotifications + */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ +// llgo:link UBaseTypeT.UlTaskGenericNotifyTake C.ulTaskGenericNotifyTake +func (recv_ UBaseTypeT) UlTaskGenericNotifyTake(xClearCountOnExit BaseTypeT, xTicksToWait TickTypeT) c.Uint32T { + return 0 +} + +/** + * + * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these + * functions to be available. + * + * Each task has a private array of "notification values" (or 'notifications'), + * each of which is a 32-bit unsigned integer (uint32_t). The constant + * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the + * array, and (for backward compatibility) defaults to 1 if left undefined. + * Prior to FreeRTOS V10.4.0 there was only one notification value per task. + * + * If a notification is sent to an index within the array of notifications then + * the notification at that index is said to be 'pending' until it is read or + * explicitly cleared by the receiving task. xTaskNotifyStateClearIndexed() + * is the function that clears a pending notification without reading the + * notification value. The notification value at the same array index is not + * altered. Set xTask to NULL to clear the notification state of the calling + * task. + * + * Backward compatibility information: + * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and + * all task notification API functions operated on that value. Replacing the + * single notification value with an array of notification values necessitated a + * new set of API functions that could address specific notifications within the + * array. xTaskNotifyStateClear() is the original API function, and remains + * backward compatible by always operating on the notification value at index 0 + * within the array. Calling xTaskNotifyStateClear() is equivalent to calling + * xTaskNotifyStateClearIndexed() with the uxIndexToNotify parameter set to 0. + * + * @param xTask The handle of the RTOS task that will have a notification state + * cleared. Set xTask to NULL to clear a notification state in the calling + * task. To obtain a task's handle create the task using xTaskCreate() and + * make use of the pxCreatedTask parameter, or create the task using + * xTaskCreateStatic() and store the returned value, or use the task's name in + * a call to xTaskGetHandle(). + * + * @param uxIndexToClear The index within the target task's array of + * notification values to act upon. For example, setting uxIndexToClear to 1 + * will clear the state of the notification at index 1 within the array. + * uxIndexToClear must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. + * ulTaskNotifyStateClear() does not have this parameter and always acts on the + * notification at index 0. + * + * @return pdTRUE if the task's notification state was set to + * eNotWaitingNotification, otherwise pdFALSE. + * + * \ingroup TaskNotifications + */ +//go:linkname XTaskGenericNotifyStateClear C.xTaskGenericNotifyStateClear +func XTaskGenericNotifyStateClear(xTask TaskHandleT, uxIndexToClear UBaseTypeT) BaseTypeT + +/** + * + * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these + * functions to be available. + * + * Each task has a private array of "notification values" (or 'notifications'), + * each of which is a 32-bit unsigned integer (uint32_t). The constant + * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the + * array, and (for backward compatibility) defaults to 1 if left undefined. + * Prior to FreeRTOS V10.4.0 there was only one notification value per task. + * + * ulTaskNotifyValueClearIndexed() clears the bits specified by the + * ulBitsToClear bit mask in the notification value at array index uxIndexToClear + * of the task referenced by xTask. + * + * Backward compatibility information: + * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and + * all task notification API functions operated on that value. Replacing the + * single notification value with an array of notification values necessitated a + * new set of API functions that could address specific notifications within the + * array. ulTaskNotifyValueClear() is the original API function, and remains + * backward compatible by always operating on the notification value at index 0 + * within the array. Calling ulTaskNotifyValueClear() is equivalent to calling + * ulTaskNotifyValueClearIndexed() with the uxIndexToClear parameter set to 0. + * + * @param xTask The handle of the RTOS task that will have bits in one of its + * notification values cleared. Set xTask to NULL to clear bits in a + * notification value of the calling task. To obtain a task's handle create the + * task using xTaskCreate() and make use of the pxCreatedTask parameter, or + * create the task using xTaskCreateStatic() and store the returned value, or + * use the task's name in a call to xTaskGetHandle(). + * + * @param uxIndexToClear The index within the target task's array of + * notification values in which to clear the bits. uxIndexToClear + * must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. + * ulTaskNotifyValueClear() does not have this parameter and always clears bits + * in the notification value at index 0. + * + * @param ulBitsToClear Bit mask of the bits to clear in the notification value of + * xTask. Set a bit to 1 to clear the corresponding bits in the task's notification + * value. Set ulBitsToClear to 0xffffffff (UINT_MAX on 32-bit architectures) to clear + * the notification value to 0. Set ulBitsToClear to 0 to query the task's + * notification value without clearing any bits. + * + * + * @return The value of the target task's notification value before the bits + * specified by ulBitsToClear were cleared. + * \ingroup TaskNotifications + */ +//go:linkname UlTaskGenericNotifyValueClear C.ulTaskGenericNotifyValueClear +func UlTaskGenericNotifyValueClear(xTask TaskHandleT, uxIndexToClear UBaseTypeT, ulBitsToClear c.Uint32T) c.Uint32T + +/** + * + * Capture the current time for future use with xTaskCheckForTimeOut(). + * + * @param pxTimeOut Pointer to a timeout object into which the current time + * is to be captured. The captured time includes the tick count and the number + * of times the tick count has overflowed since the system first booted. + * \ingroup TaskCtrl + */ +// llgo:link (*TimeOutT).VTaskSetTimeOutState C.vTaskSetTimeOutState +func (recv_ *TimeOutT) VTaskSetTimeOutState() { +} + +/** + * + * Determines if pxTicksToWait ticks has passed since a time was captured + * using a call to vTaskSetTimeOutState(). The captured time includes the tick + * count and the number of times the tick count has overflowed. + * + * @param pxTimeOut The time status as captured previously using + * vTaskSetTimeOutState. If the timeout has not yet occurred, it is updated + * to reflect the current time status. + * @param pxTicksToWait The number of ticks to check for timeout i.e. if + * pxTicksToWait ticks have passed since pxTimeOut was last updated (either by + * vTaskSetTimeOutState() or xTaskCheckForTimeOut()), the timeout has occurred. + * If the timeout has not occurred, pxTicksToWait is updated to reflect the + * number of remaining ticks. + * + * @return If timeout has occurred, pdTRUE is returned. Otherwise pdFALSE is + * returned and pxTicksToWait is updated to reflect the number of remaining + * ticks. + * + * @see https://www.FreeRTOS.org/xTaskCheckForTimeOut.html + * + * Example Usage: + * @code{c} + * // Driver library function used to receive uxWantedBytes from an Rx buffer + * // that is filled by a UART interrupt. If there are not enough bytes in the + * // Rx buffer then the task enters the Blocked state until it is notified that + * // more data has been placed into the buffer. If there is still not enough + * // data then the task re-enters the Blocked state, and xTaskCheckForTimeOut() + * // is used to re-calculate the Block time to ensure the total amount of time + * // spent in the Blocked state does not exceed MAX_TIME_TO_WAIT. This + * // continues until either the buffer contains at least uxWantedBytes bytes, + * // or the total amount of time spent in the Blocked state reaches + * // MAX_TIME_TO_WAIT - at which point the task reads however many bytes are + * // available up to a maximum of uxWantedBytes. + * + * size_t xUART_Receive( uint8_t *pucBuffer, size_t uxWantedBytes ) + * { + * size_t uxReceived = 0; + * TickType_t xTicksToWait = MAX_TIME_TO_WAIT; + * TimeOut_t xTimeOut; + * + * // Initialize xTimeOut. This records the time at which this function + * // was entered. + * vTaskSetTimeOutState( &xTimeOut ); + * + * // Loop until the buffer contains the wanted number of bytes, or a + * // timeout occurs. + * while( UART_bytes_in_rx_buffer( pxUARTInstance ) < uxWantedBytes ) + * { + * // The buffer didn't contain enough data so this task is going to + * // enter the Blocked state. Adjusting xTicksToWait to account for + * // any time that has been spent in the Blocked state within this + * // function so far to ensure the total amount of time spent in the + * // Blocked state does not exceed MAX_TIME_TO_WAIT. + * if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) != pdFALSE ) + * { + * //Timed out before the wanted number of bytes were available, + * // exit the loop. + * break; + * } + * + * // Wait for a maximum of xTicksToWait ticks to be notified that the + * // receive interrupt has placed more data into the buffer. + * ulTaskNotifyTake( pdTRUE, xTicksToWait ); + * } + * + * // Attempt to read uxWantedBytes from the receive buffer into pucBuffer. + * // The actual number of bytes read (which might be less than + * // uxWantedBytes) is returned. + * uxReceived = UART_read_from_receive_buffer( pxUARTInstance, + * pucBuffer, + * uxWantedBytes ); + * + * return uxReceived; + * } + * @endcode + * \ingroup TaskCtrl + */ +// llgo:link (*TimeOutT).XTaskCheckForTimeOut C.xTaskCheckForTimeOut +func (recv_ *TimeOutT) XTaskCheckForTimeOut(pxTicksToWait *TickTypeT) BaseTypeT { + return 0 +} + +/** + * + * This function corrects the tick count value after the application code has held + * interrupts disabled for an extended period resulting in tick interrupts having + * been missed. + * + * This function is similar to vTaskStepTick(), however, unlike + * vTaskStepTick(), xTaskCatchUpTicks() may move the tick count forward past a + * time at which a task should be removed from the blocked state. That means + * tasks may have to be removed from the blocked state as the tick count is + * moved. + * + * @param xTicksToCatchUp The number of tick interrupts that have been missed due to + * interrupts being disabled. Its value is not computed automatically, so must be + * computed by the application writer. + * + * @return pdTRUE if moving the tick count forward resulted in a task leaving the + * blocked state and a context switch being performed. Otherwise pdFALSE. + * + * \ingroup TaskCtrl + */ +// llgo:link TickTypeT.XTaskCatchUpTicks C.xTaskCatchUpTicks +func (recv_ TickTypeT) XTaskCatchUpTicks() BaseTypeT { + return 0 +} + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Called from the real time kernel tick (either preemptive or cooperative), + * this increments the tick count and checks if any tasks that are blocked + * for a finite period required removing from a blocked list and placing on + * a ready list. If a non-zero value is returned then a context switch is + * required because either: + * + A task was removed from a blocked list because its timeout had expired, + * or + * + Time slicing is in use and there is a task of equal priority to the + * currently running task. + * + * Note: If configNUMBER_OF_CORES > 1, this function must only be called by + * core 0. Other cores should call xTaskIncrementTickOtherCores() instead. + */ +//go:linkname XTaskIncrementTick C.xTaskIncrementTick +func XTaskIncrementTick() BaseTypeT + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes the calling task from the ready list and places it both + * on the list of tasks waiting for a particular event, and the + * list of delayed tasks. The task will be removed from both lists + * and replaced on the ready list should either the event occur (and + * there be no higher priority tasks waiting on the same event) or + * the delay period expires. + * + * The 'unordered' version replaces the event list item value with the + * xItemValue value, and inserts the list item at the end of the list. + * + * The 'ordered' version uses the existing event list item value (which is the + * owning task's priority) to insert the list item into the event list in task + * priority order. + * + * @param pxEventList The list containing tasks that are blocked waiting + * for the event to occur. + * + * @param xItemValue The item value to use for the event list item when the + * event list is not ordered by task priority. + * + * @param xTicksToWait The maximum amount of time that the task should wait + * for the event to occur. This is specified in kernel ticks, the constant + * portTICK_PERIOD_MS can be used to convert kernel ticks into a real time + * period. + */ +// llgo:link (*ListT).VTaskPlaceOnEventList C.vTaskPlaceOnEventList +func (recv_ *ListT) VTaskPlaceOnEventList(xTicksToWait TickTypeT) { +} + +// llgo:link (*ListT).VTaskPlaceOnUnorderedEventList C.vTaskPlaceOnUnorderedEventList +func (recv_ *ListT) VTaskPlaceOnUnorderedEventList(xItemValue TickTypeT, xTicksToWait TickTypeT) { +} + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * This function performs nearly the same function as vTaskPlaceOnEventList(). + * The difference being that this function does not permit tasks to block + * indefinitely, whereas vTaskPlaceOnEventList() does. + * + */ +// llgo:link (*ListT).VTaskPlaceOnEventListRestricted C.vTaskPlaceOnEventListRestricted +func (recv_ *ListT) VTaskPlaceOnEventListRestricted(xTicksToWait TickTypeT, xWaitIndefinitely BaseTypeT) { +} + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes a task from both the specified event list and the list of blocked + * tasks, and places it on a ready queue. + * + * xTaskRemoveFromEventList()/vTaskRemoveFromUnorderedEventList() will be called + * if either an event occurs to unblock a task, or the block timeout period + * expires. + * + * xTaskRemoveFromEventList() is used when the event list is in task priority + * order. It removes the list item from the head of the event list as that will + * have the highest priority owning task of all the tasks on the event list. + * vTaskRemoveFromUnorderedEventList() is used when the event list is not + * ordered and the event list items hold something other than the owning tasks + * priority. In this case the event list item value is updated to the value + * passed in the xItemValue parameter. + * + * @return pdTRUE if the task being removed has a higher priority than the task + * making the call, otherwise pdFALSE. + */ +// llgo:link (*ListT).XTaskRemoveFromEventList C.xTaskRemoveFromEventList +func (recv_ *ListT) XTaskRemoveFromEventList() BaseTypeT { + return 0 +} + +// llgo:link (*ListItemT).VTaskRemoveFromUnorderedEventList C.vTaskRemoveFromUnorderedEventList +func (recv_ *ListItemT) VTaskRemoveFromUnorderedEventList(xItemValue TickTypeT) { +} + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Sets the pointer to the current TCB to the TCB of the highest priority task + * that is ready to run. + */ +//go:linkname VTaskSwitchContext C.vTaskSwitchContext +func VTaskSwitchContext() + +/* + * THESE FUNCTIONS MUST NOT BE USED FROM APPLICATION CODE. THEY ARE USED BY + * THE EVENT BITS MODULE. + */ +//go:linkname UxTaskResetEventItemValue C.uxTaskResetEventItemValue +func UxTaskResetEventItemValue() TickTypeT + +/* + * Return the handle of the calling task. + */ +//go:linkname XTaskGetCurrentTaskHandle C.xTaskGetCurrentTaskHandle +func XTaskGetCurrentTaskHandle() TaskHandleT + +/* + * Shortcut used by the queue implementation to prevent unnecessary call to + * taskYIELD(); + */ +//go:linkname VTaskMissedYield C.vTaskMissedYield +func VTaskMissedYield() + +/* + * Returns the scheduler state as taskSCHEDULER_RUNNING, + * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED. + */ +//go:linkname XTaskGetSchedulerState C.xTaskGetSchedulerState +func XTaskGetSchedulerState() BaseTypeT + +/* + * Raises the priority of the mutex holder to that of the calling task should + * the mutex holder have a priority less than the calling task. + */ +//go:linkname XTaskPriorityInherit C.xTaskPriorityInherit +func XTaskPriorityInherit(pxMutexHolder TaskHandleT) BaseTypeT + +/* + * Set the priority of a task back to its proper priority in the case that it + * inherited a higher priority while it was holding a semaphore. + */ +//go:linkname XTaskPriorityDisinherit C.xTaskPriorityDisinherit +func XTaskPriorityDisinherit(pxMutexHolder TaskHandleT) BaseTypeT + +/* + * If a higher priority task attempting to obtain a mutex caused a lower + * priority task to inherit the higher priority task's priority - but the higher + * priority task then timed out without obtaining the mutex, then the lower + * priority task will disinherit the priority again - but only down as far as + * the highest priority task that is still waiting for the mutex (if there were + * more than one task waiting for the mutex). + */ +//go:linkname VTaskPriorityDisinheritAfterTimeout C.vTaskPriorityDisinheritAfterTimeout +func VTaskPriorityDisinheritAfterTimeout(pxMutexHolder TaskHandleT, uxHighestPriorityWaitingTask UBaseTypeT) + +/* + * Get the uxTaskNumber assigned to the task referenced by the xTask parameter. + */ +//go:linkname UxTaskGetTaskNumber C.uxTaskGetTaskNumber +func UxTaskGetTaskNumber(xTask TaskHandleT) UBaseTypeT + +/* + * Set the uxTaskNumber of the task referenced by the xTask parameter to + * uxHandle. + */ +//go:linkname VTaskSetTaskNumber C.vTaskSetTaskNumber +func VTaskSetTaskNumber(xTask TaskHandleT, uxHandle UBaseTypeT) + +/* + * Only available when configUSE_TICKLESS_IDLE is set to 1. + * If tickless mode is being used, or a low power mode is implemented, then + * the tick interrupt will not execute during idle periods. When this is the + * case, the tick count value maintained by the scheduler needs to be kept up + * to date with the actual execution time by being skipped forward by a time + * equal to the idle period. + */ +// llgo:link TickTypeT.VTaskStepTick C.vTaskStepTick +func (recv_ TickTypeT) VTaskStepTick() { +} + +/* + * Only available when configUSE_TICKLESS_IDLE is set to 1. + * Provided for use within portSUPPRESS_TICKS_AND_SLEEP() to allow the port + * specific sleep function to determine if it is ok to proceed with the sleep, + * and if it is ok to proceed, if it is ok to sleep indefinitely. + * + * This function is necessary because portSUPPRESS_TICKS_AND_SLEEP() is only + * called with the scheduler suspended, not from within a critical section. It + * is therefore possible for an interrupt to request a context switch between + * portSUPPRESS_TICKS_AND_SLEEP() and the low power mode actually being + * entered. eTaskConfirmSleepModeStatus() should be called from a short + * critical section between the timer being stopped and the sleep mode being + * entered to ensure it is ok to proceed into the sleep mode. + */ +//go:linkname ETaskConfirmSleepModeStatus C.eTaskConfirmSleepModeStatus +func ETaskConfirmSleepModeStatus() ESleepModeStatus + +/* + * For internal use only. Increment the mutex held count when a mutex is + * taken and return the handle of the task that has taken the mutex. + */ +//go:linkname PvTaskIncrementMutexHeldCount C.pvTaskIncrementMutexHeldCount +func PvTaskIncrementMutexHeldCount() TaskHandleT + +/* + * For internal use only. Same as vTaskSetTimeOutState(), but without a critical + * section. + */ +// llgo:link (*TimeOutT).VTaskInternalSetTimeOutState C.vTaskInternalSetTimeOutState +func (recv_ *TimeOutT) VTaskInternalSetTimeOutState() { +} diff --git a/freertos/timers.go b/freertos/timers.go new file mode 100644 index 00000000..d458d4c1 --- /dev/null +++ b/freertos/timers.go @@ -0,0 +1,604 @@ +package freertos + +import ( + "github.com/goplus/lib/c" + _ "unsafe" +) + +/** + * Type by which software timers are referenced. For example, a call to + * xTimerCreate() returns an TimerHandle_t variable that can then be used to + * reference the subject timer in calls to other software timer API functions + * (for example, xTimerStart(), xTimerReset(), etc.). + */ + +type TmrTimerControl struct { + Unused [8]uint8 +} +type TimerHandleT *TmrTimerControl + +// llgo:type C +type TimerCallbackFunctionT func(TimerHandleT) + +// llgo:type C +type PendedFunctionT func(c.Pointer, c.Uint32T) + +/** + * + * Creates a new software timer instance, and returns a handle by which the + * created software timer can be referenced. + * + * Internally, within the FreeRTOS implementation, software timers use a block + * of memory, in which the timer data structure is stored. If a software timer + * is created using xTimerCreate() then the required memory is automatically + * dynamically allocated inside the xTimerCreate() function. (see + * https://www.FreeRTOS.org/a00111.html). If a software timer is created using + * xTimerCreateStatic() then the application writer must provide the memory that + * will get used by the software timer. xTimerCreateStatic() therefore allows a + * software timer to be created without using any dynamic memory allocation. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a + * timer into the active state. + * + * @param pcTimerName A text name that is assigned to the timer. This is done + * purely to assist debugging. The kernel itself only ever references a timer + * by its handle, and never by its name. + * + * @param xTimerPeriodInTicks The timer period. The time is defined in tick + * periods so the constant portTICK_PERIOD_MS can be used to convert a time that + * has been specified in milliseconds. For example, if the timer must expire + * after 100 ticks, then xTimerPeriodInTicks should be set to 100. + * Alternatively, if the timer must expire after 500ms, then xPeriod can be set + * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or + * equal to 1000. Time timer period must be greater than 0. + * + * @param xAutoReload If xAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. + * If xAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * + * @param pvTimerID An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to identify which + * timer expired when the same callback function is assigned to more than one + * timer. + * + * @param pxCallbackFunction The function to call when the timer expires. + * Callback functions must have the prototype defined by TimerCallbackFunction_t, + * which is "void vCallbackFunction( TimerHandle_t xTimer );". + * + * @return If the timer is successfully created then a handle to the newly + * created timer is returned. If the timer cannot be created because there is + * insufficient FreeRTOS heap remaining to allocate the timer + * structures then NULL is returned. + * + * Example usage: + * @verbatim + * #define NUM_TIMERS 5 + * + * // An array to hold handles to the created timers. + * TimerHandle_t xTimers[ NUM_TIMERS ]; + * + * // An array to hold a count of the number of times each timer expires. + * int32_t lExpireCounters[ NUM_TIMERS ] = { 0 }; + * + * // Define a callback function that will be used by multiple timer instances. + * // The callback function does nothing but count the number of times the + * // associated timer expires, and stop the timer once the timer has expired + * // 10 times. + * void vTimerCallback( TimerHandle_t pxTimer ) + * { + * int32_t lArrayIndex; + * const int32_t xMaxExpiryCountBeforeStopping = 10; + * + * // Optionally do something if the pxTimer parameter is NULL. + * configASSERT( pxTimer ); + * + * // Which timer expired? + * lArrayIndex = ( int32_t ) pvTimerGetTimerID( pxTimer ); + * + * // Increment the number of times that pxTimer has expired. + * lExpireCounters[ lArrayIndex ] += 1; + * + * // If the timer has expired 10 times then stop it from running. + * if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping ) + * { + * // Do not use a block time if calling a timer API function from a + * // timer callback function, as doing so could cause a deadlock! + * xTimerStop( pxTimer, 0 ); + * } + * } + * + * void main( void ) + * { + * int32_t x; + * + * // Create then start some timers. Starting the timers before the scheduler + * // has been started means the timers will start running immediately that + * // the scheduler starts. + * for( x = 0; x < NUM_TIMERS; x++ ) + * { + * xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel. + * ( 100 * ( x + 1 ) ), // The timer period in ticks. + * pdTRUE, // The timers will auto-reload themselves when they expire. + * ( void * ) x, // Assign each timer a unique id equal to its array index. + * vTimerCallback // Each timer calls the same callback when it expires. + * ); + * + * if( xTimers[ x ] == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xTimers[ x ], 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timers running as they have already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +//go:linkname XTimerCreate C.xTimerCreate +func XTimerCreate(pcTimerName *c.Char, xTimerPeriodInTicks TickTypeT, xAutoReload BaseTypeT, pvTimerID c.Pointer, pxCallbackFunction TimerCallbackFunctionT) TimerHandleT + +/** + * + * Creates a new software timer instance, and returns a handle by which the + * created software timer can be referenced. + * + * Internally, within the FreeRTOS implementation, software timers use a block + * of memory, in which the timer data structure is stored. If a software timer + * is created using xTimerCreate() then the required memory is automatically + * dynamically allocated inside the xTimerCreate() function. (see + * https://www.FreeRTOS.org/a00111.html). If a software timer is created using + * xTimerCreateStatic() then the application writer must provide the memory that + * will get used by the software timer. xTimerCreateStatic() therefore allows a + * software timer to be created without using any dynamic memory allocation. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a + * timer into the active state. + * + * @param pcTimerName A text name that is assigned to the timer. This is done + * purely to assist debugging. The kernel itself only ever references a timer + * by its handle, and never by its name. + * + * @param xTimerPeriodInTicks The timer period. The time is defined in tick + * periods so the constant portTICK_PERIOD_MS can be used to convert a time that + * has been specified in milliseconds. For example, if the timer must expire + * after 100 ticks, then xTimerPeriodInTicks should be set to 100. + * Alternatively, if the timer must expire after 500ms, then xPeriod can be set + * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or + * equal to 1000. The timer period must be greater than 0. + * + * @param xAutoReload If xAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. + * If xAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * + * @param pvTimerID An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to identify which + * timer expired when the same callback function is assigned to more than one + * timer. + * + * @param pxCallbackFunction The function to call when the timer expires. + * Callback functions must have the prototype defined by TimerCallbackFunction_t, + * which is "void vCallbackFunction( TimerHandle_t xTimer );". + * + * @param pxTimerBuffer Must point to a variable of type StaticTimer_t, which + * will be then be used to hold the software timer's data structures, removing + * the need for the memory to be allocated dynamically. + * + * @return If the timer is created then a handle to the created timer is + * returned. If pxTimerBuffer was NULL then NULL is returned. + * + * Example usage: + * @verbatim + * + * // The buffer used to hold the software timer's data structure. + * static StaticTimer_t xTimerBuffer; + * + * // A variable that will be incremented by the software timer's callback + * // function. + * UBaseType_t uxVariableToIncrement = 0; + * + * // A software timer callback function that increments a variable passed to + * // it when the software timer was created. After the 5th increment the + * // callback function stops the software timer. + * static void prvTimerCallback( TimerHandle_t xExpiredTimer ) + * { + * UBaseType_t *puxVariableToIncrement; + * BaseType_t xReturned; + * + * // Obtain the address of the variable to increment from the timer ID. + * puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer ); + * + * // Increment the variable to show the timer callback has executed. + * ( *puxVariableToIncrement )++; + * + * // If this callback has executed the required number of times, stop the + * // timer. + * if( *puxVariableToIncrement == 5 ) + * { + * // This is called from a timer callback so must not block. + * xTimerStop( xExpiredTimer, staticDONT_BLOCK ); + * } + * } + * + * + * void main( void ) + * { + * // Create the software time. xTimerCreateStatic() has an extra parameter + * // than the normal xTimerCreate() API function. The parameter is a pointer + * // to the StaticTimer_t structure that will hold the software timer + * // structure. If the parameter is passed as NULL then the structure will be + * // allocated dynamically, just as if xTimerCreate() had been called. + * xTimer = xTimerCreateStatic( "T1", // Text name for the task. Helps debugging only. Not used by FreeRTOS. + * xTimerPeriod, // The period of the timer in ticks. + * pdTRUE, // This is an auto-reload timer. + * ( void * ) &uxVariableToIncrement, // A variable incremented by the software timer's callback function + * prvTimerCallback, // The function to execute when the timer expires. + * &xTimerBuffer ); // The buffer that will hold the software timer structure. + * + * // The scheduler has not started yet so a block time is not used. + * xReturned = xTimerStart( xTimer, 0 ); + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timers running as they have already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +//go:linkname XTimerCreateStatic C.xTimerCreateStatic +func XTimerCreateStatic(pcTimerName *c.Char, xTimerPeriodInTicks TickTypeT, xAutoReload BaseTypeT, pvTimerID c.Pointer, pxCallbackFunction TimerCallbackFunctionT, pxTimerBuffer *StaticTimerT) TimerHandleT + +/** + * + * Returns the ID assigned to the timer. + * + * IDs are assigned to timers using the pvTimerID parameter of the call to + * xTimerCreated() that was used to create the timer, and by calling the + * vTimerSetTimerID() API function. + * + * If the same callback function is assigned to multiple timers then the timer + * ID can be used as time specific (timer local) storage. + * + * @param xTimer The timer being queried. + * + * @return The ID assigned to the timer being queried. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + */ +//go:linkname PvTimerGetTimerID C.pvTimerGetTimerID +func PvTimerGetTimerID(xTimer TimerHandleT) c.Pointer + +/** + * + * Sets the ID assigned to the timer. + * + * IDs are assigned to timers using the pvTimerID parameter of the call to + * xTimerCreated() that was used to create the timer. + * + * If the same callback function is assigned to multiple timers then the timer + * ID can be used as time specific (timer local) storage. + * + * @param xTimer The timer being updated. + * + * @param pvNewID The ID to assign to the timer. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + */ +//go:linkname VTimerSetTimerID C.vTimerSetTimerID +func VTimerSetTimerID(xTimer TimerHandleT, pvNewID c.Pointer) + +/** + * + * 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(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the + * active state. + * + * @param xTimer The timer being queried. + * + * @return pdFALSE will be returned if the timer is dormant. A value other than + * pdFALSE will be returned if the timer is active. + * + * Example usage: + * @verbatim + * // This function assumes xTimer has already been created. + * void vAFunction( TimerHandle_t xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is active, do something. + * } + * else + * { + * // xTimer is not active, do something else. + * } + * } + * @endverbatim + */ +//go:linkname XTimerIsTimerActive C.xTimerIsTimerActive +func XTimerIsTimerActive(xTimer TimerHandleT) BaseTypeT + +/** + * + * Simply returns the handle of the timer service/daemon task. It it not valid + * to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started. + */ +//go:linkname XTimerGetTimerDaemonTaskHandle C.xTimerGetTimerDaemonTaskHandle +func XTimerGetTimerDaemonTaskHandle() TaskHandleT + +/** + * + * + * 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'). + * + * Ideally an interrupt service routine (ISR) is kept as short as possible, but + * sometimes an ISR either has a lot of processing to do, or needs to perform + * processing that is not deterministic. In these cases + * xTimerPendFunctionCallFromISR() can be used to defer processing of a function + * to the RTOS daemon task. + * + * A mechanism is provided that allows the interrupt to return directly to the + * task that will subsequently execute the pended callback function. This + * allows the callback function to execute contiguously in time with the + * interrupt - just as if the callback had executed in the interrupt itself. + * + * @param xFunctionToPend The function to execute from the timer service/ + * daemon task. The function must conform to the PendedFunction_t + * prototype. + * + * @param pvParameter1 The value of the callback function's first parameter. + * The parameter has a void * type to allow it to be used to pass any type. + * For example, unsigned longs can be cast to a void *, or the void * can be + * used to point to a structure. + * + * @param ulParameter2 The value of the callback function's second parameter. + * + * @param pxHigherPriorityTaskWoken As mentioned above, calling this function + * will result in a message being sent to the timer daemon task. If the + * priority of the timer daemon task (which is set using + * configTIMER_TASK_PRIORITY in FreeRTOSConfig.h) is higher than the priority of + * the currently running task (the task the interrupt interrupted) then + * *pxHigherPriorityTaskWoken will be set to pdTRUE within + * xTimerPendFunctionCallFromISR(), indicating that a context switch should be + * requested before the interrupt exits. For that reason + * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the + * example code below. + * + * @return pdPASS is returned if the message was successfully sent to the + * timer daemon task, otherwise pdFALSE is returned. + * + * Example usage: + * @verbatim + * + * // The callback function that will execute in the context of the daemon task. + * // Note callback functions must all use this same prototype. + * void vProcessInterface( void *pvParameter1, uint32_t ulParameter2 ) + * { + * BaseType_t xInterfaceToService; + * + * // The interface that requires servicing is passed in the second + * // parameter. The first parameter is not used in this case. + * xInterfaceToService = ( BaseType_t ) ulParameter2; + * + * // ...Perform the processing here... + * } + * + * // An ISR that receives data packets from multiple interfaces + * void vAnISR( void ) + * { + * BaseType_t xInterfaceToService, xHigherPriorityTaskWoken; + * + * // Query the hardware to determine which interface needs processing. + * xInterfaceToService = prvCheckInterfaces(); + * + * // The actual processing is to be deferred to a task. Request the + * // vProcessInterface() callback function is executed, passing in the + * // number of the interface that needs processing. The interface to + * // service is passed in the second parameter. The first parameter is + * // not used in this case. + * xHigherPriorityTaskWoken = pdFALSE; + * xTimerPendFunctionCallFromISR( vProcessInterface, NULL, ( uint32_t ) xInterfaceToService, &xHigherPriorityTaskWoken ); + * + * // 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 ); + * + * } + * @endverbatim + */ +//go:linkname XTimerPendFunctionCallFromISR C.xTimerPendFunctionCallFromISR +func XTimerPendFunctionCallFromISR(xFunctionToPend PendedFunctionT, pvParameter1 c.Pointer, ulParameter2 c.Uint32T, pxHigherPriorityTaskWoken *BaseTypeT) BaseTypeT + +/** + * + * + * 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'). + * + * @param xFunctionToPend The function to execute from the timer service/ + * daemon task. The function must conform to the PendedFunction_t + * prototype. + * + * @param pvParameter1 The value of the callback function's first parameter. + * The parameter has a void * type to allow it to be used to pass any type. + * For example, unsigned longs can be cast to a void *, or the void * can be + * used to point to a structure. + * + * @param ulParameter2 The value of the callback function's second parameter. + * + * @param xTicksToWait Calling this function will result in a message being + * sent to the timer daemon task on a queue. xTicksToWait is the amount of + * time the calling task should remain in the Blocked state (so not using any + * processing time) for space to become available on the timer queue if the + * queue is found to be full. + * + * @return pdPASS is returned if the message was successfully sent to the + * timer daemon task, otherwise pdFALSE is returned. + * + */ +//go:linkname XTimerPendFunctionCall C.xTimerPendFunctionCall +func XTimerPendFunctionCall(xFunctionToPend PendedFunctionT, pvParameter1 c.Pointer, ulParameter2 c.Uint32T, xTicksToWait TickTypeT) BaseTypeT + +/** + * + * Returns the name that was assigned to a timer when the timer was created. + * + * @param xTimer The handle of the timer being queried. + * + * @return The name assigned to the timer specified by the xTimer parameter. + */ +//go:linkname PcTimerGetName C.pcTimerGetName +func PcTimerGetName(xTimer TimerHandleT) *c.Char + +/** + * + * Updates a timer to be either an auto-reload timer, in which case the timer + * automatically resets itself each time it expires, or a one-shot timer, in + * which case the timer will only expire once unless it is manually restarted. + * + * @param xTimer The handle of the timer being updated. + * + * @param xAutoReload If xAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the timer's period (see the + * xTimerPeriodInTicks parameter of the xTimerCreate() API function). If + * xAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + */ +//go:linkname VTimerSetReloadMode C.vTimerSetReloadMode +func VTimerSetReloadMode(xTimer TimerHandleT, xAutoReload BaseTypeT) + +/** + * + * Queries a timer to determine if it is an auto-reload timer, in which case the timer + * automatically resets itself each time it expires, or a one-shot timer, in + * which case the timer will only expire once unless it is manually restarted. + * + * @param xTimer The handle of the timer being queried. + * + * @return If the timer is an auto-reload timer then pdTRUE is returned, otherwise + * pdFALSE is returned. + */ +//go:linkname XTimerGetReloadMode C.xTimerGetReloadMode +func XTimerGetReloadMode(xTimer TimerHandleT) BaseTypeT + +/** + * + * Queries a timer to determine if it is an auto-reload timer, in which case the timer + * automatically resets itself each time it expires, or a one-shot timer, in + * which case the timer will only expire once unless it is manually restarted. + * + * @param xTimer The handle of the timer being queried. + * + * @return If the timer is an auto-reload timer then pdTRUE is returned, otherwise + * pdFALSE is returned. + */ +//go:linkname UxTimerGetReloadMode C.uxTimerGetReloadMode +func UxTimerGetReloadMode(xTimer TimerHandleT) UBaseTypeT + +/** + * + * Returns the period of a timer. + * + * @param xTimer The handle of the timer being queried. + * + * @return The period of the timer in ticks. + */ +//go:linkname XTimerGetPeriod C.xTimerGetPeriod +func XTimerGetPeriod(xTimer TimerHandleT) TickTypeT + +/** + * + * 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. + * + * @param xTimer The handle of the timer being queried. + * + * @return If the timer is running then the time in ticks at which the timer + * will next expire is returned. If the timer is not running then the return + * value is undefined. + */ +//go:linkname XTimerGetExpiryTime C.xTimerGetExpiryTime +func XTimerGetExpiryTime(xTimer TimerHandleT) TickTypeT + +/** + * + * Retrieve pointer to a statically created timer's data structure + * buffer. This is the same buffer that is supplied at the time of + * creation. + * + * @param xTimer The timer for which to retrieve the buffer. + * + * @param ppxTimerBuffer Used to return a pointer to the timers's data + * structure buffer. + * + * @return pdTRUE if the buffer was retrieved, pdFALSE otherwise. + */ +//go:linkname XTimerGetStaticBuffer C.xTimerGetStaticBuffer +func XTimerGetStaticBuffer(xTimer TimerHandleT, ppxTimerBuffer **StaticTimerT) BaseTypeT + +/* + * Functions beyond this part are not part of the public API and are intended + * for use by the kernel only. + */ +//go:linkname XTimerCreateTimerTask C.xTimerCreateTimerTask +func XTimerCreateTimerTask() BaseTypeT + +//go:linkname XTimerGenericCommand C.xTimerGenericCommand +func XTimerGenericCommand(xTimer TimerHandleT, xCommandID BaseTypeT, xOptionalValue TickTypeT, pxHigherPriorityTaskWoken *BaseTypeT, xTicksToWait TickTypeT) BaseTypeT + +/** + * + * This function is used to provide a statically allocated block of memory to FreeRTOS to hold the Timer Task TCB. This function is required when + * configSUPPORT_STATIC_ALLOCATION is set. For more information see this URI: https://www.FreeRTOS.org/a00110.html#configSUPPORT_STATIC_ALLOCATION + * + * @param ppxTimerTaskTCBBuffer A handle to a statically allocated TCB buffer + * @param ppxTimerTaskStackBuffer A handle to a statically allocated Stack buffer for the idle task + * @param pulTimerTaskStackSize A pointer to the number of elements that will fit in the allocated stack buffer + */ +//go:linkname VApplicationGetTimerTaskMemory C.vApplicationGetTimerTaskMemory +func VApplicationGetTimerTaskMemory(ppxTimerTaskTCBBuffer **StaticTaskT, ppxTimerTaskStackBuffer **StackTypeT, pulTimerTaskStackSize *c.Uint32T)