W25X芯片为norflash芯片,存储空间较大,可以进行分区管理。
分区表示将norflash划分为多个盘,类似电脑C盘、D盘、E盘等。对每个盘进行各自的操作。

例如将norflash配置为4个分区:
#define MAX_NORFLASH_PART_NUM 4
static struct norflash_partition nor_part[MAX_NORFLASH_PART_NUM];//nor分区

分区信息结构体如下:
struct norflash_partition {
const char *name;//名称
u32 start_addr;//开始地址
u32 size;//大小
struct device device;//设备
};
每个分区有字节的盘符name,开始的地址,分区的大小,设备信息。

这里设备信息结构体如下:
struct device {
atomic_t ref;//设备被引用的计数,涉及设备关闭卸载等
void *private_data;//私有数据
const struct device_operations *ops;//设备操作
void *platform_data;//平台数据
void *driver_data;//驱动数据
};

typedef struct {
int counter;
} atomic_t;
ref仅为一个计数信息。

//设备操作函数
struct device_operations {
bool (*online)(const struct dev_node *node);//在线
int (*init)(const struct dev_node *node, void *);//初始化
int (*open)(const char *name, struct device **device, void *arg);//打开
int (*read)(struct device *device, void *buf, u32 len, u32);//读
int (*write)(struct device *device, void *buf, u32 len, u32);//写
int (*seek)(struct device *device, u32 offset, int orig);//设置读取指针位置
int (*ioctl)(struct device *device, u32 cmd, u32 arg);//io控制
int (*close)(struct device *device);//关闭设备
};

以上是分区信息和设备接口信息的定义。
对于一块norflash芯片,需要定义芯片级的信息:
struct norflash_info {
u32 flash_id;//flash芯片ID
u32 flash_capacity;//flash存储能力
int spi_num;//spi编号
int spi_err;//错误码
u8 spi_cs_io;//CS片选脚
u8 spi_r_width;//位宽
u8 part_num;//已使用的分区个数,0-4
u8 open_cnt;//打开次数
struct norflash_partition *const part_list;//分区信息表
OS_MUTEX mutex;//互斥信号量
u32 max_end_addr;//最大的结束地址
};
这里包括了
芯片的ID号;
芯片的存储能力,即芯片总空间大小;
使用到SPI编号、错误码信息、片选、位宽;
已使用的分区个数;
打开次数;
分区表;
互斥量;
最大的结束地址,即最后一个分区的尾地址。

定义一个norflash:
static struct norflash_info _norflash = {
.spi_num = (int) - 1,//编号
.part_list = nor_part,//分区列表
};
由于SPI编号从0开始,因此此处赋值-1。
分区表指向前面定义的分区表。

对于SPI接口的操作,使用了相关的宏定义:
//片选CS初始化
//普通IO输入
//配置为输出
//输出1
#define spi_cs_init()
do {
gpio_set_die(_norflash.spi_cs_io, 1);
gpio_set_direction(_norflash.spi_cs_io, 0);
gpio_write(_norflash.spi_cs_io, 1);
} while (0)

//片选CS un初始化
//配置为模拟输入
//配置为输入
//不上拉、不下拉
#define spi_cs_uninit()
do {
gpio_set_die(_norflash.spi_cs_io, 0);
gpio_set_direction(_norflash.spi_cs_io, 1);
gpio_set_pull_up(_norflash.spi_cs_io, 0);
gpio_set_pull_down(_norflash.spi_cs_io, 0);
} while (0)
#define spi_cs_h() gpio_write(_norflash.spi_cs_io, 1)//CS输出高
#define spi_cs_l() gpio_write(_norflash.spi_cs_io, 0)//CS输出低
#define spi_read_byte() spi_recv_byte(_norflash.spi_num, &_norflash.spi_err)//读字节
#define spi_write_byte(x) spi_send_byte(_norflash.spi_num, x)//发送字节
#define spi_dma_read(x, y) spi_dma_recv(_norflash.spi_num, x, y)//dma读
#define spi_dma_write(x, y) spi_dma_send(_norflash.spi_num, x, y)//dma写
#define spi_set_width(x) spi_set_bit_mode(_norflash.spi_num, x)//设置spi位宽

对于分区的管理:
通过name查找对应分区:
//每个分区有一个name
//根据这个name来找到这个分区的位置,即struct norflash_partition结构体
//该结构体位于_norflash.part_list中
static struct norflash_partition *norflash_find_part(const char *name)//根据name查找part
{
struct norflash_partition *part = NULL;
u32 idx;
for (idx = 0; idx < MAX_NORFLASH_PART_NUM; idx++) {//扫描整个分区list
part = &_norflash.part_list[idx];//指向该成员
if (part->name == NULL) {//名字为空则继续下一个
continue;
}
if (!strcmp(part->name, name)) {//名字不为空则比对
return part;//比对相同则返回part
}
}
return NULL;
}

//根据地址、大小和name创建一个新的分区
//首先需要确定分区列表中是否还有空闲位置
//有空闲位置,填充分区信息
//地址加大小不可超过norflash最大地址
static struct norflash_partition *norflash_new_part(const char *name, u32 addr, u32 size)//创建一个新的分区
{
struct norflash_partition *part;
u32 idx;
for (idx = 0; idx < MAX_NORFLASH_PART_NUM; idx++) {//扫描分区list,找空闲part
part = &_norflash.part_list[idx];
if (part->name == NULL) {
break;
}
}
if (part->name != NULL) {//如果4个分区用完,返回创建分区失败
log_error(“create norflash part fail\n”);
return NULL;
}
memset(part, 0, sizeof(*part));//清零
part->name = name;//名字
part->start_addr = addr;//开始地址
part->size = size;//大小
if (part->start_addr + part->size > _norflash.max_end_addr) {
_norflash.max_end_addr = part->start_addr + part->size;//最大结束地址更新
}
_norflash.part_num++;//已使用的分区数递增
return part;
}

//根据name删除一个分区
//查找比对,相同则删除,将name赋值NULL即可
static void norflash_delete_part(const char *name)//根据名字删除分区
{
struct norflash_partition *part;
u32 idx;
for (idx = 0; idx < MAX_NORFLASH_PART_NUM; idx++) {//扫描分区列表
part = &_norflash.part_list[idx];
if (part->name == NULL) {
continue;
}
if (!strcmp(part->name, name)) {//比对
part->name = NULL;//删除
_norflash.part_num–;//递减已使用分区数
}
}
}

//验证分区
//扫描整个分区列表
//p分区的地址不能与其他分区地址重叠,重叠则返回-1
//没有判断p分区结束地址是否在其他分区内
static int norflash_verify_part(struct norflash_partition *p)//验证分区
{
struct norflash_partition *part = NULL;
u32 idx;
for (idx = 0; idx < MAX_NORFLASH_PART_NUM; idx++) {
part = &_norflash.part_list[idx];
if (part->name == NULL) {
continue;
}
//将p分区与每一个创建的分区地址比较
//p分区起始地址大于等于part起始地址
//p分区起始地址小于part分区结束地址
//即p分区与part分区重叠
//如果名字不相同,则part不是p,重叠,返回错误码-1
if ((p->start_addr >= part->start_addr) && (p->start_addr < part->start_addr + part->size)) {
if (strcmp(p->name, part->name) != 0) {
return -1;
}
}
}
return 0;
}

其他一些基础函数:
//验证buf是否为全FF
//全F返回0,否则返回1
static int _check_0xff(u8 buf, u32 len)//检查buf是否为全FF
{
for (u32 i = 0; i < len; i ++) {
if ((
(buf + i)) != 0xff) {
return 1;
}
}
return 0;
}
#endif

//计算幂运算
static u32 _pow(u32 num, int n)//num的n次幂
{
u32 powint = 1;
int i;
for (i = 1; i <= n; i++) {
powint *= num;
}
return powint;
}

