-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
drivers/at: fix URC collision with command response #20062
Conversation
@@ -295,8 +336,6 @@ ssize_t at_send_cmd_get_lines(at_dev_t *dev, const char *command, | |||
goto out; | |||
} | |||
|
|||
/* only clear the response buffer after sending the command, |
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.
Removed because it implies the command and response buffer may overlap, which by function signature would be UB.
int res; | ||
do { | ||
res = at_expect_bytes(dev, bytes, timeout); | ||
} while (res != 0 && res != -ETIMEDOUT); |
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.
The timeout might be reset multiple times. Is that ok?
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 is the way timeouts worked the whole time, so I stuck to this behavior.
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.
there wasn't a loop before
before:
at_expect_bytes(dev, bytes, timeout); // takes upto timeout time
takes upto timeout time
me unroll
this:
at_expect_bytes(dev, bytes, timeout); //takes upto timeout time
if (res != 0 && res != -ETIMEDOUT) at_expect_bytes(dev, bytes, timeout);//takes upto timeout time
if (res != 0 && res != -ETIMEDOUT) at_expect_bytes(dev, bytes, timeout); //takes upto timeout time
if (res != 0 && res != -ETIMEDOUT) at_expect_bytes(dev, bytes, timeout); //takes upto timeout time
...
takes upto N-times time out unless a 0 or timeout is returned
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.
ah i see 'at_expect_bytes' would also trickle from byte to byte so the timeout is expected to be from byte to byte, not for the whole function
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'm not fond of this way of handling timeouts either, but this goes all way down to how isrpipe_read_timeout()
works. On the other hand, the modems usually send data in bursts, so I can hardly imagine a scenario where timeouts massively add up.
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.
thanks for clarification
6cd7cfc
to
6e5e648
Compare
see the static test fail |
drivers/include/at.h
Outdated
* @returns line length on success | ||
* @returns <0 on error |
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.
* @returns line length on success | |
* @returns <0 on error | |
* @retval n line length on success | |
* @retval <0 on error |
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.
the PR seems good to me
please start your PR description with What this changes and then the why ( the PR description is part may be part of the merge commit ) |
Contribution description
Fix URCs being occasionally mistaken for command response.
Causes
Some DCEs (e.g. LTE modules from uBlox) define a grace period where URCs are
guaranteed NOT to be sent as the time span between:
As follows, there is an indeterminate amount of time between:
i.e. the begin of the grace period
In other words, we can get a URC (or more?) just after issueing the command
and before the first line of response. The net effect is that such URCs will
appear to be the first line of response to the last issued command.
The current solution is to skip characters that don't match the expected
response, at the expense of losing these URCs. Note, we may already lose URCs
when calling at_drain() just before any at_send_cmd(). Success partially depends
on whether command echoing is enabled or not:
BEFORE the echoed command (@aaltuntas can you please confirm this?).
This has the advantage that we ALWAYS know what
the first line of response must look like and so if it doesn't, then it's a
URC. Thus, any procedure that calls at_send_cmd() will catch and discard
these URCs.
will catch and discard any URC (or, if MODULE_AT_URC enabled, hand it over to
the URC callbacks). For the rest, it is the application's responsibility to
handle it.
If missing URCs is unacceptable
As already mentioned, 100% URC coverage is already not guaranteed, but if that needs to be improved, the approach suggested by @aaltuntas here should be implemented.
Testing procedure
I added a python script that simulates some hard-coded responses, with URCs right before the response. Follow the instructions inside.
This is not tested against at_urc_isr, as it introduces some timing issues nevertheless. See #20059
Issues/PRs references
#20059
#14327