STM32F407移植OpenHarmony笔记7

news2024/11/28 8:44:06

继上一篇笔记,成功启动了liteos_m内核,可以创建线程了,也能看到shell控制台了。
今天研究文件系统,让控制台相关文件命令如mkdir和ls能工作。


liteos_m内核支持fatfs和littlefs两个文件系统,
fatfs适用于SD卡,
littlefs适用于NORFLASH,如W25Qxx系列。
我的板子上刚好有W25Q64,试试接入littlefs文件系统。
基于之前的研究经验,进入make menuconfig看看文件系统相关选项,先把它选上:

当启用文件系统后,LOS_KernelInit会调用OsVfsInit进行初始化,
OsVfsInit又会调用LfsInit初始化littlefs,并把littlefs注册到vfs的类型列表。


那我们怎么使用它呢,怎么让littlefs读写我们的SPIFLASH呢?

经过调查,我们需要使用mount函数,进行挂载操作来绑定文件系统和FLASH设备。
那就在bsp目录新建littlefs.c,参考代码:

#include <stdio.h>
#include "spiflash.h"
#include "lfs.h"
#include "los_fs.h"

static int LittlefsRead(int partition, UINT32 *offset, void *buf, UINT32 size)
{
    spiflash_read(*offset, buf, size);
    return LFS_ERR_OK;
}

static int LittlefsProg(int partition, UINT32 *offset, const void *buf, UINT32 size)
{
    spiflash_write(*offset, buf, size);
    return LFS_ERR_OK;
}

static int LittlefsErase(int partition, UINT32 offset, UINT32 size)
{
    spiflash_erase(offset, size);
    return LFS_ERR_OK;
}

static void LittlefsPartiton(void)
{
    int lens[1]={1024*1024};
    int addr[1]={0};
    LOS_DiskPartition("flash0", "littlefs", lens, addr, 1);
}

static void LittlefsMount(void)
{
    int ret;
    struct PartitionCfg lfs_cfg;
    lfs_cfg.readFunc = LittlefsRead;
    lfs_cfg.writeFunc = LittlefsProg;
    lfs_cfg.eraseFunc = LittlefsErase;
    lfs_cfg.readSize = 64;
    lfs_cfg.writeSize = 256;
    lfs_cfg.blockSize = 4096;
    lfs_cfg.blockCount = 256;
    lfs_cfg.cacheSize = 4096;
    lfs_cfg.partNo = 0;
    lfs_cfg.lookaheadSize = 64;
    lfs_cfg.blockCycles = 100;
    ret = mount(NULL, "/flash", "littlefs", 0, &lfs_cfg);
    printf("LittlefsInit ret=%d\n", ret);
}

int LittlefsInit(void)
{
    printf("LittlefsInit enter\n");
    spiflash_init();
    printf("SPIFLASH flash id=0x%x\n", spiflash_read_id());
    LittlefsPartiton();
    LittlefsMount();
    return LFS_ERR_OK;
}

LittlefsInit函数是初始化文件系统函数,在main里面完成LOS_KernelInit之后再调用。
spiflash_init是我们实现的W25QXX的驱动,W25QXX使用的是STM32F407的SPI接口。

使用HAL库完成SPI驱动,并用SPI读写W25QXX的部分就不在这里过多介绍了。
只要实现spiflash的init(初始化),read(读),write(写),erase(擦除)这4个函数就行。

LittlefsPartiton这个函数是定义1个磁盘分区,不然mount会失败。
具体原因是liteos_m适配的代码lfs_adapter.c里面,littlefs_block_xxx函数要用LfsGetStartAddr来寻找分区超始地址。LfsGetStartAddr会查找我们定义的分区表。

LittlefsMount函数则是调用mount函数,挂载littlefs分区,最后1个参数指定FLASH驱动参数。
mount函数最终会调用lfs_adapter.c里面的LfsMount函数。
LfsMount函数的最后1个参数会被LfsConfigAdapter((struct PartitionCfg *)data, cfg)转换为struct lfs_config结构传递给lfs_mount函数。

其它几个函数则就对FLASH读写操作进行封装就行了。

mount的第2个参数是挂载路径,可以自定义,但是用"/"我这里测试不行,只能是"/xxx"目录。


