Silicon Labs
|
Silicon Labs Community Silicon Labs Community
  • Products
    1. 8-bit MCU
    2. 32-bit MCU
    3. Bluetooth
    4. Proprietary
    5. Wi-Fi
    6. Zigbee & Thread
    7. Z-Wave
    8. Interface
    9. Isolation
    10. Power
    11. Sensors
    12. Timing
  • Development Tools
    1. Simplicity Studio
    2. Third Party Tools
  • Expert's Corner
    1. Announcements
    2. Blog
    3. General Interest
    4. Projects
How to Buy
English
  • English
  • 简体中文
  • 日本語
//
Community // Blog

Kernel 201: Bluetooth Task

06/177/2019 | 08:42 PM
Mark Mulrooney
Employee

Level 5


This blog is part of the Kernel 201: Designing a Dynamic Multiprotocol Application with Micrium OS. The table of contents for this blog series can be found here.

Note: It is recommended to download the Kernel 201 application and have the code in front of you as you go through this blog post. The code can be downloaded on the Kernel 201: Project Resources page. 

Note: This project has a slightly different RTOS interface with the Bluetooth stack than other example projects. The differences will be highlighted in this article.

Introduction

The goal of the Bluetooth task in the Kernel 201 Application is to communicate with a web browser running a WebBluetooth App. The WebBluetooth App is highlighted in detail in another post that can be found here.

The Bluetooth task will perform the following actions:

  • Start Bluetooth Advertising after the stack boots and after a disconnect
  • Handle read and write requests from the WebBluetooth App
  • Send notifications to the WebBluetooth App

Kernel 201 Bluetooth Initialization

Before starting the Bluetooth Task, configurations and initializations must be performed for the Bluetooth stack to operate correctly. Part of the configuration for the Bluetooth stack comes from the GATT editor in Simplicity Studio; the other portion of the Bluetooth configuration comes from the gecko_configuration_t structure.

 

To modify the Bluetooth GATT configuration, there is an application in Simplicity Studio to help configure the GATT database. In the Kernel 201 Application there is a file called kernel201.isc. Opening that file in Simplicity Studio will open the GATT Configurator where you can make changes to the GATT database.

In the GATT Configurator, a new Bluetooth Service called Lab Control has been added for the Kernel 201 Application. Any task in the application that wishes to have Bluetooth control will have a characteristic under the Lab Control service. For the Kernel 201 Application, each characteristic will support Read, Write and Notify. The characteristics are given unique UUID numbers that are hardcoded into the WebBluetooth App. If someone wishes to add a new task, modifications would also have to be made to the WebBluetooth App to support the new UUID. The code for the WebBluetooth App is available for download under the Kernel 201: Project Resources page.

By default, the Kernel 201 Application shows up as “Kernel201” for the Bluetooth Device Name. If you wish to change the Device Name to something else, this can be accomplished under the Device Name Characteristic in the GATT Configurator. The value field is where the new Device Name would be specified and the length must be adjusted. Note: For the DMP portion of this application to work correctly the Device Name must be 16 characters or less. This is a Kernel 201 Application requirement, not a Bluetooth requirement. 

After all changes have been made in the GATT Configurator, the kernel201.isc file needs to be saved and then click Generate to update the GATT information. For further information on the GATT Configurator, refer to UG365: GATT Configurator Users Guide

static const gecko_configuration_t bluetooth_config =
{
    .config_flags              = GECKO_CONFIG_FLAG_RTOS,
    .sleep.flags               = 0,
    .bluetooth.max_connections = LAB_BLUETOOTH_MAX_CONNECTIONS,
    .bluetooth.heap            = bluetooth_stack_heap,
    .bluetooth.heap_size       = sizeof(bluetooth_stack_heap),
    .gattdb                    = &bg_gattdb_data,
    .ota.flags                 = 0,
    .ota.device_name_len       = 3,
    .ota.device_name_ptr       = "OTA",
    .scheduler_callback        = Bluetooth_LLCallback,
    .stack_schedule_callback   = Bluetooth_UpdateCallback,
#if (HAL_PA_ENABLE)
    .pa.config_enable          = 1,
#if defined(FEATURE_PA_INPUT_FROM_VBAT)
    .pa.input                  = GECKO_RADIO_PA_INPUT_VBAT,
#else
    .pa.input                  = GECKO_RADIO_PA_INPUT_DCDC,
#endif
#endif
    .mbedtls.flags             = GECKO_MBEDTLS_FLAGS_NO_MBEDTLS_DEVICE_INIT,
    .mbedtls.dev_number        = 0,
};

 

