Compare commits

...
Sign in to create a new pull request.

6 commits

Author SHA1 Message Date
Roxy-3D
3cc3b03a9c
Revive Marlin RTOS work
Restart the experimental branch.
2021-02-25 17:56:35 -07:00
Scott Lahteine
0bdea3f854 Fit task code for updated Max7219 2018-09-10 04:16:25 -05:00
Scott Lahteine
bef6b94b7e Max7219 RTOS changes 2018-09-10 04:14:37 -05:00
Scott Lahteine
05fe47e59a Add M101 command for RTOS 2018-09-10 04:12:01 -05:00
Roxy-3D
a1fdfa56f5 Marlin on RTOS 2018-09-10 04:12:01 -05:00
Scott Lahteine
4e3bad6dce Due HAL tweak 2018-09-10 04:11:42 -05:00
13 changed files with 420 additions and 47 deletions

View file

@ -231,7 +231,7 @@ void HardFault_HandlerC(unsigned long *sp, unsigned long lr, unsigned long cause
// Reset controller
NVIC_SystemReset();
while(1) { WDT_Restart(WDT); }
for (;;) WDT_Restart(WDT);
}
__attribute__((naked)) void NMI_Handler(void) {

View file

@ -29,6 +29,9 @@
*/
#include "Marlin.h"
#include <Arduino_FreeRTOS.h>
#include <task.h>
#include <queue.h>
#include "lcd/ultralcd.h"
#include "module/motion.h"
@ -528,6 +531,13 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) {
}
}
#if ENABLED(MAX7219_DEBUG)
unsigned long int zz = 0, // Temporary - will go away soon - used by loop()
zzz = 0, // Temporary - will go away soon - used by Marlin_idle()
zzzz = 0, // Temporary - will go away soon - used by Marlin_main_loop()
zzzzz = 0; // Temporary - will go away soon - used by idle()
#endif
/**
* Standard idle routine keeps the machine alive
*/
@ -537,7 +547,8 @@ void idle(
#endif
) {
#if ENABLED(MAX7219_DEBUG)
max7219.idle_tasks();
zzzzz++;
max7219.do_command(LED_SET_ROW, 0, 5, uint8_t(zzzzz >> 5));
#endif
lcd_update();
@ -649,6 +660,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 +682,8 @@ void stop() {
* status LEDs
*/
void setup() {
unsigned short ss;
char *ptr;
#ifdef HAL_INIT
HAL_init();
@ -677,6 +693,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 (;;) { /* nada */ } // 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 +790,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,10 +960,32 @@ 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.
#if ENABLED(MAX7219_DEBUG)
max7219.do_command(LED_CLEAR_MATRIX, 0, 0, 0);
#endif
for (;;) {
#if ENABLED(MAX7219_DEBUG)
zzzz++;
max7219.do_command(LED_SET_ROW, 0, 7, uint8_t(zzzz >> 4));
if ((zzzz & 0x20) == 0x20)
max7219.do_command(LED_TOGGLE, 5, 1, 0);
#endif
#if ENABLED(SDSUPPORT)
card.checkautostart();
#endif
@ -953,5 +1016,33 @@ void loop() {
advance_command_queue();
endstops.event_handler();
idle();
vTaskDelay(1);
}
}
TaskFunction_t Marlin_idle() {
for (;;) {
#if ENABLED(MAX7219_DEBUG)
max7219.do_command(LED_SET_ROW, 0, 6, (uint8_t) (zzz++ >> 3));
#endif
vTaskDelay(3);
}
}
/**
* Very low priority, non-blocking logic can be called from loop() This represents
* a small shift from the past. FreeRTOS expects a setup() routine and loop() routine
* within an Arduino environment. loop() is called from the RTOS idle task and is of a
* very low priority. The FreeRTOS idle routine can not be any priority except zero.
*
* A loop() function must be available for FreeRTOS to call. But the main Marlin loop
* logic needs to be at a very high priority. That is the reason for the name shifts.
*/
void loop() {
#if ENABLED(MAX7219_DEBUG)
max7219.led_toggle(7, 0); // max7219.do_command(LED_TOGGLE, 7, 0, 0); // can't be used because loop() is not allowed to block!
#endif
}

View file

@ -48,10 +48,15 @@
#include "../Marlin.h"
#include "../HAL/shared/Delay.h"
#include <Arduino_FreeRTOS.h>
#include <queue.h>
Max7219 max7219;
uint8_t Max7219::led_line[MAX7219_LINES]; // = { 0 };
QueueHandle_t Max7219::queue; // = NULL
#define LINE_REG(Q) (max7219_reg_digit0 + ((Q) & 0x7))
#if _ROT == 0 || _ROT == 270
#define _LED_BIT(Q) (7 - ((Q) & 0x7))
@ -101,6 +106,52 @@ void Max7219::error(const char * const func, const int32_t v1, const int32_t v2/
#endif
}
void Max7219::do_command(uint8_t msg, uint8_t col, uint8_t row, uint32_t val ) {
led_msg_t out_led_msg;
out_led_msg.operation = msg;
out_led_msg.col = col;
out_led_msg.row = row;
out_led_msg.val = val;
while (pdPASS != xQueueSendToBack(queue, &out_led_msg, 100)) { /* nada */ }
}
TaskFunction_t Max7219::command_processor(void *ptr) {
static led_msg_t in_led_msg;
while (queue == NULL) vTaskDelay(50); // wait until the message queue is set up before processing
for (;;) {
while (pdPASS != xQueueReceive(queue, &in_led_msg, 2000)) { /* nada */ }
switch (in_led_msg.operation) {
case LED_NOP: break;
case LED_INIT: max7219.reinit(); break;
case LED_LOAD_REGS: max7219.register_setup(); break;
case LED_ON: max7219.led_on(in_led_msg.col, in_led_msg.row); break;
case LED_OFF: max7219.led_off(in_led_msg.col, in_led_msg.row); break;
case LED_TOGGLE: max7219.led_toggle(in_led_msg.col, in_led_msg.row); break;
case LED_CLEAR_MATRIX: max7219.clear(); break;
case LED_CLEAR_ROW: max7219.clear_row(in_led_msg.row); break;
case LED_CLEAR_COLUMN: max7219.clear_column(in_led_msg.col); break;
case LED_SET_ROW: max7219.set_row(in_led_msg.row, (uint8_t)in_led_msg.val); break;
case LED_SET_2_ROWS: max7219.set_rows_16bits(in_led_msg.row, (uint16_t)in_led_msg.val); break;
case LED_SET_4_ROWS: max7219.set_rows_32bits(in_led_msg.row, in_led_msg.val); break;
case LED_SET_COLUMN: max7219.set_column(in_led_msg.col, (uint8_t)in_led_msg.val); break;
case LED_IDLE_TASK: max7219.idle_tasks(); break;
}
}
}
void Max7219_PutByte(uint8_t data) {
#ifndef CPU_32_BIT
CRITICAL_SECTION_START;
#endif
}
/**
* Flip the lowest n_bytes of the supplied bits:
* flipped(x, 1) flips the low 8 bits of x.
@ -420,7 +471,7 @@ void Max7219::register_setup() {
#endif
#endif // MAX7219_INIT_TEST
void Max7219::init() {
void Max7219::reinit() {
SET_OUTPUT(MAX7219_DIN_PIN);
SET_OUTPUT(MAX7219_CLK_PIN);
OUT_WRITE(MAX7219_LOAD_PIN, HIGH);
@ -451,6 +502,22 @@ void Max7219::init() {
#endif
}
void Max7219::init() {
reinit();
queue = xQueueCreate(3 /* # of queue items */, sizeof(led_msg_t));
if (!queue) {
max7219.set_row(0, 0xE5);
for (;;) { /* nada */ }
}
// Create the Max7219 debug task. It is very low priority in an attempt to not affect the
// normal timing of Marlin. But if too many messages are sent too quickly to the task,
// the command queue will fill up and the sender will block until a message has been drained
// to make room for the next message.
xTaskCreate((TaskFunction_t)max7219.command_processor, "Max7219::LEDs", 200 /* Stack size */, NULL, 2 /* priority */, NULL);
}
/**
* This code demonstrates some simple debugging using a single 8x8 LED Matrix. If your feature could
* benefit from matrix display, add its code here. Very little processing is required, so the 7219 is
@ -510,6 +577,9 @@ void Max7219::quantity16(const uint8_t y, const uint8_t ov, const uint8_t nv) {
}
void Max7219::idle_tasks() {
return; // Temporary!!!
#define MAX7219_USE_HEAD (defined(MAX7219_DEBUG_PLANNER_HEAD) || defined(MAX7219_DEBUG_PLANNER_QUEUE))
#define MAX7219_USE_TAIL (defined(MAX7219_DEBUG_PLANNER_TAIL) || defined(MAX7219_DEBUG_PLANNER_QUEUE))
#if MAX7219_USE_HEAD || MAX7219_USE_TAIL

View file

@ -36,12 +36,14 @@
*
* If you are using the Max7219 matrix for firmware debug purposes in time sensitive
* areas of the code, please be aware that the orientation (rotation) of the display can
* affect the speed. The Max7219 can update a single column fairly fast. It is much
* faster to do a Max7219_Set_Column() with a rotation of 90 or 270 degrees than to do
* a Max7219_Set_Row(). The opposite is true for rotations of 0 or 180 degrees.
* affect the speed. The Max7219 can update a single column fairly fast. It is much
* faster to do a max7219.set_column() with a rotation of 90 or 270 degrees than to do
* a max7219.set_row(). The opposite is true for rotations of 0 or 180 degrees.
*/
#pragma once
#include <task.h>
#ifndef MAX7219_ROTATE
#define MAX7219_ROTATE 0
#endif
@ -83,11 +85,22 @@
class Max7219 {
public:
typedef struct {
uint8_t operation;
uint8_t row, col;
uint32_t val;
} led_msg_t;
static led_msg_t led_msg;
QueueHandle_t queue;
static uint8_t led_line[MAX7219_LINES];
Max7219() { }
static void init();
static void reinit();
static void register_setup();
static void putbyte(uint8_t data);
static void pulse_load();
@ -135,6 +148,10 @@ public:
// Apply custom code to update the matrix
static void idle_tasks();
// RTOS hooks
static void do_command(uint8_t msg, uint8_t row, uint8_t col, uint32_t val);
TaskFunction_t command_processor(void*);
private:
static void error(const char * const func, const int32_t v1, const int32_t v2=-1);
static void noop();
@ -155,3 +172,20 @@ private:
};
extern Max7219 max7219;
#define LED_NOP 0x00
#define LED_LOAD_REGS 0x01
#define LED_REINIT 0x02
#define LED_ON 0x03
#define LED_OFF 0x04
#define LED_TOGGLE 0x05
#define LED_CLEAR_MATRIX 0x06
#define LED_CLEAR_ROW 0x07
#define LED_CLEAR_COLUMN 0x08
#define LED_SET_ROW 0x09
#define LED_SET_2_ROWS 0x0a
#define LED_SET_4_ROWS 0x0b
#define LED_SET_COLUMN 0x0c
#define LED_IDLE_TASK 0x0d
#endif // __MAX7219_DEBUG_LEDS_H__

View file

@ -46,6 +46,8 @@
#include "../../../module/tool_change.h"
#endif
#include <Arduino_FreeRTOS.h>
#include <math.h>
#define UBL_G29_P31

View file

@ -0,0 +1,84 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* M101 Task Free Memory Watcher
*
* This code watches the free memory defined for each task in the FreeRTOS environment
* It is useful to determine how much memory each task has available.
*
* Initial version... More Marlin-specific information to be added.
*/
#include "../../inc/MarlinConfig.h"
#include "../gcode.h"
#include "../../Marlin.h"
#include <Arduino_FreeRTOS.h>
#include "../../libs/hex_print_routines.h"
#define MAX_TASKS 10
void GcodeSuite::M101() {
TaskStatus_t TaskStatArray[MAX_TASKS];
unsigned n_tasks = uxTaskGetNumberOfTasks();
if (n_tasks > MAX_TASKS) {
SERIAL_PROTOCOLLNPAIR("?Too many tasks: ", n_tasks);
SERIAL_EOL();
return;
}
SERIAL_PROTOCOLLNPGM("M101 RTOS Task Info:");
/* Generate raw status information about each task. */
n_tasks = uxTaskGetSystemState( TaskStatArray, MAX_TASKS, NULL);
SERIAL_PROTOCOLLNPAIR("n_tasks: ", n_tasks);
/* For each populated position in the TaskStatArray array,
format the raw data as human readable ASCII data. */
for (unsigned x = 0; x < n_tasks; x++) {
char t_name[configMAX_TASK_NAME_LEN + 1]; // Pad out the task name so everything lines up nicely
strcpy(t_name, TaskStatArray[x].pcTaskName);
while (strlen(t_name) < configMAX_TASK_NAME_LEN)
strcat(t_name, "_");
SERIAL_PROTOCOL(x);
SERIAL_PROTOCOLPAIR(":", t_name);
SERIAL_PROTOCOLPAIR(" Task #: ", TaskStatArray[x].xTaskNumber);
SERIAL_PROTOCOLPAIR(" Current_Priority: ", TaskStatArray[x].uxCurrentPriority);
SERIAL_PROTOCOLPAIR(" Base_Priority: ", TaskStatArray[x].uxBasePriority);
SERIAL_PROTOCOLPGM(" Stack: ");
print_hex_address((const void * const) TaskStatArray[x].pxStackBase);
SERIAL_PROTOCOLPAIR(" Free_Mem: ", (unsigned int) TaskStatArray[x].usStackHighWaterMark);
SERIAL_PROTOCOLPGM(" State: ");
switch( TaskStatArray[x].eCurrentState ) {
case eRunning: SERIAL_PROTOCOLLNPGM("Running"); break;
case eReady: SERIAL_PROTOCOLLNPGM("Ready"); break;
case eBlocked: SERIAL_PROTOCOLLNPGM("Blocked"); break;
case eSuspended: SERIAL_PROTOCOLLNPGM("Suspended"); break;
case eDeleted: SERIAL_PROTOCOLLNPGM("Deleted"); break;
default: SERIAL_PROTOCOLLNPAIR("Corrupted:", TaskStatArray[x].eCurrentState);
break;
}
}
}

View file

@ -0,0 +1,37 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "../../../inc/MarlinConfig.h"
#if ENABLED(MAX7219_DEBUG)
#include "../../gcode.h"
#include "../../../feature/Max7219_Debug_LEDs.h"
/**
* M102: Directly re-initialize Max7219 debug LEDs
*/
void GcodeSuite::M102() {
Max7219_register_setup();
}
#endif // MAX7219_DEBUG

View file

@ -353,6 +353,11 @@ void GcodeSuite::process_parsed_command(
#if ENABLED(M100_FREE_MEMORY_WATCHER)
case 100: M100(); break; // M100: Free Memory Report
#endif
case 101: M101(); break; // M101: RTOS Task Free Memory Report
#if ENABLED(MAX7219_DEBUG)
case 102: M102(); break; // M102: Max7219 register re-initialization (for debugging)
#endif
case 104: M104(); break; // M104: Set hot end temperature
case 109: M109(); break; // M109: Wait for hotend temperature to reach target

View file

@ -114,6 +114,8 @@
* M85 - Set inactivity shutdown timer with parameter S<seconds>. To disable set zero (default)
* M92 - Set planner.axis_steps_per_mm for one or more axes.
* M100 - Watch Free Memory (for debugging) (Requires M100_FREE_MEMORY_WATCHER)
* M101 - RTOS Task Free Memory report (for debugging)
* M102 - Max7219 re-initialization of setup registers (for debugging)
* M104 - Set extruder target temp.
* M105 - Report current temperatures.
* M106 - Set print fan speed.
@ -513,6 +515,12 @@ private:
static void M100();
#endif
static void M101();
#if ENABLED(MAX7219_DEBUG)
static void M102();
#endif
static void M104();
static void M105();
static void M106();

View file

@ -23,7 +23,10 @@
#include "../inc/MarlinConfig.h"
#include "../gcode/parser.h"
#if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(M100_FREE_MEMORY_WATCHER) || ENABLED(DEBUG_GCODE_PARSER)
// Needed for M101 - RTOS Task Report. We can collapse this later, but for now it is nice to
// always have the hex print functions available.
//
//#if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(M100_FREE_MEMORY_WATCHER) || ENABLED(DEBUG_GCODE_PARSER)
#include "hex_print_routines.h"
@ -78,4 +81,4 @@
void print_hex_word(const uint16_t w) { SERIAL_ECHO(hex_word(w)); }
void print_hex_address(const void * const w) { SERIAL_ECHO(hex_address(w)); }
#endif // AUTO_BED_LEVELING_UBL || M100_FREE_MEMORY_WATCHER || DEBUG_GCODE_PARSER
//#endif // AUTO_BED_LEVELING_UBL || M100_FREE_MEMORY_WATCHER || DEBUG_GCODE_PARSER

View file

@ -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

110
README.md
View file

@ -5,69 +5,107 @@
<img align="top" width=175 src="buildroot/share/pixmaps/logo/marlin-250.png" />
## NOTICE:
__This fork of the Marlin code is currently being updated and brought back to life. This is being done with consideration and constraints different than what is described below. The new, updated RTOS version of Marlin is being done for 32-bit boards. But effort is being expended to make it still compile and load on the 8-bit AVR boards (without an RTOS support layer). In other words, the 8-bit AVR boards will not benefit from having an RTOS under Marlin but they will be able to use the same code base. We won't have to fork the code base and maintain two different branches of the code.__
__With that said, the current code that is being worked on is being done so it can be aplied to an arbitrary snapshot of the Marlin v.2.0.x code. This is an experimental branch of the Marlin code but every attempt is being made to not lose any functionality. With that said, we don't want the extra burden of maintaining two branches for an extended period of time like what we went through on the transition from Marlin v1.x to Marlin v2.0. Instead, the work being done here will periodically be updated using a copy of the current Marlin BugFix v2.0.x code base to keep both branches synchronized.__
__Current expectations are that the updated README.md file and code for the branch will be available mid June.__
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
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
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.
- 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.

View file

@ -29,6 +29,7 @@ build_flags = -fmax-errors=5
-g
-ggdb
lib_deps =
FreeRTOS
https://github.com/MarlinFirmware/U8glib-HAL/archive/dev.zip
LiquidCrystal@1.3.4
TMC2130Stepper