-
Notifications
You must be signed in to change notification settings - Fork 3k
Cellular: Changed ATHandler yield to wait #6744
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
Conversation
Please review @jarvte |
remove also other yield to wait |
Please use request changes that would make this red and needs: work label applied immediately |
Yes, I wasn't added as a reviewer yet. Too fast 😁 |
0344090
to
63ce7ba
Compare
This is clunky - you should be using |
@kjbracey-arm do you mean like ATCmdParser::getc() |
Yes, like that. I assumed you were still using it for your own normal non-URC reading, but it seems to have fallen out. Having and using the |
268c49d
to
23e98b8
Compare
fill_buffer(); | ||
if (!fill_buffer()) { | ||
tr_error("fill failed %s", prefix); | ||
return; |
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.
What if we have already needed data in buffer, fetched during process_oob() -> match_urc() -> set_scope(InfoType) -> consume_char(' ') -> get_char() -> fill_buffer()? Should return only if buffer is also empty?
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.
fill_buffer
is currently waiting for data. Which it should only be doing if it thinks it hasn't got enough. So presumably it shouldn't be being called at all here. Or it should be being called with a zero timeout, at least, if you're trying to get stuff out of the serial port.
resp
a bit later does a fill_buffer
when it's out of data - that's the one that should have a timeout for the AT response time.
if (mem_str(_recv_buff, _recv_len, CRLF, CRLF_LENGTH)) { | ||
_start_time = rtos::Kernel::get_ms_count(); // time to process next (potential) URC | ||
} else if (mem_str(_recv_buff, _recv_len, CRLF, CRLF_LENGTH)) { | ||
// If no match found, look for CRLF and consume everything up to CRLF |
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.
I would move this comment bellow "else if"
#endif | ||
} while ((uint32_t)timer.read_ms() < _at_timeout); | ||
int timeout = (_start_time + _at_timeout) - rtos::Kernel::get_ms_count(); | ||
if (timeout >= 0) { |
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.
@kjbracey-arm suggests to still attempt one poll with 0 timeout even if the timeout expired. Same in write().
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.
Yes, you may have overshot your precise time, presumably due to CPU load or scheduling or debugger interference, but if you are already in your own processing context you may as well have one last immediate check before you go. No need to say "timeout" if the data is actually already there.
This is consistent with what other APIs that take "until" times do, like Semaphore::wait_until
.
uint64_t now = Kernel::get_ms_count();
if (now >= millisec) {
return wait(0);
} else if (millisec - now >= osWaitForever) {
// API permits early return
return wait(osWaitForever - 1);
} else {
return wait(millisec - now);
}
You might also want to handle the "target time is too big for int32_t" case. So:
if (now >= _start_time + _at_timeout) {
timeout = 0;
} else if ( _start_time + _at_timeout - now > INT_MAX) {
timeout = INT_MAX;
} else {
timeout = _start_time + _at_timeout - now;
}
Unfortunate that there's no poll_until
that does that for you. I possibly should add it; I didn't because it doesn't exist in any POSIX or C/C++ standard.
Requests above fixed in 13c7d05 |
@@ -1099,7 +1097,12 @@ size_t ATHandler::write(const void *data, size_t len) | |||
fhs.events = POLLOUT; | |||
size_t write_len = 0; | |||
for (; write_len < len; ) { | |||
int count = poll(&fhs, 1, _at_timeout); | |||
int timeout = (_start_time + _at_timeout) - rtos::Kernel::get_ms_count(); |
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.
This should probably have the same timeout computation logic as for the fill_buffer, so attempting something if time has passed. So maybe make it a "compute timeout" subroutine.
You only need the device error on the return from poll, not this extra one.
|
||
pollfh fhs; | ||
fhs.fh = _fileHandle; | ||
fhs.events = POLLIN; | ||
int count = poll(&fhs, 1, timeout); | ||
int timeout = 0; |
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.
Left this variable behind.
|
||
set_error(NSAPI_ERROR_DEVICE_ERROR); | ||
tr_debug("AT TIMEOUT, scope: %d timeout: %lu", _current_scope, _at_timeout); | ||
if (wait_for_timeout) { |
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 possibly feels like this set_error
should be one layer up, where you're printing the tr_warn("AT TIMEOUT")
. The error view maybe depends what you were waiting for.
@kjbracey-arm Not certain if this is approved and those 2 comments should block this PR ? @AriParkkila please review them |
@mirelachirica @jarvte Please review the update |
Can you please rebase instead of merge (the commit is not needed at all here) |
1f75d3b
to
ad37e90
Compare
ad37e90
to
287a1a8
Compare
rebased |
/morph build |
Build : SUCCESSBuild number : 2006 Triggering tests/morph test |
Test : SUCCESSBuild number : 1816 |
Exporter Build : SUCCESSBuild number : 1658 |
Description
Yield doesn't really achieve very much - it's still using 100% of CPU power and it won't let lower-priority threads run.
Fixes internal issue OTCELL-556.
Pull request type