Changed fseek guard clauses to properly handle error codes

fseek returns non-zero value upon failure, not -1.
Added proper implementation of load skip in load_program to allow skipping a program when it already exists
This commit is contained in:
Lume
2026-04-27 15:09:09 +01:00
committed by GitHub
parent b9eede2cd6
commit 42075b1e39

View File

@@ -63,22 +63,26 @@ bool fs_init(void)
true);
filesystem_t *fat = filesystem_fat_create();
int err = fs_mount("/", fat, sd);
if (err == -1)
{
DEBUG_PRINT("format /\n");
err = fs_format(fat, sd);
if (err == -1)
{
DEBUG_PRINT("format err: %s\n", strerror(errno));
return false;
}
err = fs_mount("/", fat, sd);
if (err == -1)
{
DEBUG_PRINT("mount err: %s\n", strerror(errno));
return false;
}
}
if (err != -1)
{
DEBUG_PRINT("Mounted SD card at /\n");
return true;
}
err = fs_format(fat, sd);
if (err == -1)
{
DEBUG_PRINT("Failed to format SD card\n");
return false;
}
err = fs_mount("/", fat, sd);
if (err == -1)
{
DEBUG_PRINT("Failed to mount SD card at /\n");
return false;
}
DEBUG_PRINT("Mounted SD card at /\n");
return true;
}
@@ -97,6 +101,28 @@ static bool __not_in_flash_func(is_same_existing_program)(FILE *fp)
return true;
}
// Check if a valid application exists in flash by examining the vector table
static bool is_valid_application(uint32_t *app_location)
{
// Check that the initial stack pointer is within a plausible RAM region.
// Assumed range for Pico: 0x20000000 to 0x20040000 + SCRATCH_X + SCRATCH_Y
// Which is the same as the range 0x20000000 to 0x20042000
uint32_t stack_pointer = app_location[0];
if (stack_pointer < 0x20000000 || stack_pointer > MAX_RAM + 2*4*1024) // MAX_RAM + 8KB (4KB per scratch region)
{
return false;
}
// Check that the reset vector is within the valid flash application area
uint32_t reset_vector = app_location[1];
if (reset_vector < (0x10000000 + SD_BOOT_FLASH_OFFSET) || reset_vector > (0x10000000 + PICO_FLASH_SIZE_BYTES))
{
return false;
}
return true;
}
// This function must run from RAM since it erases and programs flash memory
static bool __not_in_flash_func(load_program)(const char *filename)
{
@@ -106,13 +132,9 @@ static bool __not_in_flash_func(load_program)(const char *filename)
DEBUG_PRINT("open %s fail: %s\n", filename, strerror(errno));
return false;
}
if (is_same_existing_program(fp))
{
// Program is up to date
}
// Check file size to ensure it doesn't exceed the available flash space
if (fseek(fp, 0, SEEK_END) == -1)
if (fseek(fp, 0, SEEK_END) != 0)
{
DEBUG_PRINT("seek err: %s\n", strerror(errno));
fclose(fp);
@@ -120,7 +142,7 @@ static bool __not_in_flash_func(load_program)(const char *filename)
}
long file_size = ftell(fp);
if (file_size <= 0)
if (file_size <= 0) // Negative, to include error code -1
{
DEBUG_PRINT("invalid size: %ld\n", file_size);
fclose(fp);
@@ -135,13 +157,21 @@ static bool __not_in_flash_func(load_program)(const char *filename)
}
DEBUG_PRINT("updating: %ld bytes\n", file_size);
if (fseek(fp, 0, SEEK_SET) == -1)
if (fseek(fp, 0, SEEK_SET) != 0)
{
DEBUG_PRINT("seek err: %s\n", strerror(errno));
fclose(fp);
return false;
}
// Only check for validity after the guard clauses to make sure the file pointer (fp) is valid
if ( is_same_existing_program(fp) && is_valid_application((uint32_t*)(XIP_BASE + SD_BOOT_FLASH_OFFSET)) )
{
DEBUG_PRINT("Same program already valid in flash, skipping\n");
fclose(fp);
return true;
}
size_t program_size = 0;
uint8_t buffer[FLASH_SECTOR_SIZE] = {0};
size_t len = 0;
@@ -185,26 +215,6 @@ void __not_in_flash_func(launch_application_from)(uint32_t *app_location)
:);
}
// Check if a valid application exists in flash by examining the vector table
static bool is_valid_application(uint32_t *app_location)
{
// Check that the initial stack pointer is within a plausible RAM region (assumed range for Pico: 0x20000000 to 0x20040000)
uint32_t stack_pointer = app_location[0];
if (stack_pointer < 0x20000000 || stack_pointer > MAX_RAM + 2*4*1024) // MAX_RAM + 8KB
{
return false;
}
// Check that the reset vector is within the valid flash application area
uint32_t reset_vector = app_location[1];
if (reset_vector < (0x10000000 + SD_BOOT_FLASH_OFFSET) || reset_vector > (0x10000000 + PICO_FLASH_SIZE_BYTES))
{
return false;
}
return true;
}
void boot_default()
{
DEBUG_PRINT("entering boot_default\n");