Skip to content
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

Hardened settings safety #761

Merged
merged 9 commits into from
Oct 10, 2024
11 changes: 11 additions & 0 deletions makefiles/virtual/mcu_virtual.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,17 @@ extern "C"
{
return (uint32_t)(mcu_free_micros() % 1000);
}

/**
*Solve compiler issues
*/

void nvm_start_read(uint16_t address) {}
void nvm_start_write(uint16_t address) {}
uint8_t nvm_getc(uint16_t address) { return mcu_eeprom_getc(address); }
void nvm_putc(uint16_t address, uint8_t c) { mcu_eeprom_putc(address, c); }
void nvm_end_read(void) {}
void nvm_end_write(void) { mcu_eeprom_flush(); }
#ifdef __cplusplus
}
#endif
Expand Down
66 changes: 39 additions & 27 deletions uCNC/cnc_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,6 @@ extern "C"

#define COORD_SYS_COUNT 6

/**
* Uncomment to enable G92 storing on non volatile memory
* If disabled G92 will be stored in RAM only. Soft-reset will not erase stored value.
* */
// #define G92_STORE_NONVOLATILE

/**
* Number of segments of an arc computed with aprox. of sin/cos math
* operation before performing a full calculation
Expand All @@ -111,6 +105,29 @@ extern "C"

// #define ENABLE_PARSING_TIME_DEBUG

/**
* Disable settings safety.
* This is a feature introduced in version 1.11 to prevent user from using the machine in case of settings loading error and causing havoc
* Disabling settings safety will make the settins run in legacy more where they are simply reset to default on error without forcing the user to re-check them
*/

// #define DISABLE_SAFE_SETTINGS

/**
* Uncomment to enable G92 storing on non volatile memory
* If disabled G92 will be stored in RAM only. Soft-reset will not erase stored value.
* */
// #define G92_STORE_NONVOLATILE

/**
* This uses RAM only settings
* Storing is disabled and the defaults will be loaded at each power up
* This is useful if you don't have EEPROM/FLASH storage or the divide read/write maximum cycle count is low to prevent damage
* This is also usefull if the sender provides all settings at startup/connection
* */
// #define RAM_ONLY_SETTINGS


/**
* Override default configuration settings. Use _PER_AXIS parameters to
* define different settings for each axis.
Expand Down Expand Up @@ -559,6 +576,13 @@ extern "C"
*/
// #define ENABLE_IO_ALARM_DEBUG

/**
* Enabled extra pin diagnostic command $P
*/
// #define ENABLE_PIN_DEBUG_EXTRA_CMD
// uncomment o translate pins names when printing pins states with $P command
// #define ENABLE_PIN_TRANSLATIONS

/**
* Modifies the startup message to emulate Grbl (required by some programs so
* that uCNC is recognized a Grbl protocol controller device)
Expand All @@ -577,23 +601,6 @@ extern "C"

#define ENABLE_SYSTEM_INFO

/**
* Enables additional core grbl system commands
* For settings allows settings to only be stored in EEPROM/Flash explicitly
* on special command This makes that all $<setting-id>=<setting-value>
* commands are only performed in SRAM and not stored directly to
* EEPROM/Flash A few commands are added: $SS - Settings store - records
* settings from SRAM to EEPROM/Flash $SL - Settings load - Loads settings
* from EEPROM/Flash to SRAM $SR - Settings reset - Reloads the default value
* settings from ROM to SRAM
*
* For pin diagnostics enables command $P
* */

// #define ENABLE_EXTRA_SYSTEM_CMDS
// uncomment o translate pins names when printing pins states with $P command
// #define ENABLE_PIN_TRANSLATIONS

/**
* Compilation specific options
* */
Expand All @@ -612,11 +619,16 @@ extern "C"
#define CRC_WITHOUT_LOOKUP_TABLE

/**
* This uses RAM only settings
* Storing is disabled and the defaults will be loaded at each power up
* This is useful if you don't have EEPROM/FLASH storage or the divide read/write maximum cycle count is low to prevent damage
* Enable extra settings commands.
* For settings allows settings to only be stored in EEPROM/Flash explicitly
* on special command This makes that all $<setting-id>=<setting-value>
* commands are only performed in SRAM and not stored directly to
* EEPROM/Flash A few commands are added: $SS - Settings store - records
* settings from SRAM to EEPROM/Flash $SL - Settings load - Loads settings
* from EEPROM/Flash to SRAM $SR - Settings reset - Reloads the default value
* settings from ROM to SRAM
* */
// #define RAM_ONLY_SETTINGS
// #define ENABLE_EXTRA_SETTINGS_CMDS

