一、簡介
在嵌入式領域,F(xiàn)LASH是一種常用的存儲設備,F(xiàn)lash閃存作為嵌入式系統(tǒng)的主要存儲設備有其自身的特性。Fash的寫入操作只能把對應位置的1修改成0,而不能把0修改為1,而擦除Fash就是把對應存儲塊的內容恢復為1。因此,一般情況下向Fash寫入內容時,需要先擦除對應的存儲區(qū)間,這種擦除是以塊(Bock)為單位進行的。閃存主要有NOR和NAND兩種技術。因為Flash存儲器的擦寫次數(shù)是有限的,NAND閃存還有特殊的硬件接口和讀寫時序,于是就出現(xiàn)了專門針對FLASH的文件系統(tǒng)。比較常用的有jffs2,yaffs2,logfs,ubifs。本文基于小凌派-RK2206開發(fā)板 + OpenHarmony輕量級操作系統(tǒng) + LitteFS文件系統(tǒng),通過hal_file標準接口實現(xiàn)對Flash讀寫功能。
二、hal_file標準接口
頭文件://utils/native/lite/hals/file/hal_file.h
1、HalFileOpen()
打開/創(chuàng)建文件,類似于Linux的open函數(shù)。
int HalFileOpen(const char *path, int oflag, int mode);
參數(shù)說明:
名字 | 描述 |
path | 文件路徑 |
oflag | 參考///utils/native/lite/include/utils_file.hO_RDONLY_FS:只讀O_WRONLY_FS:只寫O_RDWR_FS:讀寫O_CREAT_FS:如果沒有則創(chuàng)建O_EXCL_FS:如果沒有則創(chuàng)建;如有則不能打開O_TRUNC_FS:如果文件存在,則清空文件內容O_APPEND_FS:如果文件存在,則標記位置移動到文件最后 |
mode | 0 |
返回值為LOS_OK表示成功,其余為失敗。
2、HalFileClose()
關閉文件,類似于Linux的close函數(shù)。
int HalFileClose(int fd);
參數(shù)說明:
名字 | 描述 |
fd | 文件句柄 |
返回值為LOS_OK表示成功,其余為失敗。
3、HalFileRead()
從文件中讀取一段內容,類似于Linux的read函數(shù)。
int HalFileRead(int fd, char* buf, unsigned int len);
參數(shù)說明:
名字 | 描述 |
fd | 文件句柄 |
buf | 從文件讀取內容的緩沖區(qū) |
len | 從文件讀取內容的大小 |
返回值為從文件讀取內容的大小,0或者小于0則為失敗。
4、HalFileWrite()
往文件寫入一段內容,類似于Linux的write函數(shù)。
int HalFileWrite(int fd, const char* buf, unsigned int len);
參數(shù)說明:
名字 | 描述 |
fd | 文件句柄 |
buf | 需要寫入到文件的內容緩沖區(qū) |
len | 需要寫入到文件的內容大小 |
返回值為成功寫入到文件的內容大小,0或者小于0則為失敗。
5、HalFileDelete()
刪除文件,類似于Linux的unlink函數(shù)。
int HalFileDelete(const char* path);
參數(shù)說明:
名字 | 描述 |
path | 文件路徑 |
返回值為LOS_OK為成功,其余則為失敗。
6、HalFileStat()
獲取文件大小,類似于Linux的stat函數(shù)。
int HalFileStat(const char* path, unsigned int* fileSize);
參數(shù)說明:
名字 | 描述 |
path | 文件路徑 |
fileSize | 文件內容大小 |
返回值為LOS_OK為成功,其余則為失敗。
7、HalFileSeek()
文件所在位置移動,類似于Linux的lseek函數(shù)。
int HalFileSeek(int fd, int offset, unsigned int whence);
參數(shù)說明:
名字 | 描述 |
fd | 文件句柄 |
offset | 文件位置移動位數(shù) |
whence | SEEK_SET_FS:從文件開頭移動 SEEK_CUR_FS:從文件當前位置移動 SEEK_END_FS:從文件結尾移動 |
返回值為LOS_OK為成功,其余則為失敗。
三、程序設計
本例程演示如何在小凌派-RK2206開發(fā)板上使用鴻蒙LiteOS-M內核接口,進行文件讀寫開發(fā)。例程流程如下所示:
(1)創(chuàng)建一個文件;
(2)每5秒進行1次文件讀寫操作;
(3)文件標識移動到文件起始處,讀文件內容,并打印;
(4)文件標識移動到文件起始處,寫文件內容;
(5)循環(huán)上述的第2~4步驟。
1、任務創(chuàng)建代碼分析
在file_example函數(shù)中通過LOS_TaskCreate函數(shù)創(chuàng)建一個線程: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函數(shù)負責打開文件,每5秒移動到文件頭讀取數(shù)據(jù),再移動到文件頭寫入一段內容,重復以上流程。
void hal_file_thread()
{
int fd;
char buffer[1024];
int read_length, write_length;
int current = 0;
/* 打開文件,如果沒有該文件就創(chuàng)建,如有該文件則打開
* 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社區(qū)中,大家可以根據(jù)以下網(wǎng)址下載。
https://gitee.com/Lockzhiner-Electronics/lockzhiner-rk2206-openharmony3.0lts
注意:編譯環(huán)境可根據(jù)以下網(wǎng)址來操作: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網(wǎng)址的說明手冊(“燒錄打印”章節(jié)):https://gitee.com/Lockzhiner-Electronics/lockzhiner-rk2206-openharmony3.0lts/blob/master/device/rockchip/README_zh.md
五、實驗結果
程序編譯燒寫到開發(fā)板后,按下開發(fā)板的RESET按鍵,通過串口軟件查看日志如下:
HalFileInit: Flash Init Successful!
read:
length = 0
content =
read:
length = 18
content = Hello World(0) =>
read:
length = 18
content = Hello World(1) =>
好了,今天的課程就到這里,我們下次再見!
-
OpenHarmony
+關注
關注
25文章
3744瀏覽量
16536
發(fā)布評論請先 登錄
相關推薦
評論