Added MCU clock speed, when available, to DRIVER element in $I output. Ref. issue #923.

Improved diagnostics provided by $MODBUSSTATS when communication has been lost.
Fix for regression.
This commit is contained in:
Terje Io
2026-03-18 18:13:42 +01:00
parent 999b309135
commit 8aa81a1c3b
9 changed files with 71 additions and 12 deletions

View File

@@ -1,6 +1,6 @@
## grblHAL ##
Latest build date is 20260314, see the [changelog](changelog.md) for details.
Latest build date is 20260318, see the [changelog](changelog.md) for details.
> [!NOTE]
> A settings reset will be performed on an update of builds prior to 20241208. Backup and restore of settings is recommended.

View File

@@ -1,5 +1,23 @@
## grblHAL changelog
<a name="20260318">Build 20260318
Core:
* Fix for regression.
* Added MCU clock speed, when available, to DRIVER element in `$I` output. Ref. issue [#923](https://github.com/grblHAL/core/issues/923).
* Improved diagnostics provided by `$MODBUSSTATS` when communication has been lost.
Plugins:
* Networking: moved shared string function to core.
* SD card: added file systems mount directory, size and remaining space to `$I` output. Ref. core issue [#923](https://github.com/grblHAL/core/issues/923).
---
<a name="20260314">Build 20260314
Core:

2
grbl.h
View File

@@ -42,7 +42,7 @@
#else
#define GRBL_VERSION "1.1f"
#endif
#define GRBL_BUILD 20260314
#define GRBL_BUILD 20260318
#define GRBL_URL "https://github.com/grblHAL"

View File

@@ -72,7 +72,6 @@ static int8_t stream_instance = -1;
static uint32_t rx_timeout = 0, silence_until = 0, silence_timeout;
static modbus_exception_t exception_code = ModBus_NoException;
static modbus_silence_timeout_t silence;
static uint32_t latency = 0;
static queue_entry_t queue[MODBUS_QUEUE_LENGTH];
static rtu_settings_t modbus;
static volatile bool spin_lock = false, is_blocking = false, is_up = false;
@@ -81,11 +80,14 @@ static volatile modbus_state_t state = ModBus_Idle;
static uint8_t dir_port = IOPORT_UNASSIGNED;
static struct {
uint32_t rx_count;
uint32_t tx_count;
uint32_t retries;
uint32_t timeouts;
uint32_t crc_errors;
uint32_t rx_exceptions;
uint32_t latency;
bool no_rx;
} stats = {};
static driver_reset_ptr driver_reset;
@@ -203,7 +205,8 @@ static void modbus_poll (void *data)
char *buf = (char *)((queue_entry_t *)packet)->msg.adu;
uint16_t rx_len = packet->msg.rx_length; // store original length for CRC check
latency = max(latency, modbus.rx_timeout - rx_timeout);
stats.rx_count++;
stats.latency = max(stats.latency, modbus.rx_timeout - rx_timeout);
do {
*buf++ = stream.read();
@@ -240,6 +243,7 @@ static void modbus_poll (void *data)
case ModBus_TimeoutException:
if(packet->async)
state = ModBus_Silent;
stats.no_rx = stream.get_rx_buffer_count() == 0;
silence_until = hal.get_elapsed_ticks() + silence_timeout;
break;
@@ -288,7 +292,8 @@ static bool modbus_send_rtu (modbus_message_t *msg, const modbus_callbacks_t *ca
case ModBus_TimeoutException:
if(packet->callbacks.on_rx_timeout)
packet->callbacks.on_rx_timeout(ModBus_Timeout, packet->msg.context);
is_blocking = packet->callbacks.retries > 0;
if(!(is_blocking = packet->callbacks.retries > 0))
stats.no_rx = stream.get_rx_buffer_count() == 0;
break;
case ModBus_Exception:
@@ -452,7 +457,7 @@ FLASHMEM static void onReportOptions (bool newopt)
on_report_options(newopt);
if(!newopt)
report_plugin("MODBUS", "0.22");
report_plugin("MODBUS", "0.23");
}
static bool modbus_rtu_isup (void)
@@ -536,13 +541,15 @@ FLASHMEM static status_code_t report_stats (sys_state_t state, char *args)
{
char buf[110];
snprintf(buf, sizeof(buf) - 1, "TX: " UINT32FMT ", retries: " UINT32FMT ", timeouts: " UINT32FMT ", RX exceptions: " UINT32FMT ", CRC errors: " UINT32FMT ", latency: " UINT32FMT,
stats.tx_count, stats.retries, stats.timeouts, stats.rx_exceptions, stats.crc_errors, latency);
if(stats.no_rx)
report_message(stats.rx_count ? "Unstable connection to modbus device?" : "No connection to modbus device?", Message_Warning);
snprintf(buf, sizeof(buf) - 1, "TX: " UINT32FMT ", retries: " UINT32FMT ", timeouts: " UINT32FMT ", RX exceptions: " UINT32FMT ", CRC errors: " UINT32FMT ", latency: " UINT32FMT,
stats.tx_count, stats.retries, stats.timeouts, stats.rx_exceptions, stats.crc_errors, stats.latency);
report_message(buf, Message_Info);
if(args && (*args == 'r' || *args == 'R'))
stats.tx_count = stats.retries = stats.timeouts = stats.rx_exceptions = stats.crc_errors = latency = 0;
memset(&stats, 0, sizeof(stats));
return Status_OK;
}

View File

@@ -1095,6 +1095,11 @@ FLASHMEM void report_build_info (char *line, bool extended)
if(hal.info) {
hal.stream.write("[DRIVER:");
hal.stream.write(hal.info);
if(hal.f_mcu) {
hal.stream.write("@");
hal.stream.write(uitoa(hal.f_mcu));
hal.stream.write("MHz");
}
hal.stream.write("]" ASCII_EOL);
}
@@ -2946,7 +2951,7 @@ ISR_CODE void report_add_realtime (report_tracking_t report)
case Report_CycleStart:
if(!settings.status_report.pin_state)
return;
return;
break;
default:
break;

View File

@@ -201,6 +201,7 @@ ISR_CODE sys_state_t ISR_FUNC(state_get)(void)
return sys_state;
}
// NOTE: keep STATE_HAS_SUBSTATE in sync if this code is expanded to cover new states
uint8_t state_get_substate (void)
{
uint8_t substate = 0;

View File

@@ -3,7 +3,7 @@
Part of grblHAL
Copyright (c) 2019-2024 Terje Io
Copyright (c) 2019-2026 Terje Io
grblHAL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -335,3 +335,25 @@ FLASHMEM char *strtointernetdt (struct tm *dt)
#endif
}
FLASHMEM char *btoa (uint64_t bytes)
{
static char buf[16];
uint_fast8_t n = 0;
uint64_t size = bytes;
while(size > 1024) {
size >>= 10;
n++;
}
strcpy(buf, ftoa((float)bytes / (float)(1ULL << 10 * n), n ? 2 : 0));
if(n == 0) // remove trailing decimal point...
buf[strlen(buf) - 1] = '\0';
strcat(buf, n == 0 ? " B" : n == 1 ? " KB" : n == 2 ? " MB" : " GB");
return buf;
}

View File

@@ -1,7 +1,7 @@
/*
strutils.h - a collection of useful string utilities
Copyright (c) 2019-2022 Terje Io
Copyright (c) 2019-2026 Terje Io
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -46,5 +46,6 @@ int32_t strlookup (const char *s1, const char *s2, const char delimiter);
bool strtotime (char *s, struct tm *time);
char *strtoisodt (struct tm *dt);
char *strtointernetdt (struct tm *dt);
char *btoa (uint64_t bytes);
#endif

View File

@@ -85,6 +85,11 @@ __NOTE:__ flags are mutually exclusive, bit map allows testing for multiple stat
#define STATE_TOOL_CHANGE bit(9) //!< Manual tool change, similar to #STATE_HOLD - but stops spindle and allows jogging.
///@}
//! \def STATE_HAS_SUBSTATE
/*! @name Bitmask with system states that may have substate(s).
*/
#define STATE_HAS_SUBSTATE (STATE_CYCLE|STATE_HOLD|STATE_ESTOP|STATE_ALARM|STATE_SAFETY_DOOR)
//! \def system_state_t
/*! @name System state enum values.