写完代码,按照之前的方法修改BUILD.gn,一切顺利的话编译通过。
下载到板子,可以看到LittlefsInit ret=0的日志。
敲ls命令,会报错,但是cd /flash切换目录后就没有问题了。

需要读写文件的话,#include<fnctl.h>使用open,read,write,close函数就可以了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1425507.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Tomcat与网络6】 Tomcat是如何扩展Java线程池的?

目录 1.Java 的线程池 2.Tomcat 的线程池 学习Tomcat的时候&#xff0c;有很多绚丽的技术值得我们学习&#xff0c;但是个人认为Tomcat的线程池扩展是最值得研究的一个部分&#xff0c;线程池的应用太广了&#xff0c;也重要了&#xff0c;Java原生线程池的特征我相信很多人都…

【Redis】一文搞懂redis的所有知识点

目录 1. 什么是Redis&#xff1f;它主要用来什么的&#xff1f; 2.说说Redis的基本数据结构类型 2.1 Redis 的五种基本数据类型​编辑 2.2 Redis 的三种特殊数据类型 3. Redis为什么这么快&#xff1f;​编辑 3.1 基于内存存储实现 3.2 高效的数据结构 3.3 合理的数据编…

Python 中常用图像数据结构

&#xff08;原文&#xff1a;https://blog.iyatt.com/?p13222 &#xff09; 1 测试环境 Python 3.12.1 numpy 1.26.3 opencv-python 4.9.0.80 pillow 10.2.0 matplotlib 3.8.2 注&#xff1a; 基于 2022.1.16 和 2022.4.9 的三篇博文再次验证并重写&#xff0c;原文已删…

嵌入式学习第十五天

内存管理: 1.malloc void *malloc(size_t size); 功能: 申请堆区空间 参数: size:申请堆区空间的大小 返回值: 返回获得的空间的首地址 失败返回NULL 2.free void free(void *ptr); 功能: 释放堆区空间 注…

复刻桌面小电视【包含代码分析】

宗旨&#xff1a;开源、分享、学习、进步&#xff0c;生命不息&#xff0c;折腾不止。 复刻小电视 感谢各位大佬的开源项目&#xff0c;让我有了学习的机会&#xff0c;如果侵权&#xff0c;请联系我删除。本人能力有限&#xff0c;如果有什么不对的地方&#xff0c;欢迎指正…

Vue3-Composition-API(二)

一、computed函数使用 1.computed 在前面我们讲解过计算属性computed&#xff1a;当我们的某些属性是依赖其他状态时&#xff0c;我们可以使用计算属性来处理 在前面的Options API中&#xff0c;我们是使用computed选项来完成的&#xff1b; 在Composition API中&#xff0c…

《C程序设计》上机实验报告(四)之一维数组

1.运行程序 #include <stdio.h> void main( ) { int a[5],i,j; for(i1;i<5;i) a[i]0; for(i1;i<5;i) for(j1;j<5;j) a[j]a[i]1; printf("%d %d\n",a[0],a[3]); } 要求&#xff1a; &#xff08;1&#xff09;输入并调试上述源程序&#xff0c;…

安装 vant-ui 实现底部导航栏 Tabbar

本例子使用vue3 介绍 vant-ui 地址&#xff1a;介绍 - Vant 4 (vant-ui.github.io) Vant 是一个轻量、可定制的移动端组件库 安装 通过 npm 安装&#xff1a; # Vue 3 项目&#xff0c;安装最新版 Vant npm i vant # Vue 2 项目&#xff0c;安装 Vant 2 npm i vantlatest-v…

数据可视化 pycharts实现中国各省市地图数据可视化

自用版 数据格式如下&#xff1a; 运行效果如下&#xff1a; import pandas as pd from pyecharts.charts import Map, TreeMap, Timeline, Page, WordCloud from pyecharts import options as opts from pyecharts.commons.utils import JsCode from pyecharts.globals im…

api接口1688商品详情接口采集商品详情数据商品价格详情页数据可支持高并发调用演示示例

接入1688商品详情API接口的步骤如下&#xff1a; 注册账号&#xff1a;首先&#xff0c;你需要在1688开放平台注册一个账号。 创建应用&#xff1a;登录后&#xff0c;在控制台中找到“我的应用”&#xff0c;点击“创建应用”。 获取API密钥&#xff1a;创建应用后&#xff…

