]> granicus.if.org Git - esp-idf/commitdiff
heap: Support adding new heap regions at runtime
authorAngus Gratton <angus@espressif.com>
Mon, 28 Aug 2017 07:12:29 +0000 (17:12 +1000)
committerAngus Gratton <gus@projectgus.com>
Tue, 5 Sep 2017 04:07:02 +0000 (14:07 +1000)
To facilitate this, the list of registered heap regions is now a linked list
(allowing entries to be appended at runtime.)

components/esp32/cpu_start.c
components/heap/heap_caps.c
components/heap/heap_caps_init.c
components/heap/heap_private.h
components/heap/include/esp_heap_caps.h
components/heap/include/esp_heap_caps_init.h [new file with mode: 0644]
components/heap/test/test_runtime_heap_reg.c [new file with mode: 0644]
docs/Doxyfile
docs/api-reference/system/mem_alloc.rst
tools/unit-test-app/sdkconfig

index 8650290cf06d7f6563109ace816075189a14cf06..facc27e8bcea40b276d8c9e44cf8d8cf98def8e8 100644 (file)
@@ -40,7 +40,7 @@
 
 #include "tcpip_adapter.h"
 
-#include "esp_heap_caps.h"
+#include "esp_heap_caps_init.h"
 #include "sdkconfig.h"
 #include "esp_system.h"
 #include "esp_spi_flash.h"
