/** * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include #include "pico/stdlib.h" #include "pico/flash.h" #include "hardware/flash.h" // We're going to erase and reprogram a region 256k from the start of flash. // Once done, we can access this at XIP_BASE + 256k. #define FLASH_TARGET_OFFSET (256 * 1024) const uint8_t *flash_target_contents = (const uint8_t *) (XIP_BASE + FLASH_TARGET_OFFSET); void print_buf(const uint8_t *buf, size_t len) { for (size_t i = 0; i < len; ++i) { printf("%02x", buf[i]); if (i % 16 == 15) printf("\n"); else printf(" "); } } // This function will be called when it's safe to call flash_range_erase static void call_flash_range_erase(void *param) { uint32_t offset = (uint32_t)param; flash_range_erase(offset, FLASH_SECTOR_SIZE); } // This function will be called when it's safe to call flash_range_program static void call_flash_range_program(void *param) { uint32_t offset = ((uintptr_t*)param)[0]; const uint8_t *data = (const uint8_t *)((uintptr_t*)param)[1]; flash_range_program(offset, data, FLASH_PAGE_SIZE); } int main() { stdio_init_all(); uint8_t random_data[FLASH_PAGE_SIZE]; for (uint i = 0; i < FLASH_PAGE_SIZE; ++i) random_data[i] = rand() >> 16; printf("Generated random data:\n"); print_buf(random_data, FLASH_PAGE_SIZE); // Note that a whole number of sectors must be erased at a time. printf("\nErasing target region...\n"); // Flash is "execute in place" and so will be in use when any code that is stored in flash runs, e.g. an interrupt handler // or code running on a different core. // Calling flash_range_erase or flash_range_program at the same time as flash is running code would cause a crash. // flash_safe_execute disables interrupts and tries to cooperate with the other core to ensure flash is not in use // See the documentation for flash_safe_execute and its assumptions and limitations int rc = flash_safe_execute(call_flash_range_erase, (void*)FLASH_TARGET_OFFSET, UINT32_MAX); hard_assert(rc == PICO_OK); printf("Done. Read back target region:\n"); print_buf(flash_target_contents, FLASH_PAGE_SIZE); printf("\nProgramming target region...\n"); uintptr_t params[] = { FLASH_TARGET_OFFSET, (uintptr_t)random_data}; rc = flash_safe_execute(call_flash_range_program, params, UINT32_MAX); hard_assert(rc == PICO_OK); printf("Done. Read back target region:\n"); print_buf(flash_target_contents, FLASH_PAGE_SIZE); bool mismatch = false; for (uint i = 0; i < FLASH_PAGE_SIZE; ++i) { if (random_data[i] != flash_target_contents[i]) mismatch = true; } if (mismatch) printf("Programming failed!\n"); else printf("Programming successful!\n"); }