前言:

  在开发板上的折腾终归是小打小闹,真正的实践还需要从实际项目和自己参考画的板子选的器件入手,记录更换未经SDK包测试过的国产FLASH调试记录和踩到的坑,重点参考SDK文档包下的ReleaseDoc\zh\02.only for reference\software 基于Hifmcv100控制器的Flash移植指南.pdf,还有\ReleaseDoc\zh\00.hardware\chip路径下的Hi3559A╱C V100 ultra-HD Mobile Camera SoC 用户指南.pdf。(顺便吐槽下海思文档的命名很是规范,存放位置也非常整齐,就是不知道遇见问题的时候该去哪个路径下找查那个文档)

问题描述:

  移植国产DDR和Flash的过程比想象中艰难,所幸不需要完整的从0-1,先控制变量保留开发板同款DDR只更换FLASH试试(因为海思的hitool可以选择烧写类型为DDR,可以将Uboot烧进去通过打印排查Flash的问题)

特别注意:

  最开始保留开发板同款DDR和Flash的时候其实也有问题,不知道是硬件缺陷还是哪里配置不对,在烧写时,必须先上电,并在一秒内快速点击hitool的烧写才能烧写进去,不然会再hitool界面打印几个####后不更新进度条,暂时没查明原因和这么做的影响。而正常开发板是先点击hitool烧写并在15秒之内上电
  选择了可行的烧写“技巧”后,先正常选择烧写到SPI Nand Flash,报错结果如下


  有网友分析可能是硬件问题,但具体的什么原因也没说(结论也对也不对,换硬件也可能解决,实际上不同硬件不同配置的,软件需要支持)

  此时还没有想到手册会补充说明,就按照常规的移植方法判断推测
https://blog.csdn.net/imzhujun/article/details/122230947一文中提到,也有类似情况,修改了flash的id就好了,跟硬件工程师简单反馈后开始同步尝试
  查阅datasheet,在/osdrv/opensource/uboot/u-boot-2016.11/drivers/mtd/nand/hifmc100/hifmc_spi_nand_ids.c里增加flash型号

  修改后尝试先烧进ddr里准备在通过命令行读写进flash对比,

  发现压根就没有发现flash啊,spi nand id都没有读到,大小直接0MB,
  再次和硬件工程师沟通之后确认电压为1.8V,也就是说,并不是之前认为的这个型号,那现在的ID肯定是不对了,

  重新添加

  重新编译

make clean
make CROSS_COMPILE=aarch64-himix100-linux- hi3559av100_defconfig
make CROSS_COMPILE=aarch64-himix100-linux- -j 20
make CROSS_COMPILE=aarch64-himix100-linux- u-boot-z.bin

  烧录

  那这样做的具体依据是什么呢,假如没有其他芯片的参考代码怎么做呢(一般都会有)?

官方提供的添加方式:

  非标驱动中 SPI Nand ID 注册信息示例如下:

特别注意

  FMC 控制器自身集成 ECC 纠错功能,FMC 启动之后会关掉 SPI Nand Flash 器件的ECC,而关闭 ECC 这个动作,只能支持将 B0h Feature 寄存器的 bit4 置成 0。所以,判断一颗 SPI Nand Flash 器件 FMC 能不能支持的第一步就是先看看这颗器件的 B0h Feature 寄存器的 bit4 是否是 ECC_EN bit,如果不是,那就不支持

 &emsp查看我们的芯片手册

  首先要确认是支持的
  新移植一个 SPI Nand Flash 器件,简单来说就是往 hifmc_spi_nand_ids.c 的 ID 注册信息结构体中增加一个 ID 节点,

步骤 1 查阅器件手册,新增 ID 节点,在节点的相应位置填信息


  3.3V和1.8V分别对应了两个型号,也就是上文我们最终选择的E5,21
  获取器件的 chip size、block size、page size、OOB size 信息,其他信息不确定的情况下,保持跟示例中的 ID 信息一致

步骤 2 从手册的 Features 章节中获取器件所支持的接口类型:


步骤 3 确定接口的 dummy 值和工作时钟:

1. Dummy num 的确认

  参照手册 SPI Nand Flash 的 SPI 接口的定义:
  (1)Standard SPI STD Read 和所有 Write 及 Erase 接口的 Dummy 值为 0;
  (2)Dual-Output/Dual-Input SPI 和 Quad-Output/Quad-Input SPI 接口 Dummy 值为1;
  (3)Dual I/O SPI 和 Quad I/O SPI 的接口 Dummy 值要参考手册计算:
