RPI Pico \ RP2040 更新可以在运行时执行 flash 吗?

问题描述 投票:0回答:1

所以主要问题是我可以在代码运行时更新程序闪存吗?

我能够通过 TCP 接收新的二进制文件并将其保存到闪存的后半部分。我现在想将其复制到前半部分,以便它在下次重新启动后运行。

我知道如果复制过程中出现任何问题,这种方法存在使电路板变砖的风险,长期方法应该使用 2 阶段引导加载程序或类似的方法,但就目前而言,这是一种快速的方法。

我发现关于是否可以写入正在执行的闪存区域的冲突信息,但我明白,如果执行复制的代码是从 RAM 运行,这应该是可能的。

以下代码尝试执行此操作,但仅写入两个扇区,然后冻结。由于上述原因,这是否是不可能的?

程序的输出是:

已写入 0 个位置(共 1048576 个)

已写入 4096 个位置(共 1048576 个)

编辑:阅读有关在第二个核心中运行代码时停止中断的问题,但已禁用该代码并且结果是相同的。

谢谢

__attribute__((section(".ram_code"))) void copy_flash_to_zero(uint32_t source_address)
{
    uint32_t flash_index = 0;
    uint8_t led_counter=0;
    uint32_t ints;

    uint8_t buffer[FLASH_SECTOR_SIZE]; // Buffer to hold data
    printf("Starting Flash update\n");

    do
    {
        // Read data from the source address in flash into the buffer
        memcpy(buffer, (const void *)(source_address + XIP_BASE + flash_index), FLASH_SECTOR_SIZE);

        // Disable interrupts during flash operations to prevent issues
        ints = save_and_disable_interrupts();
        //  Erase the flash sector at address zero plus bootloades offset (256 bytes)
        flash_range_erase(flash_index, FLASH_SECTOR_SIZE);

        // Write the buffer to flash address zero
        flash_range_program(flash_index, buffer, FLASH_SECTOR_SIZE);
        // Restore interrupts after flash operations
        restore_interrupts(ints);

        printf("position written %u out of %u\n", flash_index, FLASH_SIZE_BYTES / 2);
        fflush(stdout); // Force flush the buffer
        flash_index += FLASH_SECTOR_SIZE;
        led_counter++;
    } while (flash_index < FLASH_SIZE_BYTES / 2);

    printf("Flash update complete. RebootingX\n", source_address, FLASH_ADDRESS_ZERO);
    sleep_ms(2000);
    watchdog_reboot(0, 0, 0);
}

我希望代码能够运行,重置开发板并再次开始运行。但是,“Flash 更新完成”消息永远不会出现,并且开发板无限期挂起。

raspberry-pi-pico rp2040
1个回答
0
投票

这里的问题是,您编写的函数位于 RAM 中,但它调用了许多其他函数(如

memcpy
printf
),这些函数很可能不在 RAM 中,因此当这些函数被覆盖时,您的代码将出现故障。 您还启用了中断,并且中断服务例程可能位于闪存中。

© www.soinside.com 2019 - 2024. All rights reserved.