SylixOS中MTD调用底层接口流程分析
1. MTD设备与底层驱动的关系
MTD设备是一种特殊的抽象设备,它用于简化驱动开发。它是底层硬件和上层软件的桥梁,无论对Nand Flash或是Nor Flash,它都提供了统一的框架供上层文件系统使用。对于底层驱动,只需按照各自硬件差异实现MTD中要求的接口即可。
MTD设备同时实现了Nand驱动的通用访问流程,对于上层文件系统的读、写等访问,MTD设备中都封装了接口,对于Nand驱动的编写,就是根据对应流程填充具体函数即可。
2. MTD结构分析
2.1 MTD中注册的接口函数
为了能够实现上层文件系统的读写操作,MTD设备为Nand注册了如程序清单 2.1所示的接口。
程序清单 2.1 MTD结构
mtd->_erase = nand_erase; /* Nand擦除操作 */
mtd->_point = NULL; /* 针对片上执行介质 */
mtd->_unpoint = NULL; /* 针对片上执行介质 */
mtd->_read = nand_read; /* Nand读取操作 */
mtd->_write = nand_write; /* Nand写入操作 */
mtd->_read_oob = nand_read_oob; /* Nand读取OOB区域 */
mtd->_write_oob = nand_write_oob; /* Nand写入OOB区域 */
mtd->_sync = nand_sync; /* Nand同步 */
mtd->_lock = NULL; /* 针对支持设备锁的设备 */
mtd->_unlock = NULL; /* 针对支持设备锁的设备 */
mtd->_block_isbad = nand_block_isbad; /* Nand坏块检查 */
mtd->_block_markbad = nand_block_markbad; /* Nand坏块标记 */
对于Nand驱动编写,编程者需要了解nand_erase、nand_read、nand_write等接口的调用流程,才能明白Nand驱动的编程方法。
2.2 Nand驱动接口函数
对应MTD中的接口,在Nand驱动中最终需实现如程序清单 2.2所示的各类接口函数。
程序清单 2.2 nand_chip结构
struct nand_chip {void __iomem *IO_ADDR_R;void __iomem *IO_ADDR_W;uint8_t (*read_byte)(struct mtd_info *mtd);u16 (*read_word)(struct mtd_info *mtd);void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len); void (*select_chip)(struct mtd_info *mtd, int chip); int (*dev_ready)(struct mtd_info *mtd);void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column,int page_addr);int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this);void (*erase_cmd)(struct mtd_info *mtd, int page);int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,const uint8_t *buf, int oob_required, int page,int cached, int raw);……struct nand_ecc_ctrl ecc;
}
nand_chip中的接口并非要求全部实现,对应每一个函数在SylixOS的Base工程中都有默认实现,Nand驱动所做的是将这些接口中与默认实现不对应的单独实现。
对于Nand中所需的ECC校验操作,本文不做描述,实际调试时可设置为“软件ECC”,待Nand功能实现后,可再修改为实际的硬件ECC操作。
2.3 驱动注册
以STM32为例,Nand驱动中的nand_chip结构体大致的实现如程序清单 2.3所示。
程序清单 2.3 STM32的Nand驱动实现
pNandChip->IO_ADDR_R = (VOID *)NAND_ADDRESS;
pNandChip->IO_ADDR_W = (VOID *)NAND_ADDRESS;
pNandChip->cmdfunc = __nandCommand; /* 命令操作函数 */
pNandChip->dev_ready = __nandDevReady; /* 判断设备是否准备好 */
pNandChip->select_chip = __nandChipSelect; /* Nand片选操作 */
pNandChip->waitfunc = __nandWaitForReady; /* 判断设备操作是否结束 */
pNandChip->chip_delay = 50;
pNandChip->ecc.mode = NAND_ECC_SOFT;
因为STM32的read_byte、read_word、write_buf等接口与SylixOS中Base实现一致,所以此部分无需在Nand驱动中再次实现。
对于STM32的Nand驱动,ECC采用了软件ECC方式。
3.流程分析
3.1 复位流程
3.1.1 系统调用流程
Nand驱动初始时会调用nand_scan接口,nand_scan接口的调用关系如图 3.1所示。最终会调用到Nand驱动实现的cmdfunc函数,并传递NAND_CMD_RESET参数。
图 3.1 Nand驱动复位流程
3.1.2 Nand驱动实现
由系统调用关系可知,在__nandCommand中需实现如程序清单 3.1所示的逻辑,HAL_NAND_Reset为STM32具体的复位操作。
程序清单 3.1 STM32的Nand复位实现
switch (uiCommand) {
case NAND_CMD_RESET: /* nand复位操作 */HAL_NAND_Reset(&_G_handleType);
return;
……
}
3.2 ID读取流程
3.2.1 系统调用流程
Nand驱动初始时调用nand_scan接口读取Nand的ID,其调用关系如图 3.2所示。
图 3.2 Nand读取ID流程
nand_scan会调用到Nand驱动实现的cmdfunc函数,并传递NAND_CMD_READID参数,之后调用read_byte函数,读取到Nand的ID。
3.2.2 Nand驱动实现
由系统调用关系可知,在__nandCommand中需实现如程序清单 3.2所示的逻辑,根据STM32寄存器说明,实现STM32读取Nand ID的具体操作。
程序清单 3.2 STM32的Nand读取ID
switch (uiCommand) {
……
case NAND_CMD_READID: /* nand读取ID操作 */writeb(NAND_CMD_READID, NAND_ADDRESS | NAND_CMD);writeb(0x00, NAND_ADDRESS | NAND_ADDR);
return;
……
}
3.3 擦除流程
3.3.1 系统调用流程
MTD设备擦除时调用nand_erase接口,其调用关系如图 3.3所示,nand_erase会判断是否是单块擦除。
如果是单块擦除,则调用single_erase_cmd,该接口会调用cmdfunc函数,依次传递NAND_CMD_ERASE1参数和NAND_CMD_ERASE2参数,之后调用waitfunc等待擦除操作完成;
如果是多块擦除,则调用multi_erase_cmd,该接口会调用四次cmdfunc函数,传递NAND_CMD_ERASE1参数,再调用一次cmdfunc函数,传递NAND_CMD_ERASE2参数,之后调用waitfunc等待擦除操作完成。
图 3.3 Nand擦除流程
3.3.2 Nand驱动实现
由系统调用关系可知,在__nandCommand中需实现如程序清单 3.3所示的逻辑,根据STM32寄存器说明,实现STM32擦除Nand的具体操作。
程序清单 3.3 STM32的Nand擦除操作
switch (uiCommand) {
……
case NAND_CMD_ERASE2:writeb(NAND_CMD_ERASE2, NAND_ADDRESS | NAND_CMD);
return;
case NAND_CMD_ERASE1:writeb(NAND_CMD_ERASE1, NAND_ADDRESS | NAND_CMD);writeb((UINT8)(iPagAddr), NAND_ADDRESS | NAND_ADDR);writeb((UINT8)(iPagAddr >> 8), NAND_ADDRESS | NAND_ADDR);writeb((UINT8)(iPagAddr >> 16), NAND_ADDRESS | NAND_ADDR);
return;
……
}
同时实现__nandWaitForReady接口,如程序清单 3.4所示。
程序清单 3.4 STM32的Nand等待操作完成操作
static INT __nandWaitForReady (struct mtd_info *pMtd, struct nand_chip *this)
{UINT32 uiTime = 0;while (1) {if (__nandDevReady(pMtd)) { /* 如果已经准备好 */break;}uiTime++;if(uiTime >= MAX_WAIT_TIME) {return (LW_FALSE); /* 超时 */}}return (LW_TRUE); /* 准备好 */
}
3.4 读取流程
3.4.1 系统调用流程
MTD设备调用nand_read接口读取Nand的数据,其调用关系如图 3.4所示。
图 3.4 Nand读取流程
nand_read中首先会调用cmd_func,传递NAND_CMD_READ0参数,之后调用read_buf实现,实际进行数据读取。
3.4.2 Nand驱动实现
由系统调用关系可知,在__nandCommand中需实现如程序清单 3.5所示的逻辑,根据STM32寄存器说明,首先对读取Nand的地址进行设置。
程序清单 3.5 STM32的Nand读取地址设置
switch (uiCommand) {
……
case NAND_CMD_READ0:writeb(NAND_CMD_READ0, NAND_ADDRESS | NAND_CMD);writeb((UINT8)(iColumn), NAND_ADDRESS | NAND_ADDR);writeb((UINT8)(iColumn >> 8), NAND_ADDRESS | NAND_ADDR);writeb((UINT8)(iPagAddr), NAND_ADDRESS | NAND_ADDR);writeb((UINT8)(iPagAddr >> 8), NAND_ADDRESS | NAND_ADDR);writeb((UINT8)(iPagAddr >> 16), NAND_ADDRESS | NAND_ADDR);writeb(NAND_CMD_READSTART, NAND_ADDRESS | NAND_CMD);__nandWaitRB(1); /* 等待RB脚变为高电平 */
return;
……
}
之后调用的read_buf函数,可以使用SylixOS的Base中的默认实现。
3.5 写入流程
3.5.1 系统调用流程
MTD设备写入时调用nand_write接口写入数据至Nand,其调用关系如图 3.5所示。
图 3.5 Nand写入流程
3.5.2 Nand驱动流程
由系统调用关系可知,在__nandCommand中需实现如程序清单 3.6所示的逻辑,根据STM32寄存器说明,首先对写入Nand的地址进行设置。
程序清单 3.6 STM32的Nand写入地址设置
switch (uiCommand) {
……
case NAND_CMD_SEQIN:writeb(NAND_CMD_WRITE0, NAND_ADDRESS | NAND_CMD);writeb((UINT8)(iColumn), NAND_ADDRESS | NAND_ADDR);writeb((UINT8)(iColumn >> 8), NAND_ADDRESS | NAND_ADDR);writeb((UINT8)(iPagAddr), NAND_ADDRESS | NAND_ADDR);writeb((UINT8)(iPagAddr >> 8), NAND_ADDRESS | NAND_ADDR);writeb((UINT8)(iPagAddr >> 16), NAND_ADDRESS | NAND_ADDR);bspDelayNs(100);return;
……
}
之后调用的write_buf函数,可以使用SylixOS的Base中的默认实现。
3.6 读取OOB
3.6.1 系统调用流程
图 3.6 Nand读取OOB流程
如图 3.6所示,Nand读取OOB的流程与Nand读取操作基本相同,只是cmd_func传递的命令为NAND_CMD_READOOB,所以在Nand驱动中需要进行实现。
3.6.2 Nand驱动流程
在Nand驱动中的_nandCommand中需要响应NAND_CMD_READOOB操作,如程序清单 3.7所示。
程序清单 3.7 STM32的Nand读取OOB地址的调整
if (uiCommand == NAND_CMD_READOOB) { /* 模拟 NAND_CMD_READOOB */iColumn += pMtd->writesize;uiCommand = NAND_CMD_READ0;
}
3.7 写入OOB
3.7.1 系统调用流程
如图 3.7所示,Nand写入OOB的流程与Nand写入操作基本相同,只是在写完数据后会调用cmd_func,传递NAND_CMD_PAGEPROG命令。
图 3.7 Nand写入OOB流程
3.7.2 Nand驱动流程
在Nand驱动中的_nandCommand中需要响应NAND_CMD_PAGEPROG操作,如程序清单 3.8所示。
程序清单 3.8 STM32的Nand写入OOB的页编程命令
switch (uiCommand) {
……
case NAND_CMD_PAGEPROG:writeb(NAND_CMD_PAGEPROG, NAND_ADDRESS | NAND_CMD);return;
……
}
转载于:https://blog.51cto.com/4102785/2054530
SylixOS中MTD调用底层接口流程分析相关推荐
- 码农在使用人脸识别开发套件中的硬件主板如何调用底层接口步骤
DLT-RK3288C人脸识别开发套件 是由深圳市宁远电子科技有限公司 自主研发推出,基于行业最小最薄的DLT-RK3288C 高性能人脸识别专用主板,融合百度AI 精准的离线人脸识别技术,集算法与软 ...
- 【android系统】android系统升级流程分析(一)---recovery模式中进行update包升级流程分析
今天我们直接来看下android中具体的升级过程是如何的. 升级流程概述 升级的流程图: 升级流程分析 第一步:升级包获取 升级获取可以通过远程下载,也可直接拷贝到指定目录即可. 第二步:准备升级 然 ...
- java获取get请求返回_Java中处理调用第三方接口(post/get),该如何处理,返回的数据如何处理...
条件:1.请求URL:http://ip:port/yypt/*.jsonRequest 2.接口采用http post协议.Content-Type为application/json 调用流程: 第 ...
- java第三方接口对接_Java中处理调用第三方接口(post/get),该如何处理,返回的数据如何处理...
条件:1.请求URL:http://ip:port/yypt/*.jsonRequest 2.接口采用http post协议.Content-Type为application/json 调用流程: 第 ...
- pycharm调试如何返回上一步_如何在瑞芯微RK3399开发板上调用底层接口技术调试笔记...
广东RK3399开发板DLT3399A底层接口文档如何调用方法在DLT3399A板卡正面写有GPIO和UART4_1V8丝印的接口,并看到板子反面对应的引脚gpio丝印,选择相对应的gpio控制节点, ...
- Java中Comparable和Comparator接口区别分析
本文要来详细分析一下Java中Comparable和Comparator接口的区别,两者都有比较的功能,那么究竟有什么区别呢,感兴趣的Java开发者继续看下去吧. Comparable 简介 Comp ...
- java调取对方接口_java中如何调用对方接口
调用对方http接口步骤:URL url = new URL(path); 1.打开和url之间的连接HttpURLConnection conn = (HttpURLConnection) url. ...
- java 调用tomcat api,调用servlet接口流程
使用Servlet接口的整体流程 目前对JavaWeb的理解是:用一次提交过程来表示,当点击一个提交的标签.会将url传到tomcat服务器,在tomcat的配置文件中找到管理javaweb项目的配置 ...
- java中如何调用dal接口案例_关于Java:接口的目的
好吧,我认为接口是一种强制对象实现一定数量功能的方法,而不必使用继承.有点像合同.我半明白他们的意思. 但是,如果界面中的所有内容都是: public interface animal{ void e ...
最新文章
- linux内核模块的优缺点
- concurrent.futures dataset
- Android FFmpeg系列——5 音视频同步播放
- 2020 年国外 9 个顶级的 Java 框架,你知道几个?
- 源代码管理-SVN自动更新
- 《JavaScript 高级程序设计》 7.5 常用模式
- Angular 应用的DevDependencies
- Ubuntu中配置FTP服务
- LwIP移植到FreeRTOS(STM32F107+DP83848)
- php函数之----get_magic_quotes_gpc
- 悲观锁和乐观锁_浅谈数据库悲观锁和乐观锁
- 你喜欢那种类型的收集壁纸?
- 创业的一些挫见之第二家公司失败记录
- 【Python笔记】列表的用法
- 山石网科发布山石云·景产品 安全运维管理进入SaaS模式
- jQuery 学习-DOM篇(六):jQuery 替换 DOM 元素
- php获得mp3文件总时间,php获得音频文件信息,php获得mp3文件信息
- C++的multi_map如何输出所有key值相等的元素
- python文件seek_Python文件读取中:f.seek(0)和f.seek(0,0)有什么区别?
- 【19调剂】湖南师范大学2019年信息科学与工程学院硕士研究生复试(含调剂)方案...