RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于OpenHarmony3.1的LittleFS文件系統(tǒng)hdf驅(qū)動(dòng)實(shí)現(xiàn)

電子發(fā)燒友開(kāi)源社區(qū) ? 來(lái)源:未知 ? 作者:電子發(fā)燒友開(kāi)源社 ? 2022-09-30 18:32 ? 次閱讀

1.簡(jiǎn)介

LittleFS是一個(gè)小型的Flash文件系統(tǒng),它結(jié)合日志結(jié)構(gòu)(log-structured)文件系統(tǒng)和COW(copy-on-write)文件系統(tǒng)的思想,以日志結(jié)構(gòu)存儲(chǔ)元數(shù)據(jù),以COW結(jié)構(gòu)存儲(chǔ)數(shù)據(jù)。這種特殊的存儲(chǔ)方式,使LittleFS具有強(qiáng)大的掉電恢復(fù)能力(power-loss resilience)。分配COW數(shù)據(jù)塊時(shí)LittleFS采用了名為統(tǒng)計(jì)損耗均衡的動(dòng)態(tài)損耗均衡算法,使Flash設(shè)備的壽命得到有效保障。同時(shí)LittleFS針對(duì)資源緊缺的小型設(shè)備進(jìn)行設(shè)計(jì),具有極其有限的ROMRAM占用,并且所有RAM的使用都通過(guò)一個(gè)可配置的固定大小緩沖區(qū)進(jìn)行分配,不會(huì)隨文件系統(tǒng)的擴(kuò)大占據(jù)更多的系統(tǒng)資源。當(dāng)在一個(gè)資源非常緊缺的小型設(shè)備上,尋找一個(gè)具有掉電恢復(fù)能力并支持損耗均衡的Flash文件系統(tǒng)時(shí),LittleFS是一個(gè)比較好的選擇。

LittleFS在嵌入式開(kāi)發(fā)過(guò)程中經(jīng)常遇到,但是如何在OpenHarmony中使用呢?本文基于OpenHarmony 3.1Release + 小凌派-RK2206開(kāi)發(fā)板做LittleFS文件系統(tǒng)移植,現(xiàn)將相關(guān)移植經(jīng)驗(yàn)發(fā)布,分享給大家。文中如有問(wèn)題,請(qǐng)大家?guī)兔χ刚?/p>

2.LittleFS移植過(guò)程

本文基于OpenHarmony3.1Release做LittleFS移植,小凌派-RK2206開(kāi)發(fā)板內(nèi)部Flash有8MB大小,其中4~8MB區(qū)間為空閑區(qū)域。我將4M~5M作為L(zhǎng)ittleFS文件系統(tǒng)的/data目錄掛載硬件設(shè)備。具體移植過(guò)程主要如下所示:

1、hcs配置

1.1、hdf.hcs

創(chuàng)建/device/soc/rockchip/rk2206/hcs_config/hdf.hcs文件,具體如下:

  #include "device_info/device_info.hcs"
  #include "fs/fs_config.hcs"
  #include "gpio/gpio_config.hcs"
  #include "i2c/i2c_config.hcs"
  #include "spi/spi_config.hcs"
  root {
    module = "rockchip,rk2206_chip";
  }

(左右移動(dòng)查看全部?jī)?nèi)容)

如上所述,我將在device_info/device_info.hcs添加LittleFS設(shè)備,并在fs/fs_config.hcs添加LittleFS具體信息

1.2、BUILD.gn
新建//device/soc/rockchip/rk2206/hdf_config/BUILD.gn,具體代碼如下所示:

  import("http://drivers/adapter/khdf/liteos_m/hdf.gni")
  module_switch = defined(LOSCFG_DRIVERS_HDF)
  module_name = get_path_info(rebase_path("."), "name")
  hdf_driver(module_name) {
   hcs_sources = [ "hdf.hcs" ]
  }

(左右移動(dòng)查看全部?jī)?nèi)容)

