Browse Source

Add files for esp-idf

tangzz98 3 years ago
parent
commit
2660eb8467

+ 1 - 1
FreeRTOS/SConscript

@@ -6,7 +6,7 @@ src	= Glob('*.c')
 src += Glob(os.path.join("portable", "rt-thread", "*.c"))
 src += Glob(os.path.join("portable", "MemMang", "heap_3.c"))
 
-CPPPATH = [os.path.join(cwd, "include"), os.path.join(cwd, "portable", "rt-thread")]
+CPPPATH = [os.path.join(cwd, "include", "freertos"), os.path.join(cwd, "portable", "rt-thread")]
 
 group = DefineGroup('FreeRTOS', src, depend = [''], CPPPATH = CPPPATH)
 

+ 9 - 2
FreeRTOS/include/FreeRTOS.h → FreeRTOS/include/freertos/FreeRTOS.h

@@ -67,8 +67,15 @@
 /* Definitions specific to the port being used. */
 #include "portable.h"
 
-/* Read only */
-#define configUSE_NEWLIB_REENTRANT    0
+/* Must be defaulted before configUSE_NEWLIB_REENTRANT is used below. */
+#ifndef configUSE_NEWLIB_REENTRANT
+    #define configUSE_NEWLIB_REENTRANT    0
+#endif
+
+/* Required if struct _reent is used. */
+#if ( configUSE_NEWLIB_REENTRANT == 1 )
+    #include <reent.h>
+#endif
 
 /*
  * Check all the required application specific macros have been defined.

+ 0 - 0
FreeRTOS/include/event_groups.h → FreeRTOS/include/freertos/event_groups.h


+ 499 - 0
FreeRTOS/include/freertos/list.h

@@ -0,0 +1,499 @@
+/*
+ * FreeRTOS Kernel V10.4.6
+ * Copyright (C) 2021 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * https://www.FreeRTOS.org
+ * https://github.com/FreeRTOS
+ *
+ */
+
+/*
+ * This is the list implementation used by the scheduler.  While it is tailored
+ * heavily for the schedulers needs, it is also available for use by
+ * application code.
+ *
+ * list_ts can only store pointers to list_item_ts.  Each ListItem_t contains a
+ * numeric value (xItemValue).  Most of the time the lists are sorted in
+ * ascending item value order.
+ *
+ * Lists are created already containing one list item.  The value of this
+ * item is the maximum possible that can be stored, it is therefore always at
+ * the end of the list and acts as a marker.  The list member pxHead always
+ * points to this marker - even though it is at the tail of the list.  This
+ * is because the tail contains a wrap back pointer to the true head of
+ * the list.
+ *
+ * In addition to it's value, each list item contains a pointer to the next
+ * item in the list (pxNext), a pointer to the list it is in (pxContainer)
+ * and a pointer to back to the object that contains it.  These later two
+ * pointers are included for efficiency of list manipulation.  There is
+ * effectively a two way link between the object containing the list item and
+ * the list item itself.
+ *
+ *
+ * \page ListIntroduction List Implementation
+ * \ingroup FreeRTOSIntro
+ */
+
+
+#ifndef LIST_H
+#define LIST_H
+
+#ifndef INC_FREERTOS_H
+    #error "FreeRTOS.h must be included before list.h"
+#endif
+
+/*
+ * The list structure members are modified from within interrupts, and therefore
+ * by rights should be declared volatile.  However, they are only modified in a
+ * functionally atomic way (within critical sections of with the scheduler
+ * suspended) and are either passed by reference into a function or indexed via
+ * a volatile variable.  Therefore, in all use cases tested so far, the volatile
+ * qualifier can be omitted in order to provide a moderate performance
+ * improvement without adversely affecting functional behaviour.  The assembly
+ * instructions generated by the IAR, ARM and GCC compilers when the respective
+ * compiler's options were set for maximum optimisation has been inspected and
+ * deemed to be as intended.  That said, as compiler technology advances, and
+ * especially if aggressive cross module optimisation is used (a use case that
+ * has not been exercised to any great extend) then it is feasible that the
+ * volatile qualifier will be needed for correct optimisation.  It is expected
+ * that a compiler removing essential code because, without the volatile
+ * qualifier on the list structure members and with aggressive cross module
+ * optimisation, the compiler deemed the code unnecessary will result in
+ * complete and obvious failure of the scheduler.  If this is ever experienced
+ * then the volatile qualifier can be inserted in the relevant places within the
+ * list structures by simply defining configLIST_VOLATILE to volatile in
+ * FreeRTOSConfig.h (as per the example at the bottom of this comment block).
+ * If configLIST_VOLATILE is not defined then the preprocessor directives below
+ * will simply #define configLIST_VOLATILE away completely.
+ *
+ * To use volatile list structure members then add the following line to
+ * FreeRTOSConfig.h (without the quotes):
+ * "#define configLIST_VOLATILE volatile"
+ */
+#ifndef configLIST_VOLATILE
+    #define configLIST_VOLATILE
+#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */
+
+/* *INDENT-OFF* */
+#ifdef __cplusplus
+    extern "C" {
+#endif
+/* *INDENT-ON* */
+
+/* Macros that can be used to place known values within the list structures,
+ * then check that the known values do not get corrupted during the execution of
+ * the application.   These may catch the list data structures being overwritten in
+ * memory.  They will not catch data errors caused by incorrect configuration or
+ * use of FreeRTOS.*/
+#if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 )
+    /* Define the macros to do nothing. */
+    #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
+    #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
+    #define listFIRST_LIST_INTEGRITY_CHECK_VALUE
+    #define listSECOND_LIST_INTEGRITY_CHECK_VALUE
+    #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )
+    #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )
+    #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList )
+    #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )
+    #define listTEST_LIST_ITEM_INTEGRITY( pxItem )
+    #define listTEST_LIST_INTEGRITY( pxList )
+#else /* if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) */
+    /* Define macros that add new members into the list structures. */
+    #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE     TickType_t xListItemIntegrityValue1;
+    #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE    TickType_t xListItemIntegrityValue2;
+    #define listFIRST_LIST_INTEGRITY_CHECK_VALUE          TickType_t xListIntegrityValue1;
+    #define listSECOND_LIST_INTEGRITY_CHECK_VALUE         TickType_t xListIntegrityValue2;
+
+/* Define macros that set the new structure members to known values. */
+    #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )     ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
+    #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )    ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
+    #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList )              ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
+    #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )              ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
+
+/* Define macros that will assert if one of the structure members does not
+ * contain its expected value. */
+    #define listTEST_LIST_ITEM_INTEGRITY( pxItem )                      configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
+    #define listTEST_LIST_INTEGRITY( pxList )                           configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
+#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */
+
+
+/*
+ * Definition of the only type of object that a list can contain.
+ */
+struct xLIST;
+struct xLIST_ITEM
+{
+    listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE           /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
+    configLIST_VOLATILE TickType_t xItemValue;          /*< The value being listed.  In most cases this is used to sort the list in ascending order. */
+    struct xLIST_ITEM * configLIST_VOLATILE pxNext;     /*< Pointer to the next ListItem_t in the list. */
+    struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */
+    void * pvOwner;                                     /*< Pointer to the object (normally a TCB) that contains the list item.  There is therefore a two way link between the object containing the list item and the list item itself. */
+    struct xLIST * configLIST_VOLATILE pxContainer;     /*< Pointer to the list in which this list item is placed (if any). */
+    listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE          /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
+};
+typedef struct xLIST_ITEM ListItem_t;                   /* For some reason lint wants this as two separate definitions. */
+
+struct xMINI_LIST_ITEM
+{
+    listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
+    configLIST_VOLATILE TickType_t xItemValue;
+    struct xLIST_ITEM * configLIST_VOLATILE pxNext;
+    struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
+};
+typedef struct xMINI_LIST_ITEM MiniListItem_t;
+
+/*
+ * Definition of the type of queue used by the scheduler.
+ */
+typedef struct xLIST
+{
+    listFIRST_LIST_INTEGRITY_CHECK_VALUE      /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
+    volatile UBaseType_t uxNumberOfItems;
+    ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list.  Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */
+    MiniListItem_t xListEnd;                  /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
+    listSECOND_LIST_INTEGRITY_CHECK_VALUE     /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
+} List_t;
+
+/*
+ * Access macro to set the owner of a list item.  The owner of a list item
+ * is the object (usually a TCB) that contains the list item.
+ *
+ * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
+ * \ingroup LinkedList
+ */
+#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner )    ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) )
+
+/*
+ * Access macro to get the owner of a list item.  The owner of a list item
+ * is the object (usually a TCB) that contains the list item.
+ *
+ * \page listGET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
+ * \ingroup LinkedList
+ */
+#define listGET_LIST_ITEM_OWNER( pxListItem )             ( ( pxListItem )->pvOwner )
+
+/*
+ * Access macro to set the value of the list item.  In most cases the value is
+ * used to sort the list in ascending order.
+ *
+ * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
+ * \ingroup LinkedList
+ */
+#define listSET_LIST_ITEM_VALUE( pxListItem, xValue )     ( ( pxListItem )->xItemValue = ( xValue ) )
+
+/*
+ * Access macro to retrieve the value of the list item.  The value can
+ * represent anything - for example the priority of a task, or the time at
+ * which a task should be unblocked.
+ *
+ * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
+ * \ingroup LinkedList
+ */
+#define listGET_LIST_ITEM_VALUE( pxListItem )             ( ( pxListItem )->xItemValue )
+
+/*
+ * Access macro to retrieve the value of the list item at the head of a given
+ * list.
+ *
+ * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
+ * \ingroup LinkedList
+ */
+#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList )        ( ( ( pxList )->xListEnd ).pxNext->xItemValue )
+
+/*
+ * Return the list item at the head of the list.
+ *
+ * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY
+ * \ingroup LinkedList
+ */
+#define listGET_HEAD_ENTRY( pxList )                      ( ( ( pxList )->xListEnd ).pxNext )
+
+/*
+ * Return the next list item.
+ *
+ * \page listGET_NEXT listGET_NEXT
+ * \ingroup LinkedList
+ */
+#define listGET_NEXT( pxListItem )                        ( ( pxListItem )->pxNext )
+
+/*
+ * Return the list item that marks the end of the list
+ *
+ * \page listGET_END_MARKER listGET_END_MARKER
+ * \ingroup LinkedList
+ */
+#define listGET_END_MARKER( pxList )                      ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) )
+
+/*
+ * Access macro to determine if a list contains any items.  The macro will
+ * only have the value true if the list is empty.
+ *
+ * \page listLIST_IS_EMPTY listLIST_IS_EMPTY
+ * \ingroup LinkedList
+ */
+#define listLIST_IS_EMPTY( pxList )                       ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE )
+
+/*
+ * Access macro to return the number of items in the list.
+ */
+#define listCURRENT_LIST_LENGTH( pxList )                 ( ( pxList )->uxNumberOfItems )
+
+/*
+ * Access function to obtain the owner of the next entry in a list.
+ *
+ * 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
+ * and returns that entry's pxOwner parameter.  Using multiple calls to this
+ * function it is therefore possible to move through every item contained in
+ * a list.
+ *
+ * The pxOwner parameter of a list item is a pointer to the object that owns
+ * the list item.  In the scheduler this is normally a task control block.
+ * The pxOwner parameter effectively creates a two way link between the list
+ * item and its owner.
+ *
+ * @param pxTCB pxTCB is set to the address of the owner of the next list item.
+ * @param pxList The list from which the next item owner is to be returned.
+ *
+ * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
+ * \ingroup LinkedList
+ */
+#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )                                           \
+    {                                                                                          \
+        List_t * const pxConstList = ( pxList );                                               \
+        /* Increment the index to the next item and return the item, ensuring */               \
+        /* we don't return the marker used at the end of the list.  */                         \
+        ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;                           \
+        if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \
+        {                                                                                      \
+            ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;                       \
+        }                                                                                      \
+        ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner;                                         \
+    }
+
+/*
+ * Version of uxListRemove() that does not return a value.  Provided as a slight
+ * optimisation for xTaskIncrementTick() by being inline.
+ *
+ * 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 listREMOVE_ITEM listREMOVE_ITEM
+ * \ingroup LinkedList
+ */
+#define listREMOVE_ITEM( pxItemToRemove ) \
+    {                                     \
+        /* The list item knows which list it is in.  Obtain the list from the list \
+         * item. */                                                              \
+        List_t * const pxList = ( pxItemToRemove )->pxContainer;                 \
+                                                                                 \
+        ( pxItemToRemove )->pxNext->pxPrevious = ( pxItemToRemove )->pxPrevious; \
+        ( pxItemToRemove )->pxPrevious->pxNext = ( pxItemToRemove )->pxNext;     \
+        /* Make sure the index is left pointing to a valid item. */              \
+        if( pxList->pxIndex == ( pxItemToRemove ) )                              \
+        {                                                                        \
+            pxList->pxIndex = ( pxItemToRemove )->pxPrevious;                    \
+        }                                                                        \
+                                                                                 \
+        ( pxItemToRemove )->pxContainer = NULL;                                  \
+        ( pxList->uxNumberOfItems )--;                                           \
+    }
+
+/*
+ * Inline version of vListInsertEnd() to provide slight optimisation for
+ * xTaskIncrementTick().
+ *
+ * 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 listINSERT_END listINSERT_END
+ * \ingroup LinkedList
+ */
+#define listINSERT_END( pxList, pxNewListItem )           \
+    {                                                     \
+        ListItem_t * const pxIndex = ( pxList )->pxIndex; \
+                                                          \
+        /* Only effective when configASSERT() is also defined, these tests may catch \
+         * the list data structures being overwritten in memory.  They will not catch \
+         * data errors caused by incorrect configuration or use of FreeRTOS. */ \
+        listTEST_LIST_INTEGRITY( ( pxList ) );                                  \
+        listTEST_LIST_ITEM_INTEGRITY( ( pxNewListItem ) );                      \
+                                                                                \
+        /* Insert a new list item into ( pxList ), but rather than sort the list, \
+         * makes the new list item the last item to be removed by a call to \
+         * listGET_OWNER_OF_NEXT_ENTRY(). */                 \
+        ( pxNewListItem )->pxNext = pxIndex;                 \
+        ( pxNewListItem )->pxPrevious = pxIndex->pxPrevious; \
+                                                             \
+        pxIndex->pxPrevious->pxNext = ( pxNewListItem );     \
+        pxIndex->pxPrevious = ( pxNewListItem );             \
+                                                             \
+        /* Remember which list the item is in. */            \
+        ( pxNewListItem )->pxContainer = ( pxList );         \
+                                                             \
+        ( ( pxList )->uxNumberOfItems )++;                   \
+    }
+
+/*
+ * Access function to obtain the owner of the first entry in a list.  Lists
+ * are normally sorted in ascending item value order.
+ *
+ * This function returns the pxOwner member of the first item in the list.
+ * The pxOwner parameter of a list item is a pointer to the object that owns
+ * the list item.  In the scheduler this is normally a task control block.
+ * The pxOwner parameter effectively creates a two way link between the list
+ * item and its owner.
+ *
+ * @param pxList The list from which the owner of the head item is to be
+ * returned.
+ *
+ * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
+ * \ingroup LinkedList
+ */
+#define listGET_OWNER_OF_HEAD_ENTRY( pxList )            ( ( &( ( pxList )->xListEnd ) )->pxNext->pvOwner )
+
+/*
+ * Check to see if a list item is within a list.  The list item maintains a
+ * "container" pointer that points to the list it is in.  All this macro does
+ * is check to see if the container and the list match.
+ *
+ * @param pxList The list we want to know if the list item is within.
+ * @param pxListItem The list item we want to know if is in the list.
+ * @return pdTRUE if the list item is in the list, otherwise pdFALSE.
+ */
+#define listIS_CONTAINED_WITHIN( pxList, pxListItem )    ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) )
+
+/*
+ * Return the list a list item is contained within (referenced from).
+ *
+ * @param pxListItem The list item being queried.
+ * @return A pointer to the List_t object that references the pxListItem
+ */
+#define listLIST_ITEM_CONTAINER( pxListItem )            ( ( pxListItem )->pxContainer )
+
+/*
+ * This provides a crude means of knowing if a list has been initialised, as
+ * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise()
+ * function.
+ */
+#define listLIST_IS_INITIALISED( pxList )                ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY )
+
+/*
+ * 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
+ */
+void vListInitialise( List_t * const pxList );
+
+/*
+ * 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
+ */
+void vListInitialiseItem( ListItem_t * const pxItem );
+
+/*
+ * 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
+ */
+void vListInsert( List_t * const pxList,
+                  ListItem_t * const pxNewListItem );
+
+/*
+ * 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
+ */
+void vListInsertEnd( List_t * const pxList,
+                     ListItem_t * const pxNewListItem );
+
+/*
+ * 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
+ */
+UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove );
+
+/* *INDENT-OFF* */
+#ifdef __cplusplus
+    }
+#endif
+/* *INDENT-ON* */
+
+#endif /* ifndef LIST_H */

