-
Notifications
You must be signed in to change notification settings - Fork 3k
Unification of wait functions #2274
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* mbed Microcontroller Library | ||
* Copyright (c) 2006-2013 ARM Limited | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
// This implementation of the wait functions will be compiled only | ||
// if the RTOS is present. | ||
#ifdef MBED_CONF_RTOS_PRESENT | ||
|
||
#include "wait_api.h" | ||
#include "us_ticker_api.h" | ||
#include "rtos.h" | ||
#include "critical.h" | ||
|
||
void wait(float s) { | ||
wait_us(s * 1000000.0f); | ||
} | ||
|
||
void wait_ms(int ms) { | ||
wait_us(ms * 1000); | ||
} | ||
|
||
void wait_us(int us) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You shouldn't need to sacrifice accuracy here. If you read the current time before Thread:wait() you should be able to accurately busy wait for the rest of the time:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, that might help in some cases. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The accuracy concern still exists with neighboring threads locking interrupts over millisecond boundaries or if preemption occurs in the busy loop. I don't think it's really an issue, just a notable side effect of running an rtos. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True, but writing it like @c1728p9 suggested might still improve accuracy a bit. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, good point |
||
uint32_t start = us_ticker_read(); | ||
// Use the RTOS to wait for millisecond delays if possible | ||
int ms = us / 1000; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guessing there is a bit twiddling shift that is more appropriate to at least have a deterministic execution cycle count. Not to handle now but on M0 this will be a bit off but maybe it always has been. |
||
if ((ms > 0) && core_util_are_interrupts_enabled()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I recommend asserting if wait is called from an interrupt since this is likely not what the user wants. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not necessarily. Very short delays in interrupt context might still be OK. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with @bogdanm here. Waiting in irq isn't something we should encourage, but I would expect it to work. It wouldn't play well with the rtos, but sometimes an application simply doesn't care. Asserting in wait would also break backwards-compatiblity. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since there really wasn't an alternative to this in 2.0 I can see the need to support interrupts. It would be nice if the user could be warned if there are long delays from interrupts, since they could lead to failures in other components. |
||
Thread::wait((uint32_t)ms); | ||
us -= ms * 1000; | ||
} | ||
// Use busy waiting for sub-millisecond delays, or for the whole | ||
// interval if interrupts are not enabled | ||
if (us > 0) { | ||
while((us_ticker_read() - start) < (uint32_t)us); | ||
} | ||
} | ||
|
||
#endif // #if MBED_CONF_RTOS_PRESENT | ||
|
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 consider having wait and wait_ms use Thread:wait exclusively, since the RTOS will get you very close to ms resoultion
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.
That'd mean adding
core_utils_are_interrupts_enabled
checks to eachwait
function. Not sure this is needed.