Announcements

Help us improve the Power & Sensing Selection Guide. Share feedback

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
bluefish97
Level 2
Level 2
10 sign-ins 5 questions asked 5 replies posted

Hi, I tried to implement the mtb-littlefs in my xmc7100D board  with few modification to mq serial-read/write program: But I am encountering an error: could you tell me why I am unable to do "

lfs_file_read(lfs, &file, &boot_count, sizeof(boot_count));

"

My COM Port:

PrasadA_0-1713941252904.png

in my lfs.c:

 

lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
        void *buffer, lfs_size_t size) {
    int err = LFS_LOCK(lfs->cfg);
    if (err) {
        return err;
    }
    LFS_TRACE("lfs_file_read(%p, %p, %p, %"PRIu32")",
            (void*)lfs, (void*)file, buffer, size);
    printf("lfs_file_read(%p, %p, %p, %"PRIu32")",
                (void*)lfs, (void*)file, buffer, size);
    LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));

    lfs_ssize_t res = lfs_file_rawread(lfs, file, buffer, size);

    LFS_TRACE("lfs_file_read -> %"PRId32, res);
    LFS_UNLOCK(lfs->cfg);
    return res;
}

 

How do I solve the LS_ASSERT function from failing?

Also how do I verify little_fs is not mounted on the internal flash but on the inbuild external flash memory.

Best,

PrasadA

 

0 Likes
1 Solution
3 Replies
Yuvraj
Moderator
Moderator
Moderator
First question asked 250 replies posted 25 likes received

Hi,

May I know which flash family you are using?

Regards,

Yuvraj 

0 Likes

The flash is the inbuild external flash in XMC7100D: 

PrasadA_0-1713944653538.png

I am using the library: mtb-little_fs (for psoc-6) slightly modified for XMC71000D.

 

main.c:

/*******************************************************************************
* File Name: main.c
*
* Description: This is the source code for the Serial Flash Read and Write example
* for ModusToolbox.
*
* Related Document: See README.md
*
*
********************************************************************************
* Copyright 2018-2024, Cypress Semiconductor Corporation (an Infineon company) or
* an affiliate of Cypress Semiconductor Corporation.  All rights reserved.
*
* This software, including source code, documentation and related
* materials ("Software") is owned by Cypress Semiconductor Corporation
* or one of its affiliates ("Cypress") and is protected by and subject to
* worldwide patent protection (United States and foreign),
* United States copyright laws and international treaty provisions.
* Therefore, you may use this Software only as provided in the license
* agreement accompanying the software package from which you
* obtained this Software ("EULA").
* If no EULA applies, Cypress hereby grants you a personal, non-exclusive,
* non-transferable license to copy, modify, and compile the Software
* source code solely for use in connection with Cypress's
* integrated circuit products.  Any reproduction, modification, translation,
* compilation, or representation of this Software except as specified
* above is prohibited without the express written permission of Cypress.
*
* Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress
* reserves the right to make changes to the Software without notice. Cypress
* does not assume any liability arising out of the application or use of the
* Software or any product or circuit described in the Software. Cypress does
* not authorize its products for use in any products where a malfunction or
* failure of the Cypress product may reasonably be expected to result in
* significant property damage, injury or death ("High Risk Product"). By
* including Cypress's product in a High Risk Product, the manufacturer
* of such system or application assumes all risk of such use and in doing
* so agrees to indemnify Cypress against all liability.
*******************************************************************************/

/*******************************************************************************
* Header Files
*******************************************************************************/
#include "cycfg_qspi_memslot.h"
#include "cyhal.h"
#include "cybsp.h"
#include "cy_retarget_io.h"
#include "cy_serial_flash_qspi.h"
#include <inttypes.h>
#include <string.h>
#include "lfs.h"
#include "lfs_spi_flash_bd.h"
/* FreeRTOS headers */
#include "FreeRTOS.h"
#include "task.h"
/*******************************************************************************
* Macros
*******************************************************************************/
#define PACKET_SIZE             (64u)     /* Memory Read/Write size */

/* Used when an array of data is printed on the console */
#define NUM_BYTES_PER_LINE      (16u)
#define LED_TOGGLE_DELAY_MSEC   (1000u)   /* LED blink delay */
#define MEM_SLOT_NUM            (0u)      /* Slot number of the memory to use */
#define QSPI_BUS_FREQUENCY_HZ   (50000000lu)
#define FLASH_DATA_AFTER_ERASE  (0xFFu)   /* Flash data after erase */

#define STORAGE_DEVICE_SD_CARD              (0)

#define LITTLEFS_TASK_STACK_SIZE            (512U)
#define USER_BUTTON_INTERRUPT_PRIORITY      (7U)

/* Debounce delay for the user button. */
#define DEBOUNCE_DELAY_MS                   (50U)
/*******************************************************************************
* Global Variables
*******************************************************************************/
static TaskHandle_t littlefs_task_handle;
static cyhal_gpio_callback_data_t user_btn_callback_data;