+ 17 - 0
FreeRTOS/include/portable.h → FreeRTOS/include/freertos/portable.h

@@ -57,6 +57,8 @@
 #endif
 /* *INDENT-ON* */
 
+#ifdef configUSE_FREERTOS_PROVIDED_HEAP
+
 /* Used by heap_5.c to define the start address and size of each memory region
  * that together comprise the total FreeRTOS heap space. */
 typedef struct HeapRegion
@@ -105,6 +107,21 @@ void vPortInitialiseBlocks( void );
 size_t xPortGetFreeHeapSize( void );
 size_t xPortGetMinimumEverFreeHeapSize( void );
 
+#else  // configUSE_FREERTOS_PROVIDED_HEAP
+
+/*
+ * Map to the memory management routines required for the port.
+ *
+ * Note that libc standard malloc/free are also available for
+ * non-FreeRTOS-specific code, and behave the same as
+ * pvPortMalloc()/vPortFree().
+ */
+#define pvPortMalloc malloc
+#define vPortFree free
+#define xPortGetFreeHeapSize esp_get_free_heap_size
+#define xPortGetMinimumEverFreeHeapSize esp_get_minimum_free_heap_size
+
+#endif
 void vPortEndScheduler( void );
 
 /* *INDENT-OFF* */

+ 6 - 0
FreeRTOS/include/projdefs.h → FreeRTOS/include/freertos/projdefs.h

