Read FS FileSystem

Requirements

No specific requirement. This example should run without issue on GAP9 EVK.

Description

This example shows you how to use READFS on GAP9 with mram or external flash. In the readf_example.c the two binary files in the files folder are read and checked if they are equal (they have been generated equal).

# Boot from JTAG
mkdir build && cd build && cmake ../
make run -j

To select a different Flash type you can use the GUI interface through:

# Boot from JTAG
mkdir build && cd build && cmake ../
make menuconfig

and choose GAP_SDK -> Drivers -> FS -> ReadFS Flash Type or add CONFIG_READFS_FLASH_TYPE_MRAM/DEFAULT/OSPI=y in the sdk.config file.

Code

/* 
 * Copyright (C) 2024 GreenWaves Technologies
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <pmsis.h>
#include "bsp/fs.h"
#include "stdio.h"
#include <bsp/fs/readfs.h>

#ifndef FLASH_TYPE
#error "Flash type is undefined"
#endif

#define ITER        ( 10 )
#define BUFF_SIZE   ( 160000 )

#define PAD_GPIO_LED2    (PI_PAD_086)
#define BLINK_DELAY_US   (500 * 1000)

static PI_L2 char buff[2][BUFF_SIZE];
static int32_t count_done = 0;
static pi_fs_file_t *file[2];
static struct pi_device fs;

static uint32_t index0 = 0;
static uint32_t index1 = 0;

static int32_t exec_reads()
{
    int32_t errors = 0;

    int32_t size0 = file[0]->size;
    int32_t size1 = file[1]->size;
    int32_t rd_size0, rd_size1;

    int start0, elapsed0=0;
    int start1, elapsed1=0;
    pi_perf_conf(1<<PI_PERF_CYCLES);
    pi_perf_fc_start();
    do{
        if (size0 > BUFF_SIZE)
            rd_size0 = BUFF_SIZE;
        else
            rd_size0 = size0;

        if (size1 > BUFF_SIZE)
            rd_size1 = BUFF_SIZE;
        else
            rd_size1 = size1;

        start0 = pi_perf_fc_read(PI_PERF_CYCLES);
        pi_fs_read(file[0], buff[0], rd_size0);
        elapsed0 += pi_perf_fc_read(PI_PERF_CYCLES) - start0;
        start1 = pi_perf_fc_read(PI_PERF_CYCLES);
        pi_fs_read(file[1], buff[1], rd_size1);
        elapsed1 += pi_perf_fc_read(PI_PERF_CYCLES) - start1;

        size0 -= rd_size0;
        size1 -= rd_size1;

        for (int32_t i=0; i<rd_size0; i++)
        {
            unsigned char expected;
            expected = (index0%128) & 0x7f;
            if (expected != buff[0][i])
            {
                printf("Error, buffer: %d, index: %d, expected: 0x%x, read: 0x%x\n", 0, i, expected, buff[0][i]);
                return -6;
            }
            index0 ++;
        }

        for (int32_t i=0; i<rd_size1; i++)
        {
            unsigned char expected;
            expected = (index1 %128) | 0x80;
            if (expected != buff[1][i])
            {
                printf("Error, buffer: %d, index: %d, expected: 0x%x, read: 0x%x\n", 1, i, expected, buff[1][i]);
                return -6;
            }
            index1 ++;
        }

    } while(size0 && size1);
    index0 = 0;
    index1 = 0;
    printf("Copied: %d and %d for the two files in: %dCyc (%.2fB/Cyc) %dCyc (%.2fB/Cyc)\n\n",
        file[0]->size, file[1]->size, elapsed0, ((float) file[0]->size) / elapsed0, elapsed1, ((float) file[1]->size) / elapsed1
    );

    return errors;
}

#define QUOTE(name) #name
#define STR(macro) QUOTE(macro)

#define READFS_NAME_LEN 16

static int32_t example_entry()
{
    struct pi_readfs_conf conf;
    pi_readfs_conf_init(&conf);

    conf.fs.partition_name = pi_l2_malloc(sizeof(char)*READFS_NAME_LEN);
    conf.fs.partition_name = strcpy(conf.fs.partition_name, "readfs_");
    conf.fs.partition_name = strcat(conf.fs.partition_name, STR(FLASH_TYPE));
    printf("partition name: %s\n",conf.fs.partition_name);
    pi_open_from_conf(&fs, &conf);

    if (pi_fs_mount(&fs))
        return -2;
    printf("fs mounted\n");

    file[0] = pi_fs_open(&fs, STR(FILE0), 0);
    if (file[0] == NULL)
        return -3;

    file[1] = pi_fs_open(&fs, STR(FILE1), 0);
    if (file[1] == NULL)
        return -4;

    printf("fs opened\n");
    if (exec_reads())
        return -5;

    pi_fs_close(file[0]);
    pi_fs_close(file[1]);

    pi_fs_unmount(&fs);
    pi_l2_free(conf.fs.partition_name,sizeof(char)*READFS_NAME_LEN);

    return 0;
}

int main(void)
{
    printf("*** Entering example ReadFS ***\n");
    int32_t ret = 0;

    /* Frequency Settings: defined in the Makefile */
    int cur_fc_freq = pi_freq_set(PI_FREQ_DOMAIN_FC, 370*1000*1000);
    int cur_pe_freq = pi_freq_set(PI_FREQ_DOMAIN_PERIPH, 370*1000*1000);

    int32_t fc_freq     = pi_freq_get(PI_FREQ_DOMAIN_FC);
    int32_t periph_freq = pi_freq_get(PI_FREQ_DOMAIN_PERIPH);

    printf("\nFC     frequency: %d Mhz\n",fc_freq/1000000);
    printf("Periph frequency: %d Mhz\n",periph_freq/1000000);

#ifdef GPIO_BLINK
    /* set pad to gpio mode */
    pi_pad_function_set(PAD_GPIO_LED2, PI_PAD_FUNC1);

    /* configure gpio output */
    pi_gpio_flags_e flags = PI_GPIO_OUTPUT;
    pi_gpio_pin_configure(PAD_GPIO_LED2, flags);

    int32_t gpio_val = 1;

    printf("gpio set\n");
#endif

    for (int32_t i = 0; i < ITER; i++)
    {
#ifdef GPIO_BLINK
        pi_gpio_pin_write(PAD_GPIO_LED2, gpio_val);
#endif
        ret += example_entry();
#ifdef GPIO_BLINK
        gpio_val ^= 1;
        pi_time_wait_us(BLINK_DELAY_US);
#endif
    }

    // Exiting with LED high
    pi_gpio_pin_write(PAD_GPIO_LED2, 1);

    printf("Exiting example ReadFS\n");
    return 0;
}