天天看點

基于OpenHarmony标準接口的檔案讀寫實作案例

一、簡介

在嵌入式領域,FLASH是一種常用的儲存設備,Flash閃存作為嵌入式系統的主要儲存設備有其自身的特性。Fash的寫入操作隻能把對應位置的1修改成0,而不能把0修改為1,而擦除Fash就是把對應存儲塊的内容恢複為1。是以,一般情況下向Fash寫入内容時,需要先擦除對應的存儲區間,這種擦除是以塊(Bock)為機關進行的。閃存主要有NOR和NAND兩種技術。因為Flash存儲器的擦寫次數是有限的,NAND閃存還有特殊的硬體接口和讀寫時序,于是就出現了專門針對FLASH的檔案系統。比較常用的有jffs2,yaffs2,logfs,ubifs。本文基于小淩派-RK2206開發闆 + OpenHarmony輕量級作業系統 + LitteFS檔案系統,通過hal_file标準接口實作對Flash讀寫功能。

二、hal_file标準接口

頭檔案://utils/native/lite/hals/file/hal_file.h

1、HalFileOpen()

打開/建立檔案,類似于Linux的open函數。

int HalFileOpen(const char *path, int oflag, int mode);
           

參數說明:

基于OpenHarmony标準接口的檔案讀寫實作案例

傳回值為LOS_OK表示成功,其餘為失敗。

2、HalFileClose()

關閉檔案,類似于Linux的close函數。

int HalFileClose(int fd);

參數說明:

基于OpenHarmony标準接口的檔案讀寫實作案例

傳回值為LOS_OK表示成功,其餘為失敗。

3、HalFileRead()

從檔案中讀取一段内容,類似于Linux的read函數。

int HalFileRead(int fd, char* buf, unsigned int len);
           

參數說明:

基于OpenHarmony标準接口的檔案讀寫實作案例

傳回值為從檔案讀取内容的大小,0或者小于0則為失敗。

4、HalFileWrite()

往檔案寫入一段内容,類似于Linux的write函數。

int HalFileWrite(int fd, const char* buf, unsigned int len);
           

參數說明:

基于OpenHarmony标準接口的檔案讀寫實作案例

傳回值為成功寫入到檔案的内容大小,0或者小于0則為失敗。

5、HalFileDelete()

删除檔案,類似于Linux的unlink函數。

int HalFileDelete(const char* path);
           

參數說明:

基于OpenHarmony标準接口的檔案讀寫實作案例

傳回值為LOS_OK為成功,其餘則為失敗。

6、HalFileStat()

擷取檔案大小,類似于Linux的stat函數。

int HalFileStat(const char* path, unsigned int* fileSize);
           

參數說明:

基于OpenHarmony标準接口的檔案讀寫實作案例

傳回值為LOS_OK為成功,其餘則為失敗。

7、HalFileSeek()

檔案所在位置移動,類似于Linux的lseek函數。

int HalFileSeek(int fd, int offset, unsigned int whence);
           

參數說明:

基于OpenHarmony标準接口的檔案讀寫實作案例

傳回值為LOS_OK為成功,其餘則為失敗。

三、程式設計

本例程示範如何在小淩派-RK2206開發闆上使用鴻蒙LiteOS-M核心接口,進行檔案讀寫開發。例程流程如下所示:

(1)建立一個檔案;

(2)每5秒進行1次檔案讀寫操作;

(3)檔案辨別移動到檔案起始處,讀檔案内容,并列印;

(4)檔案辨別移動到檔案起始處,寫檔案内容;

(5)循環上述的第2~4步驟。

1、任務建立代碼分析

在file_example函數中通過LOS_TaskCreate函數建立一個線程:hal_file_thread。

void file_example()
{
    unsigned int thread_id;
    TSK_INIT_PARAM_S task = {0};
    unsigned int ret = LOS_OK;

    task.pfnTaskEntry = (TSK_ENTRY_FUNC)hal_file_thread;
    task.uwStackSize = 1024 * 10;
    task.pcName = "hal_file_thread";
    task.usTaskPrio = 25;
    ret = LOS_TaskCreate(&thread_id, &task);
    if (ret != LOS_OK)
    {
        printf("Falied to create hal_file_thread ret:0x%x\n", ret);
        return;
    }
}

APP_FEATURE_INIT(file_example);
           

2. 檔案讀寫代碼分析

hal_file_thread函數負責打開檔案,每5秒移動到檔案頭讀取資料,再移動到檔案頭寫入一段内容,重複以上流程。

void hal_file_thread()
{
    int fd;
    char buffer[1024];
    int read_length, write_length;
    int current = 0;

    /* 打開檔案,如果沒有該檔案就建立,如有該檔案則打開
     * O_TRUNC_FS => 清空檔案内容
     */
    //fd = HalFileOpen(FILE_NAME, O_RDWR_FS | O_CREAT_FS, 0);
    fd = HalFileOpen(FILE_NAME, O_RDWR_FS | O_CREAT_FS | O_TRUNC_FS, 0);
    if (fd == -1)
    {
        printf("%s HalFileOpen failed!\n", FILE_NAME);
        return;
    }

    while (1)
    {
        /* 檔案位置移動到檔案開始位置 */
        HalFileSeek(fd, 0, SEEK_SET);
        memset(buffer, 0, sizeof(buffer));
        /* 讀取檔案内容 */
        read_length = HalFileRead(fd, buffer, sizeof(buffer));
        printf("read: \n");
        printf("    length = %d\n", read_length);
        printf("    content = %s\n", buffer);

        /* 檔案位置移動到檔案開始位置 */
        HalFileSeek(fd, 0, SEEK_SET);
        memset(buffer, 0, sizeof(buffer));
        snprintf(buffer, sizeof(buffer), "Hello World(%d) => ", current);
        /* 寫入檔案 */
        write_length = HalFileWrite(fd, buffer, strlen(buffer));

        current++;
        LOS_Msleep(5000);
    }

    HalFileClose(fd);
}
           

四、編譯過程

1、搭建和下載下傳源代碼

我已将OpenHarmony源代碼上傳到Gitee社群中,大家可以根據以下網址下載下傳。

https://gitee.com/Lockzhiner-Electronics/lockzhiner-rk2206-openharmony3.0lts

注意:編譯環境可根據以下網址來操作:https://gitee.com/Lockzhiner-Electronics/lockzhiner-rk2206-openharmony3.0lts/blob/master/vendor/lockzhiner/rk2206/README_zh.md

2、修改編譯腳本

修改 vendor/lockzhiner/rk2206/sample 路徑下 BUILD.gn 檔案,指定 a7_hal_file 參與編譯。

"./a7_hal_file:hal_file_example",

修改 device/lockzhiner/rk2206/sdk_liteos 路徑下 Makefile 檔案,添加 -lhal_file_example 參與編譯。

apps_LIBS = -lhal_file_example

3、編譯固件

hb set -root .
hb set
hb build -f
           

4、燒寫固件

請參考Gitee網址的說明手冊(“燒錄列印”章節):https://gitee.com/Lockzhiner-Electronics/lockzhiner-rk2206-openharmony3.0lts/blob/master/device/rockchip/README_zh.md

五、實驗結果

程式編譯燒寫到開發闆後,按下開發闆的RESET按鍵,通過序列槽軟體檢視日志如下:

HalFileInit: Flash Init Successful!
read:
    length = 0
    content =
read:
    length = 18
    content = Hello World(0) =>
read:
    length = 18
content = Hello World(1) =>
           

好了,今天的課程就到這裡,我們下次再見!