@@ -42,6 +42,12 @@ typedef void (* TaskFunction_t)( void * );
     #define pdMS_TO_TICKS( xTimeInMs )    ( ( TickType_t ) rt_tick_from_millisecond( (rt_int32_t) xTimeInMs ) )
 #endif
 
+#ifdef ESP_PLATFORM
+#ifndef pdTICKS_TO_MS
+    #define pdTICKS_TO_MS( xTicks )   ( ( uint32_t ) ( xTicks ) * 1000 / configTICK_RATE_HZ )
+#endif
+#endif // ESP_PLATFORM
+
 #define pdFALSE                                  ( ( BaseType_t ) 0 )
 #define pdTRUE                                   ( ( BaseType_t ) 1 )
 

+ 19 - 0
FreeRTOS/include/queue.h → FreeRTOS/include/freertos/queue.h

@@ -1163,6 +1163,25 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex );
 BaseType_t xQueueGenericReset( QueueHandle_t xQueue,
                                BaseType_t xNewQueue );
 
+#ifdef ESP_PLATFORM
+/* Unimplemented */
+typedef struct QueueDefinition   * QueueSetHandle_t;
+typedef struct QueueDefinition   * QueueSetMemberHandle_t;
+QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength );
+BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
+                           QueueSetHandle_t xQueueSet );
+BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
+                                QueueSetHandle_t xQueueSet );
+QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
+                                            const TickType_t xTicksToWait );
+QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet );
+BaseType_t xQueuePeek( QueueHandle_t xQueue,
+                       void * const pvBuffer,
+                       TickType_t xTicksToWait );
+BaseType_t xQueueOverwrite(QueueHandle_t xQueue, const void * pvItemToQueue);
+BaseType_t xQueueOverwriteFromISR(QueueHandle_t xQueue, const void * pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken);
+#endif
+
 /* *INDENT-OFF* */
 #ifdef __cplusplus
     }

+ 0 - 0
FreeRTOS/include/semphr.h → FreeRTOS/include/freertos/semphr.h


+ 35 - 0
FreeRTOS/include/task.h → FreeRTOS/include/freertos/task.h

@@ -63,6 +63,10 @@
  * array. */
 #define tskDEFAULT_INDEX_TO_NOTIFY     ( 0 )
 
+#ifdef ESP_PLATFORM
+#define tskNO_AFFINITY  ( 0x7FFFFFFF )
+#endif
+
 /**
  * task. h
  *
@@ -293,6 +297,19 @@ typedef struct xTIME_OUT
                             TaskHandle_t * const pxCreatedTask );
 #endif
 
+#ifdef ESP_PLATFORM
+#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+    BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pvTaskCode,
+                                        const char * const pcName,
+                                        const uint32_t usStackDepth,
+                                        void * const pvParameters,
+                                        UBaseType_t uxPriority,
+                                        TaskHandle_t * const pvCreatedTask,
+                                        const BaseType_t xCoreID);
+
+#endif
+#endif
+
 /**
  * task. h
  * @code{c}
@@ -2226,6 +2243,24 @@ TaskHandle_t xTaskGetCurrentTaskHandle( void );
  */
 BaseType_t xTaskGetSchedulerState( void );
 
