-
Notifications
You must be signed in to change notification settings - Fork 178
Update DeepSleepLock #316
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Update DeepSleepLock #316
Changes from 3 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,96 +1,15 @@ | ||
## DeepSleepLock | ||
|
||
There is only one sleep function in Mbed OS 5.6: | ||
The `DeepSleepLock` class provides an RAII object for disabling sleep. In other words, creating a DeepSleepLock object calls its constructor, which increments the deep sleep prevention lock. The DeepSleepLock object automatically releases the deep sleep prevention lock in its destructor when the object goes out of scope. Another way to look at this is when the DeepSleepLock object exists, it prevents deep sleep. | ||
|
||
```c++ | ||
void sleep(); | ||
``` | ||
|
||
This function invokes sleep manager, which we introduce below. | ||
|
||
The idle loop invokes sleep manager by default. You can overwrite this default behavior by attaching a different idle hook function pointer. | ||
|
||
```c++ | ||
void new_idle_loop() | ||
{ | ||
// do nothing | ||
} | ||
|
||
void main() | ||
{ | ||
rtos_attach_idle_hook(&new_idle_loop); | ||
} | ||
``` | ||
|
||
### Sleep modes | ||
|
||
There are two available sleep modes: | ||
|
||
1. Sleep mode | ||
|
||
The system clock to the core stops until a reset or an interrupt occurs. This eliminates dynamic power that the processor, memory systems and buses use. This mode maintains the processor, peripheral and memory state, and the peripherals continue to work and can generate interrupts. | ||
|
||
You can wake up the processor by any internal peripheral interrupt or external pin interrupt. | ||
|
||
2. Deep sleep mode | ||
|
||
This mode is similar to sleep but saves more power and has a longer wakeup time. It saves power by turning off the high-speed clocks. Because of this, you can only enter this mode when peripherals relying on high-speed clocks are not in use. Peripherals that do not rely on high-speed clocks include the lp ticker, RTC and external interrupt on a pin. This mode maintains all state. | ||
|
||
### Sleep manager | ||
|
||
The sleep manager provides an API to control sleep modes. Deep sleep might introduce some power savings that can affect an application, for instance high speed clock dependent drivers. | ||
|
||
The `DeepSleepLock` class provides an RAII object for disabling sleep, or explicit lock/unlock methods. To prevent an application from entering deep sleep, invoke the `DeepSleepLock()::lock()` method. As soon as an application is ready for the deep sleep, allow it by invoking the `DeepSleepLock::unlock()` method. | ||
|
||
These Mbed OS drivers contain locking deep sleep: | ||
|
||
- `Ticker`. | ||
- `Timeout`. | ||
- `Timer`. | ||
- `SPI`. | ||
- `I2C`. | ||
- `CAN`. | ||
- `SerialBase`. | ||
|
||
### SleepManager class reference | ||
|
||
[https://github.com/ARMmbed/mbed-os/blob/master/platform/mbed_sleep.h](https://github.com/ARMmbed/mbed-os/blob/master/platform/mbed_sleep.h) | ||
<span class="notes">**Note:** Drivers that don't work in deep sleep mode automatically prevent deep sleep mode, so DeepSleepLock does not need to protect them.</span> | ||
|
||
### DeepSleepLock class reference | ||
|
||
[](https://os.mbed.com/docs/v5.6/mbed-os-api-doxy/classmbed_1_1_deep_sleep_lock.html) | ||
|
||
### Example | ||
|
||
This example shows SPI asynchronous transfer with deep sleep locking. | ||
|
||
```c++ | ||
|
||
SPI::transfer(const Type *tx_buffer, int tx_length, Type *rx_buffer, int rx_length, const event_callback_t& callback, int event = SPI_EVENT_COMPLETE) | ||
{ | ||
if (spi_active(&_spi)) { | ||
return queue_transfer(tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type)*8, callback, event); | ||
} | ||
// This driver requires high speed clock, needs to wait for complete flag set via a callback to unblock the deep sleep | ||
sleep_manager_lock_deep_sleep(); | ||
start_transfer(tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type)*8, callback, event); | ||
return 0; | ||
} | ||
|
||
This example shows how you can lock deep sleep to decrease interrupt latency at the expense of increased power consumption. | ||
|
||
void SPI::irq_handler_asynch(void) | ||
{ | ||
int event = spi_irq_handler_asynch(&_spi); | ||
if (_callback && (event & SPI_EVENT_ALL)) { | ||
_callback.call(event & SPI_EVENT_ALL); | ||
} | ||
if (event & (SPI_EVENT_ALL | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE)) { | ||
// all data should be written now, unlock the deep sleep | ||
sleep_manager_unlock_deep_sleep(); | ||
#if TRANSACTION_QUEUE_SIZE_SPI | ||
// SPI peripheral is free (event happend), dequeue transaction | ||
dequeue_transaction(); | ||
#endif | ||
} | ||
} | ||
``` | ||
[](https://os.mbed.com/teams/mbed_example/code/DeepSleepLock_Example_1/file/66aac0656e71/main.cpp) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
## Sleep manager | ||
|
||
There is only one sleep function in Mbed OS 5.6: | ||
|
||
```c++ | ||
void sleep(); | ||
``` | ||
|
||
This function invokes sleep manager, which we introduce below. | ||
|
||
The idle loop invokes sleep manager by default. You can overwrite this default behavior by attaching a different idle hook function pointer. | ||
|
||
```c++ | ||
void new_idle_loop() | ||
{ | ||
// do nothing | ||
} | ||
|
||
void main() | ||
{ | ||
rtos_attach_idle_hook(&new_idle_loop); | ||
} | ||
``` | ||
|
||
### Sleep modes | ||
|
||
There are two available sleep modes: | ||
|
||
1. Sleep mode | ||
|
||
The system clock to the core stops until a reset or an interrupt occurs. This eliminates dynamic power that the processor, memory systems and buses use. This mode maintains the processor, peripheral and memory state, and the peripherals continue to work and can generate interrupts. | ||
|
||
You can wake up the processor by any internal peripheral interrupt or external pin interrupt. | ||
|
||
2. Deep sleep mode | ||
|
||
This mode is similar to sleep but saves more power and has a longer wakeup time. It saves power by turning off the high-speed clocks. Because of this, you can only enter this mode when peripherals relying on high-speed clocks are not in use. Peripherals that do not rely on high-speed clocks include the lp ticker, RTC and external interrupt on a pin. This mode maintains all state. | ||
|
||
### Sleep manager | ||
|
||
The sleep manager provides an API to control sleep modes. Deep sleep might introduce some power savings that can affect an application, for instance high speed clock dependent drivers. | ||
|
||
These Mbed OS drivers contain locking deep sleep: | ||
|
||
- `Ticker`. | ||
- `Timeout`. | ||
- `Timer`. | ||
- `SPI`. | ||
- `I2C`. | ||
- `CAN`. | ||
- `SerialBase`. | ||
|
||
### Sleep manager function reference | ||
|
||
[https://github.com/ARMmbed/mbed-os/blob/master/platform/mbed_sleep.h](https://github.com/ARMmbed/mbed-os/blob/master/platform/mbed_sleep.h) | ||
|
||
### Example | ||
|
||
[](https://os.mbed.com/users/c1728p9/code/SleepManager_Example_1/file/e85412b4147e/main.cpp) | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Query: Is there any way to put this in the same teams location as the other examples?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I updated this to point to that.