Skip to content

Flash File System Using FAT

In this page, we will learn how to use the FAT file system on the flash memory with FAT::Flash class.

Add the following lines to your CMakeLists.txt.

CMakeLists.txt
target_link_libraries(your-project jxglib_FAT_Flash)
jxglib_configure_FAT(your-project FF_VOLUMES 1)

Modify the number of FF_VOLUMES according to the number of FAT volumes you want to use.

Add the following line to your source file.

Your Source File
#include "jxglib/FAT/Flash.h"

Declaring a File System

Creating a FAT::Flash instance declares that the specified region of the flash memory is reserved for the FAT file system.

FAT::Flash(const char* driveName, uint32_t addrXIP, uint32_t bytesXIP)
  • driveName: A string name for the drive, can contain any characters
  • addrXIP: The starting address of the flash memory region for the FAT file system
  • bytesXIP: The number of bytes to reserve from the end of the flash memory for the FAT file system

The construction below allocates a region from the end of the flash memory.

FAT::Flash(const char* driveName, uint32_t bytesXIP)
  • driveName: A string name for the drive, can contain any characters
  • bytesXIP: The number of bytes to reserve from the end of the flash memory for the FAT file system

Note that the constructor is just a declaration of the drive and does not modify the flash memory. The file system is created only when format command is executed on the shell or FS::Format() is called in the program for the declared drive.

Sample Program

In this sample program, we create a FAT::Flash instance on the flash memory. The instance is assigned a unique drive name and a specific region of the flash memory as follows:

Drive Name File System Type Flash Memory Region Size
FAT: FAT 0x10100000-0x10200000 1MB

Build and Flash the Program

Create a new Pico SDK project named fs-flash-fat.

Create Pico SDK Project
  1. In VSCode, run >Raspberry Pi Pico: New Pico Project in the command palette.
  2. In the dialog below, select C/C++. new-project-dialog

  3. Create a project with the following settings:

    • Name ... Enter the project name.
    • Board type ... Select your board type.
    • Location ... Select the parent directory where the project directory will be created.
    • Stdio support ... Leave Console over USB unchecked when you use LABOPlatform or other USB features because they conflict with each other. You can enable it by editing the CMakeLists.txt file later.
    • Code generation options ... Check Generate C++ code.

new-project

Open Existing Pico SDK Project

Open the project folder in VSCode using one of the following methods:

  • In a command prompt, change the current directory to the project folder and execute code ..
  • In a Explorer, choose the project folder, push Alt+D to focus the address bar, and execute code ..

    vscode-from-explorer

If the folder is already prepared as a Pico SDK project, just proceed with editing and building the project.

If not, you will see the following message at the bottom right corner of VSCode.

do-you-want-to-import

Click Yes and you will see the following window.

import-project

Click Import and the project will be prepared as a Pico SDK project.

When the Do you want to import this project as Raspberry Pi Pico project? message disappears before you click Yes, you can reveal it by clicking the icon notify-icon at the bottom right corner of VSCode.

Clone the pico-jxglib repository from GitHub so the direcory structure looks like this:

├── pico-jxglib/
└── fs-flash-fat/
    ├── CMakeLists.txt
    ├── fs-flash-fat.cpp
    └── ...
Clone the Repository

Change the current directory to the parent directory where you want to clone the pico-jxglib repository and run the following commands:

$ git clone https://github.com/ypsitau/pico-jxglib.git
$ cd pico-jxglib
$ git submodule update --init --recursive

pico-jxglib is updated almost daily. If you've already cloned it, run the following command in the pico-jxglib directory to get the latest version:

$ git pull

A directory from a Git repository can safely be moved to another location even after cloning.

Add the following lines to the end of CMakeLists.txt:

CMakeLists.txt
1
2
3
4
5
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../pico-jxglib pico-jxglib)
target_link_libraries(fs-flash-fat
    jxglib_Shell jxglib_Serial jxglib_ShellCmd_Basic
    jxglib_FAT_Flash jxglib_ShellCmd_FS)
jxglib_configure_FAT(fs-flash-fat FF_VOLUMES 1)

Enable UART or USB stdio as described below.

Enable UART and/or USB stdio

Find the following lines in CMakeLists.txt:

CMakeLists.txt
pico_enable_stdio_uart(your-project 0)
pico_enable_stdio_usb(your-project 0)

You can set the value to 1 to enable stdio or 0 to disable it.

  • pico_enable_stdio_uart() enables UART stdio that uses GPIO0 (UART0 TX) and GPIO1 (UART0 RX).
  • pico_enable_stdio_usb() enables USB stdio that uses the USB interface. Make sure to disable USB stdio when you use USB features because they conflict with each other.

Edit fs-flash-fat.cpp as follows:

fs-flash-fat.cpp
#include <stdio.h>
#include "pico/stdlib.h"
#include "jxglib/Serial.h"
#include "jxglib/Shell.h"
#include "jxglib/FAT/Flash.h"

using namespace jxglib;

int main()
{
    ::stdio_init_all();
    // Prepare the Shell with Stdio
    Serial::Terminal terminal;
    Shell::AttachTerminal(terminal.Initialize());
    // Declare the flash drive with a name and size (must be a multiple of 4096)
    FAT::Flash drive("FAT:", 0x1010'0000, 0x0010'0000); // 1MB
    for (;;) {
        Tickable::Tick();
    }
}

Build and flash the program to the board.

Build and Flash

The simplest way to build and flash the program is to use the UF2 file generated by the build process. Pico board, a USB cable, and a computer are all you need to get started. Here are the steps to build and flash the program:

  1. Pressing F7 on VSCode will build the project. If this is the first time you build the project, you will see the dialog shown below. Select Pico Using compilers: ... and the build process will start.

    select-a-kit

  2. After building, you can find the generated UF2 file in the build directory.

  3. Connect your Pico to the computer using a USB cable while holding the BOOTSEL button, and it will appear as a mass storage device. Copy the generated UF2 file to this device to flash it. No need to mind the destination directory, just copy it to the root directory of the device.

If you have a debug probe like this, you can also flash the program using OpenOCD and GDB. This is the recommended method for development, as it allows you to debug the program while running it on the board!

Running the Program

Open a terminal emulator to connect the board.

Setup Tera Term for LABOPlatform

Tera Term is available here.

From the menu bar, select [File] - [New Connection...] to open the dialog below:

teraterm-new-connection

pico-jxgLABO or a firmware that links jxglib_LABOPlatform provides two USB serial ports: one for terminal use and the other for applications such as logic analyzers and plotters. Select one of the ports and press Enter key in the terminal. When successfully connected, you will see a prompt in the terminal.

L:/>

A prompt will appear like this:

FAT:?>

FAT is the driver name specified by the FAT::Flash instance in the program. The current directory is now ?, indicating the drive is not formatted.

ls-drive shows the drive information:

FAT:?>ls-drive -r
 Drive  Format        Total Remarks
 FAT:   none              0 FAT::Flash 0x10100000-0x10200000 1024kB

Executing format command with the drive name formats the drive:

FAT:?>format fat:
drive fat: formatted in FAT12
FAT:/>ls-drive -r
 Drive  Format        Total Remarks
 FAT:   FAT12       1048576 FAT::Flash 0x10100000-0x10200000 1024kB

The prompt changes to FAT:/>, indicating the drive is now formatted and ready to use. You can create files and directories as usual:

FAT:/>touch file1 file2 file3
FAT:/>dir
-a--- 2000-01-01 00:00:00      0 file1
-a--- 2000-01-01 00:00:00      0 file2
-a--- 2000-01-01 00:00:00      0 file3