瀏覽代碼

Free some SRAM by putting some code in flash

Modified the linker script to put code into flash. Created
program_flash.cpp to move code that must be run from SRAM out of
ZuluSCSI_platform.cpp. Now ZuluSCSI_platform.cpp is running from flash.
Also running the following out of flash
- ZuluSCSI_log.cpp
- ZuluSCSI_log_trace.cpp
- ZuluSCSI_settings.cpp
- QuirksCheck.cpp
Morio 1 年之前
父節點
當前提交
c490bd584c

+ 0 - 100
lib/ZuluSCSI_platform_RP2040/ZuluSCSI_platform.cpp

@@ -764,107 +764,7 @@ uint8_t platform_get_buttons()
     return buttons_debounced;
 }
 
-/*****************************************/
-/* Flash reprogramming from bootloader   */
-/*****************************************/
-
-#ifdef PLATFORM_BOOTLOADER_SIZE
-
-extern uint32_t __real_vectors_start;
-extern uint32_t __StackTop;
-static volatile void *g_bootloader_exit_req;
-
-__attribute__((section(".time_critical.platform_rewrite_flash_page")))
-bool platform_rewrite_flash_page(uint32_t offset, uint8_t buffer[PLATFORM_FLASH_PAGE_SIZE])
-{
-    if (offset == PLATFORM_BOOTLOADER_SIZE)
-    {
-        if (buffer[3] != 0x20 || buffer[7] != 0x10)
-        {
-            logmsg("Invalid firmware file, starts with: ", bytearray(buffer, 16));
-            return false;
-        }
-    }
-
-
-#ifdef __MBED__
-    if (NVIC_GetEnableIRQ(USBCTRL_IRQn))
-    {
-        logmsg("Disabling USB during firmware flashing");
-        NVIC_DisableIRQ(USBCTRL_IRQn);
-        usb_hw->main_ctrl = 0;
-    }
-#endif // __MBED__
-
-    dbgmsg("Writing flash at offset ", offset, " data ", bytearray(buffer, 4));
-    assert(offset % PLATFORM_FLASH_PAGE_SIZE == 0);
-    assert(offset >= PLATFORM_BOOTLOADER_SIZE);
-
-    // Avoid any mbed timer interrupts triggering during the flashing.
-    __disable_irq();
-
-    // For some reason any code executed after flashing crashes
-    // unless we disable the XIP cache.
-    // Not sure why this happens, as flash_range_program() is flushing
-    // the cache correctly.
-    // The cache is now enabled from bootloader start until it starts
-    // flashing, and again after reset to main firmware.
-    xip_ctrl_hw->ctrl = 0;
-
-    flash_range_erase(offset, PLATFORM_FLASH_PAGE_SIZE);
-    flash_range_program(offset, buffer, PLATFORM_FLASH_PAGE_SIZE);
-
-    uint32_t *buf32 = (uint32_t*)buffer;
-    uint32_t num_words = PLATFORM_FLASH_PAGE_SIZE / 4;
-    for (int i = 0; i < num_words; i++)
-    {
-        uint32_t expected = buf32[i];
-        uint32_t actual = *(volatile uint32_t*)(XIP_NOCACHE_BASE + offset + i * 4);
-
-        if (actual != expected)
-        {
-            logmsg("Flash verify failed at offset ", offset + i * 4, " got ", actual, " expected ", expected);
-            __enable_irq();
-            return false;
-        }
-    }
-
-    __enable_irq();
-
-    return true;
-}
-
-void platform_boot_to_main_firmware()
-{
-    // To ensure that the system state is reset properly, we perform
-    // a SYSRESETREQ and jump straight from the reset vector to main application.
-    g_bootloader_exit_req = &g_bootloader_exit_req;
-    SCB->AIRCR = 0x05FA0004;
-    while(1);
-}
-
-void btldr_reset_handler()
-{
-    uint32_t* application_base = &__real_vectors_start;
-    if (g_bootloader_exit_req == &g_bootloader_exit_req)
-    {
-        // Boot to main application
-        application_base = (uint32_t*)(XIP_BASE + PLATFORM_BOOTLOADER_SIZE);
-    }
-
-    SCB->VTOR = (uint32_t)application_base;
-    __asm__(
-        "msr msp, %0\n\t"
-        "bx %1" : : "r" (application_base[0]),
-                    "r" (application_base[1]) : "memory");
-}
-
-// Replace the reset handler when building the bootloader
-// The rp2040_btldr.ld places real vector table at an offset.
-__attribute__((section(".btldr_vectors")))
-const void * btldr_vectors[2] = {&__StackTop, (void*)&btldr_reset_handler};
 