+#ifdef ESP_PLATFORM
+BaseType_t xTaskGetAffinity( TaskHandle_t xTask );
+TaskHandle_t xTaskGetCurrentTaskHandleForCPU( BaseType_t cpuid );
+TaskHandle_t xTaskGetIdleTaskHandleForCPU( UBaseType_t cpuid );
+/* Unimplemented */
+#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
+void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet,
+                                            BaseType_t xIndex,
+                                            void * pvValue );
+void * pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery,
+                                               BaseType_t xIndex );
+#if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS )
+typedef void (*TlsDeleteCallbackFunction_t)( int, void * );
+void vTaskSetThreadLocalStoragePointerAndDelCallback( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue, TlsDeleteCallbackFunction_t pvDelCallback);
+#endif
+#endif
+#endif
+
 /* *INDENT-OFF* */
 #ifdef __cplusplus
     }

+ 0 - 0
FreeRTOS/include/timers.h → FreeRTOS/include/freertos/timers.h


+ 215 - 0
FreeRTOS/list.c

@@ -0,0 +1,215 @@
+/*
+ * FreeRTOS Kernel V10.4.6
+ * Copyright (C) 2021 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * https://www.FreeRTOS.org
+ * https://github.com/FreeRTOS
+ *
+ */
+
+
+#include <stdlib.h>
+
+/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
+ * all the API functions to use the MPU wrappers.  That should only be done when
+ * task.h is included from an application file. */
+#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+
+#include "FreeRTOS.h"
+#include "list.h"
+
+/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified
+ * because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be
+ * defined for the header files above, but not in this file, in order to
+ * generate the correct privileged Vs unprivileged linkage and placement. */
+#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */
+
+/*-----------------------------------------------------------
+* PUBLIC LIST API documented in list.h
+*----------------------------------------------------------*/
+
+void vListInitialise( List_t * const pxList )
+{
+    /* The list structure contains a list item which is used to mark the
+     * end of the list.  To initialise the list the list end is inserted
+     * as the only list entry. */
+    pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
+
+    /* The list end value is the highest possible value in the list to
+     * ensure it remains at the end of the list. */
+    pxList->xListEnd.xItemValue = portMAX_DELAY;
+
+    /* The list end next and previous pointers point to itself so we know
+     * when the list is empty. */
+    pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );     /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
+    pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
+
+    pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
+
+    /* Write known values into the list if
+     * configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
+    listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
+    listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
+}
+/*-----------------------------------------------------------*/
+
+void vListInitialiseItem( ListItem_t * const pxItem )
+{
+    /* Make sure the list item is not recorded as being on a list. */
+    pxItem->pxContainer = NULL;
+
+    /* Write known values into the list item if
+     * configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
+    listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
+    listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
+}
+/*-----------------------------------------------------------*/
+
+void vListInsertEnd( List_t * const pxList,
+                     ListItem_t * const pxNewListItem )
+{
+    ListItem_t * const pxIndex = pxList->pxIndex;
+
+    /* Only effective when configASSERT() is also defined, these tests may catch
+     * the list data structures being overwritten in memory.  They will not catch
+     * data errors caused by incorrect configuration or use of FreeRTOS. */
+    listTEST_LIST_INTEGRITY( pxList );
+    listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
+
+    /* Insert a new list item into pxList, but rather than sort the list,
+     * makes the new list item the last item to be removed by a call to
+     * listGET_OWNER_OF_NEXT_ENTRY(). */
+    pxNewListItem->pxNext = pxIndex;
+    pxNewListItem->pxPrevious = pxIndex->pxPrevious;
+
+    /* Only used during decision coverage testing. */
+    mtCOVERAGE_TEST_DELAY();
+
+    pxIndex->pxPrevious->pxNext = pxNewListItem;
+    pxIndex->pxPrevious = pxNewListItem;
+
+    /* Remember which list the item is in. */
+    pxNewListItem->pxContainer = pxList;
+
+    ( pxList->uxNumberOfItems )++;
+}
+/*-----------------------------------------------------------*/
+
+void vListInsert( List_t * const pxList,
+                  ListItem_t * const pxNewListItem )
+{
+    ListItem_t * pxIterator;
+    const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
+
+    /* Only effective when configASSERT() is also defined, these tests may catch
+     * the list data structures being overwritten in memory.  They will not catch
+     * data errors caused by incorrect configuration or use of FreeRTOS. */
+    listTEST_LIST_INTEGRITY( pxList );
+    listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
+
+    /* Insert the new list item into the list, sorted in xItemValue order.
+     *
+     * If the list already contains a list item with the same item value then the
+     * new list item should be placed after it.  This ensures that TCBs which are
+     * stored in ready lists (all of which have the same xItemValue value) get a
+     * share of the CPU.  However, if the xItemValue is the same as the back marker
+     * the iteration loop below will not end.  Therefore the value is checked
+     * first, and the algorithm slightly modified if necessary. */
+    if( xValueOfInsertion == portMAX_DELAY )
+    {
+        pxIterator = pxList->xListEnd.pxPrevious;
+    }
+    else
+    {
+        /* *** NOTE ***********************************************************
+        *  If you find your application is crashing here then likely causes are
+        *  listed below.  In addition see https://www.FreeRTOS.org/FAQHelp.html for
+        *  more tips, and ensure configASSERT() is defined!
+        *  https://www.FreeRTOS.org/a00110.html#configASSERT
+        *
+        *   1) Stack overflow -
+        *      see https://www.FreeRTOS.org/Stacks-and-stack-overflow-checking.html
+        *   2) Incorrect interrupt priority assignment, especially on Cortex-M
+        *      parts where numerically high priority values denote low actual
+        *      interrupt priorities, which can seem counter intuitive.  See
+        *      https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html and the definition
+        *      of configMAX_SYSCALL_INTERRUPT_PRIORITY on
+        *      https://www.FreeRTOS.org/a00110.html
+        *   3) Calling an API function from within a critical section or when
+        *      the scheduler is suspended, or calling an API function that does
+        *      not end in "FromISR" from an interrupt.
+        *   4) Using a queue or semaphore before it has been initialised or
+        *      before the scheduler has been started (are interrupts firing
+        *      before vTaskStartScheduler() has been called?).
+        *   5) If the FreeRTOS port supports interrupt nesting then ensure that
+        *      the priority of the tick interrupt is at or below
+        *      configMAX_SYSCALL_INTERRUPT_PRIORITY.
+        **********************************************************************/
+
+        for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM.  This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */
+        {
+            /* There is nothing to do here, just iterating to the wanted
+             * insertion position. */
+        }
+    }
+
+    pxNewListItem->pxNext = pxIterator->pxNext;
+    pxNewListItem->pxNext->pxPrevious = pxNewListItem;
+    pxNewListItem->pxPrevious = pxIterator;
+    pxIterator->pxNext = pxNewListItem;
+
+    /* Remember which list the item is in.  This allows fast removal of the
+     * item later. */
+    pxNewListItem->pxContainer = pxList;
+
+    ( pxList->uxNumberOfItems )++;
+}
+/*-----------------------------------------------------------*/
+
+UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
+{
+/* The list item knows which list it is in.  Obtain the list from the list
+ * item. */
+    List_t * const pxList = pxItemToRemove->pxContainer;
+
+    pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
+    pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
+
+    /* Only used during decision coverage testing. */
+    mtCOVERAGE_TEST_DELAY();
+
+    /* Make sure the index is left pointing to a valid item. */
+    if( pxList->pxIndex == pxItemToRemove )
+    {
+        pxList->pxIndex = pxItemToRemove->pxPrevious;
+    }
+    else
+    {
+        mtCOVERAGE_TEST_MARKER();
+    }
+
+    pxItemToRemove->pxContainer = NULL;
+    ( pxList->uxNumberOfItems )--;
+
+    return pxList->uxNumberOfItems;
+}
+/*-----------------------------------------------------------*/

+ 137 - 0
FreeRTOS/portable/esp-idf/port_common.c

@@ -0,0 +1,137 @@
+/*
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <string.h>
+#include "FreeRTOS.h"
+#include "task.h"
+#include "portmacro.h"
+#include "esp_private/esp_int_wdt.h"
+#include "esp_system.h"
+#include "esp_heap_caps_init.h"
+#include "esp_task_wdt.h"
+#include "esp_task.h"
+#include "esp_private/crosscore_int.h"
+#include "esp_log.h"
+#include "esp_memory_utils.h"
+#include "esp_freertos_hooks.h"
+#include "sdkconfig.h"
+#include "esp_freertos_hooks.h"
+
+#if CONFIG_SPIRAM
+#include "esp_psram.h"
+#include "esp_private/esp_psram_extram.h"
+#endif
+
+#if CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL
+static const char* TAG = "cpu_start";
+#endif
+
+/* Architecture-agnostic parts of the FreeRTOS ESP-IDF port layer can go here.
+ *
+ * The actual call flow will be to call esp_startup_start_app() in <ARCH>/port.c,
+ * which will then call esp_startup_start_app_common()
+ */
+
+// Duplicate of inaccessible xSchedulerRunning; needed at startup to avoid counting nesting
+volatile unsigned port_xSchedulerRunning[portNUM_PROCESSORS] = {0};
+
+// For now, running FreeRTOS on one core and a bare metal on the other (or other OSes)
+// is not supported. For now CONFIG_FREERTOS_UNICORE and CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
+// should mirror each other's values.
+//
+// And since this should be true, we can just check for CONFIG_FREERTOS_UNICORE.
+#if CONFIG_FREERTOS_UNICORE != CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
+    #error "FreeRTOS and system configuration mismatch regarding the use of multiple cores."
+#endif
+
+static void main_task(void* args);
+
+#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
+void esp_gdbstub_init(void);
+#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
+
+extern void app_main(void);
+
+void esp_startup_start_app_common(void)
+{
+#if CONFIG_ESP_INT_WDT
+    esp_int_wdt_init();
+    //Initialize the interrupt watch dog for CPU0.
+    esp_int_wdt_cpu_init();
+#endif
+
+    esp_crosscore_int_init();
+
+#if CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME && !CONFIG_IDF_TARGET_ESP32C2
+    esp_gdbstub_init();
+#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
+
+#ifdef CONFIG_IDF_RTOS_RTTHREAD
+    app_main();
+#else
+    portBASE_TYPE res = xTaskCreatePinnedToCore(&main_task, "main",
+                                                ESP_TASK_MAIN_STACK, NULL,
+                                                ESP_TASK_MAIN_PRIO, NULL, ESP_TASK_MAIN_CORE);
+    assert(res == pdTRUE);
+    (void)res;
+#endif
+}
+
+#if !CONFIG_FREERTOS_UNICORE
+static volatile bool s_other_cpu_startup_done = false;
+static bool other_cpu_startup_idle_hook_cb(void)
+{
+    s_other_cpu_startup_done = true;
+    return true;
+}
+#endif
+
+static void main_task(void* args)
+{
+#if !CONFIG_FREERTOS_UNICORE
+    // Wait for FreeRTOS initialization to finish on other core, before replacing its startup stack
+    esp_register_freertos_idle_hook_for_cpu(other_cpu_startup_idle_hook_cb, !xPortGetCoreID());
+    while (!s_other_cpu_startup_done) {
+        ;
+    }
+    esp_deregister_freertos_idle_hook_for_cpu(other_cpu_startup_idle_hook_cb, !xPortGetCoreID());
+#endif
+
+    // [refactor-todo] check if there is a way to move the following block to esp_system startup
+    heap_caps_enable_nonos_stack_heaps();
+
+    // Now we have startup stack RAM available for heap, enable any DMA pool memory
+#if CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL
+    if (esp_psram_is_initialized()) {
+        esp_err_t r = esp_psram_extram_reserve_dma_pool(CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL);
+        if (r != ESP_OK) {
+            ESP_EARLY_LOGE(TAG, "Could not reserve internal/DMA pool (error 0x%x)", r);
+            abort();
+        }
+    }
+#endif
+
+    //Initialize TWDT if configured to do so
+#if CONFIG_ESP_TASK_WDT
+    esp_task_wdt_config_t twdt_config = {
+        .timeout_ms = CONFIG_ESP_TASK_WDT_TIMEOUT_S * 1000,
+        .idle_core_mask = 0,
+#if CONFIG_ESP_TASK_WDT_PANIC
+        .trigger_panic = true,
+#endif
+    };
+#if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0
+    twdt_config.idle_core_mask |= (1 << 0);
+#endif
+#if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1
+    twdt_config.idle_core_mask |= (1 << 1);
+#endif
+    ESP_ERROR_CHECK(esp_task_wdt_init(&twdt_config));
+#endif // CONFIG_ESP_TASK_WDT
+
+    app_main();
+    vTaskDelete(NULL);
+}

+ 44 - 0
FreeRTOS/portable/esp-idf/port_rt.c

@@ -0,0 +1,44 @@
+#include <FreeRTOS.h>
+
+static rt_base_t level = 0;
+static rt_base_t critical_nesting = 0;
+
+void vPortEnterCritical( void )
+{
+    if ( critical_nesting == 0 )
+    {
+        level = rt_hw_interrupt_disable();
+    }
+    critical_nesting += 1;
+}
+
+void vPortExitCritical( void )
+{
+    critical_nesting -= 1;
+    if ( critical_nesting == 0 )
+    {
+        rt_hw_interrupt_enable( level );
+    }
+}
+
+void vPortEndScheduler( void )
+{
+    /* Not implemented in ports where there is nothing to return to. */
+}
+
+BaseType_t rt_err_to_freertos(rt_err_t rt_err)
+{
+    switch(-rt_err)
+    {
+        case RT_EOK:
+            return pdPASS;
+        case RT_ENOMEM:
+            return errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
+        case RT_EFULL:
+            return errQUEUE_FULL;
+        case RT_EEMPTY:
+            return errQUEUE_EMPTY;
+        default:
+            return pdFAIL;
+    }
+}

+ 31 - 0
FreeRTOS/portable/esp-idf/riscv/include/freertos/FreeRTOSConfig_arch.h

@@ -0,0 +1,31 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef FREERTOS_CONFIG_RISCV_H
+#define FREERTOS_CONFIG_RISCV_H
+
+//RISC-V Archiecture specific configuration. This file is included in the common FreeRTOSConfig.h.
+
+#include "sdkconfig.h"
+
+/* ------------------------------------------------- FreeRTOS Config ---------------------------------------------------
+ * - All Vanilla FreeRTOS configuration goes into this section
+ * ------------------------------------------------------------------------------------------------------------------ */
+
+// ------------------ Scheduler Related --------------------
+
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION             0
+#define configMAX_API_CALL_INTERRUPT_PRIORITY               0
+
+/* ------------------------------------------------ ESP-IDF Additions --------------------------------------------------
+ *
+ * ------------------------------------------------------------------------------------------------------------------ */
+
+#ifndef configISR_STACK_SIZE
+#define configISR_STACK_SIZE                                (CONFIG_FREERTOS_ISR_STACKSIZE)
+#endif
+
+#endif // FREERTOS_CONFIG_RISCV_H

+ 349 - 0
FreeRTOS/portable/esp-idf/riscv/include/freertos/portmacro.h

@@ -0,0 +1,349 @@
+/*
+ * SPDX-FileCopyrightText: 2020 Amazon.com, Inc. or its affiliates
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD
+ */
+/*
+ * FreeRTOS Kernel V10.4.3
+ * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+
+#ifndef PORTMACRO_H
+#define PORTMACRO_H
+
+#ifndef __ASSEMBLER__
+
+#include "sdkconfig.h"
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include "spinlock.h"
+#include "soc/interrupt_core0_reg.h"
+#include "esp_macros.h"
+#include "esp_attr.h"
+#include "esp_cpu.h"
+#include "esp_rom_sys.h"
+#include "esp_heap_caps.h"
+#include "esp_system.h"             /* required by esp_get_...() functions in portable.h. [refactor-todo] Update portable.h */
+#include "esp_newlib.h"
+
+/* [refactor-todo] These includes are not directly used in this file. They are kept into to prevent a breaking change. Remove these. */
+#include <limits.h>
+
+/* [refactor-todo] introduce a port wrapper function to avoid including esp_timer.h into the public header */
+#if CONFIG_FREERTOS_RUN_TIME_STATS_USING_ESP_TIMER
+#include "esp_timer.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* --------------------------------------------------- Port Types ------------------------------------------------------
+ * - Port specific types.
+ * - The settings in this file configure FreeRTOS correctly for the given hardware and compiler.
+ * - These settings should not be altered.
+ * - The port types must come first as they are used further down in this file
+ * ------------------------------------------------------------------------------------------------------------------ */
+
+#define portCHAR char
+#define portFLOAT float
+#define portDOUBLE double
+#define portLONG long
+#define portSHORT short
+#define portSTACK_TYPE rt_ubase_t
+#define portBASE_TYPE rt_base_t
+
+typedef portSTACK_TYPE StackType_t;
+typedef rt_base_t BaseType_t;
+typedef rt_ubase_t UBaseType_t;
+typedef rt_tick_t TickType_t;
+#define portMAX_DELAY (TickType_t) RT_TICK_MAX
+
+struct rt_semaphore_wrapper
+{
+    struct rt_semaphore sem;
+    rt_uint16_t max_value;
+};
+
+
+/* ----------------------------------------------- Port Configurations -------------------------------------------------
+ * - Configurations values supplied by each port
+ * - Required by FreeRTOS
+ * ------------------------------------------------------------------------------------------------------------------ */
+
+#define portTICK_PERIOD_MS              ((TickType_t) (1000 / configTICK_RATE_HZ))
+#define portBYTE_ALIGNMENT              RT_ALIGN_SIZE
+#define portNOP() __asm volatile        (" nop ")
+
+
+/* ---------------------------------------------- Forward Declarations -------------------------------------------------
+ * - Forward declarations of all the port functions and macros need to implement the FreeRTOS porting interface
+ * - These must come before definition/declaration of the FreeRTOS porting interface
+ * ------------------------------------------------------------------------------------------------------------------ */
+
+// --------------------- Interrupts ------------------------
+
+/**
+ * @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
+ */
+BaseType_t xPortInIsrContext(void);
+
+/**
+ * @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
+ */
+BaseType_t xPortInterruptedFromISRContext(void);
+
+/* ---------------------- Spinlocks ------------------------
+ - Spinlocks added to match API with SMP FreeRTOS. Single core RISC-V does not need spin locks
+ - Because single core does not have a primitive spinlock data type, we have to implement one here
+ * @note [refactor-todo] Refactor critical section API so that this is no longer required
+ * ------------------------------------------------------ */
+
+/**
+ * @brief Spinlock object
+ * Owner:
+ *  - Set to 0 if uninitialized
+ *  - Set to portMUX_FREE_VAL when free
+ *  - Set to CORE_ID_REGVAL_PRO or CORE_ID_REGVAL_AP when locked
+ *  - Any other value indicates corruption
+ * Count:
+ *  - 0 if unlocked
+ *  - Recursive count if locked
+ *
+ * @note Not a true spinlock as single core RISC-V does not have atomic compare and set instruction
+ * @note Keep portMUX_INITIALIZER_UNLOCKED in sync with this struct
+ */
+typedef struct {
+    uint32_t owner;
+    uint32_t count;
+} portMUX_TYPE;
+/**< Spinlock initializer */
+#define portMUX_INITIALIZER_UNLOCKED {                      \
+            .owner = portMUX_FREE_VAL,                      \
+            .count = 0,                                     \
+        }
+#define portMUX_FREE_VAL                    SPINLOCK_FREE           /**< Spinlock is free. [refactor-todo] check if this is still required */
+#define portMUX_NO_TIMEOUT                  SPINLOCK_WAIT_FOREVER   /**< When passed for 'timeout_cycles', spin forever if necessary. [refactor-todo] check if this is still required */
+#define portMUX_TRY_LOCK                    SPINLOCK_NO_WAIT        /**< Try to acquire the spinlock a single time only. [refactor-todo] check if this is still required */
+#define portMUX_INITIALIZE(mux)    ({ \
+    (mux)->owner = portMUX_FREE_VAL; \
+    (mux)->count = 0; \
+})
+
+// ------------------ Critical Sections --------------------
+
+/**
+ * @brief Enter a critical section
+ *
+ * - Simply disable interrupts
+ * - Can be nested
+ */
+void vPortEnterCritical(void);
+
+/**
+ * @brief Exit a critical section
+ *
+ * - Reenables interrupts
+ * - Can be nested
+ */
+void vPortExitCritical(void);
+
+// ---------------------- Yielding -------------------------
+
+/**
+ * @brief Perform a context switch from a task
+ *
+ * @note [refactor-todo] The rest of ESP-IDF should call taskYield() instead
+ */
+#define vPortYield(void)    rt_thread_yield()
+
+/**
+ * @brief Checks if the current core can yield
+ *
+ * - A core cannot yield if its in an ISR or in a critical section
+ *
+ * @note [refactor-todo] See if this can be separated from port macro
+ * @note [refactor-todo] Check if this function should be renamed (due to bool return type)
+ * @return true Core can yield
+ * @return false Core cannot yield
+ */
+FORCE_INLINE_ATTR bool xPortCanYield(void);
+
+// ----------------------- System --------------------------
+
+/**
+ * @brief Get the tick rate per second
+ *
+ * @note [refactor-todo] make this inline
+ * @note [refactor-todo] Check if this function should be renamed (due to uint return type)
+ * @return uint32_t Tick rate in Hz
+ */
+uint32_t xPortGetTickRateHz(void);
+
+/**
+ * @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
+ */
+void vPortSetStackWatchpoint(void *pxStackStart);
+
+/**
+ * @brief Get the current core's ID
+ *
+ * @note Added to be compatible with SMP API
+ * @note [refactor-todo] IDF should call a FreeRTOS like macro instead of port function directly
+ * @return BaseType_t Core ID
+ */
+FORCE_INLINE_ATTR BaseType_t xPortGetCoreID(void)
+{
+    return (BaseType_t) esp_cpu_get_core_id();
+}
+
+
+
+/* ------------------------------------------- FreeRTOS Porting Interface ----------------------------------------------
+ * - Contains all the mappings of the macros required by FreeRTOS
+ * - Most come after forward declare as porting macros map to declared functions
+ * - Maps to forward declared functions
+ * ------------------------------------------------------------------------------------------------------------------ */
+
+// --------------------- Interrupts ------------------------
+
+#define portDISABLE_INTERRUPTS()            vPortEnterCritical()
+#define portENABLE_INTERRUPTS()             vPortExitCritical()
+#define portSET_INTERRUPT_MASK_FROM_ISR()                       rt_hw_interrupt_disable()
+#define portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedStatusValue)   rt_hw_interrupt_enable(uxSavedStatusValue)
+
+// ------------------ Critical Sections --------------------
+
+#define portENTER_CRITICAL(mux)                 {(void)mux;  vPortEnterCritical();}
+#define portEXIT_CRITICAL(mux)                  {(void)mux;  vPortExitCritical();}
+#define portTRY_ENTER_CRITICAL(mux, timeout)    ({  \
+    (void)mux; (void)timeout;                       \
+    vPortEnterCritical();                           \
+    BaseType_t ret = pdPASS;                        \
+    ret;                                            \
+})
+//In single-core RISC-V, we can use the same critical section API
+#define portENTER_CRITICAL_ISR(mux)                 portENTER_CRITICAL(mux)
+#define portEXIT_CRITICAL_ISR(mux)                  portEXIT_CRITICAL(mux)
+#define portTRY_ENTER_CRITICAL_ISR(mux, timeout)    portTRY_ENTER_CRITICAL(mux, timeout)
+
+/* [refactor-todo] on RISC-V, both ISR and non-ISR cases result in the same call. We can redefine this macro */
+#define portENTER_CRITICAL_SAFE(mux)    ({  \
+    if (xPortInIsrContext()) {              \
+        portENTER_CRITICAL_ISR(mux);        \
+    } else {                                \
+        portENTER_CRITICAL(mux);            \
+    }                                       \
+})
+#define portEXIT_CRITICAL_SAFE(mux)     ({  \
+    if (xPortInIsrContext()) {              \
+        portEXIT_CRITICAL_ISR(mux);         \
+    } else {                                \
+        portEXIT_CRITICAL(mux);             \
+    }                                       \
+})
+#define portTRY_ENTER_CRITICAL_SAFE(mux, timeout)   portENTER_CRITICAL_SAFE(mux, timeout)
+
+// ---------------------- Yielding -------------------------
+
+#define portYIELD() rt_thread_yield()
+#define portYIELD_FROM_ISR_NO_ARG() rt_thread_yield()
+#define portYIELD_FROM_ISR_ARG(xHigherPriorityTaskWoken) ({ \
+    if (xHigherPriorityTaskWoken == pdTRUE) { \
+        rt_thread_yield(); \
+    } \
+})
+/**
+ * @note    The macro below could be used when passing a single argument, or without any argument,
+ *          it was developed to support both usages of portYIELD inside of an ISR. Any other usage form
+ *          might result in undesired behavior
+ */
+#if defined(__cplusplus) && (__cplusplus >  201703L)
+#define portYIELD_FROM_ISR(...) CHOOSE_MACRO_VA_ARG(portYIELD_FROM_ISR_ARG, portYIELD_FROM_ISR_NO_ARG __VA_OPT__(,) __VA_ARGS__)(__VA_ARGS__)
+#else
+#define portYIELD_FROM_ISR(...) CHOOSE_MACRO_VA_ARG(portYIELD_FROM_ISR_ARG, portYIELD_FROM_ISR_NO_ARG, ##__VA_ARGS__)(__VA_ARGS__)
+#endif
+
+
+
+/* --------------------------------------------- Inline Implementations ------------------------------------------------
+ * - Implementation of inline functions of the forward declares
+ * - Should come after forward declare and FreeRTOS Porting interface, as implementation may use both.
+ * - For implementation of non-inlined functions, see port.c, port_common.c, or other assembly files
+ * ------------------------------------------------------------------------------------------------------------------ */
+
+// --------------------- Interrupts ------------------------
+
+// ---------------------- Yielding -------------------------
+
+FORCE_INLINE_ATTR bool xPortCanYield(void)
+{
+    uint32_t threshold = REG_READ(INTERRUPT_CORE0_CPU_INT_THRESH_REG);
+    /* when enter critical code, FreeRTOS will mask threshold to RVHAL_EXCM_LEVEL
+     * and exit critical code, will recover threshold value (1). so threshold <= 1
+     * means not in critical code
+     */
+    return (threshold <= 1);
+}
+
+/* Use this macro to calculate the buffer size when allocating a queue statically
+ * To ensure the buffer can fit the desired number of messages
+ */
+#define QUEUE_BUFFER_SIZE( uxQueueLength, uxItemSize )  ( ( RT_ALIGN( uxItemSize, RT_ALIGN_SIZE ) + sizeof( void * ) ) * uxQueueLength )
+
+BaseType_t rt_err_to_freertos(rt_err_t rt_err);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__ASSEMBLER__
+
+#endif /* PORTMACRO_H */

