FLASH Development Guide_Rev1.3

中文

Revision History

Version

Date

Author

Revision Content

Rev1.0

23-09-11

TL

Initial document creation

Rev1.1

24-03-25

sxx

Changed document name

Rev1.2

24-05-07

YMX

Optimized document structure, adjusted some text descriptions

Rev1.3

25-04-18

ZH

Added common issues section

1 Introduction

This document introduces the LTE-EC71X FLASH interface APIs. The API interfaces are declared in the file components/kernel/lierda_api/liot_flash/liot_flash.h.

New Addition:

The figure below shows a reference diagram for flash partition layout. Different SDK versions may have different FLASH partitions:

/*
flash layout, total 4MB
flash raw address: 0x00000000---0x00400000
flash xip address(from both ap/cp view): 0x00800000---0x00c00000

0x00000000          |---------------------------------|
                    |      header1 4KB                |
0x00001000          |---------------------------------|
                    |      header2 4KB                |
0x00002000          |---------------------------------|
                    |      fuse mirror 4KB            |
0x00003000          |---------------------------------|
                    |      bl 72KB                    |
0x00015000          |---------------------------------|
                    |      rel data(factory)20KB      |
0x0001a000          |---------------------------------|
                    |      cp img 400KB               |
0x0007e000          |---------------------------------|
                    |      app img 3116KB             |
0x00389000          |---------------------------------|
                    |      hib backup 96KB            |
0x003a1000          |---------------------------------|
                    |      lfs  48KB                  |
0x003ad000          |---------------------------------|
                    |      fota 272KB                 |
0x003f1000          |---------------------------------|
                    |      rel data 52KB              |
0x003fe000          |---------------------------------|
                    |      plat config 8KB            |
0x00400000          |---------------------------------|

*/

#define FLASH_RESERVE_USER_REGION_START           (0x3ad000)
#define FLASH_RESERVE_USER_REGION_END             (0x3ac000)
#define FLASH_RESERVE_USER_REGION_SIZE            (FLASH_RESERVE_USER_REGION_END-FLASH_RESERVE_USER_REGION_START) // 4KB

The above partition diagram illustrates the FLASH memory layout.

2 API Function Overview

Function

Description

liot_flash_erase()

Erase data in flash.

liot_flash_read()

Read data from flash.

liot_flash_write()

Write data to flash.

3 API Function Details

APIs are limited to operating on the reserved 4KB area (0x3ad000~0x3ac000). Frequent API calls reduce flash lifespan (100K cycles). It is recommended to use file system related APIs for frequent operations.

3.1 liot_flash_erase

This function is used to erase data in flash.

  1. Declaration

uint32_t liot_flash_erase(uint32_t SectorAddress, uint32_t size);
  1. Parameters

  • SectorAddress: [In] Starting address of the erase area. It must be a multiple of 0x1000 and located in user FLASH.

  • size: [In] Length to be erased.

  1. Return Value

  • 0: Success.

  • other: Failure.

3.2 liot_flash_read

This function is used to read data from flash.

  1. Declaration

uint32_t liot_flash_read(uint8_t *pData, uint32_t ReadAddr, uint32_t Size);
  1. Parameters

  • pData: [Out] Address to store data read from flash.

  • ReadAddr: [In] Starting address for reading data.

  • Size: [In] Length to be read.

  1. Return Value

  • 0: Success.

  • other: Failure.

3.3 liot_flash_write

This function is used to write data to flash.

  1. Declaration

uint32_t liot_flash_write(uint8_t *pData, uint32_t WriteAddr, uint32_t Size);
  1. Parameters

  • pData: [In] Address containing data to be written to flash.

  • WriteAddr: [In] Starting address for writing data.

  • Size: [In] Length of data to be written.

  1. Return Value

  • 0: Success.

  • other: Failure.

4 Code Example

  1. Refer to the examples/demo/src/demo_flash.c file for sample code.

#include "lierda_app_main.h"
#include "liot_flash.h"
#include "liot_os.h"
#include "liot_type.h"
#include "mem_map.h"

/*
    This project demonstrates the use of user area flash.
    In this case, we will erase a user area, write data to it, and then read the written data for printing.
    Non-user areas, such as the LIOT_BEFORE_APP_ADDR and LIOT_AFTER_APP_ADDR areas, cannot be erased, written, or read.
 */
#define FLASH_RESERVE_USER_REGION_START           (0x3e4000)
#define FLASH_RESERVE_USER_REGION_END             (0x3e5000)
#define FLASH_RESERVE_USER_REGION_SIZE            (FLASH_RESERVE_USER_REGION_END-FLASH_RESERVE_USER_REGION_START) // 4KB
void liot_flash_demo_task(void *argv)
{
    char app_data[] = "BBBBBBBBBB";

    char app_buff[11] = {0};

    liot_rtos_task_sleep_ms(2000);
    liot_trace("========== flash demo start ==========");
    liot_trace("=== Print erase flash address ====", LIOT_APP_ADDR_START, LIOT_APP_ADDR_END);
    liot_trace("=== erase before app address, ret(%d) ====", liot_flash_erase(LIOT_APP_ADDR_START, LIOT_APP_ADDR_SIZE));

    liot_rtos_task_sleep_ms(100);

    liot_trace("=== Write data to flash ====");
    liot_trace("=== write data on before app address, ret(%d) ====",
               liot_flash_write((uint8_t *)app_data, LIOT_APP_ADDR_START, 10));

    liot_rtos_task_sleep_ms(100);

    liot_trace("=== Read data from flash ====");
    liot_trace("=== read data on app address, ret(%d) ====",
               liot_flash_read((uint8_t *)(&app_buff[0]), LIOT_APP_ADDR_START, 10));

    liot_rtos_task_sleep_ms(100);

    liot_trace("=== Print the read data ===");
    liot_trace("=== app_buff(%s) ===", app_buff);

    liot_trace("========== flash demo end ==========");

    liot_rtos_task_delete(NULL); // kill itself
}
  • Execution Result:

_images/flash-guide/image_1.png

As shown in the figure above, comparing the two sets of data before and after read/write operations, liot_flash_write() successfully wrote data, and liot_flash_read() read the data BBBBBBBBBB, which matches the written data, indicating successful flash read/write operations.

5 Common Issues

5.1 How to Confirm the FLASH Address Range

The address range in the sample code is as follows:

#define FLASH_RESERVE_USER_REGION_START (0x3e4000)
#define FLASH_RESERVE_USER_REGION_END (0x3e5000)
#define FLASH_RESERVE_USER_REGION_SIZE (FLASH_RESERVE_USER_REGION_END-FLASH_RESERVE_USER_REGION_START) // 4KB

The address range varies for different modules. Check the macro definitions in “mem_map_71x.h”. For example, the address definition in 716s is as follows:

_images/flash-guide/image_2.png

5.2 Do I Need to Erase Flash Before Writing?

Erasing is recommended.

If you don’t erase, for example, if “hello world” has already been written to Flash, and you write “12345” again, the read data will be “12345 world”.

5.3 What is the Flash Erase/Write Cycle Endurance?

100K cycles.

5.4 Will Flash Data Be Erased After Re-flashing Firmware?

Yes, it will be erased.

5.5 Does EC718 Support External Flash?

Yes, external flash can be implemented through a standard 4-wire SPI interface. Note that external flash can only store data; code execution is not supported on external flash.