当前位置: 首页 > news >正文

徐州网站公司研发网站要多长时间

徐州网站公司,研发网站要多长时间,wordpress关于页面,seo服务多少钱文章目录 1. 前言2. NAND 初始化3. 访问 NAND 设备3.1 查看 NAND 设备信息3.1.1 查看 NAND 设备基本信息3.1.2 查看 NAND 设备 MTD 分区3.1.3 查看 NAND 设备坏块 3.2 NAND 擦除操作3.3 NAND 写操作3.4 NAND 读操作3.5 其它 NAND 操作 1. 前言 限于作者能力水平#xff0c;本… 文章目录 1. 前言2. NAND 初始化3. 访问 NAND 设备3.1 查看 NAND 设备信息3.1.1 查看 NAND 设备基本信息3.1.2 查看 NAND 设备 MTD 分区3.1.3 查看 NAND 设备坏块 3.2 NAND 擦除操作3.3 NAND 写操作3.4 NAND 读操作3.5 其它 NAND 操作 1. 前言 限于作者能力水平本文可能存在谬误因此而给读者带来的损失作者不做任何承诺。 2. NAND 初始化 下面以 Micron MT29F2G08AAD 型号的 Nand Flash 为例说明 ARMv7 架构下 U-Boot 对 Nand Flash 设备的初始化过程。首先可以将相关代码划分为 U-Boot NAND 驱动硬件无关通用部分 和 硬件相关的 NAND FLASH 以及其 控制器 驱动 两部分。另外抽象层次上U-Boot 将 Nor FlashNand Flash 等类型设备统一抽象为 MTD(Memory Technology Device) 类型设备对这些类型设备的访问都是通过 MTD 接口来间接进行。 board_init_r() /* common/board_r.c *//* 特定 板型 初始化这里重点关注 NAND 控制器 的 初始化 */board_init() /* board/myirtech/myd_c335x/myd_c335x.c */...gpmc_init();/* putting a blanket check on GPMC based on ZeBu for now */gpmc_cfg (struct gpmc *)GPMC_BASE;/* NAND 控制器 的一些寄存器配置 */...initr_nand()nand_init() /* drivers/mtd/nand/nand.c */nand_init_chip()struct mtd_info *mtd;#ifndef CONFIG_DM_NANDstruct nand_chip *nand nand_chip[i];ulong base_addr base_address[i];#endif...mtd nand_info[i]; /* NAND 设备 的 MTD 数据对象 */mtd-priv nand; /* MTD NAND 设备数据 */nand-IO_ADDR_R nand-IO_ADDR_W (void __iomem *)base_addr; /* NAND 设备 IO 地址空间 *//* 1. 特定 板型 的 NAND 初始化 */if (board_nand_init(nand)) /* drivers/mtd/nand/omap_gpmc.c */return;/* 2. 扫描识别并配置 NAND 控制器 上 挂接的 NAND 设备 */if (nand_scan(mtd, maxchips))return;/* 3. 注册 扫描到的、挂接在 NAND 控制器 上 NAND 设备 */nand_register(i);/* 1. 特定 板型 的 NAND 初始化 */ board_nand_init(nand).../** xloader/Uboots gpmc configuration would have configured GPMC for* nand type of memory. The following logic scans and latches on to the* first CS with NAND type memory.* TBD: need to make this logic generic to handle multiple CS NAND* devices.*/while (cs GPMC_MAX_CS) {/* Check if NAND type is set */if ((readl(gpmc_cfg-cs[cs].config1) 0xC00) 0x800) {/* Found it!! */break;}cs;}...nand-IO_ADDR_R (void __iomem *)gpmc_cfg-cs[cs].nand_dat;nand-IO_ADDR_W (void __iomem *)gpmc_cfg-cs[cs].nand_cmd;...nand-priv omap_nand_info[cs];nand-cmd_ctrl omap_nand_hwcontrol;nand-options | NAND_NO_PADDING | NAND_CACHEPRG;nand-chip_delay 100;nand-ecc.layout omap_ecclayout; /* NAND ECC 数据 layout */...nand-options ~NAND_BUSWIDTH_16; /* 8 位数据宽度 */.../* select ECC scheme */ #if defined(CONFIG_NAND_OMAP_ECCSCHEME)/* NAND ECC 模式选择 */err omap_select_ecc_scheme(nand, CONFIG_NAND_OMAP_ECCSCHEME,CONFIG_SYS_NAND_PAGE_SIZE, CONFIG_SYS_NAND_OOBSIZE);...switch (ecc_scheme) {...case OMAP_ECC_BCH8_CODE_HW: /* ECC 使用 硬件 BCH8 码 */#ifdef CONFIG_NAND_OMAP_ELM.../* intialize ELM for ECC error detection */elm_init(); /* ECC 错误检测硬件模块 ELM 初始化 */.../* populate ecc specific fields */nand-ecc.mode NAND_ECC_HW; /* 硬件 ECC */nand-ecc.strength 8;nand-ecc.size SECTOR_BYTES;nand-ecc.bytes 14;/* ECC 操作接口 */nand-ecc.hwctl omap_enable_hwecc;nand-ecc.correct omap_correct_data_bch;nand-ecc.calculate omap_calculate_ecc;nand-ecc.read_page omap_read_page_bch;...#else...#endif...}...info-ecc_scheme ecc_scheme; /* OMAP_ECC_BCH8_CODE_HW */return 0; #else... #endif#ifdef CONFIG_NAND_OMAP_GPMC_PREFETCHnand-read_buf omap_nand_read_prefetch; #else... #endifnand-dev_ready omap_dev_ready;return 0;/* 2. 扫描识别并配置 NAND 控制器 上 挂接的 NAND 设备 */ nand_scan(mtd, maxchips) /* drivers/mtd/nand/nand_base.c */.../* 扫描识别 NAND 设备 和 参数, 设置操作接口 等 */ret nand_scan_ident(mtd, maxchips, NULL);...struct nand_chip *chip mtd-priv;struct nand_flash_dev *type;/* Set the default functions */nand_set_defaults(chip, chip-options NAND_BUSWIDTH_16); /* 设置 NAND 设备缺省操作接口(读写等) */.../* check, if a user supplied command function given */if (chip-cmdfunc NULL)chip-cmdfunc nand_command;/* check, if a user supplied wait function given */if (chip-waitfunc NULL)chip-waitfunc nand_wait;if (!chip-select_chip)chip-select_chip nand_select_chip;.../* If called twice, pointers that depend on busw may need to be reset */if (!chip-read_byte || chip-read_byte nand_read_byte)chip-read_byte busw ? nand_read_byte16 : nand_read_byte;if (!chip-read_word)chip-read_word nand_read_word;if (!chip-block_bad)chip-block_bad nand_block_bad; /* 坏块 判定接口 */if (!chip-block_markbad)chip-block_markbad nand_default_block_markbad;if (!chip-write_buf || chip-write_buf nand_write_buf)chip-write_buf busw ? nand_write_buf16 : nand_write_buf;if (!chip-write_byte || chip-write_byte nand_write_byte)chip-write_byte busw ? nand_write_byte16 : nand_write_byte;if (!chip-read_buf || chip-read_buf nand_read_buf)chip-read_buf busw ? nand_read_buf16 : nand_read_buf;if (!chip-scan_bbt)chip-scan_bbt nand_default_bbt; /* 坏块 选择/建立 接口 */.../* Read the flash type *//* 识别 NAND 设备类型 */type nand_get_flash_type(mtd, chip, nand_maf_id,nand_dev_id, table);...u8 id_data[8];/* Select the device */chip-select_chip(mtd, 0);/** Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx)* after power-up.*/chip-cmdfunc(mtd, NAND_CMD_RESET, -1, -1); /* 复位 NAND 设备 ID *//* Send the command for reading device ID */chip-cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); /* 发送读取 NAND 设备 ID 命令 *//* Read manufacturer and device IDs */*maf_id chip-read_byte(mtd); /* 读取 NAND 设备 制造商 ID */*dev_id chip-read_byte(mtd); /* 读取 NAND 设备 ID */chip-cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); /* 读取 NAND 芯片 ID *//* Read entire ID string */for (i 0; i 8; i)id_data[i] chip-read_byte(mtd);...if (!type)type nand_flash_ids; /* 预定义的 NAND 设备列表: drivers/mtd/nand/nand_ids.c *//** 对比 读取到的 NAND 设备 ID 和 预定义表 nand_flash_ids[], * 看是否能找到匹配的表项.*/for (; type-name ! NULL; type) {if (is_full_id_nand(type)) { /* 对于 全 ID 标识的设备, 进行全 ID 匹配 */if (find_full_id_nand(mtd, chip, type, id_data, busw)) /* 如果 是 设备全 ID 匹配, */goto ident_done; /* 完成识别工作 */} else if (*dev_id type-dev_id) { /* 如果 不是 设备全 ID 匹配, 而是 设备 ID 匹配 */break; /* 做进一步的识别工作(如符合 ONFI/JEDEC 规范的设备匹配工作) */}}/* 可能满足 ONFI/JEDEC 规范 的 设备 识别 */chip-onfi_version 0;if (!type-name || !type-pagesize) {/* Check if the chip is ONFI compliant */if (nand_flash_detect_onfi(mtd, chip, busw)) /* 识别到 符合 ONFI 接口规范 的 NAND 设备 */goto ident_done; /* 完成识别工作 *//* Check if the chip is JEDEC compliant */if (nand_flash_detect_jedec(mtd, chip, busw)) /* 识别到 符合 JEDEC 接口规范 的 NAND 设备 */goto ident_done;}/* * 目前无法识别设备:* . 无法从预定义 NAND 芯片列表 nand_flash_ids[] 匹配设备* . 设备不符合 ONFI/JEDEC 接口规范*/if (!type-name)return ERR_PTR(-ENODEV);if (!mtd-name)mtd-name type-name; /* 设置 MTD NAND 设备名称 *//* 设置 NAND 设备容量 */chip-chipsize (uint64_t)type-chipsize 20;/* 设置 NAND 的 page size, OOB size, erase size */if (!type-pagesize chip-init_size) {/* Set the pagesize, oobsize, erasesize by the driver */busw chip-init_size(mtd, chip, id_data);} else if (!type-pagesize) {/* Decode parameters from extended ID */nand_decode_ext_id(mtd, chip, id_data, busw);} else {nand_decode_id(mtd, chip, type, id_data, busw);}/* Get chip options */chip-options | type-options; /* 设置 NAND 设备选项 */...ident_done:.../* 坏块管理相关配置 */nand_decode_bbm_options(mtd, chip, id_data);int maf_id id_data[0];/* Set the bad block position */if (mtd-writesize 512 || (chip-options NAND_BUSWIDTH_16))chip-badblockpos NAND_LARGE_BADBLOCK_POS;elsechip-badblockpos NAND_SMALL_BADBLOCK_POS;/** Bad block marker is stored in the last page of each block on Samsung* and Hynix MLC devices; stored in first two pages of each block on* Micron devices with 2KiB pages and on SLC Samsung, Hynix, Toshiba,* AMD/Spansion, and Macronix. All others scan only the first page.*/if (!nand_is_slc(chip) (maf_id NAND_MFR_SAMSUNG ||maf_id NAND_MFR_HYNIX))/* 三星 和 海力士 的 非 SLC 类型设备, 坏块标记存储在每个 block 的最后一个 page */chip-bbt_options | NAND_BBT_SCANLASTPAGE;else if ((nand_is_slc(chip) (maf_id NAND_MFR_SAMSUNG ||maf_id NAND_MFR_HYNIX ||maf_id NAND_MFR_TOSHIBA ||maf_id NAND_MFR_AMD ||maf_id NAND_MFR_MACRONIX)) ||(mtd-writesize 2048 maf_id NAND_MFR_MICRON))/* 一些厂家的 SLC 类型设备坏块标记存储在 block 的 第1 和 第2 个 page */chip-bbt_options | NAND_BBT_SCAN2NDPAGE;...chip-badblockbits 8;chip-erase single_erase; /* 设置 擦除 接口 *//* Do not replace user supplied command function! */if (mtd-writesize 512 chip-cmdfunc nand_command)chip-cmdfunc nand_command_lp; /* 覆盖命令为 大 page 接口 *//* 报告设备信息 (需要开启 CONFIG_MTD_DEBUG) */pr_info(device found, Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n,*maf_id, *dev_id);...pr_info(%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n,(int)(chip-chipsize 20), nand_is_slc(chip) ? SLC : MLC,mtd-erasesize 10, mtd-writesize, mtd-oobsize);return type; /* 返回是被的 NAND 设备类型 *//* 通过 NAND 控制器选择 NAND 芯片 */chip-select_chip(mtd, -1);/* Store the number of chips and calc total size for mtd */chip-numchips i;mtd-size i * chip-chipsize; /* 记录 MTD NAND 设备容量 */return 0;if (!ret)/** 扫描识别收尾工作: * 从 前面 扫描识别到的 NAND 设备 和 参数,* 为 NAND 设备建立缓冲,设置 NAND 设备对应的 MTD NAND 设备对象。*/ret nand_scan_tail(mtd);int i;struct nand_chip *chip mtd-priv;struct nand_ecc_ctrl *ecc chip-ecc;struct nand_buffers *nbuf;/* 为 NAND 设备 创建 缓冲: ECC, 数据 */if (!(chip-options NAND_OWN_BUFFERS)) {nbuf kzalloc(sizeof(struct nand_buffers), GFP_KERNEL);chip-buffers nbuf;} else {if (!chip-buffers)return -ENOMEM;}/* Set the internal oob buffer location, just after the page data *//* 和 NAND 页面存储一样, OOB 缓冲 紧邻 page 缓冲之后 */chip-oob_poi chip-buffers-databuf mtd-writesize;...switch (ecc-mode) {...case NAND_ECC_HW: /* 设置没有配置的 ECC 接口 */if (!ecc-read_page)ecc-read_page nand_read_page_hwecc;if (!ecc-write_page)ecc-write_page nand_write_page_hwecc;if (!ecc-read_page_raw)ecc-read_page_raw nand_read_page_raw;if (!ecc-write_page_raw)ecc-write_page_raw nand_write_page_raw;if (!ecc-read_oob)ecc-read_oob nand_read_oob_std;if (!ecc-write_oob)ecc-write_oob nand_write_oob_std;if (!ecc-read_subpage)ecc-read_subpage nand_read_subpage;if (!ecc-write_subpage)ecc-write_subpage nand_write_subpage_hwecc;...}/* For many systems, the standard OOB write also works for raw */if (!ecc-read_oob_raw)ecc-read_oob_raw ecc-read_oob;if (!ecc-write_oob_raw)ecc-write_oob_raw ecc-write_oob;// 一些其它 ECC 相关配置.../* Initialize state */chip-state FL_READY; /* NAND 设备标记为 READY 状态 */.../* Fill in remaining MTD driver data */mtd-type nand_is_slc(chip) ? MTD_NANDFLASH : MTD_MLCNANDFLASH; /* 设置 MTD NAND 设备类型: SLC 或 MLC */mtd-flags (chip-options NAND_ROM) ? MTD_CAP_ROM :MTD_CAP_NANDFLASH; /* MTD NAND 读写属性设置只读、可读写 *//* 设置 MTD NAND 设备接口: 调用 NAND 设备接口 */mtd-_erase nand_erase;mtd-_read nand_read;mtd-_write nand_write;mtd-_panic_write panic_nand_write;mtd-_read_oob nand_read_oob;mtd-_write_oob nand_write_oob;mtd-_sync nand_sync;mtd-_lock NULL;mtd-_unlock NULL;mtd-_block_isreserved nand_block_isreserved;mtd-_block_isbad nand_block_isbad;mtd-_block_markbad nand_block_markbad;mtd-writebufsize mtd-writesize;// MTD NAND ECC 相关设置...return 0;return ret;/* 3. 注册 扫描到的、挂接在 NAND 控制器 上 NAND 设备 */ nand_register(i);struct mtd_info *mtd;mtd get_nand_dev_by_index(devnum);sprintf(dev_name[devnum], nand%d, devnum);mtd-name dev_name[devnum];#ifdef CONFIG_MTD_DEVICE/** Add MTD device so that we can reference it later* via the mtdcore infrastructure (e.g. ubi).*/add_mtd_device(mtd); #endiftotal_nand_size mtd-size / 1024;if (nand_curr_device -1)nand_curr_device devnum; /* 设置当前 NAND 设备编号 */return 0; 3. 访问 NAND 设备 3.1 查看 NAND 设备信息 3.1.1 查看 NAND 设备基本信息 U-Boot 提供一些 nand info 命令可以查看 NAND 设备信息 # nand infoDevice 0: nand0, sector size 128 KiBPage size 2048 bOOB size 64 bErase size 131072 bsubpagesize 512 boptions 0x4000000cbbt options 0x 8000 从上面看到Nand Flash 设备 o page 是 2KB 大小 o page 后跟的 OOB(Spare area) 是 64 Bytes o 擦除 size 是 128KB也就是 block size 3.1.2 查看 NAND 设备 MTD 分区 前面有说过U-Boot 将 NAND 抽象为 MTD 设备进行访问通过 mtdparts 命令可以查看 NAND 设备的分区信息 # mtdpartsdevice nand0 nand.0, # parts 11#: name size offset mask_flags0: NAND.SPL 0x00020000 0x00000000 01: NAND.SPL.backup1 0x00020000 0x00020000 02: NAND.SPL.backup2 0x00020000 0x00040000 03: NAND.SPL.backup3 0x00020000 0x00060000 04: NAND.u-boot-spl-os 0x00040000 0x00080000 05: NAND.u-boot 0x00100000 0x000c0000 06: NAND.u-boot-env 0x00020000 0x001c0000 07: NAND.u-boot-env.backup10x00020000 0x001e0000 08: NAND.kernel 0x00800000 0x00200000 09: NAND.rootfs 0x0d600000 0x00a00000 0 10: NAND.userdata 0x02000000 0x0e000000 0active partition: nand0,0 - (NAND.SPL) 0x00020000 0x00000000defaults: mtdids : nand0nand.0 mtdparts: mtdpartsnand.0:128k(NAND.SPL),128k(NAND.SPL.backup1),128k(NAND.SPL.backup2),128k(NAND.SPL.backup3),256k(NAND.u-boot-spl-os),1m(NAND.u-boot),128k(NAND.u-boot-env),128k(NAND.u-boot-env.backup1),8m(NAND.kernel),214m(NAND.rootfs),-(NAND.userdata) 3.1.3 查看 NAND 设备坏块 # nand badDevice 0 bad blocks:03e40000086c0000 发现了两个坏块数据标记了它们的字节偏移位置。 3.2 NAND 擦除操作 通过 nand erase 命令可以对 NAND 发起对 NAND 的擦除操作 # nand erase c0000 100000 其中参数 c0000 是要擦除的起始位置相对于 NAND 设备开始位置的字节偏移100000 是要擦除的长度字节数。这两个参数都是十六进制数字。来看一下擦除过程的具体实现 do_nand() /* cmd/nand.c */...nand_info_t *nand;...int dev nand_curr_device; /* 默认选择当前 NAND 设备进行操作 */......cmd argv[1]; /* erase */...nand get_nand_dev_by_index(dev); /* 获取 NAND 设备 */if (strncmp(cmd, erase, 5) 0 || strncmp(cmd, scrub, 5) 0) {nand_erase_options_t opts;......printf(\nNAND %s: , cmd); /* NAND erase: *//* 解析 擦除起始位置 和 长度 参数 到 off 和 size */if (mtd_arg_off_size(argc - o, argv o, dev, off, size,maxsize, MTD_DEV_TYPE_NAND,nand-size) ! 0)return 1;/* 切换到 要操作 的 目标 NAND 设备 */if (set_dev(dev))return 1;nand get_nand_dev_by_index(dev);memset(opts, 0, sizeof(opts));opts.offset off;opts.length size;...ret nand_erase_opts(nand, opts); /* 擦除操作 */...}ret nand_erase_opts(nand, opts); /* drivers/mtd/nand/nand_util.c */.../** erase_length要擦除的 block 数目* erased_length: 已经擦除的 block 数目*/unsigned long erase_length, erased_length; /* in blocks */...erase_length lldiv(opts-length meminfo-erasesize - 1,meminfo-erasesize); /* 向上对齐到 erase size (block 大小) */...for (erased_length 0;erased_length erase_length;erase.addr meminfo-erasesize) {...if (!opts-scrub) {/* 检查位于 ofs 位置的 block 是不是坏块 */int ret mtd_block_isbad(meminfo, erase.addr);if (ret 0) { /* 坏块 */...if (!opts-spread)erased_length; /* 非 nand erase.spread 命令, 坏块也计入擦除 block 数目 */continue; /* 跳过坏块: 坏块不做擦除动作擦除坏块是非法操作 */}}erased_length; /* 已擦除 block 数目 1 */result mtd_erase(meminfo, erase); /* 擦除当前块 */...return mtd-_erase(mtd, instr);nand_erase()return nand_erase_nand(mtd, instr, 0);...struct nand_chip *chip mtd-priv; /* MTD 转入 NAND 层操作 */.../* Grab the lock and see if the device is available */nand_get_device(mtd, FL_ERASING);/* Shift to get first page */page (int)(instr-addr chip-page_shift); /* 擦除位置转换为 page 位置 */chipnr (int)(instr-addr chip-chip_shift);/* Calculate pages in each block */pages_per_block 1 (chip-phys_erase_shift - chip-page_shift);/* Select the NAND device */chip-select_chip(mtd, chipnr);/* Loop through the pages */len instr-len;instr-state MTD_ERASING;while (len) {...status chip-erase(mtd, page chip-pagemask);single_erase()struct nand_chip *chip mtd-priv;/* Send commands to erase a block *//* 发送 page 擦除操作命令 */chip-cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);chip-cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);/* 等待擦除操作完成 */return chip-waitfunc(mtd, chip);/* Increment page address and decrement length *//* 移向下一个 page */len - (1ULL chip-phys_erase_shift);page pages_per_block;...}instr-state MTD_ERASE_DONE;...} 3.3 NAND 写操作 假定以命令 nand write 0x82000000 c0000 ${filesize} 发起写操作。写操作基本流程和擦除操作差不多来看细节 do_nand()...if (strncmp(cmd, read, 4) 0 || strncmp(cmd, write, 5) 0) {...addr (ulong)simple_strtoul(argv[2], NULL, 16); // 0x82000000read strncmp(cmd, read, 4) 0; /* 1 read, 0 write */printf(\nNAND %s: , read ? read : write);s strchr(cmd, .);if (s !strcmp(s, .raw)) { // nand write.raw...} else {// off 0xc0000// size ${filesize}if (mtd_arg_off_size(argc - 3, argv 3, dev, off,size, maxsize,MTD_DEV_TYPE_NAND,nand-size) ! 0)return 1;if (set_dev(dev))return 1;...rwsize size;if (!s || !strcmp(s, .jffs2) ||!strcmp(s, .e) || !strcmp(s, .i)) {if (read)ret nand_read_skip_bad(nand, off, rwsize,NULL, maxsize,(u_char *)addr); /* 读取会自动跳过坏块 */elseret nand_write_skip_bad(nand, off, rwsize,NULL, maxsize,(u_char *)addr,WITH_WR_VERIFY); /* 写入会自动跳过坏块 */}}nand get_nand_dev_by_index(dev);}nand_write_skip_bad()...size_t left_to_write *length; /* 要写入的长度, 字节数 */...int need_skip;blocksize nand-erasesize;/* 检查写入过程中, 要跳过的坏块数目 */need_skip check_skip_len(nand, offset, *length, used_for_write);...while (left_to_write 0) {size_t block_offset offset (nand-erasesize - 1); /* 计算 block 内偏移 */.../* 写入时跳过坏块 */if (nand_block_isbad(nand, offset ~(nand-erasesize - 1))) {printf(Skip bad block 0x%08llx\n,offset ~(nand-erasesize - 1));offset nand-erasesize - block_offset;continue;}/* 调整 写入 大小 */if (left_to_write (blocksize - block_offset))write_size left_to_write;elsewrite_size blocksize - block_offset;/* 写入 block *//* * 注意前后的两个 nand_write() 不是同一个函数: * . 前一个 nand_write() 是 MTD 驱动层的 接口* . 后一个是 NAND 驱动层的 接口*/rval nand_write(nand, offset, truncated_write_size, p_buffer); /* drivers/mtd/mtcore.c */mtd_write()mtd-_write(mtd, to, len, retlen, buf);nand_write() /* drivers/mtd/nand/nand_base.c */struct mtd_oob_ops ops;nand_get_device(mtd, FL_WRITING);memset(ops, 0, sizeof(ops));ops.len len;ops.datbuf (uint8_t *)buf;ops.mode MTD_OPS_PLACE_OOB;ret nand_do_write_ops(mtd, to, ops); /* NAND 设备写操作 */*retlen ops.retlen;nand_release_device(mtd);return ret;/* 写入后再读回来验证一下数据是否正确 */if ((flags WITH_WR_VERIFY) !rval)rval nand_verify(nand, offset,truncated_write_size, p_buffer);offset write_size;p_buffer write_size;...left_to_write - write_size;}ret nand_do_write_ops(mtd, to, ops); /* NAND 设备写操作 */...struct nand_chip *chip mtd-priv;uint32_t writelen ops-len;......while (1) {int bytes mtd-writesize; /* 按 page 写入 */...uint8_t *wbuf buf; /* 数据 */...if (unlikely(oob)) {...} else {/* We still need to erase leftover OOB data */memset(chip-oob_poi, 0xff, mtd-oobsize); /* 没有指定 OOB 数据, 则将 Spare area 全部填充 0xff */}ret chip-write_page(mtd, chip, column, bytes, wbuf,oob_required, page, cached,(ops-mode MTD_OPS_RAW)); /* 写入一个 page 的数据 */nand_write_page()...chip-cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);if (unlikely(raw))status chip-ecc.write_page_raw(mtd, chip, buf, oob_required);else if (subpage)status chip-ecc.write_subpage(mtd, chip, offset, data_len, buf, oob_required);else /* 这里只考虑这一种情形 */status chip-ecc.write_page(mtd, chip, buf, oob_required);nand_write_page_hwecc()int i, eccsize chip-ecc.size;int eccbytes chip-ecc.bytes;int eccsteps chip-ecc.steps;uint8_t *ecc_calc chip-buffers-ecccalc;const uint8_t *p buf; /* 要写入的数据 */uint32_t *eccpos chip-ecc.layout-eccpos;/* 写数据到 NAND, 每次写 eccsize 个字节 (eccsize 是计算 ECC 的单元) */for (i 0; eccsteps; eccsteps--, i eccbytes, p eccsize) {chip-ecc.hwctl(mtd, NAND_ECC_WRITE);chip-write_buf(mtd, p, eccsize); /* 将数据写入到 NAND */chip-ecc.calculate(mtd, p, ecc_calc[i]); /* 计算数据 p 的 ECC, 记录到 ecc_calc[i] */}for (i 0; i chip-ecc.total; i)chip-oob_poi[eccpos[i]] ecc_calc[i];chip-write_buf(mtd, chip-oob_poi, mtd-oobsize); /* 将 ECC 数据写入到 Spare area */return 0;/* 写完一个 page */cached 0;if (!cached || !NAND_HAS_CACHEPROG(chip)) {chip-cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);status chip-waitfunc(mtd, chip);} else {...}return 0;...writelen - bytes;if (!writelen)break;...}... 3.4 NAND 读操作 可以通过 nand read 0x82000000 200000 800000 发起对 NAND 的读操作将 NAND 从 0x200000 位置开始的 0x800000 个字节读取到内存地址 0x82000000 开始的位置。NAND 读操作入口函数为 nand_read_skip_bad() 其逻辑和 nand_write_skip_bad() 非常相似在此不再赘述。值得一提的是nand_read_skip_bad() 读操作会跳过坏块。 3.5 其它 NAND 操作 nand device // 输出当前 NAND 设备信息 nand device dev // 切换到 NAND 设备 dev nand dump[.oob] offset // 导出 NAND page 和 OOB, 带 .oob 后缀仅导出 OOB ......
http://www.ho-use.cn/article/10820003.html

