
.. _sec-freertos-config:

Kernel Configuration
--------------------

The FreeRTOS kernel is configured by FreeRTOSConfig.h file which can be found
in ``{SDK_INSTALL_DIR}\kernel\freertos\builds\{DEVICE}\release\pregenerated_configuration``,
you can change the configuration file so that the kernel will be tailored to your application.
For more information about kernel configuration, please see |FreeRTOS KERNEL CONFIGURATION|.

In the |SDK|, all FreeRTOS application routines are abstracted using the following:

- A POSIX layer, which was designed for use with this |SDK|
- A Driver Porting Layer (DPL) for use by the TI Drivers

You can find example FreeRTOS projects that use the |SDK| in the ``examples/rtos/``
folder for all supported IDEs.

No native FreeRTOS examples are provided in this |SDK|. If you want to use the native
FreeRTOS routines without the abstractions provided by the |SDK|, documentation is provided
on the |FREERTOS_WEB|.

.. ifconfig:: device != 'cc23xx' and doctarget=='ble5'

  .. note::

      At this moment, the only example with FreeRTOS support is ``multi_role`` inside the SimpleLink_Lowpower_F2 SDK.

POSIX Support
-------------

Portable Operating System Interface (POSIX) is an IEEE industry API standard for
OS compatibility. The |SDK| provides support for POSIX APIs on top of
FreeRTOS (as it does for TI-RTOS7). For a more detailed description of the POSIX
support in the |SDK|, please refer to the
`POSIX Overview Workshop <https://dev.ti.com/tirex/explore/node?node=ACzypa9NTyZS--.cZMxD.g__BSEc4rl__LATEST>`_

Driver Porting Layer (DPL)
--------------------------

The TI Drivers (e.g. UART2, I2C, Power Management, etc.) are written to be used
with the Driver Porting Layer (DPL). The |SDK| includes a DPL
implementation for both FreeRTOS, TI-RTOS7 and no RTOS.

        .. figure:: resources/driver_levels_dpl.png
            :align: center

Using FreeRTOS with CCS
-----------------------

FreeRTOS is included within the SDK itself! Unlike past SDKs which required FreeRTOS to be
defined manually in the linked resources.

In order to use FreeRTOS within CCS, you must specify the location of the FreeRTOS
installation. To do this, follow these steps:

.. ifconfig:: device != 'cc23xx' and doctarget=='ble5'

  .. _freertos_examples:

  FreeRTOS examples
  -----------------

  As mentioned before, only the ``multi_role`` example supports FreeRTOS and
  it needs to be used with the gcc compiler, therefore please import the
  project located in ``multi_role/freertos/gcc``.

          .. figure:: resources/freertos_project_import.png
              :align: center

  Two projects will get imported:

          .. figure:: resources/multi_role_freertos_import.png
              :align: center


FreeRTOS vs. TI-RTOS7 modules
-----------------------------

The application and the ICall layer communicate using events to call the
OS and made context switch. The table below shows the modules that are used by
TI-RTOS7 in a typical example flow, at the same time explains which modules are
used by FreeRTOS.

.. _tbl-freertos-modules:
.. table:: Replacing modules that supports FreeRTOS in place of TI-RTOS7 modules

    +----------------------------+----------------------------------+-------------------------------------+
    | **Example flow**           | **TI-RTOS7 modules**             | **FreeRTOS modules**                |
    +----------------------------+----------------------------------+-------------------------------------+
    | 1. *Application Thread*    | *TI-RTOS7* Semaphore/Event       | SemaphoreP (used through DPL layer) |
    | Listen (pend) on event     |                                  | and mq_send / mq_receive *Blocking* |
    | number                     |                                  | Mqueue (POSIX queues)               |
    |                            |                                  |                                     |
    |                            |                                  |                                     |
    +----------------------------+----------------------------------+-------------------------------------+
    | 2. *Stack Thread*          | *TI-RTOS7* Timers                | TimersP (used through DPL layer)    |
    | Doing whatever he asked    |                                  |                                     |
    | to do by the app called    |                                  |                                     |
    |                            |                                  |                                     |
    |                            |                                  |                                     |
    +----------------------------+----------------------------------+-------------------------------------+
    | 3. *Stack Thread*          | *TI-RTOS7* utility Queue         | mq_send / mq_receive *NON-Blocking* |
    | Push a message (or number  |                                  | Mqueue (POSIX queues)               |
    | of messages) into the      |                                  |                                     |
    | queue and post an event    |                                  |                                     |
    | Queue                      |                                  |                                     |
    +----------------------------+----------------------------------+-------------------------------------+
    | 4. *Application Thread*    | *TI-RTOS7* utility Queue         | mq_send / mq_receive *NON-Blocking* |
    | OS wakes the application   |                                  | Mqueue (POSIX queues)               |
    | thread and the application |                                  |                                     |
    | pulls the message from the |                                  |                                     |
    | Non-OS queue               |                                  |                                     |
    +----------------------------+----------------------------------+-------------------------------------+
    | 5. *Application Thread*    | *TI-RTOS7* event                 | mq_send / mq_receive *Blocking*     |
    | Listen (pend) on event     |                                  | Mqueue (POSIX queues)               |
    | number - cycle has         |                                  |                                     |
    | completed                  |                                  |                                     |
    |                            |                                  |                                     |
    +----------------------------+----------------------------------+-------------------------------------+

.. only:: sdk_includes_ble

    icall_POSIX
    -----------

    The file ICall_POSIX is based on POSIX, DPL and FreeRTOS bare APIs
    calls. This implementation should allow us to support different Operating Systems if
    required. In order to do this, all the ``#ifdef FreeRTOS`` on the current ICall_POSIX
    could be changed to support a different OS.

    Here are some of the places where these defines are used (``icall_POSIX.c``):

       .. code-block:: c
         :caption: ``ical_POSIX.c - Includes``
         :emphasize-lines: 1, 2, 3, 4

         #ifdef FREERTOS
         #include <FreeRTOS.h>
         #include <task.h>
         #endif

       .. code-block:: c
         :caption: ``ical_POSIX.c - ICall_taskSelf()``
         :emphasize-lines: 4, 5, 6

         Task_Handle ICall_taskSelf(void)
         {
           Task_Handle task = NULL;
         #ifdef FREERTOS
           task = (Task_Handle) xTaskGetCurrentTaskHandle();
         #else
           task = <handler need to be returned according to the chosen OS>;
         #endif // FREERTOS
           return (task);
         }

       .. code-block:: c
         :caption: ``ical_POSIX.c``
         :emphasize-lines: 9-10

         #ifndef FREERTOS
         #if defined(HEAPMGR_CONFIG) && ((HEAPMGR_CONFIG == 0) || (HEAPMGR_CONFIG == 0x80))
         #include <rtos_heaposal.h>
         #elif defined(HEAPMGR_CONFIG) && ( (HEAPMGR_CONFIG == 1) || (HEAPMGR_CONFIG == 0x81))
         #include <rtos_heapmem.h>
         #elif defined(HEAPMGR_CONFIG) && ( (HEAPMGR_CONFIG == 2) || (HEAPMGR_CONFIG == 0x82))
         #include <rtos_heaptrack.h>
         #else
         static ICall_CSState ICall_heapCSState;
         #include <rtos_heaposal.h>
         #endif
         #endif // !FREERTOS
