浏览代码

Support task create/delete/delay.
Update tests to use FreeRTOS task API.

tangzz98 3 年之前
父节点
当前提交
81a3747975

+ 18 - 0
FreeRTOS/include/FreeRTOS.h

@@ -1113,6 +1113,24 @@
     ( ( ( portUSING_MPU_WRAPPERS == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) || \
       ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) )
 
+/*
+ * 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.
+ */
+typedef struct xSTATIC_TCB
+{
+    struct rt_thread thread;
+} StaticTask_t;
+
 typedef struct
 {
     struct rt_ipc_object *rt_ipc;

+ 3 - 3
FreeRTOS/include/FreeRTOSConfig.h

@@ -86,11 +86,8 @@ FreeRTOS/Source/tasks.c for limitations. */
 to exclude the API function. */
 #define INCLUDE_vTaskPrioritySet        1
 #define INCLUDE_uxTaskPriorityGet       1
-#define INCLUDE_vTaskDelete             1
 #define INCLUDE_vTaskCleanUpResources   1
 #define INCLUDE_vTaskSuspend            1
-#define INCLUDE_vTaskDelayUntil         1
-#define INCLUDE_vTaskDelay              1
 #define INCLUDE_eTaskGetState           1
 #define INCLUDE_xTimerPendFunctionCall  1
 
@@ -133,5 +130,8 @@ standard names. */
 #define configTOTAL_HEAP_SIZE                   ( ( size_t ) ( 46 * 1024 ) )
 #define configUSE_COUNTING_SEMAPHORES           1
 #define configUSE_MALLOC_FAILED_HOOK            0
+#define INCLUDE_vTaskDelete                     1
+#define INCLUDE_vTaskDelayUntil                 1
+#define INCLUDE_vTaskDelay                      1
 
 #endif /* FREERTOS_CONFIG_H */

+ 422 - 0
FreeRTOS/include/task.h

@@ -56,6 +56,29 @@
 #define tskKERNEL_VERSION_MINOR        4
 #define tskKERNEL_VERSION_BUILD        6
 
+/**
+ * task. h
+ *
+ * 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.
+ *
+ * \defgroup TaskHandle_t TaskHandle_t
+ * \ingroup Tasks
+ */
+struct tskTaskControlBlock; /* The old naming convention is used to prevent breaking kernel aware debuggers. */
+typedef struct tskTaskControlBlock * TaskHandle_t;
+
+/**
+ * task. h
+ *
+ * Macro for forcing a context switch.
+ *
+ * \defgroup taskYIELD taskYIELD
+ * \ingroup SchedulerControl
+ */
+#define taskYIELD()                        portYIELD()
+
 /**
  * task. h
  *
@@ -106,6 +129,405 @@
  */
 #define taskENABLE_INTERRUPTS()            portENABLE_INTERRUPTS()
 
+/*-----------------------------------------------------------
+* TASK CREATION API
+*----------------------------------------------------------*/
+
+/**
+ * task. h
+ * @code{c}
+ * BaseType_t xTaskCreate(
+ *                            TaskFunction_t pxTaskCode,
+ *                            const char *pcName,
+ *                            configSTACK_DEPTH_TYPE usStackDepth,
+ *                            void *pvParameters,
+ *                            UBaseType_t uxPriority,
+ *                            TaskHandle_t *pxCreatedTask
+ *                        );
+ * @endcode
+ *
+ * Create a new task and add it to the list of tasks that are ready to run.
+ *
+ * Internally, within the FreeRTOS implementation, tasks use two blocks of
+ * memory.  The first block is used to hold the task's data structures.  The
+ * second block is used by the task as its stack.  If a task is created using
+ * xTaskCreate() then both blocks of memory are automatically dynamically
+ * allocated inside the xTaskCreate() function.  (see
+ * https://www.FreeRTOS.org/a00111.html).  If a task is created using
+ * xTaskCreateStatic() then the application writer must provide the required
+ * memory.  xTaskCreateStatic() therefore allows a task to be created without
+ * using any dynamic memory allocation.
+ *
+ * See xTaskCreateStatic() for a version that does not use any dynamic memory
+ * allocation.
+ *
+ * xTaskCreate() can only be used to create a task that has unrestricted
+ * access to the entire microcontroller memory map.  Systems that include MPU
+ * support can alternatively create an MPU constrained task using
+ * xTaskCreateRestricted().
+ *
+ * @param pxTaskCode Pointer to the task entry function.  Tasks
+ * must be implemented to never return (i.e. continuous loop).
+ *
+ * @param pcName A descriptive name for the task.  This is mainly used to
+ * facilitate debugging.  Max length defined by configMAX_TASK_NAME_LEN - default
+ * is 16.
+ *
+ * @param usStackDepth The size of the task stack specified as the number of
+ * variables the stack can hold - not the number of bytes.  For example, if
+ * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes
+ * will be allocated for stack storage.
+ *
+ * @param pvParameters Pointer that will be used as the parameter for the task
+ * being created.
+ *
+ * @param uxPriority The priority at which the task should run.  Systems that
+ * include MPU support can optionally create tasks in a privileged (system)
+ * mode by setting bit portPRIVILEGE_BIT of the priority parameter.  For
+ * example, to create a privileged task at priority 2 the uxPriority parameter
+ * should be set to ( 2 | portPRIVILEGE_BIT ).
+ *
+ * @param pxCreatedTask Used to pass back a handle by which the created task
+ * can be referenced.
+ *
+ * @return pdPASS if the task was successfully created and added to a ready
+ * list, otherwise an error code defined in the file projdefs.h
+ *
+ * Example usage:
+ * @code{c}
+ * // Task to be created.
+ * void vTaskCode( void * pvParameters )
+ * {
+ *   for( ;; )
+ *   {
+ *       // Task code goes here.
+ *   }
+ * }
+ *
+ * // Function that creates a task.
+ * void vOtherFunction( void )
+ * {
+ * static uint8_t ucParameterToPass;
+ * TaskHandle_t xHandle = NULL;
+ *
+ *   // Create the task, storing the handle.  Note that the passed parameter ucParameterToPass
+ *   // must exist for the lifetime of the task, so in this case is declared static.  If it was just an
+ *   // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
+ *   // the new task attempts to access it.
+ *   xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
+ *   configASSERT( xHandle );
+ *
+ *   // Use the handle to delete the task.
+ *   if( xHandle != NULL )
+ *   {
+ *      vTaskDelete( xHandle );
+ *   }
+ * }
+ * @endcode
+ * \defgroup xTaskCreate xTaskCreate
+ * \ingroup Tasks
+ */
+#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+    BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
+                            const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+                            const configSTACK_DEPTH_TYPE usStackDepth,
+                            void * const pvParameters,
+                            UBaseType_t uxPriority,
+                            TaskHandle_t * const pxCreatedTask );
+#endif
+
+/**
+ * task. h
+ * @code{c}
+ * TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
+ *                               const char *pcName,
+ *                               uint32_t ulStackDepth,
+ *                               void *pvParameters,
+ *                               UBaseType_t uxPriority,
+ *                               StackType_t *puxStackBuffer,
+ *                               StaticTask_t *pxTaskBuffer );
+ * @endcode
+ *
+ * Create a new task and add it to the list of tasks that are ready to run.
+ *
+ * Internally, within the FreeRTOS implementation, tasks use two blocks of
+ * memory.  The first block is used to hold the task's data structures.  The
+ * second block is used by the task as its stack.  If a task is created using
+ * xTaskCreate() then both blocks of memory are automatically dynamically
+ * allocated inside the xTaskCreate() function.  (see
+ * https://www.FreeRTOS.org/a00111.html).  If a task is created using
+ * xTaskCreateStatic() then the application writer must provide the required
+ * memory.  xTaskCreateStatic() therefore allows a task to be created without
+ * using any dynamic memory allocation.
+ *
+ * @param pxTaskCode Pointer to the task entry function.  Tasks
+ * must be implemented to never return (i.e. continuous loop).
+ *
+ * @param pcName A descriptive name for the task.  This is mainly used to
+ * facilitate debugging.  The maximum length of the string is defined by
+ * configMAX_TASK_NAME_LEN in FreeRTOSConfig.h.
+ *
+ * @param ulStackDepth The size of the task stack specified as the number of
+ * variables the stack can hold - not the number of bytes.  For example, if
+ * the stack is 32-bits wide and ulStackDepth is defined as 100 then 400 bytes
+ * will be allocated for stack storage.
+ *
+ * @param pvParameters Pointer that will be used as the parameter for the task
+ * being created.
+ *
+ * @param uxPriority The priority at which the task will run.
+ *
+ * @param puxStackBuffer Must point to a StackType_t array that has at least
+ * ulStackDepth indexes - the array will then be used as the task's stack,
+ * removing the need for the stack to be allocated dynamically.
+ *
+ * @param pxTaskBuffer Must point to a variable of type StaticTask_t, which will
+ * then be used to hold the task's data structures, removing the need for the
+ * memory to be allocated dynamically.
+ *
+ * @return If neither puxStackBuffer nor pxTaskBuffer are NULL, then the task
+ * will be created and a handle to the created task is returned.  If either
+ * puxStackBuffer or pxTaskBuffer are NULL then the task will not be created and
+ * NULL is returned.
+ *
+ * Example usage:
+ * @code{c}
+ *
+ *  // Dimensions of the buffer that the task being created will use as its stack.
+ *  // NOTE:  This is the number of words the stack will hold, not the number of
+ *  // bytes.  For example, if each stack item is 32-bits, and this is set to 100,
+ *  // then 400 bytes (100 * 32-bits) will be allocated.
+ #define STACK_SIZE 200
+ *
+ *  // Structure that will hold the TCB of the task being created.
+ *  StaticTask_t xTaskBuffer;
+ *
+ *  // Buffer that the task being created will use as its stack.  Note this is
+ *  // an array of StackType_t variables.  The size of StackType_t is dependent on
+ *  // the RTOS port.
+ *  StackType_t xStack[ STACK_SIZE ];
+ *
+ *  // Function that implements the task being created.
+ *  void vTaskCode( void * pvParameters )
+ *  {
+ *      // The parameter value is expected to be 1 as 1 is passed in the
+ *      // pvParameters value in the call to xTaskCreateStatic().
+ *      configASSERT( ( uint32_t ) pvParameters == 1UL );
+ *
+ *      for( ;; )
+ *      {
+ *          // Task code goes here.
+ *      }
+ *  }
+ *
+ *  // Function that creates a task.
+ *  void vOtherFunction( void )
+ *  {
+ *      TaskHandle_t xHandle = NULL;
+ *
+ *      // Create the task without using any dynamic memory allocation.
+ *      xHandle = xTaskCreateStatic(
+ *                    vTaskCode,       // Function that implements the task.
+ *                    "NAME",          // Text name for the task.
+ *                    STACK_SIZE,      // Stack size in words, not bytes.
+ *                    ( void * ) 1,    // Parameter passed into the task.
+ *                    tskIDLE_PRIORITY,// Priority at which the task is created.
+ *                    xStack,          // Array to use as the task's stack.
+ *                    &xTaskBuffer );  // Variable to hold the task's data structure.
+ *
+ *      // puxStackBuffer and pxTaskBuffer were not NULL, so the task will have
+ *      // been created, and xHandle will be the task's handle.  Use the handle
+ *      // to suspend the task.
+ *      vTaskSuspend( xHandle );
+ *  }
+ * @endcode
+ * \defgroup xTaskCreateStatic xTaskCreateStatic
+ * \ingroup Tasks
+ */
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+    TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
+                                    const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+                                    const uint32_t ulStackDepth,
+                                    void * const pvParameters,
+                                    UBaseType_t uxPriority,
+                                    StackType_t * const puxStackBuffer,
+                                    StaticTask_t * const pxTaskBuffer );
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+
+/**
+ * task. h
+ * @code{c}
+ * void vTaskDelete( TaskHandle_t xTaskToDelete );
+ * @endcode
+ *
+ * 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
+ * \defgroup vTaskDelete vTaskDelete
+ * \ingroup Tasks
+ */
+void vTaskDelete( TaskHandle_t xTaskToDelete );
+
+/*-----------------------------------------------------------
+* TASK CONTROL API
+*----------------------------------------------------------*/
+
+/**
+ * task. h
+ * @code{c}
+ * void vTaskDelay( const TickType_t xTicksToDelay );
+ * @endcode
+ *
+ * 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:
+ *
+ * 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 );
+ *   }
+ * }
+ *
+ * \defgroup vTaskDelay vTaskDelay
+ * \ingroup TaskCtrl
+ */
+void vTaskDelay( const TickType_t xTicksToDelay );
+
+/**
+ * task. h
+ * @code{c}
+ * BaseType_t xTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement );
+ * @endcode
+ *
+ * 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
+ * \defgroup xTaskDelayUntil xTaskDelayUntil
+ * \ingroup TaskCtrl
+ */
+BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
+                            const TickType_t xTimeIncrement );
+
+/*
+ * vTaskDelayUntil() is the older version of xTaskDelayUntil() and does not
+ * return a value.
+ */
+#define vTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement )           \
+    {                                                                   \
+        ( void ) xTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ); \
+    }
+
 /*-----------------------------------------------------------
 * SCHEDULER CONTROL
 *----------------------------------------------------------*/

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

@@ -72,6 +72,12 @@
     #define portPOINTER_SIZE_TYPE   rt_size_t
 /*-----------------------------------------------------------*/
 
+/* Scheduler utilities. */
+    #define portYIELD()                 rt_thread_yield()
+    #define portYIELD_FROM_ISR( x )     rt_thread_yield()
+
+/*-----------------------------------------------------------*/
+
 /* Critical section management. */
     extern void vPortEnterCritical( void );
     extern void vPortExitCritical( void );

+ 153 - 0
FreeRTOS/task.c

@@ -34,6 +34,159 @@
 #include "FreeRTOS.h"
 #include "task.h"
 
+/*
+ * Task control block.  A task control block (TCB) is allocated for each task,
+ * and stores task state information, including a pointer to the task's context
+ * (the task's run time environment, including register values)
+ */
+typedef struct tskTaskControlBlock
+{
+    struct rt_thread thread;
+} tskTCB;
+typedef tskTCB TCB_t;
+
+/*-----------------------------------------------------------*/
+
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+
+    TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
+                                    const char * const pcName,
+                                    const uint32_t ulStackDepth,
+                                    void * const pvParameters,
+                                    UBaseType_t uxPriority,
+                                    StackType_t * const puxStackBuffer,
+                                    StaticTask_t * const pxTaskBuffer )
+    {
+        TaskHandle_t xReturn = NULL;
+
+        configASSERT( puxStackBuffer != NULL );
+        configASSERT( pxTaskBuffer != NULL );
+
+        #if ( configASSERT_DEFINED == 1 )
+            {
+                /* Sanity check that the size of the structure used to declare a
+                 * variable of type StaticTask_t equals the size of the real task
+                 * structure. */
+                volatile size_t xSize = sizeof( StaticTask_t );
+                configASSERT( xSize == sizeof( TCB_t ) );
+                ( void ) xSize; /* Prevent lint warning when configASSERT() is not used. */
+            }
+        #endif /* configASSERT_DEFINED */
+
+        if( ( pxTaskBuffer != NULL ) && ( puxStackBuffer != NULL ) )
+        {
+            rt_thread_init( ( struct rt_thread * ) pxTaskBuffer, pcName, pxTaskCode, pvParameters,
+                            ( void * ) puxStackBuffer, ulStackDepth * sizeof( StackType_t ), uxPriority, 1 );
+            rt_thread_startup( ( rt_thread_t ) pxTaskBuffer );
+            xReturn = ( TaskHandle_t ) pxTaskBuffer;
+        }
+
+        return xReturn;
+    }
+
+#endif /* SUPPORT_STATIC_ALLOCATION */
+
+#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+
+    BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
+                            const char * const pcName,
+                            const configSTACK_DEPTH_TYPE usStackDepth,
+                            void * const pvParameters,
+                            UBaseType_t uxPriority,
+                            TaskHandle_t * const pxCreatedTask )
+    {
+        BaseType_t xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
+        rt_thread_t thread = RT_NULL;
+
+        thread = rt_thread_create( pcName, pxTaskCode, pvParameters, usStackDepth * sizeof( StackType_t ), uxPriority, 1 );
+        if ( thread != RT_NULL )
+        {
+            rt_thread_startup( thread );
+            xReturn = pdPASS;
+        }
+        if ( pxCreatedTask != NULL )
+        {
+            *pxCreatedTask = ( TaskHandle_t ) thread;
+        }
+
+        return xReturn;
+    }
+
+#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskDelete == 1 )
+
+    void vTaskDelete( TaskHandle_t xTaskToDelete )
+    {
+        rt_thread_t thread = ( rt_thread_t ) xTaskToDelete;
+        if ( thread == RT_NULL )
+        {
+            thread = rt_thread_self();
+        }
+    #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
+        if ( rt_object_is_systemobject( ( rt_object_t ) thread ) )
+    #endif
+        {
+        #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+            rt_thread_detach( thread );
+        #endif
+    #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
+        }
+        else
+        {
+    #endif
+        #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+            rt_thread_delete( thread );
+        #endif
+        }
+
+        if ( thread == rt_thread_self() )
+        {
+            rt_schedule();
+        }
+    }
+
+#endif /* INCLUDE_vTaskDelete */
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_xTaskDelayUntil == 1 )
+
+    BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
+                                const TickType_t xTimeIncrement )
+    {
+        BaseType_t xShouldDelay = pdFALSE;
+        rt_base_t level;
+        rt_tick_t cur_tick;
+
+        RT_ASSERT( pxPreviousWakeTime != RT_NULL );
+        RT_ASSERT( xTimeIncrement > 0U );
+
+        level = rt_hw_interrupt_disable();
+        cur_tick = rt_tick_get();
+        if (cur_tick - *pxPreviousWakeTime < xTimeIncrement)
+        {
+            rt_thread_delay_until( pxPreviousWakeTime, xTimeIncrement );
+            xShouldDelay = pdTRUE;
+        }
+        rt_hw_interrupt_enable( level );
+
+        return xShouldDelay;
+    }
+
+#endif /* INCLUDE_xTaskDelayUntil */
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskDelay == 1 )
+
+    void vTaskDelay( const TickType_t xTicksToDelay )
+    {
+        rt_thread_delay( xTicksToDelay );
+    }
+
+#endif /* INCLUDE_vTaskDelay */
+/*-----------------------------------------------------------*/
+
 void vTaskSuspendAll( void )
 {
     rt_enter_critical();

+ 1 - 2
test/test_heap.c

@@ -10,13 +10,12 @@
  */
 
 /*
- * Demo: mutex
+ * Demo: heap
  *
  * This demo demonstrates allocating memory from the heap
  *
  */
 
-#include <rtthread.h>
 #include <FreeRTOS.h>
 
 // Set to 1 if using heap_5.c

+ 22 - 32
test/test_mutex_dynamic.c

@@ -16,21 +16,19 @@
  *
  */
 
-#include <rtthread.h>
 #include <FreeRTOS.h>
 #include <semphr.h>
+#include <task.h>
 
-#define THREAD_PRIORITY         8
-#define THREAD_TIMESLICE        5
+#define TASK_PRIORITY         8
 
 /* mutex handler */
-static SemaphoreHandle_t dynamic_mutex = RT_NULL;
-static rt_uint8_t number1, number2 = 0;
+static SemaphoreHandle_t dynamic_mutex = NULL;
+static TaskHandle_t TaskHandle1 = NULL;
+static TaskHandle_t TaskHandle2 = NULL;
+static BaseType_t number1, number2 = 0;
 
-ALIGN(RT_ALIGN_SIZE)
-static char thread1_stack[1024];
-static struct rt_thread thread1;
-static void rt_thread_entry1(void *parameter)
+static void vTask1Code(void *pvParameters)
 {
     while (1)
     {
@@ -38,7 +36,7 @@ static void rt_thread_entry1(void *parameter)
         xSemaphoreTake(dynamic_mutex, portMAX_DELAY);
         /* protect and deal with public variables */
         number1++;
-        rt_thread_mdelay(10);
+        vTaskDelay(pdMS_TO_TICKS(10));
         number2++;
         if (number1 != number2)
         {
@@ -59,10 +57,7 @@ static void rt_thread_entry1(void *parameter)
     }
 }
 
-ALIGN(RT_ALIGN_SIZE)
-static char thread2_stack[1024];
-static struct rt_thread thread2;
-static void rt_thread_entry2(void *parameter)
+static void vTask2Code(void * pvParameters)
 {
     while (1)
     {
@@ -80,29 +75,24 @@ int mutex_dynamic(void)
 {
     /* Create a mutex dynamically */
     dynamic_mutex = xSemaphoreCreateMutex();
-    if (dynamic_mutex == RT_NULL)
+    if (dynamic_mutex == NULL)
     {
         rt_kprintf("create dynamic mutex failed.\n");
         return -1;
     }
+    xTaskCreate( vTask1Code, "Task1", configMINIMAL_STACK_SIZE, NULL, TASK_PRIORITY, &TaskHandle1 );
+    if (TaskHandle1 == NULL)
+    {
+        rt_kprintf("Create task 1 failed\n");
+        return -1;
+    }
+    xTaskCreate( vTask2Code, "Task2", configMINIMAL_STACK_SIZE, NULL, TASK_PRIORITY, &TaskHandle2 );
+    if (TaskHandle2 == NULL)
+    {
+        rt_kprintf("Create task 2 failed\n");
+        return -1;
+    }
 
-    rt_thread_init(&thread1,
-                   "thread1",
-                   rt_thread_entry1,
-                   RT_NULL,
-                   &thread1_stack[0],
-                   sizeof(thread1_stack),
-                   THREAD_PRIORITY, THREAD_TIMESLICE);
-    rt_thread_startup(&thread1);
-
-    rt_thread_init(&thread2,
-                   "thread2",
-                   rt_thread_entry2,
-                   RT_NULL,
-                   &thread2_stack[0],
-                   sizeof(thread2_stack),
-                   THREAD_PRIORITY, THREAD_TIMESLICE);
-    rt_thread_startup(&thread2);
     return 0;
 }
 

+ 21 - 31
test/test_mutex_recursive_dynamic.c

@@ -16,21 +16,19 @@
  *
  */
 
-#include <rtthread.h>
 #include <FreeRTOS.h>
 #include <semphr.h>
+#include <task.h>
 
-#define THREAD_PRIORITY         8
-#define THREAD_TIMESLICE        5
+#define TASK_PRIORITY         8
 
 /* mutex handler */
 static SemaphoreHandle_t dynamic_mutex = RT_NULL;
-static rt_uint8_t number1, number2 = 0;
+static TaskHandle_t TaskHandle1 = NULL;
+static TaskHandle_t TaskHandle2 = NULL;
+static BaseType_t number1, number2 = 0;
 
-ALIGN(RT_ALIGN_SIZE)
-static char thread1_stack[1024];
-static struct rt_thread thread1;
-static void rt_thread_entry1(void *parameter)
+static void vTask1Code(void *pvParameters)
 {
     while (1)
     {
@@ -38,7 +36,7 @@ static void rt_thread_entry1(void *parameter)
         xSemaphoreTakeRecursive(dynamic_mutex, portMAX_DELAY);
         /* protect and deal with public variables */
         number1++;
-        rt_thread_mdelay(10);
+        vTaskDelay(pdMS_TO_TICKS(10));
         number2++;
         if (number1 != number2)
         {
@@ -59,10 +57,7 @@ static void rt_thread_entry1(void *parameter)
     }
 }
 
-ALIGN(RT_ALIGN_SIZE)
-static char thread2_stack[1024];
-static struct rt_thread thread2;
-static void rt_thread_entry2(void *parameter)
+static void vTask2Code(void * pvParameters)
 {
     while (1)
     {
@@ -80,29 +75,24 @@ int mutex_recursive_dynamic(void)
 {
     /* Create a recursive mutex dynamically */
     dynamic_mutex = xSemaphoreCreateRecursiveMutex();
-    if (dynamic_mutex == RT_NULL)
+    if (dynamic_mutex == NULL)
     {
         rt_kprintf("create dynamic mutex failed.\n");
         return -1;
     }
+    xTaskCreate( vTask1Code, "Task1", configMINIMAL_STACK_SIZE, NULL, TASK_PRIORITY, &TaskHandle1 );
+    if (TaskHandle1 == NULL)
+    {
+        rt_kprintf("Create task 1 failed\n");
+        return -1;
+    }
+    xTaskCreate( vTask2Code, "Task2", configMINIMAL_STACK_SIZE, NULL, TASK_PRIORITY, &TaskHandle2 );
+    if (TaskHandle2 == NULL)
+    {
+        rt_kprintf("Create task 2 failed\n");
+        return -1;
+    }
 
-    rt_thread_init(&thread1,
-                   "thread1",
-                   rt_thread_entry1,
-                   RT_NULL,
-                   &thread1_stack[0],
-                   sizeof(thread1_stack),
-                   THREAD_PRIORITY, THREAD_TIMESLICE);
-    rt_thread_startup(&thread1);
-
-    rt_thread_init(&thread2,
-                   "thread2",
-                   rt_thread_entry2,
-                   RT_NULL,
-                   &thread2_stack[0],
-                   sizeof(thread2_stack),
-                   THREAD_PRIORITY, THREAD_TIMESLICE);
-    rt_thread_startup(&thread2);
     return 0;
 }
 

+ 22 - 32
test/test_mutex_recursive_static.c

@@ -16,23 +16,21 @@
  *
  */
 
-#include <rtthread.h>
 #include <FreeRTOS.h>
 #include <semphr.h>
+#include <task.h>
 
-#define THREAD_PRIORITY         8
-#define THREAD_TIMESLICE        5
+#define TASK_PRIORITY         8
 
 /* mutex handler */
-static SemaphoreHandle_t static_mutex = RT_NULL;
+static SemaphoreHandle_t static_mutex = NULL;
 /* Buffer to store mutex structure */
 static StaticSemaphore_t xMutexBuffer;
-static rt_uint8_t number1, number2 = 0;
+static TaskHandle_t TaskHandle1 = NULL;
+static TaskHandle_t TaskHandle2 = NULL;
+static BaseType_t number1, number2 = 0;
 
-ALIGN(RT_ALIGN_SIZE)
-static char thread1_stack[1024];
-static struct rt_thread thread1;
-static void rt_thread_entry1(void *parameter)
+static void vTask1Code(void *pvParameters)
 {
     while (1)
     {
@@ -40,7 +38,7 @@ static void rt_thread_entry1(void *parameter)
         xSemaphoreTakeRecursive(static_mutex, portMAX_DELAY);
         /* protect and deal with public variables */
         number1++;
-        rt_thread_mdelay(10);
+        vTaskDelay(pdMS_TO_TICKS(10));
         number2++;
         if (number1 != number2)
         {
@@ -61,10 +59,7 @@ static void rt_thread_entry1(void *parameter)
     }
 }
 
-ALIGN(RT_ALIGN_SIZE)
-static char thread2_stack[1024];
-static struct rt_thread thread2;
-static void rt_thread_entry2(void *parameter)
+static void vTask2Code(void * pvParameters)
 {
     while (1)
     {
@@ -82,29 +77,24 @@ int mutex_recursive_static(void)
 {
     /* Create a recursive mutex statically */
     static_mutex = xSemaphoreCreateRecursiveMutexStatic(&xMutexBuffer);
-    if (static_mutex == RT_NULL)
+    if (static_mutex == NULL)
     {
         rt_kprintf("create static mutex failed.\n");
         return -1;
     }
+    xTaskCreate( vTask1Code, "Task1", configMINIMAL_STACK_SIZE, NULL, TASK_PRIORITY, &TaskHandle1 );
+    if (TaskHandle1 == NULL)
+    {
+        rt_kprintf("Create task 1 failed\n");
+        return -1;
+    }
+    xTaskCreate( vTask2Code, "Task2", configMINIMAL_STACK_SIZE, NULL, TASK_PRIORITY, &TaskHandle2 );
+    if (TaskHandle2 == NULL)
+    {
+        rt_kprintf("Create task 2 failed\n");
+        return -1;
+    }
 
-    rt_thread_init(&thread1,
-                   "thread1",
-                   rt_thread_entry1,
-                   RT_NULL,
-                   &thread1_stack[0],
-                   sizeof(thread1_stack),
-                   THREAD_PRIORITY, THREAD_TIMESLICE);
-    rt_thread_startup(&thread1);
-
-    rt_thread_init(&thread2,
-                   "thread2",
-                   rt_thread_entry2,
-                   RT_NULL,
-                   &thread2_stack[0],
-                   sizeof(thread2_stack),
-                   THREAD_PRIORITY, THREAD_TIMESLICE);
-    rt_thread_startup(&thread2);
     return 0;
 }
 

+ 22 - 32
test/test_mutex_static.c

@@ -16,23 +16,21 @@
  *
  */
 
-#include <rtthread.h>
 #include <FreeRTOS.h>
 #include <semphr.h>
+#include <task.h>
 
-#define THREAD_PRIORITY         8
-#define THREAD_TIMESLICE        5
+#define TASK_PRIORITY         8
 
 /* mutex handler */
-static SemaphoreHandle_t static_mutex = RT_NULL;
+static SemaphoreHandle_t static_mutex = NULL;
 /* Buffer to store mutex structure */
 static StaticSemaphore_t xMutexBuffer;
-static rt_uint8_t number1, number2 = 0;
+static TaskHandle_t TaskHandle1 = NULL;
+static TaskHandle_t TaskHandle2 = NULL;
+static BaseType_t number1, number2 = 0;
 
-ALIGN(RT_ALIGN_SIZE)
-static char thread1_stack[1024];
-static struct rt_thread thread1;
-static void rt_thread_entry1(void *parameter)
+static void vTask1Code(void *pvParameters)
 {
     while (1)
     {
@@ -40,7 +38,7 @@ static void rt_thread_entry1(void *parameter)
         xSemaphoreTake(static_mutex, portMAX_DELAY);
         /* protect and deal with public variables */
         number1++;
-        rt_thread_mdelay(10);
+        vTaskDelay(pdMS_TO_TICKS(10));
         number2++;
         if (number1 != number2)
         {
@@ -61,10 +59,7 @@ static void rt_thread_entry1(void *parameter)
     }
 }
 
-ALIGN(RT_ALIGN_SIZE)
-static char thread2_stack[1024];
-static struct rt_thread thread2;
-static void rt_thread_entry2(void *parameter)
+static void vTask2Code(void * pvParameters)
 {
     while (1)
     {
@@ -82,29 +77,24 @@ int mutex_static(void)
 {
     /* Create a mutex statically */
     static_mutex = xSemaphoreCreateMutexStatic(&xMutexBuffer);
-    if (static_mutex == RT_NULL)
+    if (static_mutex == NULL)
     {
         rt_kprintf("create static mutex failed.\n");
         return -1;
     }
+    xTaskCreate( vTask1Code, "Task1", configMINIMAL_STACK_SIZE, NULL, TASK_PRIORITY, &TaskHandle1 );
+    if (TaskHandle1 == NULL)
+    {
+        rt_kprintf("Create task 1 failed\n");
+        return -1;
+    }
+    xTaskCreate( vTask2Code, "Task2", configMINIMAL_STACK_SIZE, NULL, TASK_PRIORITY, &TaskHandle2 );
+    if (TaskHandle2 == NULL)
+    {
+        rt_kprintf("Create task 2 failed\n");
+        return -1;
+    }
 
-    rt_thread_init(&thread1,
-                   "thread1",
-                   rt_thread_entry1,
-                   RT_NULL,
-                   &thread1_stack[0],
-                   sizeof(thread1_stack),
-                   THREAD_PRIORITY, THREAD_TIMESLICE);
-    rt_thread_startup(&thread1);
-
-    rt_thread_init(&thread2,
-                   "thread2",
-                   rt_thread_entry2,
-                   RT_NULL,
-                   &thread2_stack[0],
-                   sizeof(thread2_stack),
-                   THREAD_PRIORITY, THREAD_TIMESLICE);
-    rt_thread_startup(&thread2);
     return 0;
 }
 

+ 31 - 41
test/test_semaphore_binary_dynamic.c

@@ -11,29 +11,27 @@
 /*
  * Demo: semaphore
  * This demo creates one binary semaphore dynamically
- * It creates two threads:
- *    1) thread #1: give the semaphore
- *    2) thread #2: take the semaphore
+ * It creates two tasks:
+ *    1) task #1: give the semaphore
+ *    2) task #2: take the semaphore
  *
  */
 
-#include <rtthread.h>
 #include <FreeRTOS.h>
 #include <semphr.h>
+#include <task.h>
 
-#define THREAD_PRIORITY         25
-#define THREAD_TIMESLICE        5
+#define TASK_PRIORITY         25
 
 /* Semaphore handle */
-static SemaphoreHandle_t dynamic_sem = RT_NULL;
+static SemaphoreHandle_t dynamic_sem = NULL;
+static TaskHandle_t TaskHandle1 = NULL;
+static TaskHandle_t TaskHandle2 = NULL;
 
-ALIGN(RT_ALIGN_SIZE)
-static char thread1_stack[1024];
-static struct rt_thread thread1;
-static void rt_thread1_entry(void *parameter)
+static void vTask1Code(void *pvParameters)
 {
-    static rt_err_t result;
-    static rt_uint8_t count = 0;
+    static BaseType_t result;
+    static BaseType_t count = 0;
 
     while (1)
     {
@@ -47,37 +45,34 @@ static void rt_thread1_entry(void *parameter)
         /* Release the semaphore when count is incremented by 10 */
         if (0 == (count % 10))
         {
-            rt_kprintf("thread1 release a dynamic semaphore.\n");
+            rt_kprintf("task1 release a dynamic semaphore.\n");
             result = xSemaphoreGive(dynamic_sem);
             if (result != pdPASS)
             {
-                rt_kprintf("thread2 take a dynamic semaphore, failed.\n");
+                rt_kprintf("task1 release a dynamic semaphore, failed.\n");
                 return;
             }
         }
     }
 }
 
-ALIGN(RT_ALIGN_SIZE)
-static char thread2_stack[1024];
-static struct rt_thread thread2;
-static void rt_thread2_entry(void *parameter)
+static void vTask2Code(void * pvParameters)
 {
-    static rt_err_t result;
-    static rt_uint8_t number = 0;
+    static BaseType_t result;
+    static BaseType_t number = 0;
     while (1)
     {
         /* Block on the semaphore indefinitely. Increment number after taking the semaphore */
         result = xSemaphoreTake(dynamic_sem, portMAX_DELAY);
         if (result != pdPASS)
         {
-            rt_kprintf("thread2 take a dynamic semaphore, failed.\n");
+            rt_kprintf("task2 take a dynamic semaphore, failed.\n");
             return;
         }
         else
         {
             number++;
-            rt_kprintf("thread2 take a dynamic semaphore. number = %d\n", number);
+            rt_kprintf("task2 take a dynamic semaphore. number = %d\n", number);
         }
     }
 }
@@ -86,28 +81,23 @@ int semaphore_binary_dynamic()
 {
     /* Create a binary semaphore dynamically */
     dynamic_sem = xSemaphoreCreateBinary();
-    if (dynamic_sem == RT_NULL)
+    if (dynamic_sem == NULL)
     {
         rt_kprintf("create dynamic semaphore failed.\n");
         return -1;
     }
-    rt_thread_init(&thread1,
-                   "thread1",
-                   rt_thread1_entry,
-                   RT_NULL,
-                   &thread1_stack[0],
-                   sizeof(thread1_stack),
-                   THREAD_PRIORITY, THREAD_TIMESLICE);
-    rt_thread_startup(&thread1);
-
-    rt_thread_init(&thread2,
-                   "thread2",
-                   rt_thread2_entry,
-                   RT_NULL,
-                   &thread2_stack[0],
-                   sizeof(thread2_stack),
-                   THREAD_PRIORITY - 1, THREAD_TIMESLICE);
-    rt_thread_startup(&thread2);
+    xTaskCreate( vTask1Code, "Task1", configMINIMAL_STACK_SIZE, NULL, TASK_PRIORITY, &TaskHandle1 );
+    if (TaskHandle1 == NULL)
+    {
+        rt_kprintf("Create task 1 failed\n");
+        return -1;
+    }
+    xTaskCreate( vTask2Code, "Task2", configMINIMAL_STACK_SIZE, NULL, TASK_PRIORITY - 1, &TaskHandle2 );
+    if (TaskHandle2 == NULL)
+    {
+        rt_kprintf("Create task 2 failed\n");
+        return -1;
+    }
 
     return 0;
 }

+ 31 - 41
test/test_semaphore_binary_static.c

@@ -11,31 +11,29 @@
 /*
  * Demo: semaphore
  * This demo creates one binary semaphore statically
- * It creates two threads:
- *    1) thread #1: give the semaphore
- *    2) thread #2: take the semaphore
+ * It creates two tasks:
+ *    1) task #1: give the semaphore
+ *    2) task #2: take the semaphore
  *
  */
 
-#include <rtthread.h>
 #include <FreeRTOS.h>
 #include <semphr.h>
+#include <task.h>
 
-#define THREAD_PRIORITY         25
-#define THREAD_TIMESLICE        5
+#define TASK_PRIORITY         25
 
 /* Semaphore handle */
-static SemaphoreHandle_t static_sem = RT_NULL;
+static SemaphoreHandle_t static_sem = NULL;
 /* Buffer to store semaphore structure */
 static StaticSemaphore_t xMutexBuffer;
+static TaskHandle_t TaskHandle1 = NULL;
+static TaskHandle_t TaskHandle2 = NULL;
 
-ALIGN(RT_ALIGN_SIZE)
-static char thread1_stack[1024];
-static struct rt_thread thread1;
-static void rt_thread1_entry(void *parameter)
+static void vTask1Code(void *pvParameters)
 {
-    static rt_err_t result;
-    static rt_uint8_t count = 0;
+    static BaseType_t result;
+    static BaseType_t count = 0;
 
     while (1)
     {
@@ -49,37 +47,34 @@ static void rt_thread1_entry(void *parameter)
         /* Release the semaphore when count is incremented by 10 */
         if (0 == (count % 10))
         {
-            rt_kprintf("thread1 release a static semaphore.\n");
+            rt_kprintf("task1 release a static semaphore.\n");
             result = xSemaphoreGive(static_sem);
             if (result != pdPASS)
             {
-                rt_kprintf("thread2 take a static semaphore, failed.\n");
+                rt_kprintf("task1 release a static semaphore, failed.\n");
                 return;
             }
         }
     }
 }
 
-ALIGN(RT_ALIGN_SIZE)
-static char thread2_stack[1024];
-static struct rt_thread thread2;
-static void rt_thread2_entry(void *parameter)
+static void vTask2Code(void * pvParameters)
 {
-    static rt_err_t result;
-    static rt_uint8_t number = 0;
+    static BaseType_t result;
+    static BaseType_t number = 0;
     while (1)
     {
         /* Block on the semaphore indefinitely. Increment number after taking the semaphore */
         result = xSemaphoreTake(static_sem, portMAX_DELAY);
         if (result != pdPASS)
         {
-            rt_kprintf("thread2 take a static semaphore, failed.\n");
+            rt_kprintf("task2 take a static semaphore, failed.\n");
             return;
         }
         else
         {
             number++;
-            rt_kprintf("thread2 take a static semaphore. number = %d\n", number);
+            rt_kprintf("task2 take a static semaphore. number = %d\n", number);
         }
     }
 }
@@ -88,28 +83,23 @@ int semaphore_binary_static()
 {
     /* Create a binary semaphore statically */
     static_sem = xSemaphoreCreateBinaryStatic(&xMutexBuffer);
-    if (static_sem == RT_NULL)
+    if (static_sem == NULL)
     {
         rt_kprintf("create static semaphore failed.\n");
         return -1;
     }
-    rt_thread_init(&thread1,
-                   "thread1",
-                   rt_thread1_entry,
-                   RT_NULL,
-                   &thread1_stack[0],
-                   sizeof(thread1_stack),
-                   THREAD_PRIORITY, THREAD_TIMESLICE);
-    rt_thread_startup(&thread1);
-
-    rt_thread_init(&thread2,
-                   "thread2",
-                   rt_thread2_entry,
-                   RT_NULL,
-                   &thread2_stack[0],
-                   sizeof(thread2_stack),
-                   THREAD_PRIORITY - 1, THREAD_TIMESLICE);
-    rt_thread_startup(&thread2);
+    xTaskCreate( vTask1Code, "Task1", configMINIMAL_STACK_SIZE, NULL, TASK_PRIORITY, &TaskHandle1 );
+    if (TaskHandle1 == NULL)
+    {
+        rt_kprintf("Create task 1 failed\n");
+        return -1;
+    }
+    xTaskCreate( vTask2Code, "Task2", configMINIMAL_STACK_SIZE, NULL, TASK_PRIORITY - 1, &TaskHandle2 );
+    if (TaskHandle2 == NULL)
+    {
+        rt_kprintf("Create task 2 failed\n");
+        return -1;
+    }
 
     return 0;
 }

+ 37 - 47
test/test_semaphore_counting_dynamic.c

@@ -11,85 +11,80 @@
 /*
  * Demo: semaphore
  * This demo creates one counting semaphore dynamically
- * It creates two threads:
- *    1) thread #1: take the semaphore until its value reaches 0
- *    2) thread #2: give the semaphore until its value reaches maximum
+ * It creates two tasks:
+ *    1) task #1: take the semaphore until its value reaches 0
+ *    2) task #2: give the semaphore until its value reaches maximum
  *
  */
 
-#include <rtthread.h>
 #include <FreeRTOS.h>
 #include <semphr.h>
+#include <task.h>
 
-#define THREAD_PRIORITY         25
-#define THREAD_TIMESLICE        5
+#define TASK_PRIORITY         25
 
 /* Semaphore handle */
-static SemaphoreHandle_t dynamic_sem = RT_NULL;
+static SemaphoreHandle_t dynamic_sem = NULL;
+static TaskHandle_t TaskHandle1 = NULL;
+static TaskHandle_t TaskHandle2 = NULL;
 
-ALIGN(RT_ALIGN_SIZE)
-static char thread1_stack[1024];
-static struct rt_thread thread1;
-static void rt_thread1_entry(void *parameter)
+static void vTask1Code(void *pvParameters)
 {
-    static rt_err_t result;
-    static rt_uint8_t number = 0;
+    static BaseType_t result;
+    static BaseType_t number = 0;
     while (1)
     {
-        /* Thread1 starts when thread2 is delayed. Semaphore value is 5. Should take it successfully for five times */
+        /* Task1 starts when task2 is delayed. Semaphore value is 5. Should take it successfully for five times */
         for (number = 0; number < 5; number++)
         {
             result = xSemaphoreTake(dynamic_sem, portMAX_DELAY);
             if (result != pdPASS)
             {
-                rt_kprintf("thread1 take a dynamic semaphore, failed.\n");
+                rt_kprintf("task1 take a dynamic semaphore, failed.\n");
                 return;
             }
             else
             {
-                rt_kprintf("thread1 take a dynamic semaphore. number = %d\n", number);
+                rt_kprintf("task1 take a dynamic semaphore. number = %d\n", number);
             }
         }
         /* Cannot take the semaphore for the sixth time because the value is 0 */
         result = xSemaphoreTake(dynamic_sem, 0);
         if (result != errQUEUE_EMPTY)
         {
-            rt_kprintf("thread1 take a dynamic semaphore. number = %d. Should not succeed.\n", number);
+            rt_kprintf("task1 take a dynamic semaphore. number = %d. Should not succeed.\n", number);
         }
-        rt_thread_delay(rt_tick_from_millisecond(10000));
+        vTaskDelay(pdMS_TO_TICKS(5000));
     }
 }
 
-ALIGN(RT_ALIGN_SIZE)
-static char thread2_stack[1024];
-static struct rt_thread thread2;
-static void rt_thread2_entry(void *parameter)
+static void vTask2Code(void * pvParameters)
 {
-    static rt_err_t result;
-    static rt_uint8_t number = 0;
+    static BaseType_t result;
+    static BaseType_t number = 0;
     while (1)
     {
-        /* Thread2 runs before thread1. The semaphore value is 0. Should give the semaphore 5 times successfully */
+        /* Task2 runs before task1. The semaphore value is 0. Should give the semaphore 5 times successfully */
         for (number = 0; number < 5; number++)
         {
             result = xSemaphoreGive(dynamic_sem);
             if (result != pdPASS)
             {
-                rt_kprintf("thread2 release a dynamic semaphore, failed.\n");
+                rt_kprintf("task2 release a dynamic semaphore, failed.\n");
                 return;
             }
             else
             {
-                rt_kprintf("thread2 release a dynamic semaphore. number = %d\n", number);
+                rt_kprintf("task2 release a dynamic semaphore. number = %d\n", number);
             }
         }
         /* Cannot give the semaphore for the sixth time because the max value is reached */
         result = xSemaphoreGive(dynamic_sem);
         if (result != errQUEUE_FULL)
         {
-            rt_kprintf("thread2 release a dynamic semaphore. number = %d. Should not succeed.\n", number);
+            rt_kprintf("task2 release a dynamic semaphore. number = %d. Should not succeed.\n", number);
         }
-        rt_thread_delay(rt_tick_from_millisecond(10000));
+        vTaskDelay(pdMS_TO_TICKS(5000));
     }
 }
 
@@ -97,28 +92,23 @@ int semaphore_counting_dynamic()
 {
     /* Create a counting semaphore dynamically. Max value is 5. Initial value is 0. */
     dynamic_sem = xSemaphoreCreateCounting(5, 0);
-    if (dynamic_sem == RT_NULL)
+    if (dynamic_sem == NULL)
     {
         rt_kprintf("create dynamic semaphore failed.\n");
         return -1;
     }
-    rt_thread_init(&thread1,
-                   "thread1",
-                   rt_thread1_entry,
-                   RT_NULL,
-                   &thread1_stack[0],
-                   sizeof(thread1_stack),
-                   THREAD_PRIORITY, THREAD_TIMESLICE);
-    rt_thread_startup(&thread1);
-
-    rt_thread_init(&thread2,
-                   "thread2",
-                   rt_thread2_entry,
-                   RT_NULL,
-                   &thread2_stack[0],
-                   sizeof(thread2_stack),
-                   THREAD_PRIORITY - 1, THREAD_TIMESLICE);
-    rt_thread_startup(&thread2);
+    xTaskCreate( vTask1Code, "Task1", configMINIMAL_STACK_SIZE, NULL, TASK_PRIORITY, &TaskHandle1 );
+    if (TaskHandle1 == NULL)
+    {
+        rt_kprintf("Create task 1 failed\n");
+        return -1;
+    }
+    xTaskCreate( vTask2Code, "Task2", configMINIMAL_STACK_SIZE, NULL, TASK_PRIORITY - 1, &TaskHandle2 );
+    if (TaskHandle2 == NULL)
+    {
+        rt_kprintf("Create task 2 failed\n");
+        return -1;
+    }
 
     return 0;
 }

+ 37 - 46
test/test_semaphore_counting_static.c

@@ -11,87 +11,83 @@
 /*
  * Demo: semaphore
  * This demo creates one counting semaphore statically
- * It creates two threads:
- *    1) thread #1: take the semaphore until its value reaches 0
- *    2) thread #2: give the semaphore until its value reaches maximum
+ * It creates two tasks:
+ *    1) task #1: take the semaphore until its value reaches 0
+ *    2) task #2: give the semaphore until its value reaches maximum
  *
  */
 
-#include <rtthread.h>
 #include <FreeRTOS.h>
 #include <semphr.h>
+#include <task.h>
+#include <task.h>
 
-#define THREAD_PRIORITY         25
-#define THREAD_TIMESLICE        5
+#define TASK_PRIORITY         25
 
 /* Semaphore handle */
 static SemaphoreHandle_t static_sem = RT_NULL;
 /* Buffer to store semaphore structure */
 static StaticSemaphore_t xMutexBuffer;
+static TaskHandle_t TaskHandle1 = NULL;
+static TaskHandle_t TaskHandle2 = NULL;
 
-ALIGN(RT_ALIGN_SIZE)
-static char thread1_stack[1024];
-static struct rt_thread thread1;
-static void rt_thread1_entry(void *parameter)
+static void vTask1Code(void *pvParameters)
 {
-    static rt_err_t result;
-    static rt_uint8_t number = 0;
+    static BaseType_t result;
+    static BaseType_t number = 0;
     while (1)
     {
-        /* Thread1 starts when thread2 is delayed. Semaphore value is 5. Should take it successfully for five times */
+        /* Task1 starts when task2 is delayed. Semaphore value is 5. Should take it successfully for five times */
         for (number = 0; number < 5; number++)
         {
             result = xSemaphoreTake(static_sem, portMAX_DELAY);
             if (result != pdPASS)
             {
-                rt_kprintf("thread1 take a static semaphore, failed.\n");
+                rt_kprintf("task1 take a static semaphore, failed.\n");
                 return;
             }
             else
             {
-                rt_kprintf("thread1 take a static semaphore. number = %d\n", number);
+                rt_kprintf("task1 take a static semaphore. number = %d\n", number);
             }
         }
         /* Cannot take the semaphore for the sixth time because the value is 0 */
         result = xSemaphoreTake(static_sem, 0);
         if (result != errQUEUE_EMPTY)
         {
-            rt_kprintf("thread1 take a static semaphore. number = %d. Should not succeed.\n", number);
+            rt_kprintf("task1 take a static semaphore. number = %d. Should not succeed.\n", number);
         }
-        rt_thread_delay(rt_tick_from_millisecond(10000));
+        vTaskDelay(pdMS_TO_TICKS(5000));
     }
 }
 
-ALIGN(RT_ALIGN_SIZE)
-static char thread2_stack[1024];
-static struct rt_thread thread2;
-static void rt_thread2_entry(void *parameter)
+static void vTask2Code(void * pvParameters)
 {
-    static rt_err_t result;
-    static rt_uint8_t number = 0;
+    static BaseType_t result;
+    static BaseType_t number = 0;
     while (1)
     {
-        /* Thread2 runs before thread1. The semaphore value is 0. Should give the semaphore 5 times successfully */
+        /* Task2 runs before task1. The semaphore value is 0. Should give the semaphore 5 times successfully */
         for (number = 0; number < 5; number++)
         {
             result = xSemaphoreGive(static_sem);
             if (result != pdPASS)
             {
-                rt_kprintf("thread2 release a static semaphore, failed.\n");
+                rt_kprintf("task2 release a static semaphore, failed.\n");
                 return;
             }
             else
             {
-                rt_kprintf("thread2 release a static semaphore. number = %d\n", number);
+                rt_kprintf("task2 release a static semaphore. number = %d\n", number);
             }
         }
         /* Cannot give the semaphore for the sixth time because the max value is reached */
         result = xSemaphoreGive(static_sem);
         if (result != errQUEUE_FULL)
         {
-            rt_kprintf("thread2 release a static semaphore. number = %d. Should not succeed.\n", number);
+            rt_kprintf("task2 release a static semaphore. number = %d. Should not succeed.\n", number);
         }
-        rt_thread_delay(rt_tick_from_millisecond(10000));
+        vTaskDelay(pdMS_TO_TICKS(5000));
     }
 }
 
@@ -99,28 +95,23 @@ int semaphore_counting_static()
 {
     /* Create a counting semaphore statically. Max value is 5. Initial value is 0. */
     static_sem = xSemaphoreCreateCountingStatic(5, 0, &xMutexBuffer);
-    if (static_sem == RT_NULL)
+    if (static_sem == NULL)
     {
         rt_kprintf("create static semaphore failed.\n");
         return -1;
     }
-    rt_thread_init(&thread1,
-                   "thread1",
-                   rt_thread1_entry,
-                   RT_NULL,
-                   &thread1_stack[0],
-                   sizeof(thread1_stack),
-                   THREAD_PRIORITY, THREAD_TIMESLICE);
-    rt_thread_startup(&thread1);
-
-    rt_thread_init(&thread2,
-                   "thread2",
-                   rt_thread2_entry,
-                   RT_NULL,
-                   &thread2_stack[0],
-                   sizeof(thread2_stack),
-                   THREAD_PRIORITY - 1, THREAD_TIMESLICE);
-    rt_thread_startup(&thread2);
+    xTaskCreate( vTask1Code, "Task1", configMINIMAL_STACK_SIZE, NULL, TASK_PRIORITY, &TaskHandle1 );
+    if (TaskHandle1 == NULL)
+    {
+        rt_kprintf("Create task 1 failed\n");
+        return -1;
+    }
+    xTaskCreate( vTask2Code, "Task2", configMINIMAL_STACK_SIZE, NULL, TASK_PRIORITY - 1, &TaskHandle2 );
+    if (TaskHandle2 == NULL)
+    {
+        rt_kprintf("Create task 2 failed\n");
+        return -1;
+    }
 
     return 0;
 }

+ 66 - 0
test/test_task.c

@@ -0,0 +1,66 @@
+/*
+ * Demo: task
+ *
+ * This demo creates two tasks. Task 1 is created dynamically and task 2 is created statically.
+ * Task 2 increments a number than delays for 1 second.
+ * After task 2 runs for 10 iterations, task 1 deletes task 2, then deletes itself.
+ *
+ */
+
+#include <FreeRTOS.h>
+#include <task.h>
+
+#define TASK_PRIORITY         8
+
+static TaskHandle_t TaskHandle1 = NULL;
+static TaskHandle_t TaskHandle2 = NULL;
+static StaticTask_t xTaskBuffer;
+StackType_t xStack[configMINIMAL_STACK_SIZE * 2];
+static BaseType_t num = 0;
+
+void vTask1Code(void * pvParameters)
+{
+    while (1)
+    {
+        vTaskDelay(pdMS_TO_TICKS(1000));
+        rt_kprintf("Task 1 running\n");
+        if (num > 10)
+        {
+            rt_kprintf("Delete task 2\n");
+            vTaskDelete(TaskHandle2);
+            rt_kprintf("Delete task 1\n");
+            vTaskDelete(NULL);
+            rt_kprintf("Should not reach here\n");
+        }
+    }
+}
+
+void vTask2Code(void * pvParameters)
+{
+    while (1)
+    {
+        vTaskDelay(pdMS_TO_TICKS(1000));
+        num += 1;
+        rt_kprintf("Task 2 running, num = %d\n",num);
+    }
+}
+
+int task_sample(void)
+{
+    xTaskCreate(vTask1Code, "Task1", configMINIMAL_STACK_SIZE, NULL, TASK_PRIORITY, &TaskHandle1);
+    if (TaskHandle1 == NULL)
+    {
+        rt_kprintf("Create task 1 failed\n");
+        return -1;
+    }
+    TaskHandle2 = xTaskCreateStatic(vTask2Code, "Task2", configMINIMAL_STACK_SIZE * 2, NULL, TASK_PRIORITY, xStack, &xTaskBuffer);
+    if (TaskHandle2 == NULL)
+    {
+        rt_kprintf("Create task 2 failed\n");
+        return -1;
+    }
+
+    return 0;
+}
+
+MSH_CMD_EXPORT(task_sample, task sample);