In the lab_bluetooth.c file, there is also the gecko_configuration_t Bluetooth configuration structure that must be passed in during initialization. As shown above the structure sets internal flags, heap location and size (separate heap from Micrium OS), GATT Database, callback functions and other power and security parameters. For more information on the structure, refer to UG136: Silicon Labs Bluetooth C Application Developer’s Guide.

The Kernel 201 Application also introduces a second configuration structure that is not found in other Dynamic Multiprotocol Applications or officially supported by the Bluetooth stack.

static BLUETOOTH_RTOS_CFG_s bluetooth_rtos_cfg =  // Bluetooth RTOS config
{
    .ll_prio      = SLAB_LINKLAYER_PRIO,
    .bt_prio      = SLAB_BLUETOOTH_PRIO,
    .bt_callback  = labBluetoothEvtCallback,      // Callback to signal a Bluetooth 
    .gecko_config = &bluetooth_config             //  event to process.
};

 

Typically, the function bluetooth_start_task() only takes in the task priorities for the Link Layer and Bluetooth tasks. This structure adds a callback function that will be used when there is a Bluetooth event for the labBluetoothTask to process.

This change is necessary because the existing implementation of the Bluetooth Stack’s RTOS port relied on the user application to pend on an Event Flag. Since the tasks in the Kernel 201 Application pend on Task Message Queues, it was not possible to use the Bluetooth Event Flags in conjunction with the Task Message Queue. The addition of the callback function adds the flexibility for applications to use any kernel service desired for signaling rather than being forced to use an Event Flag.

Kernel 201 Bluetooth Task

The main Bluetooth task loop is structured just like all other tasks in the Kernel 201 Application (except for the watchdog task). When the task is created, the Bluetooth stack is configured and initialized and then begins waiting for messages in the Task Message Queue.

 

while (DEF_TRUE)
{
    p_msg = OSTaskQPend( LAB_WDOG_TASK_TIMEOUT_MS, // Wait for lab message
                         OS_OPT_PEND_BLOCKING,     //  or timeout.
                        &lab_q_id,
                         0,
                        &err);

    do {
        if(err.Code == RTOS_ERR_TIMEOUT) {         // If timeout, feed watchdog
            break;
        } else if(err.Code != RTOS_ERR_NONE) {     // Assert on other errors
            APP_RTOS_ASSERT_CRITICAL(err.Code == RTOS_ERR_NONE, ;);
        }

        switch(lab_q_id) {
            case LAB_Q_ID_BLUETOOTH_EVT:
                labBluetoothHandleEvt();          // Handle Bluetooth Event
                break;

            case LAB_Q_ID_MSG:                    // Handle Lab Message
                labBluetoothHandleMsg((LAB_MSG_s*) p_msg);
                labUtilMsgFree(p_msg);            // Then free Lab Message
                break;

            default:
                break;
        }
    } while(0);

    labWDOGFeed(LAB_TASK_BLUETOOTH);              // Feed the watchdog
}

 

There are two types of messages and one error code that the Bluetooth task handles:

  • RTOS_ERR_TIMEOUT – No events have been received in the timeout period, feed the software watchdog and pend again.
  • LAB_Q_ID_BLUETOOTH_EVT – Called when there is an event from the Bluetooth stack to handle.
  • LAB_Q_ID_MSG – Called when there is a message in the void* argument of the Task Message Queue to process.

 

RTOS_ERR_TIMEOUT

As part of the software watchdog, the Bluetooth task must feed the software watchdog at a specified rate. There is a define in lab.h that all tasks use called LAB_WDOG_TASK_TIMEOUT_MS. This define specifies how often every task should check-in with the software watchdog. If the Task Message Queue does not receive a message before the timeout value is hit, the pend call returns with RTOS_ERR_TIMEOUT. Since it’s a timeout the Bluetooth task knows that no message was received, it only feeds the software watchdog and then starts pending on the Task Message Queue again.

 

LAB_Q_ID_BLUETOOTH_EVT

When the Bluetooth stack has an event for the Kernel 201 Application to process, it makes a call to the callback function specified in the BLUETOOTH_RTOS_CFG_s structure. That function is defined as follows:

