<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>nRF5340: FCB(Flash Circular Buffer) on external flash</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/110506/nrf5340-fcb-flash-circular-buffer-on-external-flash</link><description>Hi Support Team, 
 I want to use an external flash(2M byte) to store the sensor data in a &amp;#39;circular overwrite&amp;#39; way. I now tried it with the FCB(Flash Circular Buffer) on nRF5340-DK. 
 On the external flash, I use the first sector as a control block and</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Tue, 01 Apr 2025 22:40:20 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/110506/nrf5340-fcb-flash-circular-buffer-on-external-flash" /><item><title>RE: nRF5340: FCB(Flash Circular Buffer) on external flash</title><link>https://devzone.nordicsemi.com/thread/530085?ContentTypeID=1</link><pubDate>Tue, 01 Apr 2025 22:40:20 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:dbceddee-ecf8-4005-8df5-1a2399a72e8f</guid><dc:creator>chris22222</dc:creator><description>&lt;p&gt;I came to the same conclusion as your solution but technically this is incorrect.&amp;nbsp; I am working on a bug report and PR to file with zephyr. The issue is with this snippet:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;	for (int i = 0; i &amp;lt; FCB_SECTOR_COUNT; i++) {
		fcb_instance_sectors[i].fs_off = i * SPI_FLASH_SECTOR_SIZE;
		fcb_instance_sectors[i].fs_size = SPI_FLASH_SECTOR_SIZE;
	}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;flash_sector-&amp;gt;fs_off is defined as an absolute address relative to the beginning of the flash device:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;struct flash_sector {
	/** Sector offset from the beginning of the flash device */
	off_t fs_off;
	/** Sector size in bytes */
	size_t fs_size;
};&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;However fcb uses flash_area read and write accesses when interacting with the flash.&amp;nbsp; This means that it uses relative addressing, not absolute.&lt;/p&gt;
&lt;p&gt;If you define your flash_area with a partition boundary starting at 0x0000, the issue will not manifest.&amp;nbsp; However, if the partition is started at any other address like 0x5000, using fs_offset as defined will pass an absolute address into flash_area_read and flash_area_write.&amp;nbsp; fcb_init will fail to initialize because the flash_area_read of the fcb header will be out of bounds.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The way to get around this is the improperly us flash_sector-&amp;gt;fs_off with relative addressing as we both have done.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I spent about half a day figuring this out, but I was particularly stuck with fcb_init since my partition was located in the last 8 sectors of flash.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF5340: FCB(Flash Circular Buffer) on external flash</title><link>https://devzone.nordicsemi.com/thread/486327?ContentTypeID=1</link><pubDate>Wed, 29 May 2024 08:23:24 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:aaa76109-2bfb-40c4-9b5e-b08f65cf36f3</guid><dc:creator>Yanpengwu</dc:creator><description>&lt;p&gt;Hi Amanda, any update on this?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF5340: FCB(Flash Circular Buffer) on external flash</title><link>https://devzone.nordicsemi.com/thread/480516?ContentTypeID=1</link><pubDate>Wed, 24 Apr 2024 16:05:22 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:72a37e09-839c-44ca-8494-9fb760e87ccb</guid><dc:creator>Yanpengwu</dc:creator><description>&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: Currently I can init FCB and append logs successfully, but can&amp;#39;t read the correct log entries from&amp;nbsp;the flash.&lt;br /&gt;Could you help me have a look at my code? Thank you very much.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FCB Init:&lt;/strong&gt;&lt;br /&gt;&lt;pre class="ui-code" data-mode="text"&gt;#define SPI_FLASH_SECTOR_SIZE        		4096
#define FCB_VERSION							1
#define FCB_SECTOR_COUNT					511
#define FCB_SCRATCH_SECTOR_COUNT			11

// FCB sectors array, need to be inited per sector
static struct flash_sector fcb_instance_sectors[FCB_SECTOR_COUNT];