+ 112 - 0
FreeRTOS/portable/esp-idf/riscv/port.c

@@ -0,0 +1,112 @@
+/*
+ * SPDX-FileCopyrightText: 2020 Amazon.com, Inc. or its affiliates
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD
+ */
+/*
+ * FreeRTOS Kernel V10.4.3
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * https://www.FreeRTOS.org
+ * https://github.com/FreeRTOS
+ *
+ * 1 tab == 4 spaces!
+ */
+
+/*-----------------------------------------------------------------------
+ * Implementation of functions defined in portable.h for the RISC-V port.
+ *----------------------------------------------------------------------*/
+
+#include "sdkconfig.h"
+#include <string.h>
+#include "soc/soc_caps.h"
+#include "soc/periph_defs.h"
+#include "soc/system_reg.h"
+#include "hal/systimer_hal.h"
+#include "hal/systimer_ll.h"
+#include "riscv/rvruntime-frames.h"
+#include "riscv/riscv_interrupts.h"
+#include "riscv/interrupt.h"
+#include "esp_private/crosscore_int.h"
+#include "esp_attr.h"
+#include "esp_system.h"
+#include "esp_intr_alloc.h"
+#include "esp_log.h"
+#include "FreeRTOS.h"       /* This pulls in portmacro.h */
+#include "task.h"
+#include "portmacro.h"
+#include "esp_memory_utils.h"
+
+
+
+/* ---------------------------------------------- Port Implementations -------------------------------------------------
+ *
+ * ------------------------------------------------------------------------------------------------------------------ */
+
+// --------------------- Interrupts ------------------------
+
+BaseType_t xPortInIsrContext(void)
+{
+    rreturn (BaseType_t)rt_interrupt_get_nest();
+}
+
+BaseType_t IRAM_ATTR xPortInterruptedFromISRContext(void)
+{
+    /* For single core, this can be the same as xPortInIsrContext() because reading it is atomic */
+    return (BaseType_t)rt_interrupt_get_nest();
+}
+
+// ----------------------- System --------------------------
+
+uint32_t xPortGetTickRateHz(void)
+{
+    return (uint32_t)configTICK_RATE_HZ;
+}
+
+#define STACK_WATCH_AREA_SIZE 32
+#define STACK_WATCH_POINT_NUMBER (SOC_CPU_WATCHPOINTS_NUM - 1)
+
+void vPortSetStackWatchpoint(void *pxStackStart)
+{
+    uint32_t addr = (uint32_t)pxStackStart;
+    addr = (addr + (STACK_WATCH_AREA_SIZE - 1)) & (~(STACK_WATCH_AREA_SIZE - 1));
+    esp_cpu_set_watchpoint(STACK_WATCH_POINT_NUMBER, (char *)addr, STACK_WATCH_AREA_SIZE, ESP_CPU_WATCHPOINT_STORE);
+}
+
+
+
+/* ---------------------------------------------- Misc Implementations -------------------------------------------------
+ *
+ * ------------------------------------------------------------------------------------------------------------------ */
+
+// --------------------- App Start-up ----------------------
+
+/* [refactor-todo]: See if we can include this through a header */
+extern void esp_startup_start_app_common(void);
+
+void esp_startup_start_app(void)
+{
+    esp_startup_start_app_common();
+
+    ESP_LOGI(TAG, "Starting scheduler.");
+    vTaskStartScheduler();
+}

