-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
esp8266/uart: rework uart io structure so it can work with dupterm() and be used to disable stdio #2891
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
How does the group feel about moving input_buf into the py UART structure, the ask is if its reasonable direction to take
|
The input buffer for the REPL should be separate from the UART (so webrepl can work without uart). The uart itself can have an rx buffer, but that should ideally be dynamically allocated so memory is not wasted if the buffer is not used. And I think the esp8266 has a large-ish internal uart buffer so one might get away without a uart rx buffer at all. |
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.
using the hardware structure for uart_rx_any doesn't actually work, we have pulled the samples out by the time we get here. I think input_buf actually needs to be part of the low-level uart code and not spread out.
couple of subtle points not to get lost:
So I think REPL needs an input_buf, with its signaling functions that input has arrived using of course the same naming scheme. And the uart or what ever else needs to be responsible for buffering its own input and causing the async signaling to occur. |
picture is work in progress with this series of patches the following behavior exists. Current design works as is functionality new functionality is predicated on term_obj being set via dupterm. Once the dupterm has been configured the serial port is disabled and can be provisioned to other functions! nostdio over uart folded into the dupterm infrastructure. connecting uart to repl via dupterm works as expected.
I tested webrepl and my little telnet server and things seem to function well reading and writing files etc. I'm going to add another field to UART for the buffer as suggested and make the default 16 for UART0 and 0 for UART1 which is only valid for TX anyways. |
Well, I actually started from here. |
@mhoffma Is my conclusion coreect? P.S.: Using main branch of the upstream Micropython repo, when I send my AT commands, I can see the full response getting back from my module (which will blow back to my REPL and causes mass confusion!) |
I suspect this part of the patch is causing you to only receive 15 characters (technically, 15 printables + a \0 ?)
I don't know why @mhoffma is so restrictive in selecting a buffer of this size.. perhaps he will inform us! |
@mohpor |
@dpgeorge What open concerns do you have with this PR that are preventing it from being merged? Not OP, but definitely interested in this! |
In general it looks OK, but since it makes some deep changes wrt UART processing it needs a thorough review. It will need to wait until after v1.9. There are also some code style issues, such as missing curly braces for single-line statement blocks, and missing spaces around operators, like =. |
@mhoffma are you still interested in working on this? As said above there are lots of code style problems. If you don't have time then I will take it from here. |
I am interested in this, but my availability has dwindled. I got a little
time this weekend to merge to the latest and see that it all still
functions well and was planing to push that to my pull request unless you
don't want me to. Please help me isolate the changes you require and I
will make time this weekend I have a few hours in the early morning that I
can contribute. Maybe there is a special git diff that can help, if there
is I'm not sure how to use it.
Thanks
Marc
…On Thu, Jun 1, 2017 at 3:39 AM, Damien George ***@***.***> wrote:
@mhoffma <https://github.com/mhoffma> are you still interested in working
on this? As said above there are lots of code style problems. If you don't
have time then I will take it from here.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2891 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AQEAU4Bb_e43TMVGv3Xe5opIoHt-6N-Wks5r_mqvgaJpZM4MGw0o>
.
|
esp8266/esp_mphal.c
Outdated
void mp_hal_uart_rx_intr(int uart_no) { | ||
int ch; | ||
mp_obj_t term = MP_STATE_PORT(term_obj); | ||
bool uart_term=(term == NULL || term == MP_STATE_PORT(pyb_uart_objs)[uart_no]); |
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.
should this be
bool uart_term = (term == NULL || term == MP_STATE_PORT(pyb_uart_objs)[uart_no]);
esp8266/esp_mphal.c
Outdated
bool uart_term=(term == NULL || term == MP_STATE_PORT(pyb_uart_objs)[uart_no]); | ||
|
||
for (;;) { | ||
if ((ch = uart_rx_one_char(uart_no))==-1) |
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 the correct spacing?
if ((ch = uart_rx_one_char(uart_no)) == -1)
@@ -146,6 +149,31 @@ void mp_hal_signal_input(void) { | |||
#endif | |||
} | |||
|
|||
void mp_hal_uart_rx_intr(int uart_no) { |
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.
IMO this belongs in machine_uart.c, since it's specific to UART behaviour. Also, since UART1 can't receive it doesn't need to take an argument.
esp8266/esp_mphal.c
Outdated
if (ch == mp_interrupt_char) | ||
mp_keyboard_interrupt(); | ||
else | ||
ringbuf_put(&input_buf, ch); |
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.
Please use curly braces for single-line bodies.
@@ -40,6 +40,10 @@ extern const struct _mp_print_t mp_debug_print; | |||
extern ringbuf_t input_buf; | |||
// Call this after putting data to input_buf | |||
void mp_hal_signal_input(void); | |||
// Call this to put characters into connected uart buffer if repl connected | |||
void mp_hal_uart_rx_intr(int uart_no); |
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 way this function is currently implemented, it handles chars even if REPL is not connected.
esp8266/machine_uart.c
Outdated
#include "modmachine.h" | ||
|
||
// UartDev is defined and initialized in rom code. | ||
extern UartDevice UartDev; | ||
|
||
#define RXBUF_SIZE 16 |
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 unused.
esp8266/machine_uart.c
Outdated
@@ -73,6 +89,7 @@ STATIC void pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const mp_o | |||
//{ MP_QSTR_rx, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, | |||
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, | |||
{ MP_QSTR_timeout_char, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, | |||
{ MP_QSTR_rxbuflen, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 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.
Use 16 instead of 0 for the default.
esp8266/machine_uart.c
Outdated
@@ -155,6 +172,10 @@ STATIC void pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const mp_o | |||
self->timeout_char = min_timeout_char; | |||
} | |||
|
|||
self->rxbuflen = args[ARG_rxbuflen].u_int; | |||
if (self->uart_id == 0 && self->rxbuflen < 16) { |
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.
Don't need this check if 16 is given as a default above.
esp8266/machine_uart.c
Outdated
@@ -211,6 +244,29 @@ STATIC const mp_rom_map_elem_t pyb_uart_locals_dict_table[] = { | |||
|
|||
STATIC MP_DEFINE_CONST_DICT(pyb_uart_locals_dict, pyb_uart_locals_dict_table); | |||
|
|||
|
|||
|
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.
Please don't add blank lines like this. Follow existing conventions.
esp8266/machine_uart.c
Outdated
pyb_uart_init_helper(self, n_args - 1, args + 1, &kw_args); | ||
|
||
if (self->rxbuflen) { | ||
if (self->buf) { |
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.
Please use 4 spaces for indenting.
To move forward with this we really need to decide if the dupterm (on esp8266) will have only 1 slot, or more than one. This PR goes on the basis of 1 slot only. That will mean that (eventually, doesn't need to be address right now by this PR):
On the other hand, if dupterm has 2 slots then it can behave as:
For ports that want multiple dupterm slots it would be good to specify the above behaviour (or something similar) in the docs. For esp8266 it's then a question of whether it has the resources to implement 2 slots. |
I'm confused on multiple slots (2), I think you can build that behavior
right in Python keeping the kernel stuff as simple as possible. With
python you can insert any object that looks like a stream into the terminal
slot and have it do what ever you want lets say logging to the flash at the
same time as redirecting to webrepl and to a telnet session and of course
the uart (we can do what ever we want with the python language). Having
that additional state seems ok but I don't get what it really buys us when
you can model the behavior in python already. What am I missing?
…On Fri, Jun 2, 2017 at 4:34 AM, Damien George ***@***.***> wrote:
To move forward with this we really need to decide if the dupterm (on
esp8266) will have only 1 slot, or more than one. This PR goes on the basis
of 1 slot only. That will mean that (eventually, doesn't need to be address
right now by this PR):
- uos.dupterm(machine.UART(0, 115200)) should be added to boot.py so
the REPL appears by default on the UART.
- uos.dupterm(None) can be used to completely disable the REPL. For
example, this is used in cases where the UART is freed for other use and
there's no WebREPL (normal case for a stand-alone device doing its thing).
In particular this means that a NULL dupterm object does not mean to use
the default UART, as this PR currently assumes.
- webrepl needs to be modified so that it restores the UART once it is
closed/deactivated. But it should only restore it if the UART was there
before webrepl was activated.
On the other hand, if dupterm has 2 slots then it can behave as:
- uos.dupterm(machine.UART(0, 115200), 1) can be added to boot.py to
put UART in slot 1 (the second slot).
- uos.dupterm(None, 1) can be used to disable UART.
- webrepl would do uos.dupterm(ws) to enable itself, and
uos.dupterm(None) to disable, which would work by having slot 0 as the
default (equivalently one could write uos.dupterm(ws, 0) and uos.dupterm(None,
0)). webrepl doesn't need to know if UART is enabled or not.
For ports that want multiple dupterm slots it would be good to specify the
above behaviour (or something similar) in the docs. For esp8266 it's then a
question of whether it has the resources to implement 2 slots.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2891 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AQEAU0kjEqEeA_tOQ0cKS1gTKUKyeGi_ks5r_8kGgaJpZM4MGw0o>
.
|
Yes, that's how it's intended to be. (Then people will throw away that line and cry "where's my repl???777".)
Yes, I guess let's do it that way. My concern, as before, is that this "explicit slot numbers" are somewhat adhoc. The situation is as with not allowing to mount a filesystem on root. But mounting is very user-visible feature, and for dupterm(), I guess we can go for compromise. |
I'm not sure what exactly you mean, but we discussed that in the ticket you linked to. Summary: a) @dpgeorge wants to provide "duplicate", not "switch" behavior out of the box; b) it's one thing to be able to potentially implement in Python, another to make it actually work reliably (with low memory, etc.). |
That's fine we can do it anyway you want of course. Is it possible that we add that behavior on a separate PR, adding this behavior in two stages along the lines of an incremental fashion? |
From @dpgeorge on micropython#2891: IMO this belongs in machine_uart.c, since it's specific to UART behaviour. Also, since UART1 can't receive it doesn't need to take an argument. Makes more sense here as it is UART specific.
Ability to disbale UART(0) on the REPL was implemented in afd0701 |
This is the start in a series of refactorings of the UART on esp8266 so we can move in the direction of a single slotted. The first in the series of commits will globalize the UART py structure so that we have direct access to the py object from the root state structure. The original dialogue #2814 which discusses a hack implementation that allowed for disabling stdio on the UART for boards which only have a single serial port.