基于JZ2440的NOR FLASH的驱动程序的实现
来源:互联网 发布:windows rt刷安卓 编辑:程序博客网 时间:2024/05/29 16:59
本文的主要任务是实现JZ2440开发板板载的MX29LV800BBTC这款NOR FLASH驱动。
一、MX29LV800BBTC的简单介绍
这是一块容量为2MB,位宽为16位的NOR FLASH存储芯片,它可以像内存一样直接进行访问,但是不能像内存一样直接写入,它支持XIP。它的原理图如下所示:
它的引脚定义如下:
LDATA0~LDATA15:数据引脚
LADDR1~LADDR20:地址引脚
LnOE:读使能引脚
LnWE:写使能引脚
nGCS0:片选引脚
二、驱动程序编写
驱动基于Linux-3.4.10内核编写。
1、一般实现步骤
a、分配一个map_info结构体变量
b、设置这个结构体变量
c、使用:do_map_probe()
d、添加分区
2、驱动程序编写
2.1 前期准备工作,为了方便整个驱动程序的编写,定义了全局结构体,并定义了一个该结构体的全局变量,具体实现如下:
/* 构造一个方便编写驱动程序的结构体 */struct yl_nor_mtd{struct map_info *map_info;// 定义map_info结构体的指针变量struct mtd_info *mtd_info;// 定义mtd_info结构体的指针变量};/* 定义一个yl_nor_mtd结构体的全局变量 */static struct yl_nor_mtd nor_mtd;2.2 分配一个map_info结构体的指针变量
/* 1、分配一个map_info结构体变量 */nor_mtd.map_info = kzalloc(sizeof(struct map_info), GFP_KERNEL);
2.3 设置这个结构体变量
/* 2、设置 */nor_mtd.map_info->name = "yl_nor_flash";// 名字nor_mtd.map_info->phys = 0;// 物理基地址nor_mtd.map_info->size = 0x200000; // 尺寸,>=真实大小nor_mtd.map_info->bankwidth = 2;// 位宽/* 设置虚拟地址的基地址 */nor_mtd.map_info->virt = ioremap(nor_mtd.map_info->phys, nor_mtd.map_info->size);if (nor_mtd.map_info->virt == NULL) {printk("Failed to ioremap flash region\n");ret = -EIO;goto out2;}/* 其他的nor flash的通用的初始化 */simple_map_init(nor_mtd.map_info);2.4 使用这个结构体变量,获得一个mtd_info结构体变量的实例
/* 3、使用 */nor_mtd.mtd_info = do_map_probe("cfi_probe", nor_mtd.map_info);if(nor_mtd.mtd_info == NULL){printk("do_map_probe for cfi_probe failure!\n");ret = -ENXIO;goto out3;}2.5 添加分区
/* 4、添加分区 */ret = mtd_device_parse_register(nor_mtd.mtd_info, NULL, NULL,yl_s3c_nor_partitions, ARRAY_SIZE(yl_s3c_nor_partitions));添加分区需要有一个分区表作为分区依据,分区表的实现如下所示:
/* 定义nor flash的分区表 */static struct mtd_partition yl_s3c_nor_partitions[] = {[0] = {.name= "bootloader_nor",.size= SZ_256K,.offset= 0,},[1] = {.name= "params_nor",.offset = MTDPART_OFS_APPEND,.size= SZ_128K,},[2] = {.name= "rootfs_nor",.offset= MTDPART_OFS_APPEND,.size= MTDPART_SIZ_FULL,}};
#include <linux/module.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/device.h>#include <linux/platform_device.h>#include <linux/mtd/mtd.h>#include <linux/mtd/map.h>#include <linux/mtd/partitions.h>#include <linux/mtd/concat.h>#include <linux/io.h>/* 构造一个方便编写驱动程序的结构体 */struct yl_nor_mtd{struct map_info *map_info;// 定义map_info结构体的指针变量struct mtd_info *mtd_info;// 定义mtd_info结构体的指针变量};/* 定义一个yl_nor_mtd结构体的全局变量 */static struct yl_nor_mtd nor_mtd;/* 定义nor flash的分区表 */static struct mtd_partition yl_s3c_nor_partitions[] = {[0] = {.name= "bootloader_nor",.size= SZ_256K,.offset= 0,},[1] = {.name= "params_nor",.offset = MTDPART_OFS_APPEND,.size= SZ_128K,},[2] = {.name= "rootfs_nor",.offset= MTDPART_OFS_APPEND,.size= MTDPART_SIZ_FULL,}};/* 模块的入口函数 */static int __init yl_s3c_nor_init(void){int ret = 0;/* 1、分配一个map_info结构体变量 */nor_mtd.map_info = kzalloc(sizeof(struct map_info), GFP_KERNEL);if (!nor_mtd.map_info) {printk("kzalloc for map_info error!\n");ret = -ENOMEM;goto out1;}/* 2、设置 */nor_mtd.map_info->name = "yl_nor_flash";// 名字nor_mtd.map_info->phys = 0;// 物理基地址nor_mtd.map_info->size = 0x200000; // 尺寸,>=真实大小nor_mtd.map_info->bankwidth = 2;// 位宽/* 设置虚拟地址的基地址 */nor_mtd.map_info->virt = ioremap(nor_mtd.map_info->phys, nor_mtd.map_info->size);if (nor_mtd.map_info->virt == NULL) {printk("Failed to ioremap flash region\n");ret = -EIO;goto out2;}/* 其他的nor flash的通用的初始化 */simple_map_init(nor_mtd.map_info);/* 3、使用 */nor_mtd.mtd_info = do_map_probe("cfi_probe", nor_mtd.map_info);if(nor_mtd.mtd_info == NULL){printk("do_map_probe for cfi_probe failure!\n");ret = -ENXIO;goto out3;}/* 4、添加分区 */ret = mtd_device_parse_register(nor_mtd.mtd_info, NULL, NULL,yl_s3c_nor_partitions, ARRAY_SIZE(yl_s3c_nor_partitions));if(ret)// 失败{printk("mtd_device_parse_register error!\n");ret = -ENODEV;goto out3;}else// 成功{return 0;}out3:iounmap(nor_mtd.map_info->virt);out2:kfree(nor_mtd.map_info);out1:return ret;}/* 模块的出口函数 */static void __exit yl_s3c_nor_exit(void){/* 进行出口的一些操作,释放资源,解除绑定,取消注册 */mtd_device_unregister(nor_mtd.mtd_info);iounmap(nor_mtd.map_info->virt);kfree(nor_mtd.map_info);}module_init(yl_s3c_nor_init);module_exit(yl_s3c_nor_exit);MODULE_LICENSE("GPL");
3、编译驱动程序并把模块加载进内核,结果如下所示:
阅读全文
0 0
- 基于JZ2440的NOR FLASH的驱动程序的实现
- 基于JZ2440的NAND FLASH的驱动程序的实现
- NOR FLASH 的驱动程序
- JZ2440学习笔记,第二部分,移植uboot2015支持JZ2440的nor flash
- 基于stm32f103zet6之nor flash的学习
- 基于fpga的nor flash控制器
- Nor Flash的操作
- Nor flash的探测
- 基于NOR FLASH存储器的嵌入式文件系统的设计
- 基于JZ2440的QT4移植
- vivi中基于NOR FLASH的相关代码
- 基于NOR flash和ramdisk文件系统的应用
- 基于STM32与NOR FLASH的SPI通信
- NOR Flash 的BANK理解
- JS28F128 Nor Flash的驱动
- NAND Flash和NOR Flash的区别
- nand flash和nor flash的区别
- NOR flash和NAND flash的区别
- c/c++出现:fatal error LNK 1120:1 unresolved externals
- 异常处理:finally块中代码什么时候执行总结!
- win7怎么修改开机密码(最快) win7修改开机密码最便捷的方法
- 怎么学好php
- 流的作用
- 基于JZ2440的NOR FLASH的驱动程序的实现
- 为 CentOS 6.5 配置163 yum 源
- 范数介绍及C++/OpenCV/Eigen的三种实现
- PyTorch——错误集锦
- Android studio安装ButterKnife插件
- 20170522 工作日志
- 低功耗蓝牙学习指南0519
- 网易实习--编程题
- selenium3+python2.7启动Firefox53提示:KeyError: 'sessionId'