The Flash abstraction layer is an abstraction layer for the management and operation of Flash and Flash-based partitions. The upper layer unifies the Flash and partition operation API (the framework diagram is shown below), and has the following characteristics:
- Supports static and configurable partition table and can associate multiple Flash devices;
- The partition table supports **automatic loading**. Avoid the problem that the partition table is defined multiple times in multiple firmware projects;
- The code is streamlined, **no dependency** on the operating system, and can run on bare metal platforms, such as Bootloader that has certain requirements for resources;
- Unified operation interface. Ensure the file system, OTA, NVM (for example: [EasyFlash](https://github.com/armink-rtt-pkgs/EasyFlash)) and other components that have certain dependencies on Flash, and the reusability of the underlying Flash driver;
- Comes with Finsh/MSH-based test commands, which can be operated in byte addressing mode (read, write, and erase) Flash or partition through Shell, which is convenient for developers to debug and test;
The configuration instructions for each function are as follows:
- Enable debug log output (enabled by default);
- Whether the partition table is defined in `fal_cfg.h` (enabled by default). If you turn off this option, fal will automatically go to the specified location of the designated Flash to retrieve and load the partition table. For the specific configuration, see the following two options;
- The **end address** of the partition table is located at the offset on the Flash device. fal will retrieve the partition table from this address and read it directly to the top of the Flash. If you are not sure about the specific location of the partition table, you can also configure it as the end address of the Flash, fal will retrieve the entire Flash, and the retrieval time may increase.
- Enable FAL migration files for SFUD (closed by default);
- The name of the FLASH device passed in when calling the `rt_sfud_flash_probe` function should be entered (you can also check the name of the Block Device through the list_device command). This name corresponds to the Flash name in the partition table. Only when the device name is set correctly can the read and write operations on FLASH be completed.
3. Call fal_init() to initialize the library: After the migration is completed, it can be called in the application layer, such as in the main function.
- Refer to [`fal_flash_stm32f2_port.c`](https://github.com/RT-Thread-packages/fal/blob/master/samples/porting/fal_flash_stm32f2_port.c) to define the on-chip flash device.
- Refer to [`fal_flash_sfud_port.c`](https://github.com/RT-Thread-packages/fal/blob/master/samples/porting/fal_flash_sfud_port.c) to define off-chip spi flash device.
To define specific Flash device objects, users need to implement the operation functions of `init`, `read`, `write`, and `erase` according to their own Flash conditions:
Users need to implement these operation functions according to their own Flash conditions. A specific Flash device object is defined at the bottom of the file. The following example defines stm32f2 on-chip flash: stm32f2_onchip_flash
-`128*1024`: Flash block/sector size (because the STM32F2 blocks have uneven sizes, the erase granularity is the largest block size: 128K).
-`{init, read, write, erase}`: Flash operation functions. If there is no init initialization process, the first operation function position can be left blank.
-`8`: Set the write granularity, the unit is bit, 0 means not effective (the default value is 0), this member is a new member whose fal version is greater than 0.4.0. Each flash write granularity is not the same, it can be set through this member, the following are several common Flash write granularities:
The Flash device table is defined in the header file `fal_cfg.h`, you need to **create a new `fal_cfg.h` file** before defining the partition table. Please place this file in the port folder of the corresponding BSP or project directory, and Add the header file path to the project. fal_cfg.h can refer to [Sample file fal/samples/porting/fal_cfg.h](https://github.com/RT-Thread-packages/fal/blob/master/samples/porting/fal_cfg.h) to complete.
The partition table is also defined in the `fal_cfg.h` header file. Flash partitions are based on Flash devices. Each Flash device can have N partitions. The collection of these partitions is the partition table. Before configuring the partition table, make sure that the **Flash device** and **device table** have been defined. fal_cfg.h can refer to [Sample file fal/samples/porting/fal_cfg.h](https://github.com/RT-Thread-packages/fal/blob/master/samples/porting/fal_cfg.h) to complete.
The partition parameters that users need to modify include: partition name, associated Flash device name, offset address (relative to the internal Flash device), and size. Pay attention to the following points:
- Partition name guarantee **cannot be repeated**;
- The associated Flash device **must have been defined in the Flash device table**, and the **name is the same**, otherwise there will be an error that the Flash device cannot be found;
- The starting address and size of the partition **cannot exceed the address range of the Flash device**, otherwise it will cause packet initialization errors;
> Note: When defining each partition, in addition to filling in the parameter attributes described above, you need to add the attribute `FAL_PART_MAGIC_WORD` at the front and add `0` at the end (currently used for reserved functions)
FAL provides a wealth of test commands, and the project only needs to enable the Finsh/MSH function on RT-Thread. These commands will be very useful when doing some Flash-based application development and debugging. It can accurately write or read the original Flash data at the specified location, quickly verify the integrity of the Flash driver, and even perform performance tests on the Flash.
When using the fal command for the first time, directly inputting `fal probe` will display the partition table information. You can specify the object to be operated as a partition in the partition table or a flash device.
Enter `fal erase` first, followed by the starting address and length of the data to be erased. The following command is: erase 4096 bytes of data from address 0 (relative to Flash or partition)
> Note: According to the Flash characteristics, the erase action will be processed according to sector alignment. Therefore, if the erase operation address or length is not aligned with the flash sector, the entire sector data associated with it will be erased.
Enter `fal write` first, followed by N pieces of data to be written, separated by spaces. The following command is: Write 1, 2, 3, 4, 5, 5 bytes of data from address 8
Enter `fal read` first, followed by the starting address and length of the data to be read. The following command is: read 64 bytes of data from address 0
The performance test will test the erasing, writing and reading speed of the Flash. At the same time, the accuracy of writing and reading data will be tested to ensure the consistency of the writing and reading data of the entire Flash or the entire partition.
Enter `fal bench` first, followed by the sector size of the Flash to be tested (please check the corresponding Flash manual, SPI Nor Flash is generally 4096). Since the performance test will lose the data of the entire Flash or the entire partition, the command must be followed by `yes` at the end.
- [Example of fatfs file system based on FAL partition](https://github.com/RT-Thread/IoT_Board/tree/master/examples/15_component_fs_flash)
- [Application note of littlefs file system based on FAL partition](https://www.rt-thread.org/document/site/application-note/components/dfs/an0027-littlefs/)
- [EasyFlash porting instructions based on FAL partition](https://github.com/armink-rtt-pkgs/EasyFlash/tree/master/ports)
`fal_cfg.h` is the configuration file of the fal software package, which needs to be created manually by the user and defines the relevant partition table information. Please place the file in the port folder of the BSP or the port folder of the project directory (if not, create a new port folder), and add the path of the header file to the project, see "`2.2. Define the Flash Device Table `" section.