基于OpenHarmony標(biāo)準(zhǔn)接口的文件讀寫實(shí)現(xiàn)案例
??想了解更多關(guān)于開源的內(nèi)容,請?jiān)L問:??
一、簡介
在嵌入式領(lǐng)域,F(xiàn)LASH是一種常用的存儲(chǔ)設(shè)備,F(xiàn)lash閃存作為嵌入式系統(tǒng)的主要存儲(chǔ)設(shè)備有其自身的特性。Fash的寫入操作只能把對應(yīng)位置的1修改成0,而不能把0修改為1,而擦除Fash就是把對應(yīng)存儲(chǔ)塊的內(nèi)容恢復(fù)為1。因此,一般情況下向Fash寫入內(nèi)容時(shí),需要先擦除對應(yīng)的存儲(chǔ)區(qū)間,這種擦除是以塊(Bock)為單位進(jìn)行的。閃存主要有NOR和NAND兩種技術(shù)。因?yàn)镕lash存儲(chǔ)器的擦寫次數(shù)是有限的,NAND閃存還有特殊的硬件接口和讀寫時(shí)序,于是就出現(xiàn)了專門針對FLASH的文件系統(tǒng)。比較常用的有jffs2,yaffs2,logfs,ubifs。本文基于小凌派-RK2206開發(fā)板 + OpenHarmony輕量級操作系統(tǒng) + LitteFS文件系統(tǒng),通過hal_file標(biāo)準(zhǔn)接口實(shí)現(xiàn)對Flash讀寫功能。
二、hal_file標(biāo)準(zhǔn)接口
頭文件://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ù)說明:
返回值為LOS_OK表示成功,其余為失敗。
2、HalFileClose()
關(guān)閉文件,類似于Linux的close函數(shù)。
int HalFileClose(int fd);
參數(shù)說明:
返回值為LOS_OK表示成功,其余為失敗。
3、HalFileRead()
從文件中讀取一段內(nèi)容,類似于Linux的read函數(shù)。
int HalFileRead(int fd, char* buf, unsigned int len);
參數(shù)說明:
返回值為從文件讀取內(nèi)容的大小,0或者小于0則為失敗。
4、HalFileWrite()
往文件寫入一段內(nèi)容,類似于Linux的write函數(shù)。
int HalFileWrite(int fd, const char* buf, unsigned int len);
參數(shù)說明:
返回值為成功寫入到文件的內(nèi)容大小,0或者小于0則為失敗。
5、HalFileDelete()
刪除文件,類似于Linux的unlink函數(shù)。
int HalFileDelete(const char* path);
參數(shù)說明:
返回值為LOS_OK為成功,其余則為失敗。
6、HalFileStat()
獲取文件大小,類似于Linux的stat函數(shù)。
int HalFileStat(const char* path, unsigned int* fileSize);
參數(shù)說明:
返回值為LOS_OK為成功,其余則為失敗。
7、HalFileSeek()
文件所在位置移動(dòng),類似于Linux的lseek函數(shù)。
int HalFileSeek(int fd, int offset, unsigned int whence);
參數(shù)說明:
返回值為LOS_OK為成功,其余則為失敗。
三、程序設(shè)計(jì)
本例程演示如何在小凌派-RK2206開發(fā)板上使用鴻蒙LiteOS-M內(nèi)核接口,進(jìn)行文件讀寫開發(fā)。例程流程如下所示:
(1)創(chuàng)建一個(gè)文件。
(2)每5秒進(jìn)行1次文件讀寫操作。
(3)文件標(biāo)識(shí)移動(dòng)到文件起始處,讀文件內(nèi)容,并打印。
(4)文件標(biāo)識(shí)移動(dòng)到文件起始處,寫文件內(nèi)容。
(5)循環(huán)上述的第2~4步驟。
1、任務(wù)創(chuàng)建代碼分析
在file_example函數(shù)中通過LOS_TaskCreate函數(shù)創(chuàng)建一個(gè)線程: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ù)負(fù)責(zé)打開文件,每5秒移動(dòng)到文件頭讀取數(shù)據(jù),再移動(dòng)到文件頭寫入一段內(nèi)容,重復(fù)以上流程。
void hal_file_thread()
{
int fd;
char buffer[1024];
int read_length, write_length;
int current = 0;
/* 打開文件,如果沒有該文件就創(chuàng)建,如有該文件則打開
* O_TRUNC_FS => 清空文件內(nèi)容
*/
//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)
{
/* 文件位置移動(dòng)到文件開始位置 */
HalFileSeek(fd, 0, SEEK_SET);
memset(buffer, 0, sizeof(buffer));
/* 讀取文件內(nèi)容 */
read_length = HalFileRead(fd, buffer, sizeof(buffer));
printf("read: \n");
printf(" length = %d\n", read_length);
printf(" content = %s\n", buffer);
/* 文件位置移動(dòng)到文件開始位置 */
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。
五、實(shí)驗(yàn)結(jié)果
程序編譯燒寫到開發(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) =>
好了,今天的課程就到這里,我們下次再見!