Dual I/O SPI Read

  从器件手册中的波形图可以看出 Dual I/O SPI Read 需要 15-18 的 4 个 dummy cycle的时钟周期,又因为接口是两线,所以相当于要有 8 dummy cycle bit,相当于 1 dummy cycle Byte。根据芯片手册 dummy_num 的定义:&READ_DUAL_ADDR(1,INFINITE, 108)中 dummy 值填 1。
Quad I/O SPI Read

  从器件手册中的波形图可以看出 Quad I/O SPI Read 需要 11-14 的 4 个 dummy cycle的时钟周期。又因为接口是四线,所以相当于要有 16 dummy cycle bit,相当于 2dummy cycle Byte。根据芯片手册 dummy_num 的定义:&READ_QUAD_ADDR (2,INFINITE, 108)中 dummy 值填 2。

2. 接口工作时钟

  举个例子,接口&READ_QUAD_ADDR(2, INFINITE, 104),中的工作频率是依据每个
手册里面的 AC CHARACTERISTICS 表获取

步骤 4 当根据上面几个步骤填好如下图接口的信息之后,要匹配宏定义。


  在 hifmc_spi_nand_ids.c 源代码路径开头几行中匹配宏定义:

步骤 5 匹配完接口信息,最后一步要匹配器件相关函数钩子&spi_driver_no_qe,(结构体 struct spi_drv),我们需要关注的以下几个:

.wait_ready = spi_general_wait_ready,
.write_enable = spi_general_write_enable,
.qe_enable = spi_general_qe_enable,或.qe_enable = spi_do_not_qe_enable,

  说明:
  目前驱动中对于大部分 SPI Nand Flash 厂家的所使用的功能函数都是有匹配的,如果新增器件是
表格中所列厂家的器件可以尝试使用现成的,不需要额外匹配


  .wait_ready = spi_general_wait_ready,等待器件 ready。
  通过读器件 C0h feature 寄存器的 bit0 WIP 来判断器件是否处于空闲状态,目前所有 SPI Nand Flash 的满足这个机制。

  .write_enable = spi_general_write_enable,写使能接口。
  通过写 C0h feature 寄存器的 bit1 WEL 来改变器件是否可操作,目前所有 SPINand Flash 的满足这个机制。

  区别于 SPI Nor Flash,SPI Nand Flash 器件是不需要复位脚的,因为 FMC 会自动下发复位命令,所以,SPI Nand Flash 默认匹配为四线模式。但是,不是所有的厂家的 SPI Nand Flash 器件出厂时都默认四线,根据 QE bit 的情况分为两类:
  下图 不带 QE bit 的 Feature 寄存器

  下图带 QE bit 的 Feature 寄存器

  .qe_enable = spi_do_not_qe_enable,器件四线接口使能的函数接口:
  Micron MT29F2G01ABA 器件默认上电是四线使能,所以不需要使能四线。但是,有的 SPI Nand Flash 需要使能四线才能使用 QUAD 接口,对应的函数接口是:.qe_enable = spi_general_qe_enable

  当前市面上的 SPI Nand Flash 的 QE bit 使能都是遵循上面驱动中的操作。如果所新增的器件 QE
bit 使能的方式有所差异,可以参考上面的驱动代码进行修改。

步骤 6 将 ID 合入到 hifmc_spi_nand_ids.c 文件中后,编译烧写上电启动查看 U-boot 的打印信息,查看 ECC 是否跟手册要求的 ECC 类型匹配:

报错环节

  众所周知,调试总会出现奇奇怪怪的错误,完整的烧写记录如下

Boot started successfully!Send command:  getinfo version
version: U-Boot 2016.11
[EOT](OK)Send command:  getinfo bootmode
nand
[EOT](OK)Send command:  getinfo nand
Block:128KB Chip:128MB*1 Page:2KB OOB:64B ECC:4bit/512
ID:0xE5 0x21
Name:"DS35M1GA"
[EOT](OK)Send command:  nand erase 0x0 0x60000NAND erase: device 0 offset 0x0, size 0x60000Erasing at 0x0 --  33% complete.
Erasing at 0x20000 --  66% complete.
Erasing at 0x40000 -- 100% complete.
OK
[EOT](OK)Send command:  nand write 0x41000000 0x0 0x60000NAND write: device 0 offset 0x0, size 0x60000
pure data length is 393216, len_incl_bad is 393216393216 bytes written: OK
[EOT](OK)

  在移植过程中难免遇见错误,一次选错了ECC的类型(也不一定会必现)烧写后出现了下图的情况

  根据报错查找到错误打印位于osdrv/opensource/uboot/u-boot-2016.11/drivers/mtd/nand/nand_util.c中,加入打印调试信息,根据输出信息发现其实是在调用nand_verify函数验证写入数据和缓冲区的数据的过程中出错,导致写入不成功。先跳过这个判断发现流程就可以走完了!那就是说只要返回值正确的话就没问题了