void  labBluetoothEvtCallback (void)
{
    RTOS_ERR err;


    OSTaskQPost(&labBluetoothTaskTCB,
                 0,
                 LAB_Q_ID_BLUETOOTH_EVT,
                 OS_OPT_POST_FIFO,
                 &err);
}

 

In the callback function, a message is sent to the labBluetoothTask to tell it there is a message waiting to be processed. The callback function must send a message because the callback function is executed from the internal Bluetooth Task. If the callback function was to process the Bluetooth event it would lock up the internal Bluetooth task and potentially cause the Bluetooth Stack to miss other Bluetooth events.

When the signal to process an event is received by the labBluetoothTask, the function labBluetoothHandleEvt() is called. This function first retrieves the event that must be processed, and then determines how to handle it. The chart below shows the flow of the event handler:

 

gecko_evt_system_boot_id and gecko_evt_le_connection_closed_id

These events are called when the Bluetooth stack has been booted, and when a Bluetooth connection has been dropped. In both cases, the Bluetooth stack must be told to start advertising again as we don’t have a connection.

 

gecko_evt_gatt-server_user_write_request_id

The write event is called when the WebBluetooth App is wishing to send a command to a task in the system. A common example would be using the WebBluetooth App to change the LEDs.

The Bluetooth write event that is received from the Bluetooth stack also contains data such as the task the data is to be sent to, as well as the data itself. To send the data to the specified task, a lab message buffer is allocated using the utility functions. Once a buffer has been allocated, it is configured for the task destination and then the data specific to that task is copied into the buffer. The buffer is then sent to the desired task/s.

 

gecko_evt_gatt-server_user_read_request_id

The read event is called only when a WebBluetooth App first connects to the Kernel 201 Application. The read is used to determine the state of all of the tasks in the system for the WebBluetooth App. After the WebBluetooth App has connected and received the task status the first time, all subsequent updates are received via a Bluetooth notification.

 

LAB_Q_ID_MSG

When another task in the system wishes to send data via Bluetooth, a lab message must be sent to the Bluetooth task via the Task Message Queue. In most cases, this is used when a task has completed a request and is updating the remote application. In the LED example, after the LED has been changed a message is sent to the Bluetooth task so the WebBluetooth App connected, if any, is updated.

 

Kernel 201 Bluetooth Example

The following diagram shows the typical flow of data when a user wishes to change the LED:

 

  1. The user makes a request on the WebBluetooth App to change the LED color to red.
  2. The WebBluetooth App sends a Bluetooth write command to the Kernel 201 Application.
  3. The Silicon Labs internal Bluetooth stack receives the message via the radio, assemble the data and executes the labBluetoothEvtCallback() that was passed in during the Bluetooth configuration. The callback puts a LAB_Q_ID_BLUETOOTH_EVT message in the labBluetoothTask’s Task Message Queue.
  4. The labBluetoothTask receives the LAB_Q_ID_BLUETOOTH_EVT in its Task Message Queue and handles it as follows:
    1. Get the Bluetooth Event from the Bluetooth stack.
    2. Determine it is a write event.
    3. Determine it is an LED write event.
    4. Allocate a lab message buffer, configure it for a LED message and send it to the LED task via the LED Task’s Task Message Queue.
  5. The labLEDTask receives the LAB_Q_ID_MSG along with the lab message buffer pointer.
    1. It proceeds to change the LED as requested.
    2. After the change has been made, the LED task sends the same lab message content it received back to the Bluetooth task, but signals that it is an update message, not a command message.
  6. The labBluetoothTask receives a LAB_Q_ID_MSG in its Task Message Queue.
    1. The message is sent to the Silicon Labs internal Bluetooth stack via the Gecko characteristic notification command
  7. The Silicon Labs internal Bluetooth stack processes the characteristic notification command and sends the data to the WebBluetooth App.
  8. The WebBluetooth App receives the Bluetooth characteristic notification update and changes the WebBluetooth App to show the LED color has been changed to red.

 

Final Thoughts

