Micro BLE Stack¶
Overview¶
This section describes the high level design and functionality of the Micro BLE Stack that provides a non-connectable undirected advertising feature for a broadcaster application or a dual-mode application where a broadcaster and another communication protocol stack-based application are integrated.
Constraints and Requirements¶
The Micro BLE Stack has the following internal constraints and requirements:
- This design optionally depends on partial integration of ICall to save system resources if there already is an application using ICall in the dual-mode use case. In the case of using the ICall module, ICall’s system heap management and TI-RTOS service abstraction will be used.
- There is no HCI because there is no separation between the controller and the host.
- The privancy feature is not supported, but random address generation is supported
- To minimize the memory overhead and remove redundant context switching, the Micro BLE Stack doesn’t have a separate TI-RTOS tastk. It is instead integrated in the application task.
Functional Overview¶
The Micro BLE Stack consists of two layers: The Micro Link Layer (Micro LL or uLL) and Micro Generic Access Profile (Micro GAP or uGAP).
Micro LL performs:
- Radio management
- Device state management between stanby and advertising
Micro GAP performs:
- Broadcaster role
- Initialization and configuration of the Micro LL
- State Management within the role
- Interfacing with the application
Using the Micro BLE Stack¶
The source files for the Micro BLE Stack can be found in: <SDK_INSTALL_DIR>\source\ti\blestack\microstack, and the header files can be found in: <SDK_INSTALL_DIR>\source\ti\blestack\inc. The Micro Eddystone Beacon example demonstrates the use of the Micro BLE Stack, and it can be found at: <SDK_INSTALL_DIR>\examples\rtos\CC2640R2_LAUNCHXL\blestack\micro_eddystone_beacon An explanion and overview of this project can be found at Micro Eddystone Beacon.
System Architecture¶
The Micro BLE Stack consists of the Micro Link Layer (Micro LL or uLL) and Micro Generic Access Profile (Micro GAP or uGAP).
The uLL is mainly responsible for maintaining the device state and scheduling radio commands to perform advertising operations. The pre- and post-processing for each radio command execution are also done by the uLL. The uLL directly interfaces with the RF Driver.
The uGAP sits between the uLL and the application and is mainly responsible for controlling the uLL to set up and run a profile role. The application can indirectly configure the uLL through uGAP and be notified of events from uLL through uGAP callbacks. uGAP needs TI-RTOS because the clock/timer service is used.
The Micro BLE Stack is not designed to run as a separate TI-RTOS task, in order to save memory that would otherwise be required to maintain an additional task. Instead, it is integrated in the application, from TI-RTOS context’s point of view, so that all the application callbacks that are originated from RF and Clock SWIs in the Micro BLE Stack and might have lengthy operations such as command completion post processing and error handling are called in the application task context. How the Micro BLE Stack is integrated context-wise in the application is illustrated in Figure 66. Note that only the subcomponents directly relevant to the Micro BLE Stack in the application and the RF driver are depicted.
For that integration a message queue associated with the events is managed by the Micro BLE Stack internally. The message and loop code will look like the following:
void uBLEStack_eventProxy()
{
MicroEddystoneBeacon_enqueueMsg(UEB_EVT_MICROBLESTACK, 0);
}
static void MicroEddystoneBeacon_taskFxn(UArg a0, UArg a1)
{
// Initialize application
MicroEddystoneBeacon_init();
for (;;)
{
uint32 events;
// Waits for an event to be posted associated with the calling thread.
// Note that an event associated with a thread is posted when a
// message is queued to the message receive queue of the thread
#ifdef USE_ICALL
events = Event_pend(syncEvent, Event_Id_NONE, UEB_ALL_EVENTS,
ICALL_TIMEOUT_FOREVER);
#else /* !USE_ICALL */
events = Event_pend(syncEvent, Event_Id_NONE, UEB_ALL_EVENTS,
BIOS_WAIT_FOREVER);
#endif /* USE_ICALL */
if (events | UEB_QUEUE_EVT)
{
// If RTOS queue is not empty, process app message.
while (!Queue_empty(appMsgQueue))
{
uebEvt_t *pMsg = (uebEvt_t *) Util_dequeueMsg(appMsgQueue);
if (pMsg)
{
// Process message.
MicroEddystoneBeacon_processAppMsg(pMsg);
// Free the space from the message.
#ifdef USE_ICALL
ICall_free(pMsg);
#else /* USE_ICALL */
free(pMsg);
#endif /* USE_ICALL */
}
}
}
}
}
Functional Description¶
Micro Link Layer¶
The uLL is mainly responsible for maintaining the device state and scheduling, pre- and post-processing, the radio operations to send and/or receive ADV packets. The whitelist filter policy without privacy is supported.
Radio Initialization¶
The uLL has a direct interface to the RF Driver. It opens a connection to the RF Driver as an independent client using RF_open() with setup parameters for BLE PHY.
Parameters To Rely On¶
The uLL maintains parameters used for advertising. Most of the parameters can be accessed by uGAP through ub_getParameter() and ub_setParameter() functions. The list of the parameters is as follows:
- ubBDAddr: This is the device address. This can be any of the following types: Public, Random Static, Random Private Non-Resolvable and Random Private Resolvable.
- UB_PARAM_DFLT_TXPOWER: This is the TX power in dBm.
- UB_PARAM_DFLT_ADVCHANMAP: This is a map to the channels to send advertising PDUs on. It can include some or all of channels 37, 38 & 39
- UB_PARAM_DFLT_ADVTYPE: This is the type of advertising. Currently only ADV_NONCONN_IND is supported.
- UB_PARAM_DFLT_ADVINTERVAL: This is the interval between two consecutive advertising operations on the starting channel. This can range from 100 ms to 10.24 sec.
- UB_PARAM_DFLT_TIMETOADV: This is how early the application wants to get a notification before each advertising event happens. It is used to issue the App_bcastPrepareAdvCb() callback.
Micro Link Layer States¶
There are 2 states in the uLL: Standby and Advertising. The uLL changes the state from one to another at the uGAP’s request.
Standby State¶
This is the default state in the uLL. The uLL doesn’t send any packets in this state. The uLL may leave this state to enter the Advertising State.
Advertising State¶
In this state, the uLL sends advertising PDUs in advertising events.
Each advertising event is composed of one or more advertising PDUs sent on the channels specified in UB_PARAM_DFLT_ADVCHANMAP. The advertising event will be closed after one advertising PDU has been sent on each of the channels specified in UB_PARAM_DFLT_ADVCHANMAP or it can be closed earlier if requested by the uGAP.
The time between two consecutive advertising events is specified in UB_PARAM_DFLT_ADVINTERVAL. The actual interval will be UB_PARAM_DFLT_ADVINTERVAL + AdvDelay, where AdvDelay is a pseudo-random value ranging from 0 ms to 10 ms generated by the uLL for each advertising event.
An advertising event is limited to the following type in this version of design:
- A non-connectable undirected event: ADV_NONCONN_IND PDU is used. No response PDU is expected.
Per each advertising event, the following notifications will be delivered to the uGAP before and after the event. Note that these notifications are conveyed based on the application task’s priority since they are following the paths illustrated in Figure 66.
- UBS_EVT_ADV_PREPARE: This notification event is generated UB_PARAM_DFLT_TIMETOADV ms prior to every advertising event. The purpose of this event is to let the application take time to update the advertising data with up-to-date information if necessary. If UB_PARAM_DFLT_TIMETOADV is 0, this notification event won’t happen.
- UBS_EVT_ADV_DONE: This notification event is generated at the completion of every advertising event. This comes with a result status such as UBS_STATUS_SUCCESS, UBS_STATUS_FAILURE, or UBS_STATUS_ABORTED.
Micro GAP¶
The uGAP sits between the uLL and the application and is responsible for controlling the uLL to set up and run a profile role. The application can indirectly configure the uLL through the uGAP and be notified of events from the uLL through uGAP callbacks.
Parameters Management¶
The uGAP provides the application with ub_getParameter() and ub_setParameter() functions to enable it to access the parameters used for implementing profile roles. For many of those parameters that are maintained and used by the uLL as listed in Parameters To Rely On, ub_getParameter() and ub_getParameter() bypass the requests from the application to the uLL through ul_getParam() and ul_setParam(). However, there are some parameters that are maintained by the uGAP as follows:
- NumAdvEvent: The number of advertising events to be done before the Broadcaster stops its job. This is given when the application starts the Broadcaster by calling ug_bcastStart(). If this parameter is set to 0, the Broadcaster will not go to UG_BCAST_STATE_INITIALIZED state once started unless it is requested to stop.
- BcastDutyOnTime: Time period during which the Broadcaster stays in UG_BCAST_STATE_ADVERTISING state. The uLL stays in Advertising State as well. When this time period ends, the Broadcaster state will transition to UG_BCAST_STATE_WAITING and the uLL will exit Advertising State. This parameter is effective only if Broadcaster Duty Control is enabled. If Broadcaster Duty Control is disabled, transition to other state from UG_BCAST_STATE_ADVERTISING is not affected by this parameter. A 100-ms time unit is used.
- BcastDutyOffTime: Time period during which the Broadcaster stays in UB_BCAST_STATE_WAITING state. The uLL cannot be in Advertising State during this period. When this time period ends, the Broadcaster state will transition to UG_BCAST_STATE_ADVERTISING and the uLL will enter Advertising State. This parameter is effective only if Broadcast Duty Control is enabled. If 0, Broadcaster Duty Control is disabled and the Broadcaster will not enter UG_BCAST_STATE_WAITING state. A 100-ms time unit is used.
Role Management¶
The uGAP currently provides a single Profile Role: Broadcaster. The application can configure the device to be Broadcaster only.
Broadcaster Role¶
If the application configures the uGAP to operate Broadcaster role, the uGAP lets the uLL send advertising events as described in Advertising State in accordance with the parameters listed in Parameters To Rely On.
The Broadcaster Role has 4 states:
- UG_BCAST_STATE_INITIALIZED: Broadcaster is initialized but has never started. The corresponding state of the uLL can be anything but UL_STATE_ADVERTISING.
- UG_BCAST_STATE_ADVERTISING: Broadcaster is advertising in this state. The corresponding state of the uLL is UL_STATE_ADVERTISING. If Broadcaster Duty Control is enabled, the duty timer starts with the duration of BcastDutyOnTime when this state is entered. Then, the state switches to UG_BCAST_STATE_WAITING when the duty timer expires. If 0 was passed to NumAdvEvent when ug_bcastStart() is called, ugbNumAdvEvent won’t have any effect on this state. Otherwise, the state switches to UG_BCAST_STATE_IDLE if requested through ug_bcastStop() or the total number of Advertising Events since ug_bcastStart() was called reaches ugbNumAdvEvent. If ug_bcastSuspend() is called, the state switches to UG_BCAST_STATE_SUSPENDED, putting the duty timer on hold if Duty Control is enabled. The duty timer will resume when the state switches back to this state.
- UG_BCAST_STATE_WAITING: Broadcaster started but is not advertising in this state because it’s in DutyOffTime period. The corresponding state of the uLL is UL_STATE_STANDBY. If Broadcaster Duty Control is enabled, the duty timer starts with the duration of BcastDutyOffTime when this state is entered. Then, the state switches to UG_BCAST_STATE_ADVERTISING when the duty timer expires. The state switches to UG_BCAST_STATE_IDLE if requested through ug_bcastStop(). If ug_bcastSuspend() is called, the state switches to UG_BCAST_STATE_SUSPENDED, putting the duty timer on hold if Duty Control is enabled. The duty timer will resume when the state switches back to this state.
- UG_BCAST_STATE_SUSPENDED: Broadcaster started but is not advertising in this state. The corresponding state of the uLL can be anything but UL_STATE_ADVERTISING. The former state shall be recorded when this state is entered. If the suspension is lifted through ug_bcastResume(), the state will switch back to the former state. The state switches to UG_BCAST_STATE_IDLE if ug_bcastStop() is called.
The BLE specification doesn’t allow Broadcaster to have Limited Discoverable Mode. However, the uGAP provides a duty control means similar to Limited Discoverable Mode to save power consumption. The duty control can be implemented with timers based on BcastDutyOnTime and BcastDutyOffTime explained in Parameters Management. Broadcaster’s Advertising State corresponds to the uLL’s Advertising State.
The typical life cycle of the Broadcasting function encompassing the application down to the uLL is illustrated in Figure 68.
External Interface¶
The external interfaces include APIs and callbacks. Only the uGAP APIs are exposed to the application. They are listed in the following sections.
APIs¶
For Micro BLE Stack APIs, see Micro BLE Stack API Reference
Callbacks¶
App_bcast_stateChangeCB():
This callback is to notify the application of the Broadcaster’s state change. This callback is optional.
Type Definition | Typedef void (*bcast_stateChangeCB_t)(ugbState_t state); | |
Parameter | state | A new Broadcaster state |
Return | None |
App_bcast_advPrepareCB():
This callback is to notify the application of the Broadcaster’s being about to send an advertising event. Inside this callback, the application can make the ADV payload up-to-date if necessary. This callback is optional.
Type Definition | Typedef void (*bcast_advPrepareCB_t)(void); |
Parameter | None |
Return | None |
App_bcast_advDoneCB():
This callback is to notify the application of how the last advertising event has been completed. This callback is optional.
Type Definition | Typedef void (*bcast_advDoneCB_t)(bStatus_t status); | |
Parameter | status | Error code |
Return | None |