I have an application written in C that uses both cores and stores its configuration in the top sector of flash. Core 1 which is looking after the attached hardware communicates with the main program running on core 0 using the inter-core FIFOs and associated interrupts. This application has run successfully for several years on the RP2040 based Pico 1.
I am in the throes of porting the application to the RP2350 based Pico 2 and have run into a couple of problems, one of which is a ‘show-stopper’.
I am currently using early ‘A2’ chips and ran into the workaround for the flash partition table (See the data sheet RP2350-E10). This was fixed by moving my configuration data down a sector from the top of flash. The XIP safe code was also changed to use the new flash_safe_execute() routines from SDK 2.1.1
The second problem is the one I need help with here: In the main program, after I have started core 1, I set up the FIFO interrupts using irq_set_exclusive handler() and irq_set_enabled() which unfortunately cause a
*** PANIC ***
Hard Assert
which I don’t seem to be able to get around.
Since the actual application is long and complicated, I have hacked around with a couple of the programs in pico-examples to create a (shortish) program that exhibits all the features. The salient elements are the two #defines, ALLOW_INTERRUPTS and USE_FLASH which switch on the relevant portions of the code. Commenting/un-conmmenting these give the following results:
These results are completely repeatable on an RP2350A0A2 using SDK 2.1.1 on Visual Studio. As this must be a common configuration, it must be me doing something stupid. Can anyone dig me out of this hole please. I include the program code referred to along with the corresponding CMakeLists.txt:
I am in the throes of porting the application to the RP2350 based Pico 2 and have run into a couple of problems, one of which is a ‘show-stopper’.
I am currently using early ‘A2’ chips and ran into the workaround for the flash partition table (See the data sheet RP2350-E10). This was fixed by moving my configuration data down a sector from the top of flash. The XIP safe code was also changed to use the new flash_safe_execute() routines from SDK 2.1.1
The second problem is the one I need help with here: In the main program, after I have started core 1, I set up the FIFO interrupts using irq_set_exclusive handler() and irq_set_enabled() which unfortunately cause a
*** PANIC ***
Hard Assert
which I don’t seem to be able to get around.
Since the actual application is long and complicated, I have hacked around with a couple of the programs in pico-examples to create a (shortish) program that exhibits all the features. The salient elements are the two #defines, ALLOW_INTERRUPTS and USE_FLASH which switch on the relevant portions of the code. Commenting/un-conmmenting these give the following results:
Code:
ALLOW_INTERRUPTS USE_FLASH Result Off Off Silly Off On Works and programs flash On Off Doesn’t crash but doesn’t program flash On On PANIC Hard AssertCode:
/** * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: BSD-3-Clause *///#define ALLOW_INTERRUPTS 1#define USE_FLASH 1#include <stdio.h>#include <stdlib.h>#include "pico/stdlib.h"#include "pico/flash.h"#include "pico/multicore.h"#include "hardware/flash.h"void core1_main(){ printf("Core 1 starting\n"); multicore_fifo_clear_irq(); // Do we need this? #ifdef USE_FLASH // Let the system know that this core is willing to be a 'victim' // of blocking whilst the flash is being written. if(!flash_safe_execute_core_init()) { printf("flash_safe_execute_core_init() FAILED\n"); }#endif while(1);}// We're going to erase and reprogram a region 2 sectore from the end of flash.#define FLASH_TARGET_OFFSET (PICO_FLASH_SIZE_BYTES - ((FLASH_SECTOR_SIZE) * 2))const uint8_t *flash_target_contents = (const uint8_t *) (XIP_BASE + FLASH_TARGET_OFFSET);// This function will be called when it's safe to call flash_range_erasestatic 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_programstatic 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);}void core0_sio_irq(){ multicore_fifo_clear_irq(); //Never actually going to happen}int main() { stdio_init_all(); sleep_ms(500); uint8_t random_data[FLASH_PAGE_SIZE]; for (uint i = 0; i < FLASH_PAGE_SIZE; ++i) random_data[i] = rand() >> 16;printf("Starting core 1\n"); multicore_launch_core1(core1_main);#ifdef ALLOW_INTERRUPTS irq_set_exclusive_handler(SIO_FIFO_IRQ_NUM(0), core0_sio_irq); irq_set_enabled(SIO_FIFO_IRQ_NUM(0), true);#endif#ifdef USE_FLASH sleep_ms(800); // Let core1 register as a victim printf("Calling erase\n"); int rc = flash_safe_execute(call_flash_range_erase, (void*)FLASH_TARGET_OFFSET, UINT32_MAX); if(rc != PICO_OK) { printf("flash_safe_execute (Erase) returned %d\n", rc); while(1) ; } 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("\nProgramming successful\n");#else printf("Still alive\n");#endif while(1) ;}Code:
# Generated Cmake Pico project filecmake_minimum_required(VERSION 3.13)set(CMAKE_C_STANDARD 11)set(CMAKE_CXX_STANDARD 17)set(CMAKE_EXPORT_COMPILE_COMMANDS ON)# Initialise pico_sdk from installed location# (note this can come from environment, CMake cache etc)# == DO NOT EDIT THE FOLLOWING LINES for the Raspberry Pi Pico VS Code Extension to work ==if(WIN32) set(USERHOME $ENV{USERPROFILE})else() set(USERHOME $ENV{HOME})endif()set(sdkVersion 2.1.1)set(toolchainVersion 14_2_Rel1)set(picotoolVersion 2.1.1)set(picoVscode ${USERHOME}/.pico-sdk/cmake/pico-vscode.cmake)if (EXISTS ${picoVscode}) include(${picoVscode})endif()# ====================================================================================set(PICO_BOARD pico2 CACHE STRING "Board type")# Pull in Raspberry Pi Pico SDK (must be before project)include(pico_sdk_import.cmake)project(new_flash C CXX ASM)# Initialise the Raspberry Pi Pico SDKpico_sdk_init()# Add executable. Default name is the project name, version 0.1add_executable(new_flash new_flash.c )pico_set_program_name(new_flash "new_flash")pico_set_program_version(new_flash "0.1")# Modify the below lines to enable/disable output over UART/USBpico_enable_stdio_uart(new_flash 1)pico_enable_stdio_usb(new_flash 0)# Add the standard library to the buildtarget_link_libraries(new_flash pico_stdlib pico_multicore hardware_flash)# Add the standard include files to the buildtarget_include_directories(new_flash PRIVATE ${CMAKE_CURRENT_LIST_DIR})pico_add_extra_outputs(new_flash)Statistics: Posted by JohnCLB — Sun Jun 08, 2025 11:21 pm — Replies 2 — Views 46