一、简介在嵌入式领域,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 sethb 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 = 0content =read:length = 18content = hello world(0) =>read:length = 18content = hello world(1) =>好了,今天的课程就到这里,我们下次再见!
浅谈端子排安装规定
携手华为,中移动开通国内首个4/5G双模基站
联想A6 Note配置曝光搭载联发科MTK Helio P22处理器电池容量4000mAh
智慧工厂UWB高精度人员定位系统的功能
八种麦克风DIY设计方案
基于OpenHarmony标准接口的文件读写实现案例
荣耀新品预热:新款 MagicBook 笔记本和智慧屏要来了
互联网时代,高用户DOU是不是等于高用户ARPU呢?
关于编程的12条自问,你知道多少呢?
益莱储——让你的钱更值钱
供应链4.0对供应链管理有什么影响
电脑监控软件的工作原理是什么?
电信运营商和设备厂商的界限真的不可逾越吗?
MIL-STD-1553 IP核挑战传统IC实施
中国电信5G SA引领万物互联新时代
人工智能加“医真云”,每年让5700万人告别误诊
低能量电子束曝光技术
iPhone 8会“如期”上市,会随同iPhone 7 s和 iPhone 7s Plus一起发布
宝马共享汽车开进成都,率先投入100辆i3运营
华为荣耀Magic发布会回顾,正式开启未来手机智慧时代