一、簡介
在嵌入式領域,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);參數說明:
名字 | 描述 |
path | 文件路徑 |
oflag | 參考///utils/native/lite/include/utils_file.hO_RDONLY_FS:只讀O_WRONLY_FS:只寫O_RDWR_FS:讀寫O_CREAT_FS:如果沒有則創建O_EXCL_FS:如果沒有則創建;如有則不能打開O_TRUNC_FS:如果文件存在,則清空文件內容O_APPEND_FS:如果文件存在,則標記位置移動到文件最后 |
mode | 0 |
返回值為LOS_OK表示成功,其余為失敗。
2、HalFileClose()
關閉文件,類似于Linux的close函數。
int HalFileClose(int fd);參數說明:
名字 | 描述 |
fd | 文件句柄 |
返回值為LOS_OK表示成功,其余為失敗。
3、HalFileRead()
從文件中讀取一段內容,類似于Linux的read函數。
int HalFileRead(int fd, char* buf, unsigned int len);參數說明:
名字 | 描述 |
fd | 文件句柄 |
buf | 從文件讀取內容的緩沖區 |
len | 從文件讀取內容的大小 |
返回值為從文件讀取內容的大小,0或者小于0則為失敗。
4、HalFileWrite()
往文件寫入一段內容,類似于Linux的write函數。
int HalFileWrite(int fd, const char* buf, unsigned int len);參數說明:
名字 | 描述 |
fd | 文件句柄 |
buf | 需要寫入到文件的內容緩沖區 |
len | 需要寫入到文件的內容大小 |
返回值為成功寫入到文件的內容大小,0或者小于0則為失敗。
5、HalFileDelete()
刪除文件,類似于Linux的unlink函數。
int HalFileDelete(const char* path);參數說明:
名字 | 描述 |
path | 文件路徑 |
返回值為LOS_OK為成功,其余則為失敗。
6、HalFileStat()
獲取文件大小,類似于Linux的stat函數。
int HalFileStat(const char* path, unsigned int* fileSize);參數說明:
名字 | 描述 |
path | 文件路徑 |
fileSize | 文件內容大小 |
返回值為LOS_OK為成功,其余則為失敗。
7、HalFileSeek()
文件所在位置移動,類似于Linux的lseek函數。
int HalFileSeek(int fd, int offset, unsigned int whence);參數說明:
名字 | 描述 |
fd | 文件句柄 |
offset | 文件位置移動位數 |
whence | SEEK_SET_FS:從文件開頭移動 SEEK_CUR_FS:從文件當前位置移動 SEEK_END_FS:從文件結尾移動 |
返回值為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 -f4、燒寫固件
請參考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) =>好了,今天的課程就到這里,我們下次再見!
-
OpenHarmony
+關注
關注
33文章
3952瀏覽量
21102
發布評論請先 登錄
各智能化子系統為信息管理平臺預留接口要求
使用AXI4接口IP核進行DDR讀寫測試
飛凌嵌入式ElfBoard-系統應用編程之文件I/O
DMA硬件實現——讀寫實現
如何利用Verilog HDL在FPGA上實現SRAM的讀寫測試
基于小凌派RK2206開發板:OpenHarmony如何使用IoT接口控制FLASH外設
基于小凌派RK2206開發板:OpenHarmony如何使用IoT接口控制FLASH外設
基于小凌派RK2206開發板:OpenHarmony如何使用IoT接口控制UART外設
基于小凌派RK2206開發板:OpenHarmony如何使用IoT接口控制GPIO外設
基于OpenHarmony標準接口的文件讀寫實現案例
評論