flash_erase ERROR

hello:

  My project is based on "esb_rx",NCS2.5.1,nRF52832.I need a Unique address for my product ,so I add flash read/write function for my projict, base on "soc_flash_nrf"

  when I get addr for esb rx,I put them in flash.but the Program crashes and restarts.

some code:

void rx_event_handler(struct esb_evt const *event)
{
	switch (event->evt_id) {
	case ESB_EVENT_TX_SUCCESS:
		LOG_DBG("TX SUCCESS EVENT");
		connect_stat = 1;
		break;
	case ESB_EVENT_TX_FAILED:
		connect_stat = 0;
		break;
	case ESB_EVENT_RX_RECEIVED:
		if (esb_read_rx_payload(&rx_payload) == 0) {
			LOG_DBG("Packet received, len %d : "
				"0x%02x, 0x%02x, 0x%02x, 0x%02x, "
				"0x%02x, 0x%02x, 0x%02x, 0x%02x",
				rx_payload.length, rx_payload.data[0],
				rx_payload.data[1], rx_payload.data[2],
				rx_payload.data[3], rx_payload.data[4],
				rx_payload.data[5], rx_payload.data[6],
				rx_payload.data[7]);
				if(esb_in_pair_mode)
                {
					LOG_INF("get pair data 0");
                    esb_in_pair_mode = 0;

                    
                    memcpy(&get_pair_addr,rx_payload.data,sizeof(hal_nvm_t));

					//  need_save_addr = 1;
					// esb_disable();
					hal_nvm_write(&get_pair_addr);

                    // hal_esb_init();
                    
                }
                else
                {
                    memcpy(tx.data,rx_payload.data,sizeof(tx.data));
                    void audio_fifo_put(struct audio_data_t *tx);
                    tx.len = sizeof(tx.data);
                    audio_fifo_put(&tx);

                }

		} else {
			LOG_ERR("Error while reading rx packet");
		}
		break;
	}
	
int hal_nvm_write(hal_nvm_t* data)
{
	LOG_INF("Test 1: Flash erase page at 0x%x", USER_PARTITION_OFFSET);
	const struct device *flash_dev = USER_PARTITION_DEVICE;
	int ret;
	ret = flash_erase(flash_dev, USER_PARTITION_OFFSET, FLASH_PAGE_SIZE);
	if (ret != 0) {
		LOG_INF("   Flash erase failed! %d",ret);
	} else {
		LOG_INF("   Flash erase succeeded!");
	}

	if (flash_write(flash_dev, USER_PARTITION_OFFSET, data,sizeof(hal_nvm_t)) != 0) 
	{
		LOG_INF("   Flash write failed!");
		return 0;
	}		


	LOG_INF("   Flash write sucess %x!",data->addr_0[0]);
    return 1;

}

and my dts:

		flash_controller: flash-controller@4001e000 {
			compatible = "nordic,nrf52-flash-controller";
			reg = < 0x4001e000 0x1000 >;
			#address-cells = < 0x1 >;
			#size-cells = < 0x1 >;
			flash0: flash@0 {
				compatible = "soc-nv-flash";
				erase-block-size = < 0x1000 >;
				write-block-size = < 0x4 >;
				reg = < 0x0 0x80000 >;
				partitions {
					compatible = "fixed-partitions";
					#address-cells = < 0x1 >;
					#size-cells = < 0x1 >;
					boot_partition: partition@0 {
						label = "mcuboot";
						reg = < 0x0 0xc000 >;
					};
					slot0_partition: partition@c000 {
						label = "image-0";
						reg = < 0xc000 0x37000 >;
					};
					slot1_partition: partition@43000 {
						label = "image-1";
						reg = < 0x43000 0x37000 >;
					};
					storage_partition: partition@7a000 {
						label = "storage";
						reg = < 0x7a000 0x3000 >;
					};
					userstorage_partition: partition@7d000 {
						label = "user_storage";
						reg = < 0x7d000 0x3000 >;
					};
				};
			};
		};

my prj,conf:

CONFIG_NCS_SAMPLES_DEFAULTS=y
CONFIG_ESB=y

CONFIG_SPEAKER=y
CONFIG_SPEAKER_ALLOW_PWM0=y
CONFIG_SPEAKER_ALLOW_PWM1=n
CONFIG_SPEAKER_ALLOW_PWM2=n
CONFIG_PWM=n

CONFIG_NRFX_SAADC=y
CONFIG_NRFX_RTC2=y
CONFIG_NRFX_RTC0=y

# CONFIG_LOG=y
CONFIG_USE_SEGGER_RTT=y
CONFIG_RTT_CONSOLE=y
CONFIG_UART_CONSOLE=n

CONFIG_ESB_TX_RX_ENABLE=n
CONFIG_ESB_MAX_PAYLOAD_LENGTH=80
CONFIG_DK_LIBRARY=y


CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=n
CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH=y

CONFIG_NRFX_TIMER0=y
CONFIG_BOARD_ENABLE_DCDC=n

CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_MPU_ALLOW_FLASH_WRITE=y
CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS=y

And i try save my addr in timer handle ,it failed again.,But when I save my addr in button handle ,it worked,like:

extern hal_nvm_t get_pair_addr;
static void button_changed(uint32_t button_state, uint32_t has_changed)
{
	if (has_changed & USER_BUTTON) {
		uint32_t user_button_state = button_state & USER_BUTTON;
		if(user_button_state)
		{
			button_time_cnt = 5000/100 + 1;
			hal_nvm_write(&get_pair_addr);
			// save_addr_later();

		}
		else
		{
			button_time_cnt = 0;
		}
		LOG_ERR("user_button_state = %d\r\n",user_button_state);


		// app_button_state = user_button_state ? true : false;
	}
}

What did I do wrong?

Parents Reply Children
  • I tryed nvs:

    	int rc;
    	memset(&theNVM,0,sizeof(hal_nvm_t));
    	rc = nvs_read(&fs, ADDRESS_ID, &theNVM, sizeof(hal_nvm_t));
    	if (rc > 0) 
    	{ /* item was found, show it */
    		LOG_INF("Id: %d, Address: %d\n", ADDRESS_ID, theNVM.addr_0[0]);
    	} 
    	else   
    	{/* item was not found, add it */
    
    		(void)nvs_write(&fs, ADDRESS_ID, data, sizeof(hal_nvm_t));
    	}

    but error is same:here is lRTT og:

    00> *** Booting nRF Connect SDK v2.5.1-1-g87ed55cbe1fe ***
    00> I: 
    00> App start
    00> 
    00> I: 3 Sectors of 4096 bytes
    00> I: alloc wra: 0, fe8
    00> I: data wra: 0, 0
    00> I: Enhanced ShockBurst init
    00> I: nvm read failed
    00> I: pair start
    00> I: Speaker dev is 0xadcc, name is thingy_speaker
    00> E: PCM PLAY 
    00> E: PCM PLAY START
    00> I: Initialization complete
    00> I: Time to wait: 100 ms
    00> I: Timer status: enabled
    00> D: Packet received, len 8 : 0xe2, 0xf8, 0xb4, 0x57, 0x2b, 0x49, 0x8f, 0x2f
    00> I: get pair data 0
    00> ASSERTION FAIL @ WEST_TOPDIR/zephyr/kernel/mutex.c:101
    00> E: r0/a1:  0x00000004  r1/a2:  0x00I: 3 Sectors of 4096 bytes

  • The error at that line in mutex.c is

    	__ASSERT(!arch_is_in_isr(), "mutexes cannot be used inside ISRs");

    It says that this code path cannot happen in interrupt context.  So probably defer the nvs_write operation in the workqueue_thread that gets called sometime after the ISR exits. You can use some other way like message queues or similar inter context communication mechanism or offloading ISR work to call nvs_write in other context only after this ISR is being executed.

    This page can help you to understand how you submit a work item into a work queue from any context.

Related