int fcb_init_instance()
{
	struct fcb *fcb = &amp;amp;fcb_instance;
	const struct flash_area *log_fa = NULL;
	const struct flash_parameters *flash_params = NULL;
	int rc;

	memset(fcb, 0, sizeof(*fcb));
	
	// Init the array of fcb_instance_sectors, need to init it per sector
	memset(fcb_instance_sectors, 0, sizeof(fcb_instance_sectors));
	for (int i = 0; i &amp;lt; FCB_SECTOR_COUNT; i++) {
		fcb_instance_sectors[i].fs_off = i * SPI_FLASH_SECTOR_SIZE;
		fcb_instance_sectors[i].fs_size = SPI_FLASH_SECTOR_SIZE;
	}

	// 1. Open flash area log_data_parti
    rc = flash_area_open(FLASH_AREA_ID(log_data_parti), &amp;amp;log_fa);
    if (rc) {
        LOG_ERR(&amp;quot;[fcb_init_instance] Failed to open log partition: %d&amp;quot;, rc);
        return -ENODEV;
    }

	flash_params = flash_get_parameters(log_fa-&amp;gt;fa_dev);
	if (!flash_params) {
		LOG_ERR(&amp;quot;[fcb_init_instance] Failed to get flash parameters\n&amp;quot;);
		return -ENODEV;
	}

	//2. Must erase the fcb-&amp;gt;f_sectors before fcb_init, otherwise the f_magic checking will be failed!
	rc = flash_area_erase(log_fa, 0, log_fa-&amp;gt;fa_size);
	if (rc != 0) {
		LOG_ERR(&amp;quot;[fcb_init_instance] Failed to erase Flash area, error %d&amp;quot;, rc);
		flash_area_close(log_fa);
		return rc;
	} 

	// 3. int FCB instance on log_data_parti
	fcb-&amp;gt;f_magic = 0x1a1a1a1a;
    fcb-&amp;gt;f_version = FCB_VERSION;
    fcb-&amp;gt;f_sector_cnt = FCB_SECTOR_COUNT; 
	fcb-&amp;gt;f_scratch_cnt = FCB_SCRATCH_SECTOR_COUNT;
    fcb-&amp;gt;f_sectors = fcb_instance_sectors;
	fcb-&amp;gt;f_align = flash_params-&amp;gt;write_block_size;

    rc = fcb_init(log_fa-&amp;gt;fa_id, fcb);
    if (rc) {
        LOG_ERR(&amp;quot;[fcb_init_instance] FCB init failed with error %d&amp;quot;, rc);
        return rc;
    } else {
		LOG_WRN(&amp;quot;[fcb_init_instance] FCB init OK! %d&amp;quot;, rc);
	}

	flash_area_close(log_fa);

	return 0;
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Append entry to FCB:&lt;/strong&gt;&lt;br /&gt;&lt;pre class="ui-code" data-mode="text"&gt;int fcb_append_log_entry(T_log_entry* log_data, size_t len)
{
    struct fcb_entry entry_descriptor;
    int rc;

	memset(&amp;amp;entry_descriptor, 0, sizeof(struct fcb_entry));
	rc = fcb_append(&amp;amp;fcb_instance, len, &amp;amp;entry_descriptor);
    if (rc) {
		// Do rotation in case of reaching the end of partition
		if (rc == -ENOSPC) {
            LOG_ERR(&amp;quot;[fcb_append_log_entry] No space left, rotating FCB and try again&amp;quot;);
            rc = fcb_rotate(&amp;amp;fcb_instance);
            if (rc) {
                LOG_ERR(&amp;quot;[fcb_append_log_entry] FCB rotate failed with error %d&amp;quot;, rc);
                return rc;
            }

            // Retry to append
            rc = fcb_append(&amp;amp;fcb_instance, len, &amp;amp;entry_descriptor);
            if (rc) {
                LOG_ERR(&amp;quot;[fcb_append_log_entry] FCB append retry failed after rotate, error %d&amp;quot;, rc);
                return rc;
            }
        } else {
			LOG_ERR(&amp;quot;[fcb_append_log_entry] Failed to append data: %d&amp;quot;, rc);
            return rc;
        }
    }

    rc = flash_area_write(fcb_instance.fap, entry_descriptor.fe_data_off, log_data, len);
    if (rc) {
        LOG_ERR(&amp;quot;[fcb_append_log_entry] Failed to write to FCB: %d&amp;quot;, rc);
        fcb_append_finish(&amp;amp;fcb_instance, &amp;amp;entry_descriptor);
        return rc;
    }	

	rc = fcb_append_finish(&amp;amp;fcb_instance, &amp;amp;entry_descriptor);
	if (rc) {
        LOG_ERR(&amp;quot;[fcb_append_log_entry] FCB append finish failed with error %d&amp;quot;, rc);
        return rc;
    }

	return 0;	
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Read and print entries from a sector:&lt;/strong&gt;&lt;br /&gt;&lt;pre class="ui-code" data-mode="text"&gt;void fcb_print_Sector(uint16_t sector_no)
{
	struct fcb_entry entry_desc, first_entry_desc;
	T_log_entry log_data;
	int rc;

    memset(&amp;amp;entry_desc, 0, sizeof(entry_desc));
	entry_desc.fe_sector = &amp;amp;fcb_instance_sectors[sector_no];
	// Start with the first entry in this sector
    rc = fcb_getnext(&amp;amp;fcb_instance, &amp;amp;entry_desc);
	memcpy(&amp;amp;first_entry_desc, &amp;amp;entry_desc, sizeof(struct fcb_entry));

    while(rc == 0) {
		if(entry_desc.fe_sector == first_entry_desc.fe_sector){
			rc = flash_area_read(fcb_instance.fap, entry_desc.fe_data_off, &amp;amp;log_data, entry_desc.fe_data_len);
			if (rc) {
				LOG_ERR(&amp;quot;[fcb_print_Sector] Failed to read entry with error %d&amp;quot;, rc);
				continue;
			} else{
				LOG_INF(&amp;quot;[fcb_print_Sector] type=%d, value=%4.6f, timestamp=%08u&amp;quot;, 
								log_data.type, log_data.value, log_data.timestamp);
			}

			// Get the next entry
			rc = fcb_getnext(&amp;amp;fcb_instance, &amp;amp;entry_desc);
		} else {
			break;
		}
    } 	
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF5340: FCB(Flash Circular Buffer) on external flash</title><link>https://devzone.nordicsemi.com/thread/480293?ContentTypeID=1</link><pubDate>Tue, 23 Apr 2024 19:14:46 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:572a3915-8331-46fa-8dd0-199b41083b26</guid><dc:creator>Amanda Hsieh</dc:creator><description>&lt;p&gt;Hi,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I am looking into your case and will reply when I collect enough information.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Regards,&lt;br /&gt;Amanda H.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>