From a1fdfa56f562f4b666162849b6552519cc217a22 Mon Sep 17 00:00:00 2001 From: Roxy-3D Date: Mon, 21 May 2018 16:07:59 -0500 Subject: [PATCH] Marlin on RTOS --- Marlin/src/Marlin.cpp | 49 +++++++++- Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp | 2 + Marlin/src/module/planner.h | 2 +- README.md | 102 +++++++++++++------- 4 files changed, 116 insertions(+), 39 deletions(-) diff --git a/Marlin/src/Marlin.cpp b/Marlin/src/Marlin.cpp index e7d4a37fe3..f067bce082 100644 --- a/Marlin/src/Marlin.cpp +++ b/Marlin/src/Marlin.cpp @@ -29,6 +29,9 @@ */ #include "Marlin.h" +#include +#include +#include #include "lcd/ultralcd.h" #include "module/motion.h" @@ -649,6 +652,9 @@ void stop() { } } +TaskFunction_t Marlin_main_loop(); +TaskFunction_t Marlin_idle(); + /** * Marlin entry-point: Set up before the program loop * - Set up the kill pin, filament runout, power hold @@ -668,6 +674,8 @@ void stop() { * • status LEDs */ void setup() { + unsigned short ss; + char *ptr; #ifdef HAL_INIT HAL_init(); @@ -677,6 +685,24 @@ void setup() { max7219.init(); #endif + ptr = (char *) malloc(75); // reserve some memory for the RTOS to use later. It will be given + // back after the Marlin-loop task is started. + + xTaskCreate((TaskFunction_t) Marlin_idle, "Marlin_idle", 450 /* Stack size */, NULL, 4 /* priority */, NULL ); + + // Keep trying to start the Marlin_main_loop task until it succeeds. The Marlin_main_loop + // task needs to be the very last task started because we try to give it as much memory as possible. + // (it may make sense to reduce the 150 bytes of RTOS memory reservered up above!!! But for now, + // that gives developers some flexibility and debug capabilities.) + + for (ss = 10000; ss > 300; ss -= 100) + if (pdPASS == xTaskCreate((TaskFunction_t) Marlin_main_loop, "Marlin_loop", ss /* Stack size */, NULL, 5 /* priority */, NULL)) + break; + + if (ss < 350) for (;;); // Die if Marlin_main_loop didn't get enough memory. + + free(ptr); // give back the memory we reserved for generic RTOS usage + #if ENABLED(DISABLE_JTAG) // Disable JTAG on AT90USB chips to free up pins for IO MCUCR = 0x80; @@ -756,7 +782,14 @@ void setup() { // Load data from EEPROM if available (or use defaults) // This also updates variables in the planner, elsewhere - (void)settings.load(); + +//(void)settings.load(); // For some unknow reason, the EEPROM settings can not be loaded in the setup() + // function. It acts like some flavor of a data corruption problem. The + // setup() routine finishes doing all its work, but the other tasks never start + // running. We need to figure out why this is!!!! + // + // In the mean time... settings.load() is run at the start of the Marlin_main_loop() + // task. This approach seems to work around what ever the problem is. #if HAS_M206_COMMAND // Initialize current position based on home_offset @@ -919,7 +952,18 @@ void setup() { * - Call endstop manager * - Call inactivity manager */ -void loop() { +TaskFunction_t Marlin_main_loop() { + + // Load data from EEPROM if available (or use defaults) + // This also updates variables in the planner, elsewhere + + (void)settings.load(); // For some unknow reason, the EEPROM settings can not be loaded in the setup() + // function. It acts like some flavor of a data corruption problem. The + // setup() routine finishes doing all its work, but the other tasks never start + // running. We need to figure out why this is!!!! + // + // In the mean time... settings.load() is run at the start of the Marlin_main_loop() + // task. This approach seems to work around what ever the problem is. for (;;) { @@ -953,5 +997,6 @@ void loop() { advance_command_queue(); endstops.event_handler(); idle(); + vTaskDelay(1); } } diff --git a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp index 671ed79947..8f5bc95d76 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp @@ -46,6 +46,8 @@ #include "../../../module/tool_change.h" #endif + #include + #include #define UBL_G29_P31 diff --git a/Marlin/src/module/planner.h b/Marlin/src/module/planner.h index 8a639a0431..c4baa5d790 100644 --- a/Marlin/src/module/planner.h +++ b/Marlin/src/module/planner.h @@ -430,7 +430,7 @@ class Planner { FORCE_INLINE static void apply_leveling(float (&raw)[XYZ]) { apply_leveling(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); } #endif - #if PLANNER_LEVELING + #if PLANNER_LEVELING || HAS_UBL_AND_CURVES #define ARG_X float rx #define ARG_Y float ry #define ARG_Z float rz diff --git a/README.md b/README.md index c1267a1ba6..89cb9d32cb 100644 --- a/README.md +++ b/README.md @@ -8,66 +8,96 @@ Additional documentation can be found at the [Marlin Home Page](http://marlinfw.org/). Please test this firmware and let us know if it misbehaves in any way. Volunteers are standing by! -## Marlin 2.0 Bugfix Branch +## Marlin 2.1 Bugfix Branch __Not for production use. Use with caution!__ -Marlin 2.0 takes this popular RepRap firmware to the next level with support for much faster 32-bit processor boards. +Marlin 2.1 is an attempt to place a Real Time Operating System (RTOS) under Marlin 2.0. The goal is to support the same build environments and targets as the Marlin 2.0 branch. The goal is also to exactly duplicate the Marlin 2.0 functionality. This branch is not currently stable. It is only suitable for use by developers interested in the RTOS effort. The Marlin 2.1 branch will not be updated each time Marlin 2.0 is changed. It will be rebased against the Marlin 2.0 branch on an "as needed" basis. -This branch is for patches to the latest 2.0.x release version. Periodically this branch will form the basis for the next minor 2.0.x release. +The changes to place an RTOS under the Marlin code base are very minor. -Download earlier versions of Marlin on the [Releases page](https://github.com/MarlinFirmware/Marlin/releases). +It is helpful to have a Max7219 8x8 LED matrix on the machine for debug purposes. It is helpful because the various tasks that are running update the LED's so you can see what is happening. I strongly encourage everybody to spend the $2.00 to get one of these devices: https://www.ebay.com/itm/MAX7219-Dot-Matrix-8x8-Led-Display-Module-MCU-Control-For-Arduino-Innovation/222709799381?epid=1672606113&hash=item33da89d9d5:g:QmgAAOSwbw1aATcc -## Building Marlin 2.0 -To build Marlin 2.0 you'll need [Arduino IDE 1.9](https://www.arduino.cc/en/main/software) or [PlatformIO](http://docs.platformio.org/en/latest/ide.html#platformio-ide). We've posted detailed instructions on how to [build Marlin 2.0 for ARM](http://marlinfw.org/docs/basics/install_arm.html). +## Building Marlin 2.1 -## Hardware Abstraction Layer (HAL) +Currently, the Marlin 2.1 branch can only build code for the 8-bit AVR processors. It is a priority to get the build process also supporting the 32-bit platforms. -Marlin 2.0 adds a new abstraction layer so that Marlin can build and run on 32-bit boards while still retaining full 8-bit AVR compatibility. In this way, features can be enhanced for more powerful platforms while still supporting AVR, whereas splitting up the code would make it harder to maintain and keep everything in sync. +To build Marlin 2.1 for the 8-bit AVR processors, you'll need [Arduino IDE 1.9](https://www.arduino.cc/en/main/software) These steps will get Arduino configured to build Marlin 2.1 with FreeRTOS under it (for the AVR processors): -### Current HALs +1. Install FreeRTOS for Arduino + - Bring up Arduino + - Sketch / Include_Library / Manage_Libraries + - Set Type=Contributed + - Set Topic=Timing + - Scroll to FreeRTOS by Richard Barry. Real Time Operating System implemented for AVR + - Select version 10,0,0-10 and press Install + - Modified FreeRTOS files are in a .ZIP file alongside the Marlin source files. Copy supplied (and altered) FreeRTOS files to ???\Arduino\libraries\FreeRTOS\src Specifically: (FreeRTOSConfig.h, Arduino_FreeRTOS.h, variantHooks.cpp). These files can be found in an archive ../Marlin/src/FreeRTOS-changes.zip + - Configure your Marlin files in the Marlin directory + - Having a Max7219 LED Matrix is helpful... Debug info is displayed on + the device. - name|processor|speed|flash|sram|logic|fpu - ----|---------|-----|-----|----|-----|--- - [Arduino AVR](https://www.arduino.cc/)|ATmega, ATTiny, etc.|16-20MHz|64-256k|2-8k|5V|no - [Teensy++ 2.0](http://www.microchip.com/wwwproducts/en/AT90USB1286)|[AT90USB1286](http://www.microchip.com/wwwproducts/en/AT90USB1286)|16MHz|128k|8k|5V|no - [Due](https://www.arduino.cc/en/Guide/ArduinoDue), [RAMPS-FD](http://www.reprap.org/wiki/RAMPS-FD), etc.|[SAM3X8E ARM-Cortex M3](http://www.microchip.com/wwwproducts/en/ATsam3x8e)|84MHz|512k|64+32k|3.3V|no - [Re-ARM](https://www.kickstarter.com/projects/1245051645/re-arm-for-ramps-simple-32-bit-upgrade)|[LPC1768 ARM-Cortex M3](http://www.nxp.com/products/microcontrollers-and-processors/arm-based-processors-and-mcus/lpc-cortex-m-mcus/lpc1700-cortex-m3/512kb-flash-64kb-sram-ethernet-usb-lqfp100-package:LPC1768FBD100)|100MHz|512k|32+16+16k|3.3-5V|no - [MKS SBASE](http://forums.reprap.org/read.php?13,499322)|LPC1768 ARM-Cortex M3|100MHz|512k|32+16+16k|3.3-5V|no - [Azteeg X5 GT](https://www.panucatt.com/azteeg_X5_GT_reprap_3d_printer_controller_p/ax5gt.htm)|LPC1769 ARM-Cortex M3|120MHz|512k|32+16+16k|3.3-5V|no - [Selena Compact](https://github.com/Ales2-k/Selena)|LPC1768 ARM-Cortex M3|100MHz|512k|32+16+16k|3.3-5V|no - [Teensy 3.5](https://www.pjrc.com/store/teensy35.html)|ARM-Cortex M4|120MHz|512k|192k|3.3-5V|yes - [Teensy 3.6](https://www.pjrc.com/store/teensy36.html)|ARM-Cortex M4|180MHz|1M|256k|3.3V|yes +Changes: + - The Marlin idle() function is its own task now. It is slightly lower priority than the main Marlin task. Instead of being called periodically, the main Marlin task can suspend itself and the former idle() task can continue its work from where it left off. What this means is idle() no longer needs to run to completion and return to its caller. Instead, it is allowed to run an appropriate amount of time, and it gets cut off so the main Marlin task can get other work done. Admitably, this initial use of the RTOS is not very sophisticated. But it does demonstrate that the surgery to activate the RTOS is in place and working. + - A few changes have been made to the default FreeRTOS configuration. And these configuration options exposed a bug in the Arduino version of FreeRTOS (in variantHooks.cpp). And it was done with very minor changes to the Marlin code so it is a good first step. + - An M101 RTOS Free Task Memory Status routine has been added. + - The Max7219 runs as a task with a message queue. Probably, this is a waste of memory, but it serves a good purpose right now just to show FreeRTOS is doing its thing. + -### HALs in Development +To Do: + - We need the Arduino_FreeRTOS.h, FreeRTOSConfig.h and variantHooks.cpp files to only exist in one place. We need the FreeRTOS library to be configured appropriately for Marlin and not with the default settings. - name|processor|speed|flash|sram|logic|fpu - ----|---------|-----|-----|----|-----|--- - [STEVAL-3DP001V1](http://www.st.com/en/evaluation-tools/steval-3dp001v1.html)|[STM32F401VE Arm-Cortex M4](http://www.st.com/en/microcontrollers/stm32f401ve.html)|84MHz|512k|64+32k|3.3-5V|yes - [Smoothieboard](http://reprap.org/wiki/Smoothieboard)|LPC1769 ARM-Cortex M3|120MHz|512k|64k|3.3-5V|no + - We need to figure out why the settings.load() function can not be called + from setup() any more. It seems to cause some random memory corruption. + I've spent some time looking at this, and so far have not found the + answer. But... with that said... if settings.load() is moved to the + top of the Marlin_main_loop() task, it is able to go through the entire + routine (with no logic changes in configuration_store.cpp). PLEASE!!!! + If you can figure this out, please do!!! + + - Implement the previous concept of no_stepper_sleep for advanced pause in + the Marlin idle routine. This used to be a parameter passed into idle() + but this function is now run as a task. + + void idle( + //#if ENABLED(ADVANCED_PAUSE_FEATURE) + // bool no_stepper_sleep/*=false*/ + //#endif ) + + - Variables that are modified within the scope of idle() (via calls to things like lcd_update(), host_keepalive(), manage_inactivity(), thermalManager.manage_heater(), print_job_timer.tick(), buzzer.tick() ) need to be checked for atomic access. We can't have the new idle routine context + switch in the middle of a variable update. + + - The thermal code seems to be able to control the bed and hot end + temperatures. But I've seen a lot of Thermal Shutdown Kill's. I have + not searched for the root cause yet. Instead, I've turned off Thermal + Protection for the time being so I can use the time to make further + progress on RTOS related topics. + + +## Current Functionality + +Marlin 2.1 currently builds for the 8-bit AVR platforms using Arduino. This needs to be expanded to include coverage for the 32-bit platforms and Platform-IO. + +## High Priority Work Items + +- Expand build environment to address 32-bit platforms. + +- Alter build environment to handle inclusion (and configuration) of the FreeRTOS library gracefully. ## Submitting Patches -Proposed patches should be submitted as a Pull Request against the ([bugfix-2.0.x](https://github.com/MarlinFirmware/Marlin/tree/bugfix-2.0.x)) branch. +Proposed patches should be submitted as a Pull Request against the ([bugfix-2.1.x](https://github.com/MarlinFirmware/Marlin/tree/bugfix-2.1.x)) branch. -- This branch is for fixing bugs and integrating any new features for the duration of the Marlin 2.0.x life-cycle. +- This branch is for fixing bugs and integrating any new features for the duration of the Marlin 2.1.x life-cycle. - Follow the [Coding Standards](http://marlinfw.org/docs/development/coding_standards.html) to gain points with the maintainers. - Please submit your questions and concerns to the [Issue Queue](https://github.com/MarlinFirmware/Marlin/issues). ### [RepRap.org Wiki Page](http://reprap.org/wiki/Marlin) -## Credits - -The current Marlin dev team consists of: - - Roxanne Neufeld [[@Roxy-3D](https://github.com/Roxy-3D)] - English - - Scott Lahteine [[@thinkyhead](https://github.com/thinkyhead)] - English - - Bob Kuhn [[@Bob-the-Kuhn](https://github.com/Bob-the-Kuhn)] - English - - Chris Pepper [[@p3p](https://github.com/p3p)] - English - - João Brazio [[@jbrazio](https://github.com/jbrazio)] - Portuguese, English - ## License Marlin is published under the [GPL license](/LICENSE) because we believe in open development. The GPL comes with both rights and obligations. Whether you use Marlin firmware as the driver for your open or closed-source product, you must keep Marlin open, and you must provide your compatible Marlin source code to end users upon request. The most straightforward way to comply with the Marlin license is to make a fork of Marlin on Github, perform your modifications, and direct users to your modified fork. While we can't prevent the use of this code in products (3D printers, CNC, etc.) that are closed source or crippled by a patent, we would prefer that you choose another firmware or, better yet, make your own. + +