Răsfoiți Sursa

Merge branch 'feature/freertos_upstream_plus_tlsf_allocator_preview' into 'master'

freertos/heap: Preview branch containing TLSF allocator and FreeRTOS 10 kernel

Closes IDF-1637 and IDFGH-3859

See merge request espressif/esp-idf!8414
Angus Gratton 5 ani în urmă
părinte
comite
a1d3f2b291
77 a modificat fișierele cu 10562 adăugiri și 4187 ștergeri
  1. 1 1
      .gitignore
  2. 4 3
      components/app_trace/sys_view/Sample/OS/SEGGER_SYSVIEW_FreeRTOS.h
  3. 1 1
      components/driver/spi_master.c
  4. 1 1
      components/driver/test/test_spi_master.c
  5. 4 0
      components/esp_system/linker.lf
  6. 4 2
      components/freertos/CMakeLists.txt
  7. 2710 0
      components/freertos/History.txt
  8. 1 1
      components/freertos/Kconfig
  9. 31 69
      components/freertos/croutine.c
  10. 133 156
      components/freertos/event_groups.c
  11. 447 180
      components/freertos/include/freertos/FreeRTOS.h
  12. 418 0
      components/freertos/include/freertos/atomic.h
  13. 25 67
      components/freertos/include/freertos/croutine.h
  14. 29 71
      components/freertos/include/freertos/deprecated_definitions.h
  15. 60 87
      components/freertos/include/freertos/event_groups.h
  16. 47 101
      components/freertos/include/freertos/list.h
  17. 702 0
      components/freertos/include/freertos/message_buffer.h
  18. 150 120
      components/freertos/include/freertos/mpu_wrappers.h
  19. 105 142
      components/freertos/include/freertos/portable.h
  20. 0 42
      components/freertos/include/freertos/porttrace.h
  21. 90 71
      components/freertos/include/freertos/projdefs.h
  22. 52 219
      components/freertos/include/freertos/queue.h
  23. 56 80
      components/freertos/include/freertos/semphr.h
  24. 25 68
      components/freertos/include/freertos/stack_macros.h
  25. 0 0
      components/freertos/include/freertos/stdint.readme
  26. 745 0
      components/freertos/include/freertos/stream_buffer.h
  27. 425 257
      components/freertos/include/freertos/task.h
  28. 103 109
      components/freertos/include/freertos/timers.h
  29. 21 440
      components/freertos/license.txt
  30. 47 82
      components/freertos/list.c
  31. 302 320
      components/freertos/queue.c
  32. 1265 0
      components/freertos/stream_buffer.c
  33. 384 366
      components/freertos/tasks.c
  34. 1 2
      components/freertos/test/test_freertos_eventgroups.c
  35. 3 1
      components/freertos/test/test_freertos_get_state.c
  36. 103 0
      components/freertos/test/test_stream_buffers.c
  37. 1 1
      components/freertos/test/test_suspend_scheduler.c
  38. 17 0
      components/freertos/test/test_timers.c
  39. 293 234
      components/freertos/timers.c
  40. 6 8
      components/freertos/xtensa/include/freertos/FreeRTOSConfig.h
  41. 108 29
      components/freertos/xtensa/include/freertos/portmacro.h
  42. 1 1
      components/freertos/xtensa/include/freertos/xtensa_context.h
  43. 2 2
      components/freertos/xtensa/port.c
  44. 2 1
      components/heap/CMakeLists.txt
  45. 1 1
      components/heap/component.mk
  46. 6 12
      components/heap/heap_caps.c
  47. 867 0
      components/heap/heap_tlsf.c
  48. 133 0
      components/heap/heap_tlsf.h
  49. 172 0
      components/heap/heap_tlsf_block_functions.h
  50. 73 0
      components/heap/heap_tlsf_config.h
  51. 8 13
      components/heap/include/esp_heap_caps.h
  52. 2 2
      components/heap/include/multi_heap.h
  53. 1 0
      components/heap/linker.lf
  54. 133 574
      components/heap/multi_heap.c
  55. 2 2
      components/heap/multi_heap_internal.h
  56. 13 26
      components/heap/multi_heap_poisoning.c
  57. 10 8
      components/heap/test/test_aligned_alloc_caps.c
  58. 108 0
      components/heap/test/test_allocator_timings.c
  59. 15 11
      components/heap/test/test_malloc_caps.c
  60. 1 1
      components/heap/test/test_realloc.c
  61. 1 0
      components/heap/test_multi_heap_host/Makefile
  62. 1 1
      components/heap/test_multi_heap_host/test_all_configs.sh
  63. 27 77
      components/heap/test_multi_heap_host/test_multi_heap.cpp
  64. 9 0
      components/idf_test/include/idf_performance.h
  65. 5 8
      components/newlib/heap.c
  66. 0 1
      components/pthread/test/test_pthread_local_storage.c
  67. 0 1
      components/soc/include/soc/spinlock.h
  68. 1 1
      components/wear_levelling/test/test_wl.c
  69. 2 0
      docs/Doxyfile
  70. 3 1
      docs/en/COPYRIGHT.rst
  71. 28 106
      docs/en/api-guides/freertos-smp.rst
  72. 10 1
      docs/en/api-reference/system/freertos.rst
  73. 1 1
      examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/main.c
  74. 1 1
      examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/spp_task.c
  75. 1 1
      examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/components/case/sync.c
  76. 1 1
      tools/ci/config/target-test.yml
  77. 1 1
      tools/ci/static-analysis-rules.yml

+ 1 - 1
.gitignore

@@ -87,4 +87,4 @@ flake8_output.txt
 build
 
 # lock files for examples and components
-dependencies.lock
+dependencies.lock

+ 4 - 3
components/app_trace/sys_view/Sample/OS/SEGGER_SYSVIEW_FreeRTOS.h

@@ -230,11 +230,12 @@ Notes:
 
 #define traceQUEUE_CREATE( pxNewQueue )                               SEGGER_SYSVIEW_RecordU32x3(apiFastID_OFFSET + apiID_XQUEUEGENERICCREATE, uxQueueLength, uxItemSize, ucQueueType)
 #define traceQUEUE_DELETE( pxQueue )                                  SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_VQUEUEDELETE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue))
-#define traceQUEUE_PEEK( pxQueue )                                    SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICRECEIVE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer), xTicksToWait, xJustPeeking)
+#define traceQUEUE_PEEK( pxQueue )                                    SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICRECEIVE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer), xTicksToWait, 0)
 #define traceQUEUE_PEEK_FROM_ISR( pxQueue )                           SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_XQUEUEPEEKFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer))
 #define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue )                    SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_XQUEUEPEEKFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer))
-#define traceQUEUE_RECEIVE( pxQueue )                                 SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICRECEIVE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer), xTicksToWait, xJustPeeking)
-#define traceQUEUE_RECEIVE_FAILED( pxQueue )                          SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICRECEIVE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer), xTicksToWait, xJustPeeking)
+#define traceQUEUE_RECEIVE( pxQueue )                                 SEGGER_SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICRECEIVE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)0), xTicksToWait, 1)
+#define traceQUEUE_RECEIVE_FAILED( pxQueue )                          SEGGER_SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICRECEIVE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)0), xTicksToWait, 1)
+#define traceQUEUE_SEMAPHORE_RECEIVE( pxQueue )                       SEGGER_SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICRECEIVE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)0), xTicksToWait, 0)
 #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue )                        SEGGER_SYSVIEW_RecordU32x3(apiFastID_OFFSET + apiID_XQUEUERECEIVEFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer), (U32)pxHigherPriorityTaskWoken)
 #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue )                 SEGGER_SYSVIEW_RecordU32x3(apiFastID_OFFSET + apiID_XQUEUERECEIVEFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer), (U32)pxHigherPriorityTaskWoken)
 #define traceQUEUE_REGISTRY_ADD( xQueue, pcQueueName )                SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_VQUEUEADDTOREGISTRY, SEGGER_SYSVIEW_ShrinkId((U32)xQueue), (U32)pcQueueName)

+ 1 - 1
components/driver/spi_master.c

@@ -719,7 +719,7 @@ static SPI_MASTER_ISR_ATTR void uninstall_priv_desc(spi_trans_priv_t* trans_buf)
     }
     // copy data from temporary DMA-capable buffer back to IRAM buffer and free the temporary one.
     if ((void *)trans_buf->buffer_to_rcv != &trans_desc->rx_data[0] &&
-        trans_buf->buffer_to_rcv != trans_desc->rx_buffer) {
+        trans_buf->buffer_to_rcv != trans_desc->rx_buffer) { // NOLINT(clang-analyzer-unix.Malloc)
         if (trans_desc->flags & SPI_TRANS_USE_RXDATA) {
             memcpy((uint8_t *) & trans_desc->rx_data[0], trans_buf->buffer_to_rcv, (trans_desc->rxlength + 7) / 8);
         } else {

+ 1 - 1
components/driver/test/test_spi_master.c

@@ -564,7 +564,7 @@ TEST_CASE("SPI Master DMA test, TX and RX in different regions", "[spi]")
     ESP_LOGI(TAG, "iram: %p, dram: %p", data_iram, data_dram);
     ESP_LOGI(TAG, "drom: %p, malloc: %p", data_drom, data_malloc);
     TEST_ASSERT(esp_ptr_in_dram(data_dram));
-    TEST_ASSERT(esp_ptr_in_iram(data_iram));
+    TEST_ASSERT(esp_ptr_executable(data_iram) || esp_ptr_in_iram(data_iram) || esp_ptr_in_diram_iram(data_iram));
     TEST_ASSERT(esp_ptr_in_drom(data_drom));
 
     srand(52);

+ 4 - 0
components/esp_system/linker.lf

@@ -5,6 +5,10 @@ entries:
     panic_handler (noflash)
     reset_reason (noflash)
     system_api:esp_system_abort (noflash)
+    startup:do_core_init (default)
+    startup:do_secondary_init (default)
+    startup:start_cpu0_default (default)
+
 
     if ESP_CONSOLE_USB_CDC_SUPPORT_ETS_PRINTF:
         usb_console:esp_usb_console_write_char (noflash)

+ 4 - 2
components/freertos/CMakeLists.txt

@@ -16,11 +16,12 @@ set(srcs
 list(APPEND srcs 
     "croutine.c"
     "event_groups.c"
-    "FreeRTOS-openocd.c"
     "list.c"
     "queue.c"
     "tasks.c"
-    "timers.c")
+    "timers.c"
+    "stream_buffer.c"
+    "FreeRTOS-openocd.c")
 
 set(include_dirs 
     include
@@ -57,6 +58,7 @@ set_source_files_properties(
     event_groups.c
     timers.c
     queue.c
+    stream_buffer.c
     PROPERTIES COMPILE_DEFINITIONS
     _ESP_FREERTOS_INTERNAL
     )

+ 2710 - 0
components/freertos/History.txt

@@ -0,0 +1,2710 @@
+Documentation and download available at http://www.FreeRTOS.org/
+
+Changes since the last release:
+	+ Added xTaskCatchUpTicks() which corrects the tick count value after the
+	  application code has held interrupts disabled for an extended period.
+	+ Updated the xTaskResumeAll() implementation so it uses the new
+	  xTaskCatchUpTicks() function mentioned above to unwind ticks that were
+	  pended while the scheduler was suspended.
+	+ Update the Windows simulator port to use a synchronous object to prevent
+	  a user reported error whereby a task continues to run for a short time
+	  after being moved to the Blocked state.  Note we were not able to
+	  replicate the reported error.
+	+ Added the vPortGetHeapStats() API function which returns information on
+	  the heap_4 and heap_5 state.
+	+ Change type of uxPendedTicks from UBaseType_t to TickType_t to ensure it
+	  has same type as variables it is compared to, and therefore also rename
+	  the variable xPendingTicks.
+	+ Correct alignment of stack top in RISC-V port when
+	  configISR_STACK_SIZE_WORDS is defined to a non zero value.
+
+
+Changes between FreeRTOS V10.2.1 and FreeRTOS V10.2.0 released May 13 2019:
+
+	+ Added ARM Cortex-M23 port layer to complement the pre-existing ARM
+	  Cortex-M33 port layer.
+	+ The RISC-V port now automatically switches between 32-bit and 64-bit
+	  cores.
+	+ Introduced the portMEMORY_BARRIER macro to prevent instruction re-ordering
+	  when GCC link time optimisation is used.
+	+ Introduced the portDONT_DISCARD macro to the ARMv8-M ports to try and
+	  prevent the secure side builds from removing symbols required by the
+	  non secure side build.
+	+ Introduced the portARCH_NAME to provide additional data to select semi-
+	  automated build environments.
+	+ Cortex-M33 and Cortex-M23 ports now correctly disable the MPU before
+	  updating the MPU registers.
+
+	+ Added Nuvoton NuMaker-PFM-M2351 ARM Cortex-M23 demo.
+	+ Added LPC55S69 ARM Cortex-M33 demo.
+	+ Added an STM32 dual core AMP stress test demo.
+
+
+Changes between FreeRTOS V10.1.1 and FreeRTOS V10.2.0 released February 25 2019:
+
+	+ Added GCC RISC-V MCU port with three separate demo applications.
+	+ Included pre-existing ARM Cortex-M33 (ARMv8-M) GCC/ARMclang and IAR ports
+	  with Keil simulator demo.
+	+ Update the method used to detect if a timer is active.  Previously the
+	  timer was deemed to be inactive if it was not referenced from a list.
+	  However, when a timer is updated it is temporarily removed from, then
+	  re-added to a list, so now the timer's active status is stored separately.
+	+ Add vTimerSetReloadMode(), xTaskGetIdleRunTimeCounter(), and
+	  xTaskGetApplicationTaskTagFromISR() API functions.
+	+ Updated third party Xtensa port so it is MIT licensed.
+	+ Added configINCLUDE_PLATFORM_H_INSTEAD_OF_IODEFINE_H to the Renesas
+	  compiler RX600v2 port to enable switching between platform.h and
+	  iodefine.h includes within that port's port.c file.
+	+ Removed the 'FromISR' functions from the MPU ports as ISRs run privileged
+	  anyway.
+	+ Added uxTaskGetStackHighWaterMark2() function to enable the return type to
+	  be changed without breaking backward compatibility.
+	  uxTaskGetStackHighWaterMark() returns a UBaseType_t as always,
+	  uxTaskGetStackHighWaterMark2() returns configSTACK_DEPTH_TYPE to allow the
+	  user to determine the return type.
+	+ Fixed issues in memory protected ports related to different combinations
+	  of static memory only and dynamic memory only builds.  As a result the
+	  definition of tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE became more
+	  complex and was moved to FreeRTOS.h with a table explaining its definition.
+	+ Added a 'get task tag from ISR' function.
+	+ Change the method used to determine if a timer is active or not from just
+	  seeing if it is referenced from the active timer list to storing its
+	  active state explicitly.  The change prevents the timer reporting that it
+	  is inactive while it is being moved from one list to another.
+	+ The pcName parameter passed into the task create functions can be NULL,
+	  previously a name had to be provided.
+	+ When using tickless idle, prvResetNextTaskUnblockTime() is now only called
+	  in xTaskRemoveFromEventList() if the scheduler is not suspended.
+	+ Introduced portHAS_STACK_OVERFLOW_CHECKING, which should be set to 1 for
+	  FreeRTOS ports that run on architectures that have stack limit registers.
+
+
+Changes between FreeRTOS V10.1.0 and FreeRTOS V10.1.1 released 7 September 2018
+
+	+ Reverted a few structure name changes that broke several kernel aware
+	  debugger plug-ins.
+	+ Updated to the latest trace recorder code.
+	+ Fixed some formatting in the FreeRTOS+TCP TCP/IP stack code.
+	+ Reverted moving some variables from file to function scope as doing so
+	  broke debug scenarios that require the static qualifier to be removed.
+
+Changes between FreeRTOS V10.0.1 and FreeRTOS V10.1.0 released 22 August 2018
+
+	FreeRTOS Kernel Changes:
+
+	+ Update lint checked MISRA compliance to use the latest MISRA standard, was
+	  previously using the original MISRA standard.
+	+ Updated all object handles (TaskHandle_t, QueueHandle_t, etc.) to be
+	  unique types instead of void pointers, improving type safety.  (this was
+	  attempted some years back but had to be backed out due to bugs in some
+	  debuggers).  Note this required the pvContainer member of a ListItem_t
+	  struct to be renamed - set configENABLE_BACKWARD_COMPATIBILITY to 1 if
+	  this causes an issue.
+	+ Added configUSE_POSIX_ERRNO to enable per task POSIX style errno
+	  functionality in a more user friendly way - previously the generic thread
+	  local storage feature was used for this purpose.
+	+ Added Xtensa port and demo application for the XCC compiler.
+	+ Changed the implementation of vPortEndScheduler() for the Win32 port to
+	  simply call exit( 0 ).
+	+ Bug fix in vPortEnableInterrupt() for the GCC Microblaze port to protect
+	  the read modify write access to an internal Microblaze register.
+	+ Fix minor niggles when the MPU is used with regards to prototype
+	  differences, static struct size differences, etc.
+	+ The usStackHighWaterMark member of the TaskStatus_t structure now has type
+	  configSTACK_DEPTH_TYPE in place of uint16_t - that change should have been
+	  made when the configSTACK_DEPTH_TYPE type (which gets around the previous
+	  16-bit limit on stack size specifications) was introduced.
+	+ Added the xMessageBufferNextLengthBytes() API function and likewise stream
+	  buffer equivalent.
+	+ Introduce configMESSAGE_BUFFER_LENGTH_TYPE to allow the number of bytes
+	  used to hold the length of a message in the message buffer to be reduced.
+	  configMESSAGE_BUFFER_LENGTH_TYPE default to size_t, but if, for example,
+	  messages can never be more than 255 bytes it could be set to uint8_t,
+	  saving 3 bytes each time a message is written into the message buffer
+	  (assuming sizeof( size_t ) is 4).
+	+ Updated the StaticTimer_t structure to ensure it matches the size of the
+	  Timer_t structure when the size of TaskFunction_t does not equal the size
+	  of void *.
+	+ Update various Xilinx demos to use 2018.1 version of the SDK tools.
+	+ Various updates to demo tasks to maintain test coverage.
+	+ FreeRTOS+UDP was removed in FreeRTOS V10.1.0 as it was replaced by
+	  FreeRTOS+TCP, which was brought into the main download in FreeRTOS
+	  V10.0.0.  FreeRTOS+TCP can be configured as a UDP only stack, and
+	  FreeRTOS+UDP does not contain the patches applied to FreeRTOS+TCP.
+
+	FreeRTOS+TCP Changes:
+
+	+ Multiple security improvements and fixes in packet parsing routines, DNS
+	  caching, and TCP sequence number and ID generation.
+	+ Disable NBNS and LLMNR by default.
+	+ Add TCP hang protection by default.
+
+	We thank Ori Karliner of Zimperium zLabs Team for reporting these issues.
+
+
+Changes between FreeRTOS V10.0.0 and FreeRTOS V10.0.1, released December 20 2017
+
+	+ Fix position of "#if defined( __cplusplus )" in stream_buffer.h.
+	+ Correct declarations of MPU_xQueuePeek() and MPU_xQueueSemaphoreTake() in
+	  mpu_prototypes.h.
+	+ Correct formatting in vTaskList() helper function when it prints the state
+	  of the currently executing task.
+	+ Introduce #error if stream_buffer.c is built without
+	  configUSE_TASK_NOTIFICATIONS set to 1.
+	+ Update FreeRTOS+TCP to V2.0.0
+		- Improve the formatting of text that displays the available netword
+		  interfaces when FreeRTOS+TCP is used on Windows with WinPCap.
+		- Introduce ipconfigSOCKET_HAS_USER_WAKE_CALLBACK option to enable a user
+		  definable callback to execute when data arrives on a socket.
+
+Changes between FreeRTOS V9.0.1 and FreeRTOS V10.0.0:
+
+	The FreeRTOS kernel is now MIT licensed: https://www.FreeRTOS.org/license
+
+	New Features and components:
+
+	+ Stream Buffers - see http://www.FreeRTOS.org/RTOS-stream-buffer-example.html
+	+ Message Buffers - see http://www.FreeRTOS.org//RTOS-message-buffer-example.html
+	+ Move FreeRTOS+TCP into the main repository, along with the basic Win32
+	  TCP demo FreeRTOS_Plus_TCP_Minimal_Windows_Simulator.
+
+	New ports or demos:
+
+	+ Added demo for TI SimpleLink CC3220 MCU.
+	+ Added MPU and non MPU projects for Microchip CEC and MEC 17xx and 51xx
+	  MCUs.
+	+ Added CORTEX_MPU_Static_Simulator_Keil_GCC demo to test static allocation
+	  in the MPU port.
+
+	Fixes or enhancements:
+
+	+ Cortex-M ports push additional register prior to calling
+	  vTaskSwitchContext to ensure 8-byte alignment is maintained.  Only
+	  important if a user defined tick hook function performs an operation that
+	  requires 8-byte alignment.
+	+ Optimisations to the implementation of the standard tickless idle mode on
+	  Cortex-M devices.
+	+ Improvements to the Win32 port including using higher priority threads.
+	+ Ensure interrupt stack alignment on PIC32 ports.
+	+ Updated GCC TriCore port to build with later compiler versions.
+	+ Update mpu_wrappers.c to support static allocation.
+	+ The uxNumberOfItems member of List_t is now volatile - solving an issue
+	  when the IAR compiler was used with maximum optimization.
+	+ Introduced configRECORD_STACK_HIGH_ADDRESS.  When set to 1 the stack start
+	  address is saved into each task's TCB (assuming stack grows down).
+	+ Introduced configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H to allow user defined
+	  functionality, and user defined initialisation, to be added to FreeRTOS's
+	  tasks.c source file.  When configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H is
+	  set to 1 a user provided header file called freertos_task_c_additions.h
+	  will be included at the bottom of tasks.c.  Functions defined in that
+	  header file can call freertos_tasks_c_additions_init(), which in turn
+	  calls a macro called FREERTOS_TASKS_C_ADDITIONS_INIT(), if it is defined.
+	  FREERTOS_TASKS_C_ADDITIONS_INIT() can be defined in FreeRTOSConfig.h.
+	+ Introduced configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( x ) which can be
+	  defined by a user in FreeRTOSConfig.h.  The macro is called before
+	  assessing whether to enter tickless idle mode or not.  If the macro sets
+	  x to zero then tickless idle mode will not be entered.  This allows users
+	  to abort tickless idle mode entry before the tickless idle function is
+	  even called - previously it was only possible to abort from within the
+	  tickless idle function itself.
+	+ Added configPRINTF(), which can be defined by users to allow all libraries
+	  to use the same print formatter.
+	+ Introduced configMAX() and configMIN() macros which default to standard
+	  max( x, y ) and min( x, y ) macro behaviour, but can be overridden if the
+	  application writer defines the same macros in FreeRTOSConfig.h.
+	+ Corrected the definition of StaticTask_t in the case where
+	  INCLUDE_xTaskAbortDelay is set to 1.
+	+ Introduced configTIMER_SERVICE_TASK_NAME and configIDLE_TASK_NAME, both of
+	  which can be defined to strings in FreeRTOSConfig.h to change the default
+	  names of the timer service and idle tasks respectively.
+	+ Only fill the stack of a newly created task with a known value if stack
+	  checking, or high water mark checking/viewing, is in use - removing the
+	  dependency on memset() in other cases.
+	+ Introduced xTaskCreateRestrictedStatic() so static allocation can be used
+	  with the MPU.
+	+ Ensure suspended tasks cannot be unsuspended by a received task
+	  notification.
+	+ Fix race condition in vTaskSetTimeOutState().
+	+ Updated trace recorder files to the latest version.
+
+Changes since FreeRTOS V9.0.0:
+
+	+ Priority dis-inheritance behaviour has been enhanced in the case where a
+	  task that attempted to take a mutex that was held by a lower priority task
+	  timed out before it was able to obtain the mutex (causing the task that
+	  holds the mutex to have its priority raised, then lowered again, in
+	  accordance with the priority inheritance protocol).
+	+ Split the overloaded xQueueGenericReceive() function into three separate
+	  dedicated functions.
+	+ Allow the default human readable text names given to the Idle and Timer
+	  tasks to be overridden by defining the configIDLE_TASK_NAME and
+	  configTIMER_SERVICE_TASK_NAME definitions respectively in FreeRTOSConfig.h.
+	+ Introduced configINITIAL_TICK_COUNT to allow the tick count to take a
+	  value of than than 0 when the system boots.  This can be useful for
+	  testing purposes - although setting configUSE_16_BIT_TICKS to 1 can also
+	  be used to test frequent tick overflows.
+	+ Ensure the Cortex-M SysTick count is cleared to zero before starting the
+	  first task.
+	+ Add configASSERT() into ARM Cortex-M ports to check the number of priority
+	  bit settings.
+	+ Clear the 'control' register before starting ARM Cortex-M4F ports in case
+	  the FPU is used before the scheduler is started.  This just saves a few
+	  bytes on the main stack as it prevents space being left for a later save
+	  of FPU registers.
+	+ Added xSemaphoreGetMutexHolderFromISR().
+	+ Corrected use of portNVIC_PENDSVSET to portNVIC_PENDSVSET_BIT in MPU ports.
+	+ Introduced configSTACK_DEPTH_TYPE to allow users to change the type used
+	  to specify the stack size when using xTaskCreate().  For historic reasons,
+	  when FreeRTOS was only used on small MCUs, the type was set to uint16_t,
+	  but that can be too restrictive when FreeRTOS is used on larger
+	  processors.  configSTACK_DEPTH_TYPE defaults to uint16_t.
+	  xTaskCreateStatic(), being a newer function, used a uint32_t.
+	+ Increase the priority of the Windows threads used by the Win32 port.  As
+	  all the threads run on the same core, and the threads run with very high
+	  priority, there is a risk that the host will become unresponsive, so also
+	  prevent the Windows port executing on single core hosts.
+
+Changes between FreeRTOS V9.0.0 and FreeRTOS V9.0.0rc2 released May 25 2016:
+
+	See http://www.FreeRTOS.org/FreeRTOS-V9.html
+
+	RTOS kernel updates:
+
+	+ The prototype of the new xTaskCreateStatic() API function was modified to
+	  remove a parameter and improve compatibility with other new
+	  "CreateStatic()" API functions.  The stack size parameter in
+	  xTaskCreateStatic() is now uint32_t, which changes the prototype of the
+	  callback functions.  See the following URL:
+	  http://www.freertos.org/xTaskCreateStatic.html
+	+ GCC ARM Cortex-A port:  Introduced the configUSE_TASK_FPU_SUPPORT
+	  constant.  When configUSE_TASK_FPU_SUPPORT is set to 2 every task is
+	  automatically given a floating point (FPU) context.
+	+ GCC ARM Cortex-A port:  It is now possible to automatically save and
+	  restore all floating point (FPU) registers on entry to each potentially
+	  nested interrupt by defining vApplicationFPUSafeIRQHandler() instead of
+	  vApplicationIRQHandler().
+	+ All ARM Cortex-M3/4F/7 ports:  Clear the least significant bit of the task
+	  entry address placed onto the stack of a task when the task is created for
+	  strict compliance with the ARM Cortex-M3/4/7 architecture documentation
+	  (no noticeable effect unless using the QMEU emulator).
+	+ Added GCC and Keil ARM Cortex-M4F MPU ports - previously the MPU was only
+	  supported on ARM Cortex-M3.
+	+ ARM Cortex-M3/4F MPU ports:  Update to fully support the FreeRTOS V9.0.0
+	  API (other than static object creation) and added the
+	  FreeRTOS/Demo/CORTEX_MPU_Simulator_Keil_GCC demo application to
+	  demonstrate how to use the updated MPU port.
+	+ All ARM Cortex-M3/4F/7 ports:  Add additional barrier instructions to the
+	  default low power tickless implementation.
+	+ All ARM Cortex-M0 ports:  Prevent an item being left on the stack of the
+	  first task that executes.
+	+ Win32 ports:  Reduce the amount of stack used and change the way Windows
+	  threads are deleted to increase the maximum execution time.
+	+ Add an ARM Cortex-M4F port for the MikroC compiler.  Ensure to read the
+	  documentation page for this port before use.
+	+ MPS430X IAR port:  Update to be compatible with the latest EW430 tools
+	  release.
+	+ IAR32 GCC port:  Correct vPortExitCritical() when
+	  configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY.
+	+ For consistency vTaskGetTaskInfo() now has the alias vTaskGetInfo(),
+	  xTaskGetTaskHandle() now has the alias xTaskGetHandle() and
+	  pcQueueGetQueueName() now has an alias pcQueueGetName().
+	+ Fix various errors in comments and compiler warnings.
+
+	Demo application updates:
+
+	+ Update Atmel Studio projects to use Atmel Studio 7.
+	+ Update Xilinx SDK projects to use the 2016.1 version of the SDK.
+	+ Remove dependency on legacy IO libraries from the PIC32 demos.
+	+ Move the Xilinx UltraScale Cortex-R5 demo into the main distribution.
+	+ Update the MSP432 libraries to the latest version.
+	+ Add Microchip CEC1302 (ARM Cortex-M4F) demos for GCC, Keil and MikroC
+	  compilers.
+	+ Move the Atmel SAMA5D2 demo into the main distribution.
+
+Changes between FreeRTOS V9.0.0rc1 and FreeRTOS V9.0.0rc2 (release candidate 2)
+released March 30 2016:
+
+	NOTE - See http://www.FreeRTOS.org/FreeRTOS-V9.html for details
+
+	+ The functions that create RTOS objects using static memory allocation have
+	  been simplified and will not revert to using dynamic allocation if a
+	  buffer is passed into a function as NULL.
+	+ Introduced the configSUPPORT_DYNAMIC_ALLOCATION configuration constant to
+	  allow a FreeRTOS application to be built without a heap even being being
+	  defined. The Win32 example located in the
+	  /FreeRTOS/demo/WIN32-MSVC-Static-Allocation-Only directory is provided as
+	  a reference for projects that do not include a FreeRTOS heap.
+	+ Minor run-time optimisations.
+	+ Two new low power tickless implementations that target Silicon Labs EFM32
+	  microcontrollers.
+	+ Addition of the xTimerGetPeriod() and xTimerGetExpireTime() API functions.
+
+Changes between FreeRTOS V8.2.3 and FreeRTOS V9.0.0rc1 (release candidate 1)
+released February 19 2016:
+
+	RTOS Kernel Updates:
+
+	+ Major new feature - tasks, semaphores, queues, timers and event groups can
+	  now be created using statically allocated memory, so without any calls to
+	  pvPortMalloc().
+	+ Major new features - Added the xTaskAbortDelay() API function which allows
+	  one task to force another task to immediately leave the Blocked state,
+	  even if the event the blocked task is waiting for has not occurred, or the
+	  blocked task's timeout has not expired.
+	+ Updates necessary to allow FreeRTOS to run on 64-bit architectures.
+	+ Added vApplicationDaemonTaskStartupHook() which executes when the RTOS
+	  daemon task (which used to be called the timer service task) starts
+	  running.  This is useful if the application includes initialisation code
+	  that would benefit from executing after the scheduler has been started.
+	+ Added the xTaskGetTaskHandle() API function, which obtains a task handle
+	  from the task's name.  xTaskGetTaskHandle() uses multiple string compare
+	  operations, so it is recommended that it is called only once per task.
+	  The handle returned by xTaskGetTaskHandle() can then be stored locally for
+	  later re-use.
+	+ Added the pcQueueGetQueueName() API function, which obtains the name of
+	  a queue from the queue's handle.
+	+ Tickless idling (for low power applications) can now also be used when
+	  configUSE_PREEMPTION is 0.
+	+ If one task deletes another task, then the stack and TCB of the deleted
+	  task is now freed immediately.  If a task deletes itself, then the stack
+	  and TCB of the deleted task are freed by the Idle task as before.
+	+ If a task notification is used to unblock a task from an ISR, but the
+	  xHigherPriorityTaskWoken parameter is not used, then pend a context switch
+	  that will then occur during the next tick interrupt.
+	+ Heap_1.c and Heap_2.c now use the configAPPLICATION_ALLOCATED_HEAP
+	  settings, which previously was only used by heap_4.c.
+	  configAPPLICATION_ALLOCATED_HEAP allows the application writer to declare
+	  the array that will be used as the FreeRTOS heap, and in-so-doing, place
+	  the heap at a specific memory location.
+	+ TaskStatus_t structures are used to obtain details of a task.
+	  TaskStatus_t now includes the bae address of the task's stack.
+	+ Added the vTaskGetTaskInfo() API function, which returns a TaskStatus_t
+	  structure that contains information about a single task.  Previously this
+	  information could only be obtained for all the tasks at once, as an array
+	  of TaskStatus_t structures.
+	+ Added the uxSemaphoreGetCount() API function.
+	+ Replicate previous Cortex-M4F and Cortex-M7 optimisations in some
+	  Cortex-M3 port layers.
+
+	Demo Application Updates:
+
+	Further demo applications will be added prior to the final FreeRTOS V9
+	release.
+
+	+ Updated SAM4L Atmel Studio project to use Atmel Studio 7.
+	+ Added ARM Cortex-A53 64-bit port.
+	+ Added a port and demo for the ARM Cortex-A53 64-bit cores on the Xilinx
+	  Ultrascale MPSoC.
+	+ Added Cortex-M7 SAME70 GCC demo.
+	+ Added EFM32 Giant and Wonder Gecko demos.
+
+
+Changes between V8.2.2 and V8.2.3 released October 16, 2015
+
+	RTOS kernel updates:
+
+	+ Fix bug identified in a modification made in V8.2.2 to the software timer
+	  code that allows tickless low power applications to sleep indefinitely
+	  when software timers are used.
+	+ Simplify and improve efficiency of stack overflow checking.
+	+ Add xTaskNotifyStateClear() API function.
+	+ New IAR and GCC Cortex-R ports for microprocessors that do not use an ARM
+	  generic interrupt controller (GIC).
+	+ New PIC32MEC14xx port.
+	+ Add support for PIC32MZ EF parts (with floating point) into the PIC32MZ
+	  port.
+	+ Zynq7000 port layer now declares the functions that setup and clear the
+	  tick interrupt as weak symbols so they can be overridden by the
+	  application, and uses a global XScuGic object so the same object can be
+	  used by the application code.
+	+ Introduced configUSE_TASK_FPU_SUPPORT, although the PIC32MZ EF port is
+	  currently the only port that uses it.
+	+ Updates to RL78 and 78K0 IAR port layers to improve support for
+	  combinations of memory models.
+	+ Minor updates to heap_5.c to remove compiler warnings generated by some
+	  compilers.
+	+ License simplifications.  See /FreeRTOS/License/license.txt in the
+	  official distribution.
+
+	FreeRTOS+ updates:
+
+	+ Update directory names to use WolfSSL instead of CyaSSL, inline with
+	  WolfSSL's re-branding.
+	+ Update to latest WolfSSL code.
+	+ Update to latest FreeRTOS+Trace recorder code.
+	+ Add in the FreeRTOS+Trace recorder library required for streaming trace.
+
+	Demo application changes:
+
+	+ Add demo applications for Renesas RZ/T (Cortex-R), PIC32MZ EF (PIC32 with
+	  floating point hardware), PIC32MEC14xx, RX71M, RX113 and RX231.
+	+ General tidy up of spelling and compiler warnings.
+
+
+Changes between V8.2.1 and V8.2.2 released August 12, 2015
+
+	RTOS kernel updates:
+
+	+ Added Intel IA32/x86 32-bit port.
+	+ General maintenance.
+	+ PRIVILEGED_FUNCTION and PRIVILEGED_DATA macros, which are used in memory
+	  protected systems, have been added to the newer event group and software
+	  timer functions.
+	+ Add the errno definitions used by FreeRTOS+ components into projdefs.h.
+	+ Remove the restriction that prevented tick-less idle implementations
+	  waiting indefinitely when software timers were used in the same
+	  application.
+	+ Introduce xTaskNotifyAndQueryFromISR() as the interrupt safe version of
+	  xTaskNotifyAndQuery().
+	+ Add additional NOPs to the MSP430X port layers to ensure strict compliance
+	  with the hardware documentation.
+	+ Microblaze port: Added option for port optimised task selection.
+	+ Microblaze port: Previously tasks inherited the exception enable state
+	  at the time the task was created.  Now all tasks are created with
+	  exceptions enabled if the Microblaze design supports exceptions.
+	+ Windows port: Add additional safe guards to ensure the correct start up
+	  sequence and thread switching timing.
+	+ Windows port: Improve the implementation of the port optimised task
+	  selection assembly code.
+	+ Update heap_4 and heap_5 to allow use on 64-bit processors.
+	+ Simplify the code that creates a queue.
+	+ General improved tick-less idle behaviour.
+	+ Ensure none of the variables in the common kernel files are initialised to
+	  anything other than zero.
+	+ Correct calculation of xHeapStructSize in heap_4 and heap_5.
+
+	Demo application updates:
+
+	+ Added demo project for the new IA32/x86 port that targets the Galileo
+	  hardware.
+	+ Added MSP430FR5969 demos (previously provided as a separate download).
+	+ Added FreeRTOS BSP repository for automatic creation of FreeRTOS
+	  applications in the Xilinx SDK.
+	+ Added Atmel Studio / GCC project for the SAMV71 (ARM Cortex-M7)
+	+ Update Xilinx SDK projects to use version 2015.2 of the SDK.
+	+ Remove Microblaze demos that were using obsolete tools.
+	+ Add MSP43FR5969 IAR and CCS demos.
+
+	FreeRTOS+ Updates:
+
+	+ Updated FreeRTOS+Trace recorder library, which requires an update to the
+	  FreeRTOS+Trace application.
+	+ Added Reliance Edge source code and demo application.  Reliance edge is
+	  a fail safe transactional file system ideal for applications that require
+	  file storage, and especially when high reliability is essential.
+	+ Introduce configAPPLICATION_PROVIDES_cOutputBuffer to allow FreeRTOS+CLI
+	  users to place the output buffer at a fixed memory address.
+	+ Improve the NetworkInterface.c file provided for the Windows port of
+	  FreeRTOS+UDP.
+
+Changes between V8.2.0 and V8.2.1 released 24th March 2015.
+
+	RTOS kernel updates:
+
+	+ Added user definable and flexible thread local storage facility.
+	+ Added vTimerSetTimerID() API function to complement the pvTimerGetTimerID()
+	  function to allow the timer's ID to be used as timer local storage.
+	+ Fixed a potential issue related to the use of queue sets from an ISR.
+	+ Some updates to the Xilinx Microblaze GCC port.
+	+ Added ARM Cortex-M4F port for Texas Instruments Code Composer Studio.
+	+ Added ARM Cortex-M7 r0p1 port layer for IAR, GCC and Keil which contains a
+	  minor errata work around.  All other ARM Cortex-M7 core revisions should
+	  use the ARM Cortex-M4F port.
+	+ Exclude the whole of croutine.c if configUSE_CO_ROUTINES is set to 0.
+	+ Change some data types from uint32_t to size_t in preparation for 64-bit
+	  Windows port.
+	+ Update the PIC32 port to remove deprecation warnings output by the latest
+	  XC32 compilers.
+
+	Demo application updates:
+
+	+ Added demo application for TI's ARM Cortex-M4F based MSP432
+	  microcontroller using IAR, Keil and CCS compilers.
+	+ Added demo application for STM32F ARM Cortex-M7 based microcontroller
+	  using IAR and Keil.
+	+ Added demo application for Atmel SAMV71 ARM Cortex-M7 based
+	  microcontroller using IAR and Keil.
+	+ Added Microblaze demo that uses the 2014.4 version of the Xilinx SDK and
+	  runs on the KC705 evaluation board (Kintex FPGA).
+
+Changes between V8.1.2 and V8.2.0 released 16th January 2015
+
+	Changes between release candidate 1 and the official release are restricted
+	to maintenance only.
+
+	Significant RTOS kernel updates:
+
+	+ MAJOR NEW FEATURE!  Task notifications.  Please see the following URL for
+	  details: http://www.FreeRTOS.org/RTOS-task-notifications.html
+	+ NEW HEADER FILE REQUIRED!  Obsolete definitions have been separated into
+	  a new header file called FreeRTOS/Source/include/deprecated_definitions.h.
+	  This header file must be present to build.  Note some of the obsolete
+	  definitions are still used by very old demo application projects.
+
+	Other RTOS kernel updates:
+
+	+ Made xSemaphoreGiveFromISR() a function rather than a macro that calls
+	  xQueueGenericSendFromISR().  This allows for major performance
+	  enhancements at the expense of some additional code size if both functions
+	  are used in the same application.  NOTE:  In most uses cases such use of
+	  a semaphore can now be replaced with a task notification which is smaller
+	  and faster still.
+	+ The TCB is now always allocated such that the task's stack grows away from
+	  the TCB (improves debugging of stack overflows as the overflow will not
+	  overwrite the task's name).
+	+ GCC, IAR and Keil Cortex-M4F ports now use more inlining (performance
+	  enhancements at the cost of a little additional code space).
+	+ Queues are now allocated with a single call to pvPortMalloc() which
+	  allocates both the queue structure and the queue storage area.
+	+ Introduced a new critical section macro for reading the tick count that
+	  defines away to nothing in cases where the width of the tick allows the
+	  tick count to be read atomically (performance benefits - especially when
+	  optimisation is on).
+	+ Introduced configAPPLICATION_ALLOCATED_HEAP in heap_4.c to allow the
+	  application writer to provide their own heap array - and in so doing
+	  control the location of the heap.
+	+ Introduced configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES which, when set, will
+	  include known values in both list and list item structures.  The values
+	  are intended to assist debugging.  If the values get overwritten then it
+	  is likely application code has written over RAM used by the kernel.
+	+ configASSERT()s in all Cortex-M ports used to test the lowest 5 bits of
+	  the interrupt control register to detect taskENTER_CRITICAL() being called
+	  from an interrupt.  This has been changed to test all 8 bits.
+	+ Introduced uxTaskPriorityGetFromISR().
+	+ Microblze V8 port now tests XPAR_MICROBLAZE_0_USE_FPU for inequality to 0
+	  rather than equality to 1, and 2 and 3 are also valid values.
+	+ Cortex-A5 GIC-less port no longer passes the address of the interrupting
+	  peripheral into the interrupt handler.
+	+ Fix an issue in FreeRTOS-MPU where an attempt was made to free the stack
+	  belonging to a task when the task was deleted, even when the stack was
+	  allocated statically.
+	+ Utility (helper) functions that format task statistic information into
+	  human readable tables now pad task names with spaces to ensure columns
+	  line up correctly even where task name lengths vary greatly.
+	+ Update FreeRTOS+Trace recorder library to version 2.7.0.
+
+	Demo application updates:
+
+	+ Added two new standard demo task sets:  IntSemTest and TaskNotify.
+	+ Added port and demo application for Atmel SAMA5D4 Cortex-A5 MPU.
+	+ Added demo application for Altera Cyclone V Cortex-A9 MPU.
+	+ Updated Zynq demo to use version 2014.4 of Xilinx's SDK and added in
+	  demo tasks for new RTOS features.
+	+ Updated Atmel SAM4E and SAM4S demos to include a lot of additional test
+	  and demo tasks.
+	+ Fixed a corner case issue in Atmel SAM4L low power tickless
+	  implementation, and added button interrupt handling.
+	+ Make the interrupt queue tests more tolerant to heave CPU loads.
+	+ Updated MSVC FreeRTOS simulator demo to include the latest standard test
+	  and demo tasks.
+	+ Updated MingW/Eclipse FreeRTOS simulator demo to match the FreeRTOS MSVC
+	  simulator demo.
+	+ Updated all demos that use FreeRTOS+Trace to work with the latest trace
+	  recorder code.
+
+
+Changes between V8.1.1 and V8.1.2 released September 2nd 2014
+
+	Move the defaulting of configUSE_PORT_OPTIMISED_TASK_SELECTION into the
+	individual port layers where necessary so it does not affect ports that do
+	not support the definition.
+
+Changes between V8.1.0 and V8.1.1 released August 29th 2014
+
+	By popular requests - a minor patch to V8.1.0 to re-instate the ability to
+	give a mutex type semaphore (with priority inheritance) from an interrupt
+	handler.
+
+Changes between V8.0.1 and V8.1.0 released August 26th 2014
+
+	FreeRTOS scheduler, kernel, demo and test updates:
+
+	+ Improved the priority inheritance algorithms to assist integration with
+	  off the shelf middleware that may hold multiple mutexes simultaneously.
+	+ Introduce heap_5.c, which is similar to heap_4.c but allows the heap to
+	  span multiple non-contiguous memory regions.
+	+ Updated all Cortex-A9 ports to help trap a couple of common usage errors -
+	  the first being when a task incorrectly attempts to exit its implementing
+	  function and the second being when a non interrupt safe API function is
+	  called from an interrupt.
+	+ Update all Cortex-A9 ports to remove obsolete mode switches prior to
+	  restoring a task context.
+	+ configUSE_PORT_OPTIMISED_TASK_SELECTION now defaults to 1 instead of 0.
+	+ Update all Cortex-M3/4F ports to trap a non interrupt safe API function
+	  being called from an interrupt handler.
+	+ Simplify the alignment checks in heap_4.c.
+	+ Update the MSVC Windows simulator demo to use heap_5.c in place of
+	  heap_4.c to ensure end users have an example to refer to.
+	+ Updated standard demo test code to test the new priority inheritance
+	  algorithms.
+	+ Updated the standard demo tasks to make use of stdint and the FreeRTOS
+	  specific typedefs that were introduced in FreeRTOS V8.0.0.
+	+ Introduce the pdMS_TO_TICKS() macro as a more user friendly and intuitive
+	  alternative to pdTICKS_PER_MS - both of which can be used to convert a
+	  time specified in milliseconds to a time specified in RTOS ticks.
+	+ Fix a bug in the Tasking compiler's Cortex-M port that resulted in an
+	  incorrect value being written to the basepri register.  This only effects
+	  users of the Tasking compiler.
+	+ Update the Zynq demo to use version 2014.2 of the SDK and add in an lwIP
+	  example that demonstrates lwIP being used with both its raw and sockets
+	  interfaces.
+	+ Updated the CCS Cortex-R4 port to enable it to be built with the latest
+	  CCS compiler.
+
+	New ports and demo applications:
+
+	+ Two Renesas RX64M ports (RXv2 core) and demos introduced, one for the GCC
+	  compiler and one for the Renesas compiler.  Both demos use e2 studio.
+	+ Generic IAR Cortex-A5 port (without any reliance on a GIC) introduced.
+	  The new port is demonstrated on an Atmel SAMA5D3 XPlained board.
+
+	FreeRTOS+ component updates:
+
+	+ Update CyaSSL to the latest version.
+	+ Updated the FreeRTOS+ components supplied directly by Real Time Engineers
+	  Ltd. to make use of stdint and the FreeRTOS specific typedefs that were
+	  introduced in FreeRTOS V8.0.0.
+	+ Rework and simplify the FreeRTOS+FAT SL RAM disk driver.
+
+	Miscellaneous updates and maintenance:
+
+	+ Update the IAR and DS-5/ARM RZ demos to target the official RZ RSK
+	  hardware in place of the previously targeted Renesas internal (not
+	  publicly available) hardware.
+	+ Various other maintenance tasks.
+
+
+Changes between V8.0.0 and V8.0.1 released 2nd May 2014
+
+	+ Minor fixes to the event group functionality that was released in V8.0.0.
+	  The 'clear bits from ISR' functionality is now implemented using a
+	  deferred interrupt callback instead of a function, and the 'wait bits' and
+	  'task sync' functions now correctly clear internal control bits before
+	  returning a value in every possible path through the respective functions.
+	+ Ensure the updating of internal control data is protected by a critical
+	  section after a task is deleted or suspended.
+	+ Minor fixes to FreeRTOS+FAT SL - namely seeking beyond the end of a file
+	  when the offset was not a multiple of the sector size.
+	+ Ensure Cortex-A9 system registers are only ever accessed as 32-bit values,
+	  even when only the lest significant byte of the register is implemented.
+
+	Other updates:
+
+	+ Updated the XMC4200 IAR project so it links with version 7.x of the IAR
+	  tools.
+	+ Add RL78L1C demo.
+	+ Add pcTimerGetName() API function.
+	+ Call _reclaim_reent() when a task is deleted if configUSE_NEWLIB_REENTRANT
+	  is defined.
+
+Changes between V7.6.0 and V8.0.0 released 19th Feb 2014
+
+	http://www.freertos.org/upgrading-to-FreeRTOS-V8.html
+
+	FreeRTOS V8.x.x is a drop-in compatible replacement for FreeRTOS V7.x.x,
+	although a change to the type used to reference character strings may result
+	in application code generating a few (easily clearable) compiler warnings
+	after the upgrade, and an updated typedef naming convention means use of the
+	old typedef names is now discouraged.
+	See http://www.freertos.org/upgrading-to-FreeRTOS-V8.html for full
+	information.
+
+	New features and functionality:
+
+	+ Event groups - see http://www.freertos.org/FreeRTOS-Event-Groups.html
+	+ Centralised deferred interrupt processing - see
+	  http://www.freertos.org/xTimerPendFunctionCallFromISR.html
+
+	Other updates:
+
+	+ Previously, when a task left the Blocked state, a context switch was
+	  performed if the priority of the unblocked task was greater than or equal
+	  to the priority of the Running task.  Now a context switch is only
+	  performed if the priority of the unblocked task is greater than the
+	  priority of the Running task.
+	+ New low power tickless demonstration project that targets the ST STM32L
+	  microcontroller - see
+	  http://www.freertos.org/STM32L-discovery-low-power-tickless-RTOS-demo.html
+	+ Add xPortGetMinimumEverFreeHeapSize() to heap_4.c.
+	+ Small change to the tickless low power implementation on the SAM4L to
+	  ensure the alarm value (compare match value) cannot be set to zero when a
+	  tickless period is exited due to an interrupt originating from a source
+	  other than the RTOS tick.
+	+ Update the GCC/Eclipse Win32 simulator demo to make better use of Eclipse
+	  resource filters and match the functionality of the MSVC equivalent.
+	+ xTaskIsTaskSuspended() is no longer a public function.  Use
+	  eTaskGetState() in its place.
+	+ Improved trace macros, including tracing of heap usage.
+	+ Remove one level of indirection when accepting interrupts on the PIC32MZ.
+	+ Add Cortex-A9 GCC port layer.
+	+ Add Xilinx Zynq demo application.
+
+
+Changes between V7.5.3 and V7.6.0 released 18th November 2013
+
+	V7.6.0 changes some behaviour when the co-operative scheduler is used (when
+	configUSE_PREEMPTION is set to 0).  It is important to note that the
+	behaviour of the pre-emptive scheduler is unchanged - the following
+	description only applies when configUSE_PREEMPTION is set to 0:
+
+	WHEN configUSE_PREEMPTION IS SET TO 0 (which is in a small minority of
+	cases) a context switch will now only occur when a task places itself into
+	the Blocked state, or explicitly calls taskYIELD().  This differs from
+	previous versions, where a context switch would also occur when implicitly
+	moving a higher priority task out of the Blocked state.  For example,
+	previously, WHEN PREEMPTION WAS TURNED OFF, if task A unblocks task B by
+	writing to a queue, then the scheduler would switch to the higher priority
+	task.  Now, WHEN PREEMPTION IS TURNED OFF, if task A unblocks task B by
+	writing to a queue, task B will not start running until task A enters the
+	Blocked state or task A calls taskYIELD().  [If configUSE_PREEMPTION is not
+	set to 0, so the normal pre-emptive scheduler is being used, then task B
+	will start running immediately that it is moved out of the Blocked state].
+
+	Other changes:
+
+	+ Added a port layer and a demo project for the new PIC32MZ architecture.
+	+ Update the PIC32MX port layer to re-introduce some ehb instructions that
+	  were previously removed, add the ability to catch interrupt stack
+	  overflows (previously only task stack overflows were trapped), and also
+	  add the ability to catch an application task incorrectly attempting to
+	  return from its implementing function.
+	+ Make dramatic improvements to the performance of the Win32 simulator port
+	  layer.
+	+ Ensure tasks that are blocked indefinitely report their state as Blocked
+	  instead of Suspended.
+	+ Slight improvement to the Cortex-M4F port layers where previously one
+	  register was inadvertently being saved twice.
+	+ Introduce the xSemaphoreCreateBinary() API function to ensure consistency
+	  in the semantics of how each semaphore type is created.  It is no longer
+	  recommended to use vSemaphoreCreateBinary() (the version prefixed with a
+	  'v'), although it will remain in the code for backward compatibility.
+	+ Update the Cortex-M0 port layers to allow the scheduler to be started
+	  without using the SVC handler.
+	+ Added a build configuration to the PIC32MX MPLAB X demo project that
+	  targets the PIC32 USB II starter kit.  Previously all the build
+	  configurations required the Explorer 16 hardware.
+	+ Some of the standard demo tasks have been updated to ensure they execute
+	  correctly with the updated co-operative scheduling behaviour.
+	+ Added comprehensive demo for the Atmel SAM4E, including use of
+	  FreeRTOS+UDP, FreeRTOS+FAT SL and FreeRTOS+CLI.
+
+	FreeRTOS+ Changes:
+
+	+ Minor maintenance on FreeRTOS+UDP.
+
+Changes between V7.5.2 and V7.5.3 released October 14 2013
+
+	Kernel changes:
+
+	+ Prior to V7.5.x yields requested from the tick hook would occur in the
+	  same tick interrupt - revert to that original behaviour.
+	+ New API function uxQueueSpacesAvailable().
+	+ Introduced the prvTaskExitError() function to Cortex-M0, Cortex-M3/4
+	  and Cortex-M4F ports.  prvTaskExitError() is used to trap tasks that
+	  attempt to return from their implementing functions (tasks should call
+	  vTaskDelete( NULL ); if they want to exit).
+	+ The Cortex-M0 version of portSET_INTERRUPT_MASK_FROM_ISR and
+	  portCLEAR_INTERRUPT_MASK_FROM_ISR are now fully nestable.
+	+ Improved behaviour and robustness of the default Cortex-M tickless idle
+	  behaviour.
+	+ Add workaround for silicon errata PMU_CM001 in Infineon XMC4000 devices to
+	  all Cortex-M4F ports.
+	+ Add Cortex-M0 port for Keil.
+	+ Updated Cortus port.
+	+ Ensure _impure_ptr is initialised before the scheduler is started.
+	  Previously it was not set until the first context switch.
+
+	FreeRTOS+ changes:
+
+	+ Update FreeRTOS+UDP to V1.0.1 - including direct integration of the
+	  FreeRTOS+Nabto task, improvements to the DHCP behaviour, and a correction
+	  to the test that prevents the network event hook being called on the first
+	  network down event.  The FreeRTOS+UDP change history is maintained
+	  separately.
+	+ Correct the __NVIC_PRIO_BITS setting in the LPC18xx.h header files
+	  provided in the NXP CMSIS library, then update the interrupts used by the
+	  LPC18xx demos accordingly.
+	+ Replace double quotes (") with single quotes (') in FreeRTOS+CLI help
+	  strings to ensure the strings can be used with the JSON descriptions used
+	  in the FreeRTOS+Nabto demos.
+
+	Demo and miscellaneous changes:
+
+	+ Added demo for the Atmel SAMD20 Cortex-M0+.  The demo includes
+	  FreeRTOS+CLI
+	+ Added a demo for the Infineon Cortex-M0 that can be built with the IAR
+	  Keil and GCC tools.
+	+ Updated the Infineon XMC4000 demos for IAR, Keil, GCC and Tasking tools,
+	  with additional build configurations to directly support the XMC4200 and
+	  XMC4400 devices, in addition to the previously supported XMC4500.
+	+ Updated the demo application.
+	+ Added additional trace macros traceMALLOC and traceFREE to track heap
+	  usage.
+
+Changes between V7.5.0 and V7.5.2 released July 24 2013
+
+	V7.5.2 makes the new Cortex-M vPortCheckInterruptPriority() function
+	compatible with the STM32 standard peripheral driver library, and adds
+	an extra critical section to the default low power tickless mode
+	implementation.  Only users of the STM32 peripheral library or the default
+	tickless implementation need update from version 7.5.0.
+
+Changes between V7.4.2 and V7.5.0 released July 19 2013
+
+	V7.5.0 is a major upgrade that includes multiple scheduling and efficiency
+	improvements, and some new API functions.
+
+	Compatibility information for FreeRTOS users:
+	  FreeRTOS V7.5.0 is backward compatible with FreeRTOS V7.4.0 with one
+	  exception; the vTaskList() and vTaskGetRunTimeStats() functions are now
+	  considered legacy, having been replaced by the single uxTaskGetSystemState()
+	  function.  configUSE_STATS_FORMATTING_FUNCTIONS must be set to 1 in
+	  FreeRTOSConfig.h for vTaskList() and vTaskGetRunTimeStats() to be
+	  available.
+
+	Compatibility information for FreeRTOS port writers:
+	  vTaskIncrementTick() is now called xTaskIncrementTick() (because it now
+	  returns a value).
+
+	Headline changes:
+
+	+ Multiple scheduling and efficiency improvements.
+	+ Core kernel files now pass PC-Lint V8 static checking without outputting
+	  any warnings (information on the test conditions will follow).
+
+	New API functions:
+
+	+ uxTaskGetSystemState() http://www.freertos.org/uxTaskGetSystemState.html
+	+ xQueueOverwrite() http://www.freertos.org/xQueueOverwrite.html
+	+ xQueueOverwriteFromISR()
+	+ xQueuePeekFromISR()
+
+	The following ports and demos, which were previously available separately,
+	are now incorporated into the main FreeRTOS zip file download:
+
+	+ ARM Cortex-A9 IAR
+	+ ARM Cortex-A9 ARM compiler
+	+ Renesas RZ
+	+ Microsemi SmartFusion2
+
+	New FreeRTOSConfig.h settings
+	http://shop.freertos.org/FreeRTOS_API_and_Configuration_Reference_s/1822.htm
+
+	+ configUSE_TIME_SLICING
+	+ configUSE_NEWLIB_REENTRANT
+	+ configUSE_STATS_FORMATTING_FUNCTIONS
+	+ configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS
+
+	Other changes:
+
+	+ (MPU port only) The configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS
+	  options provides a mechanism that allows application writers to execute
+	  certain functions in privileged mode even when a task is running in user
+	  mode.
+	+ Ports that support interrupt nesting now include a configASSERT() that
+	  will trigger if an interrupt safe FreeRTOS function is called from an
+	  interrupt that has a priority designated as above the maximum system/API
+	  call interrupt priority.
+	+ The included FreeRTOS+Trace recorder code has been updated to the latest
+	  version, and the demo applications that use the trace recorder code have
+	  been updated accordingly.
+	+ The FreeRTOS Windows Simulator (MSVC version only) has been updated to
+	  include a new basic 'blinky' build option in addition to the original
+	  comprehensive build option.
+	+ Improve RAM usage efficiency of heap_4.c and heap_2.c.
+	+ Prevent heap_4.c from attempting to free memory blocks that were not
+	  allocated by heap_4.c, or have already been freed.
+	+ As FreeRTOS now comes with FreeRTOS+FAT SL (donated by HCC) the Chan FATfs
+	  files have been removed from FreeRTOS/Demo/Common.
+	+ Fix build error when R4 port is build in co-operative mode.
+	+ Multiple port and demo application maintenance activities.
+
+Changes between V7.4.1 and V7.4.2 released May 1 2013
+
+	NOTE: There are no changes in the FreeRTOS kernel between V7.4.1 and V7.4.2
+
+	+ Added FreeRTOS+FAT SL source code and demo project.  The demo project
+	  runs in the FreeRTOS Windows simulator for easy and hardware independent
+	  experimentation and evaluation.  See http://www.FreeRTOS.org/fat_sl
+
+Changes between V7.4.0 and V7.4.1 released April 18 2013
+
+	+ To ensure strict conformance with the spec and ensure compatibility with
+	  future chips data and instruction barrier instructions have been added to
+	  the yield macros of Cortex-M and Cortex-R port layers.  For efficiency
+	  the Cortex-M port layer "yield" and "yield" from ISR are now implemented
+	  separately as the barrier instructions are not required in the ISR case.
+	+ Added FreeRTOS+UDP into main download.
+	+ Reorganised the FreeRTOS+ directory so it now matches the FreeRTOS
+	  directory with Source and Demo subdirectories.
+	+ Implemented the Berkeley sockets select() function in FreeRTOS+UDP.
+	+ Changed (unsigned) casting in calls to standard library functions with
+	  (size_t) casting.
+	+ Added the Atmel SAM4L and Renesas RX100 demos that demonstrates the
+	  tickless (tick suppression) low power FreeRTOS features.
+	+ Add a new RL78 IAR demo that targets numerous new RL78 chips and
+	  evaluation boards.
+	+ Adjusted stack alignment on RX200 ports to ensure an assert was not
+	  falsely triggered when configASSERT() is defined.
+	+ Updated the Cortex_M4F_Infineon_XMC4500_IAR demo to build with the latest
+	  version of EWARM.
+	+ Corrected header comments in the het.c and het.h files (RM48/TMS570 demo).
+
+
+Changes between V7.3.0 and V7.4.0 released February 20 2013
+
+	+ New feature:  Queue sets.  See:
+	  http://www.FreeRTOS.org/Pend-on-multiple-rtos-objects.html
+	+ Overhauled the default tickless idle mode implementation provided with the
+	  ARM Cortex-M3 port layers.
+	+ Enhanced tickless support in the core kernel code with the introduction of
+	  the configEXPECTED_IDLE_TIME_BEFORE_SLEEP macro and the
+	  eTaskConfirmSleepModeStatus() function.
+	+ Added the QueueSet.c common demo/test file.  Several demo applications
+	  have been updated to use the new demo/test tasks.
+	+ Removed reliance on the PLIB libraries from the MPLAB PIC32 port layer and
+	  demo applications.
+	+ Added the FreeRTOS+Trace recorder code to the MSVC Win32 demo.
+	+ Renamed eTaskStateGet() to eTaskGetState() for consistency, and added a
+	  pre-processor macro for backward compatibility with the previous name.
+	+ Updated functions implemented in the core queue.c source file to allow
+	  queue.h to be included from the .c file directly (this prevents compiler
+	  warnings that were generated by some compilers).
+	+ Updated the CCS Cortex-R4 port layer to replace the CLZ assembler function
+	  with the CLZ compiler intrinsic that is provided by the latest versions of
+	  the CCS ARM compiler.
+	+ Updated all heap_x.c implementations to replace the structure that was
+	  used to ensure the start of the heap was aligned with a more portable
+	  direct C code implementation.
+	+ Added support for PIC24 devices that include EDS.
+	+ Minor optimisations to the PIC32 port layer.
+	+ Minor changes to tasks.c that allow the state viewer plug-ins to display
+	  additional information.
+	+ Bug fix:  Update prvProcessReceivedCommands() in timers.c to remove an
+	  issue that could occur if the priority of the timer daemon task was set
+	  below the priority of tasks that used timer services.
+	+ Update the FreeRTOS+Trace recorder code to the latest version.
+
+Changes between V7.2.0 and V7.3.0 released October 31 2012
+
+	+ Added ability to override the default scheduler task selection mechanism
+	  with implementations that make use of architecture specific instructions.
+	+ Added ability to suppress tick interrupts during idle time, and in so
+	  doing, provide the ability to make use of architecture specific low power
+	  functionality.
+	+ Added the portSUPPRESS_TICKS_AND_SLEEP() macro and vTaskStepTick() helper
+	  function.
+	+ Added the configSYSTICK_CLOCK_HZ configuration constant.
+	+ Reworked the Cortex-M3 and Cortex-M4F port layers for GCC, Keil and IAR to
+	  directly support basic power saving functionality.
+	+ Added hooks to allow basic power saving to be augmented in the application
+	  by making use of chip specific functionality.
+	+ Minor change to allow mutex type semaphores to be used from interrupts
+	  (which would not be a normal usage model for a mutex).
+	+ Change the behaviour of the interrupt safe interrupt mask save and restore
+	  macros in the Cortex-M ports.  The save macro now returns the previous
+	  mask value.  The restore macro now uses the previous mask value.  These
+	  changes are not necessary for the kernel's own implementation, and are
+	  made purely because the macros were being used by application writers.
+	+ Added eTaskStateGet() API function.
+	+ Added port specific optimisations to the PIC32 port layer, and updated the
+	  PIC32 demo applications to make use of this new feature.
+	+ Added port specific optimisations to the Win32 simulator port.
+	+ Added new ports and demo applications for the TI Hercules RM48 and TMS570
+	  safety microcontrollers.
+	+ Added SAM3 demos targeting the ATSAM3S-EK2 and ATSAM3X-EK evaluation
+	  boards.
+	+ Updated the PIC32 MPLAB X project to manually set the compiler include
+	  paths instead of using the IDE entry box following reports that the
+	  include paths were somehow being deleted.
+	+ Improved character handling in FreeRTOS+CLI.
+
+Changes between V7.1.1 and V7.2.0 released 14 August 2012
+
+	FreeRTOS V7.2.0 is backward compatible with FreeRTOS V7.1.2.
+
+	+ Added a FreeRTOS+ sub-directory.  The directory contains some FreeRTOS+
+	  source code, and example projects that use the FreeRTOS Win32 simulator.
+	+ Added a new example heap allocation implementation (heap_4.c) that
+	  includes memory block coalescence.
+	+ Added a demo that targets the Atmel SAM4S Cortex-M4 based microcontroller.
+	  The demo is preconfigured to build using the free Atmel Studio 6 IDE and
+	  GCC compiler.
+	+ Added xSemaphoreTakeFromISR() implementation.
+	+ The last parameter in ISR safe FreeRTOS queue and semaphore functions
+	  (xHigherPriorityTaskWoken) is now optional and can be set to NULL if it
+	  is not required.
+	+ Update the IAR and MSP430X ports to clear all lower power mode bits before
+	  exiting the tick interrupt [bug fix].
+	+ Allow xQueueReset() to be used, even when the queues event lists are not
+	  empty.
+	+ Added a vQueueDelete() handler for the FreeRTOS MPU port (this was
+	  previously missing).
+	+ Updated the vPortSVCHandler() functions in the FreeRTOS MPU port layer to
+	  ensure it compiles with the latest ARM GCC compilers from Linaro.
+	+ Updated the prvReadGP() function in the NIOS II port to ensure the compiler
+	  can choose any register for the functions parameter (required at high
+	  compiler optimisation levels).
+	+ Add #error macros into the Keil and IAR Cortex-M ports to ensure they
+	  cannot be built if the user has set configMAX_SYSCALL_INTERRUPT_PRIORITY
+	  to 0.
+	+ Added comments in the FreeRTOSConfig.h files associated with Cortex-M3 and
+	  Cortex-M4 demos stating that the configMAX_SYSCALL_INTERRUPT_PRIORITY
+	  parameter must not be set to 0.
+	+ Introduce new INCLUDE_xQueueGetMutexHolder configuration constant
+	  (defaulted to 0).
+	+ Added two new list handling macros - for internal use only in upcoming new
+	  products.
+	+ Removed all mention of the legacy vTaskStartTrace and ulTaskEndTrace
+	  macros.  FreeRTOS+Trace supersedes the legacy trace.
+	+ Added a configASSERT() into the vPortFree() function in heap_1.c as it is
+	  invalid for the function to be called.
+	+ Made the xRxLock and xTxLock members of the queue structure volatile.
+	  This is probably not necessary, and is included as a precautionary
+	  measure.
+	+ Modify the assert() that checks to see if the priority passed into an
+	  xTaskCreate() function is within valid bounds to permit the assert to be
+	  used in the FreeRTOS MPU port.
+	+ The software timer service (daemon) task is now created in a way that
+	  to ensure compatibility with FreeRTOS MPU.
+
+Changes between V7.1.0 and V7.1.1 released May 1 2012
+
+	New ports:
+
+	The following ports are brand new:
+	+ Cortex-M3 Tasking
+
+	The following ports have been available as separate downloads for a number
+	of months, but are now included in the main FreeRTOS download.
+	+ Cortex-M0 IAR
+	+ Cortex-M0 GCC
+	+ Cortex-M4F GCC (with full floating point support)
+
+
+	New demos:
+
+	The following demos are brand new:
+	+ Renesas RX63N RDK (Renesas compiler)
+
+	The following demos have been available as separate downloads for a number
+	of months, but are now included in the main FreeRTOS download.
+	+ NXP LPC1114 GCC/LPCXpresso
+	+ ST STM32F0518 IAR
+	+ Infineon XMC4500 GCC/Atollic
+	+ Infineon XMC4500 IAR
+	+ Infineon XMC4500 Keil
+	+ Infineon XMC4500 Tasking
+
+
+	Kernel miscellaneous / maintenance:
+
+	+ Introduced the portSETUP_TCB() macro to remove the requirement for the
+	  Windows simulator to use the traceTASK_CREATE() macro, leaving the trace
+	  macro available for use by FreeRTOS+Trace (http://www.FreeRTOS.org/trace).
+	+ Added a new trace macro, traceMOVE_TASK_TO_READY_STATE(), to allow future
+	  FreeRTOS+Trace versions to provide even more information to users.
+	+ Updated the FreeRTOS MPU port to be correct for changes that were
+	  introduced in FreeRTOS V7.1.0.
+	+ Introduced the xQueueReset() API function.
+	+ Introduced the xSemaphoreGetMutexHolder() API function.
+	+ Tidy up various port implementations to add the static key word where
+	  appropriate, and remove obsolete code.
+	+ Slight change to the initial stack frame given to the RX600 ports to allow
+	  them to be used in the Eclipse based E2Studio IDE without confusing GDB.
+	+ Correct the alignment given to the initial stack of Cortex-M4F tasks.
+	+ Added a NOP following each DINT instruction on MSP430 devices for strict
+	  conformance with the instructions on using DINT.
+	+ Changed the implementation of thread deletes in the Win32 port to prevent
+	  the port making use of the traceTASK_DELETE() trace macros - leaving this
+	  macro free for use by FreeRTOS+Trace.
+	+ Made some benign changes to the RX600 Renesas compiler port layer to
+	  ensure the code can be built to a library without essential code being
+	  removed by the linker.
+	+ Reverted the change in the name of the uxTaskNumber variable made in
+	  V7.1.0 as it broke the IAR plug-in.
+
+
+	Demo miscellaneous / maintenance:
+
+	+ The command interpreter has now been formally released as FreeRTOS+CLI,
+	  and been moved out of the main FreeRTOS download, to instead be available
+	  from the FreeRTOS+ Ecosystem site http://www.FreeRTOS.org/plus.
+	+ flash_timer.c/h has been added to the list of standard demo tasks.  This
+	  performs the same functionality as the flash.c tasks, but using software
+	  timers in place of tasks.
+	+ Upgraded the PIC32 demo as follows:  Changes to how the library functions
+	  are called necessitated by the new compiler version, addition of MPLAB X
+	  project with PIC32MX360, PIC32MX460 and PIC32MX795 configurations,
+	  addition of simply blinky demo, updated FreeRTOSConfig.h to include more
+	  parameters, addition of hook function stubs.
+	+ The MSP430X IAR and CCS demos have been updated to ensure the power
+	  settings are correct for the configured CPU frequency.
+	+ Rowley CrossWorks projects have been updated to correct the "multiple
+	  definition of ..." warnings introduced when the toolchain was updated.
+	+ Updated various FreeRTOSConfig.h header files associated with projects
+	  that build with Eclipse to include a #error statement informing the user
+	  that the CreateProjectDirectoryStructure.bat batch file needs to be
+	  executed before the projects can be opened.
+	+ Renamed directories that included "CCS4" in their name to remove the '4'
+	  and instead just be "CCS".  This is because the demo was updated and
+	  tested to also work with later Code Composer Studio versions.
+	+ Updated the TCP/IP periodic timer frequency in numerous uIP demos to be
+	  50ms instead of 500ms.
+
+Changes between V7.0.2 and V7.1.0 released December 13 2011
+
+	New ports:
+
+	+ Cortex-M4F IAR port.
+	+ Cortex-M4F Keil/RVDS port.
+	+ TriCore GCC port.
+
+	New demos:
+
+	+ NXP LPC4350 using the Keil MDK, and demonstrated on a Hitex development
+	  board.
+	+ ST STM32F407 using the IAR Embedded Workbench for ARM, and demonstrated on
+	  the IAR STM32F407ZG-SK starter kit.
+	+ Infineon TriCore TC1782, using the GCC compiler, demonstrated on the
+	  TriBoard TC1782 evaluation board.
+	+ Renesas RX630, using the Renesas compiler and HEW, demonstrated on an
+	  RX630 RSK (Renesas Starter Kit).
+
+	Miscellaneous / maintenance:
+
+	+ Removed all calls to printf() from the K60/IAR Kinetis demo so the project
+	  can execute stand alone - without being connected to the debugger.
+	+ Completed the command interpreter framework.  Command handlers now receive
+	  the entire command string, giving them direct access to parameters.
+	  Utility functions are provided to check the number of parameters, and
+	  return parameter sub-strings.
+	+ The previously documented fix for the bug in xTaskResumeFromISR() that
+	  effected (only) ports supporting interrupt nesting has now been
+	  incorporated into the main release.
+	+ The portALIGNMENT_ASSERT_pxCurrentTCB() definition has been added to allow
+	  specific ports to skip the second stack alignment check when a task is
+	  created.  This is because the second check is not appropriate for some
+	  ports - including the new TriCore port where the checked pointer does not
+	  actually point to a stack.
+	+ The portCLEAN_UP_TCB() macro has been added to allow port specific clean
+	  up when a task is deleted - again this is required by the TriCore port.
+	+ Various other minor changes to ensure warning free builds on a growing
+	  number of microcontroller and toolchain platforms.  This includes a
+	  (benign) correction to the prototype of the
+	  vApplicationStackOverflowHook() definition found in lots of recent demos.
+
+	Trace system:
+
+	+ The legacy trace mechanism has been completely removed - it has been
+	  obsolete for the years since the trace macros were introduced.  The
+	  configuration constant configUSE_TRACE_FACILITY is now used to optionally
+	  include additional queue and task information.  The additional information
+	  is intended to make the trace mechanism more generic, and allow the trace
+	  output to provide more information.  When configUSE_TRACE_FACILITY is set
+	  to 1:
+		- the queue structure includes an additional member to hold the queue
+		  type, which can be base, mutex, counting semaphore, binary semaphore
+		  or recursive mutex.
+		- the queue structure includes an additional member to hold a queue
+		  number.  A trace tool can set and query the queue number for its own
+		  purposes.  The kernel does not use the queue number itself.
+		- the TCB structure includes an additional member to hold a task number
+		  number.  A trace tool can set and query the task number for its own
+		  purposes.  The kernel does not use the task number itself.
+	+ Queues and all types of semaphores are now automatically allocated their
+	  type as they are created.
+	+ Added two new trace macros - traceTASK_PRIORITY_INHERIT() and
+	  traskTASK_PRIORITY_DISINHERIT().
+	+ Updated the traceQUEUE_CREATE_FAILED() macro to take a parameter that
+	  indicates the type of queue, mutex, or semaphore that failed to be
+	  created.
+	+ The position from which traceCREATE_MUTEX() is called has been moved from
+	  after the call to xQueueGenericSend() [within the same function] to before
+	  the call.  This ensures the trace events occur in the correct order.
+	+ The value passed into tracePRIORITY_SET() has been corrected for the case
+	  where vTaskPrioritySet() is called with a null parameter.
+
+Changes between V7.0.1 and V7.0.2 released September 20 2011
+
+	New ports:
+
+	+ The official FreeRTOS Renesas RX200 port and demo application have been
+	  incorporated into the main FreeRTOS zip file download.
+	+ The official FreeRTOS Renesas RL78 port and demo application have been
+	  incorporated into the main FreeRTOS zip file download.
+	+ The official FreeRTOS Freescale Kinetis K60 tower demo application has
+	  been incorporated into the main FreeRTOS zip file download.  This includes
+	  an embedded web server example.
+	+ A new Microblaze V8 port layer has been created to replace the older, now
+	  deprecated, port layer.  The V8 port supports V8.x of the Microblaze IP,
+	  including exceptions, caches, and the floating point unit.  A new
+	  Microblaze demo has also been added to demonstrate the new Microblaze V8
+	  port layer.  The demo application was created using V13.1 of the Xilinx
+	  EDK, and includes a basic embedded web server that uses lwIP V1.4.0.
+	+ The official FreeRTOS Fujitsu FM3 MB9A310 demo application has been
+	  incorporated into the main FreeRTOS zip file download.  Projects are
+	  provided for both the IAR and Keil toolchains.
+
+
+	API additions:
+
+	+ xTaskGetIdleTaskHandle() has been added.
+	+ xTaskGetTimerDaemonTaskHandle() has been added.
+	+ pcTaskGetTaskName() has been added.
+	+ vSemaphoreDelete() macro has been added to make it obvious how to delete
+	  a semaphore.  In previous versions vQueueDelete() had to be used.
+	+ vTaskCleanUpResources() has been removed.  It has been obsolete for a
+	  while.
+	+ portPOINTER_SIZE_TYPE has been introduced to prevent compiler warnings
+	  being generated when the size of a pointer does not match the size of
+	  the stack type.  This will (has already) be used in new ports, but will
+	  not be retrofitted to existing ports until the existing port itself is
+	  updated.
+
+	Other updates and news:
+
+	+ The core files have all been modified to tighten the coding standard even
+	  further.  These are style, not functional changes.
+	+ All ARM7 port layers have been slightly modified to prevent erroneous
+	  assert() failures when tasks are created and configASSERT() is defined.
+	+ All ARM IAR projects have been updated to build with the latest V6.2.x
+	  versions of the IAR Embedded Workbench for ARM tools (EWARM).  This was
+	  necessary due to a change in the way EWARM uses the CMSIS libraries.
+	+ The PIC32 port layer has been updated in preparation for V2 of the C32
+	  compiler.
+	+ The old Virtex-4 Microblaze demo has been marked as deprecated.  Please
+	  use the brand new Spartan-6 port and demo in its place.
+	+ The bones of a new generic command interpreter is located in
+	  FreeRTOS/Demo/Common/Utils/CommandInterpreter.c.  This is still a work in
+	  progress, and not documented.  It is however already in use.  It will be
+	  documented in full when the projects that are already using it are
+	  completed.
+	+ A couple of new standard demos have been included.  First, a version of
+	  flop.c called sp_flop.c.  This is similar to flop.c, but uses single
+	  precision floats in place of double precision doubles.  This allows the
+	  for testing ports to processors that have only single precision floating
+	  point units, and revert to using emulated calculations whenever a double
+	  is used.  Second, comtest_strings.c has been included to allow the test
+	  of UART drivers when an entire string is transmitted at once.  The
+	  previous comtest.c only used single character transmission and reception.
+	+ lwIP V1.4.0 is now included in the FreeRTOS/Demo/Common directory, and
+	  used by a couple of new demos.
+
+Changes between V7.0.0 and V7.0.1 released May 13 2011
+
+	+ Added a Fujitsu FM3 demo application for both the IAR and Keil tool
+	  chains.
+	+ Added a SmartFusion demo application for all of the IAR, Keil and
+	  SoftConsole (GCC/Eclipse) tool chains.
+	+ Updated the RX600 port and demo applications to take into account the
+	  different semantics required when using the latest (V1.0.2.0) version of
+	  the Renesas compiler.
+	+ Modified the RX600 Ethernet driver slightly to make it more robust under
+	  heavy load, and updated the uIP handling task to make use of the FreeRTOS
+	  software timers.
+	+ Slightly changed the PIC32 port layer to move an ehb instruction in line
+	  with the recommendations of the MIPS core manual, and ensure 8 byte stack
+	  alignment is truly always obtained.
+	+ Changed the behaviour when tasks are suspended before the scheduler has
+	  been started.  Before, there needed to be at least one task that was not
+	  in the suspended state.  This is no longer the case.
+
+Changes between V6.1.1 and V7.0.0 released April 8 2011
+
+	FreeRTOS V7.0.0 is backward compatible with FreeRTOS V6.x.x
+
+	Main changes:
+
+	+ Introduced a new software timer implementation.
+	+ Introduced a new common demo application file to exercise the new timer
+	  implementation.
+	+ Updated the Win32/MSVC simulator project to include the new software timer
+	  demo tasks and software timer tick hook test.  Much simpler software timer
+	  demonstrations are included in the demo projects for both of the new ports
+	  (MSP430X with CCS4 and STM32 with TrueStudio).
+	+ Various enhancements to the kernel implementation in tasks.c.  These are
+	  transparent to users and do not effect the pre-existing API.
+	+ Added calls to configASSERT() within the kernel code.  configASSERT() is
+	  functionally equivalent to the standard C assert() macro, but does not
+	  rely on the compiler providing assert.h.
+
+	Other changes:
+
+	+ Updated the MSP430X IAR port and demo project to include support for the
+	  medium memory model.
+	+ Added a demo project for the MSP430X that targets the MSP430X Discovery
+	  board and uses the Code Composer Studio 4 tools.  This demo includes use
+	  of the new software timer implementation.
+	+ Added an STM32F100RB demo project that targets the STM32 Discovery Board
+	  and uses the TrueStudio Eclipse based IDE from Atollic.
+	+ Removed some compiler warnings from the PSoC demo application.
+	+ Updated the PIC32 port layer to ensure the
+	  configMAX_SYSCALL_INTERRUPT_PRIORITY constant works as expected no matter
+	  what its value is (within the valid range set by the microcontroller
+	  kernel).
+	+ Updated the PIC24, dsPIC and PIC32 projects so they work with the latest
+	  MPLAB compiler versions from Microchip.
+	+ Various cosmetic changes to prepare for a standards compliance statement
+	  that will be published after the software release.
+
+
+Changes between V6.1.0 and V6.1.1 released January 14 2011
+
+	+ Added two new Windows simulator ports.  One uses the free Microsoft Visual
+	  Studio 2010 express edition, and the other the free MingW/Eclipse
+	  environment.  Demo projects are provided for both.
+	+ Added three demo projects for the PSoC 5 (CYAC5588).  These are for the
+	  GCC, Keil, and RVDS build tools, and all use the PSoC Creator IDE.
+	+ Added a demo for the low power STM32L152 microcontroller using the IAR
+	  Embedded Workbench.
+	+ Added a new port for the MSP430X core using the IAR Embedded Workbench.
+	+ Updated all the RX62N demo projects that target the Renesas Demonstration
+	  Kit (RDK) to take into account the revered LED wiring on later hardware
+	  revisions, and the new J-Link debug interface DLL.
+	+ Updated all the RX62N demo projects so the IO page served by the example
+	  embedded web server works with all web browsers.
+	+ Updated the Red Suite projects to work with the up coming Red Suite
+	  release, and to use a more recent version of the CMSIS libraries.
+	+ Added the traceTAKE_MUTEX_RECURSIVE_FAILED() trace macro.
+	+ Removed the (pointless) parameter from the traceTASK_CREATE_FAILED()
+	  trace macro.
+	+ Introduced the portALT_GET_RUN_TIME_COUNTER_VALUE() macro to compliment
+	  the already existing portGET_RUN_TIME_COUNTER_VALUE().  This allows for
+	  more flexibility in how the time base for the run time statistics feature
+	  can be implemented.
+	+ Added a "cpsie i" instruction before the "svc 0" instruction used to start
+	  the scheduler in each of the Cortex M3 ports.  This is to ensure that
+	  interrupts are globally enabled prior to the "svc 0" instruction being
+	  executed in cases where interrupts are left disabled by the C start up
+	  code.
+	+ Slight optimisation in the run time stats calculation.
+
+Changes between V6.0.5 and V6.1.0 released October 6 2010
+
+	+ Added xTaskGetTickCountFromISR() function.
+	+ Modified vTaskSuspend() to allow tasks that have just been created to be
+	  immediately suspended even when the kernel has not been started.  This
+	  allows them to effectively start in the Suspended state - a feature that
+	  has been asked for on numerous occasions to assist with initialisation
+	  procedures.
+	+ Added ports for the Renesas RX62N using IAR, GCC and Renesas tool suites.
+	+ Added a STM32F103 demo application that uses the Rowley tools.
+	+ Under specific conditions xFreeBytesRemaining within heap_2.c could end up
+	  with an incorrect	value.  This has been fixed.
+	+ xTaskCreateGeneric() has a parameter that can be used to pass the handle
+	  of the task just created out to the calling task.  The assignment to this
+	  parameter has been moved to ensure it is assigned prior to the newly
+	  created having any possibility of executing.  This takes into account the
+	  case where the assignment is made to a global variable that is accessed by
+	  the newly created task.
+	+ Fixed some build time compiler warnings in various FreeTCPIP (based on
+	  uIP) files.
+	+ Fixed some build time compiler warnings in Demo/Common/Minimal/IntQueue.c.
+
+Changes between V6.0.4 and V6.0.5 released May 17 2010
+
+	+ Added port and demo application for the Cortus APS3 processor.
+
+Changes between V6.0.3 and V6.0.4 released March 14 2010
+
+	+ All the contributed files that were located in the Demo/Unsupported_Demos
+	  directory have been removed.  These files are instead now available in the
+	  new  Community Contributions section of the FreeRTOS website.  See
+	  http://www.freertos.org/RTOS-contributed-ports.html
+	+ The project file located in the Demo/CORTEX_STM32F107_GCC_Rowley directory
+	  has been upgraded to use V2.x of the Rowley Crossworks STM32 support
+	  package.
+	+ An initial Energy Micro EFM32 demo has been included.  This will be
+	  updated over the coming months to make better use of the low power modes
+	  the EFM32 provides.
+
+Changes between V6.0.2 and V6.0.3 released February 26 2010
+
+	+ SuperH SH7216 (SH2A-FPU) port and demo application added.
+	+ Slight modification made to the default implementation of
+	  pvPortMallocAligned() and vPortFreeAligned() macros so by default they
+	  just call pvPortMalloc() and vPortFree().  The macros are only needed to
+	  be defined when a memory protection unit (MPU) is being used - and then
+	  only depending on other configuration settings.
+
+Changes between V6.0.1 and V6.0.2 released January 9th 2010
+
+	+ Changed all GCC ARM 7 ports to use 0 as the SWI instruction parameter.
+	  Previously the parameter was blank and therefore only an implicit 0 but
+	  newer GCC releases do not permit this.
+	+ Updated IAR SAM7S and SAM7X ports to work with IAR V5.40.
+	+ Changed the stack alignment requirement for PIC32 from 4 bytes to 8 bytes.
+	+ Updated prvListTaskWithinSingleList() is it works on processors where the
+	  stack grows up from low memory.
+	+ Corrected some comments.
+	+ Updated the startup file for the RVDS LPC21xx demo.
+
+Changes between V6.0.0 and V6.0.1 released November 15th 2009
+
+	+ Altered pxPortInitialiseStack() for all Cortex-M3 ports to ensure the
+	  stack pointer is where the compiler expects it to be when a task first
+	  starts executing.
+
+	  The following minor changes only effect the Cortex-M3 MPU port:
+
+	+ portRESET_PRIVILEGE() assembly macro updated to include a clobber list.
+	+ Added prototypes for all the privileged function wrappers to ensure no
+	  compile time warnings are generated no matter what the warning level
+	  setting.
+	+ Corrected the name of portSVC_prvRaisePrivilege to
+	  portSVC_RAISE_PRIVILEGE.
+	+ Added conditional compilation into xTaskGenericCreate() to prevent some
+	  compilers issuing warnings when portPRIVILEGE_BIT is defined as zero.
+
+
+Changes between V5.4.2 and V6.0.0 released October 16th 2009
+
+	FreeRTOS V6 is backward compatible with FreeRTOS V5.x.
+
+	Main changes:
+
+	+ FreeRTOS V6 is the first version to include memory protection unit (MPU)
+	  support.  Two ports now exist for the Cortex M3, the standard FreeRTOS
+	  which does not include MPU support, and FreeRTOS-MPU which does.
+	+ xTaskCreateRestricted() and vTaskAllocateMPURegions() API functions added
+	  in support of FreeRTOS-MPU.
+	+ Wording for the GPL exception has been (hopefully) clarified.  Also the
+	  license.txt file included in the download has been fixed (the previous
+	  version contained some corruption).
+
+	Other changes:
+
+	+ New API function xPortGetFreeHeapSize() added to heap_1.c and heap_2.c.
+	+ ARM7 GCC demo interrupt service routines wrappers have been modified to
+	  call the C portion using an __asm statement.  This prevents the function
+	  call being inlined at higher optimisation levels.
+	+ ARM7 ports now automatically set the THUMB bit if necessary when
+	  setting up the initial stack of a task - removing the need for
+	  THUMB_INTERWORK to be defined.  This also allows THUMB mode and ARM mode
+	  tasks to be mixed more easily.
+	+ All ARM7/9 ports now have portBYTE_ALIGNMENT set to 8 by default.
+	+ Various demo application project files have been updated to be up to date
+	  with the latest IDE versions.
+	+ The linker scripts used with command line GCC demos have been updated to
+	  include an eh_frame section to allow their use with the latest Yagarto
+	  release.  Likewise the demo makefiles have been updated to include
+	  command line options to reduce or eliminate the eh_frame section all
+	  together.
+	+ The definition of portBYTE_ALIGNMENT_MASK has been moved out of the
+	  various memory allocation files and into the common portable.h header
+	  file.
+	+ Removed unnecessary use of portLONG, portSHORT and portCHAR.
+	+ Added LM3Sxxxx demo for Rowley CrossWorks.
+	+ Posix simulator has been upgraded - see the corresponding WEB page on the
+	  FreeRTOS.org site.
+
+
+Changes between V5.4.1 and V5.4.2 released August 9th 2009
+
+	+ Added a new port and demo app for the Altera Nios2 soft core.
+	+ Added LPC1768 demo for IAR.
+	+ Added a USB CDC demo to all LPC1768 demos (Code Red, CrossWorks and IAR).
+	+ Changed clock frequency of LPC1768 demos to 99MHz.
+
+Changes between V5.4.0 and V5.4.1 released July 25th 2009
+
+	+ New hook function added.  vApplicationMallocFailedHook() is (optionally)
+	  called if pvPortMalloc() returns NULL.
+	+ Additional casting added to xTaskCheckForTimeOut().  This prevents
+	  problems that can arise should configUSE_16_BIT_TICKS be set to 1 on a
+	  32 bit architecture (which would probably be a mistake, anyway).
+	+ Corrected the parameter passed to NVIC_SetPriority() to set the MAC
+	  interrupt priority in both LPC1768 demos.
+	+ Decreased the default setting of configMINIMAL_STACK_SIZE in the PIC32
+	  demo application to ensure the heap space was not completely consumed
+	  before the scheduler was started.
+
+Changes between V5.3.1 and V5.4.0 released July 13th 2009
+
+	+ Added Virtex5 / PPC440 port and demos.
+	+ Replaced the LPC1766 Red Suite demo with an LPC1768 Red Suite demo.  The
+	  original demo was configured to use engineering samples of the CPU.  The
+	  new demo has an improved Ethernet driver.
+	+ Added LPC1768 Rowley demo with zero copy Ethernet driver.
+	+ Reworked byte alignment code to ensure 8 byte alignment works correctly.
+	+ Set configUSE_16_BIT_TICKS to 0 in the PPC405 demo projects.
+	+ Changed the initial stack setup for the PPC405 to ensure the small data
+	  area pointers are setup correctly.
+
+Changes between V5.3.0 and V5.3.1 released June 21st 2009
+
+	+ Added ColdFire V1 MCF51CN128 port and WEB server demo.
+	+ Added STM32 Connectivity Line STM32107 Cortex M3 WEB server demo.
+	+ Changed the Cortex M3 port.c asm statements to __asm so it can be
+	  compiled using Rowley CrossWorks V2 in its default configuration.
+	+ Updated the Posix/Linux simulator contributed port.
+
+Changes between V5.2.0 and V5.3.0 released June 1st 2009
+
+	Main changes:
+
+	+ Added new (optional) feature that gathers statistics on the amount of CPU
+	  time used by each task.
+	+ Added a new demo application for the Atmel AT91SAM3U Cortex-M3 based
+	  microcontroller.
+	+ Added a new demo application for the NXP LPC1766 Cortex-M3 based
+	  microcontroller.
+	+ Added a contributed port/demo that allows FreeRTOS to be 'simulated' in a
+	  Linux environment.
+
+	Minor changes:
+	+ Updated the Stellaris uIP WEB server demos to include the new run time
+	  statistics gathering feature - and include a served WEB page that
+	  presents the information in a tabular format.
+	+ Added in the lwIP port layer for the Coldfire MCF52259.
+	+ Updated the CrossWorks LPC2368 WEB server to include an image in the
+	  served content.
+	+ Changed some of the timing in the initialisation of the LPC2368 MAC to
+	  permit its use on all part revisions.
+	+ Minor modifications to the core uIP code to remove some compiler warnings.
+	+ Added xTaskGetApplicationTaskTag() function and updated the OpenWatcom
+	  demo to make use of the new function.
+	+ Added contributed demos for AVR32 AP7000, STM32 Primer 2 and STM32 using
+	  Rowley Crossworks.
+	+ Heap_1.c and Heap_2.c used to define structures for the purpose of data
+	  alignment.  These have been converted to unions to save a few bytes of
+	  RAM that would otherwise be wasted.
+	+ Remove the call to strncpy() used to copy the task name into the TCB when
+	  the maximum task name is configured to be 1 byte long.
+
+Changes between V5.1.2 and V5.2.0 released March 14th 2009
+
+	+ Optimised the queue send and receive functions (also used by semaphores).
+	+ Replaced the standard critical sections used to protect BIOS calls in the
+	  PC port to instead use scheduler locks.  This is because the BIOS calls
+	  always return with interrupts enabled.
+	+ Corrected unclosed comments in boot.s.
+
+Changes between V5.1.1 and V5.1.2 released February 9th 2009
+
+	+ Added NEC V850ES port and demo.
+	+ Added NEC 78K0R port and demo.
+	+ Added MCF52259 port and demo.
+	+ Added the AT91SAM9XE port and demo.
+	+ Updated the MCF52233 FEC driver to work around a silicon bug that
+	  prevents the part auto negotiating some network parameters.
+	+ Minor modifications to the MCF52233 makefile to permit it to be used
+	  on Linux hosts.
+	+ Updated the STM32 primer files to allow them to be built with the latest
+	  version of the RIDE tools.
+	+ Updated the threads.js Java script used for kernel aware debugging in
+	  the Rowley CrossWorks IDE.
+
+
+Changes between V5.1.0 and V5.1.1 released November 20, 2008
+
+	+ Added Coldfire MCF52233 WEB server demo using GCC and Eclipse.
+	+ Added IAR MSP430 port and demo.
+	+ Corrected several compiler time issues that had crept in as tool versions
+	  change.
+	+ Included FreeRTOS-uIP - a faster uIP.  This is not yet complete.
+
+Changes between V5.0.4 and V5.1.0 released October 24, 2008
+
+	+ Added a new port and demo application for the ColdFire V2 core using the
+	  CodeWarrior development tools.
+	+ Replaced the ARM7 demo that used the old (and now no longer supported)
+	  Keil compiler with a new port that uses the new Keil/RVDS combo.
+	+ Stack overflow checking now works for stacks that grow up from low
+	  memory (PIC24 and dsPIC).
+	+ BUG FIX - set the PIC32 definition of portSTACK_GROWTH to the correct
+	  value of -1.
+	+ MSP430 port layers have been updated to permit tasks to place the
+	  microcontroller into power down modes 1 to 3.  The demo applications have
+	  likewise been updated to demonstrate the new feature.
+	+ Replaced the two separate MSP430/Rowley port layers with a single and more
+	  flexible version.
+	+ Added more contributed ports, including ports for NEC and SAM9
+	  microcontrollers.
+	+ Changed the linker script used in the LPC2368 Eclipse demo.
+
+Changes between V5.0.3 and V5.0.4 released September 22, 2008
+
+	+ Completely re-written port for ColdFire GCC.
+	+ Bug fix:  All Cortex M3 ports have a minor change to the code that sets
+	  the pending interrupt.
+	+ Some header files require that FreeRTOS.h be included prior to their
+	  inclusion.  #error message have been added to all such header file
+	  informing users to the cause of the compilation error should the headers
+	  not be included in the correct order.
+
+Changes between V5.0.2 and V5.0.3 released July 31, 2008
+
+	Changes relating to the Cortex M3:
+
+	+ Added configMAX_SYSCALL_INTERRUPT_PRIORITY usage to all the Cortex M3
+	  ports and demos.  See the port documentation pages on the FreeRTOS.org
+	  WEB site for full usage information.
+	+ Improved efficiency of Cortex M3 port even further.
+	+ Ensure the Cortex M3 port works no matter where the vector table is
+	  located.
+	+ Added the IntQTimer demo/test tasks to a demo project for each CM3 port
+	  (Keil, GCC and IAR) to test the new configMAX_SYSCALL_INTERRUPT_PRIORITY
+	  functionality.
+	+ Added the mainINCLUDE_WEB_SERVER definition to the LM3SXXXX IAR and Keil
+	  projects to allow the WEB server to be conditionally excluded from the
+	  build and therefore allow use of the KickStart (code size limited)
+	  compiler version.
+
+	Other changes:
+
+	+ Moved the PIC24 and dsPIC versions of vPortYield() from the C file to
+	  an assembly file to allow use with all MPLAB compiler versions.  This also
+	  allows the omit-frame-pointer optimisation to be turned off.
+
+Changes between V5.0.0 and V5.0.2 released May 30, 2008
+
+	+ Updated the PIC32 port to allow queue API calls to be used from
+	  interrupts above the kernel interrupt priority, and to allow full
+	  interrupt nesting.  Task stack usages has also been reduced.
+	+ Added a new PowerPC port that demonstrates how the trace macros can be
+	  used to allow the use of a floating point co-processor.  The
+	  traceTASK_SWITCHED_OUT() and traceTASK_SWITCHED_INT() macros are used to
+	  save and restore the floating point context respectively for those tasks
+	  that actually use floating point operations.
+	+ BUG FIX:  The first PPC405 port contained a bug in that it did not leave
+	  adequate space above the stack for the backchain to be saved when a task
+	  started to execute for the first time.
+	+ Updated queue.c to add in the means to allow interrupt nesting and for
+	  queue API functions to be called from interrupts that have a priority
+	  above the kernel priority.  This is only supported on PIC32 ports thus
+	  far.
+	+ Fixed the compiler warnings that were generated when the latest version
+	  of WinAVR was used.
+	+ Remove all inline usage of 'inline' from the core kernel code.
+	+ Added the queue registry feature.  The queue registry is provided as a
+	  means for kernel aware debuggers to locate queue definitions.  It has no
+	  purpose unless you are using a kernel aware debugger.  The queue registry
+	  will only be used when configQUEUE_REGISTRY_SIZE is greater than zero.
+	+ Added the ST Cortex-M3 drivers into the Demo/Common/Drivers directory to
+	  prevent them from having to be included in multiple demos.
+	+ Added a Keil STM32 demo application.
+	+ Changed the blocktim.c test files as it is no longer legitimate for all
+	  ports to call queue API functions from within a critical section.
+	+ Added the IntQueue.c test file to test the calling of queue API functions
+	  from different interrupt priority levels, and test interrupt nesting.
+
+Changes between V5.0.0 and V5.0.1
+
+	+ V5.0.1 was a customer specific release.
+
+Changes between V4.8.0 and V5.0.0 released April 15, 2008
+
+	*** VERY IMPORTANT INFORMATION ON UPGRADING TO FREERTOS.ORG V5.0.0 ***
+
+	The parameters to the functions xQueueSendFromISR(), xQueueSendToFrontFromISR(),
+	xQueueSendToBackFromISR() and xSemaphoreGiveFromISR() have changed.  You must
+	update all calls to these functions to use the new calling convention!  Your
+	compiler might not issue any type mismatch warnings!
+
+
+	See http://www.FreeRTOS.org/upgrading.html for full information.
+
+
+	Other changes:
+
+	+ Support added for the new Luminary Micro LM3S3768 and LM3S3748 Cortex-M3
+	  microcontrollers.
+	+ New task hook feature added.
+	+ PowerPC demo updated to use version 10.1 of the Xilinx EDK.
+	+ Efficiency gains within the PIC32 port layer.
+
+Changes between V4.7.2 and V4.8.0 released March 26 2008
+
+	+ Added a Virtex4 PowerPC 405 port and demo application.
+	+ Added optional stack overflow checking and new
+	  uxTaskGetStackHighWaterMark() function.
+	+ Added new xQueueIsQueueEmptyFromISR(), xQueueIsQueueFullFromISR() and
+	  uxQueueMessagesWaitingFromISR() API functions.
+	+ Efficiency improvements to the Cortex-M3 port layer.  NOTE: This
+	  requires that an SVC handler be installed in the application.
+	+ Efficiency improvements to the queue send and receive functions.
+	+ Added new trace macros.  These are application definable to provide
+	  a flexible trace facility.
+	+ Implemented the configKERNEL_INTERRUPT_PRIORITY within the Keil Cortex
+	  M3 port layer (bringing it up to the same standard as the IAR and GCC
+	  versions).
+	+ Ports that used the arm-stellaris-eabi-gcc tools have been converted to
+	  use the arm-non-eabi-gcc tools.
+
+Changes between V4.7.1 and V4.7.2 released February 21, 2008
+
+	+ Added Fujitsu MB91460 port and demo.
+	+ Added Fujitsu MB96340 port and demo.
+	+ Tidied up the capitalisation of include files to facilitate builds on
+	  Linux hosts.
+	+ Removed some redundant casting that was generating warnings - but was
+	  included to remove warnings on other compilers.
+
+Changes between V4.7.0 and V4.7.1 released February 3, 2008
+
+	+ Updated all IAR ARM projects to use V5.11 of the IAR Embedded Workbench
+	  for ARM.
+	+ Introduced recursive semaphore feature.
+	+ Updated LPC2368 demos to take into account silicon bugs in old chip
+	  revisions.
+	+ Updated STR9 uIP port to manually set the net mask and gateway addresses.
+	+ Updating demos to allow more to run with the co-operative scheduler.
+	+ Fixed co-operative scheduler behaviour upon the occurrence of a tick
+	  interrupt while the scheduler was suspended.
+	+ Updated documentation contained within semphr.h.
+	+ ARM7 GCC ports no longer use the IRQ attribute.
+
+Changes between V4.6.1 and V4.7.0 released December 6, 2007
+
+	+ Introduced the counting semaphore macros and demo source files.  The
+          Open Watcom PC project has been updated to include the new demo.  See
+          the online documentation for more information.
+	+ Introduced the 'alternative' queue handling API and demo source files.
+	  The Open Watcom PC project has been updated to include the new demo
+	  source files.  See the online documentation for more information.
+	+ Added AT91SAM7X Eclipse demo project.
+	+ Added the STM32 primer demo project for the GCC compiler and Ride IDE.
+	+ Removed the .lock files that were mistakenly included in the V4.6.1
+	  eclipse workspaces.
+
+Changes between V4.6.0 and V4.6.1 released November 5 2007
+
+	+ Added support for the MIPS M4K based PIC32.
+	+ Added 'extern "C"' to all the header files to facilitate use with C++.
+
+Changes between V4.5.0 and V4.6.0 released October 28 2007
+
+	+ Changed the method used to force a context switch within an ISR for the
+	  ARM7/9 GCC ports only.  The portENTER_SWITCHING_ISR() and
+	  portEXIT_SWITCHING_ISR() macros are no longer supported.  This is to
+	  ensure correct behaviour no matter which GCC version is used, with or
+	  without the -fomit-frame-pointer option, and at all optimisation levels.
+	+ Corrected the prototype for xQueueGenericSend() within queue.h.
+
+Changes between V4.4.0 and V4.5.0 released September 17 2007
+
+	+ Added the xQueueSendToFront(), xQueueSendToBack() and xQueuePeek()
+	  functionality.  These should now be used in preference to the old
+	  xQueueSend() function - which is maintained for backward compatibility.
+	+ Added Mutex functionality.  The behaviour of mutexes is subtly different
+	  to the already existing binary semaphores as mutexes automatically
+	  include a priority inheritance mechanism.
+	+ Added the GenQTest.c and QPeek.c to test and demonstrate the behaviour
+	  of the new functionality.
+	+ Updated the LM3Sxxxx and PC ports to include the new GenQTest.c and
+	  QPeek.c files.
+	+ Updated the GCC port for the Cortex M3 to include the
+	  configKERNEL_INTERRUPT_PRIORITY functionality.  This was previously only
+	  included in the IAR port.
+	+ Optimised the GCC and IAR port layer code - specifically the context
+	  switch code.
+	+ Consolidated the LM3Sxxxx EK demos for all development tools into a
+	  single project that automatically detects which version of the EK the
+	  application is executing on.
+	+ Added Eclipse support for LM3Sxxxx evaluation kits.
+	+ Added Eclipse support for the Keil LPC2368 evaluation kit.
+	+ Added the Demo/Drivers directory to hold code that is common to multiple
+	  demo application projects.
+	+ Included some minor bug fixes in the uIP 1.0 code.
+	+ Added an lwIP demo for the STR9 - thanks ST for assistance.
+	+ Updated the AVR32 port to ensure correct behaviour with full compiler
+	  optimisation.
+	+ Included binaries for OpenOCD FTDI and parallel port interfaces.
+
+Changes between V4.4.0 and V4.3.1 released July 31, 2007
+
+	+ Added AVR32 UC3B demo application.
+	+ Updated AVR32 UC3A port and demo applications.
+	+ Added IAR lwIP demo for AVR32 UC3A.
+	+ Updated listGET_OWNER_OF_NEXT_ENTRY() to assist compiler optimisation
+	  (thanks Niu Yong for making the suggestion).
+	+ Added xTaskGetSchedulerState() API function.
+	+ BUG FIX:  Corrected behaviour when tasks that are blocked indefinitely
+	  have their block time adjusted (within xQueueSend() and xQueueReceive()),
+	  and are the subject of a call the vTaskResume() when they are not
+	  actually in the Suspended state (thanks Dan Searles for reporting the
+	  issues).
+
+
+Changes between V4.3.0 and V4.3.1 released June 11, 2007
+
+	+ Added STMicroelectronics STM32 Cortex-M3 demo application.
+	+ Updated ustdlib.c for the GCC LM3S6965 demo.
+
+Changes between V4.2.1 and V4.3.0 released June 5, 2007
+
+	+ Introduced configKERNEL_INTERRUPT_PRIORITY to the IAR Cortex-M3, PIC24
+	  and dsPIC ports.  See the LM3S6965 and PIC24 demo application
+	  documentation pages for more information.
+	+ Updated the PIC24 and dsPIC demos to build with V3.0 of the PIC30 GCC
+	  tools, and changed the demo applications.
+	+ Added demos for the new Ethernet and CAN enabled Luminary Micro Stellaris
+	  microcontrollers.
+	+ Corrected bug in uIP the demos that prevented frames of approximately 1480
+	  bytes and over from being transmitted.
+	+ Included the LPC2368/uIP/Rowley demo into the main FreeRTOS.org
+	  download.
+	+ Update to WizC PIC18 port to permit its use with version 14 of the
+	  compiler.  Thanks Marcel!
+
+Changes between V4.2.1 and V4.2.0 released April 2, 2007
+
+	+ Added AVR32 AT32UC3A ports for GCC and IAR.
+	+ Added -fomit-frame-pointer option to lwIP SAM7X demo makefile.
+	+ Moved location of call to LCD_Init() in STR9 demo to ensure it is only
+	  called after the scheduler has been started.
+
+Changes between V4.1.3 and V4.2.0 released February 8, 2007
+
+	+ Changes to both task.c and queue.c as a result of testing performed on
+	  the SafeRTOS code base.
+	+ Added Cortex-M3 LM3S811 demos for GCC and IAR tools.
+
+Changes between V4.1.2 and V4.1.3 released November 19, 2006
+
+	+ Added STR750 ARM7 port using the Raisonance RIDE/GCC tools.
+	+ Added -fomit-frame-pointer option to Rowley ARM7 demos as work around
+	  to GCC bug at some optimisation levels.
+	+ Altered the way the heap is defined in the LM3S811 Keil demo to prevent
+	  the RAM usage from counting toward the code size limit calculation.
+	+ CO-ROUTINE BUG FIX:  Removed the call to prvIsQueueEmpty from within
+	  xQueueCRReceive as it exited with interrupts enabled.  Thanks Paul Katz.
+	+ Tasks that block on events with a timeout of portMAX_DELAY are now
+	  blocked indefinitely if configINCLUDE_vTaskSuspend is defined.
+	  Previously portMAX_DELAY was just the longest block time possible. This
+	  is still the case if configINCLUDE_vTaskSuspend is not defined.
+	+ Minor changes to some demo application files.
+
+Changes between V4.1.1 and V4.1.2 released October 21, 2006
+
+	+ Added 16bit PIC ports and demos.
+	+ Added STR750 port and demo.
+
+
+Changes between V4.1.0 and V4.1.1 released September 24, 2006
+
+	+ Added the Luminary Micro Stellaris LM3S811 demo application.
+
+Changes between V4.0.5 and V4.1.0 released August 28, 2006
+
+	+ Prior to V4.1.0, under certain documented circumstances, it was possible
+	  for xQueueSend() and xQueueReceive() to return without having completed
+	  and without their block time expiring.  The block time effectively
+	  stated a maximum block time, and the return value of the function needed
+	  to be checked to determine the reason for returning.  This is no longer
+	  the case as the functions will only return once the block time has
+	  expired or they are able to complete their operation.  It is therefore no
+	  longer necessary to wrap calls within loops.
+	+ Changed the critical section handling in the IAR AVR port to correct the
+	  behaviour when used with later compiler versions.
+	+ Added the LPC2138 CrossWorks demo into the zip file.  Previously this was
+	  only available as a separate download.
+	+ Modified the AVR demo applications to demonstrate the use of co-routines.
+
+Changes between V4.0.4 and V4.0.5 released August 13, 2006
+
+	+ Introduced API function xTaskResumeFromISR().  Same functionality as
+	  xTaskResume(), but can be called from within an interrupt service routine.
+	+ Optimised vListInsert() in the case when the wake time is the maximum
+	  tick count value.
+	+ Bug fix:  The 'value' of the event list item is updated when the priority
+	  of a task is changed.  Previously only the priority of the TCB itself was
+	  changed.
+	+ vTaskPrioritySet() and vTaskResume() no longer use the event list item.
+	  This has not been necessary since V4.0.1 when the xMissedYield handling
+	  was added.
+	+ Lowered the PCLK setting on the ARM9 STR9 demo from 96MHz to 48MHz.
+	+ When ending the scheduler - do not try to attempt a context switch when
+	  deleting the current task.
+	+ SAM7X EMAC drivers:  Corrected the Rx frame length mask when obtaining
+	  the length from the rx descriptor.
+
+
+Changes between V4.0.3 and V4.0.4 released June 22, 2006
+
+	+ Added a port and demo application for the STR9 ARM9 based processors from
+	  ST.
+	+ Slight optimisation to the vTaskPrioritySet() function.
+	+ Included the latest uIP version (1.0) in the demo/common/ethernet
+	  directory.
+
+Changes between V4.0.2 and V4.0.3 released June 7, 2006
+
+	+ Added a port and demo application for the Cortex-M3 target using the IAR
+	  development tools.
+	+ The ARM Cortex-m3 Rowley projects have been updated to use V1.6 of the
+	  CrossStudio tools.
+	+ The heap size defined for the lwIP Rowley demo has been reduced so that
+	  the project will link correctly when using the command line GCC tools
+	  also.  The makefile has also been modified to allow debugging.
+	+ The lwIP Rowley demo not includes a 'kernel aware' debug window.
+	+ The uIP Rowley project has been updated to build with V1.6 of CrossWorks.
+	+ The second set of tasks in the blockQ demo were created the wrong way
+	  around (inconsistent to the description in the file).  This has been
+	  corrected.
+
+Changes between V4.0.1 and V4.0.2 released May 28, 2006
+
+	+ Port and demo application added for the Tern Ethernet Engine controller.
+	+ Port and demo application added for MC9S12 using GCC, thanks to
+	  Jefferson "imajeff" Smith.
+	+ The function vTaskList() now suspends the scheduler rather than disabling
+	  interrupts during the creation of the task list.
+	+ Allow a task to delete itself by passing in its own handle.  Previously
+	  this could only be done by passing in NULL.
+	+ Corrected the value passed to the WDG_PeriodValueConfig() library
+	  function in the STR71x demo.
+	+ The tick hook function is now called only within a tick isr.  Previously
+	  it was also called when the tick function was called during the scheduler
+	  unlocking process.
+	+ The EMAC driver in the SAM7X lwIP demo has been made more robust as per
+	  the thread: http://sourceforge.net/forum/message.php?msg_id=3714405
+	+ In the PC ports:  Add function prvSetTickFrequencyDefault() to set the
+	  DOS tick back to its proper value when the scheduler exits.  Thanks
+	  Raynald!
+	+ In the Borland x86 ports there was a mistake in the portFIRST_CONTEXT
+	  macro where the BP register was not popped from the stack correctly.  The
+	  BP value would never get used so this did not cause a problem, but it has
+	  been corrected all the same.
+
+
+Changes between V4.0.0 and V4.0.1 released April 7 2006
+
+	+ Improved the ARM CORTEX M3 ports so they now only have to service
+	  pendSV interrupts.
+	+ Added a Luminary Micro port and demo for use with Rowley CrossWorks.
+	+ Added the xMissedYield handling to tasks.c.
+
+Changes between V3.2.4 and V4.0.0
+
+	Major changes:
+
+	+ Added new RTOS port for Luminary Micros ARM CORTEX M3 microcontrollers.
+	+ Added new co-routine functionality.
+
+	Other kernel changes:
+
+	+ An optional tick hook call is now included in the tick function.
+	+ Introduced the xMiniListItem structure and removed the list pxHead
+	  member in order to reduce RAM usage.
+	+ Added the following definitions to the FreeRTOSConfig.h file included
+	  with every port:
+		configUSE_TICK_HOOK
+		configUSE_CO_ROUTINES
+		configMAX_CO_ROUTINE_PRIORITIES
+	+ The volatile qualification has been changed on the list members to allow
+	  the task.c code to be tidied up a bit.
+	+ The scheduler can now be started even if no tasks have been created!
+	  This is to allow co-routines to run when there are no tasks.
+	+ A task being woken by an event will now preempt the currently running task
+	  even if its priority is only equal to the currently running task.
+
+	Port and demo application changes:
+
+	+ Updated the WinAVR demo to compile with the latest version of WinAVR
+	  with no warnings generated.
+	+ Changed the WinAVR makefile to make chars signed - needed for the
+	  co-routine code if BaseType_t is set to char.
+	+ Added new demo application file crflash.c.  This demonstrates co-routine
+	  functionality including passing data between co-routines.
+	+ Added new demo application file crhook.c.  This demonstrates co-routine
+	  and tick hook functionality including passing data between and ISR and
+	  a co-routine.
+	+ Some NOP's were missing following stmdb{}^ instructions in various ARM7
+	  ports.  These have been added.
+	+ Updated the Open Watcom PC demo project to include the crflash and crhook
+	  demo co-routines as an example of their use.
+	+ Updated the H8S demo to compile with the latest version of GCC.
+	+ Updated the SAM7X EMAC drivers to take into account the hardware errata
+	  regarding lost packets.
+	+ Changed the default MAC address used by some WEB server demos as the
+	  original addresses used was not liked by some routers.
+	+ Modified the SAM7X/IAR startup code slightly to prevent it hanging on
+	  some systems when the code is executed using a j-link debugger.  The
+	  j-link macro file configures the PLL before the code executes so
+	  attempting to configure it again in the startup code was causing a
+	  problem for some user.  Now a check is performed first to see if the
+	  PLL is already set up.
+	+ GCC port now contain all assembler code in a single asm block rather than
+	  individual blocks as before.
+	+ GCC LPC2000 code now explicitly uses R0 rather than letting the assembler
+	  choose the register to use as a temporary register during the context
+	  switch.
+	+ Added portNOP() macro.
+	+ The compare match load value on LPC2000 ports now has 1 added to correct
+	  the value used.
+	+ The minimal stack depth has been increased slightly on the WIZC PIC18
+	  port.
+
+Changes between V3.2.3 and V3.2.4
+
+	+ Modified the GCC ARM7 port layer to allow use with GCC V4.0.0 and above.
+	  Many thanks to Glen Biagioni for the provided update.
+	+ Added a new Microblaze port and demo application.
+	+ Modified the SAM7X EMAC demo to default to use the MII interface rather
+	  than the RMII interface.
+	+ Modified the startup sequence of the SAM7X demo slightly to allow the
+	  EMAC longer to auto negotiate.
+
+Changes between V3.2.2 and V3.2.3
+
+	+ Added MII interface support to the SAM7X EMAC peripheral driver.
+	  Previously versions worked with the RMII interface only.
+	+ Added command line GCC support to the SAM7X lwIP demo.  Previously the
+	  project could only be built using the CrossWorks IDE.  Modifications to
+	  this end include the addition of a standard makefile and linker script to
+	  the download, and some adjustments to the stacks allocated to each task.
+	+ Changed the page returned by the lwIP WEB server demo to display the
+	  task status table rather than the TCP/IP statistics.
+	+ Corrected the capitalisation of some header file includes and makefile
+	  dependencies to facilitate use on Linux host computers.
+	+ The various LPC2000 ports had a mistake in the timer setup where the
+	  prescale value was written to T0_PC instead of T0_PR.  This would have
+	  no effect unless a prescale value was actually required.  This has been
+	  corrected.
+
+Changes between V3.2.1 and V3.2.2 - Released 23 September, 2005
+
+	+ Added an IAR port for the Philips LPC2129
+	+ The Atmel ARM7 IAR demo project files are now saved in the IAR Embedded
+	  Workbench V4.30a format.
+	+ Updated the J-Link macro file included with the SAM7X uIP demo project
+	  to allow the demo board to be reset over the J-Link.
+
+Changes between V3.2.0 and V3.2.1 - Released 1 September, 2005
+
+	+ Added lwIP demo for AT91SAM7X using Rowley tools.
+	+ Added uIP demo for AT91SAM7X using IAR tools.
+	+ Added function xTaskGetCurrentTaskHandle().
+	+ Renamed events.h to mevents.h to prevent it conflicting with the events.h
+	  generated automatically by the HCS12 processor expert utility.  events.h
+	  is only used by the PC demo application.
+	+ Both PIC18 ports now initialise the TBLPTRU to 0 as this is the value
+	  expected by the compiler, and the compilers do not write to this
+	  register.
+	+ The HCS12 banked model demo now creates the 'suicide' tasks immediately
+	  prior to starting the scheduler.  These tasks should be the last tasks to
+	  get started in order for the test to function correctly.
+
+Changes between V3.1.1 and V3.2.0 - Released 29 June, 2005
+
+	V3.2.0 introduces two new MSP430 ports and corrects a minor kernel
+	issues.  Thanks to Ares.qi for his input.
+
+	+ Added two MSP430 ports that use the Rowley CrossWorks development tools.
+	  One port just mirrors the existing GCC port.  The other port was provided
+	  by Milos Prokic.  Thanks!
+	+ V3.2.0 corrects the behavior when vTaskPrioritySet() or vTaskResume()
+	  are called while the scheduler is locked (by a call to
+	  vTaskSuspendAll()).  When this is done the subject task now starts to
+	  execute immediately when the scheduler is unlocked if it has the highest
+	  priority that is ready to run.  Previously there was a possibility that
+	  the task would not run until the next RTOS tick or call to portYIELD().
+	+ Another similar small correction ensures that in the case where more than
+	  one task is blocked on a semaphore or queue, the task with the highest
+	  priority is guaranteed to be unblocked first.
+	+ Added a couple of more test tasks to the PC demo which cover the points
+	  above.
+
+Changes between V3.1.0 and V3.1.1 - Released 21st June, 2005
+
+	This release updates the HCS12 port.  The common kernel code
+	remains unchanged.
+
+	+ Updated the HCS12 port to support banking and introduced a demo
+	  application for the MC9S12DP256.  The new demo application is
+	  located in the Demo/HCS12_CodeWarrior_banked directory.
+	+ The name of the directory containing the MC9S12F32 demo application
+	  has been changed to Demo/HCS12_CodeWarrior_small (as in 'small'
+	  memory model).
+	+ MC9S12F32 demo updated slightly to use the PLL.  The CPU speed for the
+	  demo application is now 24MHz.  Previously it was 8MHz.
+	+ The demo application file Demo/Common/Minimal/death.c has a slight
+	  alteration to prevent it using floating point variables.
+
+
+Changes between V3.0.0 and V3.1.0 - Released 11th June, 2005
+
+	+ Added new ports for ST Microsystems STR71x, and Freescale HCS12
+	  microcontrollers.  Currently the HCS12 port is limited to the small
+	  memory model.  Large memory models will be supported in the next
+	  release.
+	+ PIC18 wizC port updated.  Thanks to Marcel van Lieshout for his
+	  continuing contribution.
+	+ The accuracy of the AVR port timer setup has been improved.  Thanks to
+	  Thomas Krutmann for this contribution.
+	+ Added a new conditional compilation macro configIDLE_SHOULD_YIELD.
+	  See the WEB documentation for details.
+	+ Updated the CrossWorks uIP demo to build with V1.4 of CrossWorks.
+	+ Slight modification to the SAM7 release build configuration to correct
+	  an include path definition.
+	+ Updated the MPLAB PIC18 documentation to provide extra details on linker
+	  file configuration.
+
+Changes between V3.0.0 and V2.6.1 - Released 23rd April, 2005
+
+	V3.0.0 includes many enhancements, so this history list is broken into
+	subsections as follows:
+
+		API changes
+		New ports
+		Directory name changes
+		Kernel and miscellaneous changes changes
+
+	- API changes
+
+		+ Each port now defines BaseType_t as the data type that is most
+		  efficient for that architecture.  The type BaseType_t is used
+		  extensively in API calls necessitating the following changes to the
+		  FreeRTOS API function prototypes.
+
+		  See the "New for V3.0.0" section of the FreeRTOS online
+		  documentation for full details of API changes.
+
+	- New ports
+
+		+ The AT91FR40008 ARM7 port contributed by John Feller is now included
+		  in the download (thanks John!).
+		+ The PIC18 port for the wizC/fedC compiler contributed by Marcel van
+		  Lieshout is now included in the download (thanks Marcel!).
+		+ The IAR port for the AVR microcontroller has been upgraded to V3.0.0
+		  and is now a supported port.
+
+	- Directory name changes
+
+		For consistency, and to allow integration of the new ports, the
+		following directory names have been changed.
+
+		+ The source/portable/GCC/ARM7 directory has been renamed
+		  source/portable/GCC/ARM7_LPC2000 so it is compatible with the naming
+		  of other GCC ARM7 ports.
+		+ The Demo/PIC directory has been renamed Demo/PIC18_MPLAB to
+		  accommodate the wizC/fedC PIC port.
+		+ The demo applications for the two AVR ports no longer share the same
+		  directory.  The WinAVR demo is in the Demo/AVR_ATMega323_WinAVR
+		  directory and the IAR port in the Demo/AVR_ATMega323_IAR directory.
+
+
+	- Kernel and miscellaneous changes changes
+
+		  See the "New for V3.0.0" section of the FreeRTOS online
+		  documentation for more information.
+
+		+ Previously 'portmacro.h' contained some user editable definitions
+		  relating to the user application, and some fixed definitions relating
+		  specifically to the port being used.  The application specific
+		  definitions have been removed from 'portmacro.h' and placed inside a
+		  new header file called 'FreeRTOSConfig.h'.  'portmacro.h' should now
+		  never be modified by the user.  A 'FreeRTOSConfig.h' is now included
+		  in each of FreeRTOS/Demo subdirectories - as it's settings relate to
+		  the demo application rather than being specific to the port.
+		+ Introduced configUSE_IDLE_HOOK in idle task.
+		+ The idle task will yield when another idle priority task is ready to
+		  run. Previously the idle task would run to the end of its time slice
+		  regardless.
+		+ The idle task is now created when the scheduler is started.  This
+		  requires less stack than the previous scheme where it was created upon
+		  creation of the first application task.
+		+ The function usPortCheckFreeStackSpace() has been renamed
+		  usTaskCheckFreeStackSpace() and moved from the portable layer to
+		  tasks.c.
+		+ Corrected spelling of portMINMAL_STACK_SIZE to portMINIMAL_STACK_SIZE.
+		+ The portheap.c file included with the AVR port has been deleted.  The
+		  AVR demo now uses the standard heap1 sample memory allocator.
+		+ The GCC AVR port is now build using the standard make utility.  The
+		  batch files used previously have been deleted.  This means a recent
+		  version of WinAVR is required in order to create a binary suitable for
+		  source level debugging.
+		+ vTaskStartScheduler() no longer takes the configUSE_PREEMPTION
+		  constant as a parameter.  Instead the constant is used directly within
+		  tasks.c  and no parameter is required.
+		+ The header file 'FreeRTOS.h' has been created and is used to include
+		  'projdefs.h', 'FreeRTOSConfig.h' and 'portable.h' in the necessary
+		  order.  FreeRTOS.h can now be included in place of these other
+		  headers.
+		+ The header file 'errors.h' has been deleted.  The definitions it
+		  contained are now located within 'projdefs.h'.
+		+ pvPortMalloc() now takes a size_t parameter as per the ANSI malloc().
+		  Previously an unsigned short was used.
+		+ When resuming the scheduler a yield is performed if either a tick has
+		  been missed, or a task is moved from the pending ready list into a
+		  ready list.  Previously a yield was not performed on this second
+		  condition.
+		+ In heap1.c an overflow check has been added to ensure the next free
+		  byte variable does not wrap around.
+		+ Introduced the portTASK_FUNCTION() and portTASK_FUNCTION_PROTO()
+		  macros.
+		+ The MPLAB PIC port now saved the TABLAT register in interrupt service
+		  routines.
+
+Changes between V2.6.0 and V2.6.1 - Released Feb 22, 2005
+
+	This version adds support for the H8 processor.
+
+	Other changes:
+
+	+ tskMAX_TASK_NAME_LEN removed from the task.h header and added to each
+	  individual portmacro.h file as portMAX_TASK_NAME_LEN.  This allows RAM
+	  limited ports to allocate fewer characters to the task name.
+	+ AVR port - Replaced the inb() and outb() functions with direct memory
+	  access.  This allows the port to be built with the 20050414 build of
+	  WinAVR.
+	+ GCC LPC2106 port - removed the 'static' from the definition of
+	  vNonPreemptiveTick() to allow the demo to link when using the cooperative
+	  scheduler.
+	+ GCC LPC2106 port - Corrected the optimisation options in the batch files
+	  ROM_THUMB.bat, RAM_THUMB.bat, ROM_ARM.bat and RAM_ARM.bat.  The lower case
+	  -o is replaced by an uppercase -O.
+	+ Tasks.c - The strcpy call has been removed when copying across the task
+	  name into the TCB.
+	+ Updated the trace visualisation to always be 4 byte aligned so it can be
+	  used on ARM architectures.
+	+ There are now two tracecon executables (that convert the trace file binary
+	  into an ASCII file).  One for big endian targets and one for little endian
+	  targets.
+	+ Added ucTasksDeleted variable to prevent vTaskSuspendAll() being called
+	  too often in the idle task.
+	+ SAM7 USB driver - Replaced the duplicated RX_DATA_BK0 in the interrupt
+	  mask with the RX_DATA_BK1.
+
+
+Changes between V2.5.5 and V2.6.0 - Released January 16, 2005
+
+	+ Added the API function vTaskDelayUntil().  The demo app file
+	  Demo/Common/Minimal/flash.c has been updated to demonstrate its use.
+	+ Added INCLUDE_vTaskDelay conditional compilation.
+	+ Changed the name of the Demo/ARM7_AtmelSAM7S64_IAR directory to
+	  Demo/ARM7_AT91SAM7S64_IAR for consistency.
+	+ Modified the AT91SAM7S USB driver to allow descriptors that have
+	  a length that is an exact multiple of the FIFO to be transmitted.
+
+Changes between V2.5.4 and V2.5.5 - Released January 3, 2005
+
+	This version adds support for the Atmel SAM7 ARM7 microcontrollers
+	along with the IAR development tools.
+
+	Other changes:
+
+	+ Renamed the Demo/ARM7 directory to Demo/ARM7_LPC2106_GCC.
+	+ Renamed the Demo/ARM7_Keil directory to Demo/ARM7_LPC2129_Keil.
+	+ Modified the Philips ARM7 serial interrupt service routines to only
+	  process one interrupt per call.  This seems to enable the ISR to
+	  operate more quickly.
+	+ Removed the 'far' keyword from the Open Watcom portable layer source
+	  files.  This allows their use with V1.3 of Open Watcom.
+	+ Minor modifications to the SDCC build files to allow their use under
+	  Linux.  Thanks to Frieder Ferlemann for this contribution.
+	+ Small change to sTaskCreate() to allow a context switch even when
+	  pxCreatedTask is NULL.  Thanks to Kamil for this contribution.
+	+ inline keyword removed from vTaskSwitchContext() and VTaskIncrementTick()
+	  definitions.
+
+Changes between V2.5.3 and V2.5.4 - Released Dec 1, 2004
+
+	This is an important maintenance release.
+
+	The function cTaskResumeAll() has been modified so it can be used safely
+	prior to the kernel being initialised.  This was an issue as
+	cTaskResumeAll() is called from pvPortMalloc().  Thanks to Daniel Braun
+	for highlighting this issue.
+
+Changes between V2.5.2 and V2.5.3 - Released Nov 2, 2004
+
+	The critical section handling functions have been changed for the GCC ARM7
+	port.   Some optimisation levels use the stack differently to others.  This
+	means the interrupt flags cannot always be stored on the stack and are
+	instead now stored in a variable, which is then saved as part of the
+	tasks context.  This allows the GCC ARM7 port to be used at all
+	optimisation levels - including -Os.
+
+	Other minor changes:
+
+	+ MSP430 definition of usCriticalNesting now uses the volatile qualifier.
+	  This is probably not required but added just in case.
+
+Changes between V2.5.1 and V2.5.2 - Released Oct 26, 2004
+
+	+ Added the Keil ARM7 port.
+	+ Slight modification to comtest.c to make the delay periods more random.
+	  This creates a better test condition.
+
+Changes between V2.5.0 and V2.5.1 - Released Oct 9, 2004
+
+	+ Added the MSP430 port.
+	+ Extra comments added to the GCC ARM7 port.c and portISR.c files.
+	+ The memory pool allocated within heap_1.c has been placed within a
+	  structure to ensure correct memory alignment on 32bit systems.
+	+ Within the GCC ARM7 serial drivers an extra check is made to ensure
+	  the post to the queue was successful if then attempting immediately
+	  retrieve the posted character.
+	+ Changed the name of the constant portTICKS_PER_MS to portTICK_PERIOD_MS
+	  as the old name was misleading.
+
+
+Changes between V2.4.2 and V2.5.0 - Released Aug 12, 2004
+
+	The RTOS source code download now includes three separate memory allocation
+	schemes - so you can choose the most appropriate for your application.
+	These are found in the Source/Portable/MemMang directory.  The demo
+	application projects have also been updated to demonstrate the new schemes.
+	See the "Memory Management" page of the API documentation for more details.
+
+	+ Added heap_1.c, heap_2.c and heap_3.c in the Source/Portable/MemMang
+	  directory.
+	+ Replaced the portheap.c files for each demo application with one of the
+	  new memory allocation files.
+	+ Updated the portmacro.h file for each demo application to include the
+	  constants required for the new memory allocators: portTOTAL_HEAP_SIZE and
+	  portBYTE_ALIGNMENT.
+	+ Added a new test to the ARM7 demo application that tests the operation
+	  of the heap_2 memory allocator.
+
+
+Changes between V2.4.1 and V2.4.2 - Released July 14, 2004
+
+	+ The ARM7 port now supports THUMB mode.
+	+ Modification to the ARM7 demo application serial port driver.
+
+Changes between V2.4.0 and V2.4.1 - Released July 2, 2004
+
+	+ Rationalised the ARM7 port version of portEXIT_CRITICAL() -
+	  improvements provided by Bill Knight.
+	+ Made demo serial driver more complete and robust.
+
+
+Changes between V2.4.0 and V2.3.1 - Released June 30, 2004
+
+	+ Added the first ARM7 port - thanks to Bill Knight for the assistance
+	  provided.
+	+ Added extra files to the Demo/Common/Minimal directory.  These are
+	  equivalent to their Demo/Common/Full counterparts but with the
+	  calls to the functions defined in print.c removed.
+	+ Added TABLAT to the list of registers saved as part of a PIC18 context.
+
+Changes between V2.3.0 and V2.3.1 - Released June 25, 2004
+
+	+ Changed the way the vector table is defined to be more portable.
+	+ Corrected the definitions of SPH and SPL in portmacro.s90.
+	  The previous definitions prevented V2.3.0 operating if the iom323.h
+	  header file was included in portmacro.s90.
+
+Changes between V2.2.0 and V2.3.0 - Released June 19, 2004
+
+	+ Added an AVR port that uses the IAR compiler.
+	+ Explicit use of 'signed' qualifier on plain char types.
+	+ Modified the Open Watcom project files to use 'signed' as the
+	  default char type.
+	+ Changed odd calculation of initial pxTopOfStack value when
+	  portSTACK_GROWTH < 0.
+	+ Added inline qualifier to context switch functions within task.c.
+	  Ports that do not support the (non ANSI) inline keyword have the
+	  inline #define'd away in  their respective portmacro.h files.
+
+Changes between V2.1.1 and V2.2.0 - Released May 18, 2004
+
+	+ Added Cygnal 8051 port.
+	+ PCLATU and PCLATH are now saved as part of the PIC18 context.  This
+	  allows function pointers to be used within tasks.  Thanks to Javier
+	  Espeche for the enhancement.
+	+ Minor changes to demo application files to reduce stack usage.
+	+ Minor changes to prevent compiler warnings when compiling the new port.
+
+Changes between V2.1.0 and V2.1.1 - Released March 12, 2004
+
+	+ Bug fix - pxCurrentTCB is now initialised before the call to
+	  prvInitialiseTaskLists().  Previously pxCurrentTCB could be accessed
+	  while null during the initialisation sequence.  Thanks to Giuseppe
+	  Franco for the correction.
+
+Changes between V2.0.0 and V2.1.0 - Released Feb 29, 2004
+
+	V2.1.0 has significant reworks that greatly reduce the amount of time
+	the kernel has interrupts disabled.  The first section of modifications
+	listed here must be taken into account by users.  The second section
+	are related to the kernel implementation and as such are transparent.
+
+	Section1 :
+
+	+ The typedef TickType_t has been introduced.  All delay times should
+	  now use a variable of type TickType_t in place of the unsigned long's
+	  used previously.  API function prototypes have been updated
+	  appropriately.
+	+ The configuration macro USE_16_BIT_TICKS has been introduced.  If set
+	  to 1 TickType_t is defined as an unsigned short.  If set to 0
+	  TickType_t is defined as an unsigned long.  See the configuration
+	  section of the API documentation for more details.
+	+ The configuration macro INCLUDE_vTaskSuspendAll is now obsolete.
+	+ vTaskResumeAll() has been renamed cTaskResumeAll() as it now returns a
+	  value (see the API documentation).
+	+ ulTaskGetTickCount() has been renamed xTaskGetTickCount() as the type
+	  it returns now depends on the USE_16_BIT_TICKS definition.
+	+ cQueueReceive() must now >never< be used from within an ISR.  Use the new
+	  cQueueReceiveFromISR() function instead.
+
+	Section 2:
+
+	+ A mechanism has been introduced that allows a queue to be accessed by
+	  a task and ISR simultaneously.
+	+ A "pending ready" queue has been introduced that enables interrupts to
+	  be processed when the scheduler is suspended.
+	+ The list implementation has been improved to provide faster item
+	  removal.
+	+ The scheduler now makes use of the scheduler suspend mechanism in places
+	  where previously interrupts were disabled.
+
+Changes between V1.2.6 and V2.0.0 - Released Jan 31, 2004
+
+	+ Introduced new API functions:
+		vTaskPriorityGet ()
+		vTaskPrioritySet ()
+		vTaskSuspend ()
+		vTaskResume ()
+		vTaskSuspendAll ()
+		vTaskResumeAll ()
+	+ Added conditional compilation options that allow the components of the
+	  kernel that are unused by an application to be excluded from the build.
+	  See the Configuration section on the WEB site for more information (on
+	  the API pages).  The macros have been added to each portmacro.h file (
+	  sometimes called prtmacro.h).
+	+ Rearranged tasks.c.
+	+ Added demo application file dynamic.c.
+	+ Updated the PC demo application to make use of dynamic.c.
+	+ Updated the documentation contained in the kernel header files.
+	+ Creating a task now causes a context switch if the task being created
+	  has a higher priority than the calling task - assuming the kernel is
+	  running.
+	+ vTaskDelete() now only causes a context switch if the calling task is
+	  the task being deleted.
+
+Changes between V1.2.5 and V1.2.6 - Released December 31, 2003
+
+	Barring the change to the interrupt vector (PIC port) these are minor
+	enhancements.
+
+	+ The interrupt vector used for the PIC master ISR has been changed from
+	  0x18 to 0x08 - where it should have always been.  The incorrect address
+	  still works but probably executes a number of NOP's before getting to the
+	  ISR.
+	+ Changed the baud rate used by the AVR demo application to 38400.  This
+	  has an error percentage of less than one percent with an 8MHz clock.
+	+ Raised the priority of the Rx task in demo\full\comtest.c.  This only
+	  affects the Flashlite and PC ports.  This was done to prevent the Rx
+	  buffer becoming full.
+	+ Reverted the Flashlite COM port driver back so it does not use the DMA.
+	  The DMA appears to miss characters under stress.  The Borland Flashlite
+	  port was also calculating a register value incorrectly resulting in the
+	  wrong DMA source address being used.  The same code worked fine when
+	  compiling with Open Watcom.  Other minor enhancements were made to the
+	  interrupt handling.
+	+ Modified the PIC serial Rx ISR to check for and clear overrun errors.
+	  Overrun errors seem to prevent any further characters being received.
+	+ The PIC demo projects now have some optimisation switched on.
+
+
+Changes between V1.2.4 and V1.2.5
+
+	Small fix made to the PIC specific port.c file described below.
+
+	+ Introduced portGLOBAL_INTERRUPT_FLAG definition to test the global
+	  interrupt flag setting.  Using the two bits defined within
+	  portINITAL_INTERRUPT_STATE was causing the w register to get clobbered
+	  before the test was performed.
+
+Changes between V1.2.3 and V1.2.4
+
+	V1.2.4 contains a release version of the PIC18 port.
+	An optional exception has been included with the GPL.  See the licensing
+	section of www.FreeRTOS.org for details.
+
+	+ The function xPortInitMinimal() has been renamed to
+	  xSerialPortInitMinimal() and the function xPortInit() has been renamed
+	  to xSerialPortInit().
+	+ The function sSerialPutChar() has been renamed cSerialPutChar() and
+	  the function return type chaned to portCHAR.
+	+ The integer and flop tasks now include calls to tskYIELD(), allowing
+	  them to be used with the cooperative scheduler.
+	+ All the demo applications now use the integer and comtest tasks when the
+ 	  cooperative scheduler is being used.  Previously they were only used with
+	  the preemptive scheduler.
+	+ Minor changes made to operation of minimal versions of comtest.c and
+	  integer.c.
+	+ The ATMega port definition of portCPU_CLOSK_HZ definition changed to
+	  8MHz base 10, previously it base 16.
+
+
+
+Changes between V1.2.2a and V1.2.3
+
+	The only change of any significance is to the license, which has changed
+	from the Open Software License to the GNU GPL.
+
+	The zip file also contains a pre-release version of the PIC18 port.  This
+	has not yet completed testing and as such does not constitute part of the
+	V1.2.3 release.  It is still however covered by the GNU GPL.
+
+	There are minor source code changes to accommodate the PIC C compiler.
+	These mainly involve more explicit casting.
+
+	+ sTaskCreate() has been modified slightly to make use of the
+	  portSTACK_GROWTH macro.  This is required for the PIC port where the
+	  stack grows in the opposite direction to the other existing ports.
+	+ prvCheckTasksWaitingTermination() has been modified slightly to bring
+	  the decrementing of usCurrentNumberOfTasks within the critical section,
+	  where it should have been since the creation of an eight bit port.
+
+Changes between V1.2.2 and V1.2.2a
+
+	The makefile and buildcoff.bat files included with the AVR demo application
+	have been modified for use with the September 2003 build of WinAVR.  No
+	source files have changed.
+
+Changes between V1.2.1 and V1.2.2
+
+	There are only minor changes here to allow the PC and Flashlite 186 ports
+	to use the Borland V4.52 compiler, as supplied with the Flashlite 186
+	development kit.
+
+	+ Introduced a BCC directory under source\portable.  This contains all the
+	  files specific to the Borland compiler port.
+	+ Corrected the macro naming of portMS_PER_TICK to portTICKS_PER_MS.
+	+ Modified comtest.c to increase the rate at which the string is
+	  transmitted and received on the serial port.  The Flashlite 186 demo
+	  app baud rate has also been increased.
+	+ The values of the constants used in both integer.c files have been
+          increased to force the Borland compiler to use 32 bit values.  The
+          Borland optimiser placed the previous values in 16 bit registers, and in
+          So doing invalidated the test.
+
+Changes between V1.2.0 and V1.2.1
+
+	This version includes some minor changes to the list implementation aimed
+	at improving the context switch time - with is now approximately 10% faster.
+	Changes include the removal of some null pointer assignment checks.  These
+	were redundant where the scheduler uses the list functions, but means any
+	user application choosing to use the same list functions must now check
+	that no NULL pointers are passed as a parameter.
+
+	The Flashlite 186 serial port driver has also been modified to use a DMA
+	channel for transmissions.  The serial driver is fully functional but still
+	under development.  Flashlite users may prefer to use V1.2.0 for now.
+
+	Details:
+
+	+ Changed the baud rate for the ATMega323 serial test from 19200 to 57600.
+	+ Use vSerialPutString() instead of single character puts in
+	  Demo\Full\Comtest.c.  This allows the use of the flashlite DMA serial
+	  driver.  Also the check variable only stops incrementing after two
+	  consecutive failures.
+	+ semtest.c creates four tasks, two of which operate at the idle priority.
+	  The tasks that operate at the idle priority now use a lower expected
+	  count than those running at a higher priority.  This prevents the low
+	  priority tasks from signalling an error because they have not been
+	  scheduled enough time for each of them to count the shared variable to
+	  the higher original value.
+	+ The flashlite 186 serial driver now uses a DMA channel for transmissions.
+	+ Removed the volatile modifier from the list function parameters.  This was
+	  only ever included to prevent compiler warnings.  Now warnings are
+	  removed by casting parameters where the calls are made.
+	+ prvListGetOwnerOfNextEntry() and prvListGetOwnerOfHeadEntry() have been
+	  removed from list.c and added as macros in list.h.
+	+ usNumberOfItems has been added to the list structure.  This removes the
+	  need for a pointer comparison when checking if a list is empty, and so
+	  is slightly faster.
+	+ Removed the NULL check in vListRemove().  This makes the call faster but
+	  necessitates any application code utilising the list implementation to
+	  ensure NULL pointers are not passed.
+	+ Renamed portTICKS_PER_MS definition to portMS_PER_TICK (milli seconds
+	  per tick).  This is what it always should have been.
+
+Changes between V1.01 and V1.2.0
+
+	The majority of these changes were made to accommodate the 8bit AVR port.
+	The scheduler workings have not changed, but some of the data types used
+	have been made more friendly to an eight bit environment.
+
+	Details:
+
+	+ Changed the version numbering format.
+	+ Added AVR port.
+	+ Split the directory demo\common into demo\common\minimal and
+	  demo\common\full.  The files in the full directory are for systems with
+	  a display (currently PC and Flashlite 186 demo's).  The files in the
+	  minimal directory are for systems with limited RAM and no display
+	  (currently MegaAVR).
+	+ Minor changes to demo application function prototypes to make more use
+	  of 8bit data types.
+	+ Within the scheduler itself the following functions have slightly
+	  modified declarations to make use of 8bit data types where possible:
+		xQueueCreate(),
+		sQueueReceive(),
+		sQUeueReceive(),
+		usQueueMessageWaiting(),
+		sQueueSendFromISR(),
+		sSemaphoreTake(),
+		sSemaphoreGive(),
+		sSemaphoreGiveFromISR(),
+		sTaskCreate(),
+		sTaskMoveFromEventList().
+
+	  Where the return type has changed the function name has also changed in
+	  accordance with the naming convention.  For example
+	  usQueueMessageWaiting() has become ucQueueMessageWaiting().
+	+ The definition tskMAX_PRIORITIES has been moved from task.h to
+	  portmacro.h and renamed portMAX_PRIORITIES.  This allows different
+	  ports to allocate a different maximum number of priorities.
+	+ By default the trace facility is off, previously USE_TRACE_FACILITY
+	  was defined.
+	+ comtest.c now uses a psuedo random delay between sends.  This allows for
+	  better testing as the interrupts do not arrive at regular intervals.
+	+ Minor change to the Flashlite serial port driver.  The driver is written
+	  to demonstrate the scheduler and is not written to be efficient.
+
+
+
+Changes between V1.00 and V1.01
+
+	These changes improve the ports.  The scheduler itself has not changed.
+
+	Improved context switch mechanism used when performing a context
+	switch from an ISR (both the tick ISR and the serial comms ISR's within
+	the demo application).  The new mechanism is faster and uses less stack.
+
+	The assembler file portasm.asm has been replaced by a header file
+	portasm.h.  This includes a few assembler macro definitions.
+
+	All saving and restoring of registers onto/off of the stack is now handled
+	by the compiler.  This means the initial stack setup for a task has to
+	mimic the stack used by the compiler, which is different for debug and
+	release builds.
+
+	Slightly changed the operation of the demo application, details below.
+
+	Details:
+
+	+ portSWITCH_CONTEXT() replaced by vPortFirstContext().
+	+ pxPortInitialiseStack() modified to replicate the stack used by the
+	  compiler.
+	+ portasm.asm file removed.
+	+ portasm.h introduced.  This contains macro definitions for
+	  portSWITCH_CONTEXT() and portFIRST_CONTEXT().
+	+ Context switch from ISR now uses the compiler generated interrupt
+	  mechanism.  This is done simply by calling portSWITCH_CONTEXT and leaving
+	  the save/restore to compiler generated code.
+	+ Calls to taskYIELD() during ISR's have been replaced by calling the
+	  simpler and faster portSWITCH_CONTEXT().
+	+ The Flashlite 186 port now uses 186 instruction set (used to use 80x86
+	  instructions only).
+	+ The blocking queue tasks within the demo application did not operate
+	  quite as described.  This has been corrected.
+	+ The priority of the comtest Rx task within the demo application has been
+	  lowered.  Received characters are now processed (read from the queue) at
+	  the idle priority, allowing low priority tasks to run evenly at times of
+	  a high communications overhead.
+	+ Prevent the call to kbhit() in main.c for debug builds as the debugger
+	  seems to have problems stepping over the call.  This if for the PC port
+	  only.
+
+
+

+ 1 - 1
components/freertos/Kconfig

@@ -163,7 +163,7 @@ menu "FreeRTOS"
     config FREERTOS_IDLE_TASK_STACKSIZE
         int "Idle Task stack size"
         range 768 32768
-        default 1536
+        default 2304
         help
             The idle task has its own stack, sized in bytes. The default size is enough for most uses. Size can be
             reduced to 768 bytes if no (or simple) FreeRTOS idle hooks are used and pthread local storage or FreeRTOS

+ 31 - 69
components/freertos/croutine.c

@@ -1,76 +1,37 @@
 /*
-    FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
-    All rights reserved
-
-    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License (version 2) as published by the
-    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
-
-	***************************************************************************
-    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
-    >>!   distribute a combined work that includes FreeRTOS without being   !<<
-    >>!   obliged to provide the source code for proprietary components     !<<
-    >>!   outside of the FreeRTOS kernel.                                   !<<
-	***************************************************************************
-
-    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
-    link: http://www.freertos.org/a00114.html
-
-    ***************************************************************************
-     *                                                                       *
-     *    FreeRTOS provides completely free yet professionally developed,    *
-     *    robust, strictly quality controlled, supported, and cross          *
-     *    platform software that is more than just the market leader, it     *
-     *    is the industry's de facto standard.                               *
-     *                                                                       *
-     *    Help yourself get started quickly while simultaneously helping     *
-     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
-     *    tutorial book, reference manual, or both:                          *
-     *    http://www.FreeRTOS.org/Documentation                              *
-     *                                                                       *
-    ***************************************************************************
-
-    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
-	the FAQ page "My application does not run, what could be wrong?".  Have you
-	defined configASSERT()?
-
-	http://www.FreeRTOS.org/support - In return for receiving this top quality
-	embedded software for free we request you assist our global community by
-	participating in the support forum.
-
-	http://www.FreeRTOS.org/training - Investing in training allows your team to
-	be as productive as possible as early as possible.  Now you can receive
-	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
-	Ltd, and the world's leading authority on the world's leading RTOS.
-
-    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
-    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
-    compatible FAT file system, and our tiny thread aware UDP/IP stack.
-
-    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
-    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
-
-    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
-    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
-    licenses offer ticketed support, indemnification and commercial middleware.
-
-    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
-    engineered and independently SIL3 certified version for use in safety and
-    mission critical applications that require provable dependability.
-
-    1 tab == 4 spaces!
-*/
+ * FreeRTOS Kernel V10.2.1
+ * 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!
+ */
 
 #include "FreeRTOS.h"
 #include "task.h"
 #include "croutine.h"
 
+/* Remove the whole file is co-routines are not being used. */
+#if( configUSE_CO_ROUTINES != 0 )
+
 /*
  * Some kernel aware debuggers require data to be viewed to be global, rather
  * than file scope.
@@ -143,7 +104,6 @@ BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPri
 BaseType_t xReturn;
 CRCB_t *pxCoRoutine;
 
-	UNTESTED_FUNCTION(); //Actually, coroutines are entirely unsupported
 	/* Allocate the memory that will store the co-routine control block. */
 	pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
 	if( pxCoRoutine )
@@ -300,7 +260,7 @@ CRCB_t *pxCRCB;
 				( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
 
 				/* Is the co-routine waiting on an event also? */
-				if( pxCRCB->xEventListItem.pvContainer )
+				if( pxCRCB->xEventListItem.pxContainer )
 				{
 					( void ) uxListRemove( &( pxCRCB->xEventListItem ) );
 				}
@@ -389,3 +349,5 @@ BaseType_t xReturn;
 	return xReturn;
 }
 
+#endif /* configUSE_CO_ROUTINES == 0 */
+

+ 133 - 156
components/freertos/event_groups.c

@@ -1,71 +1,29 @@
 /*
-    FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
-    All rights reserved
-
-    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License (version 2) as published by the
-    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
-
-	***************************************************************************
-    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
-    >>!   distribute a combined work that includes FreeRTOS without being   !<<
-    >>!   obliged to provide the source code for proprietary components     !<<
-    >>!   outside of the FreeRTOS kernel.                                   !<<
-	***************************************************************************
-
-    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
-    link: http://www.freertos.org/a00114.html
-
-    ***************************************************************************
-     *                                                                       *
-     *    FreeRTOS provides completely free yet professionally developed,    *
-     *    robust, strictly quality controlled, supported, and cross          *
-     *    platform software that is more than just the market leader, it     *
-     *    is the industry's de facto standard.                               *
-     *                                                                       *
-     *    Help yourself get started quickly while simultaneously helping     *
-     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
-     *    tutorial book, reference manual, or both:                          *
-     *    http://www.FreeRTOS.org/Documentation                              *
-     *                                                                       *
-    ***************************************************************************
-
-    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
-	the FAQ page "My application does not run, what could be wrong?".  Have you
-	defined configASSERT()?
-
-	http://www.FreeRTOS.org/support - In return for receiving this top quality
-	embedded software for free we request you assist our global community by
-	participating in the support forum.
-
-	http://www.FreeRTOS.org/training - Investing in training allows your team to
-	be as productive as possible as early as possible.  Now you can receive
-	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
-	Ltd, and the world's leading authority on the world's leading RTOS.
-
-    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
-    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
-    compatible FAT file system, and our tiny thread aware UDP/IP stack.
-
-    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
-    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
-
-    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
-    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
-    licenses offer ticketed support, indemnification and commercial middleware.
-
-    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
-    engineered and independently SIL3 certified version for use in safety and
-    mission critical applications that require provable dependability.
-
-    1 tab == 4 spaces!
-*/
+ * FreeRTOS Kernel V10.2.1
+ * 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!
+ */
 
 /* Standard includes. */
 #include <stdlib.h>
@@ -81,19 +39,11 @@ task.h is included from an application file. */
 #include "timers.h"
 #include "event_groups.h"
 
-/* Lint 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. */
-
-#if ( INCLUDE_xEventGroupSetBitFromISR == 1 ) && ( configUSE_TIMERS == 0 )
-	#error configUSE_TIMERS must be set to 1 to make the xEventGroupSetBitFromISR() function available.
-#endif
-
-#if ( INCLUDE_xEventGroupSetBitFromISR == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 0 )
-	#error INCLUDE_xTimerPendFunctionCall must also be set to one to make the xEventGroupSetBitFromISR() function available.
-#endif
+/* Lint e961, e750 and e9021 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 See comment above. */
 
 /* The following bit fields convey control information in a task's event list
 item value.  It is important they don't clash with the
@@ -110,7 +60,7 @@ taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
 	#define eventEVENT_BITS_CONTROL_BYTES	0xff000000UL
 #endif
 
-typedef struct xEventGroupDefinition
+typedef struct EventGroupDef_t
 {
 	EventBits_t uxEventBits;
 	List_t xTasksWaitingForBits;		/*< List of tasks waiting for a bit to be set. */
@@ -126,7 +76,6 @@ typedef struct xEventGroupDefinition
 	portMUX_TYPE eventGroupMux;		//Mutex required due to SMP
 } EventGroup_t;
 
-
 /*-----------------------------------------------------------*/
 
 /*
@@ -137,7 +86,7 @@ typedef struct xEventGroupDefinition
  * wait condition is met if any of the bits set in uxBitsToWait for are also set
  * in uxCurrentEventBits.
  */
-static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits );
+static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION;
 
 /*-----------------------------------------------------------*/
 
@@ -150,8 +99,18 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
 		/* A StaticEventGroup_t object must be provided. */
 		configASSERT( pxEventGroupBuffer );
 
+		#if( configASSERT_DEFINED == 1 )
+		{
+			/* Sanity check that the size of the structure used to declare a
+			variable of type StaticEventGroup_t equals the size of the real
+			event group structure. */
+			volatile size_t xSize = sizeof( StaticEventGroup_t );
+			configASSERT( xSize == sizeof( EventGroup_t ) );
+		} /*lint !e529 xSize is referenced if configASSERT() is defined. */
+		#endif /* configASSERT_DEFINED */
+
 		/* The user has provided a statically allocated event group - use it. */
-		pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 EventGroup_t and StaticEventGroup_t are guaranteed to have the same size and alignment requirement - checked by configASSERT(). */
+		pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 !e9087 EventGroup_t and StaticEventGroup_t are deliberately aliased for data hiding purposes and guaranteed to have the same size and alignment requirement - checked by configASSERT(). */
 
 		if( pxEventBits != NULL )
 		{
@@ -167,16 +126,19 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
 			}
 			#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
 
-			vPortCPUInitializeMutex(&pxEventBits->eventGroupMux);
-
 			traceEVENT_GROUP_CREATE( pxEventBits );
+
+			vPortCPUInitializeMutex( &pxEventBits->eventGroupMux );
 		}
 		else
 		{
+			/* xEventGroupCreateStatic should only ever be called with
+			pxEventGroupBuffer pointing to a pre-allocated (compile time
+			allocated) StaticEventGroup_t variable. */
 			traceEVENT_GROUP_CREATE_FAILED();
 		}
 
-		return ( EventGroupHandle_t ) pxEventBits;
+		return pxEventBits;
 	}
 
 #endif /* configSUPPORT_STATIC_ALLOCATION */
@@ -188,8 +150,20 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
 	{
 	EventGroup_t *pxEventBits;
 
-		/* Allocate the event group. */
-		pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) );
+		/* Allocate the event group.  Justification for MISRA deviation as
+		follows:  pvPortMalloc() always ensures returned memory blocks are
+		aligned per the requirements of the MCU stack.  In this case
+		pvPortMalloc() must return a pointer that is guaranteed to meet the
+		alignment requirements of the EventGroup_t structure - which (if you
+		follow it through) is the alignment requirements of the TickType_t type
+		(EventBits_t being of TickType_t itself).  Therefore, whenever the
+		stack alignment requirements are greater than or equal to the
+		TickType_t alignment requirements the cast is safe.  In other cases,
+		where the natural word size of the architecture is less than
+		sizeof( TickType_t ), the TickType_t variables will be accessed in two
+		or more reads operations, and the alignment requirements is only that
+		of each individual read. */
+		pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */
 
 		if( pxEventBits != NULL )
 		{
@@ -205,16 +179,16 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
 			}
 			#endif /* configSUPPORT_STATIC_ALLOCATION */
 
-			vPortCPUInitializeMutex(&pxEventBits->eventGroupMux);
+			vPortCPUInitializeMutex( &pxEventBits->eventGroupMux );
 
 			traceEVENT_GROUP_CREATE( pxEventBits );
 		}
 		else
 		{
-			traceEVENT_GROUP_CREATE_FAILED();
+			traceEVENT_GROUP_CREATE_FAILED(); /*lint !e9063 Else branch only exists to allow tracing and does not generate code if trace macros are not defined. */
 		}
 
-		return ( EventGroupHandle_t ) pxEventBits;
+		return pxEventBits;
 	}
 
 #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
@@ -223,8 +197,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
 EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )
 {
 EventBits_t uxOriginalBitValue, uxReturn;
-EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
-BaseType_t xAlreadyYielded;
+EventGroup_t *pxEventBits = xEventGroup;
+BaseType_t xAlreadyYielded = pdFALSE;
 BaseType_t xTimeoutOccurred = pdFALSE;
 
 	configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
@@ -235,8 +209,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
 	}
 	#endif
 
-	vTaskSuspendAll();
-	taskENTER_CRITICAL(&pxEventBits->eventGroupMux);
+	taskENTER_CRITICAL( &pxEventBits->eventGroupMux );
 	{
 		uxOriginalBitValue = pxEventBits->uxEventBits;
 
@@ -275,11 +248,12 @@ BaseType_t xTimeoutOccurred = pdFALSE;
 				/* The rendezvous bits were not set, but no block time was
 				specified - just return the current event bit value. */
 				uxReturn = pxEventBits->uxEventBits;
+				xTimeoutOccurred = pdTRUE;
 			}
 		}
 	}
+	
 	taskEXIT_CRITICAL( &pxEventBits->eventGroupMux );
-	xAlreadyYielded = xTaskResumeAll();
 
 	if( xTicksToWait != ( TickType_t ) 0 )
 	{
@@ -334,15 +308,18 @@ BaseType_t xTimeoutOccurred = pdFALSE;
 
 	traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred );
 
+	/* Prevent compiler warnings when trace macros are not used. */
+	( void ) xTimeoutOccurred;
+
 	return uxReturn;
 }
 /*-----------------------------------------------------------*/
 
 EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
 {
-EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
+EventGroup_t *pxEventBits = xEventGroup;
 EventBits_t uxReturn, uxControlBits = 0;
-BaseType_t xWaitConditionMet, xAlreadyYielded;
+BaseType_t xWaitConditionMet;
 BaseType_t xTimeoutOccurred = pdFALSE;
 
 	/* Check the user is not attempting to wait on the bits used by the kernel
@@ -356,7 +333,6 @@ BaseType_t xTimeoutOccurred = pdFALSE;
 	}
 	#endif
 
-	vTaskSuspendAll();
 	taskENTER_CRITICAL( &pxEventBits->eventGroupMux );
 	{
 		const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits;
@@ -386,6 +362,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
 			/* The wait condition has not been met, but no block time was
 			specified, so just return the current value. */
 			uxReturn = uxCurrentEventBits;
+			xTimeoutOccurred = pdTRUE;
 		}
 		else
 		{
@@ -424,19 +401,12 @@ BaseType_t xTimeoutOccurred = pdFALSE;
 			traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
 		}
 	}
+
 	taskEXIT_CRITICAL( &pxEventBits->eventGroupMux );
-	xAlreadyYielded = xTaskResumeAll();
 
 	if( xTicksToWait != ( TickType_t ) 0 )
 	{
-		if( xAlreadyYielded == pdFALSE )
-		{
-			portYIELD_WITHIN_API();
-		}
-		else
-		{
-			mtCOVERAGE_TEST_MARKER();
-		}
+		portYIELD_WITHIN_API();
 
 		/* The task blocked to wait for its required bits to be set - at this
 		point either the required bits were set or the block time expired.  If
@@ -468,11 +438,9 @@ BaseType_t xTimeoutOccurred = pdFALSE;
 				{
 					mtCOVERAGE_TEST_MARKER();
 				}
+				xTimeoutOccurred = pdTRUE;
 			}
 			taskEXIT_CRITICAL( &pxEventBits->eventGroupMux );
-
-			/* Prevent compiler warnings when trace macros are not used. */
-			xTimeoutOccurred = pdFALSE;
 		}
 		else
 		{
@@ -484,13 +452,16 @@ BaseType_t xTimeoutOccurred = pdFALSE;
 	}
 	traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
 
+	/* Prevent compiler warnings when trace macros are not used. */
+	( void ) xTimeoutOccurred;
+
 	return uxReturn;
 }
 /*-----------------------------------------------------------*/
 
 EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
 {
-EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
+EventGroup_t *pxEventBits = xEventGroup;
 EventBits_t uxReturn;
 
 	/* Check the user is not attempting to clear the bits used by the kernel
@@ -522,7 +493,7 @@ EventBits_t uxReturn;
 		BaseType_t xReturn;
 
 		traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );
-		xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL );
+		xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */
 
 		return xReturn;
 	}
@@ -533,7 +504,7 @@ EventBits_t uxReturn;
 EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
 {
 UBaseType_t uxSavedInterruptStatus;
-EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
+EventGroup_t const * const pxEventBits = xEventGroup;
 EventBits_t uxReturn;
 
 	uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
@@ -543,16 +514,16 @@ EventBits_t uxReturn;
 	portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
 
 	return uxReturn;
-}
+} /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */
 /*-----------------------------------------------------------*/
 
 EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
 {
 ListItem_t *pxListItem, *pxNext;
 ListItem_t const *pxListEnd;
-List_t *pxList;
+List_t const * pxList;
 EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
-EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
+EventGroup_t *pxEventBits = xEventGroup;
 BaseType_t xMatchFound = pdFALSE;
 
 	/* Check the user is not attempting to set the bits used by the kernel
@@ -561,10 +532,9 @@ BaseType_t xMatchFound = pdFALSE;
 	configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
 
 	pxList = &( pxEventBits->xTasksWaitingForBits );
-	pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
+	pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
 
-	vTaskSuspendAll();
-	taskENTER_CRITICAL(&pxEventBits->eventGroupMux);
+	taskENTER_CRITICAL( &pxEventBits->eventGroupMux );
 	{
 		traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet );
 
@@ -623,7 +593,7 @@ BaseType_t xMatchFound = pdFALSE;
 				eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
 				that is was unblocked due to its required bits matching, rather
 				than because it timed out. */
-				( void ) xTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
+				xTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
 			}
 
 			/* Move onto the next list item.  Note pxListItem->pxNext is not
@@ -636,8 +606,7 @@ BaseType_t xMatchFound = pdFALSE;
 		bit was set in the control word. */
 		pxEventBits->uxEventBits &= ~uxBitsToClear;
 	}
-	taskEXIT_CRITICAL(&pxEventBits->eventGroupMux);
-	( void ) xTaskResumeAll();
+	taskEXIT_CRITICAL( &pxEventBits->eventGroupMux );
 
 	return pxEventBits->uxEventBits;
 }
@@ -645,47 +614,43 @@ BaseType_t xMatchFound = pdFALSE;
 
 void vEventGroupDelete( EventGroupHandle_t xEventGroup )
 {
-	EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
-	const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
+EventGroup_t *pxEventBits = xEventGroup;
+const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
+
+	traceEVENT_GROUP_DELETE( xEventGroup );
 
-	vTaskSuspendAll();
 	taskENTER_CRITICAL( &pxEventBits->eventGroupMux );
 	{
-		traceEVENT_GROUP_DELETE( xEventGroup );
-
 		while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
 		{
 			/* Unblock the task, returning 0 as the event list is being deleted
-			and	cannot therefore have any bits set. */
-			configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
-			( void ) xTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
+			and cannot therefore have any bits set. */
+			configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
+			xTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
 		}
+	}
+	taskEXIT_CRITICAL( &pxEventBits->eventGroupMux );
 
-		#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
+	#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
+	{
+		/* The event group can only have been allocated dynamically - free
+		it again. */
+		vPortFree( pxEventBits );
+	}
+	#elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
+	{
+		/* The event group could have been allocated statically or
+		dynamically, so check before attempting to free the memory. */
+		if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
 		{
-			/* The event group can only have been allocated dynamically - free
-			it again. */
-			taskEXIT_CRITICAL( &pxEventBits->eventGroupMux );
 			vPortFree( pxEventBits );
 		}
-		#elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
+		else
 		{
-			/* The event group could have been allocated statically or
-			dynamically, so check before attempting to free the memory. */
-			if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
-			{
-			    taskEXIT_CRITICAL( &pxEventBits->eventGroupMux );   //Exit mux of event group before deleting it
-			    vPortFree( pxEventBits );
-			}
-			else
-			{
-			    taskEXIT_CRITICAL( &pxEventBits->eventGroupMux );
-			    mtCOVERAGE_TEST_MARKER();
-			}
+			mtCOVERAGE_TEST_MARKER();
 		}
-		#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
 	}
-	( void ) xTaskResumeAll();
+	#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
 }
 /*-----------------------------------------------------------*/
 
@@ -693,7 +658,7 @@ void vEventGroupDelete( EventGroupHandle_t xEventGroup )
 an interrupt. */
 void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet )
 {
-	( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet );
+	( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
 }
 /*-----------------------------------------------------------*/
 
@@ -701,7 +666,7 @@ void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet
 an interrupt. */
 void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear )
 {
-	( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear );
+	( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
 }
 /*-----------------------------------------------------------*/
 
@@ -747,7 +712,7 @@ BaseType_t xWaitConditionMet = pdFALSE;
 	BaseType_t xReturn;
 
 		traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
-		xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );
+		xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */
 
 		return xReturn;
 	}
@@ -760,7 +725,7 @@ BaseType_t xWaitConditionMet = pdFALSE;
 	UBaseType_t uxEventGroupGetNumber( void* xEventGroup )
 	{
 	UBaseType_t xReturn;
-	EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
+	EventGroup_t const *pxEventBits = ( EventGroup_t * ) xEventGroup; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */
 
 		if( xEventGroup == NULL )
 		{
@@ -774,5 +739,17 @@ BaseType_t xWaitConditionMet = pdFALSE;
 		return xReturn;
 	}
 
-#endif
+#endif /* configUSE_TRACE_FACILITY */
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+	void vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber )
+	{
+		( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */
+	}
+
+#endif /* configUSE_TRACE_FACILITY */
+/*-----------------------------------------------------------*/
+
 

+ 447 - 180
components/freertos/include/freertos/FreeRTOS.h

@@ -1,71 +1,29 @@
 /*
-    FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
-    All rights reserved
-
-    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License (version 2) as published by the
-    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
-
-	***************************************************************************
-    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
-    >>!   distribute a combined work that includes FreeRTOS without being   !<<
-    >>!   obliged to provide the source code for proprietary components     !<<
-    >>!   outside of the FreeRTOS kernel.                                   !<<
-	***************************************************************************
-
-    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
-    link: http://www.freertos.org/a00114.html
-
-    ***************************************************************************
-     *                                                                       *
-     *    FreeRTOS provides completely free yet professionally developed,    *
-     *    robust, strictly quality controlled, supported, and cross          *
-     *    platform software that is more than just the market leader, it     *
-     *    is the industry's de facto standard.                               *
-     *                                                                       *
-     *    Help yourself get started quickly while simultaneously helping     *
-     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
-     *    tutorial book, reference manual, or both:                          *
-     *    http://www.FreeRTOS.org/Documentation                              *
-     *                                                                       *
-    ***************************************************************************
-
-    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
-	the FAQ page "My application does not run, what could be wrong?".  Have you
-	defined configASSERT()?
-
-	http://www.FreeRTOS.org/support - In return for receiving this top quality
-	embedded software for free we request you assist our global community by
-	participating in the support forum.
-
-	http://www.FreeRTOS.org/training - Investing in training allows your team to
-	be as productive as possible as early as possible.  Now you can receive
-	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
-	Ltd, and the world's leading authority on the world's leading RTOS.
-
-    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
-    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
-    compatible FAT file system, and our tiny thread aware UDP/IP stack.
-
-    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
-    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
-
-    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
-    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
-    licenses offer ticketed support, indemnification and commercial middleware.
-
-    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
-    engineered and independently SIL3 certified version for use in safety and
-    mission critical applications that require provable dependability.
-
-    1 tab == 4 spaces!
-*/
+ * FreeRTOS Kernel V10.2.1
+ * 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 INC_FREERTOS_H
 #define INC_FREERTOS_H
@@ -74,7 +32,6 @@
  * Include the generic headers required for the FreeRTOS port being used.
  */
 #include <stddef.h>
-#include "sys/reent.h"
 
 /*
  * If stdint.h cannot be located then:
@@ -106,6 +63,15 @@ extern "C" {
 /* Definitions specific to the port being used. */
 #include "portable.h"
 
+/* 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.
  * These macros are application specific and (as downloaded) are defined
@@ -120,6 +86,10 @@ extern "C" {
 	#error Missing definition:  configMAX_PRIORITIES must be defined in FreeRTOSConfig.h.  See the Configuration section of the FreeRTOS API documentation for details.
 #endif
 
+#if configMAX_PRIORITIES < 1
+	#error configMAX_PRIORITIES must be defined to be greater than or equal to 1.
+#endif
+
 #ifndef configUSE_PREEMPTION
 	#error Missing definition:  configUSE_PREEMPTION must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
 #endif
@@ -132,54 +102,44 @@ extern "C" {
 	#error Missing definition:  configUSE_TICK_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
 #endif
 
+#ifndef configUSE_16_BIT_TICKS
+	#error Missing definition:  configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
 #ifndef configUSE_CO_ROUTINES
-	#error  Missing definition:  configUSE_CO_ROUTINES must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
+	#define configUSE_CO_ROUTINES 0
 #endif
 
 #ifndef INCLUDE_vTaskPrioritySet
-	#error Missing definition:  INCLUDE_vTaskPrioritySet must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
+	#define INCLUDE_vTaskPrioritySet 0
 #endif
 
 #ifndef INCLUDE_uxTaskPriorityGet
-	#error Missing definition:  INCLUDE_uxTaskPriorityGet must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
+	#define INCLUDE_uxTaskPriorityGet 0
 #endif
 
 #ifndef INCLUDE_vTaskDelete
-	#error Missing definition:  INCLUDE_vTaskDelete must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
+	#define INCLUDE_vTaskDelete 0
 #endif
 
 #ifndef INCLUDE_vTaskSuspend
-	#error Missing definition:  INCLUDE_vTaskSuspend must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
+	#define INCLUDE_vTaskSuspend 0
 #endif
 
 #ifndef INCLUDE_vTaskDelayUntil
-	#error Missing definition:  INCLUDE_vTaskDelayUntil must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
+	#define INCLUDE_vTaskDelayUntil 0
 #endif
 
 #ifndef INCLUDE_vTaskDelay
-	#error Missing definition:  INCLUDE_vTaskDelay must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
-#endif
-
-#ifndef configUSE_16_BIT_TICKS
-	#error Missing definition:  configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
-#endif
-
-#if configUSE_CO_ROUTINES != 0
-	#ifndef configMAX_CO_ROUTINE_PRIORITIES
-		#error configMAX_CO_ROUTINE_PRIORITIES must be greater than or equal to 1.
-	#endif
-#endif
-
-#ifndef configMAX_PRIORITIES
-	#error configMAX_PRIORITIES must be defined to be greater than or equal to 1.
+	#define INCLUDE_vTaskDelay 0
 #endif
 
 #ifndef INCLUDE_xTaskGetIdleTaskHandle
 	#define INCLUDE_xTaskGetIdleTaskHandle 0
 #endif
 
-#ifndef INCLUDE_xTimerGetTimerDaemonTaskHandle
-	#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
+#ifndef INCLUDE_xTaskAbortDelay
+	#define INCLUDE_xTaskAbortDelay 0
 #endif
 
 #ifndef INCLUDE_xQueueGetMutexHolder
@@ -190,26 +150,56 @@ extern "C" {
 	#define INCLUDE_xSemaphoreGetMutexHolder INCLUDE_xQueueGetMutexHolder
 #endif
 
-#ifndef INCLUDE_pcTaskGetTaskName
-	#define INCLUDE_pcTaskGetTaskName 1
-#endif
-
-#ifndef configUSE_APPLICATION_TASK_TAG
-	#define configUSE_APPLICATION_TASK_TAG 0
+#ifndef INCLUDE_xTaskGetHandle
+	#define INCLUDE_xTaskGetHandle 0
 #endif
 
 #ifndef INCLUDE_uxTaskGetStackHighWaterMark
 	#define INCLUDE_uxTaskGetStackHighWaterMark 0
 #endif
 
-#ifndef INCLUDE_pxTaskGetStackStart
-	#define INCLUDE_pxTaskGetStackStart 0
+#ifndef INCLUDE_uxTaskGetStackHighWaterMark2
+	#define INCLUDE_uxTaskGetStackHighWaterMark2 0
 #endif
 
 #ifndef INCLUDE_eTaskGetState
 	#define INCLUDE_eTaskGetState 0
 #endif
 
+#ifndef INCLUDE_xTaskResumeFromISR
+	#define INCLUDE_xTaskResumeFromISR 1
+#endif
+
+#ifndef INCLUDE_xTimerPendFunctionCall
+	#define INCLUDE_xTimerPendFunctionCall 0
+#endif
+
+#ifndef INCLUDE_xTaskGetSchedulerState
+	#define INCLUDE_xTaskGetSchedulerState 0
+#endif
+
+#ifndef INCLUDE_xTaskGetCurrentTaskHandle
+	#define INCLUDE_xTaskGetCurrentTaskHandle 0
+#endif
+
+#if configUSE_CO_ROUTINES != 0
+	#ifndef configMAX_CO_ROUTINE_PRIORITIES
+		#error configMAX_CO_ROUTINE_PRIORITIES must be greater than or equal to 1.
+	#endif
+#endif
+
+#ifndef configUSE_DAEMON_TASK_STARTUP_HOOK
+	#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
+#endif
+
+#ifndef configUSE_APPLICATION_TASK_TAG
+	#define configUSE_APPLICATION_TASK_TAG 0
+#endif
+
+#ifndef configNUM_THREAD_LOCAL_STORAGE_POINTERS
+	#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0
+#endif
+
 #ifndef configUSE_RECURSIVE_MUTEXES
 	#define configUSE_RECURSIVE_MUTEXES 0
 #endif
@@ -246,18 +236,6 @@ extern "C" {
 	#error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h
 #endif
 
-#ifndef INCLUDE_xTaskResumeFromISR
-	#define INCLUDE_xTaskResumeFromISR 1
-#endif
-
-#ifndef INCLUDE_xEventGroupSetBitFromISR
-	#define INCLUDE_xEventGroupSetBitFromISR 0
-#endif
-
-#ifndef INCLUDE_xTimerPendFunctionCall
-	#define INCLUDE_xTimerPendFunctionCall 0
-#endif
-
 #ifndef configASSERT
 	#define configASSERT( x )
 	#define configASSERT_DEFINED 0
@@ -265,6 +243,22 @@ extern "C" {
 	#define configASSERT_DEFINED 1
 #endif
 
+/* configPRECONDITION should be resolve to configASSERT.
+   The CBMC proofs need a way to track assumptions and assertions.
+   A configPRECONDITION statement should express an implicit invariant or assumption made.
+   A configASSERT statement should express an invariant that must hold explicit before calling
+   the code. */
+#ifndef configPRECONDITION
+	#define configPRECONDITION( X ) configASSERT(X)
+	#define configPRECONDITION_DEFINED 0
+#else
+	#define configPRECONDITION_DEFINED 1
+#endif
+
+#ifndef portMEMORY_BARRIER
+	#define portMEMORY_BARRIER()
+#endif
+
 /* The timers module relies on xTaskGetSchedulerState(). */
 #if configUSE_TIMERS == 1
 
@@ -282,15 +276,6 @@ extern "C" {
 
 #endif /* configUSE_TIMERS */
 
-#ifndef INCLUDE_xTaskGetSchedulerState
-	#define INCLUDE_xTaskGetSchedulerState 0
-#endif
-
-#ifndef INCLUDE_xTaskGetCurrentTaskHandle
-	#define INCLUDE_xTaskGetCurrentTaskHandle 0
-#endif
-
-
 #ifndef portSET_INTERRUPT_MASK_FROM_ISR
 	#define portSET_INTERRUPT_MASK_FROM_ISR() 0
 #endif
@@ -318,6 +303,7 @@ extern "C" {
 #if ( configQUEUE_REGISTRY_SIZE < 1 )
 	#define vQueueAddToRegistry( xQueue, pcName )
 	#define vQueueUnregisterQueue( xQueue )
+	#define pcQueueGetName( xQueue )
 #endif
 
 #ifndef portPOINTER_SIZE_TYPE
@@ -390,6 +376,14 @@ extern "C" {
 	#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue )
 #endif
 
+#ifndef traceBLOCKING_ON_QUEUE_PEEK
+	/* Task is about to block because it cannot read from a
+	queue/mutex/semaphore.  pxQueue is a pointer to the queue/mutex/semaphore
+	upon which the read was attempted.  pxCurrentTCB points to the TCB of the
+	task that attempted the read. */
+	#define traceBLOCKING_ON_QUEUE_PEEK( pxQueue )
+#endif
+
 #ifndef traceBLOCKING_ON_QUEUE_SEND
 	/* Task is about to block because it cannot write to a
 	queue/mutex/semaphore.  pxQueue is a pointer to the queue/mutex/semaphore
@@ -402,26 +396,22 @@ extern "C" {
 	#define configCHECK_FOR_STACK_OVERFLOW 0
 #endif
 
-/* The following event macros are embedded in the kernel API calls. */
-
-#ifndef traceMOVED_TASK_TO_READY_STATE
-	#define traceMOVED_TASK_TO_READY_STATE( pxTCB )
+#ifndef configRECORD_STACK_HIGH_ADDRESS
+	#define configRECORD_STACK_HIGH_ADDRESS 0
 #endif
 
-#ifndef traceREADDED_TASK_TO_READY_STATE
-	#define traceREADDED_TASK_TO_READY_STATE( pxTCB )	traceMOVED_TASK_TO_READY_STATE( pxTCB )
+#ifndef configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H
+	#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 0
 #endif
 
-#ifndef traceMOVED_TASK_TO_DELAYED_LIST
-	#define traceMOVED_TASK_TO_DELAYED_LIST()
-#endif
+/* The following event macros are embedded in the kernel API calls. */
 
-#ifndef traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST
-	#define traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST()
+#ifndef traceMOVED_TASK_TO_READY_STATE
+	#define traceMOVED_TASK_TO_READY_STATE( pxTCB )
 #endif
 
-#ifndef traceMOVED_TASK_TO_SUSPENDED_LIST
-	#define traceMOVED_TASK_TO_SUSPENDED_LIST( pxTCB )
+#ifndef tracePOST_MOVED_TASK_TO_READY_STATE
+	#define tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB )
 #endif
 
 #ifndef traceQUEUE_CREATE
@@ -464,6 +454,10 @@ extern "C" {
 	#define traceCREATE_COUNTING_SEMAPHORE_FAILED()
 #endif
 
+#ifndef traceQUEUE_SEMAPHORE_RECEIVE
+	#define traceQUEUE_SEMAPHORE_RECEIVE( pxQueue )
+#endif
+
 #ifndef traceQUEUE_SEND
 	#define traceQUEUE_SEND( pxQueue )
 #endif
@@ -480,6 +474,10 @@ extern "C" {
 	#define traceQUEUE_PEEK( pxQueue )
 #endif
 
+#ifndef traceQUEUE_PEEK_FAILED
+	#define traceQUEUE_PEEK_FAILED( pxQueue )
+#endif
+
 #ifndef traceQUEUE_PEEK_FROM_ISR
 	#define traceQUEUE_PEEK_FROM_ISR( pxQueue )
 #endif
@@ -512,10 +510,6 @@ extern "C" {
 	#define traceQUEUE_DELETE( pxQueue )
 #endif
 
-#ifndef traceTASK_CREATE
-	#define traceTASK_CREATE( pxNewTCB )
-#endif
-
 #ifndef traceQUEUE_GIVE_FROM_ISR
 	#define traceQUEUE_GIVE_FROM_ISR( pxQueue )
 #endif
@@ -524,6 +518,10 @@ extern "C" {
 	#define traceQUEUE_GIVE_FROM_ISR_FAILED( pxQueue )
 #endif
 
+#ifndef traceTASK_CREATE
+	#define traceTASK_CREATE( pxNewTCB )
+#endif
+
 #ifndef traceTASK_CREATE_FAILED
 	#define traceTASK_CREATE_FAILED()
 #endif
@@ -533,7 +531,7 @@ extern "C" {
 #endif
 
 #ifndef traceTASK_DELAY_UNTIL
-	#define traceTASK_DELAY_UNTIL()
+	#define traceTASK_DELAY_UNTIL( x )
 #endif
 
 #ifndef traceTASK_DELAY
@@ -644,10 +642,86 @@ extern "C" {
 	#define traceQUEUE_REGISTRY_ADD(xQueue, pcQueueName)
 #endif
 
+#ifndef traceTASK_NOTIFY_TAKE_BLOCK
+	#define traceTASK_NOTIFY_TAKE_BLOCK()
+#endif
+
+#ifndef traceTASK_NOTIFY_TAKE
+	#define traceTASK_NOTIFY_TAKE()
+#endif
+
+#ifndef traceTASK_NOTIFY_WAIT_BLOCK
+	#define traceTASK_NOTIFY_WAIT_BLOCK()
+#endif
+
+#ifndef traceTASK_NOTIFY_WAIT
+	#define traceTASK_NOTIFY_WAIT()
+#endif
+
+#ifndef traceTASK_NOTIFY
+	#define traceTASK_NOTIFY()
+#endif
+
+#ifndef traceTASK_NOTIFY_FROM_ISR
+	#define traceTASK_NOTIFY_FROM_ISR()
+#endif
+
 #ifndef traceTASK_NOTIFY_GIVE_FROM_ISR
- 	#define traceTASK_NOTIFY_GIVE_FROM_ISR()
- #endif
- 
+	#define traceTASK_NOTIFY_GIVE_FROM_ISR()
+#endif
+
+#ifndef traceSTREAM_BUFFER_CREATE_FAILED
+	#define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer )
+#endif
+
+#ifndef traceSTREAM_BUFFER_CREATE_STATIC_FAILED
+	#define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer )
+#endif
+
+#ifndef traceSTREAM_BUFFER_CREATE
+	#define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer )
+#endif
+
+#ifndef traceSTREAM_BUFFER_DELETE
+	#define traceSTREAM_BUFFER_DELETE( xStreamBuffer )
+#endif
+
+#ifndef traceSTREAM_BUFFER_RESET
+	#define traceSTREAM_BUFFER_RESET( xStreamBuffer )
+#endif
+
+#ifndef traceBLOCKING_ON_STREAM_BUFFER_SEND
+	#define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer )
+#endif
+
+#ifndef traceSTREAM_BUFFER_SEND
+	#define traceSTREAM_BUFFER_SEND( xStreamBuffer, xBytesSent )
+#endif
+
+#ifndef traceSTREAM_BUFFER_SEND_FAILED
+	#define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer )
+#endif
+
+#ifndef traceSTREAM_BUFFER_SEND_FROM_ISR
+	#define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xBytesSent )
+#endif
+
+#ifndef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE
+	#define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer )
+#endif
+
+#ifndef traceSTREAM_BUFFER_RECEIVE
+	#define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength )
+#endif
+
+#ifndef traceSTREAM_BUFFER_RECEIVE_FAILED
+	#define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer )
+#endif
+
+#ifndef traceSTREAM_BUFFER_RECEIVE_FROM_ISR
+	#define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength )
+#endif
+
 #ifndef traceISR_EXIT_TO_SCHEDULER
 	#define traceISR_EXIT_TO_SCHEDULER()
 #endif
@@ -694,14 +768,6 @@ extern "C" {
 	#define portYIELD_WITHIN_API portYIELD
 #endif
 
-#ifndef pvPortMallocAligned
-	#define pvPortMallocAligned( x, puxStackBuffer ) ( ( ( puxStackBuffer ) == NULL ) ? ( pvPortMalloc( ( x ) ) ) : ( puxStackBuffer ) )
-#endif
-
-#ifndef vPortFreeAligned
-	#define vPortFreeAligned( pvBlockToFree ) vPortFree( pvBlockToFree )
-#endif
-
 #ifndef portSUPPRESS_TICKS_AND_SLEEP
 	#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime )
 #endif
@@ -718,6 +784,10 @@ extern "C" {
 	#define configUSE_TICKLESS_IDLE 0
 #endif
 
+#ifndef configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING
+	#define configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( x )
+#endif
+
 #ifndef configPRE_SLEEP_PROCESSING
 	#define configPRE_SLEEP_PROCESSING( x )
 #endif
@@ -734,6 +804,14 @@ extern "C" {
 	#define portTASK_USES_FLOATING_POINT()
 #endif
 
+#ifndef portALLOCATE_SECURE_CONTEXT
+	#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
+#endif
+
+#ifndef portDONT_DISCARD
+	#define portDONT_DISCARD
+#endif
+
 #ifndef configUSE_TIME_SLICING
 	#define configUSE_TIME_SLICING 1
 #endif
@@ -742,18 +820,10 @@ extern "C" {
 	#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
 #endif
 
-#ifndef configUSE_NEWLIB_REENTRANT
-	#define configUSE_NEWLIB_REENTRANT 0
-#endif
-
 #ifndef configUSE_STATS_FORMATTING_FUNCTIONS
 	#define configUSE_STATS_FORMATTING_FUNCTIONS 0
 #endif
 
-#ifndef configTASKLIST_INCLUDE_COREID
-    #define configTASKLIST_INCLUDE_COREID   0
-#endif
-
 #ifndef portASSERT_IF_INTERRUPT_PRIORITY_INVALID
 	#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID()
 #endif
@@ -766,6 +836,10 @@ extern "C" {
 	#define mtCOVERAGE_TEST_MARKER()
 #endif
 
+#ifndef mtCOVERAGE_TEST_DELAY
+	#define mtCOVERAGE_TEST_DELAY()
+#endif
+
 #ifndef portASSERT_IF_IN_ISR
 	#define portASSERT_IF_IN_ISR()
 #endif
@@ -782,6 +856,10 @@ extern "C" {
 	#define configUSE_TASK_NOTIFICATIONS 1
 #endif
 
+#ifndef configUSE_POSIX_ERRNO
+	#define configUSE_POSIX_ERRNO 0
+#endif
+
 #ifndef portTICK_TYPE_IS_ATOMIC
 	#define portTICK_TYPE_IS_ATOMIC 0
 #endif
@@ -796,10 +874,38 @@ extern "C" {
 	#define configSUPPORT_DYNAMIC_ALLOCATION 1
 #endif
 
+#ifndef configSTACK_DEPTH_TYPE
+	/* Defaults to uint16_t for backward compatibility, but can be overridden
+	in FreeRTOSConfig.h if uint16_t is too restrictive. */
+	#define configSTACK_DEPTH_TYPE uint16_t
+#endif
+
+#ifndef configMESSAGE_BUFFER_LENGTH_TYPE
+	/* Defaults to size_t for backward compatibility, but can be overridden
+	in FreeRTOSConfig.h if lengths will always be less than the number of bytes
+	in a size_t. */
+	#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
+#endif
+
+/* Sanity check the configuration. */
+#if( configUSE_TICKLESS_IDLE != 0 )
+	#if( INCLUDE_vTaskSuspend != 1 )
+		#error INCLUDE_vTaskSuspend must be set to 1 if configUSE_TICKLESS_IDLE is not set to 0
+	#endif /* INCLUDE_vTaskSuspend */
+#endif /* configUSE_TICKLESS_IDLE */
+
 #if( ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) )
 	#error configSUPPORT_STATIC_ALLOCATION and configSUPPORT_DYNAMIC_ALLOCATION cannot both be 0, but can both be 1.
 #endif
 
+#if( ( configUSE_RECURSIVE_MUTEXES == 1 ) && ( configUSE_MUTEXES != 1 ) )
+	#error configUSE_MUTEXES must be set to 1 to use recursive mutexes
+#endif
+
+#ifndef configINITIAL_TICK_COUNT
+	#define configINITIAL_TICK_COUNT 0
+#endif
+
 #if( portTICK_TYPE_IS_ATOMIC == 0 )
 	/* Either variables of tick type cannot be read atomically, or
 	portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when
@@ -823,6 +929,32 @@ V8 if desired. */
 	#define configENABLE_BACKWARD_COMPATIBILITY 1
 #endif
 
+#ifndef configPRINTF
+	/* configPRINTF() was not defined, so define it away to nothing.  To use
+	configPRINTF() then define it as follows (where MyPrintFunction() is
+	provided by the application writer):
+
+	void MyPrintFunction(const char *pcFormat, ... );
+	#define configPRINTF( X )   MyPrintFunction X
+
+	Then call like a standard printf() function, but placing brackets around
+	all parameters so they are passed as a single parameter.  For example:
+	configPRINTF( ("Value = %d", MyVariable) ); */
+	#define configPRINTF( X )
+#endif
+
+#ifndef configMAX
+	/* The application writer has not provided their own MAX macro, so define
+	the following generic implementation. */
+	#define configMAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
+#endif
+
+#ifndef configMIN
+	/* The application writer has not provided their own MAX macro, so define
+	the following generic implementation. */
+	#define configMIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
+#endif
+
 #if configENABLE_BACKWARD_COMPATIBILITY == 1
 	#define eTaskStateGet eTaskGetState
 	#define portTickType TickType_t
@@ -839,6 +971,10 @@ V8 if desired. */
 	#define xCoRoutineHandle CoRoutineHandle_t
 	#define pdTASK_HOOK_CODE TaskHookFunction_t
 	#define portTICK_RATE_MS portTICK_PERIOD_MS
+	#define pcTaskGetTaskName pcTaskGetName
+	#define pcTimerGetTimerName pcTimerGetName
+	#define pcQueueGetQueueName pcQueueGetName
+	#define vTaskGetTaskInfo vTaskGetInfo
 
 	/* Backward compatibility within the scheduler code only - these definitions
 	are not really required but are included for completeness. */
@@ -846,12 +982,97 @@ V8 if desired. */
 	#define pdTASK_CODE TaskFunction_t
 	#define xListItem ListItem_t
 	#define xList List_t
+
+	/* For libraries that break the list data hiding, and access list structure
+	members directly (which is not supposed to be done). */
+	#define pxContainer pvContainer
 #endif /* configENABLE_BACKWARD_COMPATIBILITY */
 
 #ifndef configESP32_PER_TASK_DATA
 	#define configESP32_PER_TASK_DATA 1
 #endif
 
+#if( configUSE_ALTERNATIVE_API != 0 )
+	#error The alternative API was deprecated some time ago, and was removed in FreeRTOS V9.0 0
+#endif
+
+/* Set configUSE_TASK_FPU_SUPPORT to 0 to omit floating point support even
+if floating point hardware is otherwise supported by the FreeRTOS port in use.
+This constant is not supported by all FreeRTOS ports that include floating
+point support. */
+#ifndef configUSE_TASK_FPU_SUPPORT
+	#define configUSE_TASK_FPU_SUPPORT 1
+#endif
+
+/* Set configENABLE_MPU to 1 to enable MPU support and 0 to disable it. This is
+currently used in ARMv8M ports. */
+#ifndef configENABLE_MPU
+	#define configENABLE_MPU 0
+#endif
+
+/* Set configENABLE_FPU to 1 to enable FPU support and 0 to disable it. This is
+currently used in ARMv8M ports. */
+#ifndef configENABLE_FPU
+	#define configENABLE_FPU 1
+#endif
+
+/* Set configENABLE_TRUSTZONE to 1 enable TrustZone support and 0 to disable it.
+This is currently used in ARMv8M ports. */
+#ifndef configENABLE_TRUSTZONE
+	#define configENABLE_TRUSTZONE 1
+#endif
+
+/* Set configRUN_FREERTOS_SECURE_ONLY to 1 to run the FreeRTOS ARMv8M port on
+the Secure Side only. */
+#ifndef configRUN_FREERTOS_SECURE_ONLY
+	#define configRUN_FREERTOS_SECURE_ONLY 0
+#endif
+
+/* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using
+ * dynamically allocated RAM, in which case when any task is deleted it is known
+ * that both the task's stack and TCB need to be freed.  Sometimes the
+ * FreeRTOSConfig.h settings only allow a task to be created using statically
+ * allocated RAM, in which case when any task is deleted it is known that neither
+ * the task's stack or TCB should be freed.  Sometimes the FreeRTOSConfig.h
+ * settings allow a task to be created using either statically or dynamically
+ * allocated RAM, in which case a member of the TCB is used to record whether the
+ * stack and/or TCB were allocated statically or dynamically, so when a task is
+ * deleted the RAM that was allocated dynamically is freed again and no attempt is
+ * made to free the RAM that was allocated statically.
+ * tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is only true if it is possible for a
+ * task to be created using either statically or dynamically allocated RAM.  Note
+ * that if portUSING_MPU_WRAPPERS is 1 then a protected task can be created with
+ * a statically allocated stack and a dynamically allocated TCB.
+ *
+ * The following table lists various combinations of portUSING_MPU_WRAPPERS,
+ * configSUPPORT_DYNAMIC_ALLOCATION and configSUPPORT_STATIC_ALLOCATION and
+ * when it is possible to have both static and dynamic allocation:
+ *  +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+
+ * | MPU | Dynamic | Static |     Available Functions     |       Possible Allocations        | Both Dynamic and | Need Free |
+ * |     |         |        |                             |                                   | Static Possible  |           |
+ * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+
+ * | 0   | 0       | 1      | xTaskCreateStatic           | TCB - Static, Stack - Static      | No               | No        |
+ * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------|
+ * | 0   | 1       | 0      | xTaskCreate                 | TCB - Dynamic, Stack - Dynamic    | No               | Yes       |
+ * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------|
+ * | 0   | 1       | 1      | xTaskCreate,                | 1. TCB - Dynamic, Stack - Dynamic | Yes              | Yes       |
+ * |     |         |        | xTaskCreateStatic           | 2. TCB - Static, Stack - Static   |                  |           |
+ * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------|
+ * | 1   | 0       | 1      | xTaskCreateStatic,          | TCB - Static, Stack - Static      | No               | No        |
+ * |     |         |        | xTaskCreateRestrictedStatic |                                   |                  |           |
+ * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------|
+ * | 1   | 1       | 0      | xTaskCreate,                | 1. TCB - Dynamic, Stack - Dynamic | Yes              | Yes       |
+ * |     |         |        | xTaskCreateRestricted       | 2. TCB - Dynamic, Stack - Static  |                  |           |
+ * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------|
+ * | 1   | 1       | 1      | xTaskCreate,                | 1. TCB - Dynamic, Stack - Dynamic | Yes              | Yes       |
+ * |     |         |        | xTaskCreateStatic,          | 2. TCB - Dynamic, Stack - Static  |                  |           |
+ * |     |         |        | xTaskCreateRestricted,      | 3. TCB - Static, Stack - Static   |                  |           |
+ * |     |         |        | xTaskCreateRestrictedStatic |                                   |                  |           |
+ * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+
+ */
+#define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE	( ( ( 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, FreeRTOS implements a strict
  * data hiding policy, so the real structures used by FreeRTOS to maintain the
@@ -864,25 +1085,40 @@ V8 if desired. */
  */
 struct xSTATIC_LIST_ITEM
 {
-	TickType_t xDummy1;
-	void *pvDummy2[ 4 ];
+	#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 )
+		TickType_t xDummy1;
+	#endif
+	TickType_t xDummy2;
+	void *pvDummy3[ 4 ];
+	#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 )
+		TickType_t xDummy4;
+	#endif
 };
 typedef struct xSTATIC_LIST_ITEM StaticListItem_t;
 
 /* See the comments above the struct xSTATIC_LIST_ITEM definition. */
 struct xSTATIC_MINI_LIST_ITEM
 {
-	TickType_t xDummy1;
-	void *pvDummy2[ 2 ];
+	#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 )
+		TickType_t xDummy1;
+	#endif
+	TickType_t xDummy2;
+	void *pvDummy3[ 2 ];
 };
 typedef struct xSTATIC_MINI_LIST_ITEM StaticMiniListItem_t;
 
 /* See the comments above the struct xSTATIC_LIST_ITEM definition. */
 typedef struct xSTATIC_LIST
 {
-	UBaseType_t uxDummy1;
-	void *pvDummy2;
-	StaticMiniListItem_t xDummy3;
+	#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 )
+		TickType_t xDummy1;
+	#endif
+	UBaseType_t uxDummy2;
+	void *pvDummy3;
+	StaticMiniListItem_t xDummy4;
+	#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 )
+		TickType_t xDummy5;
+	#endif
 } StaticList_t;
 
 /*
@@ -908,13 +1144,12 @@ typedef struct xSTATIC_TCB
 	UBaseType_t			uxDummy5;
 	void				*pxDummy6;
 	uint8_t				ucDummy7[ configMAX_TASK_NAME_LEN ];
-    UBaseType_t			uxDummyCoreId;
-	#if ( portSTACK_GROWTH > 0 || configENABLE_TASK_SNAPSHOT == 1 )
-		void            *pxDummy8;
+	BaseType_t			xDummyCore;
+	#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
+		void			*pxDummy8;
 	#endif
 	#if ( portCRITICAL_NESTING_IN_TCB == 1 )
 		UBaseType_t		uxDummy9;
-        uint32_t        OldInterruptState;
 	#endif
 	#if ( configUSE_TRACE_FACILITY == 1 )
 		UBaseType_t		uxDummy10[ 2 ];
@@ -927,7 +1162,7 @@ typedef struct xSTATIC_TCB
 	#endif
 	#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
 		void			*pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
-    #if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS )
+	#if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS )
 		void			*pvDummyLocalStorageCallBack[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
 	#endif
 	#endif
@@ -939,13 +1174,18 @@ typedef struct xSTATIC_TCB
 	#endif
 	#if ( configUSE_TASK_NOTIFICATIONS == 1 )
 		uint32_t 		ulDummy18;
-		uint32_t 		ucDummy19;
+		uint8_t 		ucDummy19;
 	#endif
-	#if( ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) \
-		 || ( portUSING_MPU_WRAPPERS == 1 ) )
+	#if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )
 		uint8_t			uxDummy20;
 	#endif
 
+	#if( INCLUDE_xTaskAbortDelay == 1 )
+		uint8_t ucDummy21;
+	#endif
+	#if ( configUSE_POSIX_ERRNO == 1 )
+		int				iDummy22;
+	#endif
 } StaticTask_t;
 
 /*
@@ -974,6 +1214,7 @@ typedef struct xSTATIC_QUEUE
 
 	StaticList_t xDummy3[ 2 ];
 	UBaseType_t uxDummy4[ 3 ];
+	uint8_t ucDummy5[ 2 ];
 
 	#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
 		uint8_t ucDummy6;
@@ -988,7 +1229,7 @@ typedef struct xSTATIC_QUEUE
 		uint8_t ucDummy9;
 	#endif
 
-	portMUX_TYPE muxDummy;		//Mutex required due to SMP
+	portMUX_TYPE xDummy10;
 
 } StaticQueue_t;
 typedef StaticQueue_t StaticSemaphore_t;
@@ -1020,7 +1261,7 @@ typedef struct xSTATIC_EVENT_GROUP
 			uint8_t ucDummy4;
 	#endif
 
-	portMUX_TYPE muxDummy;		//Mutex required due to SMP
+	portMUX_TYPE xDummy5;
 
 } StaticEventGroup_t;
 
@@ -1043,17 +1284,43 @@ typedef struct xSTATIC_TIMER
 	void				*pvDummy1;
 	StaticListItem_t	xDummy2;
 	TickType_t			xDummy3;
-	UBaseType_t			uxDummy4;
-	void 				*pvDummy5[ 2 ];
+	void 				*pvDummy5;
+	TaskFunction_t		pvDummy6;
 	#if( configUSE_TRACE_FACILITY == 1 )
-		UBaseType_t		uxDummy6;
+		UBaseType_t		uxDummy7;
 	#endif
+	uint8_t 			ucDummy8;
+} StaticTimer_t;
 
-	#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
-		uint8_t 		ucDummy7;
+/*
+* In line with software engineering best practice, especially when supplying a
+* library that is likely to change in future versions, FreeRTOS implements a
+* strict data hiding policy.  This means the stream buffer structure used
+* internally by FreeRTOS is not accessible to application code.  However, if
+* the application writer wants to statically allocate the memory required to
+* create a stream buffer then the size of the stream buffer object needs to be
+* know.  The StaticStreamBuffer_t structure below is provided for this purpose.
+* Its size and alignment requirements are guaranteed to match those of the
+* genuine structure, no matter which architecture is being used, and no matter
+* how the values in FreeRTOSConfig.h are set.  Its contents are somewhat
+* obfuscated in the hope users will recognise that it would be unwise to make
+* direct use of the structure members.
+*/
+typedef struct xSTATIC_STREAM_BUFFER
+{
+	size_t uxDummy1[ 4 ];
+	void * pvDummy2[ 3 ];
+	uint8_t ucDummy3;
+	#if ( configUSE_TRACE_FACILITY == 1 )
+		UBaseType_t uxDummy4;
 	#endif
 
-} StaticTimer_t;
+	portMUX_TYPE xDummy5;
+
+} StaticStreamBuffer_t;
+
+/* Message buffers are built on stream buffers. */
+typedef StaticStreamBuffer_t StaticMessageBuffer_t;
 
 #ifdef __cplusplus
 }

+ 418 - 0
components/freertos/include/freertos/atomic.h

@@ -0,0 +1,418 @@
+/*
+ * FreeRTOS Kernel V10.2.1
+ * 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!
+ */
+
+/**
+ * @file atomic.h
+ * @brief FreeRTOS atomic operation support.
+ *
+ * This file implements atomic by disabling interrupts globally. 
+ * Implementation with architecture specific atomic instructions  
+ * are to be provided under each compiler directory. 
+ */
+
+#ifndef ATOMIC_H
+#define ATOMIC_H
+
+#ifndef INC_FREERTOS_H
+    #error "include FreeRTOS.h must appear in source files before include atomic.h"
+#endif
+
+/* Standard includes. */
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Port specific definitions -- entering/exiting critical section.
+ * Refer template -- ./lib/FreeRTOS/portable/Compiler/Arch/portmacro.h
+ *
+ * Every call to ATOMIC_EXIT_CRITICAL() must be closely paired with
+ * ATOMIC_ENTER_CRITICAL().
+ *  */
+#if defined( portSET_INTERRUPT_MASK_FROM_ISR )
+
+    /* Nested interrupt scheme is supported in this port. */
+    #define ATOMIC_ENTER_CRITICAL()     \
+        UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR()
+
+    #define ATOMIC_EXIT_CRITICAL()      \
+        portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType )
+
+#else
+
+    /* Nested interrupt scheme is NOT supported in this port. */
+    #define ATOMIC_ENTER_CRITICAL()     portENTER_CRITICAL()
+    #define ATOMIC_EXIT_CRITICAL()      portEXIT_CRITICAL()
+
+#endif /* portSET_INTERRUPT_MASK_FROM_ISR() */
+
+/* Port specific definition -- "always inline". 
+ * Inline is compiler specific, and may not always get inlined depending on your optimization level. 
+ * Also, inline is considerred as performance optimization for atomic. 
+ * Thus, if portFORCE_INLINE is not provided by portmacro.h, instead of resulting error,
+ * simply define it. 
+ */
+#ifndef portFORCE_INLINE
+    #define portFORCE_INLINE 
+#endif
+
+#define ATOMIC_COMPARE_AND_SWAP_SUCCESS     0x1U        /**< Compare and swap succeeded, swapped. */
+#define ATOMIC_COMPARE_AND_SWAP_FAILURE     0x0U        /**< Compare and swap failed, did not swap. */
+
+/*----------------------------- Swap && CAS ------------------------------*/
+
+/**
+ * Atomic compare-and-swap
+ *
+ * @brief Performs an atomic compare-and-swap operation on the specified values.
+ *
+ * @param[in, out] pDestination  Pointer to memory location from where value is
+ *                               to be loaded and checked.
+ * @param[in] ulExchange         If condition meets, write this value to memory.
+ * @param[in] ulComparand        Swap condition.
+ *
+ * @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped.
+ *
+ * @note This function only swaps *pDestination with ulExchange, if previous
+ *       *pDestination value equals ulComparand.
+ */
+static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32(
+        uint32_t volatile * pDestination,
+        uint32_t ulExchange,
+        uint32_t ulComparand )
+{
+
+    uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
+
+    ATOMIC_ENTER_CRITICAL();
+
+    if ( *pDestination == ulComparand )
+    {
+        *pDestination = ulExchange;
+        ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
+    }
+
+    ATOMIC_EXIT_CRITICAL();
+
+    return ulReturnValue;
+
+}
+
+/**
+ * Atomic swap (pointers)
+ *
+ * @brief Atomically sets the address pointed to by *ppDestination to the value
+ *        of *pExchange.
+ *
+ * @param[in, out] ppDestination  Pointer to memory location from where a pointer
+ *                                value is to be loaded and written back to.
+ * @param[in] pExchange           Pointer value to be written to *ppDestination.
+ *
+ * @return The initial value of *ppDestination.
+ */
+static portFORCE_INLINE void * Atomic_SwapPointers_p32(
+        void * volatile * ppDestination,
+        void * pExchange )
+{
+    void * pReturnValue;
+
+    ATOMIC_ENTER_CRITICAL();
+
+    pReturnValue = *ppDestination;
+
+    *ppDestination = pExchange;
+
+    ATOMIC_EXIT_CRITICAL();
+
+    return pReturnValue;
+}
+
+/**
+ * Atomic compare-and-swap (pointers)
+ *
+ * @brief Performs an atomic compare-and-swap operation on the specified pointer
+ *        values.
+ *
+ * @param[in, out] ppDestination  Pointer to memory location from where a pointer
+ *                                value is to be loaded and checked.
+ * @param[in] pExchange           If condition meets, write this value to memory.
+ * @param[in] pComparand          Swap condition.
+ *
+ * @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped.
+ *
+ * @note This function only swaps *ppDestination with pExchange, if previous
+ *       *ppDestination value equals pComparand.
+ */
+static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32(
+        void * volatile * ppDestination,
+        void * pExchange, void * pComparand )
+{
+    uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
+
+    ATOMIC_ENTER_CRITICAL();
+
+    if ( *ppDestination == pComparand )
+    {
+        *ppDestination = pExchange;
+        ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
+    }
+
+    ATOMIC_EXIT_CRITICAL();
+
+    return ulReturnValue;
+}
+
+
+/*----------------------------- Arithmetic ------------------------------*/
+
+/**
+ * Atomic add
+ *
+ * @brief Atomically adds count to the value of the specified pointer points to.
+ *
+ * @param[in,out] pAddend  Pointer to memory location from where value is to be
+ *                         loaded and written back to.
+ * @param[in] ulCount      Value to be added to *pAddend.
+ *
+ * @return previous *pAddend value.
+ */
+static portFORCE_INLINE uint32_t Atomic_Add_u32(
+        uint32_t volatile * pAddend,
+        uint32_t ulCount )
+{
+    uint32_t ulCurrent;
+
+    ATOMIC_ENTER_CRITICAL();
+
+    ulCurrent = *pAddend;
+
+    *pAddend += ulCount;
+
+    ATOMIC_EXIT_CRITICAL();
+
+    return ulCurrent;
+}
+
+/**
+ * Atomic subtract
+ *
+ * @brief Atomically subtracts count from the value of the specified pointer
+ *        pointers to.
+ *
+ * @param[in,out] pAddend  Pointer to memory location from where value is to be
+ *                         loaded and written back to.
+ * @param[in] ulCount      Value to be subtract from *pAddend.
+ *
+ * @return previous *pAddend value.
+ */
+static portFORCE_INLINE uint32_t Atomic_Subtract_u32(
+        uint32_t volatile * pAddend,
+        uint32_t ulCount )
+{
+    uint32_t ulCurrent;
+
+    ATOMIC_ENTER_CRITICAL();
+
+    ulCurrent = *pAddend;
+
+    *pAddend -= ulCount;
+
+    ATOMIC_EXIT_CRITICAL();
+
+    return ulCurrent;
+}
+
+/**
+ * Atomic increment
+ *
+ * @brief Atomically increments the value of the specified pointer points to.
+ *
+ * @param[in,out] pAddend  Pointer to memory location from where value is to be
+ *                         loaded and written back to.
+ *
+ * @return *pAddend value before increment.
+ */
+static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pAddend )
+{
+    uint32_t ulCurrent;
+
+    ATOMIC_ENTER_CRITICAL();
+
+    ulCurrent = *pAddend;
+
+    *pAddend += 1;
+
+    ATOMIC_EXIT_CRITICAL();
+
+    return ulCurrent;
+}
+
+/**
+ * Atomic decrement
+ *
+ * @brief Atomically decrements the value of the specified pointer points to
+ *
+ * @param[in,out] pAddend  Pointer to memory location from where value is to be
+ *                         loaded and written back to.
+ *
+ * @return *pAddend value before decrement.
+ */
+static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pAddend )
+{
+    uint32_t ulCurrent;
+
+    ATOMIC_ENTER_CRITICAL();
+
+    ulCurrent = *pAddend;
+
+    *pAddend -= 1;
+
+    ATOMIC_EXIT_CRITICAL();
+
+    return ulCurrent;
+}
+
+/*----------------------------- Bitwise Logical ------------------------------*/
+
+/**
+ * Atomic OR
+ *
+ * @brief Performs an atomic OR operation on the specified values.
+ *
+ * @param [in, out] pDestination  Pointer to memory location from where value is
+ *                                to be loaded and written back to.
+ * @param [in] ulValue            Value to be ORed with *pDestination.
+ *
+ * @return The original value of *pDestination.
+ */
+static portFORCE_INLINE uint32_t Atomic_OR_u32(
+        uint32_t volatile * pDestination,
+        uint32_t ulValue )
+{
+    uint32_t ulCurrent;
+
+    ATOMIC_ENTER_CRITICAL();
+
+    ulCurrent = *pDestination;
+
+    *pDestination |= ulValue;
+
+    ATOMIC_EXIT_CRITICAL();
+
+    return ulCurrent;
+}
+
+/**
+ * Atomic AND
+ *
+ * @brief Performs an atomic AND operation on the specified values.
+ *
+ * @param [in, out] pDestination  Pointer to memory location from where value is
+ *                                to be loaded and written back to.
+ * @param [in] ulValue            Value to be ANDed with *pDestination.
+ *
+ * @return The original value of *pDestination.
+ */
+static portFORCE_INLINE uint32_t Atomic_AND_u32(
+        uint32_t volatile * pDestination,
+        uint32_t ulValue )
+{
+    uint32_t ulCurrent;
+
+    ATOMIC_ENTER_CRITICAL();
+
+    ulCurrent = *pDestination;
+
+    *pDestination &= ulValue;
+
+    ATOMIC_EXIT_CRITICAL();
+
+    return ulCurrent;
+}
+
+/**
+ * Atomic NAND
+ *
+ * @brief Performs an atomic NAND operation on the specified values.
+ *
+ * @param [in, out] pDestination  Pointer to memory location from where value is
+ *                                to be loaded and written back to.
+ * @param [in] ulValue            Value to be NANDed with *pDestination.
+ *
+ * @return The original value of *pDestination.
+ */
+static portFORCE_INLINE uint32_t Atomic_NAND_u32(
+        uint32_t volatile * pDestination,
+        uint32_t ulValue )
+{
+    uint32_t ulCurrent;
+
+    ATOMIC_ENTER_CRITICAL();
+
+    ulCurrent = *pDestination;
+
+    *pDestination = ~(ulCurrent & ulValue);
+
+    ATOMIC_EXIT_CRITICAL();
+
+    return ulCurrent;
+}
+
+/**
+ * Atomic XOR
+ *
+ * @brief Performs an atomic XOR operation on the specified values.
+ *
+ * @param [in, out] pDestination  Pointer to memory location from where value is
+ *                                to be loaded and written back to.
+ * @param [in] ulValue            Value to be XORed with *pDestination.
+ *
+ * @return The original value of *pDestination.
+ */
+static portFORCE_INLINE uint32_t Atomic_XOR_u32(
+        uint32_t volatile * pDestination,
+        uint32_t ulValue )
+{
+    uint32_t ulCurrent;
+
+    ATOMIC_ENTER_CRITICAL();
+
+    ulCurrent = *pDestination;
+
+    *pDestination ^= ulValue;
+
+    ATOMIC_EXIT_CRITICAL();
+
+    return ulCurrent;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ATOMIC_H */

+ 25 - 67
components/freertos/include/freertos/croutine.h

@@ -1,71 +1,29 @@
 /*
-    FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
-    All rights reserved
-
-    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License (version 2) as published by the
-    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
-
-	***************************************************************************
-    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
-    >>!   distribute a combined work that includes FreeRTOS without being   !<<
-    >>!   obliged to provide the source code for proprietary components     !<<
-    >>!   outside of the FreeRTOS kernel.                                   !<<
-	***************************************************************************
-
-    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
-    link: http://www.freertos.org/a00114.html
-
-    ***************************************************************************
-     *                                                                       *
-     *    FreeRTOS provides completely free yet professionally developed,    *
-     *    robust, strictly quality controlled, supported, and cross          *
-     *    platform software that is more than just the market leader, it     *
-     *    is the industry's de facto standard.                               *
-     *                                                                       *
-     *    Help yourself get started quickly while simultaneously helping     *
-     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
-     *    tutorial book, reference manual, or both:                          *
-     *    http://www.FreeRTOS.org/Documentation                              *
-     *                                                                       *
-    ***************************************************************************
-
-    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
-	the FAQ page "My application does not run, what could be wrong?".  Have you
-	defined configASSERT()?
-
-	http://www.FreeRTOS.org/support - In return for receiving this top quality
-	embedded software for free we request you assist our global community by
-	participating in the support forum.
-
-	http://www.FreeRTOS.org/training - Investing in training allows your team to
-	be as productive as possible as early as possible.  Now you can receive
-	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
-	Ltd, and the world's leading authority on the world's leading RTOS.
-
-    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
-    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
-    compatible FAT file system, and our tiny thread aware UDP/IP stack.
-
-    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
-    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
-
-    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
-    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
-    licenses offer ticketed support, indemnification and commercial middleware.
-
-    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
-    engineered and independently SIL3 certified version for use in safety and
-    mission critical applications that require provable dependability.
-
-    1 tab == 4 spaces!
-*/
+ * FreeRTOS Kernel V10.2.1
+ * 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 CO_ROUTINE_H
 #define CO_ROUTINE_H

+ 29 - 71
components/freertos/include/freertos/deprecated_definitions.h

@@ -1,71 +1,29 @@
 /*
-    FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
-    All rights reserved
-
-    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License (version 2) as published by the
-    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
-
-	***************************************************************************
-    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
-    >>!   distribute a combined work that includes FreeRTOS without being   !<<
-    >>!   obliged to provide the source code for proprietary components     !<<
-    >>!   outside of the FreeRTOS kernel.                                   !<<
-	***************************************************************************
-
-    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
-    link: http://www.freertos.org/a00114.html
-
-    ***************************************************************************
-     *                                                                       *
-     *    FreeRTOS provides completely free yet professionally developed,    *
-     *    robust, strictly quality controlled, supported, and cross          *
-     *    platform software that is more than just the market leader, it     *
-     *    is the industry's de facto standard.                               *
-     *                                                                       *
-     *    Help yourself get started quickly while simultaneously helping     *
-     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
-     *    tutorial book, reference manual, or both:                          *
-     *    http://www.FreeRTOS.org/Documentation                              *
-     *                                                                       *
-    ***************************************************************************
-
-    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
-	the FAQ page "My application does not run, what could be wrong?".  Have you
-	defined configASSERT()?
-
-	http://www.FreeRTOS.org/support - In return for receiving this top quality
-	embedded software for free we request you assist our global community by
-	participating in the support forum.
-
-	http://www.FreeRTOS.org/training - Investing in training allows your team to
-	be as productive as possible as early as possible.  Now you can receive
-	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
-	Ltd, and the world's leading authority on the world's leading RTOS.
-
-    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
-    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
-    compatible FAT file system, and our tiny thread aware UDP/IP stack.
-
-    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
-    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
-
-    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
-    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
-    licenses offer ticketed support, indemnification and commercial middleware.
-
-    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
-    engineered and independently SIL3 certified version for use in safety and
-    mission critical applications that require provable dependability.
-
-    1 tab == 4 spaces!
-*/
+ * FreeRTOS Kernel V10.2.1
+ * 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 DEPRECATED_DEFINITIONS_H
 #define DEPRECATED_DEFINITIONS_H
@@ -82,12 +40,12 @@ projects should not use them. */
 
 #ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
 	#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
-	typedef void ( __interrupt __far *pxISR )(void);
+	typedef void ( __interrupt __far *pxISR )();
 #endif
 
 #ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
 	#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
-	typedef void ( __interrupt __far *pxISR )(void);
+	typedef void ( __interrupt __far *pxISR )();
 #endif
 
 #ifdef GCC_MEGA_AVR
@@ -255,7 +213,7 @@ projects should not use them. */
 	FreeRTOSConfig.h when using the Borland compiler. */
 	#include "frconfig.h"
 	#include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
-    typedef void ( __interrupt __far *pxISR )(void);
+    typedef void ( __interrupt __far *pxISR )();
 #endif
 
 #ifdef BCC_FLASH_LITE_186_PORT
@@ -263,7 +221,7 @@ projects should not use them. */
 	FreeRTOSConfig.h when using the Borland compiler. */
 	#include "frconfig.h"
 	#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
-    typedef void ( __interrupt __far *pxISR )(void);
+    typedef void ( __interrupt __far *pxISR )();
 #endif
 
 #ifdef __GNUC__

+ 60 - 87
components/freertos/include/freertos/event_groups.h

@@ -1,71 +1,29 @@
 /*
-    FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
-    All rights reserved
-
-    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License (version 2) as published by the
-    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
-
-	***************************************************************************
-    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
-    >>!   distribute a combined work that includes FreeRTOS without being   !<<
-    >>!   obliged to provide the source code for proprietary components     !<<
-    >>!   outside of the FreeRTOS kernel.                                   !<<
-	***************************************************************************
-
-    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
-    link: http://www.freertos.org/a00114.html
-
-    ***************************************************************************
-     *                                                                       *
-     *    FreeRTOS provides completely free yet professionally developed,    *
-     *    robust, strictly quality controlled, supported, and cross          *
-     *    platform software that is more than just the market leader, it     *
-     *    is the industry's de facto standard.                               *
-     *                                                                       *
-     *    Help yourself get started quickly while simultaneously helping     *
-     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
-     *    tutorial book, reference manual, or both:                          *
-     *    http://www.FreeRTOS.org/Documentation                              *
-     *                                                                       *
-    ***************************************************************************
-
-    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
-	the FAQ page "My application does not run, what could be wrong?".  Have you
-	defined configASSERT()?
-
-	http://www.FreeRTOS.org/support - In return for receiving this top quality
-	embedded software for free we request you assist our global community by
-	participating in the support forum.
-
-	http://www.FreeRTOS.org/training - Investing in training allows your team to
-	be as productive as possible as early as possible.  Now you can receive
-	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
-	Ltd, and the world's leading authority on the world's leading RTOS.
-
-    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
-    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
-    compatible FAT file system, and our tiny thread aware UDP/IP stack.
-
-    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
-    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
-
-    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
-    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
-    licenses offer ticketed support, indemnification and commercial middleware.
-
-    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
-    engineered and independently SIL3 certified version for use in safety and
-    mission critical applications that require provable dependability.
-
-    1 tab == 4 spaces!
-*/
+ * FreeRTOS Kernel V10.2.1
+ * 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 EVENT_GROUPS_H
 #define EVENT_GROUPS_H
@@ -74,6 +32,7 @@
 	#error "include FreeRTOS.h" must appear in source files before "include event_groups.h"
 #endif
 
+/* FreeRTOS includes. */
 #include "timers.h"
 
 #ifdef __cplusplus
@@ -115,25 +74,31 @@ extern "C" {
  * xEventGroupCreate() returns an EventGroupHandle_t variable that can then
  * be used as a parameter to other event group functions.
  *
+ * \defgroup EventGroupHandle_t EventGroupHandle_t
  * \ingroup EventGroup
  */
+struct EventGroupDef_t;
+//typedef struct EventGroupDef_t * EventGroupHandle_t;
 typedef void * EventGroupHandle_t;
 
-/* 
+/*
  * The type that holds event bits always matches TickType_t - therefore the
  * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1,
- * 32 bits if set to 0. 
+ * 32 bits if set to 0.
  *
+ * \defgroup EventBits_t EventBits_t
  * \ingroup EventGroup
  */
 typedef TickType_t EventBits_t;
 
 /**
+ *
+ *
  * Create a new event group.
  *
  * Internally, within the FreeRTOS implementation, event groups use a [small]
  * block of memory, in which the event group's structure is stored.  If an event
- * groups is created using xEventGroupCreate() then the required memory is
+ * groups is created using xEventGropuCreate() then the required memory is
  * automatically dynamically allocated inside the xEventGroupCreate() function.
  * (see http://www.freertos.org/a00111.html).  If an event group is created
  * using xEventGropuCreateStatic() then the application writer must instead
@@ -311,6 +276,7 @@ typedef TickType_t EventBits_t;
 EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
 
 /**
+ *
  * Clear bits within an event group.  This function cannot be called from an
  * interrupt.
  *
@@ -362,6 +328,7 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits
 EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
 
 /**
+ *
  * A version of xEventGroupClearBits() that can be called from an interrupt.
  *
  * Setting bits in an event group is not a deterministic operation because there
@@ -370,8 +337,8 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBit
  * while interrupts are disabled, so protects event groups that are accessed
  * from tasks by suspending the scheduler rather than disabling interrupts.  As
  * a result event groups cannot be accessed directly from an interrupt service
- * routine.  Therefore xEventGroupClearBitsFromISR() sends a message to the 
- * timer task to have the clear operation performed in the context of the timer 
+ * routine.  Therefore xEventGroupClearBitsFromISR() sends a message to the
+ * timer task to have the clear operation performed in the context of the timer
  * task.
  *
  * @param xEventGroup The event group in which the bits are to be cleared.
@@ -380,8 +347,8 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBit
  * For example, to clear bit 3 only, set uxBitsToClear to 0x08.  To clear bit 3
  * and bit 0 set uxBitsToClear to 0x09.
  *
- * @return If the request to execute the function was posted successfully then 
- * pdPASS is returned, otherwise pdFALSE is returned.  pdFALSE will be returned 
+ * @return If the request to execute the function was posted successfully then
+ * pdPASS is returned, otherwise pdFALSE is returned.  pdFALSE will be returned
  * if the timer service queue was full.
  *
  * Example usage:
@@ -409,12 +376,13 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBit
  * \ingroup EventGroup
  */
 #if( configUSE_TRACE_FACILITY == 1 )
-	BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
+	BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
 #else
 	#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL )
 #endif
 
 /**
+ *
  * Set bits within an event group.
  * This function cannot be called from an interrupt.  xEventGroupSetBitsFromISR()
  * is a version that can be called from an interrupt.
@@ -483,12 +451,13 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBit
 EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
 
 /**
+ *
  * A version of xEventGroupSetBits() that can be called from an interrupt.
  *
  * Setting bits in an event group is not a deterministic operation because there
  * are an unknown number of tasks that may be waiting for the bit or bits being
  * set.  FreeRTOS does not allow nondeterministic operations to be performed in
- * interrupts or from critical sections.  Therefore xEventGroupSetBitFromISR()
+ * interrupts or from critical sections.  Therefore xEventGroupSetBitsFromISR()
  * sends a message to the timer task to have the set operation performed in the
  * context of the timer task - where a scheduler lock is used in place of a
  * critical section.
@@ -509,8 +478,8 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_
  * *pxHigherPriorityTaskWoken must be initialised to pdFALSE.  See the
  * example code below.
  *
- * @return If the request to execute the function was posted successfully then 
- * pdPASS is returned, otherwise pdFALSE is returned.  pdFALSE will be returned 
+ * @return If the request to execute the function was posted successfully then
+ * pdPASS is returned, otherwise pdFALSE is returned.  pdFALSE will be returned
  * if the timer service queue was full.
  *
  * Example usage:
@@ -549,12 +518,13 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_
  * \ingroup EventGroup
  */
 #if( configUSE_TRACE_FACILITY == 1 )
-	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
+	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
 #else
 	#define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken )
 #endif
 
 /**
+ *
  * Atomically set bits within an event group, then wait for a combination of
  * bits to be set within the same event group.  This functionality is typically
  * used to synchronise multiple tasks, where each task has to wait for the other
@@ -625,7 +595,7 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_
  * 			// All three tasks reached the synchronisation point before the call
  * 			// to xEventGroupSync() timed out.
  * 		}
- * 	}
+ * 	  }
  *  }
  *
  *  void vTask1( void *pvParameters )
@@ -663,7 +633,7 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_
  * 		// xEventGroupSync() was called with an indefinite block time, so
  * 		// this task will only reach here if the syncrhonisation was made by all
  * 		// three tasks, so there is no need to test the return value.
- * 	}
+ * 		}
  *  }
  *
  * @endcode
@@ -673,6 +643,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t u
 
 
 /**
+ *
  * Returns the current value of the bits in an event group.  This function
  * cannot be used from an interrupt.
  *
@@ -685,6 +656,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t u
 #define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 )
 
 /**
+ *
  * A version of xEventGroupGetBits() that can be called from an ISR.
  *
  * @param xEventGroup The event group being queried.
@@ -693,26 +665,27 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t u
  *
  * \ingroup EventGroup
  */
-EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
+EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
 
 /**
- *
  * Delete an event group that was previously created by a call to
  * xEventGroupCreate().  Tasks that are blocked on the event group will be
  * unblocked and obtain 0 as the event group's value.
  *
  * @param xEventGroup The event group being deleted.
  */
-void vEventGroupDelete( EventGroupHandle_t xEventGroup );
+void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
 
 /** @cond */
 
 /* For internal use only. */
-void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet );
-void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear );
+void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION;
+void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;
+
 
 #if (configUSE_TRACE_FACILITY == 1)
-	UBaseType_t uxEventGroupGetNumber( void* xEventGroup );
+	UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION;
+	void vEventGroupSetNumber( void* xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION;
 #endif
 
 /** @endcond */

+ 47 - 101
components/freertos/include/freertos/list.h

@@ -1,71 +1,29 @@
 /*
-    FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
-    All rights reserved
-
-    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License (version 2) as published by the
-    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
-
-	***************************************************************************
-    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
-    >>!   distribute a combined work that includes FreeRTOS without being   !<<
-    >>!   obliged to provide the source code for proprietary components     !<<
-    >>!   outside of the FreeRTOS kernel.                                   !<<
-	***************************************************************************
-
-    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
-    link: http://www.freertos.org/a00114.html
-
-    ***************************************************************************
-     *                                                                       *
-     *    FreeRTOS provides completely free yet professionally developed,    *
-     *    robust, strictly quality controlled, supported, and cross          *
-     *    platform software that is more than just the market leader, it     *
-     *    is the industry's de facto standard.                               *
-     *                                                                       *
-     *    Help yourself get started quickly while simultaneously helping     *
-     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
-     *    tutorial book, reference manual, or both:                          *
-     *    http://www.FreeRTOS.org/Documentation                              *
-     *                                                                       *
-    ***************************************************************************
-
-    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
-	the FAQ page "My application does not run, what could be wrong?".  Have you
-	defined configASSERT()?
-
-	http://www.FreeRTOS.org/support - In return for receiving this top quality
-	embedded software for free we request you assist our global community by
-	participating in the support forum.
-
-	http://www.FreeRTOS.org/training - Investing in training allows your team to
-	be as productive as possible as early as possible.  Now you can receive
-	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
-	Ltd, and the world's leading authority on the world's leading RTOS.
-
-    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
-    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
-    compatible FAT file system, and our tiny thread aware UDP/IP stack.
-
-    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
-    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
-
-    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
-    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
-    licenses offer ticketed support, indemnification and commercial middleware.
-
-    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
-    engineered and independently SIL3 certified version for use in safety and
-    mission critical applications that require provable dependability.
-
-    1 tab == 4 spaces!
-*/
+ * FreeRTOS Kernel V10.2.1
+ * 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!
+ */
 
 /*
  * This is the list implementation used by the scheduler.  While it is tailored
@@ -178,52 +136,40 @@ use of FreeRTOS.*/
 /*
  * 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. */
+	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 descending 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. */
-	void * configLIST_VOLATILE pvContainer;				/*< 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. */
+	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. */
 
-#if __GNUC_PREREQ(4, 6)
-_Static_assert(sizeof(StaticListItem_t) == sizeof(ListItem_t), "StaticListItem_t != ListItem_t");
-#endif
-
 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. */
+	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;
 
-#if __GNUC_PREREQ(4, 6)
-_Static_assert(sizeof(StaticMiniListItem_t) == sizeof(MiniListItem_t), "StaticMiniListItem_t != MiniListItem_t");
-#endif
-
-
 /*
  * 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. */
-	configLIST_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. */
+	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;
 
-#if __GNUC_PREREQ(4, 6)
-_Static_assert(sizeof(StaticList_t) == sizeof(List_t), "StaticList_t != List_t");
-#endif
-
 /*
  * 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.
@@ -237,7 +183,7 @@ _Static_assert(sizeof(StaticList_t) == sizeof(List_t), "StaticList_t != List_t")
  * 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 listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
+ * \page listGET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
  * \ingroup LinkedList
  */
 #define listGET_LIST_ITEM_OWNER( pxListItem )	( ( pxListItem )->pvOwner )
@@ -279,7 +225,7 @@ _Static_assert(sizeof(StaticList_t) == sizeof(List_t), "StaticList_t != List_t")
 #define listGET_HEAD_ENTRY( pxList )	( ( ( pxList )->xListEnd ).pxNext )
 
 /*
- * Return the list item at the head of the list.
+ * Return the next list item.
  *
  * \page listGET_NEXT listGET_NEXT
  * \ingroup LinkedList
@@ -301,7 +247,7 @@ _Static_assert(sizeof(StaticList_t) == sizeof(List_t), "StaticList_t != List_t")
  * \page listLIST_IS_EMPTY listLIST_IS_EMPTY
  * \ingroup LinkedList
  */
-#define listLIST_IS_EMPTY( pxList )	( ( BaseType_t ) ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) )
+#define listLIST_IS_EMPTY( pxList )	( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE )
 
 /*
  * Access macro to return the number of items in the list.
@@ -369,7 +315,7 @@ List_t * const pxConstList = ( pxList );													\
  * @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 ) ( ( BaseType_t ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) ) )
+#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) )
 
 /*
  * Return the list a list item is contained within (referenced from).
@@ -377,7 +323,7 @@ List_t * const pxConstList = ( pxList );													\
  * @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 )->pvContainer )
+#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer )
 
 /*
  * This provides a crude means of knowing if a list has been initialised, as
@@ -396,7 +342,7 @@ List_t * const pxConstList = ( pxList );													\
  * \page vListInitialise vListInitialise
  * \ingroup LinkedList
  */
-void vListInitialise( List_t * const pxList );
+void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION;
 
 /*
  * Must be called before a list item is used.  This sets the list container to
@@ -407,7 +353,7 @@ void vListInitialise( List_t * const pxList );
  * \page vListInitialiseItem vListInitialiseItem
  * \ingroup LinkedList
  */
-void vListInitialiseItem( ListItem_t * const pxItem );
+void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION;
 
 /*
  * Insert a list item into a list.  The item will be inserted into the list in
@@ -420,19 +366,19 @@ void vListInitialiseItem( ListItem_t * const pxItem );
  * \page vListInsert vListInsert
  * \ingroup LinkedList
  */
-void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem );
+void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
 
 /*
  * 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 pvIndex is used to walk through a list.  Calling
- * listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the 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.
  * Placing an item in a list using vListInsertEnd effectively places the item
- * in the list position pointed to by pvIndex.  This means that every other
+ * 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 pvIndex parameter again points to the item being inserted.
+ * the pxIndex parameter again points to the item being inserted.
  *
  * @param pxList The list into which the item is to be inserted.
  *
@@ -441,7 +387,7 @@ void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem );
  * \page vListInsertEnd vListInsertEnd
  * \ingroup LinkedList
  */
-void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem );
+void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
 
 /*
  * Remove an item from a list.  The list item has a pointer to the list that
@@ -456,7 +402,7 @@ void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem );
  * \page uxListRemove uxListRemove
  * \ingroup LinkedList
  */
-UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove );
+UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION;
 
 #ifdef __cplusplus
 }

+ 702 - 0
components/freertos/include/freertos/message_buffer.h

@@ -0,0 +1,702 @@
+/*
+ * FreeRTOS Kernel V10.2.1
+ * 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!
+ */
+
+
+/*
+ * Message buffers build functionality on top of FreeRTOS stream buffers.
+ * Whereas stream buffers are used to send a continuous stream of data from one
+ * task or interrupt to another, message buffers are used to send variable
+ * length discrete messages from one task or interrupt to another.  Their
+ * implementation is light weight, making them particularly suited for interrupt
+ * to task and core to core communication scenarios.
+ *
+ * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
+ * implementation (so also the message buffer implementation, as message buffers
+ * are built on top of stream buffers) assumes there is only one task or
+ * interrupt that will write to the buffer (the writer), and only one task or
+ * interrupt that will read from the buffer (the reader).  It is safe for the
+ * writer and reader to be different tasks or interrupts, but, unlike other
+ * FreeRTOS objects, it is not safe to have multiple different writers or
+ * multiple different readers.  If there are to be multiple different writers
+ * then the application writer must place each call to a writing API function
+ * (such as xMessageBufferSend()) inside a critical section and set the send
+ * block time to 0.  Likewise, if there are to be multiple different readers
+ * then the application writer must place each call to a reading API function
+ * (such as xMessageBufferRead()) inside a critical section and set the receive
+ * timeout to 0.
+ *
+ * Message buffers hold variable length messages.  To enable that, when a
+ * message is written to the message buffer an additional sizeof( size_t ) bytes
+ * are also written to store the message's length (that happens internally, with
+ * the API function).  sizeof( size_t ) is typically 4 bytes on a 32-bit
+ * architecture, so writing a 10 byte message to a message buffer on a 32-bit
+ * architecture will actually reduce the available space in the message buffer
+ * by 14 bytes (10 byte are used by the message, and 4 bytes to hold the length
+ * of the message).
+ */
+
+#ifndef FREERTOS_MESSAGE_BUFFER_H
+#define FREERTOS_MESSAGE_BUFFER_H
+
+#ifndef INC_FREERTOS_H
+	#error "include FreeRTOS.h must appear in source files before include message_buffer.h"
+#endif
+
+/* Message buffers are built onto of stream buffers. */
+#include "stream_buffer.h"
+
+#if defined( __cplusplus )
+extern "C" {
+#endif
+
+/**
+ * Type by which message buffers are referenced.  For example, a call to
+ * xMessageBufferCreate() returns an MessageBufferHandle_t variable that can
+ * then be used as a parameter to xMessageBufferSend(), xMessageBufferReceive(),
+ * etc.
+ */
+typedef void * MessageBufferHandle_t;
+
+/*-----------------------------------------------------------*/
+
+/**
+ * Creates a new message buffer using dynamically allocated memory.  See
+ * xMessageBufferCreateStatic() for a version that uses statically allocated
+ * memory (memory that is allocated at compile time).
+ *
+ * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in
+ * FreeRTOSConfig.h for xMessageBufferCreate() to be available.
+ *
+ * @param xBufferSizeBytes The total number of bytes (not messages) the message
+ * buffer will be able to hold at any one time.  When a message is written to
+ * the message buffer an additional sizeof( size_t ) bytes are also written to
+ * store the message's length.  sizeof( size_t ) is typically 4 bytes on a
+ * 32-bit architecture, so on most 32-bit architectures a 10 byte message will
+ * take up 14 bytes of message buffer space.
+ *
+ * @return If NULL is returned, then the message buffer cannot be created
+ * because there is insufficient heap memory available for FreeRTOS to allocate
+ * the message buffer data structures and storage area.  A non-NULL value being
+ * returned indicates that the message buffer has been created successfully -
+ * the returned value should be stored as the handle to the created message
+ * buffer.
+ *
+ * Example use:
+ * @code{c}       
+ *
+ * void vAFunction( void )
+ * {
+ * MessageBufferHandle_t xMessageBuffer;
+ * const size_t xMessageBufferSizeBytes = 100;
+ *
+ *   // Create a message buffer that can hold 100 bytes.  The memory used to hold
+ *   // both the message buffer structure and the messages themselves is allocated
+ *   // dynamically.  Each message added to the buffer consumes an additional 4
+ *   // bytes which are used to hold the lengh of the message.
+ *   xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes );
+ *
+ *   if( xMessageBuffer == NULL )
+ *   {
+ *       // There was not enough heap memory space available to create the
+ *       // message buffer.
+ *   }
+ *   else
+ *   {
+ *       // The message buffer was created successfully and can now be used.
+ *   }
+ *
+ * @endcode       
+ * \ingroup MessageBufferManagement
+ */
+#define xMessageBufferCreate( xBufferSizeBytes ) ( MessageBufferHandle_t ) xStreamBufferGenericCreate( xBufferSizeBytes, ( size_t ) 0, pdTRUE )
+
+/**
+ * Creates a new message buffer using statically allocated memory.  See
+ * xMessageBufferCreate() for a version that uses dynamically allocated memory.
+ *
+ * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the
+ * pucMessageBufferStorageArea parameter.  When a message is written to the
+ * message buffer an additional sizeof( size_t ) bytes are also written to store
+ * the message's length.  sizeof( size_t ) is typically 4 bytes on a 32-bit
+ * architecture, so on most 32-bit architecture a 10 byte message will take up
+ * 14 bytes of message buffer space.  The maximum number of bytes that can be
+ * stored in the message buffer is actually (xBufferSizeBytes - 1).
+ *
+ * @param pucMessageBufferStorageArea Must point to a uint8_t array that is at
+ * least xBufferSizeBytes + 1 big.  This is the array to which messages are
+ * copied when they are written to the message buffer.
+ *
+ * @param pxStaticMessageBuffer Must point to a variable of type
+ * StaticMessageBuffer_t, which will be used to hold the message buffer's data
+ * structure.
+ *
+ * @return If the message buffer is created successfully then a handle to the
+ * created message buffer is returned. If either pucMessageBufferStorageArea or
+ * pxStaticmessageBuffer are NULL then NULL is returned.
+ *
+ * Example use:
+ * @code{c}       
+ *
+ * // Used to dimension the array used to hold the messages.  The available space
+ * // will actually be one less than this, so 999.
+ * #define STORAGE_SIZE_BYTES 1000
+ *
+ * // Defines the memory that will actually hold the messages within the message
+ * // buffer.
+ * static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
+ *
+ * // The variable used to hold the message buffer structure.
+ * StaticMessageBuffer_t xMessageBufferStruct;
+ *
+ * void MyFunction( void )
+ * {
+ * MessageBufferHandle_t xMessageBuffer;
+ *
+ *   xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucBufferStorage ),
+ *                                                ucBufferStorage,
+ *                                                &xMessageBufferStruct );
+ *
+ *   // As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer
+ *   // parameters were NULL, xMessageBuffer will not be NULL, and can be used to
+ *   // reference the created message buffer in other message buffer API calls.
+ *
+ *   // Other code that uses the message buffer can go here.
+ * }
+ *
+ * @endcode       
+ * \ingroup MessageBufferManagement
+ */
+#define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) ( MessageBufferHandle_t ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, 0, pdTRUE, pucMessageBufferStorageArea, pxStaticMessageBuffer )
+
+/**
+ * Sends a discrete message to the message buffer.  The message can be any
+ * length that fits within the buffer's free space, and is copied into the
+ * buffer.
+ *
+ * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
+ * implementation (so also the message buffer implementation, as message buffers
+ * are built on top of stream buffers) assumes there is only one task or
+ * interrupt that will write to the buffer (the writer), and only one task or
+ * interrupt that will read from the buffer (the reader).  It is safe for the
+ * writer and reader to be different tasks or interrupts, but, unlike other
+ * FreeRTOS objects, it is not safe to have multiple different writers or
+ * multiple different readers.  If there are to be multiple different writers
+ * then the application writer must place each call to a writing API function
+ * (such as xMessageBufferSend()) inside a critical section and set the send
+ * block time to 0.  Likewise, if there are to be multiple different readers
+ * then the application writer must place each call to a reading API function
+ * (such as xMessageBufferRead()) inside a critical section and set the receive
+ * block time to 0.
+ *
+ * Use xMessageBufferSend() to write to a message buffer from a task.  Use
+ * xMessageBufferSendFromISR() to write to a message buffer from an interrupt
+ * service routine (ISR).
+ *
+ * @param xMessageBuffer The handle of the message buffer to which a message is
+ * being sent.
+ *
+ * @param pvTxData A pointer to the message that is to be copied into the
+ * message buffer.
+ *
+ * @param xDataLengthBytes The length of the message.  That is, the number of
+ * bytes to copy from pvTxData into the message buffer.  When a message is
+ * written to the message buffer an additional sizeof( size_t ) bytes are also
+ * written to store the message's length.  sizeof( size_t ) is typically 4 bytes
+ * on a 32-bit architecture, so on most 32-bit architecture setting
+ * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
+ * bytes (20 bytes of message data and 4 bytes to hold the message length).
+ *
+ * @param xTicksToWait The maximum amount of time the calling task should remain
+ * in the Blocked state to wait for enough space to become available in the
+ * message buffer, should the message buffer have insufficient space when
+ * xMessageBufferSend() is called.  The calling task will never block if
+ * xTicksToWait is zero.  The block time is specified in tick periods, so the
+ * absolute time it represents is dependent on the tick frequency.  The macro
+ * pdMS_TO_TICKS() can be used to convert a time specified in milliseconds into
+ * a time specified in ticks.  Setting xTicksToWait to portMAX_DELAY will cause
+ * the task to wait indefinitely (without timing out), provided
+ * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h.  Tasks do not use any
+ * CPU time when they are in the Blocked state.
+ *
+ * @return The number of bytes written to the message buffer.  If the call to
+ * xMessageBufferSend() times out before there was enough space to write the
+ * message into the message buffer then zero is returned.  If the call did not
+ * time out then xDataLengthBytes is returned.
+ *
+ * Example use:
+ * @code{c}       
+ * void vAFunction( MessageBufferHandle_t xMessageBuffer )
+ * {
+ * size_t xBytesSent;
+ * uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
+ * char *pcStringToSend = "String to send";
+ * const TickType_t x100ms = pdMS_TO_TICKS( 100 );
+ *
+ *   // Send an array to the message buffer, blocking for a maximum of 100ms to
+ *   // wait for enough space to be available in the message buffer.
+ *   xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
+ *
+ *   if( xBytesSent != sizeof( ucArrayToSend ) )
+ *   {
+ *       // The call to xMessageBufferSend() times out before there was enough
+ *       // space in the buffer for the data to be written.
+ *   }
+ *
+ *   // Send the string to the message buffer.  Return immediately if there is
+ *   // not enough space in the buffer.
+ *   xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
+ *
+ *   if( xBytesSent != strlen( pcStringToSend ) )
+ *   {
+ *       // The string could not be added to the message buffer because there was
+ *       // not enough free space in the buffer.
+ *   }
+ * }
+ * @endcode       
+ * \ingroup MessageBufferManagement
+ */
+#define xMessageBufferSend( xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) xStreamBufferSend( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait )
+
+/**
+ * Interrupt safe version of the API function that sends a discrete message to
+ * the message buffer.  The message can be any length that fits within the
+ * buffer's free space, and is copied into the buffer.
+ *
+ * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
+ * implementation (so also the message buffer implementation, as message buffers
+ * are built on top of stream buffers) assumes there is only one task or
+ * interrupt that will write to the buffer (the writer), and only one task or
+ * interrupt that will read from the buffer (the reader).  It is safe for the
+ * writer and reader to be different tasks or interrupts, but, unlike other
+ * FreeRTOS objects, it is not safe to have multiple different writers or
+ * multiple different readers.  If there are to be multiple different writers
+ * then the application writer must place each call to a writing API function
+ * (such as xMessageBufferSend()) inside a critical section and set the send
+ * block time to 0.  Likewise, if there are to be multiple different readers
+ * then the application writer must place each call to a reading API function
+ * (such as xMessageBufferRead()) inside a critical section and set the receive
+ * block time to 0.
+ *
+ * Use xMessageBufferSend() to write to a message buffer from a task.  Use
+ * xMessageBufferSendFromISR() to write to a message buffer from an interrupt
+ * service routine (ISR).
+ *
+ * @param xMessageBuffer The handle of the message buffer to which a message is
+ * being sent.
+ *
+ * @param pvTxData A pointer to the message that is to be copied into the
+ * message buffer.
+ *
+ * @param xDataLengthBytes The length of the message.  That is, the number of
+ * bytes to copy from pvTxData into the message buffer.  When a message is
+ * written to the message buffer an additional sizeof( size_t ) bytes are also
+ * written to store the message's length.  sizeof( size_t ) is typically 4 bytes
+ * on a 32-bit architecture, so on most 32-bit architecture setting
+ * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
+ * bytes (20 bytes of message data and 4 bytes to hold the message length).
+ *
+ * @param pxHigherPriorityTaskWoken  It is possible that a message buffer will
+ * have a task blocked on it waiting for data.  Calling
+ * xMessageBufferSendFromISR() can make data available, and so cause a task that
+ * was waiting for data to leave the Blocked state.  If calling
+ * xMessageBufferSendFromISR() causes a task to leave the Blocked state, and the
+ * unblocked task has a priority higher than the currently executing task (the
+ * task that was interrupted), then, internally, xMessageBufferSendFromISR()
+ * will set *pxHigherPriorityTaskWoken to pdTRUE.  If
+ * xMessageBufferSendFromISR() sets this value to pdTRUE, then normally a
+ * context switch should be performed before the interrupt is exited.  This will
+ * ensure that the interrupt returns directly to the highest priority Ready
+ * state task.  *pxHigherPriorityTaskWoken should be set to pdFALSE before it
+ * is passed into the function.  See the code example below for an example.
+ *
+ * @return The number of bytes actually written to the message buffer.  If the
+ * message buffer didn't have enough free space for the message to be stored
+ * then 0 is returned, otherwise xDataLengthBytes is returned.
+ *
+ * Example use:
+ * @code{c}       
+ * // A message buffer that has already been created.
+ * MessageBufferHandle_t xMessageBuffer;
+ *
+ * void vAnInterruptServiceRoutine( void )
+ * {
+ * size_t xBytesSent;
+ * char *pcStringToSend = "String to send";
+ * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
+ *
+ *   // Attempt to send the string to the message buffer.
+ *   xBytesSent = xMessageBufferSendFromISR( xMessageBuffer,
+ *                                           ( void * ) pcStringToSend,
+ *                                           strlen( pcStringToSend ),
+ *                                           &xHigherPriorityTaskWoken );
+ *
+ *   if( xBytesSent != strlen( pcStringToSend ) )
+ *   {
+ *       // The string could not be added to the message buffer because there was
+ *       // not enough free space in the buffer.
+ *   }
+ *
+ *   // If xHigherPriorityTaskWoken was set to pdTRUE inside
+ *   // xMessageBufferSendFromISR() then a task that has a priority above the
+ *   // priority of the currently executing task was unblocked and a context
+ *   // switch should be performed to ensure the ISR returns to the unblocked
+ *   // task.  In most FreeRTOS ports this is done by simply passing
+ *   // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
+ *   // variables value, and perform the context switch if necessary.  Check the
+ *   // documentation for the port in use for port specific instructions.
+ *   portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+ * }
+ * @endcode       
+ * \ingroup MessageBufferManagement
+ */
+#define xMessageBufferSendFromISR( xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferSendFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken )
+
+/**
+ * Receives a discrete message from a message buffer.  Messages can be of
+ * variable length and are copied out of the buffer.
+ *
+ * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
+ * implementation (so also the message buffer implementation, as message buffers
+ * are built on top of stream buffers) assumes there is only one task or
+ * interrupt that will write to the buffer (the writer), and only one task or
+ * interrupt that will read from the buffer (the reader).  It is safe for the
+ * writer and reader to be different tasks or interrupts, but, unlike other
+ * FreeRTOS objects, it is not safe to have multiple different writers or
+ * multiple different readers.  If there are to be multiple different writers
+ * then the application writer must place each call to a writing API function
+ * (such as xMessageBufferSend()) inside a critical section and set the send
+ * block time to 0.  Likewise, if there are to be multiple different readers
+ * then the application writer must place each call to a reading API function
+ * (such as xMessageBufferRead()) inside a critical section and set the receive
+ * block time to 0.
+ *
+ * Use xMessageBufferReceive() to read from a message buffer from a task.  Use
+ * xMessageBufferReceiveFromISR() to read from a message buffer from an
+ * interrupt service routine (ISR).
+ *
+ * @param xMessageBuffer The handle of the message buffer from which a message
+ * is being received.
+ *
+ * @param pvRxData A pointer to the buffer into which the received message is
+ * to be copied.
+ *
+ * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData
+ * parameter.  This sets the maximum length of the message that can be received.
+ * If xBufferLengthBytes is too small to hold the next message then the message
+ * will be left in the message buffer and 0 will be returned.
+ *
+ * @param xTicksToWait The maximum amount of time the task should remain in the
+ * Blocked state to wait for a message, should the message buffer be empty.
+ * xMessageBufferReceive() will return immediately if xTicksToWait is zero and
+ * the message buffer is empty.  The block time is specified in tick periods, so
+ * the absolute time it represents is dependent on the tick frequency.  The
+ * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds
+ * into a time specified in ticks.  Setting xTicksToWait to portMAX_DELAY will
+ * cause the task to wait indefinitely (without timing out), provided
+ * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h.  Tasks do not use any
+ * CPU time when they are in the Blocked state.
+ *
+ * @return The length, in bytes, of the message read from the message buffer, if
+ * any.  If xMessageBufferReceive() times out before a message became available
+ * then zero is returned.  If the length of the message is greater than
+ * xBufferLengthBytes then the message will be left in the message buffer and
+ * zero is returned.
+ *
+ * Example use:
+ * @code{c}       
+ * void vAFunction( MessageBuffer_t xMessageBuffer )
+ * {
+ * uint8_t ucRxData[ 20 ];
+ * size_t xReceivedBytes;
+ * const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
+ *
+ *   // Receive the next message from the message buffer.  Wait in the Blocked
+ *   // state (so not using any CPU processing time) for a maximum of 100ms for
+ *   // a message to become available.
+ *   xReceivedBytes = xMessageBufferReceive( xMessageBuffer,
+ *                                           ( void * ) ucRxData,
+ *                                           sizeof( ucRxData ),
+ *                                           xBlockTime );
+ *
+ *   if( xReceivedBytes > 0 )
+ *   {
+ *       // A ucRxData contains a message that is xReceivedBytes long.  Process
+ *       // the message here....
+ *   }
+ * }
+ * @endcode       
+ * \ingroup MessageBufferManagement
+ */
+#define xMessageBufferReceive( xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) xStreamBufferReceive( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait )
+
+
+/**
+ * An interrupt safe version of the API function that receives a discrete
+ * message from a message buffer.  Messages can be of variable length and are
+ * copied out of the buffer.
+ *
+ * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
+ * implementation (so also the message buffer implementation, as message buffers
+ * are built on top of stream buffers) assumes there is only one task or
+ * interrupt that will write to the buffer (the writer), and only one task or
+ * interrupt that will read from the buffer (the reader).  It is safe for the
+ * writer and reader to be different tasks or interrupts, but, unlike other
+ * FreeRTOS objects, it is not safe to have multiple different writers or
+ * multiple different readers.  If there are to be multiple different writers
+ * then the application writer must place each call to a writing API function
+ * (such as xMessageBufferSend()) inside a critical section and set the send
+ * block time to 0.  Likewise, if there are to be multiple different readers
+ * then the application writer must place each call to a reading API function
+ * (such as xMessageBufferRead()) inside a critical section and set the receive
+ * block time to 0.
+ *
+ * Use xMessageBufferReceive() to read from a message buffer from a task.  Use
+ * xMessageBufferReceiveFromISR() to read from a message buffer from an
+ * interrupt service routine (ISR).
+ *
+ * @param xMessageBuffer The handle of the message buffer from which a message
+ * is being received.
+ *
+ * @param pvRxData A pointer to the buffer into which the received message is
+ * to be copied.
+ *
+ * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData
+ * parameter.  This sets the maximum length of the message that can be received.
+ * If xBufferLengthBytes is too small to hold the next message then the message
+ * will be left in the message buffer and 0 will be returned.
+ *
+ * @param pxHigherPriorityTaskWoken  It is possible that a message buffer will
+ * have a task blocked on it waiting for space to become available.  Calling
+ * xMessageBufferReceiveFromISR() can make space available, and so cause a task
+ * that is waiting for space to leave the Blocked state.  If calling
+ * xMessageBufferReceiveFromISR() causes a task to leave the Blocked state, and
+ * the unblocked task has a priority higher than the currently executing task
+ * (the task that was interrupted), then, internally,
+ * xMessageBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE.
+ * If xMessageBufferReceiveFromISR() sets this value to pdTRUE, then normally a
+ * context switch should be performed before the interrupt is exited.  That will
+ * ensure the interrupt returns directly to the highest priority Ready state
+ * task.  *pxHigherPriorityTaskWoken should be set to pdFALSE before it is
+ * passed into the function.  See the code example below for an example.
+ *
+ * @return The length, in bytes, of the message read from the message buffer, if
+ * any.
+ *
+ * Example use:
+ * @code{c}       
+ * // A message buffer that has already been created.
+ * MessageBuffer_t xMessageBuffer;
+ *
+ * void vAnInterruptServiceRoutine( void )
+ * {
+ * uint8_t ucRxData[ 20 ];
+ * size_t xReceivedBytes;
+ * BaseType_t xHigherPriorityTaskWoken = pdFALSE;  // Initialised to pdFALSE.
+ *
+ *   // Receive the next message from the message buffer.
+ *   xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer,
+ *                                                 ( void * ) ucRxData,
+ *                                                 sizeof( ucRxData ),
+ *                                                 &xHigherPriorityTaskWoken );
+ *
+ *   if( xReceivedBytes > 0 )
+ *   {
+ *       // A ucRxData contains a message that is xReceivedBytes long.  Process
+ *       // the message here....
+ *   }
+ *
+ *   // If xHigherPriorityTaskWoken was set to pdTRUE inside
+ *   // xMessageBufferReceiveFromISR() then a task that has a priority above the
+ *   // priority of the currently executing task was unblocked and a context
+ *   // switch should be performed to ensure the ISR returns to the unblocked
+ *   // task.  In most FreeRTOS ports this is done by simply passing
+ *   // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
+ *   // variables value, and perform the context switch if necessary.  Check the
+ *   // documentation for the port in use for port specific instructions.
+ *   portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+ * }
+ * @endcode       
+ * \ingroup MessageBufferManagement
+ */
+#define xMessageBufferReceiveFromISR( xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferReceiveFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken )
+
+/**
+ * Deletes a message buffer that was previously created using a call to
+ * xMessageBufferCreate() or xMessageBufferCreateStatic().  If the message
+ * buffer was created using dynamic memory (that is, by xMessageBufferCreate()),
+ * then the allocated memory is freed.
+ *
+ * A message buffer handle must not be used after the message buffer has been
+ * deleted.
+ *
+ * @param xMessageBuffer The handle of the message buffer to be deleted.
+ *
+ */
+#define vMessageBufferDelete( xMessageBuffer ) vStreamBufferDelete( ( StreamBufferHandle_t ) xMessageBuffer )
+
+/**
+ * Tests to see if a message buffer is full.  A message buffer is full if it
+ * cannot accept any more messages, of any size, until space is made available
+ * by a message being removed from the message buffer.
+ *
+ * @param xMessageBuffer The handle of the message buffer being queried.
+ *
+ * @return If the message buffer referenced by xMessageBuffer is full then
+ * pdTRUE is returned.  Otherwise pdFALSE is returned.
+ */
+#define xMessageBufferIsFull( xMessageBuffer ) xStreamBufferIsFull( ( StreamBufferHandle_t ) xMessageBuffer )
+
+/**
+ * Tests to see if a message buffer is empty (does not contain any messages).
+ *
+ * @param xMessageBuffer The handle of the message buffer being queried.
+ *
+ * @return If the message buffer referenced by xMessageBuffer is empty then
+ * pdTRUE is returned.  Otherwise pdFALSE is returned.
+ *
+ */
+#define xMessageBufferIsEmpty( xMessageBuffer ) xStreamBufferIsEmpty( ( StreamBufferHandle_t ) xMessageBuffer )
+
+/**
+ * Resets a message buffer to its initial empty state, discarding any message it
+ * contained.
+ *
+ * A message buffer can only be reset if there are no tasks blocked on it.
+ *
+ * @param xMessageBuffer The handle of the message buffer being reset.
+ *
+ * @return If the message buffer was reset then pdPASS is returned.  If the
+ * message buffer could not be reset because either there was a task blocked on
+ * the message queue to wait for space to become available, or to wait for a
+ * a message to be available, then pdFAIL is returned.
+ *
+ * \ingroup MessageBufferManagement
+ */
+#define xMessageBufferReset( xMessageBuffer ) xStreamBufferReset( ( StreamBufferHandle_t ) xMessageBuffer )
+
+
+/**
+ * Returns the number of bytes of free space in the message buffer.
+ *
+ * @param xMessageBuffer The handle of the message buffer being queried.
+ *
+ * @return The number of bytes that can be written to the message buffer before
+ * the message buffer would be full.  When a message is written to the message
+ * buffer an additional sizeof( size_t ) bytes are also written to store the
+ * message's length.  sizeof( size_t ) is typically 4 bytes on a 32-bit
+ * architecture, so if xMessageBufferSpacesAvailable() returns 10, then the size
+ * of the largest message that can be written to the message buffer is 6 bytes.
+ *
+ * \ingroup MessageBufferManagement
+ */
+#define xMessageBufferSpaceAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer )
+#define xMessageBufferSpacesAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) /* Corrects typo in original macro name. */
+
+/**
+ * Returns the length (in bytes) of the next message in a message buffer.
+ * Useful if xMessageBufferReceive() returned 0 because the size of the buffer
+ * passed into xMessageBufferReceive() was too small to hold the next message.
+ *
+ * @param xMessageBuffer The handle of the message buffer being queried.
+ *
+ * @return The length (in bytes) of the next message in the message buffer, or 0
+ * if the message buffer is empty.
+ *
+ * \ingroup MessageBufferManagement
+ */
+#define xMessageBufferNextLengthBytes( xMessageBuffer ) xStreamBufferNextMessageLengthBytes( ( StreamBufferHandle_t ) xMessageBuffer ) PRIVILEGED_FUNCTION;
+
+/**
+ * For advanced users only.
+ *
+ * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when
+ * data is sent to a message buffer or stream buffer.  If there was a task that
+ * was blocked on the message or stream buffer waiting for data to arrive then
+ * the sbSEND_COMPLETED() macro sends a notification to the task to remove it
+ * from the Blocked state.  xMessageBufferSendCompletedFromISR() does the same
+ * thing.  It is provided to enable application writers to implement their own
+ * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME.
+ *
+ * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
+ * additional information.
+ *
+ * @param xMessageBuffer The handle of the stream buffer to which data was
+ * written.
+ *
+ * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
+ * initialised to pdFALSE before it is passed into
+ * xMessageBufferSendCompletedFromISR().  If calling
+ * xMessageBufferSendCompletedFromISR() removes a task from the Blocked state,
+ * and the task has a priority above the priority of the currently running task,
+ * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
+ * context switch should be performed before exiting the ISR.
+ *
+ * @return If a task was removed from the Blocked state then pdTRUE is returned.
+ * Otherwise pdFALSE is returned.
+ *
+ * \ingroup StreamBufferManagement
+ */
+#define xMessageBufferSendCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferSendCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken )
+
+/**
+ * For advanced users only.
+ *
+ * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when
+ * data is read out of a message buffer or stream buffer.  If there was a task
+ * that was blocked on the message or stream buffer waiting for data to arrive
+ * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to
+ * remove it from the Blocked state.  xMessageBufferReceiveCompletedFromISR()
+ * does the same thing.  It is provided to enable application writers to
+ * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT
+ * ANY OTHER TIME.
+ *
+ * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
+ * additional information.
+ *
+ * @param xMessageBuffer The handle of the stream buffer from which data was
+ * read.
+ *
+ * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
+ * initialised to pdFALSE before it is passed into
+ * xMessageBufferReceiveCompletedFromISR().  If calling
+ * xMessageBufferReceiveCompletedFromISR() removes a task from the Blocked state,
+ * and the task has a priority above the priority of the currently running task,
+ * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
+ * context switch should be performed before exiting the ISR.
+ *
+ * @return If a task was removed from the Blocked state then pdTRUE is returned.
+ * Otherwise pdFALSE is returned.
+ *
+ * \ingroup StreamBufferManagement
+ */
+#define xMessageBufferReceiveCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferReceiveCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken )
+
+#if defined( __cplusplus )
+} /* extern "C" */
+#endif
+
+#endif	/* !defined( FREERTOS_MESSAGE_BUFFER_H ) */

+ 150 - 120
components/freertos/include/freertos/mpu_wrappers.h

@@ -1,71 +1,29 @@
 /*
-    FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
-    All rights reserved
-
-    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License (version 2) as published by the
-    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
-
-	***************************************************************************
-    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
-    >>!   distribute a combined work that includes FreeRTOS without being   !<<
-    >>!   obliged to provide the source code for proprietary components     !<<
-    >>!   outside of the FreeRTOS kernel.                                   !<<
-	***************************************************************************
-
-    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
-    link: http://www.freertos.org/a00114.html
-
-    ***************************************************************************
-     *                                                                       *
-     *    FreeRTOS provides completely free yet professionally developed,    *
-     *    robust, strictly quality controlled, supported, and cross          *
-     *    platform software that is more than just the market leader, it     *
-     *    is the industry's de facto standard.                               *
-     *                                                                       *
-     *    Help yourself get started quickly while simultaneously helping     *
-     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
-     *    tutorial book, reference manual, or both:                          *
-     *    http://www.FreeRTOS.org/Documentation                              *
-     *                                                                       *
-    ***************************************************************************
-
-    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
-	the FAQ page "My application does not run, what could be wrong?".  Have you
-	defined configASSERT()?
-
-	http://www.FreeRTOS.org/support - In return for receiving this top quality
-	embedded software for free we request you assist our global community by
-	participating in the support forum.
-
-	http://www.FreeRTOS.org/training - Investing in training allows your team to
-	be as productive as possible as early as possible.  Now you can receive
-	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
-	Ltd, and the world's leading authority on the world's leading RTOS.
-
-    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
-    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
-    compatible FAT file system, and our tiny thread aware UDP/IP stack.
-
-    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
-    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
-
-    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
-    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
-    licenses offer ticketed support, indemnification and commercial middleware.
-
-    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
-    engineered and independently SIL3 certified version for use in safety and
-    mission critical applications that require provable dependability.
-
-    1 tab == 4 spaces!
-*/
+ * FreeRTOS Kernel V10.2.1
+ * 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 MPU_WRAPPERS_H
 #define MPU_WRAPPERS_H
@@ -79,68 +37,139 @@ only for ports that are using the MPU. */
 	those files. */
 	#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 
-		#define xTaskGenericCreate				MPU_xTaskGenericCreate
-		#define vTaskAllocateMPURegions			MPU_vTaskAllocateMPURegions
-		#define vTaskDelete						MPU_vTaskDelete
-		#define vTaskDelayUntil					MPU_vTaskDelayUntil
-		#define vTaskDelay						MPU_vTaskDelay
-		#define uxTaskPriorityGet				MPU_uxTaskPriorityGet
-		#define vTaskPrioritySet				MPU_vTaskPrioritySet
-		#define eTaskGetState					MPU_eTaskGetState
-		#define vTaskSuspend					MPU_vTaskSuspend
-		#define vTaskResume						MPU_vTaskResume
-		#define vTaskSuspendAll					MPU_vTaskSuspendAll
-		#define xTaskResumeAll					MPU_xTaskResumeAll
-		#define xTaskGetTickCount				MPU_xTaskGetTickCount
-		#define uxTaskGetNumberOfTasks			MPU_uxTaskGetNumberOfTasks
-		#define vTaskList						MPU_vTaskList
-		#define vTaskGetRunTimeStats			MPU_vTaskGetRunTimeStats
-		#define vTaskSetApplicationTaskTag		MPU_vTaskSetApplicationTaskTag
-		#define xTaskGetApplicationTaskTag		MPU_xTaskGetApplicationTaskTag
-		#define xTaskCallApplicationTaskHook	MPU_xTaskCallApplicationTaskHook
-		#define uxTaskGetStackHighWaterMark		MPU_uxTaskGetStackHighWaterMark
-		#define xTaskGetCurrentTaskHandle		MPU_xTaskGetCurrentTaskHandle
-		#define xTaskGetSchedulerState			MPU_xTaskGetSchedulerState
-		#define xTaskGetIdleTaskHandle			MPU_xTaskGetIdleTaskHandle
-		#define uxTaskGetSystemState			MPU_uxTaskGetSystemState
-
-		#define xQueueGenericCreate				MPU_xQueueGenericCreate
-		#define xQueueCreateMutex				MPU_xQueueCreateMutex
-		#define xQueueGiveMutexRecursive		MPU_xQueueGiveMutexRecursive
-		#define xQueueTakeMutexRecursive		MPU_xQueueTakeMutexRecursive
-		#define xQueueCreateCountingSemaphore	MPU_xQueueCreateCountingSemaphore
-		#define xQueueGenericSend				MPU_xQueueGenericSend
-		#define xQueueAltGenericSend			MPU_xQueueAltGenericSend
-		#define xQueueAltGenericReceive			MPU_xQueueAltGenericReceive
-		#define xQueueGenericReceive			MPU_xQueueGenericReceive
-		#define uxQueueMessagesWaiting			MPU_uxQueueMessagesWaiting
-		#define vQueueDelete					MPU_vQueueDelete
-		#define xQueueGenericReset				MPU_xQueueGenericReset
-		#define xQueueCreateSet					MPU_xQueueCreateSet
-		#define xQueueSelectFromSet				MPU_xQueueSelectFromSet
-		#define xQueueAddToSet					MPU_xQueueAddToSet
-		#define xQueueRemoveFromSet				MPU_xQueueRemoveFromSet
-		#define xQueuePeekFromISR				MPU_xQueuePeekFromISR
-		#define xQueueGetMutexHolder			MPU_xQueueGetMutexHolder
-
-		#define pvPortMalloc					MPU_pvPortMalloc
-		#define vPortFree						MPU_vPortFree
-		#define xPortGetFreeHeapSize			MPU_xPortGetFreeHeapSize
-		#define vPortInitialiseBlocks			MPU_vPortInitialiseBlocks
-
-		#if configQUEUE_REGISTRY_SIZE > 0
-			#define vQueueAddToRegistry				MPU_vQueueAddToRegistry
-			#define vQueueUnregisterQueue			MPU_vQueueUnregisterQueue
+		/*
+		 * Map standard (non MPU) API functions to equivalents that start
+		 * "MPU_".  This will cause the application code to call the MPU_
+		 * version, which wraps the non-MPU version with privilege promoting
+		 * then demoting code, so the kernel code always runs will full
+		 * privileges.
+		 */
+
+		/* Map standard tasks.h API functions to the MPU equivalents. */
+		#define xTaskCreate								MPU_xTaskCreate
+		#define xTaskCreateStatic						MPU_xTaskCreateStatic
+		#define xTaskCreateRestricted					MPU_xTaskCreateRestricted
+		#define vTaskAllocateMPURegions					MPU_vTaskAllocateMPURegions
+		#define vTaskDelete								MPU_vTaskDelete
+		#define vTaskDelay								MPU_vTaskDelay
+		#define vTaskDelayUntil							MPU_vTaskDelayUntil
+		#define xTaskAbortDelay							MPU_xTaskAbortDelay
+		#define uxTaskPriorityGet						MPU_uxTaskPriorityGet
+		#define eTaskGetState							MPU_eTaskGetState
+		#define vTaskGetInfo							MPU_vTaskGetInfo
+		#define vTaskPrioritySet						MPU_vTaskPrioritySet
+		#define vTaskSuspend							MPU_vTaskSuspend
+		#define vTaskResume								MPU_vTaskResume
+		#define vTaskSuspendAll							MPU_vTaskSuspendAll
+		#define xTaskResumeAll							MPU_xTaskResumeAll
+		#define xTaskGetTickCount						MPU_xTaskGetTickCount
+		#define uxTaskGetNumberOfTasks					MPU_uxTaskGetNumberOfTasks
+		#define pcTaskGetName							MPU_pcTaskGetName
+		#define xTaskGetHandle							MPU_xTaskGetHandle
+		#define uxTaskGetStackHighWaterMark				MPU_uxTaskGetStackHighWaterMark
+		#define uxTaskGetStackHighWaterMark2			MPU_uxTaskGetStackHighWaterMark2
+		#define vTaskSetApplicationTaskTag				MPU_vTaskSetApplicationTaskTag
+		#define xTaskGetApplicationTaskTag				MPU_xTaskGetApplicationTaskTag
+		// #define vTaskSetThreadLocalStoragePointer		MPU_vTaskSetThreadLocalStoragePointer
+		// #define pvTaskGetThreadLocalStoragePointer		MPU_pvTaskGetThreadLocalStoragePointer
+		#define xTaskCallApplicationTaskHook			MPU_xTaskCallApplicationTaskHook
+		#define xTaskGetIdleTaskHandle					MPU_xTaskGetIdleTaskHandle
+		#define uxTaskGetSystemState					MPU_uxTaskGetSystemState
+		#define vTaskList								MPU_vTaskList
+		#define vTaskGetRunTimeStats					MPU_vTaskGetRunTimeStats
+		#define ulTaskGetIdleRunTimeCounter				MPU_ulTaskGetIdleRunTimeCounter
+		#define xTaskGenericNotify						MPU_xTaskGenericNotify
+		#define xTaskNotifyWait							MPU_xTaskNotifyWait
+		#define ulTaskNotifyTake						MPU_ulTaskNotifyTake
+		#define xTaskNotifyStateClear					MPU_xTaskNotifyStateClear
+		#define xTaskCatchUpTicks						MPU_xTaskCatchUpTicks
+
+		#define xTaskGetCurrentTaskHandle				MPU_xTaskGetCurrentTaskHandle
+		#define vTaskSetTimeOutState					MPU_vTaskSetTimeOutState
+		#define xTaskCheckForTimeOut					MPU_xTaskCheckForTimeOut
+		#define xTaskGetSchedulerState					MPU_xTaskGetSchedulerState
+
+		/* Map standard queue.h API functions to the MPU equivalents. */
+		#define xQueueGenericSend						MPU_xQueueGenericSend
+		#define xQueueReceive							MPU_xQueueReceive
+		#define xQueuePeek								MPU_xQueuePeek
+		#define xQueueSemaphoreTake						MPU_xQueueSemaphoreTake
+		#define uxQueueMessagesWaiting					MPU_uxQueueMessagesWaiting
+		#define uxQueueSpacesAvailable					MPU_uxQueueSpacesAvailable
+		#define vQueueDelete							MPU_vQueueDelete
+		#define xQueueCreateMutex						MPU_xQueueCreateMutex
+		#define xQueueCreateMutexStatic					MPU_xQueueCreateMutexStatic
+		#define xQueueCreateCountingSemaphore			MPU_xQueueCreateCountingSemaphore
+		#define xQueueCreateCountingSemaphoreStatic		MPU_xQueueCreateCountingSemaphoreStatic
+		#define xQueueGetMutexHolder					MPU_xQueueGetMutexHolder
+		#define xQueueTakeMutexRecursive				MPU_xQueueTakeMutexRecursive
+		#define xQueueGiveMutexRecursive				MPU_xQueueGiveMutexRecursive
+		#define xQueueGenericCreate						MPU_xQueueGenericCreate
+		#define xQueueGenericCreateStatic				MPU_xQueueGenericCreateStatic
+		#define xQueueCreateSet							MPU_xQueueCreateSet
+		#define xQueueAddToSet							MPU_xQueueAddToSet
+		#define xQueueRemoveFromSet						MPU_xQueueRemoveFromSet
+		#define xQueueSelectFromSet						MPU_xQueueSelectFromSet
+		#define xQueueGenericReset						MPU_xQueueGenericReset
+
+		#if( configQUEUE_REGISTRY_SIZE > 0 )
+			#define vQueueAddToRegistry						MPU_vQueueAddToRegistry
+			#define vQueueUnregisterQueue					MPU_vQueueUnregisterQueue
+			#define pcQueueGetName							MPU_pcQueueGetName
 		#endif
 
-		/* Remove the privileged function macro. */
+		/* Map standard timer.h API functions to the MPU equivalents. */
+		#define xTimerCreate							MPU_xTimerCreate
+		#define xTimerCreateStatic						MPU_xTimerCreateStatic
+		#define pvTimerGetTimerID						MPU_pvTimerGetTimerID
+		#define vTimerSetTimerID						MPU_vTimerSetTimerID
+		#define xTimerIsTimerActive						MPU_xTimerIsTimerActive
+		#define xTimerGetTimerDaemonTaskHandle			MPU_xTimerGetTimerDaemonTaskHandle
+		#define xTimerPendFunctionCall					MPU_xTimerPendFunctionCall
+		#define pcTimerGetName							MPU_pcTimerGetName
+		#define vTimerSetReloadMode						MPU_vTimerSetReloadMode
+		#define xTimerGetPeriod							MPU_xTimerGetPeriod
+		#define xTimerGetExpiryTime						MPU_xTimerGetExpiryTime
+		#define xTimerGenericCommand					MPU_xTimerGenericCommand
+
+		/* Map standard event_group.h API functions to the MPU equivalents. */
+		#define xEventGroupCreate						MPU_xEventGroupCreate
+		#define xEventGroupCreateStatic					MPU_xEventGroupCreateStatic
+		#define xEventGroupWaitBits						MPU_xEventGroupWaitBits
+		#define xEventGroupClearBits					MPU_xEventGroupClearBits
+		#define xEventGroupSetBits						MPU_xEventGroupSetBits
+		#define xEventGroupSync							MPU_xEventGroupSync
+		#define vEventGroupDelete						MPU_vEventGroupDelete
+
+		/* Map standard message/stream_buffer.h API functions to the MPU
+		equivalents. */
+		#define xStreamBufferSend						MPU_xStreamBufferSend
+		#define xStreamBufferReceive					MPU_xStreamBufferReceive
+		#define xStreamBufferNextMessageLengthBytes		MPU_xStreamBufferNextMessageLengthBytes
+		#define vStreamBufferDelete						MPU_vStreamBufferDelete
+		#define xStreamBufferIsFull						MPU_xStreamBufferIsFull
+		#define xStreamBufferIsEmpty					MPU_xStreamBufferIsEmpty
+		#define xStreamBufferReset						MPU_xStreamBufferReset
+		#define xStreamBufferSpacesAvailable			MPU_xStreamBufferSpacesAvailable
+		#define xStreamBufferBytesAvailable				MPU_xStreamBufferBytesAvailable
+		#define xStreamBufferSetTriggerLevel			MPU_xStreamBufferSetTriggerLevel
+		#define xStreamBufferGenericCreate				MPU_xStreamBufferGenericCreate
+		#define xStreamBufferGenericCreateStatic		MPU_xStreamBufferGenericCreateStatic
+
+
+		/* Remove the privileged function macro, but keep the PRIVILEGED_DATA
+		macro so applications can place data in privileged access sections
+		(useful when using statically allocated objects). */
 		#define PRIVILEGED_FUNCTION
+		#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
+		#define FREERTOS_SYSTEM_CALL
 
 	#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
 
 		/* Ensure API functions go in the privileged execution section. */
 		#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
 		#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
+		#define FREERTOS_SYSTEM_CALL __attribute__((section( "freertos_system_calls")))
 
 	#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
 
@@ -148,6 +177,7 @@ only for ports that are using the MPU. */
 
 	#define PRIVILEGED_FUNCTION
 	#define PRIVILEGED_DATA
+	#define FREERTOS_SYSTEM_CALL
 	#define portUSING_MPU_WRAPPERS 0
 
 #endif /* portUSING_MPU_WRAPPERS */

+ 105 - 142
components/freertos/include/freertos/portable.h

@@ -1,71 +1,29 @@
 /*
-    FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
-    All rights reserved
-
-    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License (version 2) as published by the
-    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
-
-	***************************************************************************
-    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
-    >>!   distribute a combined work that includes FreeRTOS without being   !<<
-    >>!   obliged to provide the source code for proprietary components     !<<
-    >>!   outside of the FreeRTOS kernel.                                   !<<
-	***************************************************************************
-
-    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
-    link: http://www.freertos.org/a00114.html
-
-    ***************************************************************************
-     *                                                                       *
-     *    FreeRTOS provides completely free yet professionally developed,    *
-     *    robust, strictly quality controlled, supported, and cross          *
-     *    platform software that is more than just the market leader, it     *
-     *    is the industry's de facto standard.                               *
-     *                                                                       *
-     *    Help yourself get started quickly while simultaneously helping     *
-     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
-     *    tutorial book, reference manual, or both:                          *
-     *    http://www.FreeRTOS.org/Documentation                              *
-     *                                                                       *
-    ***************************************************************************
-
-    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
-	the FAQ page "My application does not run, what could be wrong?".  Have you
-	defined configASSERT()?
-
-	http://www.FreeRTOS.org/support - In return for receiving this top quality
-	embedded software for free we request you assist our global community by
-	participating in the support forum.
-
-	http://www.FreeRTOS.org/training - Investing in training allows your team to
-	be as productive as possible as early as possible.  Now you can receive
-	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
-	Ltd, and the world's leading authority on the world's leading RTOS.
-
-    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
-    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
-    compatible FAT file system, and our tiny thread aware UDP/IP stack.
-
-    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
-    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
-
-    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
-    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
-    licenses offer ticketed support, indemnification and commercial middleware.
-
-    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
-    engineered and independently SIL3 certified version for use in safety and
-    mission critical applications that require provable dependability.
-
-    1 tab == 4 spaces!
-*/
+ * FreeRTOS Kernel V10.2.1
+ * 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!
+ */
 
 /*-----------------------------------------------------------
  * Portable layer API.  Each function must be defined for each port.
@@ -86,7 +44,6 @@ specific constants has been moved into the deprecated_definitions.h header
 file. */
 #include "deprecated_definitions.h"
 
-
 /* If portENTER_CRITICAL is not defined then including deprecated_definitions.h
 did not result in a portmacro.h header file being included - and it should be
 included here.  In this case the path to the correct portmacro.h header file
@@ -95,8 +52,16 @@ must be set in the compiler's include path. */
 	#include "freertos/portmacro.h"
 #endif
 
+#if portBYTE_ALIGNMENT == 32
+	#define portBYTE_ALIGNMENT_MASK ( 0x001f )
+#endif
+
+#if portBYTE_ALIGNMENT == 16
+	#define portBYTE_ALIGNMENT_MASK ( 0x000f )
+#endif
+
 #if portBYTE_ALIGNMENT == 8
-	#define portBYTE_ALIGNMENT_MASK ( 0x0007U )
+	#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
 #endif
 
 #if portBYTE_ALIGNMENT == 4
@@ -119,15 +84,19 @@ must be set in the compiler's include path. */
 	#define portNUM_CONFIGURABLE_REGIONS 1
 #endif
 
+#ifndef portHAS_STACK_OVERFLOW_CHECKING
+	#define portHAS_STACK_OVERFLOW_CHECKING 0
+#endif
+
+#ifndef portARCH_NAME
+	#define portARCH_NAME NULL
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 #include "mpu_wrappers.h"
-#include "esp_system.h"
-
-#include "hal/cpu_hal.h"
-#include "xt_instr_macros.h"
 
 /*
  * Setup the stack of a new task so it is ready to be placed under the
@@ -136,11 +105,70 @@ extern "C" {
  *
  */
 #if( portUSING_MPU_WRAPPERS == 1 )
-	StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
+	#if( portHAS_STACK_OVERFLOW_CHECKING == 1 )
+		StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
+	#else
+		StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
+	#endif
 #else
-	StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION;
+	#if( portHAS_STACK_OVERFLOW_CHECKING == 1 )
+		StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION;
+	#else
+		StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION;
+	#endif
 #endif
 
+#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
+{
+	uint8_t *pucStartAddress;
+	size_t xSizeInBytes;
+} HeapRegion_t;
+
+/* Used to pass information about the heap out of vPortGetHeapStats(). */
+typedef struct xHeapStats
+{
+	size_t xAvailableHeapSpaceInBytes;		/* The total heap size currently available - this is the sum of all the free blocks, not the largest block that can be allocated. */
+	size_t xSizeOfLargestFreeBlockInBytes; 	/* The maximum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */
+	size_t xSizeOfSmallestFreeBlockInBytes; /* The minimum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */
+	size_t xNumberOfFreeBlocks;				/* The number of free memory blocks within the heap at the time vPortGetHeapStats() is called. */
+	size_t xMinimumEverFreeBytesRemaining;	/* The minimum amount of total free memory (sum of all free blocks) there has been in the heap since the system booted. */
+	size_t xNumberOfSuccessfulAllocations;	/* The number of calls to pvPortMalloc() that have returned a valid memory block. */
+	size_t xNumberOfSuccessfulFrees;		/* The number of calls to vPortFree() that has successfully freed a block of memory. */
+} HeapStats_t;
+
+/*
+ * Used to define multiple heap regions for use by heap_5.c.  This function
+ * must be called before any calls to pvPortMalloc() - not creating a task,
+ * queue, semaphore, mutex, software timer, event group, etc. will result in
+ * pvPortMalloc being called.
+ *
+ * pxHeapRegions passes in an array of HeapRegion_t structures - each of which
+ * defines a region of memory that can be used as the heap.  The array is
+ * terminated by a HeapRegions_t structure that has a size of 0.  The region
+ * with the lowest start address must appear first in the array.
+ */
+void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION;
+
+/*
+ * Returns a HeapStats_t structure filled with information about the current
+ * heap state.
+ */
+void vPortGetHeapStats( HeapStats_t *pxHeapStats );
+/*
+ * Map to the memory management routines required for the port.
+ */
+void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;
+void vPortFree( void *pv ) PRIVILEGED_FUNCTION;
+void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
+size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;
+size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION;
+
+#else  // configUSE_FREERTOS_PROVIDED_HEAP
+
 /*
  * Map to the memory management routines required for the port.
  *
@@ -153,6 +181,8 @@ extern "C" {
 #define xPortGetFreeHeapSize esp_get_free_heap_size
 #define xPortGetMinimumEverFreeHeapSize esp_get_minimum_free_heap_size
 
+#endif
+
 /*
  * Setup the hardware ready for the scheduler to take control.  This generally
  * sets up a tick interrupt and sets timers for the correct tick frequency.
@@ -166,76 +196,9 @@ BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION;
  */
 void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
 
-
-/*
- * Send an interrupt to another core in order to make the task running
- * on it yield for a higher-priority task.
- */
-
-void vPortYieldOtherCore( BaseType_t coreid) PRIVILEGED_FUNCTION;
-
-
-/*
- Callback to set a watchpoint on the end of the stack. Called every context switch to change the stack
- watchpoint around.
- */
-void vPortSetStackWatchpoint( void* pxStackStart );
-
-/*
- * This function will be called in High prio ISRs. Returns true if the current core was in ISR context
- * before calling into high prio ISR context.
- */
-BaseType_t xPortInterruptedFromISRContext(void);
-
-/*
- * The structures and methods of manipulating the MPU are contained within the
- * port layer.
- *
- * Fills the xMPUSettings structure with the memory region information
- * contained in xRegions.
- */
-#if( portUSING_MPU_WRAPPERS == 1 )
-	struct xMEMORY_REGION;
-	void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t usStackDepth ) PRIVILEGED_FUNCTION;
-	void vPortReleaseTaskMPUSettings( xMPU_SETTINGS *xMPUSettings );
-#endif
-
-/* Multi-core: get current core ID */
-static inline uint32_t IRAM_ATTR xPortGetCoreID(void) {
-    return cpu_hal_get_core_id();
-}
-
-/* Get tick rate per second */
-uint32_t xPortGetTickRateHz(void);
-
-
-static inline bool IRAM_ATTR xPortCanYield(void)
-{
-    uint32_t ps_reg = 0;
-
-    //Get the current value of PS (processor status) register
-    RSR(PS, ps_reg);
-
-    /*
-     * intlevel = (ps_reg & 0xf);
-     * excm  = (ps_reg >> 4) & 0x1;
-     * CINTLEVEL is max(excm * EXCMLEVEL, INTLEVEL), where EXCMLEVEL is 3.
-     * However, just return true, only intlevel is zero.
-     */
-
-    return ((ps_reg & PS_INTLEVEL_MASK) == 0);
-}
-
 #ifdef __cplusplus
 }
 #endif
 
-static inline void uxPortCompareSetExtram(volatile uint32_t *addr, uint32_t compare, uint32_t *set) 
-{
-#if defined(CONFIG_ESP32_SPIRAM_SUPPORT)    
-    compare_and_set_extram(addr, compare, set);
-#endif    
-}
-
 #endif /* PORTABLE_H */
 

+ 0 - 42
components/freertos/include/freertos/porttrace.h

@@ -1,42 +0,0 @@
-/*******************************************************************************
-// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
-//
-// 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.
---------------------------------------------------------------------------------
-
-/*
- * This utility helps tracing the entering and exiting from tasks. It maintains a circular buffer
- * of tasks in the order they execute, and their execution time.
- * In order to enable it, set configUSE_TRACE_FACILITY_2 to 1 in FreeRTOSConfig.h.
- * You will also need to download the FreeRTOS_trace patch that contains
- * porttrace.c and the complete version of porttrace.h
- */
-
-#ifndef PORTTRACE_H
-#define PORTTRACE_H
-
-#if configUSE_TRACE_FACILITY_2
-    #error "You need to download the FreeRTOS_trace patch that overwrites this file"
-#endif
-
-#define porttracePrint(nelements)
-#define porttraceStamp(stamp, count_incr)
-
-#endif /* PORTTRACE_H */

+ 90 - 71
components/freertos/include/freertos/projdefs.h

@@ -1,71 +1,29 @@
 /*
-    FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
-    All rights reserved
-
-    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License (version 2) as published by the
-    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
-
-	***************************************************************************
-    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
-    >>!   distribute a combined work that includes FreeRTOS without being   !<<
-    >>!   obliged to provide the source code for proprietary components     !<<
-    >>!   outside of the FreeRTOS kernel.                                   !<<
-	***************************************************************************
-
-    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
-    link: http://www.freertos.org/a00114.html
-
-    ***************************************************************************
-     *                                                                       *
-     *    FreeRTOS provides completely free yet professionally developed,    *
-     *    robust, strictly quality controlled, supported, and cross          *
-     *    platform software that is more than just the market leader, it     *
-     *    is the industry's de facto standard.                               *
-     *                                                                       *
-     *    Help yourself get started quickly while simultaneously helping     *
-     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
-     *    tutorial book, reference manual, or both:                          *
-     *    http://www.FreeRTOS.org/Documentation                              *
-     *                                                                       *
-    ***************************************************************************
-
-    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
-	the FAQ page "My application does not run, what could be wrong?".  Have you
-	defined configASSERT()?
-
-	http://www.FreeRTOS.org/support - In return for receiving this top quality
-	embedded software for free we request you assist our global community by
-	participating in the support forum.
-
-	http://www.FreeRTOS.org/training - Investing in training allows your team to
-	be as productive as possible as early as possible.  Now you can receive
-	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
-	Ltd, and the world's leading authority on the world's leading RTOS.
-
-    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
-    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
-    compatible FAT file system, and our tiny thread aware UDP/IP stack.
-
-    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
-    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
-
-    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
-    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
-    licenses offer ticketed support, indemnification and commercial middleware.
-
-    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
-    engineered and independently SIL3 certified version for use in safety and
-    mission critical applications that require provable dependability.
-
-    1 tab == 4 spaces!
-*/
+ * FreeRTOS Kernel V10.2.1
+ * 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 PROJDEFS_H
 #define PROJDEFS_H
@@ -76,9 +34,17 @@
  */
 typedef void (*TaskFunction_t)( void * );
 
-/* Converts a time in milliseconds to a time in ticks. */
-#define pdMS_TO_TICKS( xTimeInMs ) ( ( ( TickType_t ) ( xTimeInMs ) * configTICK_RATE_HZ ) / ( TickType_t ) 1000 )
-#define pdTICKS_TO_MS( xTicks )   ( ( uint32_t ) ( xTicks ) * 1000 / configTICK_RATE_HZ )
+/* Converts a time in milliseconds to a time in ticks.  This macro can be
+overridden by a macro of the same name defined in FreeRTOSConfig.h in case the
+definition here is not suitable for your application. */
+#ifndef pdMS_TO_TICKS
+	#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) )
+#endif
+
+#ifndef pdTICKS_TO_MS
+	#define pdTICKS_TO_MS( xTicks )   ( ( uint32_t ) ( xTicks ) * 1000 / configTICK_RATE_HZ )
+#endif
+
 
 #define pdFALSE			( ( BaseType_t ) 0 )
 #define pdTRUE			( ( BaseType_t ) 1 )
@@ -88,7 +54,7 @@ typedef void (*TaskFunction_t)( void * );
 #define errQUEUE_EMPTY	( ( BaseType_t ) 0 )
 #define errQUEUE_FULL	( ( BaseType_t ) 0 )
 
-/* Error definitions. */
+/* FreeRTOS error definitions. */
 #define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY	( -1 )
 #define errQUEUE_BLOCKED						( -4 )
 #define errQUEUE_YIELD							( -5 )
@@ -104,6 +70,59 @@ typedef void (*TaskFunction_t)( void * );
 	#define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL
 #endif
 
+/* The following errno values are used by FreeRTOS+ components, not FreeRTOS
+itself. */
+#define pdFREERTOS_ERRNO_NONE			0	/* No errors */
+#define	pdFREERTOS_ERRNO_ENOENT			2	/* No such file or directory */
+#define	pdFREERTOS_ERRNO_EINTR			4	/* Interrupted system call */
+#define	pdFREERTOS_ERRNO_EIO			5	/* I/O error */
+#define	pdFREERTOS_ERRNO_ENXIO			6	/* No such device or address */
+#define	pdFREERTOS_ERRNO_EBADF			9	/* Bad file number */
+#define	pdFREERTOS_ERRNO_EAGAIN			11	/* No more processes */
+#define	pdFREERTOS_ERRNO_EWOULDBLOCK	11	/* Operation would block */
+#define	pdFREERTOS_ERRNO_ENOMEM			12	/* Not enough memory */
+#define	pdFREERTOS_ERRNO_EACCES			13	/* Permission denied */
+#define	pdFREERTOS_ERRNO_EFAULT			14	/* Bad address */
+#define	pdFREERTOS_ERRNO_EBUSY			16	/* Mount device busy */
+#define	pdFREERTOS_ERRNO_EEXIST			17	/* File exists */
+#define	pdFREERTOS_ERRNO_EXDEV			18	/* Cross-device link */
+#define	pdFREERTOS_ERRNO_ENODEV			19	/* No such device */
+#define	pdFREERTOS_ERRNO_ENOTDIR		20	/* Not a directory */
+#define	pdFREERTOS_ERRNO_EISDIR			21	/* Is a directory */
+#define	pdFREERTOS_ERRNO_EINVAL			22	/* Invalid argument */
+#define	pdFREERTOS_ERRNO_ENOSPC			28	/* No space left on device */
+#define	pdFREERTOS_ERRNO_ESPIPE			29	/* Illegal seek */
+#define	pdFREERTOS_ERRNO_EROFS			30	/* Read only file system */
+#define	pdFREERTOS_ERRNO_EUNATCH		42	/* Protocol driver not attached */
+#define	pdFREERTOS_ERRNO_EBADE			50	/* Invalid exchange */
+#define	pdFREERTOS_ERRNO_EFTYPE			79	/* Inappropriate file type or format */
+#define	pdFREERTOS_ERRNO_ENMFILE		89	/* No more files */
+#define	pdFREERTOS_ERRNO_ENOTEMPTY		90	/* Directory not empty */
+#define	pdFREERTOS_ERRNO_ENAMETOOLONG 	91	/* File or path name too long */
+#define	pdFREERTOS_ERRNO_EOPNOTSUPP		95	/* Operation not supported on transport endpoint */
+#define	pdFREERTOS_ERRNO_ENOBUFS		105	/* No buffer space available */
+#define	pdFREERTOS_ERRNO_ENOPROTOOPT	109	/* Protocol not available */
+#define	pdFREERTOS_ERRNO_EADDRINUSE		112	/* Address already in use */
+#define	pdFREERTOS_ERRNO_ETIMEDOUT		116	/* Connection timed out */
+#define	pdFREERTOS_ERRNO_EINPROGRESS	119	/* Connection already in progress */
+#define	pdFREERTOS_ERRNO_EALREADY		120	/* Socket already connected */
+#define	pdFREERTOS_ERRNO_EADDRNOTAVAIL 	125	/* Address not available */
+#define	pdFREERTOS_ERRNO_EISCONN		127	/* Socket is already connected */
+#define	pdFREERTOS_ERRNO_ENOTCONN		128	/* Socket is not connected */
+#define	pdFREERTOS_ERRNO_ENOMEDIUM		135	/* No medium inserted */
+#define	pdFREERTOS_ERRNO_EILSEQ			138	/* An invalid UTF-16 sequence was encountered. */
+#define	pdFREERTOS_ERRNO_ECANCELED		140	/* Operation canceled. */
+
+/* The following endian values are used by FreeRTOS+ components, not FreeRTOS
+itself. */
+#define pdFREERTOS_LITTLE_ENDIAN		0
+#define pdFREERTOS_BIG_ENDIAN			1
+
+/* Re-defining endian values for generic naming. */
+#define pdLITTLE_ENDIAN					pdFREERTOS_LITTLE_ENDIAN
+#define pdBIG_ENDIAN					pdFREERTOS_BIG_ENDIAN
+
+
 #endif /* PROJDEFS_H */
 
 

+ 52 - 219
components/freertos/include/freertos/queue.h

@@ -1,71 +1,29 @@
 /*
-    FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
-    All rights reserved
-
-    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License (version 2) as published by the
-    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
-
-	***************************************************************************
-    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
-    >>!   distribute a combined work that includes FreeRTOS without being   !<<
-    >>!   obliged to provide the source code for proprietary components     !<<
-    >>!   outside of the FreeRTOS kernel.                                   !<<
-	***************************************************************************
-
-    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
-    link: http://www.freertos.org/a00114.html
-
-    ***************************************************************************
-     *                                                                       *
-     *    FreeRTOS provides completely free yet professionally developed,    *
-     *    robust, strictly quality controlled, supported, and cross          *
-     *    platform software that is more than just the market leader, it     *
-     *    is the industry's de facto standard.                               *
-     *                                                                       *
-     *    Help yourself get started quickly while simultaneously helping     *
-     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
-     *    tutorial book, reference manual, or both:                          *
-     *    http://www.FreeRTOS.org/Documentation                              *
-     *                                                                       *
-    ***************************************************************************
-
-    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
-	the FAQ page "My application does not run, what could be wrong?".  Have you
-	defined configASSERT()?
-
-	http://www.FreeRTOS.org/support - In return for receiving this top quality
-	embedded software for free we request you assist our global community by
-	participating in the support forum.
-
-	http://www.FreeRTOS.org/training - Investing in training allows your team to
-	be as productive as possible as early as possible.  Now you can receive
-	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
-	Ltd, and the world's leading authority on the world's leading RTOS.
-
-    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
-    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
-    compatible FAT file system, and our tiny thread aware UDP/IP stack.
-
-    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
-    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
-
-    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
-    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
-    licenses offer ticketed support, indemnification and commercial middleware.
-
-    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
-    engineered and independently SIL3 certified version for use in safety and
-    mission critical applications that require provable dependability.
-
-    1 tab == 4 spaces!
-*/
+ * FreeRTOS Kernel V10.2.1
+ * 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 QUEUE_H
@@ -79,29 +37,32 @@
 extern "C" {
 #endif
 
+#include "task.h"
 
 /**
  * Type by which queues are referenced.  For example, a call to xQueueCreate()
  * returns an QueueHandle_t variable that can then be used as a parameter to
  * xQueueSend(), xQueueReceive(), etc.
  */
-typedef void * QueueHandle_t;
+struct QueueDefinition; /* Using old naming convention so as not to break kernel aware debuggers. */
+typedef struct QueueDefinition * QueueHandle_t;
 
 /**
  * Type by which queue sets are referenced.  For example, a call to
  * xQueueCreateSet() returns an xQueueSet variable that can then be used as a
  * parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc.
  */
-typedef void * QueueSetHandle_t;
+typedef struct QueueDefinition * QueueSetHandle_t;
 
 /**
  * Queue sets can contain both queues and semaphores, so the
  * QueueSetMemberHandle_t is defined as a type to be used where a parameter or
  * return value can be either an QueueHandle_t or an SemaphoreHandle_t.
  */
-typedef void * QueueSetMemberHandle_t;
+typedef struct QueueDefinition * QueueSetMemberHandle_t;
 
 /** @cond */
+
 /* For internal use only. */
 #define	queueSEND_TO_BACK		( ( BaseType_t ) 0 )
 #define	queueSEND_TO_FRONT		( ( BaseType_t ) 1 )
@@ -244,8 +205,6 @@ typedef void * QueueSetMemberHandle_t;
 #endif /* configSUPPORT_STATIC_ALLOCATION */
 
 /**
- * This is a macro that calls xQueueGenericSend().
- *
  * Post an item to the front of a queue.  The item is queued by copy, not by
  * reference.  This function must not be called from an interrupt service
  * routine.  See xQueueSendFromISR () for an alternative which may be used
@@ -613,8 +572,6 @@ typedef void * QueueSetMemberHandle_t;
 BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION;
 
 /**
- * This is a macro that calls the xQueueGenericReceive() function.
- *
  * Receive an item from a queue without removing the item from the queue.
  * The item is received by copy so a buffer of adequate size must be
  * provided.  The number of bytes copied into the buffer was defined when
@@ -697,7 +654,7 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQ
  * @endcode
  * \ingroup QueueManagement
  */
-#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE )
+BaseType_t xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
 
 /**
  * A version of xQueuePeek() that can be called from an interrupt service
@@ -725,16 +682,6 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQ
 BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION;
 
 /**
- * queue. h
- * <pre>
- BaseType_t xQueueReceive(
-								 QueueHandle_t xQueue,
-								 void *pvBuffer,
-								 TickType_t xTicksToWait
-							);</pre>
- *
- * This is a macro that calls the xQueueGenericReceive() function.
- *
  * Receive an item from a queue.  The item is received by copy so a buffer of
  * adequate size must be provided.  The number of bytes copied into the buffer
  * was defined when the queue was created.
@@ -814,96 +761,7 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIV
  * @endcode
  * \ingroup QueueManagement
  */
-#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE )
-
-
-/**
- * It is preferred that the macro xQueueReceive() be used rather than calling
- * this function directly.
- *
- * Receive an item from a queue.  The item is received by copy so a buffer of
- * adequate size must be provided.  The number of bytes copied into the buffer
- * was defined when the queue was created.
- *
- * This function must not be used in an interrupt service routine.  See
- * xQueueReceiveFromISR for an alternative that can.
- *
- * @param xQueue The handle to the queue from which the item is to be
- * received.
- *
- * @param pvBuffer Pointer to the buffer into which the received item will
- * be copied.
- *
- * @param xTicksToWait The maximum amount of time the task should block
- * waiting for an item to receive should the queue be empty at the time
- * of the call.	 The time is defined in tick periods so the constant
- * portTICK_PERIOD_MS should be used to convert to real time if this is required.
- * xQueueGenericReceive() will return immediately if the queue is empty and
- * xTicksToWait is 0.
- *
- * @param xJustPeek When set to true, the item received from the queue is not
- * actually removed from the queue - meaning a subsequent call to
- * xQueueReceive() will return the same item.  When set to false, the item
- * being received from the queue is also removed from the queue.
- *
- * @return pdTRUE if an item was successfully received from the queue,
- * otherwise pdFALSE.
- *
- * Example usage:
- * @code{c}
- *  struct AMessage
- *  {
- * 	char ucMessageID;
- * 	char ucData[ 20 ];
- *  } xMessage;
- *
- *  QueueHandle_t xQueue;
- *
- *  // Task to create a queue and post a value.
- *  void vATask( void *pvParameters )
- *  {
- *  struct AMessage *pxMessage;
- *
- * 	// Create a queue capable of containing 10 pointers to AMessage structures.
- * 	// These should be passed by pointer as they contain a lot of data.
- * 	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
- * 	if( xQueue == 0 )
- * 	{
- * 		// Failed to create the queue.
- * 	}
- *
- * 	// ...
- *
- * 	// Send a pointer to a struct AMessage object.  Don't block if the
- * 	// queue is already full.
- * 	pxMessage = & xMessage;
- * 	xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
- *
- * 	// ... Rest of task code.
- *  }
- *
- *  // Task to receive from the queue.
- *  void vADifferentTask( void *pvParameters )
- *  {
- *  struct AMessage *pxRxedMessage;
- *
- * 	if( xQueue != 0 )
- * 	{
- * 		// Receive a message on the created queue.  Block for 10 ticks if a
- * 		// message is not immediately available.
- * 		if( xQueueGenericReceive( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
- * 		{
- * 			// pcRxedMessage now points to the struct AMessage variable posted
- * 			// by vATask.
- * 		}
- * 	}
- *
- * 	// ... Rest of task code.
- *  }
- * @endcode
- * \ingroup QueueManagement
- */
-BaseType_t xQueueGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, const BaseType_t xJustPeek ) PRIVILEGED_FUNCTION;
+BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
 
 /**
  * Return the number of messages stored in a queue.
@@ -999,7 +857,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
 #define xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_FRONT )
 
 
-/**
+/** 
  * This is a macro that calls xQueueGenericSendFromISR().
  *
  * Post an item to the back of a queue.  It is safe to use this macro from
@@ -1346,39 +1204,16 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, BaseType_t * const pxHigherP
  */
 BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
 
-/**@{*/
-/**
+/*
  * Utilities to query queues that are safe to use from an ISR.  These utilities
  * should be used only from witin an ISR, or within a critical section.
  */
 BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
 BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
 UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
-/**@}*/
 
 /** @cond */
 /**
- * xQueueAltGenericSend() is an alternative version of xQueueGenericSend().
- * Likewise xQueueAltGenericReceive() is an alternative version of
- * xQueueGenericReceive().
- *
- * The source code that implements the alternative (Alt) API is much
- * simpler	because it executes everything from within a critical section.
- * This is	the approach taken by many other RTOSes, but FreeRTOS.org has the
- * preferred fully featured API too.  The fully featured API has more
- * complex	code that takes longer to execute, but makes much less use of
- * critical sections.  Therefore the alternative API sacrifices interrupt
- * responsiveness to gain execution speed, whereas the fully featured API
- * sacrifices execution speed to ensure better interrupt responsiveness.
- */
-BaseType_t xQueueAltGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, BaseType_t xCopyPosition );
-BaseType_t xQueueAltGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, BaseType_t xJustPeeking );
-#define xQueueAltSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT )
-#define xQueueAltSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )
-#define xQueueAltReceive( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE )
-#define xQueueAltPeek( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE )
-
-/*
  * The functions defined above are for passing data to and from tasks.  The
  * functions below are the equivalents for passing data to and from
  * co-routines.
@@ -1392,7 +1227,7 @@ BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, void *pvBuffer, BaseTyp
 BaseType_t xQueueCRSend( QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait );
 BaseType_t xQueueCRReceive( QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait );
 
-/*
+/**
  * For internal use only.  Use xSemaphoreCreateMutex(),
  * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling
  * these functions directly.
@@ -1401,24 +1236,22 @@ QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION
 QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION;
 QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION;
 QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION;
-void* xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION;
+BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
+TaskHandle_t xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION;
+TaskHandle_t xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION;
 
-/*
+/**
  * For internal use only.  Use xSemaphoreTakeMutexRecursive() or
  * xSemaphoreGiveMutexRecursive() instead of calling these functions directly.
  */
 BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
-BaseType_t xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) PRIVILEGED_FUNCTION;
+BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION;
+
 /** @endcond */
 
 /**
- * Reset a queue back to its original empty state.  pdPASS is returned if the
- * queue is successfully reset.  pdFAIL is returned if the queue could not be
- * reset because there are tasks blocked on the queue waiting to either
- * receive from the queue or send to the queue.
- *
- * @param xQueue The queue to reset
- * @return always returns pdPASS
+ * Reset a queue back to its original empty state.  The return value is now
+ * obsolete and is always set to pdPASS.
  */
 #define xQueueReset( xQueue ) xQueueGenericReset( xQueue, pdFALSE )
 
@@ -1439,13 +1272,13 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) PRIVILEGED_FUNCTION
  * is the handle returned by a call to xQueueCreate().  Semaphore and mutex
  * handles can also be passed in here.
  *
- * @param pcName The name to be associated with the handle.  This is the
+ * @param pcQueueName The name to be associated with the handle.  This is the
  * name that the kernel aware debugger will display.  The queue registry only
  * stores a pointer to the string - so the string must be persistent (global or
  * preferably in ROM/Flash), not on the stack.
  */
-#if configQUEUE_REGISTRY_SIZE > 0
-	void vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+#if( configQUEUE_REGISTRY_SIZE > 0 )
+	void vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcQueueName ) PRIVILEGED_FUNCTION; /**lint !e971 Unqualified char types are allowed for strings and single characters only. */
 #endif
 
 /**
@@ -1458,13 +1291,11 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) PRIVILEGED_FUNCTION
  *
  * @param xQueue The handle of the queue being removed from the registry.
  */
-#if configQUEUE_REGISTRY_SIZE > 0
+#if( configQUEUE_REGISTRY_SIZE > 0 )
 	void vQueueUnregisterQueue( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
 #endif
 
 /**
- * @note This function has been back ported from FreeRTOS v9.0.0
- *
  * The queue registry is provided as a means for kernel aware debuggers to
  * locate queues, semaphores and mutexes.  Call pcQueueGetName() to look
  * up and return the name of a queue in the queue registry from the queue's
@@ -1476,7 +1307,7 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) PRIVILEGED_FUNCTION
  * returned.
  */
 #if( configQUEUE_REGISTRY_SIZE > 0 )
-	const char *pcQueueGetName( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+	const char *pcQueueGetName( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /**lint !e971 Unqualified char types are allowed for strings and single characters only. */
 #endif
 
 /**
@@ -1632,12 +1463,14 @@ QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const Ti
 QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION;
 
 /** @cond */
+
 /* Not public API functions. */
-void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
+void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION;
 BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) PRIVILEGED_FUNCTION;
 void vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) PRIVILEGED_FUNCTION;
 UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
 uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
+
 /** @endcond */
 
 #ifdef __cplusplus

+ 56 - 80
components/freertos/include/freertos/semphr.h

@@ -1,71 +1,29 @@
 /*
-    FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
-    All rights reserved
-
-    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License (version 2) as published by the
-    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
-
-	***************************************************************************
-    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
-    >>!   distribute a combined work that includes FreeRTOS without being   !<<
-    >>!   obliged to provide the source code for proprietary components     !<<
-    >>!   outside of the FreeRTOS kernel.                                   !<<
-	***************************************************************************
-
-    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
-    link: http://www.freertos.org/a00114.html
-
-    ***************************************************************************
-     *                                                                       *
-     *    FreeRTOS provides completely free yet professionally developed,    *
-     *    robust, strictly quality controlled, supported, and cross          *
-     *    platform software that is more than just the market leader, it     *
-     *    is the industry's de facto standard.                               *
-     *                                                                       *
-     *    Help yourself get started quickly while simultaneously helping     *
-     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
-     *    tutorial book, reference manual, or both:                          *
-     *    http://www.FreeRTOS.org/Documentation                              *
-     *                                                                       *
-    ***************************************************************************
-
-    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
-	the FAQ page "My application does not run, what could be wrong?".  Have you
-	defined configASSERT()?
-
-	http://www.FreeRTOS.org/support - In return for receiving this top quality
-	embedded software for free we request you assist our global community by
-	participating in the support forum.
-
-	http://www.FreeRTOS.org/training - Investing in training allows your team to
-	be as productive as possible as early as possible.  Now you can receive
-	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
-	Ltd, and the world's leading authority on the world's leading RTOS.
-
-    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
-    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
-    compatible FAT file system, and our tiny thread aware UDP/IP stack.
-
-    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
-    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
-
-    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
-    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
-    licenses offer ticketed support, indemnification and commercial middleware.
-
-    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
-    engineered and independently SIL3 certified version for use in safety and
-    mission critical applications that require provable dependability.
-
-    1 tab == 4 spaces!
-*/
+ * FreeRTOS Kernel V10.2.1
+ * 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 SEMAPHORE_H
 #define SEMAPHORE_H
@@ -84,6 +42,13 @@ typedef QueueHandle_t SemaphoreHandle_t;
 
 /** @cond */
 /**
+ * semphr. h
+ * <pre>vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )</pre>
+ *
+ * In many usage scenarios it is faster and more memory efficient to use a
+ * direct to task notification in place of a binary semaphore!
+ * http://www.freertos.org/RTOS-task-notifications.html
+ *
  * This old vSemaphoreCreateBinary() macro is now deprecated in favour of the
  * xSemaphoreCreateBinary() function.  Note that binary semaphores created using
  * the vSemaphoreCreateBinary() macro are created in a state such that the
@@ -160,11 +125,6 @@ typedef QueueHandle_t SemaphoreHandle_t;
  * created using xSemaphoreCreateBinary() are created in a state such that the
  * the semaphore must first be 'given' before it can be 'taken'.
  *
- * Function that creates a semaphore by using the existing queue mechanism.
- * The queue length is 1 as this is a binary semaphore.  The data size is 0
- * as nothing is actually stored - all that is important is whether the queue is
- * empty or full (the binary semaphore is available or not).
- *
  * This type of semaphore can be used for pure synchronisation between tasks or
  * between an interrupt and a task.  The semaphore need not be given back once
  * obtained, so one task/interrupt can continuously 'give' the semaphore while
@@ -172,7 +132,8 @@ typedef QueueHandle_t SemaphoreHandle_t;
  * semaphore does not use a priority inheritance mechanism.  For an alternative
  * that does use priority inheritance see xSemaphoreCreateMutex().
  *
- * @return Handle to the created semaphore.
+ * @return Handle to the created semaphore, or NULL if the memory required to
+ * hold the semaphore's data structures could not be allocated.
  *
  * Example usage:
  * @code{c}
@@ -255,7 +216,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
 
 /**
  * <i>Macro</i> to obtain a semaphore.  The semaphore must have previously been
- * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
+ * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
  * xSemaphoreCreateCounting().
  *
  * @param xSemaphore A handle to the semaphore being taken - obtained when
@@ -311,7 +272,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
  * @endcode
  * \ingroup Semaphores
  */
-#define xSemaphoreTake( xSemaphore, xBlockTime )		xQueueGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )
+#define xSemaphoreTake( xSemaphore, xBlockTime )		xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) )
 
 /**
  * <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore.
@@ -417,7 +378,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
 
 /**
  * <i>Macro</i> to release a semaphore.  The semaphore must have previously been
- * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
+ * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
  * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake().
  *
  * This macro must not be used from an ISR.  See xSemaphoreGiveFromISR () for
@@ -475,6 +436,9 @@ typedef QueueHandle_t SemaphoreHandle_t;
 #define xSemaphoreGive( xSemaphore )		xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
 
 /**
+ * semphr. h
+ * <pre>xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex )</pre>
+ *
  * <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.
  * The mutex must have previously been created using a call to
  * xSemaphoreCreateRecursiveMutex();
@@ -573,7 +537,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
 
 /**
  * <i>Macro</i> to  release a semaphore.  The semaphore must have previously been
- * created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting().
+ * created with a call to xSemaphoreCreateBinary() or xSemaphoreCreateCounting().
  *
  * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
  * must not be used with this macro.
@@ -583,7 +547,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
  * @param xSemaphore A handle to the semaphore being released.  This is the
  * handle returned when the semaphore was created.
  *
- * @param[out] pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set
+ * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set
  * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task
  * to unblock, and the unblocked task has a priority higher than the currently
  * running task.  If xSemaphoreGiveFromISR() sets this value to pdTRUE then
@@ -656,7 +620,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
 
 /**
  * <i>Macro</i> to  take a semaphore from an ISR.  The semaphore must have
- * previously been created with a call to vSemaphoreCreateBinary() or
+ * previously been created with a call to xSemaphoreCreateBinary() or
  * xSemaphoreCreateCounting().
  *
  * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
@@ -704,7 +668,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
  *
  * Mutex type semaphores cannot be used from within interrupt service routines.
  *
- * See vSemaphoreCreateBinary() for an alternative implementation that can be
+ * See xSemaphoreCreateBinary() for an alternative implementation that can be
  * used for pure synchronisation (where one task or interrupt always 'gives' the
  * semaphore and another always 'takes' the semaphore) and from within interrupt
  * service routines.
@@ -1106,6 +1070,18 @@ typedef QueueHandle_t SemaphoreHandle_t;
 #define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) )
 
 /**
+ *
+ * If xMutex is indeed a mutex type semaphore, return the current mutex holder.
+ * If xMutex is not a mutex type semaphore, or the mutex is available (not held
+ * by a task), return NULL.
+ *
+ */
+#define xSemaphoreGetMutexHolderFromISR( xSemaphore ) xQueueGetMutexHolderFromISR( ( xSemaphore ) )
+
+/**
+ * semphr.h
+ * <pre>UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );</pre>
+ *
  * If the semaphore is a counting semaphore then uxSemaphoreGetCount() returns
  * its current count value.  If the semaphore is a binary semaphore then
  * uxSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the

+ 25 - 68
components/freertos/include/freertos/StackMacros.h → components/freertos/include/freertos/stack_macros.h

@@ -1,71 +1,29 @@
 /*
-    FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
-    All rights reserved
-
-    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License (version 2) as published by the
-    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
-
-	***************************************************************************
-    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
-    >>!   distribute a combined work that includes FreeRTOS without being   !<<
-    >>!   obliged to provide the source code for proprietary components     !<<
-    >>!   outside of the FreeRTOS kernel.                                   !<<
-	***************************************************************************
-
-    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
-    link: http://www.freertos.org/a00114.html
-
-    ***************************************************************************
-     *                                                                       *
-     *    FreeRTOS provides completely free yet professionally developed,    *
-     *    robust, strictly quality controlled, supported, and cross          *
-     *    platform software that is more than just the market leader, it     *
-     *    is the industry's de facto standard.                               *
-     *                                                                       *
-     *    Help yourself get started quickly while simultaneously helping     *
-     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
-     *    tutorial book, reference manual, or both:                          *
-     *    http://www.FreeRTOS.org/Documentation                              *
-     *                                                                       *
-    ***************************************************************************
-
-    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
-	the FAQ page "My application does not run, what could be wrong?".  Have you
-	defined configASSERT()?
-
-	http://www.FreeRTOS.org/support - In return for receiving this top quality
-	embedded software for free we request you assist our global community by
-	participating in the support forum.
-
-	http://www.FreeRTOS.org/training - Investing in training allows your team to
-	be as productive as possible as early as possible.  Now you can receive
-	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
-	Ltd, and the world's leading authority on the world's leading RTOS.
-
-    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
-    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
-    compatible FAT file system, and our tiny thread aware UDP/IP stack.
-
-    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
-    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
-
-    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
-    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
-    licenses offer ticketed support, indemnification and commercial middleware.
-
-    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
-    engineered and independently SIL3 certified version for use in safety and
-    mission critical applications that require provable dependability.
-
-    1 tab == 4 spaces!
-*/
+ * FreeRTOS Kernel V10.2.1
+ * 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 STACK_MACROS_H
 #define STACK_MACROS_H
@@ -178,7 +136,6 @@
 	}
 
 #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
-/*-----------------------------------------------------------*/
 
 #endif /* STACK_MACROS_H */
 

+ 0 - 0
components/freertos/stdint.readme → components/freertos/include/freertos/stdint.readme


+ 745 - 0
components/freertos/include/freertos/stream_buffer.h

@@ -0,0 +1,745 @@
+/*
+ * FreeRTOS Kernel V10.2.1
+ * 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!
+ */
+
+/*
+ * Stream buffers are used to send a continuous stream of data from one task or
+ * interrupt to another.  Their implementation is light weight, making them
+ * particularly suited for interrupt to task and core to core communication
+ * scenarios.
+ *
+ * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
+ * implementation (so also the message buffer implementation, as message buffers
+ * are built on top of stream buffers) assumes there is only one task or
+ * interrupt that will write to the buffer (the writer), and only one task or
+ * interrupt that will read from the buffer (the reader).  It is safe for the
+ * writer and reader to be different tasks or interrupts, but, unlike other
+ * FreeRTOS objects, it is not safe to have multiple different writers or
+ * multiple different readers.  If there are to be multiple different writers
+ * then the application writer must place each call to a writing API function
+ * (such as xStreamBufferSend()) inside a critical section and set the send
+ * block time to 0.  Likewise, if there are to be multiple different readers
+ * then the application writer must place each call to a reading API function
+ * (such as xStreamBufferRead()) inside a critical section section and set the
+ * receive block time to 0.
+ *
+ */
+
+#ifndef STREAM_BUFFER_H
+#define STREAM_BUFFER_H
+
+#ifndef INC_FREERTOS_H
+	#error "include FreeRTOS.h must appear in source files before include stream_buffer.h"
+#endif
+
+#if defined( __cplusplus )
+extern "C" {
+#endif
+
+/**
+ * Type by which stream buffers are referenced.  For example, a call to
+ * xStreamBufferCreate() returns an StreamBufferHandle_t variable that can
+ * then be used as a parameter to xStreamBufferSend(), xStreamBufferReceive(),
+ * etc.
+ */
+struct StreamBufferDef_t;
+typedef struct StreamBufferDef_t * StreamBufferHandle_t;
+
+/**
+ * Creates a new stream buffer using dynamically allocated memory.  See
+ * xStreamBufferCreateStatic() for a version that uses statically allocated
+ * memory (memory that is allocated at compile time).
+ *
+ * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in
+ * FreeRTOSConfig.h for xStreamBufferCreate() to be available.
+ *
+ * @param xBufferSizeBytes The total number of bytes the stream buffer will be
+ * able to hold at any one time.
+ *
+ * @param xTriggerLevelBytes The number of bytes that must be in the stream
+ * buffer before a task that is blocked on the stream buffer to wait for data is
+ * moved out of the blocked state.  For example, if a task is blocked on a read
+ * of an empty stream buffer that has a trigger level of 1 then the task will be
+ * unblocked when a single byte is written to the buffer or the task's block
+ * time expires.  As another example, if a task is blocked on a read of an empty
+ * stream buffer that has a trigger level of 10 then the task will not be
+ * unblocked until the stream buffer contains at least 10 bytes or the task's
+ * block time expires.  If a reading task's block time expires before the
+ * trigger level is reached then the task will still receive however many bytes
+ * are actually available.  Setting a trigger level of 0 will result in a
+ * trigger level of 1 being used.  It is not valid to specify a trigger level
+ * that is greater than the buffer size.
+ *
+ * @return If NULL is returned, then the stream buffer cannot be created
+ * because there is insufficient heap memory available for FreeRTOS to allocate
+ * the stream buffer data structures and storage area.  A non-NULL value being
+ * returned indicates that the stream buffer has been created successfully -
+ * the returned value should be stored as the handle to the created stream
+ * buffer.
+ *
+ * Example use:
+ * @code{c}
+ *
+ *   void vAFunction( void )
+ *       {
+ *       StreamBufferHandle_t xStreamBuffer;
+ *       const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10;
+ *
+ *           // Create a stream buffer that can hold 100 bytes.  The memory used to hold
+ *           // both the stream buffer structure and the data in the stream buffer is
+ *           // allocated dynamically.
+ *           xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel );
+ *
+ *           if( xStreamBuffer == NULL )
+ *           {
+ *              // There was not enough heap memory space available to create the
+ *              // stream buffer.
+ *           }
+ *           else
+ *           {
+ *               // The stream buffer was created successfully and can now be used.
+ *           }
+ *       }
+ * @endcode
+ * \ingroup StreamBufferManagement
+ */
+#define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE )
+
+/**
+ * Creates a new stream buffer using statically allocated memory.  See
+ * xStreamBufferCreate() for a version that uses dynamically allocated memory.
+ *
+ * configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h for
+ * xStreamBufferCreateStatic() to be available.
+ *
+ * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the
+ * pucStreamBufferStorageArea parameter.
+ *
+ * @param xTriggerLevelBytes The number of bytes that must be in the stream
+ * buffer before a task that is blocked on the stream buffer to wait for data is
+ * moved out of the blocked state.  For example, if a task is blocked on a read
+ * of an empty stream buffer that has a trigger level of 1 then the task will be
+ * unblocked when a single byte is written to the buffer or the task's block
+ * time expires.  As another example, if a task is blocked on a read of an empty
+ * stream buffer that has a trigger level of 10 then the task will not be
+ * unblocked until the stream buffer contains at least 10 bytes or the task's
+ * block time expires.  If a reading task's block time expires before the
+ * trigger level is reached then the task will still receive however many bytes
+ * are actually available.  Setting a trigger level of 0 will result in a
+ * trigger level of 1 being used.  It is not valid to specify a trigger level
+ * that is greater than the buffer size.
+ *
+ * @param pucStreamBufferStorageArea Must point to a uint8_t array that is at
+ * least xBufferSizeBytes + 1 big.  This is the array to which streams are
+ * copied when they are written to the stream buffer.
+ *
+ * @param pxStaticStreamBuffer Must point to a variable of type
+ * StaticStreamBuffer_t, which will be used to hold the stream buffer's data
+ * structure.
+ *
+ * @return If the stream buffer is created successfully then a handle to the
+ * created stream buffer is returned. If either pucStreamBufferStorageArea or
+ * pxStaticstreamBuffer are NULL then NULL is returned.
+ *
+ * Example use:
+ * @code{c}
+ *
+ *       // Used to dimension the array used to hold the streams.  The available space
+ *       // will actually be one less than this, so 999.
+ *       #define STORAGE_SIZE_BYTES 1000
+ *
+ *       // Defines the memory that will actually hold the streams within the stream
+ *       // buffer.
+ *       static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
+ * 
+ *       // The variable used to hold the stream buffer structure.
+ *       StaticStreamBuffer_t xStreamBufferStruct;
+ *
+ *       void MyFunction( void )
+ *       {
+ *       StreamBufferHandle_t xStreamBuffer;
+ *       const size_t xTriggerLevel = 1;
+ *
+ *           xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucBufferStorage ),
+ *                                                      xTriggerLevel,
+ *                                                      ucBufferStorage,
+ *                                                      &xStreamBufferStruct );
+ *  
+ *           // As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer
+ *           // parameters were NULL, xStreamBuffer will not be NULL, and can be used to
+ *           // reference the created stream buffer in other stream buffer API calls.
+ *
+ *           // Other code that uses the stream buffer can go here.
+ *       }
+ *
+ * @endcode
+ * \ingroup StreamBufferManagement
+ */
+#define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, pucStreamBufferStorageArea, pxStaticStreamBuffer )
+
+/**
+ * Sends bytes to a stream buffer.  The bytes are copied into the stream buffer.
+ *
+ * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
+ * implementation (so also the message buffer implementation, as message buffers
+ * are built on top of stream buffers) assumes there is only one task or
+ * interrupt that will write to the buffer (the writer), and only one task or
+ * interrupt that will read from the buffer (the reader).  It is safe for the
+ * writer and reader to be different tasks or interrupts, but, unlike other
+ * FreeRTOS objects, it is not safe to have multiple different writers or
+ * multiple different readers.  If there are to be multiple different writers
+ * then the application writer must place each call to a writing API function
+ * (such as xStreamBufferSend()) inside a critical section and set the send
+ * block time to 0.  Likewise, if there are to be multiple different readers
+ * then the application writer must place each call to a reading API function
+ * (such as xStreamBufferRead()) inside a critical section and set the receive
+ * block time to 0.
+ *
+ * Use xStreamBufferSend() to write to a stream buffer from a task.  Use
+ * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt
+ * service routine (ISR).
+ *
+ * @param xStreamBuffer The handle of the stream buffer to which a stream is
+ * being sent.
+ *
+ * @param pvTxData A pointer to the buffer that holds the bytes to be copied
+ * into the stream buffer.
+ *
+ * @param xDataLengthBytes   The maximum number of bytes to copy from pvTxData
+ * into the stream buffer.
+ *
+ * @param xTicksToWait The maximum amount of time the task should remain in the
+ * Blocked state to wait for enough space to become available in the stream
+ * buffer, should the stream buffer contain too little space to hold the
+ * another xDataLengthBytes bytes.  The block time is specified in tick periods,
+ * so the absolute time it represents is dependent on the tick frequency.  The
+ * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds
+ * into a time specified in ticks.  Setting xTicksToWait to portMAX_DELAY will
+ * cause the task to wait indefinitely (without timing out), provided
+ * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h.  If a task times out
+ * before it can write all xDataLengthBytes into the buffer it will still write
+ * as many bytes as possible.  A task does not use any CPU time when it is in
+ * the blocked state.
+ *
+ * @return The number of bytes written to the stream buffer.  If a task times
+ * out before it can write all xDataLengthBytes into the buffer it will still
+ * write as many bytes as possible.
+ *
+ * Example use:
+ * @code{c}
+ *       void vAFunction( StreamBufferHandle_t xStreamBuffer )
+ *       {
+ *       size_t xBytesSent;
+ *       uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
+ *       char *pcStringToSend = "String to send";
+ *       const TickType_t x100ms = pdMS_TO_TICKS( 100 );
+ *
+ *           // Send an array to the stream buffer, blocking for a maximum of 100ms to
+ *           // wait for enough space to be available in the stream buffer.
+ *           xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
+ *
+ *           if( xBytesSent != sizeof( ucArrayToSend ) )
+ *           {
+ *              // The call to xStreamBufferSend() times out before there was enough
+ *              // space in the buffer for the data to be written, but it did
+ *              // successfully write xBytesSent bytes.
+ *           }
+ *
+ *           // Send the string to the stream buffer.  Return immediately if there is not
+ *           // enough space in the buffer.
+ *           xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
+ *
+ *           if( xBytesSent != strlen( pcStringToSend ) )
+ *           {
+ *              // The entire string could not be added to the stream buffer because
+ *              // there was not enough free space in the buffer, but xBytesSent bytes
+ *              // were sent.  Could try again to send the remaining bytes.
+ *           }
+ *       }
+ * @endcode
+ * \ingroup StreamBufferManagement
+ */
+size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
+						  const void *pvTxData,
+						  size_t xDataLengthBytes,
+						  TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
+
+/**
+ * Interrupt safe version of the API function that sends a stream of bytes to
+ * the stream buffer.
+ *
+ * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
+ * implementation (so also the message buffer implementation, as message buffers
+ * are built on top of stream buffers) assumes there is only one task or
+ * interrupt that will write to the buffer (the writer), and only one task or
+ * interrupt that will read from the buffer (the reader).  It is safe for the
+ * writer and reader to be different tasks or interrupts, but, unlike other
+ * FreeRTOS objects, it is not safe to have multiple different writers or
+ * multiple different readers.  If there are to be multiple different writers
+ * then the application writer must place each call to a writing API function
+ * (such as xStreamBufferSend()) inside a critical section and set the send
+ * block time to 0.  Likewise, if there are to be multiple different readers
+ * then the application writer must place each call to a reading API function
+ * (such as xStreamBufferRead()) inside a critical section and set the receive
+ * block time to 0.
+ *
+ * Use xStreamBufferSend() to write to a stream buffer from a task.  Use
+ * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt
+ * service routine (ISR).
+ *
+ * @param xStreamBuffer The handle of the stream buffer to which a stream is
+ * being sent.
+ *
+ * @param pvTxData A pointer to the data that is to be copied into the stream
+ * buffer.
+ *
+ * @param xDataLengthBytes The maximum number of bytes to copy from pvTxData
+ * into the stream buffer.
+ *
+ * @param pxHigherPriorityTaskWoken  It is possible that a stream buffer will
+ * have a task blocked on it waiting for data.  Calling
+ * xStreamBufferSendFromISR() can make data available, and so cause a task that
+ * was waiting for data to leave the Blocked state.  If calling
+ * xStreamBufferSendFromISR() causes a task to leave the Blocked state, and the
+ * unblocked task has a priority higher than the currently executing task (the
+ * task that was interrupted), then, internally, xStreamBufferSendFromISR()
+ * will set *pxHigherPriorityTaskWoken to pdTRUE.  If
+ * xStreamBufferSendFromISR() sets this value to pdTRUE, then normally a
+ * context switch should be performed before the interrupt is exited.  This will
+ * ensure that the interrupt returns directly to the highest priority Ready
+ * state task.  *pxHigherPriorityTaskWoken should be set to pdFALSE before it
+ * is passed into the function.  See the example code below for an example.
+ *
+ * @return The number of bytes actually written to the stream buffer, which will
+ * be less than xDataLengthBytes if the stream buffer didn't have enough free
+ * space for all the bytes to be written.
+ *
+ * Example use:
+ * @code{c}
+ *   //A stream buffer that has already been created.
+ *   StreamBufferHandle_t xStreamBuffer;
+ *
+ *   void vAnInterruptServiceRoutine( void )
+ *   {
+ *   size_t xBytesSent;
+ *   char *pcStringToSend = "String to send";
+ *   BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
+ *
+ *       // Attempt to send the string to the stream buffer.
+ *       xBytesSent = xStreamBufferSendFromISR( xStreamBuffer,
+ *                                           ( void * ) pcStringToSend,
+ *                                           strlen( pcStringToSend ),
+ *                                           &xHigherPriorityTaskWoken );
+ *
+ *       if( xBytesSent != strlen( pcStringToSend ) )
+ *       {
+ *           // There was not enough free space in the stream buffer for the entire
+ *           // string to be written, ut xBytesSent bytes were written.
+ *       }
+ * 
+ *       // If xHigherPriorityTaskWoken was set to pdTRUE inside
+ *       // xStreamBufferSendFromISR() then a task that has a priority above the
+ *       // priority of the currently executing task was unblocked and a context
+ *       // switch should be performed to ensure the ISR returns to the unblocked
+ *       // task.  In most FreeRTOS ports this is done by simply passing
+ *       // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
+ *       // variables value, and perform the context switch if necessary.  Check the
+ *       // documentation for the port in use for port specific instructions.
+ *       taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+ *   }
+ * @endcode
+ * \ingroup StreamBufferManagement
+ */
+size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
+								 const void *pvTxData,
+								 size_t xDataLengthBytes,
+								 BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
+
+/**
+ * Receives bytes from a stream buffer.
+ *
+ * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
+ * implementation (so also the message buffer implementation, as message buffers
+ * are built on top of stream buffers) assumes there is only one task or
+ * interrupt that will write to the buffer (the writer), and only one task or
+ * interrupt that will read from the buffer (the reader).  It is safe for the
+ * writer and reader to be different tasks or interrupts, but, unlike other
+ * FreeRTOS objects, it is not safe to have multiple different writers or
+ * multiple different readers.  If there are to be multiple different writers
+ * then the application writer must place each call to a writing API function
+ * (such as xStreamBufferSend()) inside a critical section and set the send
+ * block time to 0.  Likewise, if there are to be multiple different readers
+ * then the application writer must place each call to a reading API function
+ * (such as xStreamBufferRead()) inside a critical section and set the receive
+ * block time to 0.
+ *
+ * Use xStreamBufferReceive() to read from a stream buffer from a task.  Use
+ * xStreamBufferReceiveFromISR() to read from a stream buffer from an
+ * interrupt service routine (ISR).
+ *
+ * @param xStreamBuffer The handle of the stream buffer from which bytes are to
+ * be received.
+ *
+ * @param pvRxData A pointer to the buffer into which the received bytes will be
+ * copied.
+ *
+ * @param xBufferLengthBytes The length of the buffer pointed to by the
+ * pvRxData parameter.  This sets the maximum number of bytes to receive in one
+ * call.  xStreamBufferReceive will return as many bytes as possible up to a
+ * maximum set by xBufferLengthBytes.
+ *
+ * @param xTicksToWait The maximum amount of time the task should remain in the
+ * Blocked state to wait for data to become available if the stream buffer is
+ * empty.  xStreamBufferReceive() will return immediately if xTicksToWait is
+ * zero.  The block time is specified in tick periods, so the absolute time it
+ * represents is dependent on the tick frequency.  The macro pdMS_TO_TICKS() can
+ * be used to convert a time specified in milliseconds into a time specified in
+ * ticks.  Setting xTicksToWait to portMAX_DELAY will cause the task to wait
+ * indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1
+ * in FreeRTOSConfig.h.  A task does not use any CPU time when it is in the
+ * Blocked state.
+ *
+ * @return The number of bytes actually read from the stream buffer, which will
+ * be less than xBufferLengthBytes if the call to xStreamBufferReceive() timed
+ * out before xBufferLengthBytes were available.
+ *
+ * Example use:
+ * @code{c}
+ *   void vAFunction( StreamBuffer_t xStreamBuffer )
+ *   {
+ *   uint8_t ucRxData[ 20 ];
+ *   size_t xReceivedBytes;
+ *   const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
+ *
+ *       // Receive up to another sizeof( ucRxData ) bytes from the stream buffer.
+ *       // Wait in the Blocked state (so not using any CPU processing time) for a
+ *       // maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be
+ *       // available.
+ *       xReceivedBytes = xStreamBufferReceive( xStreamBuffer,
+ *                                           ( void * ) ucRxData,
+ *                                           sizeof( ucRxData ),
+ *                                           xBlockTime );
+ *
+ *       if( xReceivedBytes > 0 )
+ *       {
+ *           // A ucRxData contains another xRecievedBytes bytes of data, which can
+ *           // be processed here....
+ *       }
+ *   }
+ * @endcode
+ * \ingroup StreamBufferManagement
+ */
+size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
+							 void *pvRxData,
+							 size_t xBufferLengthBytes,
+							 TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
+
+
+/**
+ * An interrupt safe version of the API function that receives bytes from a
+ * stream buffer.
+ *
+ * Use xStreamBufferReceive() to read bytes from a stream buffer from a task.
+ * Use xStreamBufferReceiveFromISR() to read bytes from a stream buffer from an
+ * interrupt service routine (ISR).
+ *
+ * @param xStreamBuffer The handle of the stream buffer from which a stream
+ * is being received.
+ *
+ * @param pvRxData A pointer to the buffer into which the received bytes are
+ * copied.
+ *
+ * @param xBufferLengthBytes The length of the buffer pointed to by the
+ * pvRxData parameter.  This sets the maximum number of bytes to receive in one
+ * call.  xStreamBufferReceive will return as many bytes as possible up to a
+ * maximum set by xBufferLengthBytes.
+ *
+ * @param pxHigherPriorityTaskWoken  It is possible that a stream buffer will
+ * have a task blocked on it waiting for space to become available.  Calling
+ * xStreamBufferReceiveFromISR() can make space available, and so cause a task
+ * that is waiting for space to leave the Blocked state.  If calling
+ * xStreamBufferReceiveFromISR() causes a task to leave the Blocked state, and
+ * the unblocked task has a priority higher than the currently executing task
+ * (the task that was interrupted), then, internally,
+ * xStreamBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE.
+ * If xStreamBufferReceiveFromISR() sets this value to pdTRUE, then normally a
+ * context switch should be performed before the interrupt is exited.  That will
+ * ensure the interrupt returns directly to the highest priority Ready state
+ * task.  *pxHigherPriorityTaskWoken should be set to pdFALSE before it is
+ * passed into the function.  See the code example below for an example.
+ *
+ * @return The number of bytes read from the stream buffer, if any.
+ *
+ * Example use:
+ * @code{c}
+ *   // A stream buffer that has already been created.
+ *   StreamBuffer_t xStreamBuffer;
+ *
+ *   void vAnInterruptServiceRoutine( void )
+ *   {
+ *   uint8_t ucRxData[ 20 ];
+ *   size_t xReceivedBytes;
+ *   BaseType_t xHigherPriorityTaskWoken = pdFALSE;  // Initialised to pdFALSE.
+ *
+ *       // Receive the next stream from the stream buffer.
+ *       xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer,
+ *                                                   ( void * ) ucRxData,
+ *                                                   sizeof( ucRxData ),
+ *                                                   &xHigherPriorityTaskWoken );
+ *
+ *       if( xReceivedBytes > 0 )
+ *       {
+ *           // ucRxData contains xReceivedBytes read from the stream buffer.
+ *           // Process the stream here....
+ *       }
+ *
+ *       // If xHigherPriorityTaskWoken was set to pdTRUE inside
+ *       // xStreamBufferReceiveFromISR() then a task that has a priority above the
+ *       // priority of the currently executing task was unblocked and a context
+ *       // switch should be performed to ensure the ISR returns to the unblocked
+ *       // task.  In most FreeRTOS ports this is done by simply passing
+ *       // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
+ *       // variables value, and perform the context switch if necessary.  Check the
+ *       // documentation for the port in use for port specific instructions.
+ *       taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+ *   }
+ * @endcode
+ * \ingroup StreamBufferManagement
+ */
+size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
+									void *pvRxData,
+									size_t xBufferLengthBytes,
+									BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
+
+/**
+ * Deletes a stream buffer that was previously created using a call to
+ * xStreamBufferCreate() or xStreamBufferCreateStatic().  If the stream
+ * buffer was created using dynamic memory (that is, by xStreamBufferCreate()),
+ * then the allocated memory is freed.
+ *
+ * A stream buffer handle must not be used after the stream buffer has been
+ * deleted.
+ *
+ * @param xStreamBuffer The handle of the stream buffer to be deleted.
+ *
+ * \ingroup StreamBufferManagement
+ */
+void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
+
+/**
+ * Queries a stream buffer to see if it is full.  A stream buffer is full if it
+ * does not have any free space, and therefore cannot accept any more data.
+ *
+ * @param xStreamBuffer The handle of the stream buffer being queried.
+ *
+ * @return If the stream buffer is full then pdTRUE is returned.  Otherwise
+ * pdFALSE is returned.
+ *
+ * \ingroup StreamBufferManagement
+ */
+BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
+
+/**
+ * Queries a stream buffer to see if it is empty.  A stream buffer is empty if
+ * it does not contain any data.
+ *
+ * @param xStreamBuffer The handle of the stream buffer being queried.
+ *
+ * @return If the stream buffer is empty then pdTRUE is returned.  Otherwise
+ * pdFALSE is returned.
+ *
+ * \ingroup StreamBufferManagement
+ */
+BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
+
+/**
+ * Resets a stream buffer to its initial, empty, state.  Any data that was in
+ * the stream buffer is discarded.  A stream buffer can only be reset if there
+ * are no tasks blocked waiting to either send to or receive from the stream
+ * buffer.
+ *
+ * @param xStreamBuffer The handle of the stream buffer being reset.
+ *
+ * @return If the stream buffer is reset then pdPASS is returned.  If there was
+ * a task blocked waiting to send to or read from the stream buffer then the
+ * stream buffer is not reset and pdFAIL is returned.
+ *
+ * \ingroup StreamBufferManagement
+ */
+BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
+
+/**
+ * Queries a stream buffer to see how much free space it contains, which is
+ * equal to the amount of data that can be sent to the stream buffer before it
+ * is full.
+ *
+ * @param xStreamBuffer The handle of the stream buffer being queried.
+ *
+ * @return The number of bytes that can be written to the stream buffer before
+ * the stream buffer would be full.
+ *
+ * \defgroup xStreamBufferSpacesAvailable xStreamBufferSpacesAvailable
+ * \ingroup StreamBufferManagement
+ */
+size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
+
+/**
+ * Queries a stream buffer to see how much data it contains, which is equal to
+ * the number of bytes that can be read from the stream buffer before the stream
+ * buffer would be empty.
+ *
+ * @param xStreamBuffer The handle of the stream buffer being queried.
+ *
+ * @return The number of bytes that can be read from the stream buffer before
+ * the stream buffer would be empty.
+ *
+ * \defgroup xStreamBufferBytesAvailable xStreamBufferBytesAvailable
+ * \ingroup StreamBufferManagement
+ */
+size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
+
+/**
+ * A stream buffer's trigger level is the number of bytes that must be in the
+ * stream buffer before a task that is blocked on the stream buffer to
+ * wait for data is moved out of the blocked state.  For example, if a task is
+ * blocked on a read of an empty stream buffer that has a trigger level of 1
+ * then the task will be unblocked when a single byte is written to the buffer
+ * or the task's block time expires.  As another example, if a task is blocked
+ * on a read of an empty stream buffer that has a trigger level of 10 then the
+ * task will not be unblocked until the stream buffer contains at least 10 bytes
+ * or the task's block time expires.  If a reading task's block time expires
+ * before the trigger level is reached then the task will still receive however
+ * many bytes are actually available.  Setting a trigger level of 0 will result
+ * in a trigger level of 1 being used.  It is not valid to specify a trigger
+ * level that is greater than the buffer size.
+ *
+ * A trigger level is set when the stream buffer is created, and can be modified
+ * using xStreamBufferSetTriggerLevel().
+ *
+ * @param xStreamBuffer The handle of the stream buffer being updated.
+ *
+ * @param xTriggerLevel The new trigger level for the stream buffer.
+ *
+ * @return If xTriggerLevel was less than or equal to the stream buffer's length
+ * then the trigger level will be updated and pdTRUE is returned.  Otherwise
+ * pdFALSE is returned.
+ *
+ * \ingroup StreamBufferManagement
+ */
+BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) PRIVILEGED_FUNCTION;
+
+/**
+ * For advanced users only.
+ *
+ * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when
+ * data is sent to a message buffer or stream buffer.  If there was a task that
+ * was blocked on the message or stream buffer waiting for data to arrive then
+ * the sbSEND_COMPLETED() macro sends a notification to the task to remove it
+ * from the Blocked state.  xStreamBufferSendCompletedFromISR() does the same
+ * thing.  It is provided to enable application writers to implement their own
+ * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME.
+ *
+ * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
+ * additional information.
+ *
+ * @param xStreamBuffer The handle of the stream buffer to which data was
+ * written.
+ *
+ * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
+ * initialised to pdFALSE before it is passed into
+ * xStreamBufferSendCompletedFromISR().  If calling
+ * xStreamBufferSendCompletedFromISR() removes a task from the Blocked state,
+ * and the task has a priority above the priority of the currently running task,
+ * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
+ * context switch should be performed before exiting the ISR.
+ *
+ * @return If a task was removed from the Blocked state then pdTRUE is returned.
+ * Otherwise pdFALSE is returned.
+ *
+ * \ingroup StreamBufferManagement
+ */
+BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
+
+/**
+ * For advanced users only.
+ *
+ * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when
+ * data is read out of a message buffer or stream buffer.  If there was a task
+ * that was blocked on the message or stream buffer waiting for data to arrive
+ * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to
+ * remove it from the Blocked state.  xStreamBufferReceiveCompletedFromISR()
+ * does the same thing.  It is provided to enable application writers to
+ * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT
+ * ANY OTHER TIME.
+ *
+ * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
+ * additional information.
+ *
+ * @param xStreamBuffer The handle of the stream buffer from which data was
+ * read.
+ *
+ * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
+ * initialised to pdFALSE before it is passed into
+ * xStreamBufferReceiveCompletedFromISR().  If calling
+ * xStreamBufferReceiveCompletedFromISR() removes a task from the Blocked state,
+ * and the task has a priority above the priority of the currently running task,
+ * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
+ * context switch should be performed before exiting the ISR.
+ *
+ * @return If a task was removed from the Blocked state then pdTRUE is returned.
+ * Otherwise pdFALSE is returned.
+ *
+ * \ingroup StreamBufferManagement
+ */
+BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
+
+/** @cond */
+/* Functions below here are not part of the public API. */
+StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes,
+												 size_t xTriggerLevelBytes,
+												 BaseType_t xIsMessageBuffer ) PRIVILEGED_FUNCTION;
+
+StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
+													   size_t xTriggerLevelBytes,
+													   BaseType_t xIsMessageBuffer,
+													   uint8_t * const pucStreamBufferStorageArea,
+													   StaticStreamBuffer_t * const pxStaticStreamBuffer ) PRIVILEGED_FUNCTION;
+
+size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
+
+#if( configUSE_TRACE_FACILITY == 1 )
+	void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION;
+	UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
+	uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
+#endif
+
+/** @endcond */
+
+#if defined( __cplusplus )
+}
+#endif
+
+#endif	/* !defined( STREAM_BUFFER_H ) */

Fișier diff suprimat deoarece este prea mare
+ 425 - 257
components/freertos/include/freertos/task.h


+ 103 - 109
components/freertos/include/freertos/timers.h

@@ -1,71 +1,29 @@
 /*
-    FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
-    All rights reserved
-
-    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License (version 2) as published by the
-    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
-
-	***************************************************************************
-    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
-    >>!   distribute a combined work that includes FreeRTOS without being   !<<
-    >>!   obliged to provide the source code for proprietary components     !<<
-    >>!   outside of the FreeRTOS kernel.                                   !<<
-	***************************************************************************
-
-    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
-    link: http://www.freertos.org/a00114.html
-
-    ***************************************************************************
-     *                                                                       *
-     *    FreeRTOS provides completely free yet professionally developed,    *
-     *    robust, strictly quality controlled, supported, and cross          *
-     *    platform software that is more than just the market leader, it     *
-     *    is the industry's de facto standard.                               *
-     *                                                                       *
-     *    Help yourself get started quickly while simultaneously helping     *
-     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
-     *    tutorial book, reference manual, or both:                          *
-     *    http://www.FreeRTOS.org/Documentation                              *
-     *                                                                       *
-    ***************************************************************************
-
-    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
-	the FAQ page "My application does not run, what could be wrong?".  Have you
-	defined configASSERT()?
-
-	http://www.FreeRTOS.org/support - In return for receiving this top quality
-	embedded software for free we request you assist our global community by
-	participating in the support forum.
-
-	http://www.FreeRTOS.org/training - Investing in training allows your team to
-	be as productive as possible as early as possible.  Now you can receive
-	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
-	Ltd, and the world's leading authority on the world's leading RTOS.
-
-    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
-    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
-    compatible FAT file system, and our tiny thread aware UDP/IP stack.
-
-    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
-    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
-
-    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
-    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
-    licenses offer ticketed support, indemnification and commercial middleware.
-
-    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
-    engineered and independently SIL3 certified version for use in safety and
-    mission critical applications that require provable dependability.
-
-    1 tab == 4 spaces!
-*/
+ * FreeRTOS Kernel V10.2.1
+ * 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 TIMERS_H
@@ -75,10 +33,10 @@
 	#error "include FreeRTOS.h must appear in source files before include timers.h"
 #endif
 
-/*lint -e537 This headers are only multiply included if the application code
+/*lint -save -e537 This headers are only multiply included if the application code
 happens to also be including task.h. */
 #include "task.h"
-/*lint +e537 */
+/*lint -restore */
 
 #ifdef __cplusplus
 extern "C" {
@@ -115,14 +73,15 @@ or interrupt version of the queue send function should be used. */
  * reference the subject timer in calls to other software timer API functions
  * (for example, xTimerStart(), xTimerReset(), etc.).
  */
-typedef void * TimerHandle_t;
-
-/**
+struct tmrTimerControl; /* The old naming convention is used to prevent breaking kernel aware debuggers. */
+//typedef struct tmrTimerControl * TimerHandle_t;
+typedef void* TimerHandle_t;
+/*
  * Defines the prototype to which timer callback functions must conform.
  */
 typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer );
 
-/**
+/*
  * Defines the prototype to which functions used with the
  * xTimerPendFunctionCallFromISR() function must conform.
  */
@@ -260,11 +219,11 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
  * @endcode
  */
 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
-	TimerHandle_t xTimerCreate(	const char * const pcTimerName,
+	TimerHandle_t xTimerCreate(	const char * const pcTimerName,			/*lint !e971 Unqualified char types are allowed for strings and single characters only. */
 								const TickType_t xTimerPeriodInTicks,
 								const UBaseType_t uxAutoReload,
 								void * const pvTimerID,
-								TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+								TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION;
 #endif
 
  /**
@@ -388,18 +347,20 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
 										const UBaseType_t uxAutoReload,
 										void * const pvTimerID,
 										TimerCallbackFunction_t pxCallbackFunction,
-										StaticTimer_t *pxTimerBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
- #endif /* configSUPPORT_STATIC_ALLOCATION */
+										StaticTimer_t *pxTimerBuffer ) PRIVILEGED_FUNCTION;
+#endif /* configSUPPORT_STATIC_ALLOCATION */
 
 /**
+ * void *pvTimerGetTimerID( TimerHandle_t xTimer );
+ *
  * Returns the ID assigned to the timer.
  *
  * IDs are assigned to timers using the pvTimerID parameter of the call to
- * xTimerCreated() that was used to create the timer.
+ * xTimerCreated() that was used to create the timer, and by calling the
+ * vTimerSetTimerID() API function.
  *
  * If the same callback function is assigned to multiple timers then the timer
- * ID can be used within the callback function to identify which timer actually
- * expired.
+ * ID can be used as time specific (timer local) storage.
  *
  * @param xTimer The timer being queried.
  *
@@ -409,9 +370,11 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
  *
  * See the xTimerCreate() API function example usage scenario.
  */
-void *pvTimerGetTimerID( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
+void *pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
 
 /**
+ * void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID );
+ *
  * Sets the ID assigned to the timer.
  *
  * IDs are assigned to timers using the pvTimerID parameter of the call to
@@ -431,12 +394,12 @@ void *pvTimerGetTimerID( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
 void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) PRIVILEGED_FUNCTION;
 
 /**
+ * BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer );
+ *
  * Queries a timer to see if it is active or dormant.
  *
  * A timer will be dormant if:
- *
  *     1) It has been created but not started, or
- *
  *     2) It is an expired one-shot timer that has not been restarted.
  *
  * Timers are created in the dormant state.  The xTimerStart(), xTimerReset(),
@@ -474,31 +437,11 @@ BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
  * Simply returns the handle of the timer service/daemon task.  It it not valid
  * to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started.
  */
-TaskHandle_t xTimerGetTimerDaemonTaskHandle( void );
-
-/**
- * Returns the period of a timer.
- *
- * @param xTimer The handle of the timer being queried.
- *
- * @return The period of the timer in ticks.
- */
-TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
+TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
 
 /**
- * Returns the time in ticks at which the timer will expire.  If this is less
- * than the current tick count then the expiry time has overflowed from the
- * current time.
+ * BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait );
  *
- * @param xTimer The handle of the timer being queried.
- *
- * @return If the timer is running then the time in ticks at which the timer
- * will next expire is returned.  If the timer is not running then the return
- * value is undefined.
- */
-TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
-
-/**
  * Timer functionality is provided by a timer service/daemon task.  Many of the
  * public FreeRTOS timer API functions send commands to the timer service task
  * through a queue called the timer command queue.  The timer command queue is
@@ -813,7 +756,7 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
  *
  *     // Starting the scheduler will start the timer running as it has already
  *     // been set into the active state.
- *     xTaskStartScheduler();
+ *     vTaskStartScheduler();
  *
  *     // Should not reach here.
  *     for( ;; );
@@ -1200,7 +1143,7 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
  *	}
  * @endcode
  */
-BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken );
+BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
 
  /**
   * Used to defer the execution of a function to the RTOS daemon task (the timer
@@ -1228,18 +1171,64 @@ BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void
   * timer daemon task, otherwise pdFALSE is returned.
   *
   */
-BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait );
+BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
 
 /**
+ * const char * const pcTimerGetName( TimerHandle_t xTimer );
+ *
  * Returns the name that was assigned to a timer when the timer was created.
  *
  * @param xTimer The handle of the timer being queried.
  *
  * @return The name assigned to the timer specified by the xTimer parameter.
  */
-const char * pcTimerGetTimerName( TimerHandle_t xTimer ); /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+const char * pcTimerGetName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+
+/**
+ * void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload );
+ *
+ * Updates a timer to be either an autoreload timer, in which case the timer
+ * automatically resets itself each time it expires, or a one shot timer, in
+ * which case the timer will only expire once unless it is manually restarted.
+ *
+ * @param xTimer The handle of the timer being updated.
+ *
+ * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will
+ * expire repeatedly with a frequency set by the timer's period (see the
+ * xTimerPeriodInTicks parameter of the xTimerCreate() API function).  If
+ * uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and
+ * enter the dormant state after it expires.
+ */
+void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) PRIVILEGED_FUNCTION;
+
+/**
+ * TickType_t xTimerGetPeriod( TimerHandle_t xTimer );
+ *
+ * Returns the period of a timer.
+ *
+ * @param xTimer The handle of the timer being queried.
+ *
+ * @return The period of the timer in ticks.
+ */
+TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
+
+/**
+* TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer );
+*
+* Returns the time in ticks at which the timer will expire.  If this is less
+* than the current tick count then the expiry time has overflowed from the
+* current time.
+*
+* @param xTimer The handle of the timer being queried.
+*
+* @return If the timer is running then the time in ticks at which the timer
+* will next expire is returned.  If the timer is not running then the return
+* value is undefined.
+*/
+TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
 
 /** @cond */
+
 /*
  * Functions beyond this part are not part of the public API and are intended
  * for use by the kernel only.
@@ -1247,6 +1236,11 @@ const char * pcTimerGetTimerName( TimerHandle_t xTimer ); /*lint !e971 Unqualifi
 BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
 BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
 
+#if( configUSE_TRACE_FACILITY == 1 )
+	void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber ) PRIVILEGED_FUNCTION;
+	UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
+#endif
+
 /** @endcond */
 
 #ifdef __cplusplus

+ 21 - 440
components/freertos/license.txt

@@ -1,440 +1,21 @@
-The FreeRTOS.org source code is licensed by the *modified* GNU General Public
-License (GPL), text provided below.  A special exception to the GPL is 
-included to allow you to distribute a combined work that includes FreeRTOS 
-without being obliged to provide the source code for any proprietary 
-components.  See the licensing section of http://www.FreeRTOS.org for full 
-details.  The exception text is also included at the bottom of this file.
-
-The FreeRTOS download also includes demo application source code, some of 
-which is provided by third parties AND IS LICENSED SEPARATELY FROM FREERTOS.
-
-For the avoidance of any doubt refer to the comment included at the top
-of each source and header file for license and copyright information.
-
-This is a list of files for which Real Time Engineers Ltd are not the 
-copyright owner and are NOT COVERED BY THE GPL.
-
-
-1) Various header files provided by silicon manufacturers and tool vendors
-   that define processor specific memory addresses and utility macros.
-   Permission has been granted by the various copyright holders for these
-   files to be included in the FreeRTOS download.  Users must ensure license
-   conditions are adhered to for any use other than compilation of the 
-   FreeRTOS demo applications.
-
-2) The uIP TCP/IP stack the copyright of which is held by Adam Dunkels.
-   Users must ensure the open source license conditions stated at the top 
-   of each uIP source file is understood and adhered to.
-
-3) The lwIP TCP/IP stack the copyright of which is held by the Swedish 
-   Institute of Computer Science.  Users must ensure the open source license 
-   conditions stated at the top  of each lwIP source file is understood and 
-   adhered to.
-
-4) Various peripheral driver source files and binaries provided by silicon
-   manufacturers and tool vendors.  Permission has been granted by the
-   various copyright holders for these files to be included in the FreeRTOS
-   download.  Users must ensure license conditions are adhered to for any
-   use other than compilation of the FreeRTOS demo applications.
-
-5) The files contained within FreeRTOS\Demo\WizNET_DEMO_TERN_186\tern_code,
-   which are slightly modified versions of code provided by and copyright to
-   Tern Inc.
-
-Errors and omissions should be reported to Richard Barry, contact details for
-whom can be obtained from http://www.FreeRTOS.org.
-
-
-
-
-
-The GPL license text follows.
-
-A special exception to the GPL is included to allow you to distribute a 
-combined work that includes FreeRTOS without being obliged to provide
-the source code for any proprietary components.  See the licensing section
-of http://www.FreeRTOS.org for full details.  The exception text is also
-included at the bottom of this file.
-
---------------------------------------------------------------------
-
-
-
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License** as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
-
-----------------------------------------------------------------------------
-
-The FreeRTOS GPL Exception Text:
-
-Any FreeRTOS source code, whether modified or in it's original release form, 
-or whether in whole or in part, can only be distributed by you under the terms 
-of the GNU General Public License plus this exception. An independent module is 
-a module which is not derived from or based on FreeRTOS.
-
-Clause 1:
-
-Linking FreeRTOS statically or dynamically with other modules is making a 
-combined work based on FreeRTOS. Thus, the terms and conditions of the GNU 
-General Public License cover the whole combination.
-
-As a special exception, the copyright holder of FreeRTOS gives you permission 
-to link FreeRTOS with independent modules that communicate with FreeRTOS 
-solely through the FreeRTOS API interface, regardless of the license terms of 
-these independent modules, and to copy and distribute the resulting combined 
-work under terms of your choice, provided that
-
-  + Every copy of the combined work is accompanied by a written statement that 
-  details to the recipient the version of FreeRTOS used and an offer by yourself 
-  to provide the FreeRTOS source code (including any modifications you may have 
-  made) should the recipient request it.
-
-  + The combined work is not itself an RTOS, scheduler, kernel or related product.
-
-  + The independent modules add significant and primary functionality to FreeRTOS 
-  and do not merely extend the existing functionality already present in FreeRTOS.
-
-Clause 2:
-
-FreeRTOS may not be used for any competitive or comparative purpose, including the 
-publication of any form of run time or compile time metric, without the express 
-permission of Real Time Engineers Ltd. (this is the norm within the industry and 
-is intended to ensure information accuracy).
+MIT License
+
+Copyright (C) 2017 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.

+ 47 - 82
components/freertos/list.c

@@ -1,71 +1,29 @@
 /*
-    FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
-    All rights reserved
-
-    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License (version 2) as published by the
-    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
-
-	***************************************************************************
-    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
-    >>!   distribute a combined work that includes FreeRTOS without being   !<<
-    >>!   obliged to provide the source code for proprietary components     !<<
-    >>!   outside of the FreeRTOS kernel.                                   !<<
-	***************************************************************************
-
-    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
-    link: http://www.freertos.org/a00114.html
-
-    ***************************************************************************
-     *                                                                       *
-     *    FreeRTOS provides completely free yet professionally developed,    *
-     *    robust, strictly quality controlled, supported, and cross          *
-     *    platform software that is more than just the market leader, it     *
-     *    is the industry's de facto standard.                               *
-     *                                                                       *
-     *    Help yourself get started quickly while simultaneously helping     *
-     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
-     *    tutorial book, reference manual, or both:                          *
-     *    http://www.FreeRTOS.org/Documentation                              *
-     *                                                                       *
-    ***************************************************************************
-
-    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
-	the FAQ page "My application does not run, what could be wrong?".  Have you
-	defined configASSERT()?
-
-	http://www.FreeRTOS.org/support - In return for receiving this top quality
-	embedded software for free we request you assist our global community by
-	participating in the support forum.
-
-	http://www.FreeRTOS.org/training - Investing in training allows your team to
-	be as productive as possible as early as possible.  Now you can receive
-	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
-	Ltd, and the world's leading authority on the world's leading RTOS.
-
-    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
-    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
-    compatible FAT file system, and our tiny thread aware UDP/IP stack.
-
-    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
-    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
-
-    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
-    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
-    licenses offer ticketed support, indemnification and commercial middleware.
-
-    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
-    engineered and independently SIL3 certified version for use in safety and
-    mission critical applications that require provable dependability.
-
-    1 tab == 4 spaces!
-*/
+ * FreeRTOS Kernel V10.2.1
+ * 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!
+ */
 
 
 #include <stdlib.h>
@@ -82,7 +40,7 @@ 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 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
+	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. */
@@ -90,8 +48,8 @@ void vListInitialise( List_t * const pxList )
 
 	/* 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 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 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
+	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;
 
@@ -105,7 +63,7 @@ void vListInitialise( List_t * const pxList )
 void vListInitialiseItem( ListItem_t * const pxItem )
 {
 	/* Make sure the list item is not recorded as being on a list. */
-	pxItem->pvContainer = NULL;
+	pxItem->pxContainer = NULL;
 
 	/* Write known values into the list item if
 	configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
@@ -129,11 +87,15 @@ ListItem_t * const pxIndex = pxList->pxIndex;
 	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->pvContainer = ( void * ) pxList;
+	pxNewListItem->pxContainer = pxList;
 
 	( pxList->uxNumberOfItems )++;
 }
@@ -153,7 +115,7 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
 	/* 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 TCB's which are
+	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
@@ -166,18 +128,18 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
 	{
 		/* *** NOTE ***********************************************************
 		If you find your application is crashing here then likely causes are
-		listed below.  In addition see http://www.freertos.org/FAQHelp.html for
+		listed below.  In addition see https://www.freertos.org/FAQHelp.html for
 		more tips, and ensure configASSERT() is defined!
-		http://www.freertos.org/a00110.html#configASSERT
+		https://www.freertos.org/a00110.html#configASSERT
 
 			1) Stack overflow -
-			   see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
+			   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
-			   http://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
+			   https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
 			   of configMAX_SYSCALL_INTERRUPT_PRIORITY on
-			   http://www.freertos.org/a00110.html
+			   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.
@@ -186,7 +148,7 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
 			   before vTaskStartScheduler() has been called?).
 		**********************************************************************/
 
-		for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
+		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. */
@@ -200,7 +162,7 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
 
 	/* Remember which list the item is in.  This allows fast removal of the
 	item later. */
-	pxNewListItem->pvContainer = ( void * ) pxList;
+	pxNewListItem->pxContainer = pxList;
 
 	( pxList->uxNumberOfItems )++;
 }
@@ -210,11 +172,14 @@ 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 = ( List_t * ) pxItemToRemove->pvContainer;
+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)
 	{
@@ -225,7 +190,7 @@ List_t * const pxList = ( List_t * ) pxItemToRemove->pvContainer;
 		mtCOVERAGE_TEST_MARKER();
 	}
 
-	pxItemToRemove->pvContainer = NULL;
+	pxItemToRemove->pxContainer = NULL;
 	( pxList->uxNumberOfItems )--;
 
 	return pxList->uxNumberOfItems;

Fișier diff suprimat deoarece este prea mare
+ 302 - 320
components/freertos/queue.c


+ 1265 - 0
components/freertos/stream_buffer.c

@@ -0,0 +1,1265 @@
+/*
+ * FreeRTOS Kernel V10.2.1
+ * 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!
+ */
+
+/* Standard includes. */
+#include <stdint.h>
+#include <string.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
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "stream_buffer.h"
+
+#if( configUSE_TASK_NOTIFICATIONS != 1 )
+	#error configUSE_TASK_NOTIFICATIONS must be set to 1 to build stream_buffer.c
+#endif
+
+/* Lint e961, e9021 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. */
+
+/* If the user has not provided application specific Rx notification macros,
+or #defined the notification macros away, them provide default implementations
+that uses task notifications. */
+/*lint -save -e9026 Function like macros allowed and needed here so they can be overidden. */
+#ifndef sbRECEIVE_COMPLETED
+	#define sbRECEIVE_COMPLETED( pxStreamBuffer )										\
+		taskENTER_CRITICAL( &pxStreamBuffer->xStreamBufferMux );																\
+		{																				\
+			if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL )						\
+			{																			\
+				( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToSend,			\
+									  ( uint32_t ) 0,									\
+									  eNoAction );										\
+				( pxStreamBuffer )->xTaskWaitingToSend = NULL;							\
+			}																			\
+		}																				\
+		taskEXIT_CRITICAL( &pxStreamBuffer->xStreamBufferMux );
+#endif /* sbRECEIVE_COMPLETED */
+
+#ifndef sbRECEIVE_COMPLETED_FROM_ISR
+	#define sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer,								\
+										  pxHigherPriorityTaskWoken )					\
+	{																					\
+	UBaseType_t uxSavedInterruptStatus;													\
+																						\
+		uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR();		\
+		{																				\
+			if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL )						\
+			{																			\
+				( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend,	\
+											 ( uint32_t ) 0,							\
+											 eNoAction,									\
+											 pxHigherPriorityTaskWoken );				\
+				( pxStreamBuffer )->xTaskWaitingToSend = NULL;							\
+			}																			\
+		}																				\
+		portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );					\
+	}
+#endif /* sbRECEIVE_COMPLETED_FROM_ISR */
+
+/* If the user has not provided an application specific Tx notification macro,
+or #defined the notification macro away, them provide a default implementation
+that uses task notifications. */
+#ifndef sbSEND_COMPLETED
+	#define sbSEND_COMPLETED( pxStreamBuffer )											\
+		taskENTER_CRITICAL( &pxStreamBuffer->xStreamBufferMux );																\
+		{																				\
+			if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL )						\
+			{																			\
+				( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToReceive,		\
+									  ( uint32_t ) 0,									\
+									  eNoAction );										\
+				( pxStreamBuffer )->xTaskWaitingToReceive = NULL;						\
+			}																			\
+		}																				\
+		taskEXIT_CRITICAL( &pxStreamBuffer->xStreamBufferMux );
+#endif /* sbSEND_COMPLETED */
+
+#ifndef sbSEND_COMPLETE_FROM_ISR
+	#define sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken )		\
+	{																					\
+	UBaseType_t uxSavedInterruptStatus;													\
+																						\
+		uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR();		\
+		{																				\
+			if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL )						\
+			{																			\
+				( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive,	\
+											 ( uint32_t ) 0,							\
+											 eNoAction,									\
+											 pxHigherPriorityTaskWoken );				\
+				( pxStreamBuffer )->xTaskWaitingToReceive = NULL;						\
+			}																			\
+		}																				\
+		portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );					\
+	}
+#endif /* sbSEND_COMPLETE_FROM_ISR */
+/*lint -restore (9026) */
+
+/* The number of bytes used to hold the length of a message in the buffer. */
+#define sbBYTES_TO_STORE_MESSAGE_LENGTH ( sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) )
+
+/* Bits stored in the ucFlags field of the stream buffer. */
+#define sbFLAGS_IS_MESSAGE_BUFFER		( ( uint8_t ) 1 ) /* Set if the stream buffer was created as a message buffer, in which case it holds discrete messages rather than a stream. */
+#define sbFLAGS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 2 ) /* Set if the stream buffer was created using statically allocated memory. */
+
+/*-----------------------------------------------------------*/
+
+/* Structure that hold state information on the buffer. */
+typedef struct StreamBufferDef_t /*lint !e9058 Style convention uses tag. */
+{
+	volatile size_t xTail;				/* Index to the next item to read within the buffer. */
+	volatile size_t xHead;				/* Index to the next item to write within the buffer. */
+	size_t xLength;						/* The length of the buffer pointed to by pucBuffer. */
+	size_t xTriggerLevelBytes;			/* The number of bytes that must be in the stream buffer before a task that is waiting for data is unblocked. */
+	volatile TaskHandle_t xTaskWaitingToReceive; /* Holds the handle of a task waiting for data, or NULL if no tasks are waiting. */
+	volatile TaskHandle_t xTaskWaitingToSend;	/* Holds the handle of a task waiting to send data to a message buffer that is full. */
+	uint8_t *pucBuffer;					/* Points to the buffer itself - that is - the RAM that stores the data passed through the buffer. */
+	uint8_t ucFlags;
+
+	#if ( configUSE_TRACE_FACILITY == 1 )
+		UBaseType_t uxStreamBufferNumber;		/* Used for tracing purposes. */
+	#endif
+
+	portMUX_TYPE xStreamBufferMux;	//Mutex required due to SMP
+} StreamBuffer_t;
+
+/*
+ * The number of bytes available to be read from the buffer.
+ */
+static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ) PRIVILEGED_FUNCTION;
+
+/*
+ * Add xCount bytes from pucData into the pxStreamBuffer message buffer.
+ * Returns the number of bytes written, which will either equal xCount in the
+ * success case, or 0 if there was not enough space in the buffer (in which case
+ * no data is written into the buffer).
+ */
+static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer, const uint8_t *pucData, size_t xCount ) PRIVILEGED_FUNCTION;
+
+/*
+ * If the stream buffer is being used as a message buffer, then reads an entire
+ * message out of the buffer.  If the stream buffer is being used as a stream
+ * buffer then read as many bytes as possible from the buffer.
+ * prvReadBytesFromBuffer() is called to actually extract the bytes from the
+ * buffer's data storage area.
+ */
+static size_t prvReadMessageFromBuffer( StreamBuffer_t *pxStreamBuffer,
+										void *pvRxData,
+										size_t xBufferLengthBytes,
+										size_t xBytesAvailable,
+										size_t xBytesToStoreMessageLength ) PRIVILEGED_FUNCTION;
+
+/*
+ * If the stream buffer is being used as a message buffer, then writes an entire
+ * message to the buffer.  If the stream buffer is being used as a stream
+ * buffer then write as many bytes as possible to the buffer.
+ * prvWriteBytestoBuffer() is called to actually send the bytes to the buffer's
+ * data storage area.
+ */
+static size_t prvWriteMessageToBuffer(  StreamBuffer_t * const pxStreamBuffer,
+										const void * pvTxData,
+										size_t xDataLengthBytes,
+										size_t xSpace,
+										size_t xRequiredSpace ) PRIVILEGED_FUNCTION;
+
+/*
+ * Read xMaxCount bytes from the pxStreamBuffer message buffer and write them
+ * to pucData.
+ */
+static size_t prvReadBytesFromBuffer( StreamBuffer_t *pxStreamBuffer,
+									  uint8_t *pucData,
+									  size_t xMaxCount,
+									  size_t xBytesAvailable ) PRIVILEGED_FUNCTION;
+
+/*
+ * Called by both pxStreamBufferCreate() and pxStreamBufferCreateStatic() to
+ * initialise the members of the newly created stream buffer structure.
+ */
+static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
+										  uint8_t * const pucBuffer,
+										  size_t xBufferSizeBytes,
+										  size_t xTriggerLevelBytes,
+										  uint8_t ucFlags ) PRIVILEGED_FUNCTION;
+
+/*-----------------------------------------------------------*/
+
+#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+
+	StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer )
+	{
+	uint8_t *pucAllocatedMemory;
+	uint8_t ucFlags;
+
+		/* In case the stream buffer is going to be used as a message buffer
+		(that is, it will hold discrete messages with a little meta data that
+		says how big the next message is) check the buffer will be large enough
+		to hold at least one message. */
+		if( xIsMessageBuffer == pdTRUE )
+		{
+			/* Is a message buffer but not statically allocated. */
+			ucFlags = sbFLAGS_IS_MESSAGE_BUFFER;
+			configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH );
+		}
+		else
+		{
+			/* Not a message buffer and not statically allocated. */
+			ucFlags = 0;
+			configASSERT( xBufferSizeBytes > 0 );
+		}
+		configASSERT( xTriggerLevelBytes <= xBufferSizeBytes );
+
+		/* A trigger level of 0 would cause a waiting task to unblock even when
+		the buffer was empty. */
+		if( xTriggerLevelBytes == ( size_t ) 0 )
+		{
+			xTriggerLevelBytes = ( size_t ) 1;
+		}
+
+		/* A stream buffer requires a StreamBuffer_t structure and a buffer.
+		Both are allocated in a single call to pvPortMalloc().  The
+		StreamBuffer_t structure is placed at the start of the allocated memory
+		and the buffer follows immediately after.  The requested size is
+		incremented so the free space is returned as the user would expect -
+		this is a quirk of the implementation that means otherwise the free
+		space would be reported as one byte smaller than would be logically
+		expected. */
+		xBufferSizeBytes++;
+		pucAllocatedMemory = ( uint8_t * ) pvPortMalloc( xBufferSizeBytes + sizeof( StreamBuffer_t ) ); /*lint !e9079 malloc() only returns void*. */
+
+		if( pucAllocatedMemory != NULL )
+		{
+			prvInitialiseNewStreamBuffer( ( StreamBuffer_t * ) pucAllocatedMemory, /* Structure at the start of the allocated memory. */ /*lint !e9087 Safe cast as allocated memory is aligned. */ /*lint !e826 Area is not too small and alignment is guaranteed provided malloc() behaves as expected and returns aligned buffer. */
+										   pucAllocatedMemory + sizeof( StreamBuffer_t ),  /* Storage area follows. */ /*lint !e9016 Indexing past structure valid for uint8_t pointer, also storage area has no alignment requirement. */
+										   xBufferSizeBytes,
+										   xTriggerLevelBytes,
+										   ucFlags );
+
+			traceSTREAM_BUFFER_CREATE( ( ( StreamBuffer_t * ) pucAllocatedMemory ), xIsMessageBuffer );
+		}
+		else
+		{
+			traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer );
+		}
+
+		return ( StreamBufferHandle_t ) pucAllocatedMemory; /*lint !e9087 !e826 Safe cast as allocated memory is aligned. */
+	}
+
+#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
+/*-----------------------------------------------------------*/
+
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+
+	StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
+														   size_t xTriggerLevelBytes,
+														   BaseType_t xIsMessageBuffer,
+														   uint8_t * const pucStreamBufferStorageArea,
+														   StaticStreamBuffer_t * const pxStaticStreamBuffer )
+	{
+	StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) pxStaticStreamBuffer; /*lint !e740 !e9087 Safe cast as StaticStreamBuffer_t is opaque Streambuffer_t. */
+	StreamBufferHandle_t xReturn;
+	uint8_t ucFlags;
+
+		configASSERT( pucStreamBufferStorageArea );
+		configASSERT( pxStaticStreamBuffer );
+		configASSERT( xTriggerLevelBytes <= xBufferSizeBytes );
+
+		/* A trigger level of 0 would cause a waiting task to unblock even when
+		the buffer was empty. */
+		if( xTriggerLevelBytes == ( size_t ) 0 )
+		{
+			xTriggerLevelBytes = ( size_t ) 1;
+		}
+
+		if( xIsMessageBuffer != pdFALSE )
+		{
+			/* Statically allocated message buffer. */
+			ucFlags = sbFLAGS_IS_MESSAGE_BUFFER | sbFLAGS_IS_STATICALLY_ALLOCATED;
+		}
+		else
+		{
+			/* Statically allocated stream buffer. */
+			ucFlags = sbFLAGS_IS_STATICALLY_ALLOCATED;
+		}
+
+		/* In case the stream buffer is going to be used as a message buffer
+		(that is, it will hold discrete messages with a little meta data that
+		says how big the next message is) check the buffer will be large enough
+		to hold at least one message. */
+		configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH );
+
+		#if( configASSERT_DEFINED == 1 )
+		{
+			/* Sanity check that the size of the structure used to declare a
+			variable of type StaticStreamBuffer_t equals the size of the real
+			message buffer structure. */
+			volatile size_t xSize = sizeof( StaticStreamBuffer_t );
+			configASSERT( xSize == sizeof( StreamBuffer_t ) );
+		} /*lint !e529 xSize is referenced is configASSERT() is defined. */
+		#endif /* configASSERT_DEFINED */
+
+		if( ( pucStreamBufferStorageArea != NULL ) && ( pxStaticStreamBuffer != NULL ) )
+		{
+			prvInitialiseNewStreamBuffer( pxStreamBuffer,
+										  pucStreamBufferStorageArea,
+										  xBufferSizeBytes,
+										  xTriggerLevelBytes,
+										  ucFlags );
+			/* Remember this was statically allocated in case it is ever deleted
+			again. */
+			pxStreamBuffer->ucFlags |= sbFLAGS_IS_STATICALLY_ALLOCATED;
+
+			traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer );
+
+			xReturn = ( StreamBufferHandle_t ) pxStaticStreamBuffer; /*lint !e9087 Data hiding requires cast to opaque type. */
+		}
+		else
+		{
+			xReturn = NULL;
+			traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer );
+		}
+
+		return xReturn;
+	}
+
+#endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
+/*-----------------------------------------------------------*/
+
+void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer )
+{
+StreamBuffer_t * pxStreamBuffer = xStreamBuffer;
+
+	configASSERT( pxStreamBuffer );
+
+	traceSTREAM_BUFFER_DELETE( xStreamBuffer );
+
+	if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) pdFALSE )
+	{
+		#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+		{
+			/* Both the structure and the buffer were allocated using a single call
+			to pvPortMalloc(), hence only one call to vPortFree() is required. */
+			vPortFree( ( void * ) pxStreamBuffer ); /*lint !e9087 Standard free() semantics require void *, plus pxStreamBuffer was allocated by pvPortMalloc(). */
+		}
+		#else
+		{
+			/* Should not be possible to get here, ucFlags must be corrupt.
+			Force an assert. */
+			configASSERT( xStreamBuffer == ( StreamBufferHandle_t ) ~0 );
+		}
+		#endif
+	}
+	else
+	{
+		/* The structure and buffer were not allocated dynamically and cannot be
+		freed - just scrub the structure so future use will assert. */
+		( void ) memset( pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) );
+	}
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer )
+{
+StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
+BaseType_t xReturn = pdFAIL;
+
+#if( configUSE_TRACE_FACILITY == 1 )
+	UBaseType_t uxStreamBufferNumber;
+#endif
+
+	configASSERT( pxStreamBuffer );
+
+	#if( configUSE_TRACE_FACILITY == 1 )
+	{
+		/* Store the stream buffer number so it can be restored after the
+		reset. */
+		uxStreamBufferNumber = pxStreamBuffer->uxStreamBufferNumber;
+	}
+	#endif
+
+	/* Can only reset a message buffer if there are no tasks blocked on it. */
+	taskENTER_CRITICAL( &pxStreamBuffer->xStreamBufferMux );
+	{
+		if( pxStreamBuffer->xTaskWaitingToReceive == NULL )
+		{
+			if( pxStreamBuffer->xTaskWaitingToSend == NULL )
+			{
+				prvInitialiseNewStreamBuffer( pxStreamBuffer,
+											  pxStreamBuffer->pucBuffer,
+											  pxStreamBuffer->xLength,
+											  pxStreamBuffer->xTriggerLevelBytes,
+											  pxStreamBuffer->ucFlags );
+				xReturn = pdPASS;
+
+				#if( configUSE_TRACE_FACILITY == 1 )
+				{
+					pxStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber;
+				}
+				#endif
+
+				traceSTREAM_BUFFER_RESET( xStreamBuffer );
+			}
+		}
+	}
+	taskEXIT_CRITICAL( &pxStreamBuffer->xStreamBufferMux );
+
+	return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel )
+{
+StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
+BaseType_t xReturn;
+
+	configASSERT( pxStreamBuffer );
+
+	/* It is not valid for the trigger level to be 0. */
+	if( xTriggerLevel == ( size_t ) 0 )
+	{
+		xTriggerLevel = ( size_t ) 1;
+	}
+
+	/* The trigger level is the number of bytes that must be in the stream
+	buffer before a task that is waiting for data is unblocked. */
+	if( xTriggerLevel <= pxStreamBuffer->xLength )
+	{
+		pxStreamBuffer->xTriggerLevelBytes = xTriggerLevel;
+		xReturn = pdPASS;
+	}
+	else
+	{
+		xReturn = pdFALSE;
+	}
+
+	return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer )
+{
+const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
+size_t xSpace;
+
+	configASSERT( pxStreamBuffer );
+
+	xSpace = pxStreamBuffer->xLength + pxStreamBuffer->xTail;
+	xSpace -= pxStreamBuffer->xHead;
+	xSpace -= ( size_t ) 1;
+
+	if( xSpace >= pxStreamBuffer->xLength )
+	{
+		xSpace -= pxStreamBuffer->xLength;
+	}
+	else
+	{
+		mtCOVERAGE_TEST_MARKER();
+	}
+
+	return xSpace;
+}
+/*-----------------------------------------------------------*/
+
+size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer )
+{
+const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
+size_t xReturn;
+
+	configASSERT( pxStreamBuffer );
+
+	xReturn = prvBytesInBuffer( pxStreamBuffer );
+	return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
+						  const void *pvTxData,
+						  size_t xDataLengthBytes,
+						  TickType_t xTicksToWait )
+{
+StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
+size_t xReturn, xSpace = 0;
+size_t xRequiredSpace = xDataLengthBytes;
+TimeOut_t xTimeOut;
+
+	configASSERT( pvTxData );
+	configASSERT( pxStreamBuffer );
+
+	/* This send function is used to write to both message buffers and stream
+	buffers.  If this is a message buffer then the space needed must be
+	increased by the amount of bytes needed to store the length of the
+	message. */
+	if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
+	{
+		xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH;
+
+		/* Overflow? */
+		configASSERT( xRequiredSpace > xDataLengthBytes );
+	}
+	else
+	{
+		mtCOVERAGE_TEST_MARKER();
+	}
+
+	if( xTicksToWait != ( TickType_t ) 0 )
+	{
+		vTaskSetTimeOutState( &xTimeOut );
+
+		do
+		{
+			/* Wait until the required number of bytes are free in the message
+			buffer. */
+			taskENTER_CRITICAL( &pxStreamBuffer->xStreamBufferMux );
+			{
+				xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );
+
+				if( xSpace < xRequiredSpace )
+				{
+					/* Clear notification state as going to wait for space. */
+					( void ) xTaskNotifyStateClear( NULL );
+
+					/* Should only be one writer. */
+					configASSERT( pxStreamBuffer->xTaskWaitingToSend == NULL );
+					pxStreamBuffer->xTaskWaitingToSend = xTaskGetCurrentTaskHandle();
+				}
+				else
+				{
+					taskEXIT_CRITICAL( &pxStreamBuffer->xStreamBufferMux );
+					break;
+				}
+			}
+			taskEXIT_CRITICAL( &pxStreamBuffer->xStreamBufferMux );
+
+			traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer );
+			( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait );
+			pxStreamBuffer->xTaskWaitingToSend = NULL;
+
+		} while( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE );
+	}
+	else
+	{
+		mtCOVERAGE_TEST_MARKER();
+	}
+
+	if( xSpace == ( size_t ) 0 )
+	{
+		xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );
+	}
+	else
+	{
+		mtCOVERAGE_TEST_MARKER();
+	}
+
+	xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace );
+
+	if( xReturn > ( size_t ) 0 )
+	{
+		traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn );
+
+		/* Was a task waiting for the data? */
+		if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes )
+		{
+			sbSEND_COMPLETED( pxStreamBuffer );
+		}
+		else
+		{
+			mtCOVERAGE_TEST_MARKER();
+		}
+	}
+	else
+	{
+		mtCOVERAGE_TEST_MARKER();
+		traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer );
+	}
+
+	return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
+								 const void *pvTxData,
+								 size_t xDataLengthBytes,
+								 BaseType_t * const pxHigherPriorityTaskWoken )
+{
+StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
+size_t xReturn, xSpace;
+size_t xRequiredSpace = xDataLengthBytes;
+
+	configASSERT( pvTxData );
+	configASSERT( pxStreamBuffer );
+
+	/* This send function is used to write to both message buffers and stream
+	buffers.  If this is a message buffer then the space needed must be
+	increased by the amount of bytes needed to store the length of the
+	message. */
+	if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
+	{
+		xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH;
+	}
+	else
+	{
+		mtCOVERAGE_TEST_MARKER();
+	}
+
+	xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );
+	xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace );
+
+	if( xReturn > ( size_t ) 0 )
+	{
+		/* Was a task waiting for the data? */
+		if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes )
+		{
+			sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken );
+		}
+		else
+		{
+			mtCOVERAGE_TEST_MARKER();
+		}
+	}
+	else
+	{
+		mtCOVERAGE_TEST_MARKER();
+	}
+
+	traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn );
+
+	return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer,
+									   const void * pvTxData,
+									   size_t xDataLengthBytes,
+									   size_t xSpace,
+									   size_t xRequiredSpace )
+{
+	BaseType_t xShouldWrite;
+	size_t xReturn;
+
+	if( xSpace == ( size_t ) 0 )
+	{
+		/* Doesn't matter if this is a stream buffer or a message buffer, there
+		is no space to write. */
+		xShouldWrite = pdFALSE;
+	}
+	else if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) == ( uint8_t ) 0 )
+	{
+		/* This is a stream buffer, as opposed to a message buffer, so writing a
+		stream of bytes rather than discrete messages.  Write as many bytes as
+		possible. */
+		xShouldWrite = pdTRUE;
+		xDataLengthBytes = configMIN( xDataLengthBytes, xSpace );
+	}
+	else if( xSpace >= xRequiredSpace )
+	{
+		/* This is a message buffer, as opposed to a stream buffer, and there
+		is enough space to write both the message length and the message itself
+		into the buffer.  Start by writing the length of the data, the data
+		itself will be written later in this function. */
+		xShouldWrite = pdTRUE;
+		( void ) prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) &( xDataLengthBytes ), sbBYTES_TO_STORE_MESSAGE_LENGTH );
+	}
+	else
+	{
+		/* There is space available, but not enough space. */
+		xShouldWrite = pdFALSE;
+	}
+
+	if( xShouldWrite != pdFALSE )
+	{
+		/* Writes the data itself. */
+		xReturn = prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) pvTxData, xDataLengthBytes ); /*lint !e9079 Storage buffer is implemented as uint8_t for ease of sizing, alighment and access. */
+	}
+	else
+	{
+		xReturn = 0;
+	}
+
+	return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
+							 void *pvRxData,
+							 size_t xBufferLengthBytes,
+							 TickType_t xTicksToWait )
+{
+StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
+size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength;
+
+	configASSERT( pvRxData );
+	configASSERT( pxStreamBuffer );
+
+	/* This receive function is used by both message buffers, which store
+	discrete messages, and stream buffers, which store a continuous stream of
+	bytes.  Discrete messages include an additional
+	sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the
+	message. */
+	if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
+	{
+		xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;
+	}
+	else
+	{
+		xBytesToStoreMessageLength = 0;
+	}
+
+	if( xTicksToWait != ( TickType_t ) 0 )
+	{
+		/* Checking if there is data and clearing the notification state must be
+		performed atomically. */
+		taskENTER_CRITICAL( &pxStreamBuffer->xStreamBufferMux );
+		{
+			xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
+
+			/* If this function was invoked by a message buffer read then
+			xBytesToStoreMessageLength holds the number of bytes used to hold
+			the length of the next discrete message.  If this function was
+			invoked by a stream buffer read then xBytesToStoreMessageLength will
+			be 0. */
+			if( xBytesAvailable <= xBytesToStoreMessageLength )
+			{
+				/* Clear notification state as going to wait for data. */
+				( void ) xTaskNotifyStateClear( NULL );
+
+				/* Should only be one reader. */
+				configASSERT( pxStreamBuffer->xTaskWaitingToReceive == NULL );
+				pxStreamBuffer->xTaskWaitingToReceive = xTaskGetCurrentTaskHandle();
+			}
+			else
+			{
+				mtCOVERAGE_TEST_MARKER();
+			}
+		}
+		taskEXIT_CRITICAL( &pxStreamBuffer->xStreamBufferMux );
+
+		if( xBytesAvailable <= xBytesToStoreMessageLength )
+		{
+			/* Wait for data to be available. */
+			traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer );
+			( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait );
+			pxStreamBuffer->xTaskWaitingToReceive = NULL;
+
+			/* Recheck the data available after blocking. */
+			xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
+		}
+		else
+		{
+			mtCOVERAGE_TEST_MARKER();
+		}
+	}
+	else
+	{
+		xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
+	}
+
+	/* Whether receiving a discrete message (where xBytesToStoreMessageLength
+	holds the number of bytes used to store the message length) or a stream of
+	bytes (where xBytesToStoreMessageLength is zero), the number of bytes
+	available must be greater than xBytesToStoreMessageLength to be able to
+	read bytes from the buffer. */
+	if( xBytesAvailable > xBytesToStoreMessageLength )
+	{
+		xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength );
+
+		/* Was a task waiting for space in the buffer? */
+		if( xReceivedLength != ( size_t ) 0 )
+		{
+			traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength );
+			sbRECEIVE_COMPLETED( pxStreamBuffer );
+		}
+		else
+		{
+			mtCOVERAGE_TEST_MARKER();
+		}
+	}
+	else
+	{
+		traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer );
+		mtCOVERAGE_TEST_MARKER();
+	}
+
+	return xReceivedLength;
+}
+/*-----------------------------------------------------------*/
+
+size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer )
+{
+StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
+size_t xReturn, xBytesAvailable, xOriginalTail;
+configMESSAGE_BUFFER_LENGTH_TYPE xTempReturn;
+
+	configASSERT( pxStreamBuffer );
+
+	/* Ensure the stream buffer is being used as a message buffer. */
+	if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
+	{
+		xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
+		if( xBytesAvailable > sbBYTES_TO_STORE_MESSAGE_LENGTH )
+		{
+			/* The number of bytes available is greater than the number of bytes
+			required to hold the length of the next message, so another message
+			is available.  Return its length without removing the length bytes
+			from the buffer.  A copy of the tail is stored so the buffer can be
+			returned to its prior state as the message is not actually being
+			removed from the buffer. */
+			xOriginalTail = pxStreamBuffer->xTail;
+			( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempReturn, sbBYTES_TO_STORE_MESSAGE_LENGTH, xBytesAvailable );
+			xReturn = ( size_t ) xTempReturn;
+			pxStreamBuffer->xTail = xOriginalTail;
+		}
+		else
+		{
+			/* The minimum amount of bytes in a message buffer is
+			( sbBYTES_TO_STORE_MESSAGE_LENGTH + 1 ), so if xBytesAvailable is
+			less than sbBYTES_TO_STORE_MESSAGE_LENGTH the only other valid
+			value is 0. */
+			configASSERT( xBytesAvailable == 0 );
+			xReturn = 0;
+		}
+	}
+	else
+	{
+		xReturn = 0;
+	}
+
+	return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
+									void *pvRxData,
+									size_t xBufferLengthBytes,
+									BaseType_t * const pxHigherPriorityTaskWoken )
+{
+StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
+size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength;
+
+	configASSERT( pvRxData );
+	configASSERT( pxStreamBuffer );
+
+	/* This receive function is used by both message buffers, which store
+	discrete messages, and stream buffers, which store a continuous stream of
+	bytes.  Discrete messages include an additional
+	sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the
+	message. */
+	if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
+	{
+		xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;
+	}
+	else
+	{
+		xBytesToStoreMessageLength = 0;
+	}
+
+	xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
+
+	/* Whether receiving a discrete message (where xBytesToStoreMessageLength
+	holds the number of bytes used to store the message length) or a stream of
+	bytes (where xBytesToStoreMessageLength is zero), the number of bytes
+	available must be greater than xBytesToStoreMessageLength to be able to
+	read bytes from the buffer. */
+	if( xBytesAvailable > xBytesToStoreMessageLength )
+	{
+		xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength );
+
+		/* Was a task waiting for space in the buffer? */
+		if( xReceivedLength != ( size_t ) 0 )
+		{
+			sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken );
+		}
+		else
+		{
+			mtCOVERAGE_TEST_MARKER();
+		}
+	}
+	else
+	{
+		mtCOVERAGE_TEST_MARKER();
+	}
+
+	traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength );
+
+	return xReceivedLength;
+}
+/*-----------------------------------------------------------*/
+
+static size_t prvReadMessageFromBuffer( StreamBuffer_t *pxStreamBuffer,
+										void *pvRxData,
+										size_t xBufferLengthBytes,
+										size_t xBytesAvailable,
+										size_t xBytesToStoreMessageLength )
+{
+size_t xOriginalTail, xReceivedLength, xNextMessageLength;
+configMESSAGE_BUFFER_LENGTH_TYPE xTempNextMessageLength;
+
+	if( xBytesToStoreMessageLength != ( size_t ) 0 )
+	{
+		/* A discrete message is being received.  First receive the length
+		of the message.  A copy of the tail is stored so the buffer can be
+		returned to its prior state if the length of the message is too
+		large for the provided buffer. */
+		xOriginalTail = pxStreamBuffer->xTail;
+		( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempNextMessageLength, xBytesToStoreMessageLength, xBytesAvailable );
+		xNextMessageLength = ( size_t ) xTempNextMessageLength;
+
+		/* Reduce the number of bytes available by the number of bytes just
+		read out. */
+		xBytesAvailable -= xBytesToStoreMessageLength;
+
+		/* Check there is enough space in the buffer provided by the
+		user. */
+		if( xNextMessageLength > xBufferLengthBytes )
+		{
+			/* The user has provided insufficient space to read the message
+			so return the buffer to its previous state (so the length of
+			the message is in the buffer again). */
+			pxStreamBuffer->xTail = xOriginalTail;
+			xNextMessageLength = 0;
+		}
+		else
+		{
+			mtCOVERAGE_TEST_MARKER();
+		}
+	}
+	else
+	{
+		/* A stream of bytes is being received (as opposed to a discrete
+		message), so read as many bytes as possible. */
+		xNextMessageLength = xBufferLengthBytes;
+	}
+
+	/* Read the actual data. */
+	xReceivedLength = prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) pvRxData, xNextMessageLength, xBytesAvailable ); /*lint !e9079 Data storage area is implemented as uint8_t array for ease of sizing, indexing and alignment. */
+
+	return xReceivedLength;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer )
+{
+const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
+BaseType_t xReturn;
+size_t xTail;
+
+	configASSERT( pxStreamBuffer );
+
+	/* True if no bytes are available. */
+	xTail = pxStreamBuffer->xTail;
+	if( pxStreamBuffer->xHead == xTail )
+	{
+		xReturn = pdTRUE;
+	}
+	else
+	{
+		xReturn = pdFALSE;
+	}
+
+	return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer )
+{
+BaseType_t xReturn;
+size_t xBytesToStoreMessageLength;
+const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
+
+	configASSERT( pxStreamBuffer );
+
+	/* This generic version of the receive function is used by both message
+	buffers, which store discrete messages, and stream buffers, which store a
+	continuous stream of bytes.  Discrete messages include an additional
+	sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the message. */
+	if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
+	{
+		xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;
+	}
+	else
+	{
+		xBytesToStoreMessageLength = 0;
+	}
+
+	/* True if the available space equals zero. */
+	if( xStreamBufferSpacesAvailable( xStreamBuffer ) <= xBytesToStoreMessageLength )
+	{
+		xReturn = pdTRUE;
+	}
+	else
+	{
+		xReturn = pdFALSE;
+	}
+
+	return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken )
+{
+StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
+BaseType_t xReturn;
+UBaseType_t uxSavedInterruptStatus;
+
+	configASSERT( pxStreamBuffer );
+
+	uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR();
+	{
+		if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL )
+		{
+			( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive,
+										 ( uint32_t ) 0,
+										 eNoAction,
+										 pxHigherPriorityTaskWoken );
+			( pxStreamBuffer )->xTaskWaitingToReceive = NULL;
+			xReturn = pdTRUE;
+		}
+		else
+		{
+			xReturn = pdFALSE;
+		}
+	}
+	portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
+
+	return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken )
+{
+StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
+BaseType_t xReturn;
+UBaseType_t uxSavedInterruptStatus;
+
+	configASSERT( pxStreamBuffer );
+
+	uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR();
+	{
+		if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL )
+		{
+			( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend,
+										 ( uint32_t ) 0,
+										 eNoAction,
+										 pxHigherPriorityTaskWoken );
+			( pxStreamBuffer )->xTaskWaitingToSend = NULL;
+			xReturn = pdTRUE;
+		}
+		else
+		{
+			xReturn = pdFALSE;
+		}
+	}
+	portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
+
+	return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer, const uint8_t *pucData, size_t xCount )
+{
+size_t xNextHead, xFirstLength;
+
+	configASSERT( xCount > ( size_t ) 0 );
+
+	xNextHead = pxStreamBuffer->xHead;
+
+	/* Calculate the number of bytes that can be added in the first write -
+	which may be less than the total number of bytes that need to be added if
+	the buffer will wrap back to the beginning. */
+	xFirstLength = configMIN( pxStreamBuffer->xLength - xNextHead, xCount );
+
+	/* Write as many bytes as can be written in the first write. */
+	configASSERT( ( xNextHead + xFirstLength ) <= pxStreamBuffer->xLength );
+	( void ) memcpy( ( void* ) ( &( pxStreamBuffer->pucBuffer[ xNextHead ] ) ), ( const void * ) pucData, xFirstLength ); /*lint !e9087 memcpy() requires void *. */
+
+	/* If the number of bytes written was less than the number that could be
+	written in the first write... */
+	if( xCount > xFirstLength )
+	{
+		/* ...then write the remaining bytes to the start of the buffer. */
+		configASSERT( ( xCount - xFirstLength ) <= pxStreamBuffer->xLength );
+		( void ) memcpy( ( void * ) pxStreamBuffer->pucBuffer, ( const void * ) &( pucData[ xFirstLength ] ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */
+	}
+	else
+	{
+		mtCOVERAGE_TEST_MARKER();
+	}
+
+	xNextHead += xCount;
+	if( xNextHead >= pxStreamBuffer->xLength )
+	{
+		xNextHead -= pxStreamBuffer->xLength;
+	}
+	else
+	{
+		mtCOVERAGE_TEST_MARKER();
+	}
+
+	pxStreamBuffer->xHead = xNextHead;
+
+	return xCount;
+}
+/*-----------------------------------------------------------*/
+
+static size_t prvReadBytesFromBuffer( StreamBuffer_t *pxStreamBuffer, uint8_t *pucData, size_t xMaxCount, size_t xBytesAvailable )
+{
+size_t xCount, xFirstLength, xNextTail;
+
+	/* Use the minimum of the wanted bytes and the available bytes. */
+	xCount = configMIN( xBytesAvailable, xMaxCount );
+
+	if( xCount > ( size_t ) 0 )
+	{
+		xNextTail = pxStreamBuffer->xTail;
+
+		/* Calculate the number of bytes that can be read - which may be
+		less than the number wanted if the data wraps around to the start of
+		the buffer. */
+		xFirstLength = configMIN( pxStreamBuffer->xLength - xNextTail, xCount );
+
+		/* Obtain the number of bytes it is possible to obtain in the first
+		read.  Asserts check bounds of read and write. */
+		configASSERT( xFirstLength <= xMaxCount );
+		configASSERT( ( xNextTail + xFirstLength ) <= pxStreamBuffer->xLength );
+		( void ) memcpy( ( void * ) pucData, ( const void * ) &( pxStreamBuffer->pucBuffer[ xNextTail ] ), xFirstLength ); /*lint !e9087 memcpy() requires void *. */
+
+		/* If the total number of wanted bytes is greater than the number
+		that could be read in the first read... */
+		if( xCount > xFirstLength )
+		{
+			/*...then read the remaining bytes from the start of the buffer. */
+			configASSERT( xCount <= xMaxCount );
+			( void ) memcpy( ( void * ) &( pucData[ xFirstLength ] ), ( void * ) ( pxStreamBuffer->pucBuffer ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */
+		}
+		else
+		{
+			mtCOVERAGE_TEST_MARKER();
+		}
+
+		/* Move the tail pointer to effectively remove the data read from
+		the buffer. */
+		xNextTail += xCount;
+
+		if( xNextTail >= pxStreamBuffer->xLength )
+		{
+			xNextTail -= pxStreamBuffer->xLength;
+		}
+
+		pxStreamBuffer->xTail = xNextTail;
+	}
+	else
+	{
+		mtCOVERAGE_TEST_MARKER();
+	}
+
+	return xCount;
+}
+/*-----------------------------------------------------------*/
+
+static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer )
+{
+/* Returns the distance between xTail and xHead. */
+size_t xCount;
+
+	xCount = pxStreamBuffer->xLength + pxStreamBuffer->xHead;
+	xCount -= pxStreamBuffer->xTail;
+	if ( xCount >= pxStreamBuffer->xLength )
+	{
+		xCount -= pxStreamBuffer->xLength;
+	}
+	else
+	{
+		mtCOVERAGE_TEST_MARKER();
+	}
+
+	return xCount;
+}
+/*-----------------------------------------------------------*/
+
+static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
+										  uint8_t * const pucBuffer,
+										  size_t xBufferSizeBytes,
+										  size_t xTriggerLevelBytes,
+										  uint8_t ucFlags )
+{
+	/* Assert here is deliberately writing to the entire buffer to ensure it can
+	be written to without generating exceptions, and is setting the buffer to a
+	known value to assist in development/debugging. */
+	#if( configASSERT_DEFINED == 1 )
+	{
+		/* The value written just has to be identifiable when looking at the
+		memory.  Don't use 0xA5 as that is the stack fill value and could
+		result in confusion as to what is actually being observed. */
+		const BaseType_t xWriteValue = 0x55;
+		configASSERT( memset( pucBuffer, ( int ) xWriteValue, xBufferSizeBytes ) == pucBuffer );
+	} /*lint !e529 !e438 xWriteValue is only used if configASSERT() is defined. */
+	#endif
+
+	( void ) memset( ( void * ) pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); /*lint !e9087 memset() requires void *. */
+	pxStreamBuffer->pucBuffer = pucBuffer;
+	pxStreamBuffer->xLength = xBufferSizeBytes;
+	pxStreamBuffer->xTriggerLevelBytes = xTriggerLevelBytes;
+	pxStreamBuffer->ucFlags = ucFlags;
+	vPortCPUInitializeMutex( &pxStreamBuffer->xStreamBufferMux );
+}
+
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+	UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer )
+	{
+		return xStreamBuffer->uxStreamBufferNumber;
+	}
+
+#endif /* configUSE_TRACE_FACILITY */
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+	void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber )
+	{
+		xStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber;
+	}
+
+#endif /* configUSE_TRACE_FACILITY */
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+	uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer )
+	{
+		return ( xStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER );
+	}
+
+#endif /* configUSE_TRACE_FACILITY */
+/*-----------------------------------------------------------*/

Fișier diff suprimat deoarece este prea mare
+ 384 - 366
components/freertos/tasks.c


+ 1 - 2
components/freertos/test/test_freertos_eventgroups.c

@@ -125,7 +125,7 @@ TEST_CASE("FreeRTOS Event Group Sync", "[freertos]")
 }
 
 /*-----------------Test case for event group trace facilities-----------------*/
-#ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY
+#ifdef  CONFIG_FREERTOS_USE_TRACE_FACILITY
 /*
  * Test event group Trace Facility functions such as
  * xEventGroupClearBitsFromISR(), xEventGroupSetBitsFromISR()
@@ -217,5 +217,4 @@ TEST_CASE("FreeRTOS Event Group ISR", "[freertos]")
     vSemaphoreDelete(done_sem);
     vTaskDelay(10);     //Give time for idle task to clear up deleted tasks
 }
-
 #endif      //CONFIG_FREERTOS_USE_TRACE_FACILITY

+ 3 - 1
components/freertos/test/test_freertos_get_state.c

@@ -29,8 +29,10 @@ void test_task_get_state(void* arg)
 
 void blocked_task(void *arg)
 {
+    uint32_t notify_value;
+
     while(1){
-        vTaskDelay(portMAX_DELAY);
+        xTaskNotifyWait(0, 0xFFFFFFFF, &notify_value, portMAX_DELAY);
     }
 }
 

+ 103 - 0
components/freertos/test/test_stream_buffers.c

@@ -0,0 +1,103 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/semphr.h"
+#include "freertos/stream_buffer.h"
+#include "freertos/message_buffer.h"
+#include "unity.h"
+#include "test_utils.h"
+
+typedef struct {
+    StreamBufferHandle_t sb;
+    SemaphoreHandle_t end_test;
+    bool send_fail;
+    bool receive_fail;
+    bool produce_isr;
+}test_context;
+
+static void producer_task(void *arg) 
+{
+    test_context *tc  = arg;
+    uint8_t produced = 0;
+    printf("Starting sender task... \n");
+
+    while(produced < 100) {
+
+        if(!tc->produce_isr) {
+            BaseType_t result = xStreamBufferSend(tc->sb, &produced, 1, 0);
+            if(!result) {
+                tc->send_fail = true;
+                xSemaphoreGive(tc->end_test);
+                vTaskDelete(NULL);
+            } else {
+                produced++;
+            }
+        }
+
+        vTaskDelay(1);
+    }
+
+    tc->send_fail = false;
+    vTaskDelete(NULL);
+}
+
+static void receiver_task(void *arg)
+{
+    test_context *tc = arg;
+    uint8_t expected_consumed = 0;
+    printf("Starting receiver task... \n");
+
+    for(;;){
+         uint8_t read_byte = 0xFF; 
+         uint32_t result = xStreamBufferReceive(tc->sb, &read_byte, 1, 1000);
+         
+         if((read_byte != expected_consumed) || !result) {
+            tc->receive_fail = true;
+            xSemaphoreGive(tc->end_test);
+            vTaskDelete(NULL);
+         } else {
+             expected_consumed++;
+             if(expected_consumed == 99) {
+                 break;
+             }
+         }
+    }
+
+    tc->receive_fail = false;
+    xSemaphoreGive(tc->end_test);
+    vTaskDelete(NULL);
+}
+
+TEST_CASE("Send-receive stream buffer test", "[freertos]")
+{
+    BaseType_t result;
+    test_context tc;
+
+    tc.sb = xStreamBufferCreate(128, 1);
+    tc.end_test = xSemaphoreCreateBinary();
+    
+    TEST_ASSERT(tc.sb);
+    TEST_ASSERT(tc.end_test);
+
+    tc.send_fail = false;
+    tc.receive_fail = false;
+    tc.produce_isr = false;
+
+    result = xTaskCreatePinnedToCore(producer_task, "sender", 4096, &tc, UNITY_FREERTOS_PRIORITY + 2, NULL, 0);
+    TEST_ASSERT(result == pdTRUE);
+    result = xTaskCreatePinnedToCore(receiver_task, "receiver", 4096, &tc, UNITY_FREERTOS_PRIORITY + 1, NULL, 1);
+    TEST_ASSERT(result == pdTRUE);
+
+    result = xSemaphoreTake(tc.end_test, 2000);
+    TEST_ASSERT(result == pdTRUE);
+
+    vTaskDelay(1);
+
+    TEST_ASSERT(tc.send_fail == false);
+    TEST_ASSERT(tc.receive_fail == false);
+
+    vStreamBufferDelete(tc.sb);
+    vSemaphoreDelete(tc.end_test);
+}

+ 1 - 1
components/freertos/test/test_suspend_scheduler.c

@@ -61,7 +61,7 @@ static void counter_task_fn(void *vp_config)
 TEST_CASE("Scheduler disabled can handle a pending context switch on resume", "[freertos]")
 {
     isr_count = 0;
-    isr_semaphore = xSemaphoreCreateMutex();
+    isr_semaphore = xSemaphoreCreateBinary();
     TaskHandle_t counter_task;
     intr_handle_t isr_handle = NULL;
 

+ 17 - 0
components/freertos/test/test_timers.c

@@ -68,3 +68,20 @@ TEST_CASE("Recurring FreeRTOS timers", "[freertos]")
 
     TEST_ASSERT( xTimerDelete(recurring, 1) );
 }
+
+#ifdef CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION
+TEST_CASE("Static timer creation", "[freertos]")
+{
+    StaticTimer_t static_timer;
+    TimerHandle_t created_timer;
+    volatile int count = 0;
+
+    created_timer = xTimerCreateStatic("oneshot", 100 / portTICK_PERIOD_MS, 
+                                    pdTRUE,
+                                    (void *)&count, 
+                                    timer_callback, 
+                                    &static_timer);
+    
+    TEST_ASSERT_NOT_NULL(created_timer);
+}
+#endif

+ 293 - 234
components/freertos/timers.c

@@ -1,71 +1,29 @@
 /*
-    FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
-    All rights reserved
-
-    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License (version 2) as published by the
-    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
-
-	***************************************************************************
-    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
-    >>!   distribute a combined work that includes FreeRTOS without being   !<<
-    >>!   obliged to provide the source code for proprietary components     !<<
-    >>!   outside of the FreeRTOS kernel.                                   !<<
-	***************************************************************************
-
-    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
-    link: http://www.freertos.org/a00114.html
-
-    ***************************************************************************
-     *                                                                       *
-     *    FreeRTOS provides completely free yet professionally developed,    *
-     *    robust, strictly quality controlled, supported, and cross          *
-     *    platform software that is more than just the market leader, it     *
-     *    is the industry's de facto standard.                               *
-     *                                                                       *
-     *    Help yourself get started quickly while simultaneously helping     *
-     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
-     *    tutorial book, reference manual, or both:                          *
-     *    http://www.FreeRTOS.org/Documentation                              *
-     *                                                                       *
-    ***************************************************************************
-
-    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
-	the FAQ page "My application does not run, what could be wrong?".  Have you
-	defined configASSERT()?
-
-	http://www.FreeRTOS.org/support - In return for receiving this top quality
-	embedded software for free we request you assist our global community by
-	participating in the support forum.
-
-	http://www.FreeRTOS.org/training - Investing in training allows your team to
-	be as productive as possible as early as possible.  Now you can receive
-	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
-	Ltd, and the world's leading authority on the world's leading RTOS.
-
-    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
-    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
-    compatible FAT file system, and our tiny thread aware UDP/IP stack.
-
-    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
-    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
-
-    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
-    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
-    licenses offer ticketed support, indemnification and commercial middleware.
-
-    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
-    engineered and independently SIL3 certified version for use in safety and
-    mission critical applications that require provable dependability.
-
-    1 tab == 4 spaces!
-*/
+ * FreeRTOS Kernel V10.2.1
+ * 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!
+ */
 
 /* Standard includes. */
 #include <stdlib.h>
@@ -79,17 +37,16 @@ task.h is included from an application file. */
 #include "task.h"
 #include "queue.h"
 #include "timers.h"
-#include "portmacro.h"
 
 #if ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 0 )
 	#error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available.
 #endif
 
-/* Lint 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. */
+/* 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 !e9021 !e961 !e750. */
 
 
 /* This entire source file will be skipped if the application is not configured
@@ -101,22 +58,29 @@ configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */
 /* Misc definitions. */
 #define tmrNO_DELAY		( TickType_t ) 0U
 
+/* The name assigned to the timer service task.  This can be overridden by
+defining trmTIMER_SERVICE_TASK_NAME in FreeRTOSConfig.h. */
+#ifndef configTIMER_SERVICE_TASK_NAME
+	#define configTIMER_SERVICE_TASK_NAME "Tmr Svc"
+#endif
+
+/* Bit definitions used in the ucStatus member of a timer structure. */
+#define tmrSTATUS_IS_ACTIVE					( ( uint8_t ) 0x01 )
+#define tmrSTATUS_IS_STATICALLY_ALLOCATED	( ( uint8_t ) 0x02 )
+#define tmrSTATUS_IS_AUTORELOAD				( ( uint8_t ) 0x04 )
+
 /* The definition of the timers themselves. */
-typedef struct tmrTimerControl
+typedef struct tmrTimerControl /* The old naming convention is used to prevent breaking kernel aware debuggers. */
 {
 	const char				*pcTimerName;		/*<< Text name.  This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
 	ListItem_t				xTimerListItem;		/*<< Standard linked list item as used by all kernel features for event management. */
 	TickType_t				xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */
-	UBaseType_t				uxAutoReload;		/*<< Set to pdTRUE if the timer should be automatically restarted once expired.  Set to pdFALSE if the timer is, in effect, a one-shot timer. */
 	void 					*pvTimerID;			/*<< An ID to identify the timer.  This allows the timer to be identified when the same callback is used for multiple timers. */
 	TimerCallbackFunction_t	pxCallbackFunction;	/*<< The function that will be called when the timer expires. */
 	#if( configUSE_TRACE_FACILITY == 1 )
 		UBaseType_t			uxTimerNumber;		/*<< An ID assigned by trace tools such as FreeRTOS+Trace */
 	#endif
-
-	#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
-		uint8_t 			ucStaticallyAllocated; /*<< Set to pdTRUE if the timer was created statically so no attempt is made to free the memory again if the timer is later deleted. */
-	#endif
+	uint8_t 				ucStatus;			/*<< Holds bits to say if the timer was statically allocated or not, and if it is active or not. */
 } xTIMER;
 
 /* The old xTIMER name is maintained above then typedefed to the new Timer_t
@@ -159,12 +123,15 @@ typedef struct tmrTimerQueueMessage
 	} u;
 } DaemonTaskMessage_t;
 
-/*lint -e956 A manual analysis and inspection has been used to determine which
-static variables must be declared volatile. */
+/*lint -save -e956 A manual analysis and inspection has been used to determine
+which static variables must be declared volatile. */
 
 /* The list in which active timers are stored.  Timers are referenced in expire
 time order, with the nearest expiry time at the front of the list.  Only the
-timer service task is allowed to access these lists. */
+timer service task is allowed to access these lists.
+xActiveTimerList1 and xActiveTimerList2 could be at function scope but that
+breaks some kernel aware debuggers, and debuggers that reply on removing the
+static qualifier. */
 PRIVILEGED_DATA static List_t xActiveTimerList1;
 PRIVILEGED_DATA static List_t xActiveTimerList2;
 PRIVILEGED_DATA static List_t *pxCurrentTimerList;
@@ -172,19 +139,24 @@ PRIVILEGED_DATA static List_t *pxOverflowTimerList;
 
 /* A queue that is used to send commands to the timer service task. */
 PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL;
+PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL;
 
 /* Mux. We use a single mux for all the timers for now. ToDo: maybe increase granularity here? */
 PRIVILEGED_DATA portMUX_TYPE xTimerMux = portMUX_INITIALIZER_UNLOCKED;
 
-#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )
+/*lint -restore */
 
-	PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL;
+/*-----------------------------------------------------------*/
 
-#endif
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
 
-/*lint +e956 */
+	/* If static allocation is supported then the application must provide the
+	following callback function - which enables the application to optionally
+	provide the memory that will be used by the timer task as the task's stack
+	and TCB. */
+	extern void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize );
 
-/*-----------------------------------------------------------*/
+#endif
 
 /*
  * Initialise the infrastructure used by the timer service task if it has not
@@ -197,13 +169,13 @@ static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION;
  * task.  Other tasks communicate with the timer service task using the
  * xTimerQueue queue.
  */
-static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION;
+static portTASK_FUNCTION_PROTO( prvTimerTask, pvParameters ) PRIVILEGED_FUNCTION;
 
 /*
  * Called by the timer service task to interpret and process a command it
  * received on the timer queue.
  */
-static void	prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION;
+static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION;
 
 /*
  * Insert the timer into either xActiveTimerList1, or xActiveTimerList2,
@@ -241,18 +213,18 @@ static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) PRIV
  * If a timer has expired, process it.  Otherwise, block the timer service task
  * until either a timer does expire or a command is received.
  */
-static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, const BaseType_t xListWasEmpty ) PRIVILEGED_FUNCTION;
+static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty ) PRIVILEGED_FUNCTION;
 
 /*
  * Called after a Timer_t structure has been allocated either statically or
  * dynamically to fill in the structure's members.
  */
-static void prvInitialiseNewTimer(	const char * const pcTimerName,
+static void prvInitialiseNewTimer(	const char * const pcTimerName,			/*lint !e971 Unqualified char types are allowed for strings and single characters only. */
 									const TickType_t xTimerPeriodInTicks,
 									const UBaseType_t uxAutoReload,
 									void * const pvTimerID,
 									TimerCallbackFunction_t pxCallbackFunction,
-									Timer_t *pxNewTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+									Timer_t *pxNewTimer ) PRIVILEGED_FUNCTION;
 /*-----------------------------------------------------------*/
 
 BaseType_t xTimerCreateTimerTask( void )
@@ -263,29 +235,41 @@ BaseType_t xReturn = pdFAIL;
 	configUSE_TIMERS is set to 1.  Check that the infrastructure used by the
 	timer service task has been created/initialised.  If timers have already
 	been created then the initialisation will already have been performed. */
-
-	/* For now, the timer task will be fixed to core 0. This means whatever process
-	   running on whatever core schedules the timer, the timer callback function
-	   will *ALWAYS* run on core 0. */
 	prvCheckForValidListAndQueue();
 
 	if( xTimerQueue != NULL )
 	{
-		/* Although static allocation has been backported from FreeRTOS v9.0.0,
-		   the timer task is still allocated dynamically. The actual timers
-		   however can be allocated statically.*/
-	    #if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )
+		#if( configSUPPORT_STATIC_ALLOCATION == 1 && configSUPPORT_STATIC_ALLOCATION == 0 )
 		{
-			/* Create the timer task, storing its handle in xTimerTaskHandle so
-			it can be returned by the xTimerGetTimerDaemonTaskHandle() function. */
-			xReturn = xTaskCreatePinnedToCore( prvTimerTask, "Tmr Svc", ( uint16_t ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle, 0 );
+			StaticTask_t *pxTimerTaskTCBBuffer = NULL;
+			StackType_t *pxTimerTaskStackBuffer = NULL;
+			uint32_t ulTimerTaskStackSize;
+
+			vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize );
+			xTimerTaskHandle = xTaskCreateStaticPinnedToCore(	prvTimerTask,
+													configTIMER_SERVICE_TASK_NAME,
+													ulTimerTaskStackSize,
+													NULL,
+													( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
+													pxTimerTaskStackBuffer,
+													pxTimerTaskTCBBuffer,
+													0 );
+
+			if( xTimerTaskHandle != NULL )
+			{
+				xReturn = pdPASS;
+			}
 		}
 		#else
 		{
-			/* Create the timer task without storing its handle. */
-			xReturn = xTaskCreatePinnedToCore( prvTimerTask, "Tmr Svc", ( uint16_t ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, NULL, 0 );
+			xReturn = xTaskCreatePinnedToCore(	prvTimerTask,
+									configTIMER_SERVICE_TASK_NAME,
+									configTIMER_TASK_STACK_DEPTH,
+									NULL,
+									( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
+									&xTimerTaskHandle, 0 );
 		}
-		#endif
+		#endif /* configSUPPORT_STATIC_ALLOCATION */
 	}
 	else
 	{
@@ -299,44 +283,39 @@ BaseType_t xReturn = pdFAIL;
 
 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
 
-	TimerHandle_t xTimerCreate(	const char * const pcTimerName,
+	TimerHandle_t xTimerCreate(	const char * const pcTimerName,			/*lint !e971 Unqualified char types are allowed for strings and single characters only. */
 								const TickType_t xTimerPeriodInTicks,
 								const UBaseType_t uxAutoReload,
 								void * const pvTimerID,
-								TimerCallbackFunction_t pxCallbackFunction ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+								TimerCallbackFunction_t pxCallbackFunction )
 	{
 	Timer_t *pxNewTimer;
 
-		pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) );
+		pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of Timer_t is always a pointer to the timer's mame. */
 
 		if( pxNewTimer != NULL )
 		{
+			/* Status is thus far zero as the timer is not created statically
+			and has not been started.  The autoreload bit may get set in
+			prvInitialiseNewTimer. */
+			pxNewTimer->ucStatus = 0x00;
 			prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );
-
-			#if( configSUPPORT_STATIC_ALLOCATION == 1 )
-			{
-				/* Timers can be created statically or dynamically, so note this
-				timer was created dynamically in case the timer is later
-				deleted. */
-				pxNewTimer->ucStaticallyAllocated = pdFALSE;
-			}
-			#endif /* configSUPPORT_STATIC_ALLOCATION */
 		}
 
 		return pxNewTimer;
 	}
 
-#endif /* configSUPPORT_STATIC_ALLOCATION */
+#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
 /*-----------------------------------------------------------*/
 
 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
 
-	TimerHandle_t xTimerCreateStatic(	const char * const pcTimerName,
+	TimerHandle_t xTimerCreateStatic(	const char * const pcTimerName,		/*lint !e971 Unqualified char types are allowed for strings and single characters only. */
 										const TickType_t xTimerPeriodInTicks,
 										const UBaseType_t uxAutoReload,
 										void * const pvTimerID,
 										TimerCallbackFunction_t pxCallbackFunction,
-										StaticTimer_t *pxTimerBuffer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+										StaticTimer_t *pxTimerBuffer )
 	{
 	Timer_t *pxNewTimer;
 
@@ -344,7 +323,7 @@ BaseType_t xReturn = pdFAIL;
 		{
 			/* Sanity check that the size of the structure used to declare a
 			variable of type StaticTimer_t equals the size of the real timer
-			structures. */
+			structure. */
 			volatile size_t xSize = sizeof( StaticTimer_t );
 			configASSERT( xSize == sizeof( Timer_t ) );
 			( void ) xSize; /* Keeps lint quiet when configASSERT() is not defined. */
@@ -353,19 +332,16 @@ BaseType_t xReturn = pdFAIL;
 
 		/* A pointer to a StaticTimer_t structure MUST be provided, use it. */
 		configASSERT( pxTimerBuffer );
-		pxNewTimer = ( Timer_t * ) pxTimerBuffer; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */
+		pxNewTimer = ( Timer_t * ) pxTimerBuffer; /*lint !e740 !e9087 StaticTimer_t is a pointer to a Timer_t, so guaranteed to be aligned and sized correctly (checked by an assert()), so this is safe. */
 
 		if( pxNewTimer != NULL )
 		{
-			prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );
+			/* Timers can be created statically or dynamically so note this
+			timer was created statically in case it is later deleted.  The
+			autoreload bit may get set in prvInitialiseNewTimer(). */
+			pxNewTimer->ucStatus = tmrSTATUS_IS_STATICALLY_ALLOCATED;
 
-			#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
-			{
-				/* Timers can be created statically or dynamically so note this
-				timer was created statically in case it is later deleted. */
-				pxNewTimer->ucStaticallyAllocated = pdTRUE;
-			}
-			#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
+			prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );
 		}
 
 		return pxNewTimer;
@@ -374,12 +350,12 @@ BaseType_t xReturn = pdFAIL;
 #endif /* configSUPPORT_STATIC_ALLOCATION */
 /*-----------------------------------------------------------*/
 
-static void prvInitialiseNewTimer(	const char * const pcTimerName,
+static void prvInitialiseNewTimer(	const char * const pcTimerName,			/*lint !e971 Unqualified char types are allowed for strings and single characters only. */
 									const TickType_t xTimerPeriodInTicks,
 									const UBaseType_t uxAutoReload,
 									void * const pvTimerID,
 									TimerCallbackFunction_t pxCallbackFunction,
-									Timer_t *pxNewTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+									Timer_t *pxNewTimer )
 {
 	/* 0 is not a valid value for xTimerPeriodInTicks. */
 	configASSERT( ( xTimerPeriodInTicks > 0 ) );
@@ -394,10 +370,13 @@ static void prvInitialiseNewTimer(	const char * const pcTimerName,
 		parameters. */
 		pxNewTimer->pcTimerName = pcTimerName;
 		pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;
-		pxNewTimer->uxAutoReload = uxAutoReload;
 		pxNewTimer->pvTimerID = pvTimerID;
 		pxNewTimer->pxCallbackFunction = pxCallbackFunction;
 		vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );
+		if( uxAutoReload != pdFALSE )
+		{
+			pxNewTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD;
+		}
 		traceTIMER_CREATE( pxNewTimer );
 	}
 }
@@ -408,6 +387,8 @@ BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommand
 BaseType_t xReturn = pdFAIL;
 DaemonTaskMessage_t xMessage;
 
+	configASSERT( xTimer );
+
 	/* Send a message to the timer service task to perform a particular action
 	on a particular timer definition. */
 	if( xTimerQueue != NULL )
@@ -415,7 +396,7 @@ DaemonTaskMessage_t xMessage;
 		/* Send a command to the timer service task to start the xTimer timer. */
 		xMessage.xMessageID = xCommandID;
 		xMessage.u.xTimerParameters.xMessageValue = xOptionalValue;
-		xMessage.u.xTimerParameters.pxTimer = ( Timer_t * ) xTimer;
+		xMessage.u.xTimerParameters.pxTimer = xTimer;
 
 		if( xCommandID < tmrFIRST_FROM_ISR_COMMAND )
 		{
@@ -444,43 +425,60 @@ DaemonTaskMessage_t xMessage;
 }
 /*-----------------------------------------------------------*/
 
-#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )
+TaskHandle_t xTimerGetTimerDaemonTaskHandle( void )
+{
+	/* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been
+	started, then xTimerTaskHandle will be NULL. */
+	configASSERT( ( xTimerTaskHandle != NULL ) );
+	return xTimerTaskHandle;
+}
+/*-----------------------------------------------------------*/
 
-	TaskHandle_t xTimerGetTimerDaemonTaskHandle( void )
-	{
-		/* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been
-		started, then xTimerTaskHandle will be NULL. */
-		configASSERT( ( xTimerTaskHandle != NULL ) );
-		return xTimerTaskHandle;
-	}
+TickType_t xTimerGetPeriod( TimerHandle_t xTimer )
+{
+Timer_t *pxTimer = xTimer;
 
-#endif
+	configASSERT( xTimer );
+	return pxTimer->xTimerPeriodInTicks;
+}
 /*-----------------------------------------------------------*/
 
-TickType_t xTimerGetPeriod( TimerHandle_t xTimer )
+void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload )
 {
-Timer_t *pxTimer = ( Timer_t * ) xTimer;
+Timer_t * pxTimer =  xTimer;
 
-    configASSERT( xTimer );
-    return pxTimer->xTimerPeriodInTicks;
+	configASSERT( xTimer );
+	taskENTER_CRITICAL( &xTimerMux);
+	{
+		if( uxAutoReload != pdFALSE )
+		{
+			pxTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD;
+		}
+		else
+		{
+			pxTimer->ucStatus &= ~tmrSTATUS_IS_AUTORELOAD;
+		}
+	}
+	taskEXIT_CRITICAL( &xTimerMux);
 }
 /*-----------------------------------------------------------*/
 
 TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer )
 {
-Timer_t * pxTimer = ( Timer_t * ) xTimer;
+Timer_t * pxTimer =  xTimer;
 TickType_t xReturn;
 
-    configASSERT( xTimer );
-    xReturn = listGET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ) );
-    return xReturn;
+	configASSERT( xTimer );
+	xReturn = listGET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ) );
+	return xReturn;
 }
-
 /*-----------------------------------------------------------*/
-const char * pcTimerGetTimerName( TimerHandle_t xTimer )
+
+const char * pcTimerGetName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
 {
-Timer_t *pxTimer = ( Timer_t * ) xTimer;
+Timer_t *pxTimer = xTimer;
 
+	configASSERT( xTimer );
 	return pxTimer->pcTimerName;
 }
 /*-----------------------------------------------------------*/
@@ -488,7 +486,7 @@ Timer_t *pxTimer = ( Timer_t * ) xTimer;
 static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow )
 {
 BaseType_t xResult;
-Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );
+Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks and co-routines too.  Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */
 
 	/* Remove the timer from the list of active timers.  A check has already
 	been performed to ensure the list is not empty. */
@@ -497,12 +495,12 @@ Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTi
 
 	/* If the timer is an auto reload timer then calculate the next
 	expiry time and re-insert the timer in the list of active timers. */
-	if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )
+	if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 )
 	{
 		/* The timer is inserted into a list using a time relative to anything
 		other than the current time.  It will therefore be inserted into the
 		correct list relative to the time this task thinks it is now. */
-		if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) == pdTRUE )
+		if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) != pdFALSE )
 		{
 			/* The timer expired before it was added to the active timer
 			list.  Reload it now.  */
@@ -517,6 +515,7 @@ Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTi
 	}
 	else
 	{
+		pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;
 		mtCOVERAGE_TEST_MARKER();
 	}
 
@@ -525,7 +524,7 @@ Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTi
 }
 /*-----------------------------------------------------------*/
 
-static void prvTimerTask( void *pvParameters )
+static portTASK_FUNCTION( prvTimerTask, pvParameters )
 {
 TickType_t xNextExpireTime;
 BaseType_t xListWasEmpty;
@@ -533,6 +532,18 @@ BaseType_t xListWasEmpty;
 	/* Just to avoid compiler warnings. */
 	( void ) pvParameters;
 
+	#if( configUSE_DAEMON_TASK_STARTUP_HOOK == 1 )
+	{
+		extern void vApplicationDaemonTaskStartupHook( void );
+
+		/* Allow the application writer to execute some code in the context of
+		this task at the point the task starts executing.  This is useful if the
+		application includes initialisation code that would benefit from
+		executing after the scheduler has been started. */
+		vApplicationDaemonTaskStartupHook();
+	}
+	#endif /* configUSE_DAEMON_TASK_STARTUP_HOOK */
+
 	for( ;; )
 	{
 		/* Query the timers list to see if it contains any timers, and if so,
@@ -549,12 +560,12 @@ BaseType_t xListWasEmpty;
 }
 /*-----------------------------------------------------------*/
 
-static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, const BaseType_t xListWasEmpty )
+static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty )
 {
 TickType_t xTimeNow;
 BaseType_t xTimerListsWereSwitched;
 
-	vTaskSuspendAll();
+	taskENTER_CRITICAL( &xTimerMux);
 	{
 		/* Obtain the time now to make an assessment as to whether the timer
 		has expired or not.  If obtaining the time causes the lists to switch
@@ -567,7 +578,7 @@ BaseType_t xTimerListsWereSwitched;
 			/* The tick count has not overflowed, has the timer expired? */
 			if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) )
 			{
-				( void ) xTaskResumeAll();
+				taskEXIT_CRITICAL( &xTimerMux);
 				prvProcessExpiredTimer( xNextExpireTime, xTimeNow );
 			}
 			else
@@ -578,25 +589,28 @@ BaseType_t xTimerListsWereSwitched;
 				received - whichever comes first.  The following line cannot
 				be reached unless xNextExpireTime > xTimeNow, except in the
 				case when the current timer list is empty. */
-				vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ) );
-
-				if( xTaskResumeAll() == pdFALSE )
-				{
-					/* Yield to wait for either a command to arrive, or the
-					block time to expire.  If a command arrived between the
-					critical section being exited and this yield then the yield
-					will not cause the task to block. */
-					portYIELD_WITHIN_API();
-				}
-				else
+				if( xListWasEmpty != pdFALSE )
 				{
-					mtCOVERAGE_TEST_MARKER();
+					/* The current timer list is empty - is the overflow list
+					also empty? */
+					xListWasEmpty = listLIST_IS_EMPTY( pxOverflowTimerList );
 				}
+
+				vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ), xListWasEmpty );
+
+				taskEXIT_CRITICAL( &xTimerMux);
+				
+				/* Yield to wait for either a command to arrive, or the
+				block time to expire.  If a command arrived between the
+				critical section being exited and this yield then the yield
+				will not cause the task to block. */
+				portYIELD_WITHIN_API();
+				
 			}
 		}
 		else
 		{
-			( void ) xTaskResumeAll();
+			taskEXIT_CRITICAL( &xTimerMux);
 		}
 	}
 }
@@ -662,7 +676,7 @@ BaseType_t xProcessTimerNow = pdFALSE;
 	{
 		/* Has the expiry time elapsed between the command to start/reset a
 		timer was issued, and the time the command was processed? */
-		if( ( xTimeNow - xCommandTime ) >= pxTimer->xTimerPeriodInTicks )
+		if( ( ( TickType_t ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks ) /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
 		{
 			/* The time between a command being issued and the command being
 			processed actually exceeds the timers period.  */
@@ -731,7 +745,7 @@ TickType_t xTimeNow;
 			software timer. */
 			pxTimer = xMessage.u.xTimerParameters.pxTimer;
 
-			if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE )
+			if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) /*lint !e961. The cast is only redundant when NULL is passed into the macro. */
 			{
 				/* The timer is in a list, remove it. */
 				( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
@@ -754,19 +768,20 @@ TickType_t xTimeNow;
 			switch( xMessage.xMessageID )
 			{
 				case tmrCOMMAND_START :
-			    case tmrCOMMAND_START_FROM_ISR :
-			    case tmrCOMMAND_RESET :
-			    case tmrCOMMAND_RESET_FROM_ISR :
+				case tmrCOMMAND_START_FROM_ISR :
+				case tmrCOMMAND_RESET :
+				case tmrCOMMAND_RESET_FROM_ISR :
 				case tmrCOMMAND_START_DONT_TRACE :
 					/* Start or restart a timer. */
-					if( prvInsertTimerInActiveList( pxTimer,  xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) == pdTRUE )
+					pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE;
+					if( prvInsertTimerInActiveList( pxTimer,  xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) != pdFALSE )
 					{
 						/* The timer expired before it was added to the active
 						timer list.  Process it now. */
 						pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
 						traceTIMER_EXPIRED( pxTimer );
 
-						if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )
+						if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 )
 						{
 							xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY );
 							configASSERT( xResult );
@@ -785,48 +800,48 @@ TickType_t xTimeNow;
 
 				case tmrCOMMAND_STOP :
 				case tmrCOMMAND_STOP_FROM_ISR :
-					/* The timer has already been removed from the active list.
-					There is nothing to do here. */
+					/* The timer has already been removed from the active list. */
+					pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;
 					break;
 
 				case tmrCOMMAND_CHANGE_PERIOD :
 				case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR :
+					pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE;
 					pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue;
 					configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) );
 
-					/* The new period does not really have a reference, and can be
-					longer or shorter than the old one.  The command time is
-					therefore set to the current time, and as the period cannot be
-					zero the next expiry time can only be in the future, meaning
-					(unlike for the xTimerStart() case above) there is no fail case
-					that needs to be handled here. */
+					/* The new period does not really have a reference, and can
+					be longer or shorter than the old one.  The command time is
+					therefore set to the current time, and as the period cannot
+					be zero the next expiry time can only be in the future,
+					meaning (unlike for the xTimerStart() case above) there is
+					no fail case that needs to be handled here. */
 					( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow );
 					break;
 
 				case tmrCOMMAND_DELETE :
-					/* The timer has already been removed from the active list,
-					just free up the memory if the memory was dynamically
-					allocated. */
-					#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
+					#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
 					{
-						/* The timer can only have been allocated dynamically -
-						free it again. */
-						vPortFree( pxTimer );
-					}
-					#elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
-					{
-						/* The timer could have been allocated statically or
-						dynamically, so check before attempting to free the
-						memory. */
-						if( pxTimer->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
+						/* The timer has already been removed from the active list,
+						just free up the memory if the memory was dynamically
+						allocated. */
+						if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) 0 )
 						{
 							vPortFree( pxTimer );
 						}
 						else
 						{
-							mtCOVERAGE_TEST_MARKER();
+							pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;
 						}
 					}
+					#else
+					{
+						/* If dynamic allocation is not enabled, the memory
+						could not have been dynamically allocated. So there is
+						no need to free the memory - just mark the timer as
+						"not active". */
+						pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;
+					}
 					#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
 					break;
 
@@ -855,7 +870,7 @@ BaseType_t xResult;
 		xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );
 
 		/* Remove the timer from the list. */
-		pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );
+		pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks and co-routines too.  Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */
 		( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
 		traceTIMER_EXPIRED( pxTimer );
 
@@ -864,7 +879,7 @@ BaseType_t xResult;
 		have not yet been switched. */
 		pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
 
-		if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )
+		if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 )
 		{
 			/* Calculate the reload value, and if the reload value results in
 			the timer going into the same timer list then it has already expired
@@ -903,14 +918,10 @@ static void prvCheckForValidListAndQueue( void )
 	/* Check that the list from which active timers are referenced, and the
 	queue used to communicate with the timer service, have been
 	initialised. */
-
-	/* Erm, yes, this is a problem. We can't lock until the lock is initialized, and we can't initialize the lock
-	   atomically because we don't have a lock yet... I'm pretty sure doubly-initializing a lock on 2 cpus
-	   is no problem in the current implementation, but this is not a nice way to solve things. ToDo - improve. */
-
+	
 	if( xTimerQueue == NULL ) vPortCPUInitializeMutex( &xTimerMux );
 
-	taskENTER_CRITICAL( &xTimerMux );
+	taskENTER_CRITICAL( &xTimerMux);
 	{
 		if( xTimerQueue == NULL )
 		{
@@ -918,8 +929,21 @@ static void prvCheckForValidListAndQueue( void )
 			vListInitialise( &xActiveTimerList2 );
 			pxCurrentTimerList = &xActiveTimerList1;
 			pxOverflowTimerList = &xActiveTimerList2;
-			xTimerQueue = xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) );
-			configASSERT( xTimerQueue );
+
+			#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+			{
+				/* The timer queue is allocated statically in case
+				configSUPPORT_DYNAMIC_ALLOCATION is 0. */
+				static StaticQueue_t xStaticTimerQueue; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */
+				static uint8_t ucStaticTimerQueueStorage[ ( size_t ) configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ]; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */
+
+				xTimerQueue = xQueueCreateStatic( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, ( UBaseType_t ) sizeof( DaemonTaskMessage_t ), &( ucStaticTimerQueueStorage[ 0 ] ), &xStaticTimerQueue );
+			}
+			#else
+			{
+				xTimerQueue = xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) );
+			}
+			#endif
 
 			#if ( configQUEUE_REGISTRY_SIZE > 0 )
 			{
@@ -939,48 +963,63 @@ static void prvCheckForValidListAndQueue( void )
 			mtCOVERAGE_TEST_MARKER();
 		}
 	}
-	taskEXIT_CRITICAL( &xTimerMux );
+	taskEXIT_CRITICAL( &xTimerMux);
 }
 /*-----------------------------------------------------------*/
 
 BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer )
 {
-BaseType_t xTimerIsInActiveList;
-Timer_t *pxTimer = ( Timer_t * ) xTimer;
+BaseType_t xReturn;
+Timer_t *pxTimer = xTimer;
+
+	configASSERT( xTimer );
 
 	/* Is the timer in the list of active timers? */
-	taskENTER_CRITICAL( &xTimerMux );
+	taskENTER_CRITICAL( &xTimerMux);
 	{
-		/* Checking to see if it is in the NULL list in effect checks to see if
-		it is referenced from either the current or the overflow timer lists in
-		one go, but the logic has to be reversed, hence the '!'. */
-		xTimerIsInActiveList = ( BaseType_t ) !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) );
+		if( ( pxTimer->ucStatus & tmrSTATUS_IS_ACTIVE ) == 0 )
+		{
+			xReturn = pdFALSE;
+		}
+		else
+		{
+			xReturn = pdTRUE;
+		}
 	}
-	taskEXIT_CRITICAL( &xTimerMux );
+	taskEXIT_CRITICAL( &xTimerMux);
 
-	return xTimerIsInActiveList;
+	return xReturn;
 } /*lint !e818 Can't be pointer to const due to the typedef. */
 /*-----------------------------------------------------------*/
 
 void *pvTimerGetTimerID( const TimerHandle_t xTimer )
 {
-Timer_t * const pxTimer = ( Timer_t * ) xTimer;
+Timer_t * const pxTimer = xTimer;
+void *pvReturn;
 
-	return pxTimer->pvTimerID;
+	configASSERT( xTimer );
+
+	taskENTER_CRITICAL( &xTimerMux);
+	{
+		pvReturn = pxTimer->pvTimerID;
+	}
+	taskEXIT_CRITICAL( &xTimerMux);
+
+	return pvReturn;
 }
 /*-----------------------------------------------------------*/
 
 void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID )
 {
-Timer_t * const pxTimer = ( Timer_t * ) xTimer;
+Timer_t * const pxTimer = xTimer;
 
-    configASSERT( xTimer );
+	configASSERT( xTimer );
 
-    //taskENTER_CRITICAL();     //Atomic instruction, critical not necessary
-    //{
-        pxTimer->pvTimerID = pvNewID;
-    //}
-    //taskEXIT_CRITICAL();
+	taskENTER_CRITICAL( &xTimerMux);
+	{
+		pxTimer->pvTimerID = pvNewID;
+	}
+	taskEXIT_CRITICAL( &xTimerMux);
 }
 /*-----------------------------------------------------------*/
 
@@ -1037,6 +1076,26 @@ Timer_t * const pxTimer = ( Timer_t * ) xTimer;
 #endif /* INCLUDE_xTimerPendFunctionCall */
 /*-----------------------------------------------------------*/
 
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+	UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer )
+	{
+		return ( ( Timer_t * ) xTimer )->uxTimerNumber;
+	}
+
+#endif /* configUSE_TRACE_FACILITY */
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+	void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber )
+	{
+		( ( Timer_t * ) xTimer )->uxTimerNumber = uxTimerNumber;
+	}
+
+#endif /* configUSE_TRACE_FACILITY */
+/*-----------------------------------------------------------*/
+
 /* This entire source file will be skipped if the application is not configured
 to include software timer functionality.  If you want to include software timer
 functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */

+ 6 - 8
components/freertos/xtensa/include/freertos/FreeRTOSConfig.h

@@ -84,10 +84,10 @@
 #define portNUM_PROCESSORS 1
 #endif
 
-#define XT_USE_THREAD_SAFE_CLIB			0
-#define configASSERT_2	0
-#define portUSING_MPU_WRAPPERS 0
-#define configUSE_MUTEX 1
+#define XT_USE_THREAD_SAFE_CLIB		0
+#define configASSERT_2	            0
+#define portUSING_MPU_WRAPPERS      0
+#define configUSE_MUTEX             1
 #undef XT_USE_SWPRI
 
 #if CONFIG_FREERTOS_CORETIMER_0
@@ -96,7 +96,7 @@
 #define XT_TIMER_INDEX 1
 #endif
 
-#define configNUM_THREAD_LOCAL_STORAGE_POINTERS CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS
+#define configNUM_THREAD_LOCAL_STORAGE_POINTERS  CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS
 #define configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS 1
 
 #ifndef __ASSEMBLER__
@@ -171,7 +171,7 @@ int xt_clock_freq(void) __attribute__((deprecated));
 #define configUSE_PREEMPTION			1
 #define configUSE_IDLE_HOOK				1
 #define configUSE_TICK_HOOK				1
-
+#define configRECORD_STACK_HIGH_ADDRESS 1
 #define configTICK_RATE_HZ				( CONFIG_FREERTOS_HZ )
 
 /* Default clock rate for simulator */
@@ -256,8 +256,6 @@ int xt_clock_freq(void) __attribute__((deprecated));
 #endif
 
 
-
-
 /* Co-routine definitions. */
 #define configUSE_CO_ROUTINES 			0
 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

+ 108 - 29
components/freertos/xtensa/include/freertos/portmacro.h

@@ -72,6 +72,7 @@ extern "C" {
 
 #ifndef __ASSEMBLER__
 
+#include <sdkconfig.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <stdbool.h>
@@ -82,11 +83,16 @@ extern "C" {
 #include <xtensa/xtruntime.h>
 #include "esp_private/crosscore_int.h"
 #include "esp_timer.h"              /* required for FreeRTOS run time stats */
+#include "esp_system.h"
+#include "esp_newlib.h"
 #include "soc/spinlock.h"
 #include <esp_heap_caps.h>
 #include "esp_rom_sys.h"
 #include "sdkconfig.h"
 #include "freertos/xtensa_api.h"
+#include "esp_system.h"
+#include "soc/cpu.h"
+#include <limits.h>
 
 #ifdef CONFIG_LEGACY_INCLUDE_COMMON_HEADERS
 #include "soc/soc_memory_layout.h"
@@ -127,18 +133,10 @@ typedef unsigned portBASE_TYPE	UBaseType_t;
 
 // portbenchmark
 #include "portbenchmark.h"
+
 #include "sdkconfig.h"
 #include "esp_attr.h"
 
-static inline uint32_t xPortGetCoreID(void);
-
-// Critical section management. NW-TODO: replace XTOS_SET_INTLEVEL with more efficient version, if any?
-// These cannot be nested. They should be used with a lot of care and cannot be called from interrupt level.
-//
-// Only applies to one CPU. See notes above & below for reasons not to use these.
-#define portDISABLE_INTERRUPTS()      do { XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); portbenchmarkINTERRUPT_DISABLE(); } while (0)
-#define portENABLE_INTERRUPTS()       do { portbenchmarkINTERRUPT_RESTORE(0); XTOS_SET_INTLEVEL(0); } while (0)
-
 // Cleaner solution allows nested interrupts disabling and restoring via local registers or stack.
 // They can be called from interrupts too.
 // WARNING: Only applies to current CPU. See notes above.
@@ -172,48 +170,45 @@ This all assumes that interrupts are either entirely disabled or enabled. Interr
 will break this scheme.
 
 Remark: For the ESP32, portENTER_CRITICAL and portENTER_CRITICAL_ISR both alias vTaskEnterCritical, meaning
-that either function can be called both from ISR as well as task context. This is not standard FreeRTOS
+that either function can be called both from ISR as well as task context. This is not standard FreeRTOS 
 behaviour; please keep this in mind if you need any compatibility with other FreeRTOS implementations.
 */
-
 /* "mux" data structure (spinlock) */
-typedef struct {
-    spinlock_t spinlock;
-} portMUX_TYPE;
+typedef spinlock_t portMUX_TYPE;
 
 #define portMUX_FREE_VAL		SPINLOCK_FREE
 #define portMUX_NO_TIMEOUT      SPINLOCK_WAIT_FOREVER  /* When passed for 'timeout_cycles', spin forever if necessary */
 #define portMUX_TRY_LOCK        SPINLOCK_NO_WAIT       /* Try to acquire the spinlock a single time only */
-#define portMUX_INITIALIZER_UNLOCKED  {.spinlock=SPINLOCK_INITIALIZER} 
-
-#define portASSERT_IF_IN_ISR()        vPortAssertIfInISR()
-void vPortAssertIfInISR(void);
+#define portMUX_INITIALIZER_UNLOCKED  SPINLOCK_INITIALIZER 
 
 #define portCRITICAL_NESTING_IN_TCB 0
 
 static inline void __attribute__((always_inline)) vPortCPUInitializeMutex(portMUX_TYPE *mux) 
 {
-    spinlock_initialize(&mux->spinlock);
+    spinlock_initialize(mux);
 }
 
 static inline void __attribute__((always_inline)) vPortCPUAcquireMutex(portMUX_TYPE *mux) 
 {
-    spinlock_acquire(&mux->spinlock, portMUX_NO_TIMEOUT);
+    spinlock_acquire(mux, portMUX_NO_TIMEOUT);
 }
 
 static inline bool __attribute__((always_inline)) vPortCPUAcquireMutexTimeout(portMUX_TYPE *mux, int timeout) 
 {
-    return (spinlock_acquire(&mux->spinlock, timeout));
+    return (spinlock_acquire(mux, timeout));
 }
 
 static inline void __attribute__((always_inline)) vPortCPUReleaseMutex(portMUX_TYPE *mux)
 {
-    spinlock_release(&mux->spinlock);
+    spinlock_release(mux);
 }
 
 void vPortEnterCritical(portMUX_TYPE *mux);
 void vPortExitCritical(portMUX_TYPE *mux);
 
+#define portASSERT_IF_IN_ISR()  vPortAssertIfInISR()
+void vPortAssertIfInISR(void);
+
 /*
  * Returns true if the current core is in ISR context; low prio ISR, med prio ISR or timer tick ISR. High prio ISRs
  * aren't detected here, but they normally cannot call C code, so that should not be an issue anyway.
@@ -246,8 +241,8 @@ static inline void __attribute__((always_inline)) vPortExitCriticalCompliance(po
 /* Calling port*_CRITICAL from ISR context would cause an assert failure.
  * If the parent function is called from both ISR and Non-ISR context then call port*_CRITICAL_SAFE
  */
-#define portENTER_CRITICAL(mux)  vPortEnterCriticalCompliance(mux)   
-#define portEXIT_CRITICAL(mux)   vPortExitCriticalCompliance(mux)     
+#define portENTER_CRITICAL(mux)        vPortEnterCriticalCompliance(mux)
+#define portEXIT_CRITICAL(mux)         vPortExitCriticalCompliance(mux) 
 #else
 #define portENTER_CRITICAL(mux)        vPortEnterCritical(mux)
 #define portEXIT_CRITICAL(mux)         vPortExitCritical(mux)
@@ -276,6 +271,7 @@ static inline void __attribute__((always_inline)) vPortExitCriticalSafe(portMUX_
 
 #define portENTER_CRITICAL_SAFE(mux)  vPortEnterCriticalSafe(mux)
 #define portEXIT_CRITICAL_SAFE(mux)  vPortExitCriticalSafe(mux)
+
 /*
  * Wrapper for the Xtensa compare-and-set instruction. This subroutine will atomically compare
  * *addr to 'compare'. If *addr == compare, *addr is set to *set. *set is updated with the previous
@@ -289,6 +285,14 @@ static inline void __attribute__((always_inline)) uxPortCompareSet(volatile uint
     compare_and_set_native(addr, compare, set);
 }
 
+// Critical section management. NW-TODO: replace XTOS_SET_INTLEVEL with more efficient version, if any?
+// These cannot be nested. They should be used with a lot of care and cannot be called from interrupt level.
+//
+// Only applies to one CPU. See notes above & below for reasons not to use these.
+#define portDISABLE_INTERRUPTS()      do { XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); portbenchmarkINTERRUPT_DISABLE(); } while (0)
+#define portENABLE_INTERRUPTS()       do { portbenchmarkINTERRUPT_RESTORE(0); XTOS_SET_INTLEVEL(0); } while (0)
+
+
 // These FreeRTOS versions are similar to the nested versions above
 #define portSET_INTERRUPT_MASK_FROM_ISR()            portENTER_CRITICAL_NESTED()
 #define portCLEAR_INTERRUPT_MASK_FROM_ISR(state)     portEXIT_CRITICAL_NESTED(state)
@@ -297,10 +301,26 @@ static inline void __attribute__((always_inline)) uxPortCompareSet(volatile uint
 //the stack memory to always be internal.
 #define portTcbMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)
 #define portStackMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)
-
 #define pvPortMallocTcbMem(size) heap_caps_malloc(size, portTcbMemoryCaps)
 #define pvPortMallocStackMem(size)  heap_caps_malloc(size, portStackMemoryCaps)
 
+//xTaskCreateStatic uses these functions to check incoming memory.
+#define portVALID_TCB_MEM(ptr) (esp_ptr_internal(ptr) && esp_ptr_byte_accessible(ptr))
+#ifdef CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
+#define portVALID_STACK_MEM(ptr) esp_ptr_byte_accessible(ptr)
+#else
+#define portVALID_STACK_MEM(ptr) (esp_ptr_internal(ptr) && esp_ptr_byte_accessible(ptr))
+#endif
+
+
+static inline void uxPortCompareSetExtram(volatile uint32_t *addr, uint32_t compare, uint32_t *set) 
+{
+#ifdef CONFIG_SPIRAM   
+    compare_and_set_extram(addr, compare, set);
+#endif    
+}
+
+
 /*-----------------------------------------------------------*/
 
 /* Architecture specifics. */
@@ -397,13 +417,11 @@ extern void esp_vApplicationTickHook( void );
 #define vApplicationTickHook    esp_vApplicationTickHook
 #endif /* !CONFIG_FREERTOS_LEGACY_HOOKS */
 
-void _xt_coproc_release(volatile void * coproc_sa_base);
 void vApplicationSleep( TickType_t xExpectedIdleTime );
-void vPortSetStackWatchpoint( void* pxStackStart );
 
 #define portSUPPRESS_TICKS_AND_SLEEP( idleTime ) vApplicationSleep( idleTime )
 
-/*-----------------------------------------------------------*/
+void _xt_coproc_release(volatile void * coproc_sa_base);
 
 /* Architecture specific optimisations. */
 #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
@@ -423,7 +441,68 @@ void vPortSetStackWatchpoint( void* pxStackStart );
 
 #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
 
-/*-----------------------------------------------------------*/
+/*
+ * Send an interrupt to another core in order to make the task running
+ * on it yield for a higher-priority task.
+ */
+
+void vPortYieldOtherCore( BaseType_t coreid) ;
+
+/*
+ Callback to set a watchpoint on the end of the stack. Called every context switch to change the stack
+ watchpoint around.
+ */
+void vPortSetStackWatchpoint( void* pxStackStart );
+
+/*
+ * Returns true if the current core is in ISR context; low prio ISR, med prio ISR or timer tick ISR. High prio ISRs
+ * aren't detected here, but they normally cannot call C code, so that should not be an issue anyway.
+ */
+BaseType_t xPortInIsrContext(void);
+
+/*
+ * This function will be called in High prio ISRs. Returns true if the current core was in ISR context
+ * before calling into high prio ISR context.
+ */
+BaseType_t xPortInterruptedFromISRContext(void);
+
+/*
+ * The structures and methods of manipulating the MPU are contained within the
+ * port layer.
+ *
+ * Fills the xMPUSettings structure with the memory region information
+ * contained in xRegions.
+ */
+#if( portUSING_MPU_WRAPPERS == 1 )
+    struct xMEMORY_REGION;
+    void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t usStackDepth ) PRIVILEGED_FUNCTION;
+    void vPortReleaseTaskMPUSettings( xMPU_SETTINGS *xMPUSettings );
+#endif
+
+/* Multi-core: get current core ID */
+static inline uint32_t IRAM_ATTR xPortGetCoreID(void) {
+    return cpu_hal_get_core_id();
+}
+
+/* Get tick rate per second */
+uint32_t xPortGetTickRateHz(void);
+
+static inline bool IRAM_ATTR xPortCanYield(void)
+{
+    uint32_t ps_reg = 0;
+
+    //Get the current value of PS (processor status) register
+    RSR(PS, ps_reg);
+
+    /*
+     * intlevel = (ps_reg & 0xf);
+     * excm  = (ps_reg >> 4) & 0x1;
+     * CINTLEVEL is max(excm * EXCMLEVEL, INTLEVEL), where EXCMLEVEL is 3.
+     * However, just return true, only intlevel is zero.
+     */
+
+    return ((ps_reg & PS_INTLEVEL_MASK) == 0);
+}
 
 // porttrace
 #if configUSE_TRACE_FACILITY_2

+ 1 - 1
components/freertos/xtensa/include/freertos/xtensa_context.h

@@ -1,2 +1,2 @@
 /* This header file has been moved, please include <xtensa/xtensa_context.h> in future */ 
-#include <xtensa/xtensa_context.h>
+#include <xtensa/xtensa_context.h>

+ 2 - 2
components/freertos/xtensa/port.c

@@ -109,7 +109,6 @@
 #include "esp_intr_alloc.h"
 #include "esp_log.h"
 #include "sdkconfig.h"
-#include "esp_compiler.h"
 
 #include "esp_task_wdt.h"
 #include "esp_task.h"
@@ -290,6 +289,7 @@ void vPortEndScheduler( void )
 {
 	/* It is unlikely that the Xtensa port will get stopped.  If required simply
 	disable the tick interrupt here. */
+	abort();
 }
 
 /*-----------------------------------------------------------*/
@@ -619,4 +619,4 @@ void esp_startup_start_app(void)
 
 	ESP_LOGI(TAG, "Starting scheduler on PRO CPU.");
 	vTaskStartScheduler();
-}
+}

+ 2 - 1
components/heap/CMakeLists.txt

@@ -1,7 +1,8 @@
 set(srcs 
     "heap_caps.c"
     "heap_caps_init.c"
-    "multi_heap.c")
+    "multi_heap.c"
+    "heap_tlsf.c")
 
 if(NOT CONFIG_HEAP_POISONING_DISABLED)
     list(APPEND srcs "multi_heap_poisoning.c")

+ 1 - 1
components/heap/component.mk

@@ -2,7 +2,7 @@
 # Component Makefile
 #
 
-COMPONENT_OBJS := heap_caps_init.o heap_caps.o multi_heap.o
+COMPONENT_OBJS := heap_caps_init.o heap_caps.o multi_heap.o heap_tlsf.o
 
 ifndef CONFIG_HEAP_POISONING_DISABLED
 COMPONENT_OBJS += multi_heap_poisoning.o

+ 6 - 12
components/heap/heap_caps.c

@@ -598,6 +598,11 @@ IRAM_ATTR void *heap_caps_aligned_alloc(size_t alignment, size_t size, int caps)
     return NULL;
 }
 
+IRAM_ATTR void heap_caps_aligned_free(void *ptr)
+{
+    heap_caps_free(ptr);
+}
+
 void *heap_caps_aligned_calloc(size_t alignment, size_t n, size_t size, uint32_t caps)
 {    
     size_t size_bytes;
@@ -611,15 +616,4 @@ void *heap_caps_aligned_calloc(size_t alignment, size_t n, size_t size, uint32_t
     }
 
     return ptr;
-}
-
-IRAM_ATTR void heap_caps_aligned_free(void *ptr)
-{
-    if (ptr == NULL) {
-        return;
-    }
-
-    heap_t *heap = find_containing_heap(ptr);
-    assert(heap != NULL && "free() target pointer is outside heap areas");
-    multi_heap_aligned_free(heap->heap, ptr);
-}
+}

+ 867 - 0
components/heap/heap_tlsf.c

@@ -0,0 +1,867 @@
+/*
+** Two Level Segregated Fit memory allocator, version 3.1.
+** Written by Matthew Conte
+**	http://tlsf.baisoku.org
+**
+** Based on the original documentation by Miguel Masmano:
+**	http://www.gii.upv.es/tlsf/main/docs
+**
+** This implementation was written to the specification
+** of the document, therefore no GPL restrictions apply.
+** 
+** Copyright (c) 2006-2016, Matthew Conte
+** All rights reserved.
+** 
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**     * Redistributions of source code must retain the above copyright
+**       notice, this list of conditions and the following disclaimer.
+**     * Redistributions in binary form must reproduce the above copyright
+**       notice, this list of conditions and the following disclaimer in the
+**       documentation and/or other materials provided with the distribution.
+**     * Neither the name of the copyright holder nor the
+**       names of its contributors may be used to endorse or promote products
+**       derived from this software without specific prior written permission.
+** 
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL MATTHEW CONTE BE LIABLE FOR ANY
+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#include "multi_heap_config.h"
+#include "multi_heap.h"
+#include "multi_heap_internal.h"
+#include "heap_tlsf.h"
+
+/*
+** Architecture-specific bit manipulation routines.
+**
+** TLSF achieves O(1) cost for malloc and free operations by limiting
+** the search for a free block to a free list of guaranteed size
+** adequate to fulfill the request, combined with efficient free list
+** queries using bitmasks and architecture-specific bit-manipulation
+** routines.
+**
+** Most modern processors provide instructions to count leading zeroes
+** in a word, find the lowest and highest set bit, etc. These
+** specific implementations will be used when available, falling back
+** to a reasonably efficient generic implementation.
+**
+** NOTE: TLSF spec relies on ffs/fls returning value 0..31.
+** ffs/fls return 1-32 by default, returning 0 for error.
+*/
+static inline __attribute__((__always_inline__)) int tlsf_ffs(unsigned int word)
+{
+	const unsigned int reverse = word & (~word + 1);
+	const int bit = 32 - __builtin_clz(reverse);
+	return bit - 1;
+}
+
+static inline __attribute__((__always_inline__)) int tlsf_fls(unsigned int word)
+{
+	const int bit = word ? 32 - __builtin_clz(word) : 0;
+	return bit - 1;
+}
+
+/*
+** Set assert macro, if it has not been provided by the user.
+*/
+#if !defined (tlsf_assert)
+#define tlsf_assert assert
+#endif
+
+/*
+** Static assertion mechanism.
+*/
+#define _tlsf_glue2(x, y) x ## y
+#define _tlsf_glue(x, y) _tlsf_glue2(x, y)
+#define tlsf_static_assert(exp) \
+	typedef char _tlsf_glue(static_assert, __LINE__) [(exp) ? 1 : -1]
+
+/* This code has been tested on 32- and 64-bit (LP/LLP) architectures. */
+tlsf_static_assert(sizeof(int) * CHAR_BIT == 32);
+tlsf_static_assert(sizeof(size_t) * CHAR_BIT >= 32);
+tlsf_static_assert(sizeof(size_t) * CHAR_BIT <= 64);
+
+/* SL_INDEX_COUNT must be <= number of bits in sl_bitmap's storage type. */
+tlsf_static_assert(sizeof(unsigned int) * CHAR_BIT >= SL_INDEX_COUNT);
+
+/* Ensure we've properly tuned our sizes. */
+tlsf_static_assert(ALIGN_SIZE == SMALL_BLOCK_SIZE / SL_INDEX_COUNT);
+
+static inline __attribute__((__always_inline__)) size_t align_up(size_t x, size_t align)
+{
+	tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two");
+	return (x + (align - 1)) & ~(align - 1);
+}
+
+static inline __attribute__((__always_inline__)) size_t align_down(size_t x, size_t align)
+{
+	tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two");
+	return x - (x & (align - 1));
+}
+
+static inline __attribute__((__always_inline__)) void* align_ptr(const void* ptr, size_t align)
+{
+	const tlsfptr_t aligned =
+		(tlsf_cast(tlsfptr_t, ptr) + (align - 1)) & ~(align - 1);
+	tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two");
+	return tlsf_cast(void*, aligned);
+}
+
+/*
+** Adjust an allocation size to be aligned to word size, and no smaller
+** than internal minimum.
+*/
+static inline __attribute__((__always_inline__)) size_t adjust_request_size(size_t size, size_t align)
+{
+	size_t adjust = 0;
+	if (size)
+	{
+		const size_t aligned = align_up(size, align);
+
+		/* aligned sized must not exceed block_size_max or we'll go out of bounds on sl_bitmap */
+		if (aligned < block_size_max) 
+		{
+			adjust = tlsf_max(aligned, block_size_min);
+		}
+	}
+	return adjust;
+}
+
+/*
+** TLSF utility functions. In most cases, these are direct translations of
+** the documentation found in the white paper.
+*/
+
+static inline __attribute__((__always_inline__)) void mapping_insert(size_t size, int* fli, int* sli)
+{
+	int fl, sl;
+	if (size < SMALL_BLOCK_SIZE)
+	{
+		/* Store small blocks in first list. */
+		fl = 0;
+		sl = tlsf_cast(int, size) >> 2;
+	}
+	else
+	{
+		fl = tlsf_fls(size);
+		sl = tlsf_cast(int, size >> (fl - SL_INDEX_COUNT_LOG2)) ^ (1 << SL_INDEX_COUNT_LOG2);
+		fl -= (FL_INDEX_SHIFT - 1);
+	}
+	*fli = fl;
+	*sli = sl;
+}
+
+/* This version rounds up to the next block size (for allocations) */
+static inline __attribute__((__always_inline__)) void mapping_search(size_t size, int* fli, int* sli)
+{
+	if (size >= SMALL_BLOCK_SIZE)
+	{
+		const size_t round = (1 << (tlsf_fls(size) - SL_INDEX_COUNT_LOG2)) - 1;
+		size += round;
+	}
+	mapping_insert(size, fli, sli);
+}
+
+static inline __attribute__((__always_inline__)) block_header_t* search_suitable_block(control_t* control, int* fli, int* sli)
+{
+	int fl = *fli;
+	int sl = *sli;
+
+	/*
+	** First, search for a block in the list associated with the given
+	** fl/sl index.
+	*/
+	unsigned int sl_map = control->sl_bitmap[fl] & (~0U << sl);
+	if (!sl_map)
+	{
+		/* No block exists. Search in the next largest first-level list. */
+		const unsigned int fl_map = control->fl_bitmap & (~0U << (fl + 1));
+		if (!fl_map)
+		{
+			/* No free blocks available, memory has been exhausted. */
+			return 0;
+		}
+
+		fl = tlsf_ffs(fl_map);
+		*fli = fl;
+		sl_map = control->sl_bitmap[fl];
+	}
+	tlsf_assert(sl_map && "internal error - second level bitmap is null");
+	sl = tlsf_ffs(sl_map);
+	*sli = sl;
+
+	/* Return the first block in the free list. */
+	return control->blocks[fl][sl];
+}
+
+/* Remove a free block from the free list.*/
+static inline __attribute__((__always_inline__)) void remove_free_block(control_t* control, block_header_t* block, int fl, int sl)
+{
+	block_header_t* prev = block->prev_free;
+	block_header_t* next = block->next_free;
+	tlsf_assert(prev && "prev_free field can not be null");
+	tlsf_assert(next && "next_free field can not be null");
+	next->prev_free = prev;
+	prev->next_free = next;
+
+	/* If this block is the head of the free list, set new head. */
+	if (control->blocks[fl][sl] == block)
+	{
+		control->blocks[fl][sl] = next;
+
+		/* If the new head is null, clear the bitmap. */
+		if (next == &control->block_null)
+		{
+			control->sl_bitmap[fl] &= ~(1 << sl);
+
+			/* If the second bitmap is now empty, clear the fl bitmap. */
+			if (!control->sl_bitmap[fl])
+			{
+				control->fl_bitmap &= ~(1 << fl);
+			}
+		}
+	}
+}
+
+/* Insert a free block into the free block list. */
+static inline __attribute__((__always_inline__)) void insert_free_block(control_t* control, block_header_t* block, int fl, int sl)
+{
+	block_header_t* current = control->blocks[fl][sl];
+	tlsf_assert(current && "free list cannot have a null entry");
+	tlsf_assert(block && "cannot insert a null entry into the free list");
+	block->next_free = current;
+	block->prev_free = &control->block_null;
+	current->prev_free = block;
+
+	tlsf_assert(block_to_ptr(block) == align_ptr(block_to_ptr(block), ALIGN_SIZE)
+		&& "block not aligned properly");
+	/*
+	** Insert the new block at the head of the list, and mark the first-
+	** and second-level bitmaps appropriately.
+	*/
+	control->blocks[fl][sl] = block;
+	control->fl_bitmap |= (1 << fl);
+	control->sl_bitmap[fl] |= (1 << sl);
+}
+
+/* Remove a given block from the free list. */
+static inline __attribute__((__always_inline__)) void block_remove(control_t* control, block_header_t* block)
+{
+	int fl, sl;
+	mapping_insert(block_size(block), &fl, &sl);
+	remove_free_block(control, block, fl, sl);
+}
+
+/* Insert a given block into the free list. */
+static inline __attribute__((__always_inline__)) void block_insert(control_t* control, block_header_t* block)
+{
+	int fl, sl;
+	mapping_insert(block_size(block), &fl, &sl);
+	insert_free_block(control, block, fl, sl);
+}
+
+static inline __attribute__((__always_inline__)) int block_can_split(block_header_t* block, size_t size)
+{
+	return block_size(block) >= sizeof(block_header_t) + size;
+}
+
+/* Split a block into two, the second of which is free. */
+static inline __attribute__((__always_inline__)) block_header_t* block_split(block_header_t* block, size_t size)
+{
+	/* Calculate the amount of space left in the remaining block. */
+	block_header_t* remaining =
+		offset_to_block(block_to_ptr(block), size - block_header_overhead);
+
+	const size_t remain_size = block_size(block) - (size + block_header_overhead);
+
+	tlsf_assert(block_to_ptr(remaining) == align_ptr(block_to_ptr(remaining), ALIGN_SIZE)
+		&& "remaining block not aligned properly");
+
+	tlsf_assert(block_size(block) == remain_size + size + block_header_overhead);
+	block_set_size(remaining, remain_size);
+	tlsf_assert(block_size(remaining) >= block_size_min && "block split with invalid size");
+
+	block_set_size(block, size);
+	block_mark_as_free(remaining);
+
+	return remaining;
+}
+
+/* Absorb a free block's storage into an adjacent previous free block. */
+static inline __attribute__((__always_inline__)) block_header_t* block_absorb(block_header_t* prev, block_header_t* block)
+{
+	tlsf_assert(!block_is_last(prev) && "previous block can't be last");
+	/* Note: Leaves flags untouched. */
+	prev->size += block_size(block) + block_header_overhead;
+	block_link_next(prev);
+
+#ifdef MULTI_HEAP_POISONING_SLOW
+        /* next_block header needs to be replaced with a fill pattern */
+        multi_heap_internal_poison_fill_region(block, sizeof(block_header_t), true /* free */);
+#endif
+
+	return prev;
+}
+
+/* Merge a just-freed block with an adjacent previous free block. */
+static inline __attribute__((__always_inline__)) block_header_t* block_merge_prev(control_t* control, block_header_t* block)
+{
+	if (block_is_prev_free(block))
+	{
+		block_header_t* prev = block_prev(block);
+		tlsf_assert(prev && "prev physical block can't be null");
+		tlsf_assert(block_is_free(prev) && "prev block is not free though marked as such");
+		block_remove(control, prev);
+		block = block_absorb(prev, block);
+	}
+
+	return block;
+}
+
+/* Merge a just-freed block with an adjacent free block. */
+static inline __attribute__((__always_inline__)) block_header_t* block_merge_next(control_t* control, block_header_t* block)
+{
+	block_header_t* next = block_next(block);
+	tlsf_assert(next && "next physical block can't be null");
+
+	if (block_is_free(next))
+	{
+		tlsf_assert(!block_is_last(block) && "previous block can't be last");
+		block_remove(control, next);
+		block = block_absorb(block, next);
+	}
+
+	return block;
+}
+
+/* Trim any trailing block space off the end of a block, return to pool. */
+static inline __attribute__((__always_inline__)) void block_trim_free(control_t* control, block_header_t* block, size_t size)
+{
+	tlsf_assert(block_is_free(block) && "block must be free");
+	if (block_can_split(block, size))
+	{
+		block_header_t* remaining_block = block_split(block, size);
+		block_link_next(block);
+		block_set_prev_free(remaining_block);
+		block_insert(control, remaining_block);
+	}
+}
+
+/* Trim any trailing block space off the end of a used block, return to pool. */
+static inline __attribute__((__always_inline__)) void block_trim_used(control_t* control, block_header_t* block, size_t size)
+{
+	tlsf_assert(!block_is_free(block) && "block must be used");
+	if (block_can_split(block, size))
+	{
+		/* If the next block is free, we must coalesce. */
+		block_header_t* remaining_block = block_split(block, size);
+		block_set_prev_used(remaining_block);
+
+		remaining_block = block_merge_next(control, remaining_block);
+		block_insert(control, remaining_block);
+	}
+}
+
+static inline __attribute__((__always_inline__)) block_header_t* block_trim_free_leading(control_t* control, block_header_t* block, size_t size)
+{
+	block_header_t* remaining_block = block;
+	if (block_can_split(block, size))
+	{
+		/* We want the 2nd block. */
+		remaining_block = block_split(block, size - block_header_overhead);
+		block_set_prev_free(remaining_block);
+
+		block_link_next(block);
+		block_insert(control, block);
+	}
+
+	return remaining_block;
+}
+
+static inline  __attribute__((__always_inline__)) block_header_t* block_locate_free(control_t* control, size_t size)
+{
+	int fl = 0, sl = 0;
+	block_header_t* block = 0;
+
+	if (size)
+	{
+		mapping_search(size, &fl, &sl);
+		
+		/*
+		** mapping_search can futz with the size, so for excessively large sizes it can sometimes wind up 
+		** with indices that are off the end of the block array.
+		** So, we protect against that here, since this is the only callsite of mapping_search.
+		** Note that we don't need to check sl, since it comes from a modulo operation that guarantees it's always in range.
+		*/
+		if (fl < FL_INDEX_COUNT)
+		{
+			block = search_suitable_block(control, &fl, &sl);
+		}
+	}
+
+	if (block)
+	{
+		tlsf_assert(block_size(block) >= size);
+		remove_free_block(control, block, fl, sl);
+	}
+
+	return block;
+}
+
+static inline __attribute__((__always_inline__)) void* block_prepare_used(control_t* control, block_header_t* block, size_t size)
+{
+	void* p = 0;
+	if (block)
+	{
+		tlsf_assert(size && "size must be non-zero");
+		block_trim_free(control, block, size);
+		block_mark_as_used(block);
+		p = block_to_ptr(block);
+	}
+	return p;
+}
+
+/* Clear structure and point all empty lists at the null block. */
+static void control_construct(control_t* control)
+{
+	int i, j;
+
+	control->block_null.next_free = &control->block_null;
+	control->block_null.prev_free = &control->block_null;
+
+	control->fl_bitmap = 0;
+	for (i = 0; i < FL_INDEX_COUNT; ++i)
+	{
+		control->sl_bitmap[i] = 0;
+		for (j = 0; j < SL_INDEX_COUNT; ++j)
+		{
+			control->blocks[i][j] = &control->block_null;
+		}
+	}
+}
+
+/*
+** Debugging utilities.
+*/
+
+typedef struct integrity_t
+{
+	int prev_status;
+	int status;
+} integrity_t;
+
+#define tlsf_insist(x) { tlsf_assert(x); if (!(x)) { status--; } }
+
+static void integrity_walker(void* ptr, size_t size, int used, void* user)
+{
+	block_header_t* block = block_from_ptr(ptr);
+	integrity_t* integ = tlsf_cast(integrity_t*, user);
+	const int this_prev_status = block_is_prev_free(block) ? 1 : 0;
+	const int this_status = block_is_free(block) ? 1 : 0;
+	const size_t this_block_size = block_size(block);
+
+	int status = 0;
+	(void)used;
+	tlsf_insist(integ->prev_status == this_prev_status && "prev status incorrect");
+	tlsf_insist(size == this_block_size && "block size incorrect");
+
+	integ->prev_status = this_status;
+	integ->status += status;
+}
+
+int tlsf_check(tlsf_t tlsf)
+{
+	int i, j;
+
+	control_t* control = tlsf_cast(control_t*, tlsf);
+	int status = 0;
+
+	/* Check that the free lists and bitmaps are accurate. */
+	for (i = 0; i < FL_INDEX_COUNT; ++i)
+	{
+		for (j = 0; j < SL_INDEX_COUNT; ++j)
+		{
+			const int fl_map = control->fl_bitmap & (1 << i);
+			const int sl_list = control->sl_bitmap[i];
+			const int sl_map = sl_list & (1 << j);
+			const block_header_t* block = control->blocks[i][j];
+
+			/* Check that first- and second-level lists agree. */
+			if (!fl_map)
+			{
+				tlsf_insist(!sl_map && "second-level map must be null");
+			}
+
+			if (!sl_map)
+			{
+				tlsf_insist(block == &control->block_null && "block list must be null");
+				continue;
+			}
+
+			/* Check that there is at least one free block. */
+			tlsf_insist(sl_list && "no free blocks in second-level map");
+			tlsf_insist(block != &control->block_null && "block should not be null");
+
+			while (block != &control->block_null)
+			{
+				int fli, sli;
+				tlsf_insist(block_is_free(block) && "block should be free");
+				tlsf_insist(!block_is_prev_free(block) && "blocks should have coalesced");
+				tlsf_insist(!block_is_free(block_next(block)) && "blocks should have coalesced");
+				tlsf_insist(block_is_prev_free(block_next(block)) && "block should be free");
+				tlsf_insist(block_size(block) >= block_size_min && "block not minimum size");
+
+				mapping_insert(block_size(block), &fli, &sli);
+				tlsf_insist(fli == i && sli == j && "block size indexed in wrong list");
+				block = block->next_free;
+			}
+		}
+	}
+
+	return status;
+}
+
+#undef tlsf_insist
+
+static void default_walker(void* ptr, size_t size, int used, void* user)
+{
+	(void)user;
+	printf("\t%p %s size: %x (%p)\n", ptr, used ? "used" : "free", (unsigned int)size, block_from_ptr(ptr));
+}
+
+void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user)
+{
+	tlsf_walker pool_walker = walker ? walker : default_walker;
+	block_header_t* block =
+		offset_to_block(pool, -(int)block_header_overhead);
+
+	while (block && !block_is_last(block))
+	{
+		pool_walker(
+			block_to_ptr(block),
+			block_size(block),
+			!block_is_free(block),
+			user);
+		block = block_next(block);
+	}
+}
+
+size_t tlsf_block_size(void* ptr)
+{
+	size_t size = 0;
+	if (ptr)
+	{
+		const block_header_t* block = block_from_ptr(ptr);
+		size = block_size(block);
+	}
+	return size;
+}
+
+int tlsf_check_pool(pool_t pool)
+{
+	/* Check that the blocks are physically correct. */
+	integrity_t integ = { 0, 0 };
+	tlsf_walk_pool(pool, integrity_walker, &integ);
+
+	return integ.status;
+}
+
+/*
+** Size of the TLSF structures in a given memory block passed to
+** tlsf_create, equal to the size of a control_t
+*/
+size_t tlsf_size(void)
+{
+	return sizeof(control_t);
+}
+
+size_t tlsf_align_size(void)
+{
+	return ALIGN_SIZE;
+}
+
+size_t tlsf_block_size_min(void)
+{
+	return block_size_min;
+}
+
+size_t tlsf_block_size_max(void)
+{
+	return block_size_max;
+}
+
+/*
+** Overhead of the TLSF structures in a given memory block passed to
+** tlsf_add_pool, equal to the overhead of a free block and the
+** sentinel block.
+*/
+size_t tlsf_pool_overhead(void)
+{
+	return 2 * block_header_overhead;
+}
+
+size_t tlsf_alloc_overhead(void)
+{
+	return block_header_overhead;
+}
+
+pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes)
+{
+	block_header_t* block;
+	block_header_t* next;
+
+	const size_t pool_overhead = tlsf_pool_overhead();
+	const size_t pool_bytes = align_down(bytes - pool_overhead, ALIGN_SIZE);
+
+	if (((ptrdiff_t)mem % ALIGN_SIZE) != 0)
+	{
+		printf("tlsf_add_pool: Memory must be aligned by %u bytes.\n",
+			(unsigned int)ALIGN_SIZE);
+		return 0;
+	}
+
+	if (pool_bytes < block_size_min || pool_bytes > block_size_max)
+	{
+#if defined (TLSF_64BIT)
+		printf("tlsf_add_pool: Memory size must be between 0x%x and 0x%x00 bytes.\n", 
+			(unsigned int)(pool_overhead + block_size_min),
+			(unsigned int)((pool_overhead + block_size_max) / 256));
+#else
+		printf("tlsf_add_pool: Memory size must be between %u and %u bytes.\n", 
+			(unsigned int)(pool_overhead + block_size_min),
+			(unsigned int)(pool_overhead + block_size_max));
+#endif
+		return 0;
+	}
+
+	/*
+	** Create the main free block. Offset the start of the block slightly
+	** so that the prev_phys_block field falls outside of the pool -
+	** it will never be used.
+	*/
+	block = offset_to_block(mem, -(tlsfptr_t)block_header_overhead);
+	block_set_size(block, pool_bytes);
+	block_set_free(block);
+	block_set_prev_used(block);
+	block_insert(tlsf_cast(control_t*, tlsf), block);
+
+	/* Split the block to create a zero-size sentinel block. */
+	next = block_link_next(block);
+	block_set_size(next, 0);
+	block_set_used(next);
+	block_set_prev_free(next);
+
+	return mem;
+}
+
+void tlsf_remove_pool(tlsf_t tlsf, pool_t pool)
+{
+	control_t* control = tlsf_cast(control_t*, tlsf);
+	block_header_t* block = offset_to_block(pool, -(int)block_header_overhead);
+
+	int fl = 0, sl = 0;
+
+	tlsf_assert(block_is_free(block) && "block should be free");
+	tlsf_assert(!block_is_free(block_next(block)) && "next block should not be free");
+	tlsf_assert(block_size(block_next(block)) == 0 && "next block size should be zero");
+
+	mapping_insert(block_size(block), &fl, &sl);
+	remove_free_block(control, block, fl, sl);
+}
+
+/*
+** TLSF main interface.
+*/
+
+
+tlsf_t tlsf_create(void* mem)
+{
+#if _DEBUG
+	if (test_ffs_fls())
+	{
+		return 0;
+	}
+#endif
+
+	if (((tlsfptr_t)mem % ALIGN_SIZE) != 0)
+	{
+		printf("tlsf_create: Memory must be aligned to %u bytes.\n",
+			(unsigned int)ALIGN_SIZE);
+		return 0;
+	}
+
+	control_construct(tlsf_cast(control_t*, mem));
+
+	return tlsf_cast(tlsf_t, mem);
+}
+
+pool_t tlsf_get_pool(tlsf_t tlsf)
+{
+	return tlsf_cast(pool_t, (char*)tlsf + tlsf_size());
+}
+
+tlsf_t tlsf_create_with_pool(void* mem, size_t bytes)
+{
+	tlsf_t tlsf = tlsf_create(mem);
+	tlsf_add_pool(tlsf, (char*)mem + tlsf_size(), bytes - tlsf_size());
+	return tlsf;
+}
+
+void* tlsf_malloc(tlsf_t tlsf, size_t size)
+{
+	control_t* control = tlsf_cast(control_t*, tlsf);
+	size_t adjust = adjust_request_size(size, ALIGN_SIZE);
+	block_header_t* block = block_locate_free(control, adjust);
+	return block_prepare_used(control, block, adjust);
+}
+
+void* tlsf_memalign(tlsf_t tlsf, size_t align, size_t size)
+{
+	control_t* control = tlsf_cast(control_t*, tlsf);
+	const size_t adjust = adjust_request_size(size, ALIGN_SIZE);
+
+	/*
+	** We must allocate an additional minimum block size bytes so that if
+	** our free block will leave an alignment gap which is smaller, we can
+	** trim a leading free block and release it back to the pool. We must
+	** do this because the previous physical block is in use, therefore
+	** the prev_phys_block field is not valid, and we can't simply adjust
+	** the size of that block.
+	*/
+	const size_t gap_minimum = sizeof(block_header_t);
+	const size_t size_with_gap = adjust_request_size(adjust + align + gap_minimum, align);
+
+	/*
+	** If alignment is less than or equals base alignment, we're done.
+	** If we requested 0 bytes, return null, as tlsf_malloc(0) does.
+	*/
+	const size_t aligned_size = (adjust && align > ALIGN_SIZE) ? size_with_gap : adjust;
+
+	block_header_t* block = block_locate_free(control, aligned_size);
+
+	/* This can't be a static assert. */
+	tlsf_assert(sizeof(block_header_t) == block_size_min + block_header_overhead);
+
+	if (block)
+	{
+		void* ptr = block_to_ptr(block);
+		void* aligned = align_ptr(ptr, align);
+		size_t gap = tlsf_cast(size_t,
+			tlsf_cast(tlsfptr_t, aligned) - tlsf_cast(tlsfptr_t, ptr));
+
+		/* If gap size is too small, offset to next aligned boundary. */
+		if (gap && gap < gap_minimum)
+		{
+			const size_t gap_remain = gap_minimum - gap;
+			const size_t offset = tlsf_max(gap_remain, align);
+			const void* next_aligned = tlsf_cast(void*,
+				tlsf_cast(tlsfptr_t, aligned) + offset);
+
+			aligned = align_ptr(next_aligned, align);
+			gap = tlsf_cast(size_t,
+				tlsf_cast(tlsfptr_t, aligned) - tlsf_cast(tlsfptr_t, ptr));
+		}
+
+		if (gap)
+		{
+			tlsf_assert(gap >= gap_minimum && "gap size too small");
+			block = block_trim_free_leading(control, block, gap);
+		}
+	}
+
+	return block_prepare_used(control, block, adjust);
+}
+
+void tlsf_free(tlsf_t tlsf, void* ptr)
+{
+	/* Don't attempt to free a NULL pointer. */
+	if (ptr)
+	{
+		control_t* control = tlsf_cast(control_t*, tlsf);
+		block_header_t* block = block_from_ptr(ptr);
+		tlsf_assert(!block_is_free(block) && "block already marked as free");
+		block_mark_as_free(block);
+		block = block_merge_prev(control, block);
+		block = block_merge_next(control, block);
+		block_insert(control, block);
+	}
+}
+
+/*
+** The TLSF block information provides us with enough information to
+** provide a reasonably intelligent implementation of realloc, growing or
+** shrinking the currently allocated block as required.
+**
+** This routine handles the somewhat esoteric edge cases of realloc:
+** - a non-zero size with a null pointer will behave like malloc
+** - a zero size with a non-null pointer will behave like free
+** - a request that cannot be satisfied will leave the original buffer
+**   untouched
+** - an extended buffer size will leave the newly-allocated area with
+**   contents undefined
+*/
+void* tlsf_realloc(tlsf_t tlsf, void* ptr, size_t size)
+{
+	control_t* control = tlsf_cast(control_t*, tlsf);
+	void* p = 0;
+
+	/* Zero-size requests are treated as free. */
+	if (ptr && size == 0)
+	{
+		tlsf_free(tlsf, ptr);
+	}
+	/* Requests with NULL pointers are treated as malloc. */
+	else if (!ptr)
+	{
+		p = tlsf_malloc(tlsf, size);
+	}
+	else
+	{
+		block_header_t* block = block_from_ptr(ptr);
+		block_header_t* next = block_next(block);
+
+		const size_t cursize = block_size(block);
+		const size_t combined = cursize + block_size(next) + block_header_overhead;
+		const size_t adjust = adjust_request_size(size, ALIGN_SIZE);
+
+		tlsf_assert(!block_is_free(block) && "block already marked as free");
+
+		/*
+		** If the next block is used, or when combined with the current
+		** block, does not offer enough space, we must reallocate and copy.
+		*/
+		if (adjust > cursize && (!block_is_free(next) || adjust > combined))
+		{
+			p = tlsf_malloc(tlsf, size);
+			if (p)
+			{
+				const size_t minsize = tlsf_min(cursize, size);
+				memcpy(p, ptr, minsize);
+				tlsf_free(tlsf, ptr);
+			}
+		}
+		else
+		{
+			/* Do we need to expand to the next block? */
+			if (adjust > cursize)
+			{
+				block_merge_next(control, block);
+				block_mark_as_used(block);
+			}
+
+			/* Trim the resulting block and return the original pointer. */
+			block_trim_used(control, block, adjust);
+			p = ptr;
+		}
+	}
+
+	return p;
+}

+ 133 - 0
components/heap/heap_tlsf.h

@@ -0,0 +1,133 @@
+/*
+** Two Level Segregated Fit memory allocator, version 3.1.
+** Written by Matthew Conte
+**	http://tlsf.baisoku.org
+**
+** Based on the original documentation by Miguel Masmano:
+**	http://www.gii.upv.es/tlsf/main/docs
+**
+** This implementation was written to the specification
+** of the document, therefore no GPL restrictions apply.
+** 
+** Copyright (c) 2006-2016, Matthew Conte
+** All rights reserved.
+** 
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**     * Redistributions of source code must retain the above copyright
+**       notice, this list of conditions and the following disclaimer.
+**     * Redistributions in binary form must reproduce the above copyright
+**       notice, this list of conditions and the following disclaimer in the
+**       documentation and/or other materials provided with the distribution.
+**     * Neither the name of the copyright holder nor the
+**       names of its contributors may be used to endorse or promote products
+**       derived from this software without specific prior written permission.
+** 
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL MATTHEW CONTE BE LIABLE FOR ANY
+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#pragma once
+#include <assert.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>
+#include "heap_tlsf_config.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+** Cast and min/max macros.
+*/
+#define tlsf_cast(t, exp)	((t) (exp))
+#define tlsf_min(a, b)		((a) < (b) ? (a) : (b))
+#define tlsf_max(a, b)		((a) > (b) ? (a) : (b))
+
+/* A type used for casting when doing pointer arithmetic. */
+typedef ptrdiff_t tlsfptr_t;
+
+typedef struct block_header_t
+{
+	/* Points to the previous physical block. */
+	struct block_header_t* prev_phys_block;
+
+	/* The size of this block, excluding the block header. */
+	size_t size;
+
+	/* Next and previous free blocks. */
+	struct block_header_t* next_free;
+	struct block_header_t* prev_free;
+} block_header_t;
+
+/* The TLSF control structure. */
+typedef struct control_t
+{
+	/* Empty lists point at this block to indicate they are free. */
+	block_header_t block_null;
+
+	/* Bitmaps for free lists. */
+	unsigned int fl_bitmap;
+	unsigned int sl_bitmap[FL_INDEX_COUNT];
+
+	/* Head of free lists. */
+	block_header_t* blocks[FL_INDEX_COUNT][SL_INDEX_COUNT];
+} control_t;
+
+#include "heap_tlsf_block_functions.h"
+
+/* tlsf_t: a TLSF structure. Can contain 1 to N pools. */
+/* pool_t: a block of memory that TLSF can manage. */
+typedef void* tlsf_t;
+typedef void* pool_t;
+
+/* Create/destroy a memory pool. */
+tlsf_t tlsf_create(void* mem);
+tlsf_t tlsf_create_with_pool(void* mem, size_t bytes);
+pool_t tlsf_get_pool(tlsf_t tlsf);
+
+/* Add/remove memory pools. */
+pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes);
+void tlsf_remove_pool(tlsf_t tlsf, pool_t pool);
+
+/* malloc/memalign/realloc/free replacements. */
+void* tlsf_malloc(tlsf_t tlsf, size_t size);
+void* tlsf_memalign(tlsf_t tlsf, size_t align, size_t size);
+void* tlsf_realloc(tlsf_t tlsf, void* ptr, size_t size);
+void tlsf_free(tlsf_t tlsf, void* ptr);
+
+/* Returns internal block size, not original request size */
+size_t tlsf_block_size(void* ptr);
+
+/* Overheads/limits of internal structures. */
+size_t tlsf_size(void);
+size_t tlsf_align_size(void);
+size_t tlsf_block_size_min(void);
+size_t tlsf_block_size_max(void);
+size_t tlsf_pool_overhead(void);
+size_t tlsf_alloc_overhead(void);
+
+/* Debugging. */
+typedef void (*tlsf_walker)(void* ptr, size_t size, int used, void* user);
+void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user);
+/* Returns nonzero if any internal consistency check fails. */
+int tlsf_check(tlsf_t tlsf);
+int tlsf_check_pool(pool_t pool);
+
+#if defined(__cplusplus)
+};
+#endif
+
+

+ 172 - 0
components/heap/heap_tlsf_block_functions.h

@@ -0,0 +1,172 @@
+/*
+** Two Level Segregated Fit memory allocator, version 3.1.
+** Written by Matthew Conte
+**	http://tlsf.baisoku.org
+**
+** Based on the original documentation by Miguel Masmano:
+**	http://www.gii.upv.es/tlsf/main/docs
+**
+** This implementation was written to the specification
+** of the document, therefore no GPL restrictions apply.
+** 
+** Copyright (c) 2006-2016, Matthew Conte
+** All rights reserved.
+** 
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**     * Redistributions of source code must retain the above copyright
+**       notice, this list of conditions and the following disclaimer.
+**     * Redistributions in binary form must reproduce the above copyright
+**       notice, this list of conditions and the following disclaimer in the
+**       documentation and/or other materials provided with the distribution.
+**     * Neither the name of the copyright holder nor the
+**       names of its contributors may be used to endorse or promote products
+**       derived from this software without specific prior written permission.
+** 
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL MATTHEW CONTE BE LIABLE FOR ANY
+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#pragma once 
+
+/*
+** Data structures and associated constants.
+*/
+
+/*
+** Since block sizes are always at least a multiple of 4, the two least
+** significant bits of the size field are used to store the block status:
+** - bit 0: whether block is busy or free
+** - bit 1: whether previous block is busy or free
+*/
+#define block_header_free_bit  (1 << 0)
+#define block_header_prev_free_bit  (1 << 1)
+
+/*
+** The size of the block header exposed to used blocks is the size field.
+** The prev_phys_block field is stored *inside* the previous free block.
+*/
+#define block_header_overhead  (sizeof(size_t))
+
+/* User data starts directly after the size field in a used block. */
+#define block_start_offset (offsetof(block_header_t, size) + sizeof(size_t))
+
+/*
+** A free block must be large enough to store its header minus the size of
+** the prev_phys_block field, and no larger than the number of addressable
+** bits for FL_INDEX.
+*/
+#define block_size_min  (sizeof(block_header_t) - sizeof(block_header_t*))
+#define block_size_max  (tlsf_cast(size_t, 1) << FL_INDEX_MAX)
+
+/*
+** block_header_t member functions.
+*/
+static inline __attribute__((__always_inline__)) size_t block_size(const block_header_t* block)
+{
+	return block->size & ~(block_header_free_bit | block_header_prev_free_bit);
+}
+
+static inline __attribute__((__always_inline__)) void block_set_size(block_header_t* block, size_t size)
+{
+	const size_t oldsize = block->size;
+	block->size = size | (oldsize & (block_header_free_bit | block_header_prev_free_bit));
+}
+
+static inline __attribute__((__always_inline__)) int block_is_last(const block_header_t* block)
+{
+	return block_size(block) == 0;
+}
+
+static inline __attribute__((__always_inline__)) int block_is_free(const block_header_t* block)
+{
+	return tlsf_cast(int, block->size & block_header_free_bit);
+}
+
+static inline __attribute__((__always_inline__)) void block_set_free(block_header_t* block)
+{
+	block->size |= block_header_free_bit;
+}
+
+static inline __attribute__((__always_inline__)) void block_set_used(block_header_t* block)
+{
+	block->size &= ~block_header_free_bit;
+}
+
+static inline __attribute__((__always_inline__)) int block_is_prev_free(const block_header_t* block)
+{
+	return tlsf_cast(int, block->size & block_header_prev_free_bit);
+}
+
+static inline __attribute__((__always_inline__)) void block_set_prev_free(block_header_t* block)
+{
+	block->size |= block_header_prev_free_bit;
+}
+
+static inline __attribute__((__always_inline__)) void block_set_prev_used(block_header_t* block)
+{
+	block->size &= ~block_header_prev_free_bit;
+}
+
+static inline __attribute__((__always_inline__)) block_header_t* block_from_ptr(const void* ptr)
+{
+	return tlsf_cast(block_header_t*,
+		tlsf_cast(unsigned char*, ptr) - block_start_offset);
+}
+
+static inline __attribute__((__always_inline__)) void* block_to_ptr(const block_header_t* block)
+{
+	return tlsf_cast(void*,
+		tlsf_cast(unsigned char*, block) + block_start_offset);
+}
+
+/* Return location of next block after block of given size. */
+static inline __attribute__((__always_inline__)) block_header_t* offset_to_block(const void* ptr, size_t size)
+{
+	return tlsf_cast(block_header_t*, tlsf_cast(tlsfptr_t, ptr) + size);
+}
+
+/* Return location of previous block. */
+static inline __attribute__((__always_inline__)) block_header_t* block_prev(const block_header_t* block)
+{
+	return block->prev_phys_block;
+}
+
+/* Return location of next existing block. */
+static inline __attribute__((__always_inline__)) block_header_t* block_next(const block_header_t* block)
+{
+	block_header_t* next = offset_to_block(block_to_ptr(block),
+		block_size(block) - block_header_overhead);
+	return next;
+}
+
+/* Link a new block with its physical neighbor, return the neighbor. */
+static inline __attribute__((__always_inline__)) block_header_t* block_link_next(block_header_t* block)
+{
+	block_header_t* next = block_next(block);
+	next->prev_phys_block = block;
+	return next;
+}
+
+static inline __attribute__((__always_inline__)) void block_mark_as_free(block_header_t* block)
+{
+	/* Link the block to the next block, first. */
+	block_header_t* next = block_link_next(block);
+	block_set_prev_free(next);
+	block_set_free(block);
+}
+
+static inline __attribute__((__always_inline__)) void block_mark_as_used(block_header_t* block)
+{
+	block_header_t* next = block_next(block);
+	block_set_prev_used(next);
+	block_set_used(block);
+}

+ 73 - 0
components/heap/heap_tlsf_config.h

@@ -0,0 +1,73 @@
+/*
+** Two Level Segregated Fit memory allocator, version 3.1.
+** Written by Matthew Conte
+**	http://tlsf.baisoku.org
+**
+** Based on the original documentation by Miguel Masmano:
+**	http://www.gii.upv.es/tlsf/main/docs
+**
+** This implementation was written to the specification
+** of the document, therefore no GPL restrictions apply.
+** 
+** Copyright (c) 2006-2016, Matthew Conte
+** All rights reserved.
+** 
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**     * Redistributions of source code must retain the above copyright
+**       notice, this list of conditions and the following disclaimer.
+**     * Redistributions in binary form must reproduce the above copyright
+**       notice, this list of conditions and the following disclaimer in the
+**       documentation and/or other materials provided with the distribution.
+**     * Neither the name of the copyright holder nor the
+**       names of its contributors may be used to endorse or promote products
+**       derived from this software without specific prior written permission.
+** 
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL MATTHEW CONTE BE LIABLE FOR ANY
+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#pragma once
+
+enum tlsf_config
+{
+	/* log2 of number of linear subdivisions of block sizes. Larger
+	** values require more memory in the control structure. Values of
+	** 4 or 5 are typical.
+	*/
+	SL_INDEX_COUNT_LOG2  = 5,
+
+	/* All allocation sizes and addresses are aligned to 4 bytes. */
+	ALIGN_SIZE_LOG2 = 2,
+	ALIGN_SIZE = (1 << ALIGN_SIZE_LOG2),
+
+	/*
+	** We support allocations of sizes up to (1 << FL_INDEX_MAX) bits.
+	** However, because we linearly subdivide the second-level lists, and
+	** our minimum size granularity is 4 bytes, it doesn't make sense to
+	** create first-level lists for sizes smaller than SL_INDEX_COUNT * 4,
+	** or (1 << (SL_INDEX_COUNT_LOG2 + 2)) bytes, as there we will be
+	** trying to split size ranges into more slots than we have available.
+	** Instead, we calculate the minimum threshold size, and place all
+	** blocks below that size into the 0th first-level list.
+	*/
+
+	/* Tunning the first level, we can reduce TLSF pool overhead 
+	 * in exchange of manage a pool smaller than 4GB
+	 */ 
+	FL_INDEX_MAX = 30,
+
+	SL_INDEX_COUNT = (1 << SL_INDEX_COUNT_LOG2),
+	FL_INDEX_SHIFT = (SL_INDEX_COUNT_LOG2 + ALIGN_SIZE_LOG2),
+	FL_INDEX_COUNT = (FL_INDEX_MAX - FL_INDEX_SHIFT + 1),
+
+	SMALL_BLOCK_SIZE = (1 << FL_INDEX_SHIFT),
+};

+ 8 - 13
components/heap/include/esp_heap_caps.h

@@ -116,12 +116,18 @@ void *heap_caps_realloc( void *ptr, size_t size, int caps);
  *
  * @return A pointer to the memory allocated on success, NULL on failure
  * 
- * @note Any memory allocated with heaps_caps_aligned_alloc() MUST 
- * be freed with heap_caps_aligned_free() and CANNOT be passed to free()
  * 
  */
 void *heap_caps_aligned_alloc(size_t alignment, size_t size, int caps);
 
+/**
+ * @brief Used to deallocate memory previously allocated with heap_caps_aligned_alloc
+ * 
+ * @param ptr Pointer to the memory allocated
+ * @note This function is deprecated, plase consider using heap_caps_free() instead 
+ */
+void __attribute__((deprecated))  heap_caps_aligned_free(void *ptr);                                                  
+
 /**
  * @brief Allocate a aligned chunk of memory which has the given capabilities. The initialized value in the memory is set to zero.
  *
@@ -134,20 +140,9 @@ void *heap_caps_aligned_alloc(size_t alignment, size_t size, int caps);
  *
  * @return A pointer to the memory allocated on success, NULL on failure
  * 
- * @note Any memory allocated with heap_caps_aligned_calloc() MUST 
- * be freed with heap_caps_aligned_free() and CANNOT be passed to free()
  */
 void *heap_caps_aligned_calloc(size_t alignment, size_t n, size_t size, uint32_t caps);
 
-/**
- * @brief Used to deallocate memory previously allocated with heap_caps_aligned_alloc
- * 
- * @param ptr Pointer to the memory allocated
- * @note This function is aimed to deallocate only memory allocated with
- *       heap_caps_aligned_alloc, memory allocated with heap_caps_malloc
- *       MUST not be passed to this function
- */
-void heap_caps_aligned_free(void *ptr);
 
 /**
  * @brief Allocate a chunk of memory which has the given capabilities. The initialized value in the memory is set to zero.

+ 2 - 2
components/heap/include/multi_heap.h

@@ -55,9 +55,9 @@ void *multi_heap_malloc(multi_heap_handle_t heap, size_t size);
  *
  * @param heap Handle to a registered heap.
  * @param p NULL, or a pointer previously returned from multi_heap_aligned_alloc() for the same heap.
+ * @note This function is deprecated, consider using  multi_heap_free() instead
  */
-void multi_heap_aligned_free(multi_heap_handle_t heap, void *p);
-
+void __attribute__((deprecated)) multi_heap_aligned_free(multi_heap_handle_t heap, void *p);
 
 /** @brief free() a buffer in a given heap.
  *

+ 1 - 0
components/heap/linker.lf

@@ -1,5 +1,6 @@
 [mapping:heap]
 archive: libheap.a
 entries:
+    heap_tlsf (noflash)
     multi_heap (noflash)
     multi_heap_poisoning (noflash)

+ 133 - 574
components/heap/multi_heap.c

@@ -18,6 +18,8 @@
 #include <string.h>
 #include <stddef.h>
 #include <stdio.h>
+#include <sys/cdefs.h>
+#include "heap_tlsf.h"
 #include <multi_heap.h>
 #include "multi_heap_internal.h"
 
@@ -36,11 +38,11 @@ void *multi_heap_malloc(multi_heap_handle_t heap, size_t size)
 void *multi_heap_aligned_alloc(multi_heap_handle_t heap, size_t size, size_t alignment)
     __attribute__((alias("multi_heap_aligned_alloc_impl")));
 
-void multi_heap_free(multi_heap_handle_t heap, void *p)
+void multi_heap_aligned_free(multi_heap_handle_t heap, void *p)
     __attribute__((alias("multi_heap_free_impl")));
 
-void multi_heap_aligned_free(multi_heap_handle_t heap, void *p)
-    __attribute__((alias("multi_heap_aligned_free_impl")));
+void multi_heap_free(multi_heap_handle_t heap, void *p)
+    __attribute__((alias("multi_heap_free_impl")));
 
 void *multi_heap_realloc(multi_heap_handle_t heap, void *p, size_t size)
     __attribute__((alias("multi_heap_realloc_impl")));
@@ -74,302 +76,70 @@ void *multi_heap_get_block_owner(multi_heap_block_handle_t block)
 #define ALIGN_UP(X) ALIGN((X)+sizeof(void *)-1)
 #define ALIGN_UP_BY(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
 
-struct heap_block;
-
-/* Block in the heap
-
-   Heap implementation uses two single linked lists, a block list (all blocks) and a free list (free blocks).
 
-   'header' holds a pointer to the next block (used or free) ORed with a free flag (the LSB of the pointer.) is_free() and get_next_block() utility functions allow typed access to these values.
-
-   'next_free' is valid if the block is free and is a pointer to the next block in the free list.
-*/
-typedef struct heap_block {
-    intptr_t header;                  /* Encodes next block in heap (used or unused) and also free/used flag */
-    union {
-        uint8_t data[1];              /* First byte of data, valid if block is used. Actual size of data is 'block_data_size(block)' */
-        struct heap_block *next_free; /* Pointer to next free block, valid if block is free */
-    };
-} heap_block_t;
-
-/* These masks apply to the 'header' field of heap_block_t */
-#define BLOCK_FREE_FLAG 0x1  /* If set, this block is free & next_free pointer is valid */
-#define NEXT_BLOCK_MASK (~3) /* AND header with this mask to get pointer to next block (free or used) */
-
-/* Metadata header for the heap, stored at the beginning of heap space.
-
-   'first_block' is a "fake" first block, minimum length, used to provide a pointer to the first used & free block in
-   the heap. This block is never allocated or merged into an adjacent block.
-
-   'last_block' is a pointer to a final free block of length 0, which is added at the end of the heap when it is
-   registered. This block is also never allocated or merged into an adjacent block.
- */
 typedef struct multi_heap_info {
     void *lock;
     size_t free_bytes;
     size_t minimum_free_bytes;
-    heap_block_t *last_block;
-    heap_block_t first_block; /* initial 'free block', never allocated */
+    size_t pool_size;
+    tlsf_t heap_data;
 } heap_t;
 
-/* Given a pointer to the 'data' field of a block (ie the previous malloc/realloc result), return a pointer to the
-   containing block.
-*/
-static inline heap_block_t *get_block(const void *data_ptr)
-{
-    return (heap_block_t *)((char *)data_ptr - offsetof(heap_block_t, data));
-}
-
-/* Return the next sequential block in the heap.
- */
-static inline heap_block_t *get_next_block(const heap_block_t *block)
-{
-    intptr_t next = block->header & NEXT_BLOCK_MASK;
-    if (next == 0) {
-        return NULL; /* last_block */
-    }
-    assert(next > (intptr_t)block);
-    return (heap_block_t *)next;
-}
-
 /* Return true if this block is free. */
-static inline bool is_free(const heap_block_t *block)
-{
-    return block->header & BLOCK_FREE_FLAG;
-}
-
-/* Return true if this block is the first in the heap */
-static inline bool is_first_block(const heap_t *heap, const heap_block_t *block)
-{
-    return (block == &heap->first_block);
-}
-
-/* Return true if this block is the last_block in the heap
-   (the only block with no next pointer) */
-static inline bool is_last_block(const heap_block_t *block)
+static inline bool is_free(const block_header_t *block)
 {
-    return (block->header & NEXT_BLOCK_MASK) == 0;
+    return ((block->size & 0x01) != 0);
 }
 
 /* Data size of the block (excludes this block's header) */
-static inline size_t block_data_size(const heap_block_t *block)
+static inline size_t block_data_size(const block_header_t *block)
 {
-    intptr_t next = (intptr_t)block->header & NEXT_BLOCK_MASK;
-    intptr_t this = (intptr_t)block;
-    if (next == 0) {
-        return 0; /* this is the last block in the heap */
-    }
-    return next - this - sizeof(block->header);
+    return (block->size & ~0x03);
 }
 
 /* Check a block is valid for this heap. Used to verify parameters. */
-static void assert_valid_block(const heap_t *heap, const heap_block_t *block)
+static void assert_valid_block(const heap_t *heap, const block_header_t *block)
 {
-    MULTI_HEAP_ASSERT(block >= &heap->first_block && block <= heap->last_block,
-                      block); // block not in heap
-    if (heap < (const heap_t *)heap->last_block) {
-        const heap_block_t *next = get_next_block(block);
-        MULTI_HEAP_ASSERT(next >= &heap->first_block && next <= heap->last_block, block); // Next block not in heap
-        if (is_free(block)) {
-            // Check block->next_free is valid
-            MULTI_HEAP_ASSERT(block->next_free >= &heap->first_block && block->next_free <= heap->last_block, &block->next_free);
-        }
-    }
-}
-
-/* Get the first free block before 'block' in the heap. 'block' can be a free block or in use.
-
-   Result is always the closest free block to 'block' in the heap, that is located before 'block'. There may be multiple
-   allocated blocks between the result and 'block'.
-
-   If 'block' is free, the result's 'next_free' pointer will already point to 'block'.
+    pool_t pool = tlsf_get_pool(heap->heap_data);
+    void *ptr = block_to_ptr(block);
 
-   Result will never be NULL, but it may be the header block heap->first_block.
-*/
-static heap_block_t *get_prev_free_block(heap_t *heap, const heap_block_t *block)
-{
-    assert(!is_first_block(heap, block)); /* can't look for a block before first_block */
-
-    for (heap_block_t *b = &heap->first_block; b != NULL && b < block; b = b->next_free) {
-        MULTI_HEAP_ASSERT(is_free(b), b); // Block should be free
-        if (b->next_free == NULL || b->next_free >= block) {
-            if (is_free(block)) {
-                 /* if block is on freelist, 'b' should be the item before it. */
-                MULTI_HEAP_ASSERT(b->next_free == block, &b->next_free);
-            }
-            return b; /* b is the last free block before 'block' */
-        }
-    }
-    abort(); /* There should always be a previous free block, even if it's heap->first_block */
-}
-
-/* Merge some block 'a' into the following block 'b'.
-
-   If both blocks are free, resulting block is marked free.
-   If only one block is free, resulting block is marked in use. No data is moved.
-
-   This operation may fail if block 'a' is the first block or 'b' is the last block,
-   the caller should check block_data_size() to know if anything happened here or not.
-*/
-static heap_block_t *merge_adjacent(heap_t *heap, heap_block_t *a, heap_block_t *b)
-{
-    assert(a < b);
-
-    /* Can't merge header blocks, just return the non-header block as-is */
-    if (is_last_block(b)) {
-        return a;
-    }
-    if (is_first_block(heap, a)) {
-        return b;
-    }
-
-    MULTI_HEAP_ASSERT(get_next_block(a) == b, a); // Blocks should be in order
-
-    bool free = is_free(a) && is_free(b); /* merging two free blocks creates a free block */
-    if (!free && (is_free(a) || is_free(b))) {
-        /* only one of these blocks is free, so resulting block will be a used block.
-           means we need to take the free block out of the free list
-         */
-        heap_block_t *free_block = is_free(a) ? a : b;
-        heap_block_t *prev_free = get_prev_free_block(heap, free_block);
-        MULTI_HEAP_ASSERT(free_block->next_free > prev_free, &free_block->next_free); // Next free block should be after prev one
-        prev_free->next_free = free_block->next_free;
-
-        heap->free_bytes -= block_data_size(free_block);
-    }
-
-    a->header = b->header & NEXT_BLOCK_MASK;
-    MULTI_HEAP_ASSERT(a->header != 0, a);
-    if (free) {
-        a->header |= BLOCK_FREE_FLAG;
-        if (b->next_free != NULL) {
-            MULTI_HEAP_ASSERT(b->next_free > a, &b->next_free);
-            MULTI_HEAP_ASSERT(b->next_free > b, &b->next_free);
-        }
-        a->next_free = b->next_free;
-
-        /* b's header can be put into the pool of free bytes */
-        heap->free_bytes += sizeof(a->header);
-    }
-
-#ifdef MULTI_HEAP_POISONING_SLOW
-    /* b's former block header needs to be replaced with a fill pattern */
-    multi_heap_internal_poison_fill_region(b, sizeof(heap_block_t), free);
-#endif
-
-    return a;
-}
-
-/* Split a block so it can hold at least 'size' bytes of data, making any spare
-   space into a new free block.
-
-   'block' should be marked in-use when this function is called (implementation detail, this function
-   doesn't set the next_free pointer).
-
-   'prev_free_block' is the free block before 'block', if already known. Can be NULL if not yet known.
-   (This is a performance optimisation to avoid walking the freelist twice when possible.)
-*/
-static void split_if_necessary(heap_t *heap, heap_block_t *block, size_t size, heap_block_t *prev_free_block)
-{
-    const size_t block_size = block_data_size(block);
-    MULTI_HEAP_ASSERT(!is_free(block), block); // split block shouldn't be free
-    MULTI_HEAP_ASSERT(size <= block_size, block); // size should be valid
-    size = ALIGN_UP(size);
-
-    /* can't split the head or tail block */
-    assert(!is_first_block(heap, block));
-    assert(!is_last_block(block));
-
-    heap_block_t *new_block = (heap_block_t *)(block->data + size);
-    heap_block_t *next_block = get_next_block(block);
-
-    if (is_free(next_block) && !is_last_block(next_block)) {
-        /* The next block is free, just extend it upwards. */
-        new_block->header = next_block->header;
-        new_block->next_free = next_block->next_free;
-        if (prev_free_block == NULL) {
-            prev_free_block = get_prev_free_block(heap, block);
-        }
-        /* prev_free_block should point to the next block (which we found to be free). */
-        MULTI_HEAP_ASSERT(prev_free_block->next_free == next_block,
-                          &prev_free_block->next_free); // free blocks should be in order
-        /* Note: We have not introduced a new block header, hence the simple math. */
-        heap->free_bytes += block_size - size;
-#ifdef MULTI_HEAP_POISONING_SLOW
-        /* next_block header needs to be replaced with a fill pattern */
-        multi_heap_internal_poison_fill_region(next_block, sizeof(heap_block_t), true /* free */);
-#endif
-    } else {
-        /* Insert a free block between the current and the next one. */
-        if (block_data_size(block) < size + sizeof(heap_block_t)) {
-            /* Can't split 'block' if we're not going to get a usable free block afterwards */
-            return;
-        }
-        if (prev_free_block == NULL) {
-            prev_free_block = get_prev_free_block(heap, block);
-        }
-        new_block->header = block->header | BLOCK_FREE_FLAG;
-        new_block->next_free = prev_free_block->next_free;
-        /* prev_free_block should point to a free block after new_block */
-        MULTI_HEAP_ASSERT(prev_free_block->next_free > new_block,
-                          &prev_free_block->next_free); // free blocks should be in order
-        heap->free_bytes += block_data_size(new_block);
-    }
-    block->header = (intptr_t)new_block;
-    prev_free_block->next_free = new_block;
+    MULTI_HEAP_ASSERT((ptr >= pool) && 
+                    (ptr < pool + heap->pool_size), 
+                    (uintptr_t)ptr);
 }
 
 void *multi_heap_get_block_address_impl(multi_heap_block_handle_t block)
 {
-    return ((char *)block + offsetof(heap_block_t, data));
+    void *ptr = block_to_ptr(block);
+    return (ptr);
 }
 
 size_t multi_heap_get_allocated_size_impl(multi_heap_handle_t heap, void *p)
 {
-    heap_block_t *pb = get_block(p);
-
-    assert_valid_block(heap, pb);
-    MULTI_HEAP_ASSERT(!is_free(pb), pb); // block shouldn't be free
-    return block_data_size(pb);
+    return tlsf_block_size(p);
 }
 
 multi_heap_handle_t multi_heap_register_impl(void *start_ptr, size_t size)
 {
-    uintptr_t start = ALIGN_UP((uintptr_t)start_ptr);
-    uintptr_t end = ALIGN((uintptr_t)start_ptr + size);
-    heap_t *heap = (heap_t *)start;
-    size = end - start;
+    assert(start_ptr);
+    if(size < (tlsf_size() + tlsf_block_size_min() + sizeof(heap_t))) {
+        //Region too small to be a heap.
+        return NULL;
+    }
+
+    heap_t *result = (heap_t *)start_ptr;
+    size -= sizeof(heap_t);
 
-    if (end < start || size < sizeof(heap_t) + 2*sizeof(heap_block_t)) {
-        return NULL; /* 'size' is too small to fit a heap here */
+    result->heap_data = tlsf_create_with_pool(start_ptr + sizeof(heap_t), size);
+    if(!result->heap_data) {
+        return NULL;
     }
-    heap->lock = NULL;
-    heap->last_block = (heap_block_t *)(end - sizeof(heap_block_t));
-
-    /* first 'real' (allocatable) free block goes after the heap structure */
-    heap_block_t *first_free_block = (heap_block_t *)(start + sizeof(heap_t));
-    first_free_block->header = (intptr_t)heap->last_block | BLOCK_FREE_FLAG;
-    first_free_block->next_free = heap->last_block;
-
-    /* last block is 'free' but has a NULL next pointer */
-    heap->last_block->header = BLOCK_FREE_FLAG;
-    heap->last_block->next_free = NULL;
-
-    /* first block also 'free' but has legitimate length,
-       malloc will never allocate into this block. */
-    heap->first_block.header = (intptr_t)first_free_block | BLOCK_FREE_FLAG;
-    heap->first_block.next_free = first_free_block;
-
-    /* free bytes is:
-       - total bytes in heap
-       - minus heap_t header at top (includes heap->first_block)
-       - minus header of first_free_block
-       - minus whole block at heap->last_block
-    */
-    heap->free_bytes = size - sizeof(heap_t) - sizeof(first_free_block->header) - sizeof(heap_block_t);
-    heap->minimum_free_bytes = heap->free_bytes;
-
-    return heap;
+
+    result->lock = NULL;
+    result->free_bytes = size - tlsf_size();
+    result->pool_size = size;
+    result->minimum_free_bytes = result->free_bytes;
+    return result;
 }
 
 void multi_heap_set_lock(multi_heap_handle_t heap, void *lock)
@@ -389,18 +159,26 @@ void inline multi_heap_internal_unlock(multi_heap_handle_t heap)
 
 multi_heap_block_handle_t multi_heap_get_first_block(multi_heap_handle_t heap)
 {
-    return &heap->first_block;
+    assert(heap != NULL);
+    pool_t pool = tlsf_get_pool(heap->heap_data);
+    block_header_t* block = offset_to_block(pool, -(int)block_header_overhead);
+
+    return (multi_heap_block_handle_t)block;
 }
 
 multi_heap_block_handle_t multi_heap_get_next_block(multi_heap_handle_t heap, multi_heap_block_handle_t block)
 {
-    heap_block_t *next = get_next_block(block);
-    /* check for valid free last block to avoid assert in assert_valid_block */
-    if (next == heap->last_block && is_last_block(next) && is_free(next)) {
+    assert(heap != NULL);
+    assert_valid_block(heap, block);
+    block_header_t* next = block_next(block);
+ 
+    if(block_data_size(next) == 0) {
+        //Last block:
         return NULL;
+    } else {
+        return (multi_heap_block_handle_t)next;
     }
-    assert_valid_block(heap, next);
-    return next;
+
 }
 
 bool multi_heap_is_free(multi_heap_block_handle_t block)
@@ -410,355 +188,132 @@ bool multi_heap_is_free(multi_heap_block_handle_t block)
 
 void *multi_heap_malloc_impl(multi_heap_handle_t heap, size_t size)
 {
-    heap_block_t *best_block = NULL;
-    heap_block_t *prev_free = NULL;
-    heap_block_t *prev = NULL;
-    size_t best_size = SIZE_MAX;
-    size = ALIGN_UP(size);
-
     if (size == 0 || heap == NULL) {
         return NULL;
     }
 
-    multi_heap_internal_lock(heap);
-
-    /* Note: this check must be done while holding the lock as both
-       malloc & realloc may temporarily shrink the free_bytes value
-       before they split a large block. This can result in false negatives,
-       especially if the heap is unfragmented.
-    */
-    if (heap->free_bytes < size) {
-        MULTI_HEAP_UNLOCK(heap->lock);
-        return NULL;
-    }
-
-    /* Find best free block to perform the allocation in */
-    prev = &heap->first_block;
-    for (heap_block_t *b = heap->first_block.next_free; b != NULL; b = b->next_free) {
-        MULTI_HEAP_ASSERT(b > prev, &prev->next_free); // free blocks should be ascending in address
-        MULTI_HEAP_ASSERT(is_free(b), b); // block should be free
-        size_t bs = block_data_size(b);
-        if (bs >= size && bs < best_size) {
-            best_block = b;
-            best_size = bs;
-            prev_free = prev;
-            if (bs == size) {
-                break; /* we've found a perfect sized block */
-            }
-        }
-        prev = b;
-    }
-
-    if (best_block == NULL) {
-        multi_heap_internal_unlock(heap);
-        return NULL; /* No room in heap */
-    }
-
-    prev_free->next_free = best_block->next_free;
-    best_block->header &= ~BLOCK_FREE_FLAG;
-
-    heap->free_bytes -= block_data_size(best_block);
-
-    split_if_necessary(heap, best_block, size, prev_free);
-
-    if (heap->free_bytes < heap->minimum_free_bytes) {
-        heap->minimum_free_bytes = heap->free_bytes;
-    }
-
-    multi_heap_internal_unlock(heap);
-
-    return best_block->data;
-}
-
-void *multi_heap_aligned_alloc_impl(multi_heap_handle_t heap, size_t size, size_t alignment)
-{
-    if (heap == NULL) {
-        return NULL;
-    }
-
-    if (!size) {
-        return NULL;
-    }
-
-    if (!alignment) {
-        return NULL;
-    }
-
-    //Alignment must be a power of two...
-    if ((alignment & (alignment - 1)) != 0) {
-        return NULL;
-    }
-
-    uint32_t overhead = (sizeof(uint32_t) + (alignment - 1));
 
     multi_heap_internal_lock(heap);
-    void *head = multi_heap_malloc_impl(heap, size + overhead);
-    if (head == NULL) {
-        multi_heap_internal_unlock(heap);
-        return NULL;
-    }
-
-    //Lets align our new obtained block address:
-    //and save information to recover original block pointer
-    //to allow us to deallocate the memory when needed
-    void *ptr = (void *)ALIGN_UP_BY((uintptr_t)head + sizeof(uint32_t), alignment);
-    *((uint32_t *)ptr - 1) = (uint32_t)((uintptr_t)ptr - (uintptr_t)head);
-
+    void *result = tlsf_malloc(heap->heap_data, size);
+    if(result) {
+        heap->free_bytes -= tlsf_block_size(result);
+        if (heap->free_bytes < heap->minimum_free_bytes) {
+            heap->minimum_free_bytes = heap->free_bytes;
+        }
+    }    
     multi_heap_internal_unlock(heap);
-    return ptr;
-}
 
-void multi_heap_aligned_free_impl(multi_heap_handle_t heap, void *p)
-{
-    if (p == NULL) {
-        return;
-    }
-
-    multi_heap_internal_lock(heap);
-    uint32_t offset = *((uint32_t *)p - 1);
-    void *block_head = (void *)((uint8_t *)p - offset);
-
-#ifdef MULTI_HEAP_POISONING_SLOW
-        multi_heap_internal_poison_fill_region(block_head, multi_heap_get_allocated_size_impl(heap, block_head), true /* free */);
-#endif
-
-    multi_heap_free_impl(heap, block_head);
-    multi_heap_internal_unlock(heap);
+    return result;
 }
 
 void multi_heap_free_impl(multi_heap_handle_t heap, void *p)
 {
-    heap_block_t *pb = get_block(p);
 
     if (heap == NULL || p == NULL) {
         return;
     }
 
-    multi_heap_internal_lock(heap);
-
-    assert_valid_block(heap, pb);
-    MULTI_HEAP_ASSERT(!is_free(pb), pb); // block should not be free
-    MULTI_HEAP_ASSERT(!is_last_block(pb), pb); // block should not be last block
-    MULTI_HEAP_ASSERT(!is_first_block(heap, pb), pb); // block should not be first block
-
-    heap_block_t *next = get_next_block(pb);
-
-    /* Update freelist pointers */
-    heap_block_t *prev_free = get_prev_free_block(heap, pb);
-    // freelist validity check
-    MULTI_HEAP_ASSERT(prev_free->next_free == NULL || prev_free->next_free > pb, &prev_free->next_free);
-    pb->next_free = prev_free->next_free;
-    prev_free->next_free = pb;
-
-    /* Mark this block as free */
-    pb->header |= BLOCK_FREE_FLAG;
-
-    heap->free_bytes += block_data_size(pb);
-
-    /* Try and merge previous free block into this one */
-    if (get_next_block(prev_free) == pb) {
-        pb = merge_adjacent(heap, prev_free, pb);
-    }
-
-    /* If next block is free, try to merge the two */
-    if (is_free(next)) {
-        pb = merge_adjacent(heap, pb, next);
-    }
+    assert_valid_block(heap, p);
 
+    multi_heap_internal_lock(heap);
+    heap->free_bytes += tlsf_block_size(p);
+    tlsf_free(heap->heap_data, p);
     multi_heap_internal_unlock(heap);
 }
 
-
 void *multi_heap_realloc_impl(multi_heap_handle_t heap, void *p, size_t size)
 {
-    heap_block_t *pb = get_block(p);
-    void *result;
-    size = ALIGN_UP(size);
-
     assert(heap != NULL);
 
     if (p == NULL) {
         return multi_heap_malloc_impl(heap, size);
     }
 
-    assert_valid_block(heap, pb);
-    // non-null realloc arg should be allocated
-    MULTI_HEAP_ASSERT(!is_free(pb), pb);
-
-    if (size == 0) {
-        /* note: calling multi_free_impl() here as we've already been
-           through any poison-unwrapping */
-        multi_heap_free_impl(heap, p);
-        return NULL;
-    }
+    assert_valid_block(heap, p);
 
     if (heap == NULL) {
         return NULL;
     }
 
     multi_heap_internal_lock(heap);
-    result = NULL;
-
-    if (size <= block_data_size(pb)) {
-        // Shrinking....
-        split_if_necessary(heap, pb, size, NULL);
-        result = pb->data;
-    }
-    else if (heap->free_bytes < size - block_data_size(pb)) {
-        // Growing, but there's not enough total free space in the heap
-        multi_heap_internal_unlock(heap);
-        return NULL;
-    }
-
-    // New size is larger than existing block
-    if (result == NULL) {
-        // See if we can grow into one or both adjacent blocks
-        heap_block_t *orig_pb = pb;
-        size_t orig_size = block_data_size(orig_pb);
-        heap_block_t *next = get_next_block(pb);
-        heap_block_t *prev = get_prev_free_block(heap, pb);
-
-        // Can only grow into the previous free block if it's adjacent
-        size_t prev_grow_size = (get_next_block(prev) == pb) ? block_data_size(prev) : 0;
-
-        // Can grow into next block? (we may also need to grow into 'prev' to get to our desired size)
-        if (is_free(next) && (block_data_size(pb) + block_data_size(next) + prev_grow_size >= size)) {
-            pb = merge_adjacent(heap, pb, next);
+    size_t previous_block_size =  tlsf_block_size(p);
+    void *result = tlsf_realloc(heap->heap_data, p, size);
+    if(result) {
+        heap->free_bytes += previous_block_size;
+        heap->free_bytes -= tlsf_block_size(result);
+        if (heap->free_bytes < heap->minimum_free_bytes) {
+            heap->minimum_free_bytes = heap->free_bytes;
         }
+    }
+    
+    multi_heap_internal_unlock(heap);
 
-        // Can grow into previous block?
-        // (try this even if we're already big enough from growing into 'next', as it reduces fragmentation)
-        if (prev_grow_size > 0 && (block_data_size(pb) + prev_grow_size >= size)) {
-            pb = merge_adjacent(heap, prev, pb);
-            // this doesn't guarantee we'll be left with a big enough block, as it's
-            // possible for the merge to fail if prev == heap->first_block
-        }
+    return result;
+}
 
-        if (block_data_size(pb) >= size) {
-            memmove(pb->data, orig_pb->data, orig_size);
-            split_if_necessary(heap, pb, size, NULL);
-            result = pb->data;
-        }
+void *multi_heap_aligned_alloc_impl(multi_heap_handle_t heap, size_t size, size_t alignment)
+{
+    if(heap == NULL) {
+        return NULL;
     }
 
-    if (result == NULL) {
-        // Need to allocate elsewhere and copy data over
-        //
-        // (Calling _impl versions here as we've already been through any
-        // unwrapping for heap poisoning features.)
-        result = multi_heap_malloc_impl(heap, size);
-        if (result != NULL) {
-            memcpy(result, pb->data, block_data_size(pb));
-            multi_heap_free_impl(heap, pb->data);
-        }
+    if(!size) {
+        return NULL;
     }
 
-    if (heap->free_bytes < heap->minimum_free_bytes) {
-        heap->minimum_free_bytes = heap->free_bytes;
+    //Alignment must be a power of two:
+    if(((alignment & (alignment - 1)) != 0) ||(!alignment)) {
+        return NULL;
     }
 
+    multi_heap_internal_lock(heap);
+    void *result = tlsf_memalign(heap->heap_data, alignment, size);
+    if(result) {
+        heap->free_bytes -= tlsf_block_size(result);
+        if(heap->free_bytes < heap->minimum_free_bytes) {
+            heap->minimum_free_bytes = heap->free_bytes;
+        }
+    }
     multi_heap_internal_unlock(heap);
+
     return result;
 }
 
-#define FAIL_PRINT(MSG, ...) do {                                       \
-        if (print_errors) {                                             \
-            MULTI_HEAP_STDERR_PRINTF(MSG, __VA_ARGS__);                 \
-        }                                                               \
-        valid = false;                                                  \
-    }                                                                   \
-    while(0)
-
 bool multi_heap_check(multi_heap_handle_t heap, bool print_errors)
 {
+    (void)print_errors;
     bool valid = true;
-    size_t total_free_bytes = 0;
     assert(heap != NULL);
 
     multi_heap_internal_lock(heap);
-
-    heap_block_t *prev = NULL;
-    heap_block_t *prev_free = NULL;
-    heap_block_t *expected_free = NULL;
-
-    /* note: not using get_next_block() in loop, so that assertions aren't checked here */
-    for(heap_block_t *b = &heap->first_block; b != NULL; b = (heap_block_t *)(b->header & NEXT_BLOCK_MASK)) {
-        if (b == prev) {
-            FAIL_PRINT("CORRUPT HEAP: Block %p points to itself\n", b);
-            goto done;
-        }
-        if (b < prev) {
-            FAIL_PRINT("CORRUPT HEAP: Block %p is before prev block %p\n", b, prev);
-            goto done;
-        }
-        if (b > heap->last_block || b < &heap->first_block) {
-            FAIL_PRINT("CORRUPT HEAP: Block %p is outside heap (last valid block %p)\n", b, prev);
-            goto done;
-        }
-        if (is_free(b)) {
-            if (prev != NULL && is_free(prev) && !is_first_block(heap, prev) && !is_last_block(b)) {
-                FAIL_PRINT("CORRUPT HEAP: Two adjacent free blocks found, %p and %p\n", prev, b);
-            }
-            if (expected_free != NULL && expected_free != b) {
-                FAIL_PRINT("CORRUPT HEAP: Prev free block %p pointed to next free %p but this free block is %p\n",
-                       prev_free, expected_free, b);
-            }
-            prev_free = b;
-            expected_free = b->next_free;
-            if (!is_first_block(heap, b)) {
-                total_free_bytes += block_data_size(b);
-            }
-        }
-        prev = b;
-
-#ifdef MULTI_HEAP_POISONING
-        if (!is_last_block(b)) {
-            /* For slow heap poisoning, any block should contain correct poisoning patterns and/or fills */
-            bool poison_ok;
-            if (is_free(b) && b != heap->last_block) {
-                uint32_t block_len = (intptr_t)get_next_block(b) - (intptr_t)b - sizeof(heap_block_t);
-                poison_ok = multi_heap_internal_check_block_poisoning(&b[1], block_len, true, print_errors);
-            }
-            else {
-                poison_ok = multi_heap_internal_check_block_poisoning(b->data, block_data_size(b), false, print_errors);
-            }
-            valid = poison_ok && valid;
-        }
-#endif
-
-    } /* for(heap_block_t b = ... */
-
-    if (prev != heap->last_block) {
-        FAIL_PRINT("CORRUPT HEAP: Last block %p not %p\n", prev, heap->last_block);
-    }
-    if (!is_free(heap->last_block)) {
-        FAIL_PRINT("CORRUPT HEAP: Expected prev block %p to be free\n", heap->last_block);
+    if(tlsf_check(heap->heap_data)) {
+        valid = false;
     }
 
-    if (heap->free_bytes != total_free_bytes) {
-        FAIL_PRINT("CORRUPT HEAP: Expected %u free bytes counted %u\n", (unsigned)heap->free_bytes, (unsigned)total_free_bytes);
+    if(tlsf_check_pool(tlsf_get_pool(heap->heap_data))) {
+        valid = false;
     }
 
- done:
     multi_heap_internal_unlock(heap);
-
     return valid;
 }
 
+static void multi_heap_dump_tlsf(void* ptr, size_t size, int used, void* user)
+{
+    (void)user;
+    MULTI_HEAP_STDERR_PRINTF("Block %p data, size: %d bytes, Free: %s \n", 
+                            (void *)ptr,
+                            size,
+                            used ? "No" : "Yes");
+}
+
 void multi_heap_dump(multi_heap_handle_t heap)
 {
     assert(heap != NULL);
 
     multi_heap_internal_lock(heap);
-    MULTI_HEAP_STDERR_PRINTF("Heap start %p end %p\nFirst free block %p\n", &heap->first_block, heap->last_block, heap->first_block.next_free);
-    for(heap_block_t *b = &heap->first_block; b != NULL; b = get_next_block(b)) {
-        MULTI_HEAP_STDERR_PRINTF("Block %p data size 0x%08x bytes next block %p", b, block_data_size(b), get_next_block(b));
-        if (is_free(b)) {
-            MULTI_HEAP_STDERR_PRINTF(" FREE. Next free %p\n", b->next_free);
-        } else {
-            MULTI_HEAP_STDERR_PRINTF("%s", "\n"); /* C macros & optional __VA_ARGS__ */
-        }
-    }
+    MULTI_HEAP_STDERR_PRINTF("Showing data for heap: %p \n", (void *)heap);
+    tlsf_walk_pool(tlsf_get_pool(heap->heap_data), multi_heap_dump_tlsf, NULL);
     multi_heap_internal_unlock(heap);
 }
 
@@ -767,6 +322,7 @@ size_t multi_heap_free_size_impl(multi_heap_handle_t heap)
     if (heap == NULL) {
         return 0;
     }
+
     return heap->free_bytes;
 }
 
@@ -775,9 +331,27 @@ size_t multi_heap_minimum_free_size_impl(multi_heap_handle_t heap)
     if (heap == NULL) {
         return 0;
     }
+
     return heap->minimum_free_bytes;
 }
 
+static void multi_heap_get_info_tlsf(void* ptr, size_t size, int used, void* user)
+{
+    multi_heap_info_t *info = user;
+    
+    if(used) {
+        info->allocated_blocks++;
+    } else {
+        info->free_blocks++;
+        
+        if(size > info->largest_free_block ) {
+            info->largest_free_block = size;
+        }   
+    }
+    
+    info->total_blocks++; 
+}
+
 void multi_heap_get_info_impl(multi_heap_handle_t heap, multi_heap_info_t *info)
 {
     memset(info, 0, sizeof(multi_heap_info_t));
@@ -787,25 +361,10 @@ void multi_heap_get_info_impl(multi_heap_handle_t heap, multi_heap_info_t *info)
     }
 
     multi_heap_internal_lock(heap);
-    for(heap_block_t *b = get_next_block(&heap->first_block); !is_last_block(b); b = get_next_block(b)) {
-        info->total_blocks++;
-        if (is_free(b)) {
-            size_t s = block_data_size(b);
-            info->total_free_bytes += s;
-            if (s > info->largest_free_block) {
-                info->largest_free_block = s;
-            }
-            info->free_blocks++;
-        } else {
-            info->total_allocated_bytes += block_data_size(b);
-            info->allocated_blocks++;
-        }
-    }
-
+    tlsf_walk_pool(tlsf_get_pool(heap->heap_data), multi_heap_get_info_tlsf, info);
+    info->total_allocated_bytes = (heap->pool_size - tlsf_size()) - heap->free_bytes;
     info->minimum_free_bytes = heap->minimum_free_bytes;
-    // heap has wrong total size (address printed here is not indicative of the real error)
-    MULTI_HEAP_ASSERT(info->total_free_bytes == heap->free_bytes, heap);
-
+    info->total_free_bytes = heap->free_bytes;
+    info->largest_free_block = info->largest_free_block ? 1 << (31 - __builtin_clz(info->largest_free_block)) : 0;
     multi_heap_internal_unlock(heap);
-
 }

+ 2 - 2
components/heap/multi_heap_internal.h

@@ -14,7 +14,7 @@
 #pragma once
 
 /* Opaque handle to a heap block */
-typedef const struct heap_block *multi_heap_block_handle_t;
+typedef const struct block_header_t *multi_heap_block_handle_t;
 
 /* Internal definitions for the "implementation" of the multi_heap API,
    as defined in multi_heap.c.
@@ -27,8 +27,8 @@ typedef const struct heap_block *multi_heap_block_handle_t;
 void *multi_heap_malloc_impl(multi_heap_handle_t heap, size_t size);
 void *multi_heap_aligned_alloc_impl(multi_heap_handle_t heap, size_t size, size_t alignment);
 void multi_heap_free_impl(multi_heap_handle_t heap, void *p);
-void multi_heap_aligned_free_impl(multi_heap_handle_t heap, void *p);
 void *multi_heap_realloc_impl(multi_heap_handle_t heap, void *p, size_t size);
+void *multi_heap_aligned_alloc_impl(multi_heap_handle_t heap, size_t size, size_t alignment);
 multi_heap_handle_t multi_heap_register_impl(void *start, size_t size);
 void multi_heap_get_info_impl(multi_heap_handle_t heap, multi_heap_info_t *info);
 size_t multi_heap_free_size_impl(multi_heap_handle_t heap);

+ 13 - 26
components/heap/multi_heap_poisoning.c

@@ -241,21 +241,6 @@ void *multi_heap_malloc(multi_heap_handle_t heap, size_t size)
     return data;
 }
 
-void multi_heap_aligned_free(multi_heap_handle_t heap, void *p)
-{
-    multi_heap_internal_lock(heap);
-    poison_head_t *head = verify_allocated_region(p, true);
-    assert(head != NULL); 
-
-#ifdef SLOW
-    /* replace everything with FREE_FILL_PATTERN, including the poison head/tail */
-    memset(head, FREE_FILL_PATTERN, head->alloc_size + POISON_OVERHEAD);
-#endif
-
-    multi_heap_aligned_free_impl(heap, head);
-    multi_heap_internal_unlock(heap);
-}
-
 void multi_heap_free(multi_heap_handle_t heap, void *p)
 {
     if (p == NULL) {
@@ -276,6 +261,11 @@ void multi_heap_free(multi_heap_handle_t heap, void *p)
     multi_heap_internal_unlock(heap);
 }
 
+void multi_heap_aligned_free(multi_heap_handle_t heap, void *p)
+{
+    multi_heap_free(heap, p);
+}
+
 void *multi_heap_realloc(multi_heap_handle_t heap, void *p, size_t size)
 {
     poison_head_t *head = NULL;
@@ -337,17 +327,6 @@ void *multi_heap_get_block_address(multi_heap_block_handle_t block)
     return head + sizeof(poison_head_t);
 }
 
-size_t multi_heap_get_allocated_size(multi_heap_handle_t heap, void *p)
-{
-    poison_head_t *head = verify_allocated_region(p, true);
-    assert(head != NULL);
-    size_t result = multi_heap_get_allocated_size_impl(heap, head);
-    if (result > 0) {
-        return result - POISON_OVERHEAD;
-    }
-    return 0;
-}
-
 void *multi_heap_get_block_owner(multi_heap_block_handle_t block)
 {
     return MULTI_HEAP_GET_BLOCK_OWNER((poison_head_t*)multi_heap_get_block_address_impl(block));
@@ -371,6 +350,14 @@ static inline void subtract_poison_overhead(size_t *arg) {
     }
 }
 
+size_t multi_heap_get_allocated_size(multi_heap_handle_t heap, void *p)
+{
+    poison_head_t *head = verify_allocated_region(p, true);
+    assert(head != NULL);
+    size_t result = multi_heap_get_allocated_size_impl(heap, head);
+    return result;
+}
+
 void multi_heap_get_info(multi_heap_handle_t heap, multi_heap_info_t *info)
 {
     multi_heap_get_info_impl(heap, info);

+ 10 - 8
components/heap/test/test_aligned_alloc_caps.c

@@ -11,6 +11,7 @@
 #include <stdlib.h>
 #include <sys/param.h>
 #include <string.h>
+#include <malloc.h>
 
 TEST_CASE("Capabilities aligned allocator test", "[heap]")
 {
@@ -19,7 +20,7 @@ TEST_CASE("Capabilities aligned allocator test", "[heap]")
     printf("[ALIGNED_ALLOC] Allocating from default CAP: \n");
     
     for(;alignments <= 1024; alignments++) {
-        uint8_t *buf = (uint8_t *)heap_caps_aligned_alloc(alignments, (alignments + 137), MALLOC_CAP_DEFAULT);
+        uint8_t *buf = (uint8_t *)memalign(alignments, (alignments + 137));
         if(((alignments & (alignments - 1)) != 0) || (!alignments)) {
             TEST_ASSERT( buf == NULL );
             //printf("[ALIGNED_ALLOC] alignment: %u is not a power of two, don't allow allocation \n", aligments);
@@ -28,7 +29,6 @@ TEST_CASE("Capabilities aligned allocator test", "[heap]")
             printf("[ALIGNED_ALLOC] alignment required: %u \n", alignments);
             printf("[ALIGNED_ALLOC] address of allocated memory: %p \n\n", (void *)buf);
             //Address of obtained block must be aligned with selected value
-
             if((alignments & 0x03) == 0) {
                 //Alignment is a multiple of four:
                 TEST_ASSERT(((intptr_t)buf & 0x03) == 0);
@@ -41,7 +41,7 @@ TEST_CASE("Capabilities aligned allocator test", "[heap]")
             //canary verification will fail:
             memset(buf, 0xA5, (alignments + 137));
 
-            heap_caps_aligned_free(buf);    
+            free(buf);    
         }
     } 
 
@@ -71,10 +71,12 @@ TEST_CASE("Capabilities aligned allocator test", "[heap]")
                 //Exotic alignments:
                 TEST_ASSERT(((intptr_t)buf & (alignments - 1)) == 0);
             }
+
+
             //Write some data, if it corrupts memory probably the heap
             //canary verification will fail:
             memset(buf, 0xA5, (10*1024));
-            heap_caps_aligned_free(buf);    
+            heap_caps_free(buf);    
         }
     } 
 #endif
@@ -109,7 +111,7 @@ TEST_CASE("Capabilities aligned calloc test", "[heap]")
             //canary verification will fail:
             memset(buf, 0xA5, (alignments + 137));
 
-            heap_caps_aligned_free(buf);    
+            heap_caps_free(buf);    
         }
     } 
 
@@ -118,12 +120,12 @@ TEST_CASE("Capabilities aligned calloc test", "[heap]")
     memset(&byte_array, 0, sizeof(byte_array));
     uint8_t *buf = (uint8_t *)heap_caps_aligned_calloc(1024, 1, 1024, MALLOC_CAP_DEFAULT);
     TEST_ASSERT(memcmp(byte_array, buf, sizeof(byte_array)) == 0);
-    heap_caps_aligned_free(buf);
+    heap_caps_free(buf);
 
     //Same size, but different chunk:
     buf = (uint8_t *)heap_caps_aligned_calloc(1024, 1024, 1, MALLOC_CAP_DEFAULT);
     TEST_ASSERT(memcmp(byte_array, buf, sizeof(byte_array)) == 0);
-    heap_caps_aligned_free(buf);
+    heap_caps_free(buf);
 
     //Alloc from a non permitted area:
     uint32_t *not_permitted_buf = (uint32_t *)heap_caps_aligned_calloc(alignments, 1, (alignments + 137), MALLOC_CAP_32BIT);
@@ -154,7 +156,7 @@ TEST_CASE("Capabilities aligned calloc test", "[heap]")
             //Write some data, if it corrupts memory probably the heap
             //canary verification will fail:
             memset(buf, 0xA5, (10*1024));
-            heap_caps_aligned_free(buf);    
+            heap_caps_free(buf);    
         }
     } 
 #endif

+ 108 - 0
components/heap/test/test_allocator_timings.c

@@ -0,0 +1,108 @@
+#include "freertos/FreeRTOS.h"
+#include <esp_types.h>
+#include <stdio.h>
+#include "unity.h"
+#include "esp_attr.h"
+#include "esp_heap_caps.h"
+#include <stdlib.h>
+#include <sys/param.h>
+#include <string.h>
+#include <test_utils.h>
+
+//This test only makes sense with poisoning disabled
+#ifndef CONFIG_HEAP_POISONING_COMPREHENSIVE
+
+#define NUM_POINTERS 128
+#define ITERATIONS 10000
+
+TEST_CASE("Heap many random allocations timings", "[heap]")
+{
+    void *p[NUM_POINTERS] = { 0 };
+    size_t s[NUM_POINTERS] = { 0 };
+
+    uint32_t cycles_before;
+    uint64_t alloc_time_average = 0;
+    uint64_t free_time_average = 0;
+    uint64_t realloc_time_average = 0;
+
+    for (int i = 0; i < ITERATIONS; i++) {
+        uint8_t n = esp_random() % NUM_POINTERS;
+
+        if (esp_random() % 4 == 0) {
+            /* 1 in 4 iterations, try to realloc the buffer instead
+               of using malloc/free
+            */
+            size_t new_size = esp_random() % 1024;
+           
+            cycles_before = portGET_RUN_TIME_COUNTER_VALUE();
+            void *new_p = heap_caps_realloc(p[n], new_size, MALLOC_CAP_DEFAULT);
+            realloc_time_average = portGET_RUN_TIME_COUNTER_VALUE() - cycles_before;
+           
+            printf("realloc %p -> %p (%zu -> %zu) time spent cycles: %lld \n", p[n], new_p, s[n], new_size, realloc_time_average);
+            heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true);
+            if (new_size == 0 || new_p != NULL) {
+                p[n] = new_p;
+                s[n] = new_size;
+                if (new_size > 0) {
+                    memset(p[n], n, new_size);
+                }
+            }
+            continue;
+        }
+
+        if (p[n] != NULL) {
+            if (s[n] > 0) {
+                /* Verify pre-existing contents of p[n] */
+                uint8_t compare[s[n]];
+                memset(compare, n, s[n]);
+                TEST_ASSERT(( memcmp(compare, p[n], s[n]) == 0 ));
+            }
+            TEST_ASSERT(heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true));
+            
+            cycles_before = portGET_RUN_TIME_COUNTER_VALUE();
+            heap_caps_free(p[n]);
+            free_time_average = portGET_RUN_TIME_COUNTER_VALUE() - cycles_before;
+
+            printf("freed %p (%zu) time spent cycles: %lld\n", p[n], s[n], free_time_average);
+
+            if (!heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true)) {
+                printf("FAILED iteration %d after freeing %p\n", i, p[n]);
+                heap_caps_dump(MALLOC_CAP_DEFAULT);
+                TEST_ASSERT(0);
+            }
+        }
+
+        s[n] = rand() % 1024;
+        heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true);
+        cycles_before = portGET_RUN_TIME_COUNTER_VALUE();
+        p[n] = heap_caps_malloc(s[n], MALLOC_CAP_DEFAULT);
+        alloc_time_average = portGET_RUN_TIME_COUNTER_VALUE() - cycles_before;
+        
+        printf("malloc %p (%zu) time spent cycles: %lld \n", p[n], s[n], alloc_time_average);
+
+        if (!heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true)) {
+            printf("FAILED iteration %d after mallocing %p (%zu bytes)\n", i, p[n], s[n]);
+            heap_caps_dump(MALLOC_CAP_DEFAULT);
+            TEST_ASSERT(0);
+        }
+
+        if (p[n] != NULL) {
+            memset(p[n], n, s[n]);
+        }
+    }
+
+    for (int i = 0; i < NUM_POINTERS; i++) {
+        cycles_before = portGET_RUN_TIME_COUNTER_VALUE();
+        heap_caps_free( p[i]);
+        free_time_average = portGET_RUN_TIME_COUNTER_VALUE() - cycles_before;
+
+        if (!heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true)) {
+            printf("FAILED during cleanup after freeing %p\n", p[i]);
+            heap_caps_dump(MALLOC_CAP_DEFAULT);
+            TEST_ASSERT(0);
+        }
+    }
+    
+    TEST_ASSERT(heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true));
+}
+#endif

+ 15 - 11
components/heap/test/test_malloc_caps.c

@@ -34,8 +34,8 @@ TEST_CASE("Capabilities allocator test", "[heap]")
     free32 = heap_caps_get_free_size(MALLOC_CAP_32BIT);
     printf("Free 8bit-capable memory (both reduced): %dK, 32-bit capable memory %dK\n", free8, free32);
     //Both should have gone down by 10K; 8bit capable ram is also 32-bit capable
-    TEST_ASSERT(free8<(free8start-10*1024));
-    TEST_ASSERT(free32<(free32start-10*1024));
+    TEST_ASSERT(free8<=(free8start-10*1024));
+    TEST_ASSERT(free32<=(free32start-10*1024));
     //Assume we got DRAM back
     TEST_ASSERT((((int)m1)&0xFF000000)==0x3F000000);
     free(m1);
@@ -55,7 +55,7 @@ TEST_CASE("Capabilities allocator test", "[heap]")
         free32 = heap_caps_get_free_size(MALLOC_CAP_32BIT);
         printf("Free 8bit-capable memory (after 32-bit): %dK, 32-bit capable memory %dK\n", free8, free32);
         //Only 32-bit should have gone down by alloc32: 32-bit isn't necessarily 8bit capable
-        TEST_ASSERT(free32<(free32start-alloc32));
+        TEST_ASSERT(free32<=(free32start-alloc32));
         TEST_ASSERT(free8==free8start);
         free(m1);
     } else {
@@ -121,8 +121,8 @@ TEST_CASE("IRAM_8BIT capability test", "[heap]")
 
     TEST_ASSERT((((int)ptr)&0xFF000000)==0x40000000);
 
-    TEST_ASSERT(heap_caps_get_free_size(MALLOC_CAP_IRAM_8BIT) == (free_size - largest_free_size));
-    TEST_ASSERT(heap_caps_get_free_size(MALLOC_CAP_32BIT) == (free_size32 - largest_free_size));
+    TEST_ASSERT(heap_caps_get_free_size(MALLOC_CAP_IRAM_8BIT) == (free_size - heap_caps_get_allocated_size(ptr)));
+    TEST_ASSERT(heap_caps_get_free_size(MALLOC_CAP_32BIT) == (free_size32 - heap_caps_get_allocated_size(ptr)));
 
     free(ptr);
 }
@@ -133,7 +133,6 @@ TEST_CASE("heap_caps metadata test", "[heap]")
     /* need to print something as first printf allocates some heap */
     printf("heap_caps metadata test\n");
     heap_caps_print_heap_info(MALLOC_CAP_8BIT);
-    heap_caps_print_heap_info(MALLOC_CAP_32BIT);
 
     multi_heap_info_t original;
     heap_caps_get_info(&original, MALLOC_CAP_8BIT);
@@ -146,11 +145,15 @@ TEST_CASE("heap_caps metadata test", "[heap]")
 
     multi_heap_info_t after;
     heap_caps_get_info(&after, MALLOC_CAP_8BIT);
-    TEST_ASSERT(after.largest_free_block < original.largest_free_block);
-    TEST_ASSERT(after.total_free_bytes < original.total_free_bytes);
+    TEST_ASSERT(after.largest_free_block <= original.largest_free_block);
+    TEST_ASSERT(after.total_free_bytes <= original.total_free_bytes);
 
     free(b);
     heap_caps_get_info(&after, MALLOC_CAP_8BIT);
+    
+    printf("\n\n After test, heap status:\n");
+    heap_caps_print_heap_info(MALLOC_CAP_8BIT);
+
     /* Allow some leeway here, because LWIP sometimes allocates up to 144 bytes in the background
        as part of timer management.
     */
@@ -167,9 +170,9 @@ static IRAM_ATTR __attribute__((noinline)) bool iram_malloc_test(void)
     spi_flash_guard_get()->start(); // Disables flash cache
 
     bool result = true;
-    void *x = heap_caps_malloc(64, MALLOC_CAP_32BIT);
+    void *x = heap_caps_malloc(64, MALLOC_CAP_EXEC);
     result = result && (x != NULL);
-    void *y = heap_caps_realloc(x, 32, MALLOC_CAP_32BIT);
+    void *y = heap_caps_realloc(x, 32, MALLOC_CAP_EXEC);
     result = result && (y != NULL);
     heap_caps_free(y);
 
@@ -178,6 +181,7 @@ static IRAM_ATTR __attribute__((noinline)) bool iram_malloc_test(void)
     return result;
 }
 
+
 TEST_CASE("heap_caps_xxx functions work with flash cache disabled", "[heap]")
 {
     TEST_ASSERT( iram_malloc_test() );
@@ -240,4 +244,4 @@ TEST_CASE("allocation with invalid capability should also trigger the alloc fail
     TEST_ASSERT(called_user_failed_hook != false);
 
     (void)ptr;
-}
+}

+ 1 - 1
components/heap/test/test_realloc.c

@@ -34,7 +34,7 @@ TEST_CASE("realloc shrink buffer with EXEC CAPS", "[heap]")
     TEST_ASSERT(y);
 
     //y needs to fall in a compatible memory area of IRAM:
-    TEST_ASSERT(esp_ptr_executable(y));
+    TEST_ASSERT(esp_ptr_executable(y)|| esp_ptr_in_iram(y) || esp_ptr_in_diram_iram(y));
 
     free(y);
 }

+ 1 - 0
components/heap/test_multi_heap_host/Makefile

@@ -7,6 +7,7 @@ endif
 
 SOURCE_FILES = $(abspath \
     ../multi_heap.c \
+    ../heap_tlsf.c \
 	../multi_heap_poisoning.c \
 	test_multi_heap.cpp \
 	main.cpp \

+ 1 - 1
components/heap/test_multi_heap_host/test_all_configs.sh

@@ -5,7 +5,7 @@
 
 FAIL=0
 
-for FLAGS in "CONFIG_HEAP_POISONING_NONE" "CONFIG_HEAP_POISONING_LIGHT" "CONFIG_HEAP_POISONING_COMPREHENSIVE"; do
+for FLAGS in "CONFIG_HEAP_POISONING_NONE" "CONFIG_HEAP_POISONING_LIGHT" "CONFIG_HEAP_POISONING_COMPREHENSIVE" ; do
     echo "==== Testing with config: ${FLAGS} ===="
     CPPFLAGS="-D${FLAGS}" make clean test || FAIL=1
 done

+ 27 - 77
components/heap/test_multi_heap_host/test_multi_heap.cpp

@@ -18,7 +18,7 @@
 
 TEST_CASE("multi_heap simple allocations", "[multi_heap]")
 {
-    uint8_t small_heap[128];
+    uint8_t small_heap[4 * 1024];
 
     multi_heap_handle_t heap = multi_heap_register(small_heap, sizeof(small_heap));
 
@@ -59,10 +59,10 @@ TEST_CASE("multi_heap simple allocations", "[multi_heap]")
 
 TEST_CASE("multi_heap fragmentation", "[multi_heap]")
 {
-    uint8_t small_heap[256];
+    uint8_t small_heap[4 * 1024];
     multi_heap_handle_t heap = multi_heap_register(small_heap, sizeof(small_heap));
 
-    const size_t alloc_size = 24;
+    const size_t alloc_size = 128;
 
     void *p[4];
     for (int i = 0; i < 4; i++) {
@@ -85,13 +85,13 @@ TEST_CASE("multi_heap fragmentation", "[multi_heap]")
     multi_heap_free(heap, p[0]);
     multi_heap_free(heap, p[1]);
     multi_heap_free(heap, p[3]);
-
+             
     printf("1 allocations:\n");
     multi_heap_dump(heap);
     printf("****************\n");
 
     void *big = multi_heap_malloc(heap, alloc_size * 3);
-    REQUIRE( p[3] == big ); /* big should go where p[3] was freed from */
+    //Blocks in TLSF are organized in different form, so this makes no sense
     multi_heap_free(heap, big);
 
     multi_heap_free(heap, p[2]);
@@ -101,7 +101,7 @@ TEST_CASE("multi_heap fragmentation", "[multi_heap]")
     printf("****************\n");
 
     big = multi_heap_malloc(heap, alloc_size * 2);
-    REQUIRE( p[0] == big ); /* big should now go where p[0] was freed from */
+    //Blocks in TLSF are organized in different form, so this makes no sense
     multi_heap_free(heap, big);
 }
 
@@ -109,7 +109,7 @@ TEST_CASE("multi_heap fragmentation", "[multi_heap]")
 TEST_CASE("multi_heap defrag", "[multi_heap]")
 {
     void *p[4];
-    uint8_t small_heap[512];
+    uint8_t small_heap[4 * 1024];
     multi_heap_info_t info, info2;
     multi_heap_handle_t heap = multi_heap_register(small_heap, sizeof(small_heap));
 
@@ -159,7 +159,7 @@ TEST_CASE("multi_heap defrag", "[multi_heap]")
 TEST_CASE("multi_heap defrag realloc", "[multi_heap]")
 {
     void *p[4];
-    uint8_t small_heap[512];
+    uint8_t small_heap[4 * 1024];
     multi_heap_info_t info, info2;
     multi_heap_handle_t heap = multi_heap_register(small_heap, sizeof(small_heap));
 
@@ -204,7 +204,7 @@ TEST_CASE("multi_heap defrag realloc", "[multi_heap]")
 
 TEST_CASE("multi_heap many random allocations", "[multi_heap]")
 {
-    uint8_t big_heap[1024];
+    uint8_t big_heap[8 * 1024];
     const int NUM_POINTERS = 64;
 
     printf("Running multi-allocation test...\n");
@@ -215,7 +215,7 @@ TEST_CASE("multi_heap many random allocations", "[multi_heap]")
 
     const size_t initial_free = multi_heap_free_size(heap);
 
-    const int ITERATIONS = 100000;
+    const int ITERATIONS = 10000;
 
     for (int i = 0; i < ITERATIONS; i++) {
         /* check all pointers allocated so far are valid inside big_heap */
@@ -296,7 +296,7 @@ TEST_CASE("multi_heap many random allocations", "[multi_heap]")
 
 TEST_CASE("multi_heap_get_info() function", "[multi_heap]")
 {
-    uint8_t heapdata[256];
+    uint8_t heapdata[4 * 1024];
     multi_heap_handle_t heap = multi_heap_register(heapdata, sizeof(heapdata));
     multi_heap_info_t before, after, freed;
 
@@ -349,25 +349,26 @@ TEST_CASE("multi_heap_get_info() function", "[multi_heap]")
 
 TEST_CASE("multi_heap minimum-size allocations", "[multi_heap]")
 {
-    uint8_t heapdata[16384];
-    void *p[sizeof(heapdata) / sizeof(void *)];
+    uint8_t heapdata[4096];
+    void *p[sizeof(heapdata) / sizeof(void *)] = {NULL};
     const size_t NUM_P = sizeof(p) / sizeof(void *);
+    size_t allocated_size = 0;
     multi_heap_handle_t heap = multi_heap_register(heapdata, sizeof(heapdata));
-
     size_t before_free = multi_heap_free_size(heap);
 
     size_t i;
     for (i = 0; i < NUM_P; i++) {
+        //TLSF minimum block size is 4 bytes
         p[i] = multi_heap_malloc(heap, 1);
         if (p[i] == NULL) {
             break;
-        }
+        } 
     }
 
     REQUIRE( i < NUM_P); // Should have run out of heap before we ran out of pointers
     printf("Allocated %zu minimum size chunks\n", i);
-
-    REQUIRE( 0 == multi_heap_free_size(heap) );
+    
+    REQUIRE(multi_heap_free_size(heap) < before_free);
     multi_heap_check(heap, true);
 
     /* Free in random order */
@@ -391,7 +392,7 @@ TEST_CASE("multi_heap minimum-size allocations", "[multi_heap]")
 TEST_CASE("multi_heap_realloc()", "[multi_heap]")
 {
     const uint32_t PATTERN = 0xABABDADA;
-    uint8_t small_heap[300];
+    uint8_t small_heap[4 * 1024];
     multi_heap_handle_t heap = multi_heap_register(small_heap, sizeof(small_heap));
 
     uint32_t *a = (uint32_t *)multi_heap_malloc(heap, 64);
@@ -427,9 +428,9 @@ TEST_CASE("multi_heap_realloc()", "[multi_heap]")
     REQUIRE( f == b ); /* 'b' should be extended in-place, over space formerly occupied by 'd' */
 
 #ifdef MULTI_HEAP_POISONING
-#define TOO_MUCH 92 + 1
+#define TOO_MUCH 7420 + 1
 #else
-#define TOO_MUCH 128 + 1
+#define TOO_MUCH 7420 + 1
 #endif
     /* not enough contiguous space left in the heap */
     uint32_t *g = (uint32_t *)multi_heap_realloc(heap, e, TOO_MUCH);
@@ -443,61 +444,11 @@ TEST_CASE("multi_heap_realloc()", "[multi_heap]")
 #endif
 }
 
-TEST_CASE("corrupt heap block", "[multi_heap]")
-{
-    uint8_t small_heap[256];
-    multi_heap_handle_t heap = multi_heap_register(small_heap, sizeof(small_heap));
-
-    void *a = multi_heap_malloc(heap, 32);
-    REQUIRE( multi_heap_check(heap, true) );
-    memset(a, 0xEE, 64);
-    REQUIRE( !multi_heap_check(heap, true) );
-}
-
-TEST_CASE("unaligned heaps", "[multi_heap]")
-{
-    const size_t CHUNK_LEN = 256;
-    const size_t CANARY_LEN = 16;
-    const uint8_t CANARY_BYTE = 0x3E;
-    uint8_t heap_chunk[CHUNK_LEN + CANARY_LEN * 2];
-
-    /* Put some canary bytes before and after the bytes we intend to use for
-       the heap, make sure they aren't ever overwritten */
-    memset(heap_chunk, CANARY_BYTE, CANARY_LEN);
-    memset(heap_chunk + CANARY_LEN + CHUNK_LEN, CANARY_BYTE, CANARY_LEN);
-
-    for (int i = 0; i < 8; i++) {
-        printf("Testing with offset %d\n", i);
-        multi_heap_handle_t heap = multi_heap_register(heap_chunk + CANARY_LEN + i, CHUNK_LEN - i);
-        multi_heap_info_t info;
-
-        REQUIRE( multi_heap_check(heap, true) );
-
-        multi_heap_get_info(heap, &info);
-
-        REQUIRE( info.total_free_bytes > CHUNK_LEN - 64 - i );
-        REQUIRE( info.largest_free_block > CHUNK_LEN - 64 - i );
-
-        void *a = multi_heap_malloc(heap, info.largest_free_block);
-        REQUIRE( a != NULL );
-        memset(a, 0xAA, info.largest_free_block);
-
-        REQUIRE( multi_heap_check(heap, true) );
-
-        multi_heap_free(heap, a);
-
-        REQUIRE( multi_heap_check(heap, true) );
-
-        for (unsigned j = 0; j < CANARY_LEN; j++) { // check canaries
-            REQUIRE( heap_chunk[j] == CANARY_BYTE );
-            REQUIRE( heap_chunk[CHUNK_LEN + CANARY_LEN + j] == CANARY_BYTE );
-        }
-    }
-}
-
+// TLSF only accepts heaps aligned to 4-byte boundary so
+// only aligned allocation tests make sense.
 TEST_CASE("multi_heap aligned allocations", "[multi_heap]")
 {
-    uint8_t test_heap[1024 * 1024];
+    uint8_t test_heap[4 * 1024];
     multi_heap_handle_t heap = multi_heap_register(test_heap, sizeof(test_heap));
     uint32_t aligments = 0; // starts from alignment by 4-byte boundary
     size_t old_size = multi_heap_free_size(heap);
@@ -508,7 +459,7 @@ TEST_CASE("multi_heap aligned allocations", "[multi_heap]")
     multi_heap_dump(heap);
     printf("*********************\n");
 
-    for(;aligments < 500 * 1024; aligments++) {
+    for(;aligments <= 256; aligments++) {
 
         //Use some stupid size value to test correct alignment even in strange
         //memory layout objects:
@@ -525,7 +476,6 @@ TEST_CASE("multi_heap aligned allocations", "[multi_heap]")
             //printf("[ALIGNED_ALLOC] allocated size: %d \n", multi_heap_get_allocated_size(heap, buf));    
             printf("[ALIGNED_ALLOC] address of allocated memory: %p \n\n", (void *)buf);
             //Address of obtained block must be aligned with selected value
-
             if((aligments & 0x03) == 0) {
                 //Alignment is a multiple of four:
                 REQUIRE(((intptr_t)buf & 0x03) == 0);
@@ -538,10 +488,10 @@ TEST_CASE("multi_heap aligned allocations", "[multi_heap]")
             //canary verification will fail:
             memset(buf, 0xA5, (aligments + 137));
 
-            multi_heap_aligned_free(heap, buf);    
+            multi_heap_free(heap, buf);    
         }
     }
 
     printf("[ALIGNED_ALLOC] heap_size after: %d \n", multi_heap_free_size(heap));
     REQUIRE((old_size - multi_heap_free_size(heap)) <= leakage);
-}
+}

+ 9 - 0
components/idf_test/include/idf_performance.h

@@ -154,3 +154,12 @@
 #ifndef IDF_PERFORMANCE_MAX_SCHEDULING_TIME
 #define IDF_PERFORMANCE_MAX_SCHEDULING_TIME                                     2000
 #endif
+
+#ifndef IDF_PERFORMANCE_MAX_MALLOC_DEFAULT_AVERAGE_TIME
+#define IDF_PERFORMANCE_MAX_MALLOC_DEFAULT_AVERAGE_TIME                         2600
+#endif
+
+#ifndef IDF_PERFORMANCE_MAX_FREE_DEFAULT_AVERAGE_TIME
+#define IDF_PERFORMANCE_MAX_FREE_DEFAULT_AVERAGE_TIME                           950
+#endif
+

+ 5 - 8
components/newlib/heap.c

@@ -26,7 +26,6 @@
 extern void *heap_caps_malloc_default( size_t size );
 extern void *heap_caps_realloc_default( void *ptr, size_t size );
 
-
 void* malloc(size_t size)
 {
     return heap_caps_malloc_default(size);
@@ -77,6 +76,11 @@ void* _calloc_r(struct _reent *r, size_t nmemb, size_t size)
     return result;
 }
 
+void* memalign(size_t alignment, size_t n)
+{
+    return heap_caps_aligned_alloc(alignment, n, MALLOC_CAP_DEFAULT);
+}
+
 /* No-op function, used to force linking this file,
    instead of the heap implementation from newlib.
  */
@@ -89,13 +93,6 @@ void newlib_include_heap_impl(void)
    Define them as non-functional stubs here, so that the application
    can not cause the newlib heap implementation to be linked in
  */
-void* memalign(size_t alignment, size_t n)
-{
-    extern void memalign_function_was_linked_but_unsupported_in_esp_idf(void);
-    memalign_function_was_linked_but_unsupported_in_esp_idf();
-    return NULL;
-    
-}
 
 int malloc_trim(size_t pad)
 {

+ 0 - 1
components/pthread/test/test_pthread_local_storage.c

@@ -119,7 +119,6 @@ static void *thread_test_pthread_destructor(void *v_key)
 
 static void test_pthread_destructor(void *value)
 {
-    printf("Destructor called...\n");
     actual_destructor_ptr = value;
 }
 

+ 0 - 1
components/soc/include/soc/spinlock.h

@@ -46,7 +46,6 @@ typedef struct {
 static inline void __attribute__((always_inline)) spinlock_initialize(spinlock_t *lock)
 {
     assert(lock);
-
 #if !CONFIG_FREERTOS_UNICORE
     lock->owner = SPINLOCK_FREE;
     lock->count = 0;

+ 1 - 1
components/wear_levelling/test/test_wl.c

@@ -139,7 +139,7 @@ TEST_CASE("multiple tasks can access wl handle simultaneously", "[wear_levelling
     TEST_ESP_OK(wl_erase_range(handle, 0, sector_size * 8));
     read_write_test_arg_t args1 = READ_WRITE_TEST_ARG_INIT(0, 1, handle, sector_size/sizeof(uint32_t));
     read_write_test_arg_t args2 = READ_WRITE_TEST_ARG_INIT(sector_size, 2, handle, sector_size/sizeof(uint32_t));
-    const size_t stack_size = 4096;
+    const size_t stack_size = 8192;
 
     printf("writing 1 and 2\n");
     const int cpuid_0 = 0;

+ 2 - 0
docs/Doxyfile

@@ -299,6 +299,8 @@ INPUT = \
     $(IDF_PATH)/components/freertos/include/freertos/semphr.h \
     $(IDF_PATH)/components/freertos/include/freertos/timers.h \
     $(IDF_PATH)/components/freertos/include/freertos/event_groups.h \
+    $(IDF_PATH)/components/freertos/include/freertos/stream_buffer.h \
+    $(IDF_PATH)/components/freertos/include/freertos/message_buffer.h \
     ### Ringbuffer
     $(IDF_PATH)/components/esp_ringbuf/include/freertos/ringbuf.h \
     ### Helper functions for error codes

+ 3 - 1
docs/en/COPYRIGHT.rst

@@ -19,7 +19,7 @@ These third party libraries can be included into the application (firmware) prod
 
 * :component:`Xtensa header files<xtensa/include/xtensa>` are Copyright (C) 2013 Tensilica Inc and are licensed under the MIT License as reproduced in the individual header files.
 
-* Original parts of FreeRTOS_ (components/freertos) are Copyright (C) 2015 Real Time Engineers Ltd and is licensed under the GNU General Public License V2 with the FreeRTOS Linking Exception, as described in :component_file:`license.txt<freertos/license.txt>`.
+* Original parts of FreeRTOS_ (components/freertos) are Copyright (C) 2017 Amazon.com, Inc. or its affiliates are licensed under the MIT License, as described in :component_file:`license.txt<freertos/license.txt>`.
 
 * Original parts of LWIP_ (components/lwip) are Copyright (C) 2001, 2002 Swedish Institute of Computer Science and are licensed under the BSD License as described in :component_file:`COPYING file<lwip/lwip/COPYING>`.
 
@@ -65,6 +65,8 @@ These third party libraries can be included into the application (firmware) prod
 
 * `cryptoauthlib`_ Microchip CryptoAuthentication Library - Copyright (c) 2015 - 2018 Microchip Technology Inc, is licensed under common Microchip software License as described in :example_file:`LICENSE file <peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib/cryptoauthlib/LICENSE>`
 
+* :component_file:` TLSF allocator <heap/heap_tlsf.c>` Two Level Segregated Fit memory allocator, Copyright (c) 2006-2016, Matthew Conte, and licensed under the BSD license.
+
 Build Tools
 -----------
 

+ 28 - 106
docs/en/api-guides/freertos-smp.rst

@@ -21,59 +21,47 @@ found via https://www.freertos.org/a00106.html
 For information regarding features that are exclusive to ESP-IDF FreeRTOS,
 see :doc:`ESP-IDF FreeRTOS Additions<../api-reference/system/freertos_additions>`.
 
-:ref:`backported-features`: Although ESP-IDF FreeRTOS is based on the Xtensa
-port of FreeRTOS v8.2.0, a number of FreeRTOS v9.0.0 features have been backported
-to ESP-IDF.
+.. only:: esp32
 
-.. only:: not CONFIG_FREERTOS_UNICORE
-
-  :ref:`tasks-and-task-creation`: Use :cpp:func:`xTaskCreatePinnedToCore` or
-  :cpp:func:`xTaskCreateStaticPinnedToCore` to create tasks in ESP-IDF FreeRTOS. The
-  last parameter of the two functions is ``xCoreID``. This parameter specifies
-  which core the task is pinned to. Acceptable values are ``0`` for **PRO_CPU**,
+  :ref:`tasks-and-task-creation`: Use :cpp:func:`xTaskCreatePinnedToCore` or 
+  :cpp:func:`xTaskCreateStaticPinnedToCore` to create tasks in ESP-IDF FreeRTOS. The 
+  last parameter of the two functions is ``xCoreID``. This parameter specifies 
+  which core the task is pinned to. Acceptable values are ``0`` for **PRO_CPU**, 
   ``1`` for **APP_CPU**, or ``tskNO_AFFINITY`` which allows the task to run on
   both.
 
-  :ref:`round-robin-scheduling`: The ESP-IDF FreeRTOS scheduler will skip tasks when
-  implementing Round-Robin scheduling between multiple tasks in the Ready state
-  that are of the same priority. To avoid this behavior, ensure that those tasks either
+  :ref:`round-robin-scheduling`: The ESP-IDF FreeRTOS scheduler will skip tasks when 
+  implementing Round-Robin scheduling between multiple tasks in the Ready state 
+  that are of the same priority. To avoid this behavior, ensure that those tasks either 
   enter a blocked state, or are distributed across a wider range of priorities.
 
-  :ref:`scheduler-suspension`: Suspending the scheduler in ESP-IDF FreeRTOS will only
-  affect the scheduler on the the calling core. In other words, calling
+  :ref:`scheduler-suspension`: Suspending the scheduler in ESP-IDF FreeRTOS will only 
+  affect the scheduler on the the calling core. In other words, calling 
   :cpp:func:`vTaskSuspendAll` on **PRO_CPU** will not prevent **APP_CPU** from scheduling, and
   vice versa. Use critical sections or semaphores instead for simultaneous
   access protection.
 
-  :ref:`tick-interrupt-synchronicity`: Tick interrupts of **PRO_CPU** and **APP_CPU**
-  are not synchronized. Do not expect to use :cpp:func:`vTaskDelay` or
-  :cpp:func:`vTaskDelayUntil` as an accurate method of synchronizing task execution
-  between the two cores. Use a counting semaphore instead as their context
+  :ref:`tick-interrupt-synchronicity`: Tick interrupts of **PRO_CPU** and **APP_CPU** 
+  are not synchronized. Do not expect to use :cpp:func:`vTaskDelay` or 
+  :cpp:func:`vTaskDelayUntil` as an accurate method of synchronizing task execution 
+  between the two cores. Use a counting semaphore instead as their context 
   switches are not tied to tick interrupts due to preemption.
 
   :ref:`critical-sections`: In ESP-IDF FreeRTOS, critical sections are implemented using
-  mutexes. Entering critical sections involve taking a mutex, then disabling the
-  scheduler and interrupts of the calling core. However the other core is left
+  mutexes. Entering critical sections involve taking a mutex, then disabling the 
+  scheduler and interrupts of the calling core. However the other core is left 
   unaffected. If the other core attemps to take same mutex, it will spin until
   the calling core has released the mutex by exiting the critical section.
 
-  :ref:`floating-points`: The {IDF_TARGET_NAME} supports hardware acceleration of single
+  :ref:`floating-points`: The ESP32 supports hardware acceleration of single
   precision floating point arithmetic (``float``). However the use of hardware
   acceleration leads to some behavioral restrictions in ESP-IDF FreeRTOS.
-  Therefore, tasks that utilize ``float`` will automatically be pinned to a core if
-  not done so already. Furthermore, ``float`` cannot be used in interrupt service
+  Therefore, tasks that utilize ``float`` will automatically be pinned to a core if 
+  not done so already. Furthermore, ``float`` cannot be used in interrupt service 
   routines.
 
-`Task Deletion`_: Task deletion behavior has been backported from FreeRTOS
-v9.0.0 and modified to be SMP compatible. Task memory will be freed immediately
-when :cpp:func:`vTaskDelete` is called to delete a task that is not currently running
-and not pinned to the other core. Otherwise, freeing of task memory will still
-be delegated to the Idle Task.
-
-:ref:`deletion-callbacks`: ESP-IDF FreeRTOS has backported the Thread Local
-Storage Pointers (TLSP) feature. However the extra feature of Deletion Callbacks has been
-added. Deletion callbacks are called automatically during task deletion and are
-used to free memory pointed to by TLSP. Call
+:ref:`deletion-callbacks`: Deletion callbacks are called automatically during task deletion and are
+used to free memory pointed to by TLSP. Call 
 :cpp:func:`vTaskSetThreadLocalStoragePointerAndDelCallback()` to set TLSP and Deletion
 Callbacks.
 
@@ -82,64 +70,6 @@ set in the project configuration (``idf.py menuconfig``) such as running ESP-IDF
 Unicore (single core) Mode, or configuring the number of Thread Local Storage Pointers
 each task will have.
 
-
-.. _backported-features:
-
-Backported Features
--------------------
-
-The following features have been backported from FreeRTOS v9.0.0 to ESP-IDF.
-
-Static Alocation
-^^^^^^^^^^^^^^^^^
-
-This feature has been backported from FreeRTOS v9.0.0 to ESP-IDF. The
-:ref:`CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION` option must be enabled in `menuconfig`
-in order for static allocation functions to be available. Once enabled, the
-following functions can be called...
-
- - :cpp:func:`xTaskCreateStatic` (see :ref:`backporting-notes` below)
- - :c:macro:`xQueueCreateStatic`
- - :c:macro:`xSemaphoreCreateBinaryStatic`
- - :c:macro:`xSemaphoreCreateCountingStatic`
- - :c:macro:`xSemaphoreCreateMutexStatic`
- - :c:macro:`xSemaphoreCreateRecursiveMutexStatic`
- - :cpp:func:`xTimerCreateStatic`  (see :ref:`backporting-notes` below)
- - :cpp:func:`xEventGroupCreateStatic`
-
-Other Features
-^^^^^^^^^^^^^^
-
- - :cpp:func:`vTaskSetThreadLocalStoragePointer` (see :ref:`backporting-notes` below)
- - :cpp:func:`pvTaskGetThreadLocalStoragePointer` (see :ref:`backporting-notes` below)
- - :cpp:func:`vTimerSetTimerID`
- - :cpp:func:`xTimerGetPeriod`
- - :cpp:func:`xTimerGetExpiryTime`
- - :cpp:func:`pcQueueGetName`
- - :c:macro:`uxSemaphoreGetCount`
-
-.. _backporting-notes:
-
-Backporting Notes
-^^^^^^^^^^^^^^^^^
-
-**1)** :cpp:func:`xTaskCreateStatic` has been made SMP compatible in a similar
-fashion to :cpp:func:`xTaskCreate` (see :ref:`tasks-and-task-creation`). Therefore
-:cpp:func:`xTaskCreateStaticPinnedToCore` can also be called.
-
-**2)** Although vanilla FreeRTOS allows the Timer feature's daemon task to
-be statically allocated, the daemon task is always dynamically allocated in
-ESP-IDF. Therefore ``vApplicationGetTimerTaskMemory`` **does not** need to be
-defined when using statically allocated timers in ESP-IDF FreeRTOS.
-
-**3)** The Thread Local Storage Pointer feature has been modified in ESP-IDF
-FreeRTOS to include Deletion Callbacks (see :ref:`deletion-callbacks`). Therefore
-the function :cpp:func:`vTaskSetThreadLocalStoragePointerAndDelCallback` can also be
-called.
-
-
-
-
 .. _tasks-and-task-creation:
 
 Tasks and Task Creation
@@ -149,9 +79,9 @@ Tasks in ESP-IDF FreeRTOS are designed to run on a particular core, therefore
 two new task creation functions have been added to ESP-IDF FreeRTOS by
 appending ``PinnedToCore`` to the names of the task creation functions in
 vanilla FreeRTOS. The vanilla FreeRTOS functions of :cpp:func:`xTaskCreate`
-and :cpp:func:`xTaskCreateStatic` have led to the addition of
-:cpp:func:`xTaskCreatePinnedToCore` and :cpp:func:`xTaskCreateStaticPinnedToCore` in
-ESP-IDF FreeRTOS (see :ref:`backported-features`).
+and :cpp:func:`xTaskCreateStatic` have led to the addition of 
+:cpp:func:`xTaskCreatePinnedToCore` and :cpp:func:`xTaskCreateStaticPinnedToCore` in 
+ESP-IDF FreeRTOS 
 
 For more details see :component_file:`freertos/tasks.c`
 
@@ -434,10 +364,9 @@ matter.
 Task Deletion
 -------------
 
-FreeRTOS task deletion prior to v9.0.0 delegated the freeing of task memory
-entirely to the Idle Task. Currently, the freeing of task memory will occur
-immediately (within :cpp:func:`vTaskDelete`) if the task being deleted is not currently
-running or is not pinned to the other core (with respect to the core
+In FreeRTOS task deletion the freeing of task memory will occur
+immediately (within :cpp:func:`vTaskDelete`) if the task being deleted is not currently 
+running or is not pinned to the other core (with respect to the core 
 :cpp:func:`vTaskDelete` is called on). TLSP deletion callbacks will also run immediately
 if the same conditions are met.
 
@@ -479,9 +408,6 @@ called for that TLSP during task deletion. If a deletion callback is `NULL`,
 users should manually free the memory pointed to by the associated TLSP before
 task deletion in order to avoid memory leak.
 
-:ref:`CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS` in menuconfig can be used
-to configure the number TLSP and Deletion Callbacks a TCB will have.
-
 For more details see :doc:`FreeRTOS API reference<../api-reference/system/freertos>`.
 
 
@@ -512,11 +438,7 @@ ESP-IDF FreeRTOS configurations, see :doc:`FreeRTOS <../api-reference/kconfig>`
     will be modified. For more details regarding the effects of running ESP-IDF FreeRTOS
     on a single core, search for occurences of ``CONFIG_FREERTOS_UNICORE`` in the ESP-IDF components.
 
-:ref:`CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS` will define the
-number of Thread Local Storage Pointers each task will have in ESP-IDF
-FreeRTOS.
-
-:ref:`CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION` will enable the backported
+:ref:`CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION` will enable the 
 functionality of :cpp:func:`xTaskCreateStaticPinnedToCore` in ESP-IDF FreeRTOS
 
 :ref:`CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION` will trigger a halt in

+ 10 - 1
docs/en/api-reference/system/freertos.rst

@@ -7,7 +7,7 @@ Overview
 This section contains documentation of FreeRTOS types, functions, and macros. It is automatically generated from FreeRTOS header files.
 
 .. note::
-    ESP-IDF FreeRTOS is based on the Xtensa port of FreeRTOS v8.2.0, however some functions of FreeRTOS v9.0.0 have been backported. See the :ref:`backported-features` for more information.
+    ESP-IDF FreeRTOS is based on the Xtensa port of FreeRTOS v10.2.0,
 
 For more information about FreeRTOS features specific to ESP-IDF, see :doc:`ESP-IDF FreeRTOS SMP Changes<../../api-guides/freertos-smp>`
 and :doc:`ESP-IDF FreeRTOS Additions<freertos_additions>`.
@@ -39,4 +39,13 @@ Event Group API
 
 .. include-build-file:: inc/event_groups.inc
 
+Stream Buffer API
+-----------------
 
+.. include-build-file:: inc/stream_buffer.inc
+
+
+Message Buffer API
+------------------
+
+.. include-build-file:: inc/message_buffer.inc

+ 1 - 1
examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/main.c

@@ -362,7 +362,7 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
         do {
             int tmr_id = 0;
             s_tmr = xTimerCreate("connTmr", (10000 / portTICK_RATE_MS),
-                               pdTRUE, (void *)tmr_id, a2d_app_heart_beat);
+                               pdTRUE, (void *) &tmr_id, a2d_app_heart_beat);
             xTimerStart(s_tmr, portMAX_DELAY);
         } while (0);
         break;

+ 1 - 1
examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/spp_task.c

@@ -102,7 +102,7 @@ static void spp_task_task_handler(void *arg)
 void spp_task_task_start_up(void)
 {
     spp_task_task_queue = xQueueCreate(10, sizeof(spp_task_msg_t));
-    xTaskCreate(spp_task_task_handler, "SPPAppT", 2048, NULL, 10, spp_task_task_handle);
+    xTaskCreate(spp_task_task_handler, "SPPAppT", 2048, NULL, 10, &spp_task_task_handle);
     return;
 }
 

+ 1 - 1
examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/components/case/sync.c

@@ -424,7 +424,7 @@ static void handle_sync_timeout(void *arg)
     static bool run_first = true;
     if (run_first == true) {
         xSemaphoreTake((SemaphoreHandle_t)arg, (portTickType)portMAX_DELAY);
-        esp_timer_start_periodic( (SemaphoreHandle_t)arg, 1000000);
+        esp_timer_start_periodic( (esp_timer_handle_t)arg, 1000000);
         run_first = false;
     }
     switch (sync_obj.state) {

+ 1 - 1
tools/ci/config/target-test.yml

@@ -592,7 +592,7 @@ UT_034:
 
 UT_035:
   extends: .unit_test_s2_template
-  parallel: 41
+  parallel: 42
   tags:
     - ESP32S2_IDF
     - UT_T1_1

+ 1 - 1
tools/ci/static-analysis-rules.yml

@@ -20,4 +20,4 @@ skip:
   - "components/nghttp/nghttp2"
   - "components/protobuf-c/protobuf-c"
   - "components/spiffs/spiffs"
-  - "components/unity/unity"
+  - "components/unity/unity"

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff