mirror of
https://github.com/grblHAL/core.git
synced 2026-03-23 11:32:44 +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:
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);
|
||||
|
||||
Reference in New Issue
Block a user