The Bluetooth Task is one of two wireless tasks in the system that will send commands to the other tasks in the system and report back the status of the system. The other task is the Proprietary Wireless that is covered in Kernel 201: Proprietary Wireless Task. The Bluetooth Task has the advantage that the developer does not need to make multiple RAIL calls to configure the radio or listen for hardware interrupts because it is abstracted away by the Bluetooth Stack. The Proprietary Wireless Task does not have this luxury and will require some more in-depth knowledge of the RAIL API. If you have any questions or comments on the Bluetooth Task feel free to leave them below.

  • Blog Posts
  • Micrium OS

Tags

  • Wireless
  • High Performance Jitter Attenuators
  • EFR32FG22 Series 2 SoCs
  • EFR32MG21 Series 2 SoCs
  • Security
  • Bluegiga Legacy Modules
  • Zigbee SDK
  • ZigBee and Thread
  • EFR32BG13 Series 1 Modules
  • Internet Infrastructure
  • Sensors
  • Wireless Xpress BGX13
  • Blue Gecko Bluetooth Low Energy SoCs
  • Z-Wave
  • Micrium OS
  • Blog Posts
  • Low Jitter Clock Generators
  • Bluetooth Classic
  • Makers
  • Flex SDK
  • Tips and Tricks
  • timing
  • Smart Cities
  • Smart Homes
  • IoT Heroes
  • Reviews
  • RAIL
  • Simplicity Studio
  • Tiny Gecko
  • EFR32MG22 Series 2 SoCs
  • Mighty Gecko SoCs
  • Timing
  • Temperature Sensors
  • Blue Gecko Bluetooth Low Energy Modules
  • Ultra Low Jitter Clock Generators
  • General Purpose Clock Generators
  • EFR32BG22 Series 2 SoCs
  • Industry 4.0
  • Giant Gecko
  • 32-bit MCUs
  • Bluetooth Low Energy
  • 32-bit MCU SDK
  • Gecko
  • Microcontrollers
  • Jitter Attenuators
  • EFR32BG21 Series 2 SoCs
  • News and Events
  • Wi-Fi
  • Bluetooth SDK
  • Community Spotlight
  • Clock Generators
  • Biometric Sensors
  • General Purpose Jitter Attenuators
  • Giant Gecko S1
  • WF200
  • Flex Gecko
  • Internet of Things
  • 8-bit MCUs
  • Wireless Jitter Attenuators
  • Isolation
  • Powered Devices
  • Power

Top Authors

  • Avatar image Siliconlabs
  • Avatar image Jackie Padgett
  • Avatar image Nari Shin
  • Avatar image lynchtron
  • Avatar image deirdrewalsh
  • Avatar image Lance Looper
  • Avatar image lethawicker

Archives

  • 2016 February
  • 2016 March
  • 2016 April
  • 2016 May
  • 2016 June
  • 2016 July
  • 2016 August
  • 2016 September
  • 2016 October
  • 2016 November
  • 2016 December
  • 2017 January
  • 2017 February
  • 2017 March
  • 2017 April
  • 2017 May
  • 2017 June
  • 2017 July
  • 2017 August
  • 2017 September
  • 2017 October
  • 2017 November
  • 2017 December
  • 2018 January
  • 2018 February
  • 2018 March
  • 2018 April
  • 2018 May
  • 2018 June
  • 2018 July
  • 2018 August
  • 2018 September
  • 2018 October
  • 2018 November
  • 2018 December
  • 2019 January
  • 2019 February
  • 2019 March
  • 2019 April
  • 2019 May
  • 2019 June
  • 2019 July
  • 2019 August
  • 2019 September
  • 2019 October
  • 2019 November
  • 2019 December
  • 2020 January
  • 2020 February
  • 2020 March
  • 2020 April
  • 2020 May
  • 2020 June
  • 2020 July
  • 2020 August
  • 2020 September
  • 2020 October
  • 2020 November
  • 2020 December
  • 2021 January
  • 2021 February
Silicon Labs
Stay Connected With Us
Plug into the latest on Silicon Labs products, including product releases and resources, documentation updates, PCN notifications, upcoming events, and more.
  • About Us
  • Careers
  • Community
  • Contact Us
  • Corporate Responsibility
  • Privacy and Terms
  • Press Room
  • Investor Relations
  • Site Feedback
  • Cookies
Copyright © Silicon Laboratories. All rights reserved.
粤ICP备15107361号
Also of Interest:
  • Bring Your IoT Designs to Life with Smart,...
  • A Guide to IoT Protocols at Works With...
  • IoT Hero Rainus Enhances the In-Store Shopping...