-#endif // PLATFORM_BOOTLOADER_SIZE
 
 /************************************/
 /* ROM drive in extra flash space   */

+ 142 - 0
lib/ZuluSCSI_platform_RP2040/program_flash.cpp

@@ -0,0 +1,142 @@
+/** 
+ * ZuluSCSI™ - Copyright (c) 2022 Rabbit Hole Computing™
+ * 
+ * ZuluSCSI™ firmware is licensed under the GPL version 3 or any later version. 
+ * 
+ * https://www.gnu.org/licenses/gpl-3.0.html
+ * ----
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version. 
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details. 
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+**/
+
+/**
+ * This has been removed from ZuluSCSI_platform.cpp so this code can be
+ * placed in SRAM while ZuluSCSI_platform.cpp.o can be placed in flash
+*/
+
+#include "ZuluSCSI_platform.h"
+#include "ZuluSCSI_log.h"
+#include <hardware/flash.h>
+#include <hardware/structs/xip_ctrl.h>
+#include <hardware/structs/usb.h>
+#ifndef __MBED__
+#ifndef PIO_FRAMEWORK_ARDUINO_NO_USB
+# include <SerialUSB.h>
+# include <class/cdc/cdc_device.h>
+#endif
+#else
+# include <USB/PluggableUSBSerial.h>
+#endif // __MBED__
+
+/*****************************************/
+/* Flash reprogramming from bootloader   */
+/*****************************************/
+
+#ifdef PLATFORM_BOOTLOADER_SIZE
+
+extern uint32_t __real_vectors_start;
+extern uint32_t __StackTop;
+static volatile void *g_bootloader_exit_req;
+
+__attribute__((section(".time_critical.platform_rewrite_flash_page")))
+bool platform_rewrite_flash_page(uint32_t offset, uint8_t buffer[PLATFORM_FLASH_PAGE_SIZE])
+{
+    if (offset == PLATFORM_BOOTLOADER_SIZE)
+    {
+        if (buffer[3] != 0x20 || buffer[7] != 0x10)
+        {
+            logmsg("Invalid firmware file, starts with: ", bytearray(buffer, 16));
+            return false;
+        }
+    }
+
+
+#ifdef __MBED__
+    if (NVIC_GetEnableIRQ(USBCTRL_IRQn))
+    {
+        logmsg("Disabling USB during firmware flashing");
+        NVIC_DisableIRQ(USBCTRL_IRQn);
+        usb_hw->main_ctrl = 0;
+    }
+#endif // __MBED__
+
+    dbgmsg("Writing flash at offset ", offset, " data ", bytearray(buffer, 4));
+    assert(offset % PLATFORM_FLASH_PAGE_SIZE == 0);
+    assert(offset >= PLATFORM_BOOTLOADER_SIZE);
+
+    // Avoid any mbed timer interrupts triggering during the flashing.
+    __disable_irq();
+
+    // For some reason any code executed after flashing crashes
+    // unless we disable the XIP cache.
+    // Not sure why this happens, as flash_range_program() is flushing
+    // the cache correctly.
+    // The cache is now enabled from bootloader start until it starts
+    // flashing, and again after reset to main firmware.
+    xip_ctrl_hw->ctrl = 0;
+
+    flash_range_erase(offset, PLATFORM_FLASH_PAGE_SIZE);
+    flash_range_program(offset, buffer, PLATFORM_FLASH_PAGE_SIZE);
+
+    uint32_t *buf32 = (uint32_t*)buffer;
+    uint32_t num_words = PLATFORM_FLASH_PAGE_SIZE / 4;
+    for (int i = 0; i < num_words; i++)
+    {
+        uint32_t expected = buf32[i];
+        uint32_t actual = *(volatile uint32_t*)(XIP_NOCACHE_BASE + offset + i * 4);
+
+        if (actual != expected)
+        {
+            logmsg("Flash verify failed at offset ", offset + i * 4, " got ", actual, " expected ", expected);
+            __enable_irq();
+            return false;
+        }
+    }
+
+    __enable_irq();
+
+    return true;
+}
+
+
+void platform_boot_to_main_firmware()
+{
+    // To ensure that the system state is reset properly, we perform
+    // a SYSRESETREQ and jump straight from the reset vector to main application.
+    g_bootloader_exit_req = &g_bootloader_exit_req;
+    SCB->AIRCR = 0x05FA0004;
+    while(1);
+}
+
+void btldr_reset_handler()
+{
+    uint32_t* application_base = &__real_vectors_start;
+    if (g_bootloader_exit_req == &g_bootloader_exit_req)
+    {
+        // Boot to main application
+        application_base = (uint32_t*)(XIP_BASE + PLATFORM_BOOTLOADER_SIZE);
+    }
+
+    SCB->VTOR = (uint32_t)application_base;
+    __asm__(
+        "msr msp, %0\n\t"
+        "bx %1" : : "r" (application_base[0]),
+                    "r" (application_base[1]) : "memory");
+}
+
+// Replace the reset handler when building the bootloader
+// The rp2040_btldr.ld places real vector table at an offset.
+__attribute__((section(".btldr_vectors")))
+const void * btldr_vectors[2] = {&__StackTop, (void*)&btldr_reset_handler};
+
+#endif // PLATFORM_BOOTLOADER_SIZE