上述代碼將在編譯OpenHarmony3.1Rlease時(shí),將編譯hdf.hcs。

1.3、device_info.hcs
創(chuàng)建/device/soc/rockchip/rk2206/hcs_config/device_info/device_info.hcs文件,在文件中添加LittleFS設(shè)備,具體代碼如下所示:

device_fs :: device {
     device0 :: deviceNode {
      policy = 0;
      priority = 5;
      permission = 0777;
      moduleName = "HDF_PLATFORM_FS_LITTLEFS";
      serviceName = "littlefs_config";
      deviceMatchAttr = "rockchip_rk2206_fs_littlefs";
  }
}

(左右移動(dòng)查看全部?jī)?nèi)容)

上述代碼表示建設(shè)一個(gè)設(shè)備驅(qū)動(dòng),該驅(qū)動(dòng)的模塊名稱(即moduleName)為“HDF_PLATFORM_FS_LITTLEFS”,OpenHamrony系統(tǒng)依據(jù)該名稱匹配驅(qū)動(dòng)程序;設(shè)備匹配信息(即deviceMatchAttr)添加小凌派開(kāi)發(fā)板Flash特殊信息(比如:分區(qū)信息,掛載目錄名、起始地址、結(jié)束地址等)。

1.4、fs_config.hcs

新建//device/soc/rockchip/rk2206/hdf_config/fs/fs_config.hcs文件,該文件主要寫(xiě)清楚設(shè)備掛載信息,具體如下:

root {
    platform {
      fs_config {
        template fs_controller {
          match_attr = "";
          mount_points = [];
          block_size = [];
          block_start = [];
          block_count = [];
        }


        fs_littefs :: fs_controller {
          match_attr = "rockchip_rk2206_fs_littlefs";
          mount_points = ["/data"];
          block_size = [4096];
          block_start = [1024];
          block_count = [256];
        }
      }
    }
  }

(左右移動(dòng)查看全部?jī)?nèi)容)

(1)points:掛載目錄。
(2)block_size:Flash的擦除塊大小。
(3)block_start:該掛載Flash區(qū)域的起始?jí)K地址,實(shí)際Flash地址為block_size * block_start。
(4)block_count:該掛載Flash區(qū)域的存儲(chǔ)塊總數(shù)。

注意:match_attr所表示的字符串要與device_info.hcs所表示的字符串要一致。

2、hdf驅(qū)動(dòng)
新建//device/soc/rockchip/rk2206/hdf_driver/fs文件夾,文件夾下創(chuàng)建2個(gè)文件,具體如下所示:

2.1、fs_driver.c
2.1.1、添加必要的頭文件

#include 
#include 
#include "los_config.h"
#include "hdf_log.h"
#include "hdf_device_desc.h"
#include "device_resource_if.h"
#include "osal_mem.h"
#include "lfs_api.h"

(左右移動(dòng)查看全部?jī)?nèi)容)

2.1.2、添加HDF驅(qū)動(dòng)

添加LittleFS匹配的hdf驅(qū)動(dòng),具體代碼如下所示:

static struct HdfDriverEntry g_fsDriverEntry = {
  .moduleVersion = 1,
  .moduleName = "HDF_PLATFORM_FS_LITTLEFS",
  .Bind = fs_driver_bind,
  .Init = fs_driver_init,
  .Release = fs_driver_release,
};

(左右移動(dòng)查看全部?jī)?nèi)容)

HDF_INIT(g_fsDriverEntry);

其中,moduleName必須要與device_info.hcs中的moduleName保持一致。

2.1.3、fs_driver_init函數(shù)

fs_driver_init為hdf驅(qū)動(dòng)加載函數(shù)。OpenHarmony啟動(dòng)時(shí),將根據(jù)hcs的編寫(xiě)匹配對(duì)應(yīng)的驅(qū)動(dòng)程序,并運(yùn)行fs_driver_init函數(shù)。該函數(shù)負(fù)責(zé):

(1)讀取hcs文件的配置參數(shù)。

(2)初始化Flash。

(3)適配LittleFS對(duì)應(yīng)的read、write、erase和sync函數(shù),并適配LittleFS相關(guān)參數(shù)。

(4)掛載LittleFS。

具體代碼如下所示:

static int32_t fs_driver_init(struct HdfDeviceObject *device)
{
   int result;
   int32_t ret;
   struct FileOpInfo *file_op_info = NULL;


   if (device == NULL) {
     PRINT_ERR("device is null
");
     return HDF_ERR_INVALID_OBJECT;
   }
   if (device->property == NULL)
   {
     PRINT_ERR("device is null
");
     return HDF_ERR_INVALID_OBJECT;
   }


   /* Flash設(shè)備初始化 */
   FlashInit();


/* 讀取hcS參數(shù) */
   ret = fs_driver_readdrs(device->property, &m_fs_cfg[0]);
   if (ret != HDF_SUCCESS)
   {
     PRINT_ERR("%s: fs_driver_readdrs faiLED(%d)
", ret);
     return ret;
   }
    
/* 適配LitteleFS對(duì)應(yīng)的函數(shù)和參數(shù) */
   for (int i = 0; i < sizeof(m_fs_cfg) / sizeof(m_fs_cfg[0]); i++) {
     if (m_fs_cfg[i].mount_point == NULL)
     {
       PRINT_LOG("m_fs_cfg[%d].mount_point is null
", i);
       continue;
     }


     m_fs_cfg[i].lfs_cfg.read = flash_littlefs_read;
     m_fs_cfg[i].lfs_cfg.prog = flash_littlefs_write;
     m_fs_cfg[i].lfs_cfg.erase = flash_littlefs_erase;
     m_fs_cfg[i].lfs_cfg.sync = flash_littlefs_sync;


     m_fs_cfg[i].lfs_cfg.read_size = 4;
     m_fs_cfg[i].lfs_cfg.prog_size = 4;
     m_fs_cfg[i].lfs_cfg.cache_size = 256;
     m_fs_cfg[i].lfs_cfg.lookahead_size = 64;
     m_fs_cfg[i].lfs_cfg.block_cycles = 1000;


     m_fs_cfg[i].lfs_cfg.file_max = LFS_FILE_MAX;
     m_fs_cfg[i].lfs_cfg.name_max = LFS_NAME_MAX;
      
/* 準(zhǔn)備掛載 */
     result = SetDefaultMountPath(i, m_fs_cfg[i].mount_point);
     if (result != VFS_OK)
     {
       PRINT_ERR("SetDefaultMountPath(%d, %d) failed(%d)
", i, m_fs_cfg[i].mount_point, result);
       continue;
     }
      
/* 掛載目錄 */
     result = mount(NULL, m_fs_cfg[i].mount_point, "littlefs", 0, &m_fs_cfg[i].lfs_cfg);
     printf("%s: mount fs on '%s' %s
", __func__, m_fs_cfg[i].mount_point, (result == 0) ? "succeed" : "failed");
     if (CheckPathIsMounted(m_fs_cfg[i].mount_point, &file_op_info) == TRUE) {
       int lfs_ret = lfs_mkdir(&file_op_info->lfsInfo, m_fs_cfg[i].mount_point);
       if (lfs_ret == LFS_ERR_OK) {
         PRINT_LOG("create root dir(%s) success.
", m_fs_cfg[i].mount_point);
       } else if (lfs_ret == LFS_ERR_EXIST) {
         PRINT_LOG("root dir(%s) exist.
", m_fs_cfg[i].mount_point);
       } else {
         PRINT_LOG("create root dir(%s) failed.", m_fs_cfg[i].mount_point);
       }
     }
  }
    
  return HDF_SUCCESS;
}

(左右移動(dòng)查看全部?jī)?nèi)容)

2.2、BUILD.gn

BUILD.gn負(fù)責(zé)將fs_driver.c編譯到內(nèi)核中,具體源代碼如下所示:

import("http://drivers/adapter/khdf/liteos_m/hdf.gni")
module_switch = defined(LOSCFG_SOC_SERIES_RK22XX) && defined(LOSCFG_DRIVERS_HDF_PLATFORM) && defined(LOSCFG_FS_LITTLEFS)
module_name = get_path_info(rebase_path("."), "name")
hdf_driver(module_name) {
 sources = [
   "fs_driver.c",
 ]
 include_dirs = [ "." ]
}

(左右移動(dòng)查看全部?jī)?nèi)容)

3、測(cè)試程序

我在main函數(shù)中添加一個(gè)任務(wù),負(fù)責(zé)每隔5秒讀寫(xiě)文件。具體代碼如下所示:

/* 文件系統(tǒng)測(cè)試 */
static void file_rw()
{
  static unsigned int cur = 0;
  char file_name[] = "/data/a.txt";
  int fd_w, fd_r;
  unsigned char buffer[256];
  /* 寫(xiě)操作 */
  fd_w = open(file_name, O_WRONLY | O_CREAT);
  if (fd_w == -1)
  {
    printf("write: %s open failed!
", file_name);
    return;
  }
  memset(buffer, 0, sizeof(buffer));
  snprintf(buffer, sizeof(buffer), "Hello World and %d
", cur++);
  printf("write: %s", buffer);
  write(fd_w, buffer, strlen(buffer));
  close(fd_w);


  /* 讀操作 */
  fd_r = open(file_name, O_RDONLY);
  if (fd_r == -1)
  {
    printf("read: %s open failed!
", file_name);
    return;
  }
  lseek(fd_r, 0, SEEK_SET);
  memset(buffer, 0, sizeof(buffer));
  read(fd_r, buffer, sizeof(buffer));
  printf("read: %s", buffer);
  close(fd_r);
}


static void IotProcess(void *arg)
{
  static const unsigned int SLEEP_MAXSEC = 5;


  while (1)
  {
    printf("%s: sleep %d sec!
", __func__, SLEEP_MAXSEC);


    /* 文件系統(tǒng)測(cè)試 */
    file_rw(); 


    LOS_Msleep(SLEEP_MAXSEC * 1000);
  }
}

(左右移動(dòng)查看全部?jī)?nèi)容)

3

結(jié)果

程序編譯燒寫(xiě)到開(kāi)發(fā)板后,按下開(kāi)發(fā)板的RESET按鍵,通過(guò)串口軟件查看日志如下:

[MAIN:D]Main: OpenHarmony start schedule...
Entering scheduler
IotProcess: sleep 5 sec!
write: Hello World and 0
read: Hello World and 0
IotProcess: sleep 5 sec!
write: Hello World and 1
read: Hello World and 1
IotProcess: sleep 5 sec!
write: Hello World and 2
read: Hello World and 2
......

(左右移動(dòng)查看全部?jī)?nèi)容)


聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • HDF框架
    +關(guān)注

    關(guān)注

    0

    文章

    9

    瀏覽量

    2764
  • OpenHarmony
    +關(guān)注

    關(guān)注

    25

    文章

    3713

    瀏覽量

    16254

原文標(biāo)題:基于OpenHarmony3.1的LittleFS文件系統(tǒng)hdf驅(qū)動(dòng)實(shí)現(xiàn)

文章出處:【微信號(hào):HarmonyOS_Community,微信公眾號(hào):電子發(fā)燒友開(kāi)源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    芯海科技系列OpenHarmony3.1芯片支持智慧生態(tài)構(gòu)建

    隨著OpenHarmony3.1的正式發(fā)布,芯??萍甲鳛?b class='flag-5'>OpenHarmony生態(tài)的重要參與者,及時(shí)推出了兩款與系統(tǒng)適配的新品:健康測(cè)量CS1262芯片和無(wú)線連接CST85F01模組,為智慧生態(tài)的構(gòu)建貢獻(xiàn)了芯海力量。
    的頭像 發(fā)表于 12-17 17:25 ?112次閱讀
    芯??萍枷盗?b class='flag-5'>OpenHarmony3.1</b>芯片支持智慧生態(tài)構(gòu)建

    stm32單片機(jī)基于rt-thread 的 littlefs 文件系統(tǒng) 的使用

    簡(jiǎn)介littlefs是ARM官方推出的,專為嵌入式系統(tǒng)設(shè)計(jì)的文件系統(tǒng),相比傳統(tǒng)的文件系統(tǒng),littlefs具有以下優(yōu)點(diǎn):1、自帶擦寫(xiě)均衡2、
    的頭像 發(fā)表于 11-06 08:04 ?615次閱讀
    stm32單片機(jī)基于rt-thread 的 <b class='flag-5'>littlefs</b> <b class='flag-5'>文件系統(tǒng)</b> 的使用

    Linux根文件系統(tǒng)的掛載過(guò)程

    Linux根文件系統(tǒng)(rootfs)是Linux系統(tǒng)中所有其他文件系統(tǒng)和目錄的起點(diǎn),它是內(nèi)核啟動(dòng)時(shí)掛載的第一個(gè)文件系統(tǒng)
    的頭像 發(fā)表于 10-05 16:50 ?402次閱讀

    小型文件系統(tǒng)如何選擇?FatFs和LittleFs優(yōu)缺點(diǎn)比較

    和刪除文件實(shí)現(xiàn)了數(shù)據(jù)的持久化存儲(chǔ)和分層次的目錄結(jié)構(gòu)。文件系統(tǒng)的存在極大地簡(jiǎn)化了數(shù)據(jù)管理任務(wù),提升了系統(tǒng)整體的穩(wěn)定性和便利性,對(duì)于系統(tǒng)配置、
    的頭像 發(fā)表于 09-29 16:14 ?1596次閱讀
    小型<b class='flag-5'>文件系統(tǒng)</b>如何選擇?FatFs和<b class='flag-5'>LittleFs</b>優(yōu)缺點(diǎn)比較

    [2K300適配OpenharmonyV4.1]根文件系統(tǒng)制作請(qǐng)教

    文件系統(tǒng)rootfs.img燒錄到2k300上,燒錄失敗。對(duì)比2k300開(kāi)源資料中的Openharmony 文件系統(tǒng),該文件系統(tǒng)為ext4格式,但是2k500編譯出來(lái)的為Ubifs
    發(fā)表于 09-11 11:18

    如何修改buildroot和debian文件系統(tǒng)

    本文檔主要介紹在沒(méi)有編譯環(huán)境的情況下,如何修改buildroot和debian文件系統(tǒng)方法,如在buildroot文件系統(tǒng)中添加文件、修改目錄等文件操作,在debian
    的頭像 發(fā)表于 07-22 17:46 ?457次閱讀
    如何修改buildroot和debian<b class='flag-5'>文件系統(tǒng)</b>

    linux--sysfs文件系統(tǒng)

    sysfs文件系統(tǒng) sysfs,全稱為System Filesystem,是一個(gè)由Linux內(nèi)核實(shí)現(xiàn)的虛擬文件系統(tǒng)。它扮演著一個(gè)橋梁的角色,將內(nèi)核中的設(shè)備和驅(qū)動(dòng)程序信息以
    的頭像 發(fā)表于 07-08 11:37 ?841次閱讀
    linux--sysfs<b class='flag-5'>文件系統(tǒng)</b>

    esp32s2寫(xiě)文件系統(tǒng)時(shí)io外部中斷觸發(fā)不及時(shí),怎么解決?

    芯片esp32s2,idf release v4.4,目前問(wèn)題,io配置為邊沿觸發(fā),需要采集上升沿下降沿之間的脈沖寬度,假如一個(gè)40ms的脈沖,在寫(xiě)文件系統(tǒng)時(shí)脈沖采集到的寬度為10-20ms,不寫(xiě)文件系統(tǒng)沒(méi)問(wèn)題,文件系統(tǒng)使用FA
    發(fā)表于 06-12 08:29

    如何將Littlefs安裝到通過(guò)qspi連接到電路板的外部串行閃存上?

    我正試圖在 XMC7100 V1.1 中的 qspi 外部串行閃存上閃存 littlefs 文件系統(tǒng)。 我看到庫(kù)中的 mtb-littlefs 不包括在 XMC7100 套件中。 如果我下載任何
    發(fā)表于 05-27 06:03

    【嵌入式SD NAND】基于FATFS/Littlefs文件系統(tǒng)的日志框架實(shí)現(xiàn)

    文章目錄 【嵌入式】基于FATFS/Littlefs文件系統(tǒng)的日志框架實(shí)現(xiàn) 1. 概述 2. 設(shè)計(jì)概要 3. 設(shè)計(jì)實(shí)現(xiàn) 3.1 初始化 `i
    的頭像 發(fā)表于 03-14 18:13 ?1053次閱讀
    【嵌入式SD NAND】基于FATFS/<b class='flag-5'>Littlefs</b><b class='flag-5'>文件系統(tǒng)</b>的日志框架<b class='flag-5'>實(shí)現(xiàn)</b>

    【嵌入式SD NAND】基于FATFS/Littlefs文件系統(tǒng)的日志框架實(shí)現(xiàn)

    文章目錄 【嵌入式】基于FATFS/Littlefs文件系統(tǒng)的日志框架實(shí)現(xiàn) 概述 設(shè)計(jì)概要 設(shè)計(jì)實(shí)現(xiàn) 3.1 初始化 init 3.2 日志
    發(fā)表于 03-14 18:12

    【嵌入式SD NAND】基于FATFS/Littlefs文件系統(tǒng)的日志框架實(shí)現(xiàn)

    文章目錄【嵌入式】基于FATFS/Littlefs文件系統(tǒng)的日志框架實(shí)現(xiàn)1.概述2.設(shè)計(jì)概要3.設(shè)計(jì)實(shí)現(xiàn)3.1初始化`init`3.2日志寫(xiě)
    的頭像 發(fā)表于 03-14 18:12 ?1156次閱讀
    【嵌入式SD NAND】基于FATFS/<b class='flag-5'>Littlefs</b><b class='flag-5'>文件系統(tǒng)</b>的日志框架<b class='flag-5'>實(shí)現(xiàn)</b>

    Linux系統(tǒng)如何擴(kuò)展文件系統(tǒng)

    當(dāng)數(shù)據(jù)盤(pán)沒(méi)有創(chuàng)建分區(qū),只在設(shè)備上創(chuàng)建了文件系統(tǒng)。或者格式化了硬盤(pán),就直接mount上系統(tǒng)使用。
    的頭像 發(fā)表于 02-21 09:53 ?834次閱讀

    鴻蒙輕內(nèi)核源碼分析:虛擬文件系統(tǒng) VFS

    VFS(Virtual File System)是文件系統(tǒng)的虛擬層,它不是一個(gè)實(shí)際的文件系統(tǒng),而是一個(gè)異構(gòu)文件系統(tǒng)之上的軟件粘合層,為用戶提供統(tǒng)一的類(lèi) Unix 文件操作接口。由于不同
    的頭像 發(fā)表于 02-18 14:50 ?805次閱讀

    LittleFS是否可以應(yīng)用于SD卡中呢?

    LittleFS是一個(gè)應(yīng)用于單片機(jī)內(nèi)部flash和外掛NOR flash的文件系統(tǒng)。
    的頭像 發(fā)表于 12-28 16:41 ?4531次閱讀
    <b class='flag-5'>LittleFS</b>是否可以應(yīng)用于SD卡中呢?
    RM新时代网站-首页