/* This enables RTOS aware debugging */
static volatile int uxTopUsedPriority;


/*******************************************************************************
* Function Prototypes
*******************************************************************************/
static void user_button_interrupt_handler(void *handler_arg, cyhal_gpio_event_t event);

/*******************************************************************************
* Function Definitions
*******************************************************************************/

/*******************************************************************************
* Function Name: check_status
********************************************************************************
* Summary:
*  Prints the message, indicates the non-zero status by turning the LED on, and
*  asserts the non-zero status.
*
* Parameters:
*  message - message to print if status is non-zero.
*  status - status for evaluation.
*
* Return:
*  void
*
*******************************************************************************/
void check_status(char *message, uint32_t status)
{
    if (0u != status)
    {
        printf("\r\n=====================================================\r\n");
        printf("\nFAIL: %s\r\n", message);
        printf("Error Code: 0x%08"PRIX32"\n", status);
        printf("\r\n=====================================================\r\n");

        /* On failure, turn the LED ON */
        cyhal_gpio_write(CYBSP_USER_LED, CYBSP_LED_STATE_ON);
        while(true); /* Wait forever here when error occurs. */
    }
}


/*******************************************************************************
* Function Name: print_array
********************************************************************************
* Summary:
*  Prints the content of the buffer to the UART console.
*
* Parameters:
*  message - message to print before array output
*  buf - buffer to print on the console.
*  size - size of the buffer.
*
* Return:
*  void
*
*******************************************************************************/
void print_array(char *message, uint8_t *buf, uint32_t size)
{
    printf("\r\n%s (%"PRIu32" bytes):\r\n", message, size);
    printf("-------------------------\r\n");

    for (uint32_t index = 0; index < size; index++)
    {
        printf("0x%02X ", buf[index]);

        if (0u == ((index + 1) % NUM_BYTES_PER_LINE))
        {
            printf("\r\n");
        }
    }
}
static void user_button_interrupt_handler(void *handler_arg, cyhal_gpio_event_t event)
{
    (void) handler_arg;
    (void) event;

    BaseType_t higher_priority_task_woken = pdFALSE;
    vTaskNotifyGiveFromISR(littlefs_task_handle, &higher_priority_task_woken);

    /* Yield if xHigherPriorityTaskWoken was set to true */
    portYIELD_FROM_ISR( higher_priority_task_woken );
}