norflash芯片分区相关推荐

  1. linux ——Uboot模式下读取NORflash芯片数据

    命令: md指令 uboot下输入指令md,会提示md的用法,memory display,即内存显示. md [.b, .w, .l] address [# of objects]- memory ...

  2. NorFlash芯片特性分析

    Nor Flash是Intel在1988年推出的非易失闪存芯片,可随机读取,擦写时间长,可以擦写1~100W次,支持XIP(eXecute In Place). 本文以JS28F512M29EWH为例 ...

  3. norflash的基本操作

    norflash与mcu之间主要通过SPI接口进行通信. norflash的初始化主要包括SPI接口的初始化.分区创建及初始化操作.详细过程: 初始化norflash访问的SPI接口 根据名字创建分区 ...

  4. C语言获取norflash大小,NOR Flash 编程

    NOR Flash 编程1//************************************************************************************* ...

  5. norflash的基本操作2

    norflash芯片擦除 芯片手册中仅扇区.块.整片擦除操作 整片擦除无须使用addr地址 int _norflash_eraser(u8 eraser, u32 addr)//擦除 {u8 eras ...

  6. 【SemiDrive源码分析】【X9芯片启动流程】30 - AP1 Android Kernel 启动流程 start_kernel 函数详细分析(一)

    [SemiDrive源码分析][X9芯片启动流程]30 - AP1 Android Kernel 启动流程 start_kernel 函数详细分析(一) 一.Android Kernel 启动流程分析 ...

  7. FL2440(S3C2440A 芯片) 开发板开发笔记

    FL2440(S3C2440A 芯片) 开发板开发笔记 开发板的拨码开关指南: FL2440 改 vnfg 飞凌嵌入式 www. witech. com. cn 09. 8. 22 1 开发板使用手册 ...

  8. NandFlash系列之一:NorFlash与NandFlash对比

    NandFlash系列之一:NorFlash与NandFlash对比 作者:刘洪涛,华清远见嵌入式学院高级讲师. FLASH存储器又称闪存,主要有两种:NorFlash和NandFlash,下面我们从 ...

  9. NorFlash和NandFlash区别

    NorFlash和NandFlash区别 Flash编程原理都是只能将1写为0,而不能将0写成1.所以在Flash编程之前,必须将对应的块擦除,而擦除的过程就是将所有位都写为1的过程,块内的所有字节变 ...

最新文章

  1. 整理一些sql server基础资料
  2. JAVA基础整理-100.Java 多线编程
  3. JS实现表格Table动态添加删除行
  4. 23-爬虫之scrapy框架增量式实时监测数据爬取10
  5. jQuery对象与dom对象不能划等号
  6. 1130 - Host ‘win7' is not allowed to connect to this mysql server
  7. 【区块链】认识区块链的基本概念
  8. Javacript和AngularJS中的Promises
  9. 网络连接的netstat命令
  10. emqx http not found 怎么回事_幽默笑话:行倒是行,但两个大男人这么说话算怎么回事...
  11. win2008server R2 x64 部署.net core到IIS--ASP .NET Core HTTP Error 502.5 – Process Failure
  12. python 爬虫抓取网页数据导出excel_Python实现抓取网页生成Excel文件的方法示例
  13. Cimage类的介绍及使用
  14. c# 汉语拼音排序函数
  15. Ubuntu下ASIC/FPGA环境搭建
  16. linux怎么模糊查找文件,linux怎么模糊查找一个文件
  17. 使用Scikit-learn开启机器学习之旅
  18. 笔记本3.0 typec接口插上U盘没有反应
  19. SVM 美国威斯康星州乳腺癌检测
  20. 博客园页面定制html代码,博客园代码定制

热门文章

  1. 使用html+css实现一个静态页面(含源码)
  2. AD的设计里面找不到生成PCB选项
  3. 数据库简单sql语句(CURD)
  4. Ardupilot环境搭建
  5. 【3D视觉原理】2-3D传感器原理
  6. 大脑的默认模式网络DMN
  7. vim删除文本的命令
  8. 关于swfobject.js详解
  9. 【数学】扩展卢卡斯定理
  10. 关于 window.open() referer 非法请求的问题