-
-
Notifications
You must be signed in to change notification settings - Fork 19.3k
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
Fix MeatPack with per-serial-port instances #21306
Fix MeatPack with per-serial-port instances #21306
Conversation
… the multiserial class. This prevents mixing meatpack's internal decoding state between serial ports when both are used.
e93d95a
to
42e1a45
Compare
I added a "Needs Discussion" label based on your comment in #21301 since we have two solutions. |
Yes, if we decide enabled/disable meatpack per serial port, we need this PR. But yet it has the issue with the parser holding internal state. You need to add the options to the configuration for the user enabled/disable it too. And most importantly? Did you test it? |
Is there a documentation of Meatpack protocol somewhere, or is it just this code as the documentation ?
Does meatpack can interpret XY as something special or does it says "it's Y so it's not for me, let output it transparently, X is for me so let's glob it for my decoder" ? Reading the code, I think meatpack does not do that, it mixes things up so an approach that's just splitting at the output of the decoding will likely fails if the input is garbage/interleaved. |
MeatPack as a stream protocol gets one instance per serial port (that wants it) and each instance can be enabled and disabled independently of the others. It is disabled by default until the start sequence arrives, and it remains enabled until the end sequence arrives. It's unclear how to handle a port stuck in MeatPack mode if the sender just "goes away," but presumably on reconnect the plugin will say something again, or we can choose to turn it off on any detectable fresh reconnect. |
The protocol is generally described here https://github.com/scottmudge/OctoPrint-MeatPack and when this first arrived I validated the code in Marlin by reading the corresponding (and not very long) MeatPack compression code to make sure that I grokked it completely. |
If I understand correctly, the multi-serial code can actually disregard the MeatPack aspect of the serial ports that it wraps, and therefore if we use simple inheritance to add MeatPack to a base class then the Multi-Serial class won't need any special case for extended classes like MeatPackSerial. |
Alright. It's not 100% transparent, yet, since if you send 2
True.
Yes, that's the idea. But we still need something to enable the base class and that the idea of this PR. If MEATPACK_ENABLED_ON_SERIAL_PORT_0 is defined, then the serial class is This is just a preprocessor/typedef work going on here to select the right type to use for the final serial class, but adding MeatPackSerial in the hierarchy here should be transparent. |
This reverts commit cf96951.
Check whether binary stream bypasses everything else, including MeatPack and the queue feeder, when it is in effect. |
I don't understand. Do you want me to check, or you've checked it's ok ? |
Note that it is not expected that a binary stream should arrive as part of a print job, but should be a fairly atomic operation. And, if a host were sending a binary stream — either alone or in tandem with a G-code to initiate it — it's most likely that MeatPack would be temporarily suspended, as it certainly would not want to be involved in a transfer of data which is not G-code. That said, a MeatPack-compressed stream would be a nice extra optimization for a G-code binary file transfer. |
It looks like it's not bypassed. Not sure it's good either.
|
Meatpack will perform poorly on a binary stream. It's currently good because the alphabet of the data to encode is very small and repetitive. On a (pseudo) random alphabet, it'll escape almost all its code and instead, will consume twice the binary space (if I understand the encoding algorithm correctly) And if it's not switched off, then it'll break on |
binary file transfer uses heatshrink for stream compression. The version of Binary File Transfer in Marlin at the moment just uses the line_buffer as a working buffer rather than allocate its own memory, it is completely independent in general. I'm still working on the finished version, but with all these serial changes I'm not sure how to integrate at the correct point anymore. |
I would like to welcome our new Grep's overlord! 😉 |
I think we missed a sanity check for enabling |
When Scott frenetic commits slows down, I'll add the check. My initial attempt was not logical since it relied on user not removing the #ifdef stuff. |
diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h
index 400ed51d93..186be664e5 100644
--- a/Marlin/src/inc/SanityCheck.h
+++ b/Marlin/src/inc/SanityCheck.h
@@ -3346,6 +3346,9 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
#elif NONE(MEATPACK_ON_SERIAL_PORT_1, MEATPACK_ON_SERIAL_PORT_2)
#error "MEATPACK is now enabled with MEATPACK_ON_SERIAL_PORT_1, MEATPACK_ON_SERIAL_PORT_2, etc."
#endif
+ #if ENABLED(MEATPACK_ON_SERIAL_PORT_2) && !DISABLED(SERIAL_PORT_2)
+ #error "MEATPACK_ON_SERIAL_PORT_2 is only valid when SERIAL_PORT_2 is defined"
+ #endif
#endif
/** Like this ? |
When there's lots of activity throwing new commits in the way, I find that instead of fetch-and-merge (adding yet another ugly merge commit) this tends to avoid conflict, or at least minimizes it. Undo commit… Stash … Fetch … Pull … Restore Stash … Commit … Push. If the push fails, wait a few seconds and… Undo commit… Stash … Fetch … Pull … Restore Stash … Commit … Push. |
I was joking. You're committing very fast, I can't keep up. So I'm monitoring the commit time and when it's old enough, I'm retrying... I'm rebasing, it works better than fetch & merge in that case, unless you've updated the same part of code as I did. It's a single command ( |
Note that |
As mentioned on #21010, this works well on: CR-6 SE, with BTT SKR CR6 board (USB software serial + BTT TFT via hardware serial). |
Thanks for sticking through and getting this solved. Hopefully this brings us closer to stability and a higher confidence in the next release. The codebase deserves a lot of refactoring, but for now it's all about patching existing issues. I'll go through issues over the coming days and compile a list of the problems that need the most attention. |
@thinkyhead If there is anything I can do, I'm happy to. Core serial buffering protocol handling might be a bit out of my league, but I'm happy to look into other things. |
This is working great, as expected. Just as a follow up as i am home and able to test now. |
* bugfix-2.0.x: (248 commits) [cron] Bump distribution date (2021-03-11) Fix password menu stickiness before first auth (MarlinFirmware#21295) Lerdge-K TMC 2208/9 UART pins (MarlinFirmware#21299) Fix LERDGE 'extends' env references (MarlinFirmware#21305) Fix TouchMI stow in G34 (MarlinFirmware#21291) Fix MeatPack with per-serial-port instances (MarlinFirmware#21306) Tricked-out declaration Update MEATPACK test Number serial from 1 to match settings Clean up spaces and words Fix serial index types Add binary file transfer test fix meat pack internal buffer for multi serial [cron] Bump distribution date (2021-03-10) Fix LPC + TMC boot loop (MarlinFirmware#21298) Distinguish serial index from mask (MarlinFirmware#21287) Host Keepalive followup (MarlinFirmware#21290) [cron] Bump distribution date (2021-03-09) CUSTOM_USER_BUTTONS followup (MarlinFirmware#21284) Fix Host Keepalive serial target (MarlinFirmware#21283) ... # Conflicts: # Marlin/Configuration.h # Marlin/Configuration_adv.h
Description
I made a mistake in my previous implementation. I had encapsulated Meatpack over the multiserial class.
This causes mix up and issues in meatpack's internal decoding state between serial ports when both are used.
This implementation attach meatpack to each serial port individually (in fact, it allows to enable meatpack per serial port instead of globally).
Since each serial port will have its own instance of Meatpack's internal decoding state, it's not possible anymore that one port breaks the other. Also, it's now possible to disable Meatpack on the TFT port for example (unlikely to speak Meatpack) while still having the USB port or UART port using Meatpack.
Requirements
It's a generic code. MEATPACK must be enabled to have any effect.
Benefits
See above
Configurations
See attached file for the modifications
Related Issues
It's another take at #21301. The idea in #21301 is to cache the meatpack decoding but mess up are still possible when both port sends Meatpack escape code since a single Meatpack's instance is used. I think my approach is more correct, even if has a larger impact on code size.
@rhapsodyv Can you check it and comment, please ?