Managing Bluetooth Low Energy Stack RAM Usage
The Bluetooth Low Energy stack is provided as a complied library and cannot be modified by the user. However, some of the stack variables are defined at the application level, and the user has some control over the size of these variables. This is a guide to optimizing stack RAM memory usage by adjusting the application level variable defines as dependent upon the application use case.
The application level variables are defined to support the maximum number of connections and activities, which is 10 and 11 respectively. (See the CEVA documentation provided with your RSL15 download, in the default location C:\Users\<user_name>\ON_Semiconductor\PACK\ONSemiconductor\RSL15\<version>\documentation\ceva.) If the application use case does not require the maximum number of connections and activities, application level variable sizes can be reduced to save memory.
NOTE: It is not recommended to adjust application level variable sizes in the HCI stack, as this can adversely affect Bluetooth certification.
The simplest method and recommended starting point to reduce stack memory usage is to reduce the value of APP_MAX_NB_CON. This scales most of the other application level variables as well, resulting in a reduction of memory usage. This is usually sufficient for most users. If you are an advanced user requiring further optimization, read on.
The memory allocated by the stack is divided into different parts. The first part comprises the required environment and global variables that are independent of the number of connections or activities. This part cannot be changed by developers.
The second part is heap memory, which the kernel takes as a global variable (.bss section), and later the kernel and the Bluetooth Low Energy stack use it as the heap memory for their procedures. It is divided into four parts:
- Environment variables
- Message heap memory
- Data base memory
- Non-retention memory
By default, all parameters are set to address the maximum number of connections and activities, which are 10 and 11 respectively. If definition APP_HEAP_SIZE_DEFINED is defined in the app.h file of any Bluetooth Low Energy application, then the heap sizes can be customized in the ble_protocol_support.c file (where they are defined and allocated). The following code example shows how the required memory sizes can be calculated (defined in ble_protocol_support.c).
/// Memory allocated for environment variables
uint32_t rwip_heap_env[RWIP_CALC_HEAP_LEN(APP_RWIP_HEAP_ENV_SIZE)];
/// Memory allocated for Attribute database
uint32_t rwip_heap_db[RWIP_CALC_HEAP_LEN(APP_RWIP_HEAP_DB_SIZE)];
/// Memory allocated for kernel messages
uint32_t rwip_heap_msg[RWIP_CALC_HEAP_LEN(APP_RWIP_HEAP_MSG_SIZE)];
/// Non Retention memory block
uint32_t rwip_heap_non_ret[RWIP_CALC_HEAP_LEN(APP_RWIP_HEAP_NON_RET_SIZE)];
We assume:
APP_MAX_NB_ACTIVITY and APP_MAX_NB_CON are defined in the application, based on the application’s use case. Please note that PP_BLE_CONNECTION_MAX needs to be at least one value bigger than APP_MAX_NB_CON.
APP_RWIP_HEAP_ENV_SIZE =
(600 + (APP_MAX_NB_ACTIVITY) * 230)
+ APP_MAX_NB_CON * ((sizeof(struct gapc_env_tag)
+ KE_HEAP_MEM_RESERVED)
+ (sizeof(struct gattc_env_tag) + KE_HEAP_MEM_RESERVED)
+ (sizeof(struct l2cc_env_tag) + KE_HEAP_MEM_RESERVED))
+ ((APP_MAX_NB_ACTIVITY ) * (sizeof(struct gapm_actv_scan_tag)
+ KE_HEAP_MEM_RESERVED))
APP_RWIP_HEAP_DB_SIZE: This depends on how much data base memory (GATT services) is added. The default value is 3072 bytes, but developers can choose a smaller value based on their use case. This stack memory heap (section) is used for several purposes:
- GAP and GATT database: total size 158 B
- Database of Bluetooth Low Energy Profiles. Considering that only BAS and DIS are available, the required sizes are as follows, providing an application requests adding them:
- DISC: 694 B
- DISS: 154 B
- BASC: 392B
- BASS: 70 B
NOTE: BASC and BSS can be one instance or two instances. Depending how many an application adds, the used memory size increases by two if two instances are configured.
- Database for custom services. Each service needs 22 B for service itself. For each attribute it needs a maximum of 22 B in addition, depending on attribute types. We recommend that you consider the maximum value.
- L2CAP credit-based connection-oriented channels environment (LECB): this needs 36 B per channel.
APP_RWIP_HEAP_MSG_SIZE =
(1650 + 2 * ((16 + (APP_MAX_NB_ACTIVITY - 1) * 56)
+ (58 + (APP_MAX_NB_ACTIVITY - 1) * 26)
+ ((APP_MAX_NB_ACTIVITY) * 66)
+ ((APP_MAX_NB_ACTIVITY) * 100)
+((APP_MAX_NB_ACTIVITY) * 12)))
+(((BLEHL_HEAP_MSG_SIZE_PER_CON * APP_MAX_NB_CON) > BLEHL_HEAP_DATA_THP_SIZE)
?
(BLEHL_HEAP_MSG_SIZE_PER_CON * APP_MAX_NB_CON) : BLEHL_HEAP_DATA_THP_SIZE)
APP_RWIP_HEAP_NON_RET_SIZE: By default, this is set to 656 bytes. It is used for security algorithm calculations. This part of memory does not need to be in retention mode when the use case calls for keeping the Bluetooth Low Energy link active and going to sleep with VDDM in retention. If enough memory is allocated — for example, in the database — the kernel can allocate this part of memory from another heap. Developers need to make sure that this default amount of memory is available, in non-ret heap or in another heap.
In this way, users can set their own APP_MAX_NB_CON and APP_MAX_NB_ACTIVITY values, and decrease the memory size allocated by default settings.