-
Notifications
You must be signed in to change notification settings - Fork 973
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
Simplify Malyan variants #1000
Comments
Oh, I just remembered that F1 cannot actually do remapping, so I suspect that the M200 bootloader which runs on F1, maybe copies the ISR table into the start of flash when uploading the sketch. Are any of these bootloaders open-source, or is it all closed? |
You're close but off just a bit. First, a bit of history and some explanations - I bought one of these printer off of amazon used, loved it, and got frustrated with the software, which is closed source. Instead of doing the sane thing and moving to ANY other board, I ordered a few bluepills off the internet, downloaded ST's 103 programming guide, and decided to reverse engineer the hardware and software. So these files have the remnants of some terrible, terrible hacks in them, but most are needed in some form. Malyan's bootloader is not open source, but if you want to mail me at at dot , I have extracted it (and figured out their stupid scheme that prevents people from replacing the chip when it burns out). The bootloader is the first 8k or so, and it has some peculiarities we're working around in the variants. Now, what about the rest of the ugly hacks? Thus, by repeatedly testing different assertions and seeing if the fan still turned on, I was able to figure out where in the boot sequence things failed. Debuggging via fan. Loading stack pointer - sure seems like something the bootloader would do, right? The bare metal 103 does it, so the bootloader should. It does not, so don't remove that line or once again, you'll break everything. CPI...Here's the only thing I'm moderately ashamed of. Via turnOnFan, I knew we were reaching my ResetHandler. I knew I could take control of the hardware, and I also knew we were crashing into a fault handler during static variable initialization. Thanks to @clearchris's work on Klipper, we now know that what is really going on is that the Malyan bootloader (which runs on their M100, M200, M300, M350 machines) leaves the systick handler running when it starts the firmware, and watches some data in RAM. During init, depending on what gets copied where, it can crash as it acts on data that is NOT what it expects. I had no idea about the systick at the time, but I did know that if I disabled the handlers during init, I could get past it, and once the system was intialized, everything ran fine. So I did, and proceeded to go on with working on Marlin on STM32. It's ok to remove the turnOnFan reference. |
Github ate my attempt to obfuscate the email address, but it's my handle at gmail dot com. |
Thanks for your elaborate reply, that clarifies a lot and gives good boundaries for cleaning up. Kudos for figuring all this stuff out :-) One more question, though: How is an upload triggered? Does the bootloader always wait at startup for a bit, or is there some "update" button to trigger it? Can the sketch also reboot into the bootloader somehow? And if no sketch is uploaded, does the bootloader then also leave systick running or does it do quick jump to the sketch? |
The only way to update firmware (for people without soldering skills) is to update via SD card - the bootloader’s main purpose is to look at the SD card for a file (firmware.bin) and a flag file (fcupdate.flg) and if both are present, firmware.bin will be flashed onto the board. The bootloader also implements an ESP8266 OTA update protocol which it can perform. The sketch can reboot into the bootloader via a fixed address call, and if no sketch is loaded, the bootloader crashes hard.
… On Mar 20, 2020, at 1:34 PM, Matthijs Kooijman ***@***.***> wrote:
Thanks for your elaborate reply, that clarifies a lot and gives good boundaries for cleaning up. Kudos for figuring all this stuff out :-)
One more question, though: How is an upload triggered? Does the bootloader always wait at startup for a bit, or is there some "update" button to trigger it? Can the sketch also reboot into the bootloader somehow? And if no sketch is uploaded, does the bootloader then also leave systick running or does it do quick jump to the sketch?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#1000 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AHVGS4JHIQPR3IABGMG7W5LRIPHN5ANCNFSM4LQKWACA>.
|
So that sounds like the systick is always started, even if no update is performed? IOW, doing another reset and expect the bootloader to start the sketch immediately without enabling systick is not going to work (unless the bootloader maybe skips all its work and directly boots the sketch depending on the reset reason flag, that's what optiboot on AVR does IIRC). |
The systick is always started. In fact, the only time things work the way you’d expect (system is bare/uninitialized) is when a flash update has been performed. Like I said, we could turn off Systick instead of disabling fault/interrupts, but since the current code works, I’ve always had other things to do (like figure out how to get DMA to work in the core).
… On Mar 20, 2020, at 1:48 PM, Matthijs Kooijman ***@***.***> wrote:
So that sounds like the systick is always started, even if no update is performed? IOW, doing another reset and expect the bootloader to start the sketch immediately without enabling systick is not going to work (unless the bootloader maybe skips all its work and directly boots the sketch depending on the reset reason flag, that's what optiboot on AVR does IIRC).
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#1000 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AHVGS4ITLSOSMYKRCSCYOSDRIPJATANCNFSM4LQKWACA>.
|
Yep, I can confirm everything JC has said. 100% correct. |
I thought a bit more on how to generalize this, my thoughts are below (mostly for my own reference, but feedback is welcome of course). SP loadingIt would be nice if the default startup script would just always load SP that. I'm not quite sure why this is done for all families except for F1 now. I checked the latest version (1.8.0) of the F1 firmware package, which also does not include any SP initialization code (but this is the same version as included in this repo, according to 332dde3). I also checked the latest version (1.25.0) of the F4 firmware package, which does still contain the SP load, so it is not something that was global disabled. I think it would be good to use the Interrupt / systick disablingCurrently, interrupts are disabled during memory initialization to prevent the bootloader from interfering. If this just hapens through the systick handler, I think it would be better to disable that, since that just requires running some extra code at the start of the reset handler (no need to re-enable interrupts at the end). Also, I think that with the current code, there might even be a race condition. Interrupts are re-enabled after calling SystemInit, which only resets system clocks and does not touch systick. Then, static constructors are called (through ISR table remapppingThis also needs to be kept, but we could maybe also integrate this remapping into the core and trigger it with a variant define? This remapping should probably also be done earlier: Mx00 now does it in Linker scriptsThe M200 linker script only has an offset in the flash (compared to a cleanly generated script using CubeMX). We could probably unhardcode this and use the The Mx00 linker script additionally defines a VTRAM section for the vector table, that should also be kept (but might also be generalized with the linker override script, if we can somehow figure out how big it should be). |
Is there any update on this ? |
I haven't had time to work on this anymore since my last comment, unfortunately. |
Thanks for the quick answer. I guess I will have to get in mind this issue for #710 |
I had another look at this today, because I have a board that needs ISR table remapping, so I looked at how these variants did that. I haven't done any work here, but I've seen that with #1091 merged, most of the above simplifications (and my previous summary comment #1000 (comment)) are still applicable, except that the flash offset in the linker script is no longer hardcoded but uses |
Today, I noticed some startup customizations in the Malyan M200 and Mx00 variants, of which I wonder if they are really needed. The way they work now, might pose complications for implementing a custom reset handler for #710, so I wonder if these customizations cannot be removed, or generalized.
There's two things here:
Arduino_Core_STM32/variants/MALYANMx00_F070CB/variant.cpp
Lines 101 to 108 in 213a3d5
Looking at the latter, it seems the changes compared to the default scripts are minimal. It seems there used be an "enable fan" command in there, but it is commented out. The actual changes do noot seem so relevant: disabling/enabling interrupts (
cpsid
/cpsie
), some barriers (dsb
/isb
) and a breakpoint (bkpt
) in an unreachable place. The M200 startup actually adds an initialization of the stack pointer (which should not actually be needed, since a reset already does that), but looking at other default startup code all these load the stack pointer, except for all of the F1 startup code. So I doubt any of these changes are intentional, they might just be the result o basing off an older or newer version of the startup scripts.Here's the startup code diffs (with comment and whitespace changes removed):
Looking at the history, relevant PRs are #382, #422 and #354. The last one mentions "the startup assembler must account for some oddities of the bootloader which is already running". It suspect, this means that there is a bootloader in regular flash, which lives in the first 8K, so the linker script is modified to put the sketch after the bootloader. Since the ISR table lives at 0x0, the 0x0 block must be remapped to RAM, and the ISR vector table copied there. Finally, because maybe the bootloader neglects to initialize the SP (as the hardware normally does), the reset handler must do this.
@xC0000005, can you confirm or shed more light here? In particular, how much of this applies to which variant? It seems Mx00 remaps memory and copies the ISR table, but M200 does not (but it does leave 8K of memory free?). Is the bootloader different and does that maybe handle remapping already?
The text was updated successfully, but these errors were encountered: