==================================================
Optimizing Bluetooth Low Energy Stack Memory Usage
==================================================

Configuration of the Bluetooth Low Energy protocol stack is
essential for maximizing the amount of RAM and flash memory
available for the application. Refer to :ref:`stack_features_configuration`
to configure parameters that impact runtime RAM usage, such as the maximum
allowable size and number of PDUs. The TI Bluetooth Low Energy
protocol stack is implemented to use a small RAM footprint, and
allow the application to control the behavior of the stack by using
the runtime ICall heap. For example, an application that only sends
one GATT notification per connection event must store only one PDU
in the heap, whereas as an application that must send multiple
notifications must enqueue multiple PDUs in the heap.

To increase the available flash memory allocated to the application
project, minimize the flash usage of the protocol stack by including
only Bluetooth Low Energy features required to implement the defined
role of the device. The available protocol stack configurable
features are described in :ref:`stack_features_configuration`.
Adding additional features to the protocol stack has the net effect
of reducing the amount of flash memory to the application.

Flash optimization
^^^^^^^^^^^^^^^^^^

The following tips may be useful for reducing the footprint of the |STACK|.
In general, there is a feature vs. flash footprint trade-off. Each of the
improvements below offer a cost in terms of feature removal.

* Use only one page of SNV option under the Advanced Settings of the BLE stack in the syscfg file.

* Remove or exclude the Menu Module (located in the Common folder) or other unused drivers from
  your project.

* Use the syscfg file to choose only necessary functionality to pull in the smallest part possible of the library for the given 
  use case. In general, this means a library that implements only one role (e.g. peripheral)
  with no additional features enabled (i.e. L2CAP CoC). See
  :ref:`stack_features_configuration`.

* Remove HAL Asserts by unchecking the ``HAL_ASSERT`` option under the advanced settings of the BLE stack in the syscfg file.

* Verify that your application uses the *optimize for flash size* compiler
  optimization settings (For TIClang it is implemented with the -z flag).

* Enable the Link-Time Optimization (LTO) at the Arm Compiler section
  (optimization symbol: ``-flto``). To do so, right click on the project
  and select ``Properties`` |rarr| ``Build`` |rarr| ``Arm Compiler``
  |rarr| ``Optimization`` |rarr| ``Select Link-Time Optimization (LTO)``.

.. warning::

  LTO is disable by default and it is up to the user to enable it.
  However, for this current SDK version only some initial tests have been completed to evaluate the impact
  of enabling this optimization on the program behavior. Therefore, it is not yet recommended to enable it
  for production purposes.

RAM optimization
^^^^^^^^^^^^^^^^

The following tips may be useful for reducing the RAM footprint of the |STACK|.
It is important to remember that often removing RAM results in reduced
throughput or features, the tradeoffs listed below should be evaluated
carefully.

.. 
  #comments
  The following bullet is commented out. Remove the comment directive to
  re-integrate it if or when necessary.

  * If using L2CAP CoC, reference :ref:`l2cap-ram` for defines that may configure
    L2CAP CoC functionality and their RAM implications

* Set ``MAX_NUM_PDU`` and ``MAX_PDU_SIZE`` to reduce the amount of packets
  that can be queued up by the stack at a time. This will reduce heap
  consumption with the tradeoff of bandwidth. They can be set under the General Configuration 
  of the BLE stack in the syscfg file.

* The LE Data Length Extension feature will default to an RX size of 251.
  If the peer device also supports DLE and a ``connMaxRxOctets`` value is
  negotiated > 27 (default) then the controller will allocate
  connMaxRxOctets*4. 4 is the number of receive buffers in the
  controller and is a fixed parameter of the stack. However, connMaxRxOctets
  can be limited by either disabling Data Length Extension or limiting the
  max of TX and RX octets. Trimming the values of TX and RX is covered in
  :ref:`sec-ram-considerations-dle`.

* Carefully set ``MAX_NUM_BLE_CONNS`` under the General Configuration section 
  of the BLE stack in the syscfg file. This define has a large effect on the
  amount of dynamic memory used by the stack. Below are examples of structures
  that the stack will allocate on initialization based on number of Connections.
  Each structure is multiplied by ``MAX_NUM_BLE_CONNS``

    - ``rxDataQ_t`` : Each connection's receive queue
    - ``rxDataQ_t`` : Each connection's receive queue
    - ``RCL_CmdBle5Connection`` : Command to run connection event as central or peripheral
    - ``RCL_CtxConnection`` : Context for a connection

* The BLE5-Stack uses FreeRTOS heap_4 module for its memory allocation, refer to  
  :ref:`sec-heap-debugging` for more information on how to control and view the heap.

* Ensure read-only data is ``const``. Objects that never change 
  (data tables, BLE service/characteristic tables, initialized string buffers) 
  should be marked ``const`` to enable the linker to place the objects in 
  (read-only) flash rather than (read-write) RAM.

* Remove dependecies on software timers. Disabling FreeRTOS software timers 
  through SysConfig, can save ~1kB of RAM.

* Avoid ``snprintf()``. The C runtime library allocates a couple hundred bytes
  of RAM for temporary buffers.

.. warning::

    The above RAM estimations may vary by release, and are not an exhaustive
    list. It is intended as a way to allow the developer to profile the RAM
    requirements based on the desired settings. The best way to estimate RAM
    usage is to measure it in the field using the techniques covered in
    :ref:`sec-heap-debugging`