-
Notifications
You must be signed in to change notification settings - Fork 2.1k
drivers/slipmux: Add to RIOT #21418
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
base: master
Are you sure you want to change the base?
drivers/slipmux: Add to RIOT #21418
Conversation
I don't quite understand the purpose if this. Sure, with this approach you can omit the IP and UDP header, but is that really worth the hassle? |
From the byte-wise overhead, it is not that much of a difference yes. I don't think it is that much of a hassle tho. Beside, as soon as you use IP+UDP you have endpoints in a network and those need to be configured (I need to know the IP I want to talk to). Doing slipmux configuration frames you have a guaranteed point to point channel with no configuration nor hassle ;) |
I can't comment on the code right now, but maybe for the open aspects:
|
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.
First round of review.
drivers/include/slipdev.h
Outdated
#if IS_USED(MODULE_SLIPDEV_STDIO) | ||
chunk_ringbuf_t rb_config; /**< Ringbuffer to store received CONFIG frames.*/ | ||
uint8_t rxmem_config[CONFIG_SLIPDEV_BUFSIZE]; /**< memory used by RX buffer */ | ||
kernel_pid_t coap_server_pid; |
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.
kernel_pid_t coap_server_pid; | |
kernel_pid_t coap_server_pid; /**< The PID of the CoAP server */ |
Wrt to future extensions, maybe that can be more generalized so that, e.g., also a gcoap or unicoap queue could be put here, if they exist to not have to provide an extra server then.
Again, mainly a comment for future improvements, this does not have to be addressed in this PR.
(edit: but would also address @chrysn's comment)
examples/basic/default/Makefile
Outdated
# Modules to include: | ||
USEMODULE += slipdev_stdio |
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 prefer this to be its own example.
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 second commit adds an usage example, where the shell commands are exposed to coap and through it to slipmux. That commit will be dropped prio merging.
Thanks for the review!
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 resolved your other comments without fixing them as they would be dropped too.
e203f61
to
7af6c9c
Compare
drivers/slipdev/slipdev.c
Outdated
void slipdev_setup(slipdev_t *dev, const slipdev_params_t *params, uint8_t index) | ||
{ | ||
#if IS_USED(MODULE_SLIPDEV_STDIO) |
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 a separate pseudo-module for this, normal slipdev stdio multiplex should not require a CoAP server.
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 are repeating yourself ;)
I am not sure yet if "just a separate pseudo-module" is the correct call. What do you think about making the driver "slipmux" with no functionality (not even slip). One can then add the pseudomodules slipmux_ip
, slipmux_configuration
and slipmux_stdio
which add their respective functions. This way, one could use configuration frames (-> coap) without needing IP/gnrc as a dependency.
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.
If you desire to do so go ahead.
I just want to avoid bloating the slipdev driver for simple device to device links that might have a multiplexed debug interface for convenience.
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 will be much more work than I thought. I'll move that task to a followup PR. For this one, I adopted your wish and guarded it with its own pseudomodule.
In addition, I changed the way the parsing is guarded with the #if IS_USED(..)
. Before: The whole case of stdio was removed if the module was not selected. Now: Only the data processing is removed, the cases for parsing remain. (Same for configuration frames). Reason is simple: If you remove the parsing + states, any byte received will be treated as a IP packet and then dropped by gnrc as "undefined packet type". This no-longer the case, instead, receiving a diagnostic/configuration frame without their pseudomodules enabled, they will be silently ignored.
88d8ca1
to
12435ec
Compare
@benpicco I think this is ready for another review. If that is positive, I will drop the shell/example related commit and squash the others. |
@benpicco ping :) |
review(miri) fix up review(ben): Guard slipmux config handling with own pseudo module adjustment for review, to be dropped fixup whitespace issues
12435ec
to
99211c0
Compare
@@ -120,13 +129,19 @@ typedef struct { | |||
typedef struct { | |||
netdev_t netdev; /**< parent class */ | |||
slipdev_params_t config; /**< configuration parameters */ | |||
chunk_ringbuf_t rb; /**< Ringbuffer to store received frames. */ | |||
chunk_ringbuf_t rb; /**< Ringbuffer to store received NET frames. */ |
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 “NET frames” wording from the draft?
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.
no it is not, it would be "Packet Transfer". I thought I would assume a bit that the reader is more likely to know RIOT than the Draft, so I picked a name that represents "Packet Transfer" for RIOT networking humans. Do you think that was a poor choice? I have no hard feelings on this. ("Packet frames" is rather confusing as one could say "coap packet")
/* Written to from interrupts (with irq_disable */ | ||
/* to prevent any simultaneous writes), */ | ||
/* consumed exclusively in the network stack's */ | ||
/* loop at _isr. */ | ||
|
||
uint8_t rxmem[CONFIG_SLIPDEV_BUFSIZE]; /**< memory used by RX buffer */ | ||
|
||
#if IS_USED(MODULE_SLIPDEV_CONFIG) | ||
chunk_ringbuf_t rb_config; /**< Ringbuffer to store received CONFIG frames.*/ |
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.
Same here for “CONFIG frames”.
Some high-level comments from my side:
Isn't it also missing diagnostic transfer? Just had a quick glance at the code, but could only find references to configuration frames.
|
crb_consume_chunk(&dev->rb_config, buf, len); | ||
|
||
/* Is crc correct via Residue test */ | ||
if (crc16_ccitt_fcs_update(SPECIAL_INIT_FCS, buf, len) != 0xF0B8) { |
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.
where does this constant come from? mind using a define or at least add a comment?
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's a residue test, the magic value is defined here, in the crc header. Please don't make me add all crcs residue values as defines 😨
That's because those were already implemented in RIOT and are just called stdio via slip. Blame @miri64 for that :p If you enable this, every
Eventually, yes. There is still work to be done on the coap-handling/server side. If I can get away with minimal documentation this time, I would appreciate. I fear it will be duplicated work if I re-implement it later (for example with unicoap). Plus, as mentioned in a comment with benpicco, the handling of the pseudomodule is not ideal in the moment. For example, it is not possible to enable configuration transfer without packet transfer. And even if you could, nanocoap depends on udp, which means you would still pull in a lot of wasted code & bytes. Both issues are scheduled for follow-up work.
That is correct.
That's nanocoap specific, I do not interact with them myself (beside the shell stuff but thats just an example of what one could do and will be dropped before merging). Afaik it is just a XFA defining names and callbacks. The nanocoap server just magically knows that XFA and looks up the endpoints on the fly. |
Contribution description
Hey 🪼,
this adds an (incomplete) implementation of Slipmux to RIOT. It extends the current slip driver and is backwards compatible.
The second commit adds an usage example, where the shell commands are exposed to coap and through it to slipmux. That commit will be dropped prio merging.
It is incomplete as frame abort is missing.
Testing procedure
Grab your favorite slipmux tool and connect RIOTs stdio to it. Make sure to build RIOT with
USEMODULE += slipdev_stdio
and optionally setCFLAGS += "-DCONFIG_NANOCOAP_BLOCK_SIZE_EXP_MAX=10"
to be able to handle coap packets that are longer than 64 bytes. See the changes I made to the default example.Feedback wanted: coap server
My current approach spawns a new thread with a nanocoap server to handle the incoming and outgoing configuration frames. This might cause issues when another coap server is in use (one that is connected to the network instead of just the uart). For example, the
NANOCOAP_RESOURCE(..)
s will be shared between them.I also experimented with sending the coap messages with a fake ip6+udp header into gnrc. One can then only run one single coap server (and it is no longer bound to nanocoap) who listens for such packets. The outgoing way is a bit more annoying, here a new dummy interface must be created, to which gnrc can direct those fake ip6+udp headers. Very similar to how it is already done with the current slip implementation.
What alternative approaches do you see? Any idea is appreciated.