nor flash 框架 及 代码

norflash的框架和nandflash是一样的,我们要做的也是实现硬件相关层的工作,也就是提供实际的读写函数!我们参考内核自带的norflash驱动来看看具体要做哪些设置!参考:drivers/mtd/maps/physmap.cplatform_driver_register(&physmap_flash_driver);static struct platform_driver physmap_flash_driver = { .probe = physmap_flash_probe, .remove = physmap_flash_remove, .shutdown = physmap_flash_shutdown, .driver = { .name = "physmap-flash", .owner = THIS_MODULE, },};physmap_flash_probe struct physmap_flash_info *info; info = devm_kzalloc(&dev->dev, sizeof(struct physmap_flash_info), info->map[i].name = dev_name(&dev->dev); info->map[i].phys = dev->resource[i].start; info->map[i].size = resource_size(&dev->resource[i]); info->map[i].bankwidth = physmap_data->width; info->map[i].set_vpp = physmap_set_vpp; info->map[i].pfow_base = physmap_data->pfow_base; info->map[i].map_priv_1 = (unsigned long)dev; info->map[i].virt = devm_ioremap(&dev->dev, info->map[i].phys, simple_map_init(&info->map[i]); map->read = simple_map_read; map->write = simple_map_write; map->copy_from = simple_map_copy_from; map->copy_to = simple_map_copy_to; do_map_probe(*probe_type, &info->map[i]) get_mtd_chip_driver(name);//我们以cfi识别为例,jedec请参见注释2 list_for_each(pos, &chip_drvs_list) //chip_drvs_list的由来可参见注释1 ret = drv->probe(map);//找到cfi的probe函数 mtd_do_chip_probe(map, &cfi_chip_probe);//见注释3 genprobe_ident_chips(map, cp); genprobe_new_chip(map, cp, &cfi) cfi_interleave_supported(nr_chips)//判断位宽是否被支持 cp->probe_chip(map, 0, NULL, cfi) cfi_qry_mode_on(base, map, cfi) cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);//复位 //往0x55写入0x98,进入cfi模式 cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); if (cfi_qry_present(map, base, cfi)) //下面主要是判断是否成功进入cfi模式 qry[0] = cfi_build_cmd('Q', map, cfi);//构造命令 qry[1] = cfi_build_cmd('R', map, cfi); qry[2] = cfi_build_cmd('Y', map, cfi); val[0] = map_read(map, base + osf*0x10);//到0x10地址处读数据 val[1] = map_read(map, base + osf*0x11); val[2] = map_read(map, base + osf*0x12); if (!map_word_equal(map, qry[0], val[0])) //判断构造的与读的是否一致 if (!map_word_equal(map, qry[1], val[1])) if (!map_word_equal(map, qry[2], val[2])) cfi_chip_setup(map, cfi); for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) //在cfi模式下读出各地址的信息 ((unsigned char *)cfi->cfiq)[i] = cfi_read_query(map,base + (0x10 + i)*ofs_factor); cfi_send_gen_cmd(0xf0, 0, base, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0xaa, addr_unlock1, base, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x55, addr_unlock2, base, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x90, addr_unlock1, base, map, cfi, cfi->device_type, NULL); cfi->mfr = cfi_read_query16(map, base); cfi->id = cfi_read_query16(map, base + ofs_factor); //读出设备id和厂家id check_cmd_set(map, 1); cfi_cmdset_0002(map, primary); mtd->priv = map; mtd->_erase = cfi_amdstd_erase_varsize;//下面是一些默认函数 mtd->_write = cfi_amdstd_write_words mtd->_read = cfi_amdstd_read; info->mtd[i]->owner = THIS_MODULE; mtd_device_parse_register(info->cmtd, part_types, NULL, physmap_data->parts, physmap_data->nr_parts);调用mtd_device_parse_register添加分区,接着就会创建磁盘等操作,一旦发生读写就会调用等待队列里面的函数!根据以上的分析,我们可以将norflash的驱动程序总结为四大步骤:1、将一些硬件相关的信息,如位宽等初始化在mtd_info结构体里面2、调用simple_map_init来将一些读写函数初始化在mtd_info结构体里面3、调用do_map_probe来识别norflash4、调用mtd_device_parse_register来添加分区,创建磁盘等!注释1:module_init(cfi_probe_init); register_mtd_chip_driver(&cfi_chipdrv); list_add(&drv->list, &chip_drvs_list);static struct mtd_chip_driver cfi_chipdrv = { .probe = cfi_probe, .name = "cfi_probe", .module = THIS_MODULE};注释2:module_init(jedec_probe_init); register_mtd_chip_driver(&jedec_chipdrv); list_add(&drv->list, &chip_drvs_list);static struct mtd_chip_driver jedec_chipdrv = { .probe = jedec_probe, .name = "jedec_probe", .module = THIS_MODULE}; jedec_probe mtd_do_chip_probe(map, &jedec_chip_probe); genprobe_ident_chips(map, cp); genprobe_new_chip(map, cp, &cfi) cp->probe_chip(map, 0, NULL, cfi)//jedec_probe_chip jedec_reset(base, map, cfi);//复位 cfi_send_gen_cmd(0xF0, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); cfi->mfr = jedec_read_mfr(map, base, cfi); cfi->id = jedec_read_id(map, base, cfi); //遍历jedec_table数组,找到设备id和厂家id相匹配的项,就匹配成功! jedec_match( base, map, cfi, &jedec_table[i] ) cfi_jedec_setup(map, cfi, i)//将匹配项的信息放进cfi结构体里面 cfi->cfiq->DevSize = jedec_table[index].dev_size; cfi->cfi_mode = CFI_MODE_JEDEC;注释3:static struct chip_probe cfi_chip_probe = { .name = "CFI", .probe_chip = cfi_probe_chip};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值