mirror of
https://github.com/grblHAL/core.git
synced 2026-02-05 08:34:01 +08:00
Workaround for POS (Power on self-test) failure messages(s) not output on "native" USB connect.
Fixed handling of NVS buffer allocation, size was not increased as expected when physical NVS is capable of holding more than 2 Kbytes. This could lead to POS failure or plugins not initializing when a large tool table is configured.
This commit is contained in:
19
changelog.md
19
changelog.md
@@ -1,5 +1,24 @@
|
||||
## grblHAL changelog
|
||||
|
||||
<a name="20251023">Build 20251023
|
||||
|
||||
Core:
|
||||
|
||||
* Workaround for POS (Power on self-test) failure messages(s) not output on "native" USB connect.
|
||||
|
||||
* Fixed handling of NVS buffer allocation, size was not increased as expected when physical NVS is capable of holding more than 2 Kbytes.
|
||||
This could lead to POS failure or plugins not initializing when a large tool table is configured.
|
||||
|
||||
Drivers:
|
||||
|
||||
* Simulator: fix for double free bug, ref. issue [#17](https://github.com/grblHAL/Simulator/issues/17) and block reporting not working.
|
||||
|
||||
Plugins:
|
||||
|
||||
* SD card, macros: fix for lost parameter context when tool change commands that executes macros is run from `G65` macros.
|
||||
|
||||
---
|
||||
|
||||
<a name="20251020">20251020
|
||||
|
||||
Core:
|
||||
|
||||
2
grbl.h
2
grbl.h
@@ -42,7 +42,7 @@
|
||||
#else
|
||||
#define GRBL_VERSION "1.1f"
|
||||
#endif
|
||||
#define GRBL_BUILD 20251022
|
||||
#define GRBL_BUILD 20251023
|
||||
|
||||
#define GRBL_URL "https://github.com/grblHAL"
|
||||
|
||||
|
||||
102
grbllib.c
102
grbllib.c
@@ -105,6 +105,27 @@ __attribute__((weak)) void board_ports_init (void)
|
||||
// NOOP
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void task_free (core_task_t *task)
|
||||
{
|
||||
task->fn = NULL;
|
||||
task->next = NULL;
|
||||
if(last_freed == NULL)
|
||||
last_freed = task;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline core_task_t *task_run (core_task_t *task)
|
||||
{
|
||||
core_task_t *t = task;
|
||||
foreground_task_ptr fn = task->fn;
|
||||
void *data = task->data;
|
||||
|
||||
task = task->next;
|
||||
task_free(t);
|
||||
fn(data);
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
void dummy_bool_handler (bool arg)
|
||||
{
|
||||
// NOOP
|
||||
@@ -190,6 +211,20 @@ static void onLinestateChanged (serial_linestate_t state)
|
||||
on_linestate_changed(state);
|
||||
}
|
||||
|
||||
static void print_pos_msg (void *data)
|
||||
{
|
||||
hal.stream.write("grblHAL: power on self-test (POS) failed!" ASCII_EOL);
|
||||
|
||||
if(on_booted) do {
|
||||
} while((on_booted = task_run(on_booted)));
|
||||
}
|
||||
|
||||
static void onPosFailure (serial_linestate_t state)
|
||||
{
|
||||
if(state.dtr) // delay a bit to let the USB stack come up
|
||||
task_add_delayed(print_pos_msg, NULL, 50);
|
||||
}
|
||||
|
||||
static bool onProbeToolsetter (tool_data_t *tool, coord_data_t *position, bool at_g59_3, bool on)
|
||||
{
|
||||
bool ok = false;
|
||||
@@ -269,10 +304,6 @@ int grbl_enter (void)
|
||||
|
||||
limits_init();
|
||||
|
||||
#if NVSDATA_BUFFER_ENABLE
|
||||
nvs_buffer_alloc(); // Allocate memory block for NVS buffer
|
||||
#endif
|
||||
|
||||
settings_clear();
|
||||
report_init_fns();
|
||||
|
||||
@@ -282,6 +313,10 @@ int grbl_enter (void)
|
||||
|
||||
driver.init = driver_init();
|
||||
|
||||
#if NVSDATA_BUFFER_ENABLE
|
||||
nvs_buffer_alloc(); // Allocate memory block for NVS buffer
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGOUT
|
||||
debug_stream_init();
|
||||
#endif
|
||||
@@ -501,27 +536,6 @@ __attribute__((always_inline)) static inline core_task_t *task_alloc (void)
|
||||
return task;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void task_free (core_task_t *task)
|
||||
{
|
||||
task->fn = NULL;
|
||||
task->next = NULL;
|
||||
if(last_freed == NULL)
|
||||
last_freed = task;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline core_task_t *task_run (core_task_t *task)
|
||||
{
|
||||
core_task_t *t = task;
|
||||
foreground_task_ptr fn = task->fn;
|
||||
void *data = task->data;
|
||||
|
||||
task = task->next;
|
||||
task_free(t);
|
||||
fn(data);
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
static void task_execute (sys_state_t state)
|
||||
{
|
||||
static uint32_t last_ms = 0;
|
||||
@@ -752,9 +766,41 @@ ISR_CODE bool ISR_FUNC(task_run_on_startup)(foreground_task_ptr fn, void *data)
|
||||
// for core use only, called once from protocol.c on cold start
|
||||
void task_execute_on_startup (void)
|
||||
{
|
||||
if(on_booted) do {
|
||||
if(!sys.driver_started) {
|
||||
|
||||
// Clear task queues except startup warnings.
|
||||
|
||||
core_task_t *task, *prev = NULL;
|
||||
|
||||
if((task = on_booted)) do {
|
||||
if(!(task->fn == report_warning)) {
|
||||
if(prev)
|
||||
prev->next = task->next;
|
||||
else {
|
||||
prev = NULL;
|
||||
on_booted = task->next;
|
||||
}
|
||||
task_free(task);
|
||||
} else
|
||||
prev = task;
|
||||
} while((task = prev ? prev->next : on_booted));
|
||||
|
||||
while(next_task)
|
||||
task_delete(next_task->fn, NULL);
|
||||
|
||||
while(systick_task)
|
||||
task_delete_systick(systick_task->fn, NULL);
|
||||
}
|
||||
|
||||
if(on_booted && (sys.driver_started || !hal.stream.state.linestate_event)) do {
|
||||
} while((on_booted = task_run(on_booted)));
|
||||
|
||||
if(!sys.driver_started)
|
||||
while(true);
|
||||
if(!sys.driver_started) {
|
||||
|
||||
if(hal.stream.state.linestate_event)
|
||||
hal.stream.on_linestate_changed = onPosFailure;
|
||||
|
||||
while(true)
|
||||
grbl.on_execute_realtime(state_get());
|
||||
}
|
||||
}
|
||||
|
||||
7
nvs.h
7
nvs.h
@@ -30,6 +30,13 @@ Minimum 1024 bytes required, more if > 5 axes enabled, space for driver and/or p
|
||||
#define NVS_SIZE 2048
|
||||
#endif
|
||||
|
||||
#ifndef NVS_SIZE_MAX
|
||||
/*! \brief Max size in bytes of the NVS buffer in RAM.
|
||||
Must be >= NVS_SIZE.
|
||||
*/
|
||||
#define NVS_SIZE_MAX 4096 // Limit to 4K for now
|
||||
#endif
|
||||
|
||||
//! Number of bytes used for storing CRC values. Do not change this!
|
||||
#ifndef NVS_CRC_BYTES
|
||||
#define NVS_CRC_BYTES 2
|
||||
|
||||
94
nvs_buffer.c
94
nvs_buffer.c
@@ -37,11 +37,14 @@
|
||||
#include "crc.h"
|
||||
#include "nvs.h"
|
||||
|
||||
static uint8_t *nvsbuffer = NULL;
|
||||
settings_dirty_t settings_dirty;
|
||||
|
||||
static nvs_io_t physical_nvs;
|
||||
static bool dirty;
|
||||
uint32_t nvs_size_max = NVS_SIZE;
|
||||
settings_dirty_t settings_dirty;
|
||||
static struct {
|
||||
uint8_t *addr;
|
||||
uint32_t size;
|
||||
} nvsbuffer = { .size = NVS_SIZE };
|
||||
|
||||
typedef struct {
|
||||
uint16_t addr;
|
||||
@@ -123,17 +126,17 @@ static const emap_t target[] = {
|
||||
{0, 0, 0} // list termination - do not remove
|
||||
};
|
||||
|
||||
inline static uint8_t ram_get_byte (uint32_t addr)
|
||||
inline static uint8_t ram_get_byte (uint32_t offset)
|
||||
{
|
||||
return nvsbuffer[addr];
|
||||
return nvsbuffer.addr[offset];
|
||||
}
|
||||
|
||||
inline static void ram_put_byte (uint32_t addr, uint8_t new_value)
|
||||
inline static void ram_put_byte (uint32_t offset, uint8_t new_value)
|
||||
{
|
||||
if(addr == 0)
|
||||
if(offset == 0)
|
||||
settings_dirty.version = true;
|
||||
dirty = dirty || nvsbuffer[addr] != new_value || addr == 0;
|
||||
nvsbuffer[addr] = new_value;
|
||||
dirty = dirty || nvsbuffer.addr[offset] != new_value || offset == 0;
|
||||
nvsbuffer.addr[offset] = new_value;
|
||||
}
|
||||
|
||||
static nvs_transfer_result_t memcpy_to_ram (uint32_t destination, uint8_t *source, uint32_t size, bool with_checksum)
|
||||
@@ -208,7 +211,7 @@ static nvs_transfer_result_t memcpy_from_ram (uint8_t *destination, uint32_t sou
|
||||
if(hal.nvs.driver_area.address && source > hal.nvs.driver_area.address + hal.nvs.driver_area.size)
|
||||
return physical_nvs.memcpy_from_nvs(destination, source, size, with_checksum);
|
||||
|
||||
uint16_t checksum = with_checksum ? calc_checksum(&nvsbuffer[source], size) : 0;
|
||||
uint16_t checksum = with_checksum ? calc_checksum(&nvsbuffer.addr[source], size) : 0;
|
||||
|
||||
for(; size > 0; size--)
|
||||
*(destination++) = ram_get_byte(source++);
|
||||
@@ -223,29 +226,23 @@ static nvs_transfer_result_t memcpy_from_ram (uint8_t *destination, uint32_t sou
|
||||
// Try to allocate RAM from heap for buffer/emulation.
|
||||
bool nvs_buffer_alloc (void)
|
||||
{
|
||||
static uint32_t nvs_size = NVS_SIZE;
|
||||
if(nvsbuffer.addr == NULL) {
|
||||
|
||||
if(hal.nvs.size_max > nvs_size) {
|
||||
nvs_size_max = min(4096, hal.nvs.size_max); // Limit to 4K for now
|
||||
if(nvsbuffer)
|
||||
free(nvsbuffer);
|
||||
if(hal.nvs.size_max > NVS_SIZE)
|
||||
nvsbuffer.size = min(NVS_SIZE_MAX, hal.nvs.size_max);
|
||||
|
||||
if(nvsbuffer.size >= GRBL_NVS_SIZE && (nvsbuffer.addr = malloc(nvsbuffer.size)))
|
||||
memset(nvsbuffer.addr, 0xFF, nvsbuffer.size);
|
||||
}
|
||||
|
||||
assert(nvs_size_max >= GRBL_NVS_SIZE);
|
||||
|
||||
if((nvsbuffer = malloc(nvs_size_max))) {
|
||||
nvs_size = nvs_size_max;
|
||||
memset(nvsbuffer, 0xFF, nvs_size_max);
|
||||
}
|
||||
|
||||
return nvsbuffer != NULL;
|
||||
return nvsbuffer.addr != NULL;
|
||||
}
|
||||
|
||||
void nvs_buffer_free (void)
|
||||
{
|
||||
if(nvsbuffer) {
|
||||
if(nvsbuffer.addr) {
|
||||
nvs_buffer_sync_physical();
|
||||
free(nvsbuffer);
|
||||
free(nvsbuffer.addr);
|
||||
}
|
||||
}
|
||||
//
|
||||
@@ -255,15 +252,15 @@ bool nvs_buffer_init (void)
|
||||
{
|
||||
hal.nvs.size = ((hal.nvs.size - 1) | 0x03) + 1; // Ensure NVS area ends on a word boundary
|
||||
|
||||
if(nvsbuffer) {
|
||||
if(nvsbuffer.addr) {
|
||||
|
||||
memcpy(&physical_nvs, &hal.nvs, sizeof(nvs_io_t)); // save pointers to physical storage handler functions
|
||||
|
||||
// Copy physical storage content to RAM when available
|
||||
if(physical_nvs.type == NVS_Flash)
|
||||
physical_nvs.memcpy_from_flash(nvsbuffer);
|
||||
physical_nvs.memcpy_from_flash(nvsbuffer.addr);
|
||||
else if(physical_nvs.type != NVS_None)
|
||||
physical_nvs.memcpy_from_nvs(nvsbuffer, 0, GRBL_NVS_SIZE + hal.nvs.driver_area.size, false);
|
||||
physical_nvs.memcpy_from_nvs(nvsbuffer.addr, 0, GRBL_NVS_SIZE + hal.nvs.driver_area.size, false);
|
||||
|
||||
// Switch hal to use RAM version of non-volatile storage data
|
||||
hal.nvs.type = NVS_Emulated;
|
||||
@@ -279,9 +276,9 @@ bool nvs_buffer_init (void)
|
||||
if(physical_nvs.type == NVS_None || ram_get_byte(0) != SETTINGS_VERSION) {
|
||||
settings_restore(settings_all);
|
||||
if(physical_nvs.type == NVS_Flash)
|
||||
physical_nvs.memcpy_to_flash(nvsbuffer);
|
||||
physical_nvs.memcpy_to_flash(nvsbuffer.addr);
|
||||
else if(physical_nvs.memcpy_to_nvs)
|
||||
physical_nvs.memcpy_to_nvs(0, nvsbuffer, GRBL_NVS_SIZE + hal.nvs.driver_area.size, false);
|
||||
physical_nvs.memcpy_to_nvs(0, nvsbuffer.addr, GRBL_NVS_SIZE + hal.nvs.driver_area.size, false);
|
||||
if(physical_nvs.type != NVS_None)
|
||||
grbl.report.status_message(Status_SettingReadFail);
|
||||
}
|
||||
@@ -291,7 +288,7 @@ bool nvs_buffer_init (void)
|
||||
// Clear settings dirty flags
|
||||
memset(&settings_dirty, 0, sizeof(settings_dirty_t));
|
||||
|
||||
return nvsbuffer != NULL;
|
||||
return nvsbuffer.addr != NULL;
|
||||
}
|
||||
|
||||
// Allocate NVS block for driver settings.
|
||||
@@ -300,22 +297,23 @@ nvs_address_t nvs_alloc (size_t size)
|
||||
{
|
||||
static uint8_t *mem_address;
|
||||
|
||||
uint8_t *start_address;
|
||||
nvs_address_t addr = 0;
|
||||
|
||||
// Check if already switched to emulation or buffer allocation failed, return NULL if so.
|
||||
if(hal.nvs.type == NVS_Emulated || nvsbuffer == NULL)
|
||||
if(hal.nvs.type == NVS_Emulated || (nvsbuffer.addr == NULL && !nvs_buffer_alloc()))
|
||||
return 0;
|
||||
|
||||
if(hal.nvs.driver_area.address == 0) {
|
||||
hal.nvs.driver_area.address = GRBL_NVS_SIZE;
|
||||
hal.nvs.driver_area.mem_address = mem_address = nvsbuffer + GRBL_NVS_SIZE;
|
||||
hal.nvs.driver_area.mem_address = mem_address = nvsbuffer.addr + hal.nvs.driver_area.address;
|
||||
}
|
||||
|
||||
size += NVS_CRC_BYTES; // add room for checksum.
|
||||
if(hal.nvs.driver_area.size + size < (nvs_size_max - GRBL_NVS_SIZE)) {
|
||||
mem_address = (uint8_t *)((uintptr_t)(mem_address - 1) | 0x03) + 1; // Align to word boundary
|
||||
addr = mem_address - nvsbuffer;
|
||||
mem_address += size;
|
||||
start_address = (uint8_t *)((uintptr_t)(mem_address - 1) | 0x03) + 1; // Align to word boundary
|
||||
if(start_address + size < nvsbuffer.addr + nvsbuffer.size) {
|
||||
addr = start_address - nvsbuffer.addr;
|
||||
mem_address = start_address + size;
|
||||
hal.nvs.driver_area.size = mem_address - hal.nvs.driver_area.mem_address;
|
||||
hal.nvs.size = GRBL_NVS_SIZE + hal.nvs.driver_area.size + 1;
|
||||
}
|
||||
@@ -332,13 +330,13 @@ void nvs_buffer_sync_physical (void)
|
||||
if(physical_nvs.memcpy_to_nvs) {
|
||||
|
||||
if(settings_dirty.version)
|
||||
settings_dirty.version = physical_nvs.memcpy_to_nvs(0, nvsbuffer, 1, false) != NVS_TransferResult_OK;
|
||||
settings_dirty.version = physical_nvs.memcpy_to_nvs(0, nvsbuffer.addr, 1, false) != NVS_TransferResult_OK;
|
||||
|
||||
if(settings_dirty.global_settings)
|
||||
settings_dirty.global_settings = physical_nvs.memcpy_to_nvs(NVS_ADDR_GLOBAL, (uint8_t *)(nvsbuffer + NVS_ADDR_GLOBAL), sizeof(settings_t) + NVS_CRC_BYTES, false) != NVS_TransferResult_OK;
|
||||
settings_dirty.global_settings = physical_nvs.memcpy_to_nvs(NVS_ADDR_GLOBAL, (uint8_t *)(nvsbuffer.addr + NVS_ADDR_GLOBAL), sizeof(settings_t) + NVS_CRC_BYTES, false) != NVS_TransferResult_OK;
|
||||
|
||||
if(settings_dirty.build_info)
|
||||
settings_dirty.build_info = physical_nvs.memcpy_to_nvs(NVS_ADDR_BUILD_INFO, (uint8_t *)(nvsbuffer + NVS_ADDR_BUILD_INFO), sizeof(stored_line_t) + NVS_CRC_BYTES, false) != NVS_TransferResult_OK;
|
||||
settings_dirty.build_info = physical_nvs.memcpy_to_nvs(NVS_ADDR_BUILD_INFO, (uint8_t *)(nvsbuffer.addr + NVS_ADDR_BUILD_INFO), sizeof(stored_line_t) + NVS_CRC_BYTES, false) != NVS_TransferResult_OK;
|
||||
|
||||
uint_fast8_t idx = N_STARTUP_LINE, offset;
|
||||
if(settings_dirty.startup_lines) do {
|
||||
@@ -346,7 +344,7 @@ void nvs_buffer_sync_physical (void)
|
||||
if(bit_istrue(settings_dirty.startup_lines, bit(idx))) {
|
||||
bit_false(settings_dirty.startup_lines, bit(idx));
|
||||
offset = NVS_ADDR_STARTUP_BLOCK + idx * (sizeof(stored_line_t) + NVS_CRC_BYTES);
|
||||
if(physical_nvs.memcpy_to_nvs(offset, (uint8_t *)(nvsbuffer + offset), sizeof(stored_line_t) + NVS_CRC_BYTES, false) == NVS_TransferResult_OK)
|
||||
if(physical_nvs.memcpy_to_nvs(offset, (uint8_t *)(nvsbuffer.addr + offset), sizeof(stored_line_t) + NVS_CRC_BYTES, false) == NVS_TransferResult_OK)
|
||||
bit_false(settings_dirty.startup_lines, bit(idx));
|
||||
}
|
||||
} while(idx);
|
||||
@@ -355,14 +353,14 @@ void nvs_buffer_sync_physical (void)
|
||||
if(settings_dirty.coord_data) do {
|
||||
if(bit_istrue(settings_dirty.coord_data, bit(idx))) {
|
||||
offset = NVS_ADDR_PARAMETERS + idx * (sizeof(coord_data_t) + NVS_CRC_BYTES);
|
||||
if(physical_nvs.memcpy_to_nvs(offset, (uint8_t *)(nvsbuffer + offset), sizeof(coord_data_t) + NVS_CRC_BYTES, false) == NVS_TransferResult_OK)
|
||||
if(physical_nvs.memcpy_to_nvs(offset, (uint8_t *)(nvsbuffer.addr + offset), sizeof(coord_data_t) + NVS_CRC_BYTES, false) == NVS_TransferResult_OK)
|
||||
bit_false(settings_dirty.coord_data, bit(idx));
|
||||
}
|
||||
} while(idx--);
|
||||
|
||||
if(settings_dirty.driver_settings) {
|
||||
if(hal.nvs.driver_area.size > 0)
|
||||
settings_dirty.driver_settings = physical_nvs.memcpy_to_nvs(hal.nvs.driver_area.address, (uint8_t *)(nvsbuffer + hal.nvs.driver_area.address), hal.nvs.driver_area.size, false) != NVS_TransferResult_OK;
|
||||
settings_dirty.driver_settings = physical_nvs.memcpy_to_nvs(hal.nvs.driver_area.address, (uint8_t *)(nvsbuffer.addr + hal.nvs.driver_area.address), hal.nvs.driver_area.size, false) != NVS_TransferResult_OK;
|
||||
else
|
||||
settings_dirty.driver_settings = false;
|
||||
}
|
||||
@@ -373,7 +371,7 @@ void nvs_buffer_sync_physical (void)
|
||||
idx--;
|
||||
if(bit_istrue(settings_dirty.tool_data, bit(idx))) {
|
||||
offset = NVS_ADDR_TOOL_TABLE + idx * (sizeof(tool_data_t) + NVS_CRC_BYTES);
|
||||
if(physical_nvs.memcpy_to_nvs(offset, (uint8_t *)(nvsbuffer + offset), sizeof(tool_data_t) + NVS_CRC_BYTES, false) == NVS_TransferResult_OK)
|
||||
if(physical_nvs.memcpy_to_nvs(offset, (uint8_t *)(nvsbuffer.addr + offset), sizeof(tool_data_t) + NVS_CRC_BYTES, false) == NVS_TransferResult_OK)
|
||||
bit_false(settings_dirty.tool_data, bit(idx));
|
||||
}
|
||||
} while(idx);
|
||||
@@ -390,7 +388,7 @@ void nvs_buffer_sync_physical (void)
|
||||
} else if(physical_nvs.memcpy_to_flash) {
|
||||
uint_fast8_t retries = 4;
|
||||
do {
|
||||
if(physical_nvs.memcpy_to_flash(nvsbuffer))
|
||||
if(physical_nvs.memcpy_to_flash(nvsbuffer.addr))
|
||||
retries = 0;
|
||||
else if(--retries == 0)
|
||||
report_message("Settings write failed!", Message_Warning);
|
||||
@@ -425,7 +423,7 @@ void nvs_memmap (void)
|
||||
strcpy(buf, "Parameters: ");
|
||||
strcat(buf, uitoa(NVS_ADDR_PARAMETERS));
|
||||
strcat(buf, " ");
|
||||
strcat(buf, uitoa(N_CoordinateSystems * (sizeof(coord_data_t) + NVS_CRC_BYTES)));
|
||||
strcat(buf, uitoa(NVS_SIZE_PARAMETERS));
|
||||
strcat(buf, " ");
|
||||
strcat(buf, uitoa(NVS_ADDR_PARAMETERS + N_CoordinateSystems * (sizeof(coord_data_t) + NVS_CRC_BYTES)));
|
||||
report_message(buf, Message_Plain);
|
||||
@@ -433,7 +431,7 @@ void nvs_memmap (void)
|
||||
strcpy(buf, "Startup block: ");
|
||||
strcat(buf, uitoa(NVS_ADDR_STARTUP_BLOCK));
|
||||
strcat(buf, " ");
|
||||
strcat(buf, uitoa(N_STARTUP_LINE * (sizeof(stored_line_t) + NVS_CRC_BYTES)));
|
||||
strcat(buf, uitoa(NVS_SIZE_STARTUP_BLOCK));
|
||||
strcat(buf, " ");
|
||||
strcat(buf, uitoa(NVS_ADDR_STARTUP_BLOCK + N_STARTUP_LINE * (sizeof(stored_line_t) + NVS_CRC_BYTES)));
|
||||
report_message(buf, Message_Plain);
|
||||
@@ -441,7 +439,7 @@ void nvs_memmap (void)
|
||||
strcpy(buf, "Build info: ");
|
||||
strcat(buf, uitoa(NVS_ADDR_BUILD_INFO));
|
||||
strcat(buf, " ");
|
||||
strcat(buf, uitoa(sizeof(stored_line_t) + NVS_CRC_BYTES));
|
||||
strcat(buf, uitoa(NVS_SIZE_BUILD_INFO));
|
||||
strcat(buf, " ");
|
||||
strcat(buf, uitoa(NVS_ADDR_BUILD_INFO + sizeof(stored_line_t) + NVS_CRC_BYTES));
|
||||
report_message(buf, Message_Plain);
|
||||
|
||||
@@ -288,6 +288,13 @@ plan_block_t *plan_get_current_block (void)
|
||||
}
|
||||
|
||||
|
||||
// Returns address of the last block added, if available. Called by the grblHAL simulator.
|
||||
plan_block_t *plan_get_recent_block (void)
|
||||
{
|
||||
return block_buffer_head == block_buffer_tail ? NULL : block_buffer_head->prev;
|
||||
}
|
||||
|
||||
|
||||
inline float plan_get_exec_block_exit_speed_sqr (void)
|
||||
{
|
||||
plan_block_t *block = block_buffer_tail->next;
|
||||
|
||||
@@ -170,6 +170,9 @@ plan_block_t *plan_get_system_motion_block (void);
|
||||
// Gets the current block. Returns NULL if buffer empty
|
||||
plan_block_t *plan_get_current_block (void);
|
||||
|
||||
// Gets last added block. Returns NULL if buffer empty
|
||||
plan_block_t *plan_get_recent_block (void);
|
||||
|
||||
// Called by step segment buffer when computing executing block velocity profile.
|
||||
float plan_get_exec_block_exit_speed_sqr (void);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user