index 137d1a1607e68f1c2179d6aba371b1e1fb7323cc..7993e371370c171de8ecc54c789b2241bee32369 100644 (file)
@@ -94,8 +94,8 @@ IRAM_ATTR void *heap_caps_malloc( size_t size, uint32_t caps )
     }
     for (int prio = 0; prio < SOC_MEMORY_TYPE_NO_PRIOS; prio++) {
         //Iterate over heaps and check capabilities at this priority
-        for (int heap_idx = 0; heap_idx < num_registered_heaps; heap_idx++) {
-            heap_t *heap = &registered_heaps[heap_idx];
+        heap_t *heap;
+        SLIST_FOREACH(heap, &registered_heaps, next) {
             if (heap->heap == NULL) {
                 continue;
             }
@@ -142,8 +142,8 @@ IRAM_ATTR void *heap_caps_malloc( size_t size, uint32_t caps )
 IRAM_ATTR static heap_t *find_containing_heap(void *ptr )
 {
     intptr_t p = (intptr_t)ptr;
-    for (size_t i = 0; i < num_registered_heaps; i++) {
-        heap_t *heap = &registered_heaps[i];
+    heap_t *heap;
+    SLIST_FOREACH(heap, &registered_heaps, next) {
         if (heap->heap != NULL && p >= heap->start && p < heap->end) {
             return heap;
         }
@@ -216,8 +216,8 @@ IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, int caps)
 size_t heap_caps_get_free_size( uint32_t caps )
 {
     size_t ret = 0;
-    for (int i = 0; i < num_registered_heaps; i++) {
-        heap_t *heap = &registered_heaps[i];
+    heap_t *heap;
+    SLIST_FOREACH(heap, &registered_heaps, next) {
         if (heap_caps_match(heap, caps)) {
             ret += multi_heap_free_size(heap->heap);
         }
@@ -228,8 +228,8 @@ size_t heap_caps_get_free_size( uint32_t caps )
 size_t heap_caps_get_minimum_free_size( uint32_t caps )
 {
     size_t ret = 0;
-    for (int i = 0; i < num_registered_heaps; i++) {
-        heap_t *heap = &registered_heaps[i];
+    heap_t *heap;
+    SLIST_FOREACH(heap, &registered_heaps, next) {
         if (heap_caps_match(heap, caps)) {
             ret += multi_heap_minimum_free_size(heap->heap);
         }
@@ -248,8 +248,8 @@ void heap_caps_get_info( multi_heap_info_t *info, uint32_t caps )
 {
     bzero(info, sizeof(multi_heap_info_t));
 
-    for (int i = 0; i < num_registered_heaps; i++) {
-        heap_t *heap = &registered_heaps[i];
+    heap_t *heap;
+    SLIST_FOREACH(heap, &registered_heaps, next) {
         if (heap_caps_match(heap, caps)) {
             multi_heap_info_t hinfo;
             multi_heap_get_info(heap->heap, &hinfo);
@@ -270,8 +270,8 @@ void heap_caps_print_heap_info( uint32_t caps )
 {
     multi_heap_info_t info;
     printf("Heap summary for capabilities 0x%08X:\n", caps);
-    for (int i = 0; i < num_registered_heaps; i++) {
-        heap_t *heap = &registered_heaps[i];
+    heap_t *heap;
+    SLIST_FOREACH(heap, &registered_heaps, next) {
         if (heap_caps_match(heap, caps)) {
             multi_heap_get_info(heap->heap, &info);
 
index eac375011c30c3ad9b572f9070d60f51cf560a22..36d75674deef6e7d1dd2d82418d6db41ab9f9d4b 100644 (file)
 #include "heap_private.h"
 #include <assert.h>
 #include <string.h>
-#include <esp_log.h>
-#include <multi_heap.h>
-#include <esp_heap_caps.h>
-#include <soc/soc_memory_layout.h>
+#include <sys/lock.h>
+
+#include "esp_log.h"
+#include "multi_heap.h"
+#include "esp_heap_caps_init.h"
+#include "soc/soc_memory_layout.h"
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
 
 static const char *TAG = "heap_init";
 
-heap_t *registered_heaps;
-size_t num_registered_heaps;
+/* Linked-list of registered heaps */
+struct registered_heap_ll registered_heaps;
 
 static void register_heap(heap_t *region)
 {
@@ -34,10 +39,10 @@ static void register_heap(heap_t *region)
 
 void heap_caps_enable_nonos_stack_heaps()
 {
-    for (int i = 0; i < num_registered_heaps; i++) {
+    heap_t *heap;
+    SLIST_FOREACH(heap, &registered_heaps, next) {
         // Assume any not-yet-registered heap is
         // a nonos-stack heap
-        heap_t *heap = &registered_heaps[i];
         if (heap->heap == NULL) {
             register_heap(heap);
             if (heap->heap != NULL) {
@@ -125,10 +130,10 @@ void heap_caps_init()
     }
 
     /* Count the heaps left after merging */
-    num_registered_heaps = 0;
+    size_t num_heaps = 0;
     for (int i = 0; i < soc_memory_region_count; i++) {
         if (regions[i].type != -1) {
-            num_registered_heaps++;
+            num_heaps++;
         }
     }
 
@@ -136,7 +141,7 @@ void heap_caps_init()
 
        Once we have a heap to copy it to, we will copy it to a heap buffer.
     */
-    heap_t temp_heaps[num_registered_heaps];
+    heap_t temp_heaps[num_heaps];
     size_t heap_idx = 0;
 
     ESP_EARLY_LOGI(TAG, "Initializing. RAM available for dynamic allocation:");
@@ -148,47 +153,112 @@ void heap_caps_init()
             continue;
         }
         heap_idx++;
-        assert(heap_idx <= num_registered_heaps);
+        assert(heap_idx <= num_heaps);
 
-        heap->type = region->type;
+        memcpy(heap->caps, type->caps, sizeof(heap->caps));
         heap->start = region->start;
         heap->end = region->start + region->size;
-        memcpy(heap->caps, type->caps, sizeof(heap->caps));
         vPortCPUInitializeMutex(&heap->heap_mux);
-
-        ESP_EARLY_LOGI(TAG, "At %08X len %08X (%d KiB): %s",
-                       region->start, region->size, region->size / 1024, type->name);
-
         if (type->startup_stack) {
             /* Will be registered when OS scheduler starts */
             heap->heap = NULL;
         } else {
             register_heap(heap);
         }
+        SLIST_NEXT(heap, next) = NULL;
+
+        ESP_EARLY_LOGI(TAG, "At %08X len %08X (%d KiB): %s",
+                       region->start, region->size, region->size / 1024, type->name);
     }
 
-    assert(heap_idx == num_registered_heaps);
+    assert(heap_idx == num_heaps);
+
+    /* Allocate the permanent heap data that we'll use as a linked list at runtime.
+
+       Allocate this part of data contiguously, even though it's a linked list... */
+    assert(SLIST_EMPTY(&registered_heaps));
 
-    /* Allocate the permanent heap data that we'll use for runtime */
-    registered_heaps = NULL;
-    for (int i = 0; i < num_registered_heaps; i++) {
+    heap_t *heaps_array = NULL;
+    for (int i = 0; i < num_heaps; i++) {
         if (heap_caps_match(&temp_heaps[i], MALLOC_CAP_8BIT)) {
             /* use the first DRAM heap which can fit the data */
-            registered_heaps = multi_heap_malloc(temp_heaps[i].heap, sizeof(heap_t) * num_registered_heaps);
-            if (registered_heaps != NULL) {
+            heaps_array = multi_heap_malloc(temp_heaps[i].heap, sizeof(heap_t) * num_heaps);
+            if (heaps_array != NULL) {
                 break;
             }
         }
     }
-    assert(registered_heaps != NULL); /* if NULL, there's not enough free startup heap space */
+    assert(heaps_array != NULL); /* if NULL, there's not enough free startup heap space */
+
+    memcpy(heaps_array, temp_heaps, sizeof(heap_t)*num_heaps);
+
+    /* Iterate the heaps and set their locks, also add them to the linked list. */
+    for (int i = 0; i < num_heaps; i++) {
+        if (heaps_array[i].heap != NULL) {
+            multi_heap_set_lock(heaps_array[i].heap, &heaps_array[i].heap_mux);
+        }
+        if (i == 0) {
+            SLIST_INSERT_HEAD(&registered_heaps, &heaps_array[0], next);
+        } else {
+            SLIST_INSERT_AFTER(&heaps_array[i-1], &heaps_array[i], next);
+        }
+    }
+}
 
-    memcpy(registered_heaps, temp_heaps, sizeof(heap_t)*num_registered_heaps);
+esp_err_t heap_caps_add_region(intptr_t start, intptr_t end)
+{
+    if (start == 0) {
+        return ESP_ERR_INVALID_ARG;
+    }
 
-    /* Now the heap_mux fields live on the heap, assign them */
-    for (int i = 0; i < num_registered_heaps; i++) {
-        if (registered_heaps[i].heap != NULL) {
-            multi_heap_set_lock(registered_heaps[i].heap, &registered_heaps[i].heap_mux);
+    for (int i = 0; i < soc_memory_region_count; i++) {
+        const soc_memory_region_t *region = &soc_memory_regions[i];
+        if (region->start <= start && (region->start + region->size) > end) {
+            const uint32_t *caps = soc_memory_types[region->type].caps;
+            return heap_caps_add_region_with_caps(caps, start, end);
         }
     }
+
+    return ESP_ERR_NOT_FOUND;
 }
 
+esp_err_t heap_caps_add_region_with_caps(const uint32_t caps[], intptr_t start, intptr_t end)
+{
+    esp_err_t err = ESP_FAIL;
+    if (caps == NULL || start == 0 || end == 0 || end < start) {
+        return ESP_ERR_INVALID_ARG;
+    }
+
+    heap_t *p_new = malloc(sizeof(heap_t));
+    if (p_new == NULL) {
+        err = ESP_ERR_NO_MEM;
+        goto done;
+    }
+    memcpy(p_new->caps, caps, sizeof(p_new->caps));
+    p_new->start = start;
+    p_new->end = end;
+    vPortCPUInitializeMutex(&p_new->heap_mux);
+    p_new->heap = multi_heap_register((void *)start, end - start);
+    SLIST_NEXT(p_new, next) = NULL;
+    if (p_new->heap == NULL) {
+        err = ESP_FAIL;
+        goto done;
+    }
+    multi_heap_set_lock(p_new->heap, &p_new->heap_mux);
+
+    /* (This insertion is atomic to registered_heaps, so
+       we don't need to worry about thread safety for readers,
+       only for writers. */
+    static _lock_t registered_heaps_write_lock;
+    _lock_acquire(&registered_heaps_write_lock);
+    SLIST_INSERT_HEAD(&registered_heaps, p_new, next);
+    _lock_release(&registered_heaps_write_lock);
+
+    err = ESP_OK;
+
+ done:
+    if (err != ESP_OK) {
+        free(p_new);
+    }
+    return err;
+}
index e655e80608024300323a10a814b9193cf7d4886c..58ce307f63cd04ad0bd16ee5dce2fb95962b0e3a 100644 (file)
 #include <freertos/FreeRTOS.h>
 #include <soc/soc_memory_layout.h>
 #include "multi_heap.h"
+#include "rom/queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /* Some common heap registration data structures used
    for heap_caps_init.c to share heap information with heap_caps.c
 */
 
 /* Type for describing each registered heap */
-typedef struct {
-    size_t type;
+typedef struct heap_t_ {
     uint32_t caps[SOC_MEMORY_TYPE_NO_PRIOS]; ///< Capabilities for the type of memory in this heap (as a prioritised set). Copied from soc_memory_types so it's in RAM not flash.
     intptr_t start;
     intptr_t end;
     portMUX_TYPE heap_mux;
     multi_heap_handle_t heap;
+    SLIST_ENTRY(heap_t_) next;
 } heap_t;
 
-extern heap_t *registered_heaps;
-extern size_t num_registered_heaps;
+/* All registered heaps.
+
+   Forms a single linked list, even though most entries are contiguous.
+   This means at the expense of 4 bytes per heap, new heaps can be
+   added at runtime in a fast & thread-safe way.
+*/
+extern SLIST_HEAD(registered_heap_ll, heap_t_) registered_heaps;
 
 bool heap_caps_match(const heap_t *heap, uint32_t caps);
 
+#ifdef __cplusplus
+}
+#endif
index 26bc2abebb77ef049804bbb7306759b76818a443..23c310fa26d5fea652856f1e1b0026f82d5b5054 100644 (file)
 #define MALLOC_CAP_SPISRAM          (1<<10) ///< Memory must be in SPI SRAM
 #define MALLOC_CAP_INVALID          (1<<31) ///< Memory can't be used / list end marker
 
-
-/**
- * @brief Initialize the capability-aware heap allocator.
- *
- * This is called once in the IDF startup code. Do not call it
- * at other times.
- */
-void heap_caps_init();
-
-/**
- * @brief Enable heap(s) in memory regions where the startup stacks are located.
- *
- * On startup, the pro/app CPUs have a certain memory region they use as stack, so we
- * cannot do allocations in the regions these stack frames are. When FreeRTOS is
- * completely started, they do not use that memory anymore and heap(s) there can
- * be enabled.
- */
-void heap_caps_enable_nonos_stack_heaps();
-
 /**
  * @brief Allocate a chunk of memory which has the given capabilities
  *
diff --git a/components/heap/include/esp_heap_caps_init.h b/components/heap/include/esp_heap_caps_init.h
new file mode 100644 (file)
index 0000000..b29e785
--- /dev/null
@@ -0,0 +1,83 @@
+// Copyright 2017 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#pragma once
+
+#include "esp_err.h"
+#include "esp_heap_caps.h"
+#include "soc/soc_memory_layout.h"
+
+/**
+ * @brief Initialize the capability-aware heap allocator.
+ *
+ * This is called once in the IDF startup code. Do not call it
+ * at other times.
+ */
+void heap_caps_init();
+
+/**
+ * @brief Enable heap(s) in memory regions where the startup stacks are located.
+ *
+ * On startup, the pro/app CPUs have a certain memory region they use as stack, so we
+ * cannot do allocations in the regions these stack frames are. When FreeRTOS is
+ * completely started, they do not use that memory anymore and heap(s) there can
+ * be enabled.
+ */
+void heap_caps_enable_nonos_stack_heaps();
+
+/**
+ * @brief Add a region of memory to the collection of heaps at runtime.
+ *
+ * Most memory regions are defined in soc_memory_layout.c for the SoC,
+ * and are registered via heap_caps_init(). Some regions can't be used
+ * immediately and are later enabled via heap_caps_enable_nonos_stack_heaps().
+ *
+ * Call this function to add a region of memory to the heap at some later time.
+ *
+ * This function does not consider any of the "reserved" regions or other data in soc_memory_layout, caller needs to
+ * consider this themselves.
+ *
+ * All memory within the region specified by start & end parameters must be otherwise unused.
+ *
+ * The capabilities of the newly registered memory will be determined by the start address, as looked up in the regions
+ * specified in soc_memory_layout.c.
+ *
+ * Use heap_caps_add_region_with_caps() to register a region with custom capabilities.
+ *
+ * @param start Start address of new region.
+ * @param end End address of new region.
+ *
+ * @return ESP_OK on success, ESP_ERR_INVALID_ARG if a parameter is invalid, ESP_ERR_NOT_FOUND if the
+ * specified start address doesn't reside in a known region, or any error returned by heap_caps_add_region_with_caps().
+ */
+esp_err_t heap_caps_add_region(intptr_t start, intptr_t end);
+
+
+/**
+ * @brief Add a region of memory to the collection of heaps at runtime, with custom capabilities.
+ *
+ * Similar to heap_caps_add_region(), only custom memory capabilities are specified by the caller.
+ *
+ * @param caps Ordered array of capability masks for the new region, in order of priority. Must have length
+ * SOC_MEMORY_TYPE_NO_PRIOS. Does not need to remain valid after the call returns.
+ * @param start Start address of new region.
+ * @param end End address of new region.
+ *
+ * @return ESP_OK on success, ESP_ERR_INVALID_ARG if a parameter is invalid, ESP_ERR_NO_MEM if no
+ * memory to register new heap.
+ */
+esp_err_t heap_caps_add_region_with_caps(const uint32_t caps[], intptr_t start, intptr_t end);
+
+
+
+
diff --git a/components/heap/test/test_runtime_heap_reg.c b/components/heap/test/test_runtime_heap_reg.c
new file mode 100644 (file)
index 0000000..766e5ce
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ Tests for registering new heap memory at runtime
+*/
+
+#include <stdio.h>
+#include "unity.h"
+#include "esp_heap_caps_init.h"
+#include "esp_system.h"
+#include <stdlib.h>
+
+
+/* NOTE: This is not a well-formed unit test, it leaks memory */
+TEST_CASE("Allocate new heap at runtime", "[heap][ignore]")
+{
+    const size_t BUF_SZ = 1000;
+    const size_t HEAP_OVERHEAD_MAX = 200;
+    void *buffer = malloc(BUF_SZ);
+    TEST_ASSERT_NOT_NULL(buffer);
+    uint32_t before_free = esp_get_free_heap_size();
+    TEST_ESP_OK( heap_caps_add_region((intptr_t)buffer, (intptr_t)buffer + BUF_SZ) );
+    uint32_t after_free = esp_get_free_heap_size();
+    printf("Before %u after %u\n", before_free, after_free);
+    /* allow for some 'heap overhead' from accounting structures */
+    TEST_ASSERT(after_free > before_free + BUF_SZ - HEAP_OVERHEAD_MAX);
+}
+
+/* NOTE: This is not a well-formed unit test, it leaks memory and
+   may fail if run twice in a row without a reset.
+*/
+TEST_CASE("Allocate new heap with new capability", "[heap][ignore]")
+{
+    const size_t BUF_SZ = 100;
+    const size_t ALLOC_SZ = 64; // More than half of BUF_SZ
+    const uint32_t MALLOC_CAP_INVENTED = (1<<30); /* this must be unused in esp_heap_caps.h */
+
+    /* no memory exists to provide this capability */
+    TEST_ASSERT_NULL( heap_caps_malloc(ALLOC_SZ, MALLOC_CAP_INVENTED) );
+
+    void *buffer = malloc(BUF_SZ);
+    TEST_ASSERT_NOT_NULL(buffer);
+    uint32_t caps[SOC_MEMORY_TYPE_NO_PRIOS] = { MALLOC_CAP_INVENTED };
+    TEST_ESP_OK( heap_caps_add_region_with_caps(caps, (intptr_t)buffer, (intptr_t)buffer + BUF_SZ) );
+
+    /* ta-da, it's now possible! */
+    TEST_ASSERT_NOT_NULL( heap_caps_malloc(ALLOC_SZ, MALLOC_CAP_INVENTED) );
+}
+
index 5f8c07dabf99d75bb5e7d59559fea492c7ad364b..f71c5522681b98766c0246255aa7ef788225bc19 100644 (file)
@@ -109,6 +109,7 @@ INPUT = \
     ##
     ## Memory Allocation    #
     ../components/heap/include/esp_heap_caps.h \
+    ../components/heap/include/esp_heap_caps_init.h \
     ../components/heap/include/multi_heap.h \
     ## Interrupt Allocation
     ../components/esp32/include/esp_intr_alloc.h \
index 852714f92961277129d6d951b7306241e68abe5a..41372d931bfa85f517414788aa9c61f2e0152220 100644 (file)
@@ -31,7 +31,13 @@ API Reference - Heap Allocation
 
 .. include:: /_build/inc/esp_heap_caps.inc
 
+API Reference - Initialisation
+------------------------------
+
+.. include:: /_build/inc/esp_heap_caps_init.inc
+
 API Reference - Heap Regions
 ----------------------------
 
 .. include:: /_build/inc/multi_heap.inc
+
index 25697d0bcf9b06a46781bc36c79b06a7bceef2db..d95e91b0e5ab61c7816a3ddc9def58eea86103c2 100644 (file)
@@ -134,7 +134,13 @@ CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32
 CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2048
 CONFIG_MAIN_TASK_STACK_SIZE=4096
 CONFIG_IPC_TASK_STACK_SIZE=1024
-CONFIG_NEWLIB_STDOUT_ADDCR=y
+CONFIG_TIMER_TASK_STACK_SIZE=4096
+CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y
+# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set
+# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set
+# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set
+# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set
+CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y
 # CONFIG_NEWLIB_NANO_FORMAT is not set
 CONFIG_CONSOLE_UART_DEFAULT=y
 # CONFIG_CONSOLE_UART_CUSTOM is not set
@@ -174,6 +180,7 @@ CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000
 # CONFIG_ESP32_XTAL_FREQ_26 is not set
 CONFIG_ESP32_XTAL_FREQ_AUTO=y
 CONFIG_ESP32_XTAL_FREQ=0
+# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set
 # CONFIG_NO_BLOBS is not set
 
 #
@@ -191,13 +198,21 @@ CONFIG_ESP32_WIFI_RX_BA_WIN=6
 CONFIG_ESP32_WIFI_NVS_ENABLED=y
 
 #
-# PHY
+# Phy
 #
 CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y
 # CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set
 CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20
 CONFIG_ESP32_PHY_MAX_TX_POWER=20
 
+#
+# Ethernet
+#
+CONFIG_DMA_RX_BUF_NUM=10
+CONFIG_DMA_TX_BUF_NUM=10
+# CONFIG_EMAC_L2_TO_L3_RX_BUF_MODE is not set
+CONFIG_EMAC_TASK_PRIORITY=20
+
 #
 # FAT Filesystem support
 #
@@ -317,6 +332,72 @@ CONFIG_MBEDTLS_MPI_USE_INTERRUPT=y
 CONFIG_MBEDTLS_HARDWARE_SHA=y
 CONFIG_MBEDTLS_HAVE_TIME=y
 # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set
+CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y
+# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set
+# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set
+# CONFIG_MBEDTLS_TLS_DISABLED is not set
+CONFIG_MBEDTLS_TLS_SERVER=y
+CONFIG_MBEDTLS_TLS_CLIENT=y
+CONFIG_MBEDTLS_TLS_ENABLED=y
+
+#
+# TLS Key Exchange Methods
+#
+# CONFIG_MBEDTLS_PSK_MODES is not set
+CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y
+CONFIG_MBEDTLS_SSL_RENEGOTIATION=y
+# CONFIG_MBEDTLS_SSL_PROTO_SSL3 is not set
+CONFIG_MBEDTLS_SSL_PROTO_TLS1=y
+CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y
+CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y
+# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set
+CONFIG_MBEDTLS_SSL_ALPN=y
+CONFIG_MBEDTLS_SSL_SESSION_TICKETS=y
+
+#
+# Symmetric Ciphers
+#
+CONFIG_MBEDTLS_AES_C=y
+# CONFIG_MBEDTLS_CAMELLIA_C is not set
+# CONFIG_MBEDTLS_DES_C is not set
+CONFIG_MBEDTLS_RC4_DISABLED=y
+# CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT is not set
+# CONFIG_MBEDTLS_RC4_ENABLED is not set
+# CONFIG_MBEDTLS_BLOWFISH_C is not set
+# CONFIG_MBEDTLS_XTEA_C is not set
+CONFIG_MBEDTLS_CCM_C=y
+CONFIG_MBEDTLS_GCM_C=y
+# CONFIG_MBEDTLS_RIPEMD160_C is not set
+
+#
+# Certificates
+#
+CONFIG_MBEDTLS_PEM_PARSE_C=y
+CONFIG_MBEDTLS_PEM_WRITE_C=y
+CONFIG_MBEDTLS_X509_CRL_PARSE_C=y
+CONFIG_MBEDTLS_X509_CSR_PARSE_C=y
+CONFIG_MBEDTLS_ECP_C=y
+CONFIG_MBEDTLS_ECDH_C=y
+CONFIG_MBEDTLS_ECDSA_C=y
+CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y
+CONFIG_MBEDTLS_ECP_NIST_OPTIM=y
 
 #
 # OpenSSL
@@ -331,6 +412,11 @@ CONFIG_OPENSSL_ASSERT_DO_NOTHING=y
 # CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set
 CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y
 
+#
+# tcpip adapter
+#
+CONFIG_IP_LOST_TIMER_INTERVAL=120
+
 #
 # Wear Levelling
 #