+ 5 - 0
lib/ZuluSCSI_platform_RP2040/rp2040-daynaport.ld

@@ -73,6 +73,11 @@ SECTIONS
         /* Put only non-timecritical code in flash
          * This includes e.g. floating point math routines.
          */
+        .pio/build/ZuluSCSI_Pico_DaynaPORT/src/ZuluSCSI_log.cpp.o(.text .text*)
+        .pio/build/ZuluSCSI_Pico_DaynaPORT/src/ZuluSCSI_log_trace.cpp.o(.text .text*)
+        .pio/build/ZuluSCSI_Pico_DaynaPORT/src/ZuluSCSI_settings.cpp.o(.text .text*)
+        .pio/build/ZuluSCSI_Pico_DaynaPORT/src/QuirksCheck.cpp.o(.text .text*)
+        *libZuluSCSI_platform_RP2040.a:ZuluSCSI_platform.cpp.o(.text .text*)
         *libm*:(.text .text*)
         *libc*:(.text .text*)
         *libgcc*:*df*(.text .text*)

+ 6 - 1
lib/ZuluSCSI_platform_RP2040/rp2040.ld

@@ -73,6 +73,11 @@ SECTIONS
         /* Put only non-timecritical code in flash
          * This includes e.g. floating point math routines.
          */
+        .pio/build/ZuluSCSI_RP2040/src/ZuluSCSI_log.cpp.o(.text .text*)
+        .pio/build/ZuluSCSI_RP2040/src/ZuluSCSI_log_trace.cpp.o(.text .text*)
+        .pio/build/ZuluSCSI_RP2040/src/ZuluSCSI_settings.cpp.o(.text .text*)
+        .pio/build/ZuluSCSI_RP2040/src/QuirksCheck.cpp.o(.text .text*)
+        *libZuluSCSI_platform_RP2040.a:ZuluSCSI_platform.cpp.o(.text .text*)
         *libm*:(.text .text*)
         *libc*:(.text .text*)
         *libgcc*:*df*(.text .text*)
@@ -86,6 +91,7 @@ SECTIONS
         *libc*:*printf*(.text .text*)
         *libc*:*toa*(.text .text*)
         *libminIni.a:(.text .text*)
+        *libCUEParser.a:(.text .text*)
 
         /* RP2040 breakpoints in RAM code don't always work very well
          * because the boot routine tends to overwrite them.
@@ -132,7 +138,6 @@ SECTIONS
         . = ALIGN(4);
         *(.text)
         *(.text*)
-
         . = ALIGN(4);
         *(.data*)
         . = ALIGN(4);

+ 1 - 0
platformio.ini

@@ -112,6 +112,7 @@ build_flags =
     -DHAS_SDIO_CLASS
     -DUSE_ARDUINO=1
     -DZULUSCSI_V2_0
+    -Wl,-Map=${BUILD_DIR}/${PROGNAME}.map
 
 ; ZuluSCSI RP2040 hardware platform, as above, but with audio output support enabled
 [env:ZuluSCSI_RP2040_Audio]

+ 1 - 1
src/ZuluSCSI_config.h

@@ -28,7 +28,7 @@
 #include <ZuluSCSI_platform.h>
 
 // Use variables for version number
-#define FW_VER_NUM      "24.03.08"
+#define FW_VER_NUM      "24.03.12"
 #define FW_VER_SUFFIX   "dev"
 #define ZULU_FW_VERSION FW_VER_NUM "-" FW_VER_SUFFIX