Gecko Bootloader can load application images into the application area from different sources.
What it cannot do is uploading the application image to a temporary storage slot of the internal/external flash before loading it from there into the application area. This article helps you implement the missing step: uploading the image to the internal/external flash via a Bluetooth connection.
This article guides you through how to upload images to storage slots using the standard OTA DFU process (used by the OTA Apploader). To learn how to load the uploaded images from the slots into the application area please read this article: https://www.silabs.com/community/wireless/bluetooth/knowledge-base.entry.html/2017/07/19/switching_betweenfi-GnNI
To make the OTA uploader compatible with Silicon Labs Bluetooth OTA Apploader that loads the image directly to the application area, first we have to understand how the standard OTA DFU method works.
The standard OTA DFU sequence (implemented in the OTA Apploader) looks like this:
The OTA uploader uses a similar process:
The attached code implements image uploading to the slots using the standard OTA process. It is also extended with the possibility to select a slot to upload to, and to select a slot to boot from. You are free to modify this example according to your needs.
To create a project with multislot OTA DFU follow these steps:
//case gecko_evt_gatt_server_user_write_request_id: // ... //break;
(Note: setting gecko_bootloader=true in the .isc file will copy btl_interface.c and btl_interface_storage.c into your project again. Remove the instances you copied before to avoid duplicated definitions)
The external signal mechanism in the BLE SDK, gives you the ability to handle external events, such as GPIO interrupts.
Up to 32 separate signals can be sent from the user application to the Bluetooth stack through a call to the API function gecko_external_signal(). This API takes a 32 bit parameter which is interpreted as a set of 32 flags, one for each channel. The use for each channel can be set by the user. A call to this API causes the stack to send a system_external_signal event to the application. This event has a 32 bit value to indicate which signals have been sent since the last event. Sending the same signal multiple times will only result in multiple events once the signal has been cleared.
The example attached to this article is written for an EFR32BG1P device but can be easily ported to other devices. This application uses the external signal mechanism to signal the Bluetooth stack when a button on the WSTK board is pressed. The first step is to set up the GPIO lines for interrupts. This is done at the system_boot event (gecko_evt_system_boot_id) by calling setup_external_interrupts(). This function sets up the GPIO lines as inputs, configures them to generate interrupts and registers a callback to process the interrupts. When a button is pressed, the callback function ButtonHandler() is called. This function receives a single parameter to indicate which interrupts are active, gecko_external_signal() is then called to indicate to the stack which button was pressed. The system_external_signal event handler (gecko_system_external_signal_id) processes these signals. When this event is handled all of the signals are cleared.
The external signal mechanism is a convenient way for the application to allow the Bluetooth stack to schedule handling of non-Bluetooth tasks required by the application such as interrupt servicing.
This article discusses the lazy soft timer and how you can use it to optimize your application's current consumption.
Lazy is perhaps a misleading term. No need to “re-invent" the wheel, let’s see what the API Reference Guide has to say.
“This command can be used to start a software timer with some slack. Slack parameter allows stack to optimize wake ups and save power. Timer event is triggered between time and time + slack.”
What this means is that if the device wakes up for any other reason (e.g. radio wake-up, GPIO) between time and time+slack then the stack will also raise a soft timer event. If no other interrupt comes between time and time+slack then the soft timer event will wake-up the device at time+slack.
The reason why this saves energy is that there is fixed overhead for each wake-up. Looking at the EFR32BG1 datasheet we can see that wake-up from Deep Sleep (EM2) takes 10.7 us (table 4.9) and HFXO startup time is 300 us (table 4.32). This translates into energy that is being consumed without executing any code and on every single wake-up.
The idea behind the lazy soft timer is to pack more code execution into each wake-up period and reduce the overall need for additional wake-ups, thus reducing the overall energy consumption.
This is especially useful when used with radio wake-ups. During TX/RX the SoC is most of the time in EM1 (CPU not running) and waiting for the radio TX/RX operation to be finalized. While doing this the HFXO is running at 38.4 MHz and that alone cost 49 uA or 65 uA per MHz (a total of 1.88 mA or 2.49 mA) depending on whether the DC/DC is being used or not (tables 4.5, 4.6 and 4.7, EM1 current specs). When the stack raises a soft timer event right after a radio wake-up it allows a more efficient usage of the CPU which can execute application code instead of simply idling in EM1.
This example is based on the Thermometer example with EFR32 internal temperature sensor but using a smaller sampling interval of 100 ms. We then connect from a master device with a connection interval of 100 ms (a second WSTK+BGTool or BLED112 as master gives control over the connection parameters) and subscribe to indications from the temperature measurement characteristic which starts the soft timer or lazy soft timer.
Start by creating an SoC - Empty sample app for your chosen hardware.
Using BGTool you can now read the temperature sampled from the internal temperature sensor and change the connection parameters as needed.
The difference compared to the original internal temperature sensor is just one API call on line 202 in app.c shown below:
// Replace this: gecko_cmd_hardware_set_soft_timer(TICKS_PER_SECOND / 10, 0, 0); // With this: gecko_cmd_hardware_set_lazy_soft_timer(TICKS_PER_SECOND / 10, TICKS_PER_SECOND / 10, 0, 0);
Because the sensor readout doesn’t need to be extremely accurate, we’re giving it a slack which equals the timeout of 100 ms so that the stack should always be able to sync this up to a radio wake-up on one of the connection intervals.
Using the "traditional" soft timer we can see 3 peaks in the current consumption.
The smallest peaks are the DC/DC refreshing. The tallest peak is the radio activity on a connection interval. The other 2 peaks are the soft timer wake-ups which trigger the ADC sensor readout. Let’s take a closer look at the sensor readout.
The sensor readout phase takes just under 1 ms with an average current consumption of 4.34 mA. For finalizing the metrics to compare against the lazy soft timer usage let’s see what the overall average current consumption looks like.
So on average we are using 155 uA, with 100 ms sampling rate of the ADC temperature sensor triggered by a soft timer and a connection to a master device with 100 ms connection interval.
When using the lazy soft timer the first thing that’s noticeable is that the sensor readout peaks are gone.
And the biggest different comes on the average current consumption where we go from the original 155 uA to 115 uA, which represents an improvement of 25%.
If this would be a battery powered application it would translate into 25% more battery life. The difference between the average energy consumption can also be observed using the Energy Profiler tool built in to Simplicity Studio as shown below.
What is happening now is that the ADC sensor readout is done at the same time as the RX/TX radio operations when the CPU would otherwise be idling on top of a running (and power hungry) HFXO. Looking at the connection intervals we can see a small increase in the current consumption between using the soft timer and the lazy soft timer (upper and lower figure respectively).
The lazy soft timer offers the opportunity to sync up timer wake ups with other system wake ups, which allows you to further optimize your system’s energy consumption when timer accuracy is not a requirement.