+ 1 - 0
FreeRTOS/include/FreeRTOSConfig.h → FreeRTOS/portable/rt-thread/FreeRTOSConfig.h

@@ -34,6 +34,7 @@
 #define configUSE_TIME_SLICING                  1
 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
 #define configUSE_16_BIT_TICKS                  0
+#define configUSE_FREERTOS_PROVIDED_HEAP        1
 
 /* The following read-only options are controlled by rtconfig.h. */
 #define configTICK_RATE_HZ                      RT_TICK_PER_SECOND

+ 1 - 0
FreeRTOS/portable/rt-thread/portmacro.h

@@ -68,6 +68,7 @@
 /*-----------------------------------------------------------*/
 
 /* Architecture specifics. */
+    #define portTICK_PERIOD_MS      ((TickType_t) (1000 / configTICK_RATE_HZ))
     #define portBYTE_ALIGNMENT      RT_ALIGN_SIZE
     #define portPOINTER_SIZE_TYPE   rt_size_t
 /*-----------------------------------------------------------*/

+ 65 - 0
FreeRTOS/queue.c

@@ -723,3 +723,68 @@ BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue )
     return xReturn;
 }
 /*-----------------------------------------------------------*/
+
+#ifdef ESP_PLATFORM
+/* Unimplemented */
+#include "esp_log.h"
+static const char *TAG = "freertos";
+QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength )
+{
+    ESP_LOGE(TAG, "xQueueCreateSet unimplemented");
+    configASSERT(0);
+    return NULL;
+}
+BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
+                           QueueSetHandle_t xQueueSet )
+{
+    ESP_LOGE(TAG, "xQueueAddToSet unimplemented");
+    configASSERT(0);
+    return pdFAIL;
+}
+
+BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
+                                QueueSetHandle_t xQueueSet )
+{
+    ESP_LOGE(TAG, "xQueueRemoveFromSet unimplemented");
+    configASSERT(0);
+    return pdFAIL;
+}
+
+QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
+                                            const TickType_t xTicksToWait )
+{
+    ESP_LOGE(TAG, "xQueueSelectFromSet unimplemented");
+    configASSERT(0);
+    return NULL;
+}
+
+QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet )
+{
+    ESP_LOGE(TAG, "xQueueSelectFromSetFromISR unimplemented");
+    configASSERT(0);
+    return NULL;
+}
+
+BaseType_t xQueuePeek( QueueHandle_t xQueue,
+                       void * const pvBuffer,
+                       TickType_t xTicksToWait )
+{
+    ESP_LOGE(TAG, "xQueuePeek unimplemented");
+    configASSERT(0);
+    return pdFAIL;
+}
+
+BaseType_t xQueueOverwrite(QueueHandle_t xQueue, const void * pvItemToQueue)
+{
+    ESP_LOGE(TAG, "xQueueOverwrite unimplemented");
+    configASSERT(0);
+    return pdFAIL;
+}
+
+BaseType_t xQueueOverwriteFromISR(QueueHandle_t xQueue, const void * pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken)
+{
+    ESP_LOGE(TAG, "xQueueOverwriteFromISR unimplemented");
+    configASSERT(0);
+    return pdFAIL;
+}
+#endif