static void print_block_device_parameters(struct lfs_config *lfs_cfg)
{
    printf("Number of blocks: %"PRIu32"\n", lfs_cfg->block_count);
    printf("Erase block size: %"PRIu32" bytes\n", lfs_cfg->block_size);
    printf("Prog size: %"PRIu32" bytes\n\n", lfs_cfg->prog_size);
}
static void increment_boot_count(lfs_t *lfs, struct lfs_config *lfs_cfg)
{
    uint32_t boot_count = 0;
    lfs_file_t file;

    /* Mount the filesystem */
    int err = lfs_mount(lfs, lfs_cfg);

    /* Reformat if we cannot mount the filesystem.
     * This should only happen when littlefs is set up on the storage device for
     * the first time.
     */
    if (err) {
        printf("\nError in mounting. This could be the first time littlefs is used on the storage device.\n");
        printf("Formatting the block device...\n\n");

        lfs_format(lfs, lfs_cfg);
        lfs_mount(lfs, lfs_cfg);
    }

    /* Read the current boot count. */
    lfs_file_open(lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT);
    lfs_file_read(lfs, &file, &boot_count, sizeof(boot_count));

    /* Update the boot count. */
    boot_count += 1;
    lfs_file_rewind(lfs, &file);
    lfs_file_write(lfs, &file, &boot_count, sizeof(boot_count));

    /* The storage is not updated until the file_sd is closed successfully. */
    lfs_file_close(lfs, &file);

    /* Release any resources we were using. */
    lfs_unmount(lfs);

    /* Print the boot count. */
    printf("boot_count: %"PRIu32"\n\n", boot_count);
}
static void littlefs_task(void* arg)
{
    cy_rslt_t result;
    lfs_t lfs;
    struct lfs_config lfs_cfg;

    /* Step 1: Get the default configuration for the block device.
     * Step 2: Initialize the lfs_config structure to zero (not required if it
     *         is a global variable)
     * Step 3: Create the block device
     * Step 4: Print the block device parameters such as erase block size
     * Step 5: Perform file system operations to increment the boot count
     */

#if(STORAGE_DEVICE_SD_CARD)
    lfs_sd_bd_config_t sd_bd_cfg;

    printf("Incrementing the boot count on SD Card...\n\n");

    /* Get the default configuration for the SD card block device. */
    lfs_sd_bd_get_default_config(&sd_bd_cfg);

    /* Initialize the pointers in lfs_cfg to NULL. */
    memset(&lfs_cfg, 0, sizeof(lfs_cfg));

    /* Create the SD card block device. */
    result = lfs_sd_bd_create(&lfs_cfg, &sd_bd_cfg);
    check_status("Creating SD card block device failed", result);
#else
    lfs_spi_flash_bd_config_t spi_flash_bd_cfg;

    printf("\nIncrementing the boot count on SPI flash...\n\n");

    /* Get the default configuration for the SPI flash block device. */
    lfs_spi_flash_bd_get_default_config(&spi_flash_bd_cfg);

    /* Initialize the pointers in lfs_cfg to NULL. */
    memset(&lfs_cfg, 0, sizeof(lfs_cfg));

    /* Create the SPI flash block device. */
    result = lfs_spi_flash_bd_create(&lfs_cfg, &spi_flash_bd_cfg);
    check_status("Creating SPI flash block device failed", result);
#endif /* #if(STORAGE_DEVICE_SD_CARD) */

    print_block_device_parameters(&lfs_cfg);
    increment_boot_count(&lfs, &lfs_cfg);

    /* Enable the user button interrupt */
    cyhal_gpio_enable_event(CYBSP_USER_BTN, CYHAL_GPIO_IRQ_FALL, USER_BUTTON_INTERRUPT_PRIORITY, true);

    printf("Press the user button to format the block device or press reset to increment the boot count again\n\n");

    /* Wait until the user button press is notified through the interrupt */
    while (true)
    {
        if(1lu == ulTaskNotifyTake(pdTRUE, portMAX_DELAY))
        {
            /* Debounce the button press. */
            vTaskDelay(pdMS_TO_TICKS(DEBOUNCE_DELAY_MS));

            if(!cyhal_gpio_read(CYBSP_USER_BTN)) { break; }
        }
    }

    /* User button is pressed. Format the block device. */
    printf("Formatting the block device...\n");
    lfs_format(&lfs, &lfs_cfg);
    printf("Formatting completed...\n");

#if(STORAGE_DEVICE_SD_CARD)
    lfs_sd_bd_destroy(&lfs_cfg);
#else
    lfs_spi_flash_bd_destroy(&lfs_cfg);
#endif /* #if(STORAGE_DEVICE_SD_CARD) */

    printf("Press reset to continue...\n");
}
/*******************************************************************************
* Function Name: main
********************************************************************************
* Summary:
*  This is the main function for CM4 CPU. It does...
*     1. Initializes UART for console output and SMIF for interfacing a QSPI
*       flash.
*     2. Performs erase followed by write and verifies the written data by
*       reading it back.
*
* Parameters:
*  void
*
* Return:
*  int
*
*******************************************************************************/
int main(void)
{
    cy_rslt_t result;

    /* This enables RTOS aware debugging in OpenOCD */
    uxTopUsedPriority = configMAX_PRIORITIES - 1;

    /* Initialize the device and board peripherals */
    result = cybsp_init() ;
    CY_ASSERT (result == CY_RSLT_SUCCESS);

    /* Initialize retarget-io to use the debug UART port */
    result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, CY_RETARGET_IO_BAUDRATE);
    CY_ASSERT (result == CY_RSLT_SUCCESS);

    /* Initialize the user button used for erasing the block device. */
    result = cyhal_gpio_init(CYBSP_USER_BTN, CYHAL_GPIO_DIR_INPUT, CYHAL_GPIO_DRIVE_PULLUP, CYBSP_BTN_OFF);
    CY_ASSERT (result == CY_RSLT_SUCCESS);

    /* Configure GPIO interrupt */
    user_btn_callback_data.callback = user_button_interrupt_handler;

    /* Configure & the user button interrupt */
    cyhal_gpio_register_callback(CYBSP_USER_BTN, &user_btn_callback_data);

    /* Enable global interrupts */
    __enable_irq();

    /* \x1b[2J\x1b[;H - ANSI ESC sequence for clear screen */
    printf("\x1b[2J\x1b[;H");

    printf("************* "
           "Littlefs File System on SD Card and QSPI NOR Flash "
           "************* \n\n");

    /* Create the user tasks. See the respective task definition for more
     * details of these tasks.
     */
    xTaskCreate(littlefs_task, "Littlefs Task", LITTLEFS_TASK_STACK_SIZE,
                NULL, (configMAX_PRIORITIES - 1), &littlefs_task_handle);

    /* Start the RTOS scheduler. This function should never return */
    vTaskStartScheduler();

    (void) result; /* To avoid compiler warning */

    for (;;)
    {
    }
}


/* [] END OF FILE */

Best,

PA

0 Likes
Yuvraj
Moderator
Moderator
Moderator
First question asked 250 replies posted 25 likes received

Hi,

Looks like your query is already being discussed in the thread:  https://community.infineon.com/t5/XMC/Mtb-littlefs-in-XMC7100-external-flash/td-p/743057

You will get further assistance in parent thread https://community.infineon.com/t5/XMC/Mtb-littlefs-in-XMC7100-external-flash/td-p/743057

Regards,

Yuvraj