C语言数据结构之二叉树

少年恃险若平地 独倚长剑凌清秋 &#x1f3a5;烟雨长虹&#xff0c;孤鹜齐飞的个人主页 &#x1f525;个人专栏 &#x1f3a5;前期回顾-栈和队列 期待小伙伴们的支持与关注&#xff01;&#xff01;&#xff01; 目录 树的定义与判定 树的定义 树的判定 树的相关概念 树的运用…

网络工程师必学知识:2、IPv4和IPv6地址划分

网络工程师必学知识&#xff1a;2、IPv4和IPv6地址划分 1.概述&#xff1a;2.IPv4&#xff1a;地址划分&#xff1a;有类划分&#xff0c;无类划分。一、有类划分&#xff1a;分为5类。ABCDE&#xff0c;掩码分别位8、16、24、28、27取值范围&#xff1a;出类别bit不变&#xf…

我是赵士杰,自述我的 Java 之旅:四年编码,千言万语中成长

你好我的朋友&#xff0c;请先容许我作一个简单介绍&#xff1a;我是赵士杰&#xff0c;一名 Java 攻城狮&#xff0c;欢迎关注我的微信公众号【技术人阿杰】。 不知不觉中&#xff0c;我在撰写技术博客领域已经投入了四年的精力&#xff0c;这也让我从一个默默无名之辈成长为了…

种草日记|林曦老师的冬日好物分享

冬天将尽春天就要来了&#xff0c;换季的时候最容易引起皮肤干燥、头发毛躁不舒服的问题&#xff0c;今天就来说说林曦老师推荐的冬日护理爱用好物。大家都要“如婴儿乎”&#xff0c;照顾好自己哦&#xff5e;      1、Aco甘油保湿霜    Aco甘油保湿霜好大一罐&#x…

《Vue3 基础知识》 使用 GoGoCod 升级到Vue3+ElementPlus 适配处理

此篇为 《Vue2ElementUI 自动转 Vue3ElementPlus&#xff08;GoGoCode&#xff09;》 的扩展&#xff01; Vue3 适配 Vue3 不兼容适配 Vue 3 迁移指南 在此&#xff0c;本章只讲述项目或组件库中遇到的问题&#xff1b; Vue3 移除 o n &#xff0c; on&#xff0c; on&#…

【Web前端实操21】商城官网_白色导航

今日份实现白色导航栏部分&#xff0c;也就是第三部分&#xff0c;效果如图中划线所示&#xff1a; 本次实现代码如之前的全局样式不再赘述&#xff0c;如有需要可以去我博客的Web前端实操19或者20自行查看。 本次主要更新mi.css和index.htm。 实现导航栏所需要的CSS样…

【图解面试】深入解析数据类型转换

将值从一种数据类型转换到另一种数据类型通常称为数据类型转换。在面试过程中大多数都是以代码输出题出现&#xff0c;但是要了解到具体的转换规则&#xff0c;彻底搞懂底层原理&#xff0c;才能应对变来变去的值类型~ 转布尔类型 Boolean类型有两个字面值&#xff1a; true …

调整Activation Function参数对神经网络的影响

目录 介绍&#xff1a; 数据集&#xff1a; 模型一&#xff08;tanh&#xff09; &#xff1a; 模型二&#xff08;relu&#xff09;&#xff1a; 模型三&#xff08;sigmoid&#xff09; &#xff1a; 模型四&#xff08;多层tanh&#xff09;&#xff1a; 模型五&am…

使用“快速开始”将数据传输到新的 iPhone 或 iPad

使用“快速开始”将数据传输到新的 iPhone 或 iPad 使用 iPhone 或 iPad 自动设置你的新 iOS 设备。 使用“快速开始”的过程会同时占用两台设备&#xff0c;因此请务必选择在几分钟内都不需要使用当前设备的时候进行设置。 确保你当前的设备已连接到无线局域网&#xff0c;并…

一篇带你彻底搞懂 Python 编程进阶之闭包

前言 在Python编程语言中&#xff0c;闭包是强大而灵活的语法&#xff0c;它为开发者提供了一种优雅而高效的方式来处理函数和代码结构。作为自动化测试和测试开发同学&#xff0c;弄懂它的作用及工作原理很有必要&#xff0c;面试中提及到的概率非常之大。 关于函数名的本质 …