+ 68 - 0
FreeRTOS/tasks.c

@@ -165,6 +165,25 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
 #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
 /*-----------------------------------------------------------*/
 
+#ifdef ESP_PLATFORM
+#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+
+    BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pvTaskCode,
+                            const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+                            const uint32_t usStackDepth,
+                            void * const pvParameters,
+                            UBaseType_t uxPriority,
+                            TaskHandle_t * const pvCreatedTask,
+                            const BaseType_t xCoreID)
+    {
+        ( void ) xCoreID;
+        return xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pvCreatedTask );
+    }
+
+#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
+#endif
+/*-----------------------------------------------------------*/
+
 static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
                                   const char * const pcName,
                                   const uint32_t ulStackDepth,
@@ -1180,3 +1199,52 @@ BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
 
 #endif /* INCLUDE_uxTaskGetStackHighWaterMark */
 /*-----------------------------------------------------------*/
+
+
+#ifdef ESP_PLATFORM
+BaseType_t xTaskGetAffinity( TaskHandle_t xTask )
+{
+    ( void ) xTask;
+    return 0;
+}
+
+TaskHandle_t xTaskGetCurrentTaskHandleForCPU( BaseType_t cpuid )
+{
+    ( void ) cpuid;
+    return xTaskGetCurrentTaskHandle();
+}
+
+TaskHandle_t xTaskGetIdleTaskHandleForCPU( UBaseType_t cpuid )
+{
+    ( void ) cpuid;
+    return xTaskGetIdleTaskHandle();
+}
+
+/* Unimplemented */
+#include "esp_log.h"
+static const char *TAG = "freertos";
+#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
+void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet,
+                                            BaseType_t xIndex,
+                                            void * pvValue )
+{
+    ESP_LOGE(TAG, "vTaskSetThreadLocalStoragePointer unimplemented");
+    configASSERT(0);
+}
+void * pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery,
+                                               BaseType_t xIndex )
+{
+    ESP_LOGE(TAG, "pvTaskGetThreadLocalStoragePointer unimplemented");
+    configASSERT(0);
+    return NULL;
+}
+#if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS )
+typedef void (*TlsDeleteCallbackFunction_t)( int, void * );
+void vTaskSetThreadLocalStoragePointerAndDelCallback( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue, TlsDeleteCallbackFunction_t pvDelCallback)
+{
+    ESP_LOGE(TAG, "vTaskSetThreadLocalStoragePointerAndDelCallback unimplemented");
+    configASSERT(0);
+}
+#endif
+#endif
+#endif