/**
* EXPERIMENTAL! Uncomment to enable fast math macros to reduce the number of
Expand Down
8 changes: 4 additions & 4 deletions uCNC/src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ __NOTE__: Not all event hooks might be listed here. To find all available event
| cnc_stop | NULL | ENABLE_MAIN_LOOP_MODULES | Fires when a halt/stop condition is triggered |
| cnc_parse_cmd_error | NULL | ENABLE_MAIN_LOOP_MODULES | Fires when an invalid command is received |
| cnc_alarm | NULL | ENABLE_MAIN_LOOP_MODULES | Fires when an alarm is triggered |
| settings_change | settings_args_t* | ENABLE_SETTINGS_MODULES | Fires when a $ setting is changed. Arg is a pointer to a settings_args_t struct |
| settings_load | settings_args_t* | ENABLE_SETTINGS_MODULES | Fires when settings are loaded from memory. Arg is a pointer to a settings_args_t struct |
| settings_save | settings_args_t* | ENABLE_SETTINGS_MODULES | Fires when settings are saved into memory. Arg is a pointer to a settings_args_t struct |
| settings_erase | settings_args_t* | ENABLE_SETTINGS_MODULES | Fires when settings are erased/reset. Arg is a pointer to a settings_args_t struct |
| settings_extended_change | setting_args_t* | ENABLE_SETTINGS_MODULES | Fires when a $ setting is changed. Arg is a pointer to a setting_args_t struct identifying the changed setting id and value |
| settings_extended_load | NULL | ENABLE_SETTINGS_MODULES | Fires when the base settings ($) are loaded from memory. Arg is a pointer to a settings_args_t struct |
| settings_extended_save | NULL | ENABLE_SETTINGS_MODULES | Fires when the base settings ($) are saved into memory. Arg is a pointer to a settings_args_t struct |
| settings_extended_erase | NULL | ENABLE_SETTINGS_MODULES | Fires when the base settings are erased/reset ($). This will only be triggered when the base address of the settings is targeted |
| proto_status | NULL | - | Fires when printing the status message |
| proto_cnc_settings | NULL | ENABLE_SETTINGS_MODULES | Fires when printing settings values |
| proto_cnc_info | NULL | ENABLE_SYSTEM_INFO | Fires when printing response to $I command |
Expand Down
32 changes: 26 additions & 6 deletions uCNC/src/cnc.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@
#define LOOP_FAULT 3
#define LOOP_REQUIRE_RESET 4

#define UNLOCK_OK 0
#define UNLOCK_LOCKED 1
#define UNLOCK_ERROR 2

#define RTCMD_NORMAL_MASK (RT_CMD_FEED_100 | RT_CMD_FEED_INC_COARSE | RT_CMD_FEED_DEC_COARSE | RT_CMD_FEED_INC_FINE | RT_CMD_FEED_DEC_FINE)
#define RTCMD_RAPID_MASK (RT_CMD_RAPIDFEED_100 | RT_CMD_RAPIDFEED_OVR1 | RT_CMD_RAPIDFEED_OVR2)
#define RTCMD_SPINDLE_MASK (RT_CMD_SPINDLE_100 | RT_CMD_SPINDLE_INC_COARSE | RT_CMD_SPINDLE_DEC_COARSE | RT_CMD_SPINDLE_INC_FINE | RT_CMD_SPINDLE_DEC_FINE | RT_CMD_SPINDLE_TOGGLE)
Expand Down Expand Up @@ -467,15 +463,31 @@ uint8_t cnc_unlock(bool force)
// forces to clear EXEC_UNHOMED error to allow motion after limit switch trigger
if (force)
{
CLEARFLAG(cnc_state.exec_state, EXEC_UNHOMED);
cnc_state.alarm = EXEC_ALARM_NOALARM;

#ifndef DISABLE_SAFE_SETTINGS
// on settins error prevent unlock until settings error is cleared
if (!(g_settings_error & SETTINGS_READ_ERROR))
{
#endif
CLEARFLAG(cnc_state.exec_state, EXEC_UNHOMED);
cnc_state.alarm = EXEC_ALARM_NOALARM;
#ifndef DISABLE_SAFE_SETTINGS
}
#endif
}

// if any alarm state is still active checks system faults
if (cnc_get_exec_state(EXEC_ALARM) || cnc_has_alarm())
{
if (!cnc_get_exec_state(EXEC_KILL))
{
#ifndef DISABLE_SAFE_SETTINGS
// on settins error prevent unlock until settings error is cleared
if ((g_settings_error & SETTINGS_READ_ERROR))
{
proto_feedback(MSG_FEEDBACK_16);
}
#endif
proto_feedback(MSG_FEEDBACK_2);
return UNLOCK_LOCKED;
}
Expand Down Expand Up @@ -552,6 +564,14 @@ void cnc_clear_exec_state(uint8_t statemask)
CLEARFLAG(statemask, EXEC_UNHOMED);
}

#ifndef DISABLE_SAFE_SETTINGS
// on settins error prevent unlock
if (g_settings_error & SETTINGS_READ_ERROR)
{
CLEARFLAG(statemask, EXEC_UNHOMED);
}
#endif

uint8_t limits = 0;
#if (LIMITS_MASK != 0)
limits = io_get_limits(); // can't clear the EXEC_UNHOMED is any limit is triggered
Expand Down
5 changes: 5 additions & 0 deletions uCNC/src/cnc.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ extern "C"
#define EXEC_GCODE_LOCKED (EXEC_ALARM | EXEC_DOOR | EXEC_JOG) // Gcode is locked by an alarm or any special motion state
#define EXEC_ALLACTIVE 255 // All states

// unlock result codes
#define UNLOCK_OK 0
#define UNLOCK_LOCKED 1
#define UNLOCK_ERROR 2

// creates a set of helper masks used to configure the controller
#define ESTOP_MASK 1
#define SAFETY_DOOR_MASK 2
Expand Down
Loading
Loading