Skip to content

flash_safe_execute returns -4 when both cores are in use #2243

Description

@sykacek

I need to read data from the sensor and write the values into RP2040 internal flash. I thought that good approach would be use one core for handling the flash and the other for handling the sensor. I need to write data periodically (every 4 seconds), but flash_safe_execute returns -4 when executed. In the code below I use core 1 for writing to flash, although results are same when writing to flash from core 0 (I never use both cores for flash operations).

#include "pico/stdlib.h"
#include <stdio.h>

#include "pico/flash.h"
#include "pico/multicore.h"
#include "hardware/flash.h"
#include "hardware/sync.h"

#define LED		(25)

#define NVS_SIZE		(4096)
#define NVS_SECTORS		(446)
#define PAGE_SIZE		(256)
#define PAGE_SECTORS		(NVS_SECTORS * NVS_SIZE / PAGE_SIZE)

#define FLASH_WRITE_START	(0x42000)
#define FLASH_READ_START	(FLASH_WRITE_START + XIP_BASE)

#define FLASH_SECTORS		(256)

volatile int led = 1;
volatile uint32_t offset = FLASH_WRITE_START;
static unsigned char buffer[256] = "hello world from flash! 256";

void __not_in_flash_func(call_write_flash)(void *param){
	puts("call from write");
	(void)(param);

	flash_range_program(offset, buffer, 256);
	offset += 256;
}

void core1_entry(void) {
	/* when uncommented core 1 task crashes */
	//flash_safe_execute_core_init();

	while(1){	
		int val = multicore_fifo_pop_blocking();
		printf("value from core %d is %d\n", get_core_num(), val);
		
		if(val % 21 == 0){
			printf("writing to flash returned %d\n", flash_safe_execute(call_write_flash, NULL, 200));
		}
	}
}

bool core0_timer_callback(repeating_timer_t *rt){
	int i = *(int *)(rt->user_data);

	multicore_fifo_push_blocking(i++);
	printf("value from core %d is %d\n", get_core_num(), i);

	gpio_put(25, i % 2);
	*(int *)rt->user_data = i;
	/*if(i % 5 == 0){
		printf("writing to flash returned %d\n", flash_safe_execute(call_write_flash, NULL, 200));
	}*/

	return true;
}

int main(void){
	while(!stdio_init_all()){
		;
	}

/*
	uint32_t irqs = save_and_disable_interrupts();
	flash_range_erase(FLASH_WRITE_START, NVS_SECTORS * NVS_SIZE);
	restore_interrupts_from_disabled(irqs);

	sleep_ms(10000);
*/

	gpio_init(25);
	gpio_set_dir(25, GPIO_OUT);

	multicore_launch_core1(core1_entry);

	repeating_timer_t tim;
	add_repeating_timer_ms(200, core0_timer_callback, (void *)&led, &tim);

	while(1){
		tight_loop_contents();
	}
}

Commented section in main function does not seem to have any influence on results, flash_safe_execute returns -4 persists.
When first called flash_safe_execute_core_init() on core 1, I don't get any response from the core.
Assuming core0 is safe causes the whole system break after first flash call from core 1.

add_compile_definitions(PICO_FLASH_ASSUME_CORE0_SAFE=1)

Specifying binary type in CMakeLists.txt does not change anything

pico_set_binary_type(app copy_to_ram)

Just in case there is whole CMakeLists.txt below

cmake_minimum_required(VERSION 3.13)

include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)

project(app)

pico_sdk_init()

add_compile_options(-Wall -Wextra)

add_executable(app
	main.c
)

target_include_directories(app PRIVATE
	${CMAKE_CURRENT_LIST_DIR}
)

target_link_libraries(app
	pico_stdlib
	hardware_flash
	pico_multicore
)

pico_enable_stdio_usb(app 1)
pico_enable_stdio_uart(app 1)
pico_add_extra_outputs(app)
pico_set_binary_type(app copy_to_ram)

add_custom_target(flash cp ${PROJECT_NAME}.uf2 /run/media/nero/RPI-RP2)

Why flash_safe_execute returns -4 and how to write to flash when both cores are running?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions