Skip to content

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

Merged
merged 9 commits into from
Sep 7, 2017
Merged

Conversation

0xc0170
Copy link
Contributor

@0xc0170 0xc0170 commented Aug 15, 2017

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 progress

To 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-

@@ -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) {
Copy link
Contributor

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.

@@ -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();
Copy link
Contributor

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.

@@ -26,6 +26,7 @@ void Ticker::detach() {
core_util_critical_section_enter();
remove();
_function = 0;
sleep_manager_unlock_deep_sleep();
Copy link
Contributor

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.

@@ -41,6 +42,7 @@ void Timer::stop() {
core_util_critical_section_enter();
_time += slicetime();
_running = 0;
sleep_manager_unlock_deep_sleep();
Copy link
Contributor

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.

@0xc0170
Copy link
Contributor Author

0xc0170 commented Aug 17, 2017

@c1728p9 Added fixes for the last review.

@0xc0170 0xc0170 force-pushed the dev_sleep_drivers branch 2 times, most recently from 6eb12e8 to 18ed12c Compare August 17, 2017 08:48
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)) {
Copy link
Contributor

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();
Copy link
Contributor

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.

@0xc0170
Copy link
Contributor Author

0xc0170 commented Aug 18, 2017

@c1728p9 Fixed, I'll rebase once all approved to clean the history

@0xc0170 0xc0170 force-pushed the dev_sleep_drivers branch from 92ddba2 to e0048cb Compare August 20, 2017 15:46
@0xc0170 0xc0170 changed the title Drivers: add sleep locks (feature-hal-spec branch) Add sleep manager API Aug 21, 2017
@0xc0170
Copy link
Contributor Author

0xc0170 commented Aug 21, 2017

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:

  • add sleep manager API
  • deep sleep locks in drivers (Serial, SPI, etc)
  • rtos idle loop locks deep sleep (backward compability) for now

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

@0xc0170
Copy link
Contributor Author

0xc0170 commented Aug 21, 2017

retest uvisor

@0xc0170 0xc0170 mentioned this pull request Aug 21, 2017
@0xc0170
Copy link
Contributor Author

0xc0170 commented Aug 22, 2017

/morph test

@mbed-bot
Copy link

Result: FAILURE

Your command has finished executing! Here's what you wrote!

/morph test

@0xc0170
Copy link
Contributor Author

0xc0170 commented Aug 22, 2017

/morph test

@mbed-bot
Copy link

Result: FAILURE

Your command has finished executing! Here's what you wrote!

/morph test

Output

mbed Build Number: 1077

Build Prep failed!

@studavekar
Copy link
Contributor

/morph test

@mbed-bot
Copy link

Result: SUCCESS

Your command has finished executing! Here's what you wrote!

/morph test

Output

mbed Build Number: 1078

All builds and test passed!

@0xc0170 0xc0170 force-pushed the dev_sleep_drivers branch from 8a3cb67 to 65c075b Compare August 23, 2017 13:30
@0xc0170
Copy link
Contributor Author

0xc0170 commented Aug 23, 2017

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"
Copy link
Contributor

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.

Copy link
Contributor Author

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.


bool sleep_manager_can_deep_sleep(void)
{
core_util_critical_section_enter();
Copy link
Contributor

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;
Copy link
Contributor

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?

Copy link
Contributor

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

@0xc0170 0xc0170 force-pushed the dev_sleep_drivers branch from 65c075b to ac3b9d4 Compare August 29, 2017 15:03
@0xc0170
Copy link
Contributor Author

0xc0170 commented Aug 30, 2017

/morph test

@mbed-bot
Copy link

Result: ABORTED

Your command has finished executing! Here's what you wrote!

/morph test

Output

mbed Build Number: 1142

Build 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.
@0xc0170
Copy link
Contributor Author

0xc0170 commented Sep 7, 2017

Rebased (removed HAL docs changes, will come as separate PR), tested with nucloe f429, all good.

@studavekar
Copy link
Contributor

/morph test

@studavekar
Copy link
Contributor

Jobs seems have completed with results : http://mbed-ci-master-2.austin.arm.com:8081/job/pr_pipeline/1247/

@theotherjimmy
Copy link
Contributor

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();
Copy link
Contributor

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?

Copy link
Contributor

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();
Copy link
Contributor

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()
Copy link
Contributor

@c1728p9 c1728p9 Sep 7, 2017

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.

Copy link
Contributor

@c1728p9 c1728p9 left a 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.

@theotherjimmy theotherjimmy merged commit e12f116 into ARMmbed:master Sep 7, 2017
@sg-
Copy link
Contributor

sg- commented Sep 8, 2017

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=

@0xc0170
Copy link
Contributor Author

0xc0170 commented Sep 9, 2017

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

@0xc0170 0xc0170 deleted the dev_sleep_drivers branch September 9, 2017 07:42
@jeromecoutant
Copy link
Collaborator

Hi
In tests-mbed_drivers-lp_timeout and tests-mbed_hal-lp_ticker, we are still using deepsleep function which is deprecated.
Maybe you should update these tests ?
Thx

@0xc0170
Copy link
Contributor Author

0xc0170 commented Sep 20, 2017

In tests-mbed_drivers-lp_timeout and tests-mbed_hal-lp_ticker, we are still using deepsleep function which is deprecated.
Maybe you should update these tests ?

Yes, I'll do

@nvlsianpu
Copy link
Contributor

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
Copy link
Contributor

nvlsianpu commented Oct 11, 2017

@0xc0170, @pan- ^^

@0xc0170
Copy link
Contributor Author

0xc0170 commented Oct 11, 2017

@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 .

@nvlsianpu
Copy link
Contributor

@0xc0170 #5297

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants