-
Notifications
You must be signed in to change notification settings - Fork 3k
Add sleep manager API #4912
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
Add sleep manager API #4912
Conversation
a85b351
to
08ba260
Compare
@@ -115,9 +115,11 @@ int CAN::filter(unsigned int id, unsigned int mask, CANFormat format, int handle | |||
void CAN::attach(Callback<void()> func, IrqType type) { |
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.
Attach could also be called to replace a callback of the same type. If this is the case then deep sleep shouldn't be locked a second time.
drivers/SerialBase.cpp
Outdated
@@ -73,9 +76,11 @@ void SerialBase::attach(Callback<void()> func, IrqType type) { | |||
// Disable interrupts when attaching interrupt handler | |||
core_util_critical_section_enter(); | |||
if (func) { | |||
sleep_manager_lock_deep_sleep(); |
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.
Attach could also be called to replace a callback of the same type. If this is the case then deep sleep shouldn't be locked a second time.
drivers/Ticker.cpp
Outdated
@@ -26,6 +26,7 @@ void Ticker::detach() { | |||
core_util_critical_section_enter(); | |||
remove(); | |||
_function = 0; | |||
sleep_manager_unlock_deep_sleep(); |
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.
Detach could be called while already detached (like during object destruction) which could cause an underflow.
drivers/Timer.cpp
Outdated
@@ -41,6 +42,7 @@ void Timer::stop() { | |||
core_util_critical_section_enter(); | |||
_time += slicetime(); | |||
_running = 0; | |||
sleep_manager_unlock_deep_sleep(); |
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.
Unlock should only be called if the timer was running.
@c1728p9 Added fixes for the last review. |
6eb12e8
to
18ed12c
Compare
drivers/I2C.cpp
Outdated
@@ -125,6 +125,7 @@ void I2C::unlock() { | |||
int I2C::transfer(int address, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, const event_callback_t& callback, int event, bool repeated) | |||
{ | |||
lock(); | |||
sleep_manager_lock_deep_sleep(); | |||
if (i2c_active(&_i2c)) { |
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.
If I2C is already active, you aren't starting a new transfer. You should probably either unlock before returning or add the lock until after the active check.
drivers/CAN.cpp
Outdated
_irq[(CanIrqType)type] = func; | ||
can_irq_set(&_can, (CanIrqType)type, 1); | ||
} else { | ||
sleep_manager_unlock_deep_sleep(); |
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.
Same problem could occur with the else case - it is valid to call attach with null multiple times in a row. Maybe as a general strategy, each interrupt type could be locked when donothing
is replaced, and unlocked when donothing
is set. A similar change should also be made for SerialBase.
@c1728p9 Fixed, I'll rebase once all approved to clean the history |
92ddba2
to
e0048cb
Compare
This now should be feature complete (testing ongoing, plus reviews so expect me to rebase). I rebased it , so the first comment is not relevant anymore - this is now adding these:
It should be good to go - being backward compatible plus adding new feature that we will use with upcoming tickless addition. This is still against feature hal spec branch. I'll send tests as separate patch soon. Quickly tested with rtos tests for K64F and GCC ARM - all OK |
retest uvisor |
/morph test |
Result: FAILUREYour command has finished executing! Here's what you wrote!
|
/morph test |
Result: FAILUREYour command has finished executing! Here's what you wrote!
OutputBuild Prep failed! |
/morph test |
Result: SUCCESSYour command has finished executing! Here's what you wrote!
OutputAll builds and test passed! |
8a3cb67
to
65c075b
Compare
I added DeepSleepLock RAII object . One thing to consider - it is currently just lock/unlock on aquicistion/release. But to be usable also with async, we might need to add also lock/unlock methods. This however might require more additions to be completed ? For instance, should it track pair lock/unlock, thus when destroying, it would clean up ? Please review |
drivers/CAN.h
Outdated
@@ -24,6 +24,7 @@ | |||
#include "platform/Callback.h" | |||
#include "platform/PlatformMutex.h" | |||
#include "platform/NonCopyable.h" | |||
#include "platform/mbed_sleep.h" |
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.
Is this intentionally propagation of "mbed_sleep.h" inclusion to any module which using the driver? If not this should be moved to the cpp file of the driver instead. This remark is up to all drivers headers in this patch.
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.
@nvlsianpu thanks for the review, the PR updated , all should be fixed.
hal/mbed_sleep_manager.c
Outdated
|
||
bool sleep_manager_can_deep_sleep(void) | ||
{ | ||
core_util_critical_section_enter(); |
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.
Critical section is not required for read of natively supported integer (uint16). It only extend call execution time.
* void f() { | ||
* // some code here | ||
* { | ||
* DeepSleepLock lock; |
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.
Dose such a object will not been cutted out as unused object?
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.
It looks like it is guaranteed by cpp object life cycle behaviour. cpp reference
65c075b
to
ac3b9d4
Compare
/morph test |
Result: ABORTEDYour command has finished executing! Here's what you wrote!
OutputBuild failed! |
As attach provides API to change a callback, lock/unlock should only happen if we are doing the first/last callback (start-stop).
attach/detach can be multiple invoked. Therefore lock/unlock deep sleep only for the very first time it is invoked (when callbacks are actually changed).
RAII object for disabling, then restoring the deep sleep mode
This commits contains two tests: - race condition - deep sleep locking/unlocking
For backward compability, we invoke just sleep mode. Adding critical section to complete lock/unlock deepsleep section.
As Callback currently does not have fully functional comparision (see ARMmbed#5017), we workaround by doing null check.
35dfd55
to
f6c34a2
Compare
Rebased (removed HAL docs changes, will come as separate PR), tested with nucloe f429, all good. |
/morph test |
Jobs seems have completed with results : http://mbed-ci-master-2.austin.arm.com:8081/job/pr_pipeline/1247/ |
Awesome! LGTM. |
@@ -102,6 +103,10 @@ class Ticker : public TimerEvent, private NonCopyable<Ticker> { | |||
* @param t the time between calls in micro-seconds | |||
*/ | |||
void attach_us(Callback<void()> func, us_timestamp_t t) { | |||
// lock only for the initial callback setup | |||
if (!_function) { | |||
sleep_manager_lock_deep_sleep(); |
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.
How does the sleep manager get unlocked?
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.
Generally, sleep_manager_unlock_deep_sleep
, but you're asking for the specific unlock for this call to lock right?
@@ -40,6 +41,9 @@ void Timer::start() { | |||
void Timer::stop() { | |||
core_util_critical_section_enter(); | |||
_time += slicetime(); | |||
if (_running) { | |||
sleep_manager_unlock_deep_sleep(); |
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.
You might want to unlock this on object destruction.
|
||
/** Mark the start of a locked deep sleep section | ||
*/ | ||
void lock() |
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.
Is there any reason to expose lock and unlock? This brings back the risks of forgetting to balance locks and unlocks.
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.
Looks good to me. There are a couple of things that should be addressed after this is merged.
Nice change removing the donothing. Looks like there is one straggler left in the codebase. https://github.com/ARMmbed/mbed-os/search?utf8=%E2%9C%93&q=callback%28donothing%29&type= |
It was left there as donothing replacement in this PR was required for making new API working (compare if a callback was attached or not). Thanks for checking ! Yes, I'll send PR shortly to align also InterruptIn |
Hi |
Yes, I'll do |
Apparently looks like this path broke nrf52_Dk (nrf52840 as well) spi (tests-api-spi). Commit cb4e9b3 introduced such a change. Even if i comment off sleep instruction it still failed. |
@nvlsianpu I do not fully get even if you comment out sleep, then it still fails? Can you create an issue with details, I would like to reproduce it locally . |
This goes to feature-hal-spec, based on the sleep manager work that is here #4882 . Review only the last commit (at the moment SHA 34f9f43). This goes to
feature-hal-spec
branch = work in progressTo move further with sleep, I am sending this early to get feedback.
The goal is to have deepsleep locks for those drivers that depend on high speed clocks (it can be that some drivers for a target might support deep sleep but this is not usual, plus speed is limited often).
@bulislaw @c1728p9 @pan-