nand位反转

  参考到原因可能是:由于nand存在位反转缺陷,当写入页数据的时候,需要根据页数据生成ECC校验码,并写入当前页后面的oob区。当开始读该页的数据的时候,由于nand的位反转缺陷,可能导致读出的数据某位发生了错误。所以需要继续读出oob区的校验码,根据校验码修正数据中的错误位。

  可是校验码其实早在nand_write的时候就已经写入oob区了,读取数据的时候自然会根据oob区的校验码修改数据,为什么还要和缓冲区的数据校验呢?(缓冲区的数据其实就是源数据)查阅了旧版的uboot中,并没有这个判断选项,所以暂且先将其关闭,测试是否能成功。

  对应的日志结果如下

  和之前屏蔽掉判断的结果一样,都是可以烧写进去,但是还是无法正常启动,重启只能打印空格
开始查找对比之前的日志情况,但是在nand write的时候没有报过坏块的错误

  决定nand erase.chip擦除下,发现还是报了很多坏块

  拿hitool烧写是可以烧写成功,可还是重启失败,难道是刚好0地址坏块导致的?
后来查到手册上相关部分是这么描述的。Block0必须为好块

  手册里没有描述BLOCK0都有哪些地址,但是单片机的block0还是很熟悉的,应该大同小异吧

Block0

  连接被控总线的是FLASH,RAM和片上外设,这些功能部件共同排列在一个4GB的地址空间内。我们在编程的时候,操作的也正是这些功能部件。存储器本身不具有地址信息,它的地址是由芯片厂商或用户分配,给存储器分配地址的过程就称为存储器映射。如果给存储器再分配一个地址就叫存储器重映射


  查看现在的烧写日志

  越发怀疑这三个坏块位于block0,影响了坏块表的管理
  直接nand scrub.chip -y,问题解决,证明了是硬件坏块的问题,现在只需要更换全新的flash芯片即可。

nand scrub

  为什么一个指令就会影响芯片不可靠了呢?因为该命令会擦除工厂标记的坏块表,一旦擦除,无法恢复。
  但一般情况下,在u-boot下即使使用了nand scrub也不会感觉到有问题存在,因为一切正常。可是如果你的程序要批量生产,那么使用这个命令后带来的潜在的问题或许是你无法承受的。
  nand flash工厂在一个比较宽的温度和电压范围内测试并标记了nand坏块,这些坏块在一定的温度或电压下仍然可以工作,但可能在另一时刻条件发生改变后便会失效,这将成为一个潜在的定时炸弹。虽然闪存技术在逐步提高,但现在2GB的闪存在出厂时仍然允许存在最多40个坏块。所以一旦将工厂做出的坏块表擦除,将一些坏块作为好块来使用,会给系统的稳定性带来很大的出现问题的几率和危险。遇见过前辈留下了在批量烧写芯片之前使用了这个命令来擦除flash,结果产品中经常出现一些莫名的无法启动的系统的问题,长时间得不到解决。
不过终于U-boot烧进去了!

补充说明

  海思的文档中是这样解释坏块的判定的:

FMC 在 Boot 时,遇到坏块之后能够自动跳过坏块去寻找好块并读取 Boot 信息。每次跳坏块过程最大可以连续跳过 4 个坏块,若在一次跳坏块的过程中连续出现 5 个物理坏块,则 Boot 失败。整个 Boot 过程可以出现若干次跳坏块过程,当遇到好块时,此次跳坏块过程结束,若再次遇到坏块,则开始一次新的跳坏块过程。
FMC 逻辑对坏块的判定条件有三个:
当前物理块的第一个页和最后一个页坏块标记位标记位 0xff。
当前物理块的第一个页和最后一个页空块标记位标记位 0x00。
当前物理块的第一个页和最后一个页的 OOB 所在纠错单元 ECC 可纠错。
只有以上三个条件同时满足,FMC 逻辑才能判定这个快为好块,否则判定为坏块。