相关文章:

  • 展览馆网站建设方案书沃尔玛网上商城中国
  • 沈阳软件公司 网站制作深圳企业社保登录入口
  • 韶关建网站怎样建立个人网络平台
  • 军用棉被门网站建设网站建设需要哪些证
  • 手机交互设计网站wordpress 新编辑器
  • 企业网站网页网页代码编辑器有哪些软件
  • 安徽网站建设合肥网站建设郑州住房城乡建设官网
  • 网站建设过程发生的费用如何提升网站流量
  • 枫泾网站建设展馆设计的主题有哪些
  • 快速设计网站北京网页设计培训机构
  • 携程网网站是哪家公司做的wordpress远程本地化
  • 汽车网站建设预算梅州在建高铁最新消息
  • 市北区开发建设局 网站php wordpress joom
  • 网站优化北京seowordpress解析
  • django网站开发视频教程下载网站备案需要具备什么条件
  • 东莞专业微网站建设价格dede可以做视频网站
  • 海口自助建站软件最好的网站推广
  • php和html5做网站亦庄公司做网站
  • 阳江 网站开发设计的商城网站建设
  • 网站404页面做晚了WordPress搭建在线电影
  • dw网页制作教案郑州网站优化外包顾问
  • 保险网站哪个好网站优化排名首页
  • 上海网站推广珈维安卓手机怎么搭建网页
  • 网站名称管理生物公司网站建设方案
  • 网站鼠标悬停动态效果代码python基础教程下载
  • 网站如何带来流量重庆娱乐场所最新通知
  • 淘宝上找人做网站百度糯米网站怎么做
  • wordpress本地网站搭建整套课程网站出现风险如何处理方法
  • 网站搭建配置手机app在哪里找
  • 动态公司网站设计js跳转网站