海思3559U-Boot移植(二):更换新的SPI Nand Flash相关推荐

  1. 海思3559平台移植二维码解码库zbar

    1. 下载并解压 zbar 源码包: http://zbar.sourceforge.net/download.html zbar-0.10.tar.bz2 解压缩: tar -xvjf zbar-0 ...

  2. 海思Hi3559A平台移植 opencv4.0.0

    原文:https://blog.csdn.net/xclshwd/article/details/85257117 海思Hi3559A平台移植 opencv4.0.0 2018年12月26日 09:5 ...

  3. 海思Hi3516A上移植OpenCV

    最近新换了工作,工作中一项任务是将OpenCV移植到Hi3516A平台上.这项工作涉及到很多步骤,中间可以说经历了千难万险,克服了种种艰难困苦,最终成功了!现将过程详细写出,一方面作为此段工作的总结和 ...

  4. python交叉编译_交叉编译Python3.6.2,使用海思arm-hisiv200-linux-gcc,移植到arm开发板上...

    最近在学习Python,感觉使用Python可以快速的写出程序,比之前使用的C语言快多了,能省出很多时间.多学一点知识有更多的选择.本职工作是嵌入式开发,学习了Python后想移植到开发板上,尝试嵌入 ...

  5. mysql移植海思_live555 交叉编译移植到海思开发板

    1.首先到它的主页下载一个源码包: http://www.live555.com/liveMedia/public/ 我下载的是latest的,具体什么版本还真不清楚 2.放到linux目录下解压: ...

  6. HI3515海思开发板移植3G模块笔记

    硬件平台: 海思Hi3515 Linux 3G模块: 1.移动模块:ZTE M305(TD-SCDMA) 2.联通模块:HUAWEI EM770W(WCDMA) 3.电信模块:HUAWEI EM660 ...

  7. 海思3519上移植Qt5.5.1

    1. 源码下载 网址:http://download.qt.io/archive/qt/5.5/5.5.1/single/ 源码包: qt-everywhere-opensource-src-5.5. ...

  8. 如何在海思 Hi3519AV100上移植YOLOV3 (3)

    隔了好久来填坑,这次写一下怎么在板卡中部署模型. 打个小广告: 海思hi3519av100开发板链接: https://item.taobao.com/item.htm?spm=a230r.1.14. ...

  9. 51-20210316华为海思Hi3516DV300的linux系统编译1(SPI模式)

    51-20210316华为海思Hi3516DV300的linux系统编译 2021/3/16 10:42 https://xueqiu.com/7970718062/159110439 官井想开挖掘机 ...

最新文章

  1. php设置backlog,高并发调优backlog多大合适?
  2. mysql数据库比对视频教程_MySQL数据库全学习实战视频教程(27讲 )
  3. Java RandomAccessFile的使用
  4. 用基于模型和接口的T4来生成RESTful服务
  5. ThreeJS获取快照
  6. 腾讯面试题 TCP/IP协议四个层次
  7. python - hash类型操作
  8. 一条一条来,MySQL变量、流程控制与游标,完整详细可收藏
  9. sys/queue.h分析(图片复制不过来,查看原文)
  10. 《精通Python设计模式》学习之原型模式
  11. maven 打包指定依赖包_Maven打包成Jar文件时依赖包的问题
  12. win10安装时有个修复计算机,win10出现故障,在安全模式下安装Windows更新,彻底修复问题...
  13. 用二分法求方程的近似解的方法
  14. matlab排课方案,求助matlab大神,学校的课程安排太骚了,我们压根就不用学matlab...
  15. 学习总结-《父与子的编程之旅》chapter 3
  16. Java全栈开发---Java ERP系统开发:商业ERP(十三)CXF框架,物流BOS系统开发
  17. 葫芦兄弟java7723_雪人兄弟(官方正版)
  18. 王阳明的智慧:如何让职场从“举步维艰”到“平步青云”?
  19. 查询水果价格c语言程序框图,浙大版《C语言程序设计(第3版)》题目集 练习3-8 查询水果价格 (15 分)...
  20. PVE安装画面灰白只显示鼠标解决方案

热门文章

  1. 搞技术的要不要学习财务知识
  2. 机器人断脚_专家称在火星照片上发现远古机器人断脚!
  3. android app防止锁屏_触控禁止!Touch Protector 锁定屏幕触控功能,避免意外操作(Android)...
  4. Code Composer Studio 安装教程与入门
  5. android 虚拟键盘控制
  6. kc网络电话 不能使用 GPRS蜂窝网络?
  7. 内网转发工具EW的使用
  8. 霍尼韦尔、康斐尔、山特维克可乐满、丹佛斯、希尔顿、诺和诺德等最新资讯 | 跨国企业在中国...
  9. ACCDB与MDB的读取区别
  10. oracle查表空间剩余,查看Oracle表空间剩余