点击“硬核王同学” 选择关注|点赞|收藏” 

福利干货第一时间送达!

大家好,我是硬核王同学,最近在做免费的嵌入式知识分享,帮助对嵌入式感兴趣的同学学习嵌入式、做项目、找工作!

什么是Flash?

定义:Flash芯片是一种 非易失性存储器,断电后仍能保存数据,广泛应用于嵌入式设备存储程序与数据。

核心特性:

  1. 非易失性:数据长期保存,无需电源。

  2. 块擦除:以固定块(如4KB)为单位擦写,无法单字节修改。

  3. 有限寿命:擦写次数受限(如NAND Flash约千次至十万次)。

类型与用途:

  • NOR Flash:支持代码直接运行(XIP),用于存储 启动程序(如U-Boot),速度快但容量小。

  • NAND Flash:容量大、成本低,用于 大容量存储(如嵌入式文件系统),需ECC纠错。

如何在Uboot上移植NOR Flash芯片?

1.确定硬件正常。在硬件产品方案已经得到正常的验证情况下,在板子上替换flash芯片,排查flash有无虚焊。

2.烧写uboot,有3种办法。第一种,通过专用的烧录器,在还没有焊接到板子之前,给flash芯片烧写镜像;第二种,将uboot文件转换成xmodem,通过串口烧写;第三种,在uboot的环境下,通过cmd命令烧写。

3.在uboot上修改源码,将flash芯片移植进来。

4.重新烧写uboot,确认flash芯片是否识别并正常跑通。

如果焊接出错,有如图打印:

用烧录器烧录镜像到flash,可以看这篇文章:https://jingyan.baidu.com/article/27fa7326ef938107f8271f97.html

uboot文件转换成xmodem,通过串口将给flash烧写,可以看这篇文章:

uboot文件转换成xmodem,通过串口将给flash烧写

在uboot的环境下,通过cmd命令烧写flash,可以看这篇文章:

在uboot的环境下,通过cmd命令烧写flash

那么如何修改源码,移植flash识别并正常跑通呢?

移植一个新的flash需要做的事情很简单,将flash对应的id和一些特性加入uboot中就可以了。

当验证过uboot源码在原来的硬件方案上是可以正常使用的,先烧录一个正常可用的uboot到flash上。再在这个基础上去修改源码。

之前用的flash,型号为XM25QH128C,直接搜一下这个名字,可以找到和这颗芯片相关的代码文件。

可以看到是在uboot/drivers/mtd/spi/xmc.c这个文件中有XM25QH128C的代码,实际上在这个文件中添加我们新的flash芯片的id和特性就可以正常使用了,同一家公司的flash驱动都是可以通用的,如果出现没有通用的驱动,就需要我们根据别的公司的驱动一点点调试移植了。

这次移植的芯片是XM25QH256CXM25QH256C _ Ver 2.0.pdf,从芯片手册中可以看到,芯片的id是4019。

那么在flash的id表中把这个芯片加进来就可以了。

diff --git a/uboot/drivers/mtd/spi/xmc.c b/uboot/drivers/mtd/spi/xmc.c
index adbfe47..97b2b25 100644
--- a/uboot/drivers/mtd/spi/xmc.c
+++ b/uboot/drivers/mtd/spi/xmc.c
@@ -43,6 +43,7 @@
 #define XMC_ID_XM25QH64B       0x6017
 #define XMC_ID_XM25QH128C      0x4018
 #define XMC_ID_XM25QH64C       0x4017
+#define XMC_ID_XM25QH256C      0x4019
 
 #define XMC_SR_WIP             (1 << 0)        /* Write-in-Progress */
 #define XMC_SR_WEL      (1 << 1)
@@ -181,6 +182,20 @@ static struct xmc_spi_flash_params xmc_spi_flash_table[] = {
                        {.speed = 50000000,.delay = 1,},
                },
        },
+       {
+               .id                     = XMC_ID_XM25QH256C,
+               .l2_page_size           = 8,
+               .pages_per_sector       = 16,
+               .sectors_per_block      = 16,
+               .nr_blocks              = 512,
+               .name                   = "XM25QH256C",
+#ifdef FLASH_MULTI_WIRE_SUPPORT
+               .multi_wire_open = ONE_WIRE_SUPPORT | DUAL_WIRE_SUPPORT | QUAD_WIRE_SUPPORT | MULTI_WIRE_SUPPORT,
+#endif
+               .spd_info = {
+                       {.speed = 50000000,.delay = 1,},
+               },
+       },
 
 };

注意,这里的参数是如何计算的?

一、已知条件
总存储容量:
XM25QH256C 的总存储容量为 256M-bit,即 32M-byte。
换算为字节:Total Capacity=32×1024 KB=32768 KBTotal Capacity=32×1024KB=32768KB
存储组织结构:
手册中提到以下关键参数:
Page Size:页面大小为 256 字节(l2_page_size = 8 表示 2828 字节)。
Pages per Sector:每个扇区包含 16 个页。
Sectors per Block:每个块包含 16 个扇区。
二、逐级计算
1. 单个页的大小
根据 l2_page_size = 8,表示页面大小为 2828 字节:Page Size=256 BytesPage Size=256Bytes
2. 单个扇区的大小
每个扇区包含 16 个页,因此:Sector Size=Page Size×Pages per Sector=256×16=4096 Bytes=4 KBSector Size=Page Size×Pages per Sector=256×16=4096Bytes=4KB
3. 单个块的大小
每个块包含 16 个扇区,因此:Block Size=Sector Size×Sectors per Block=4096×16=65536 Bytes=64 KBBlock Size=Sector Size×Sectors per Block=4096×16=65536Bytes=64KB
4. 总块数
总存储容量为 32MB,因此总块数为:Total Blocks=Total CapacityBlock Size=3276864=512Total Blocks=Block SizeTotal Capacity=6432768=512
三、验证与总结
通过上述计算可以得出:
每个块的大小为 64KB。
总共有 512 个块。

编译后,重新烧写uboot,通过cmd命令:sf probe 0可以看到flahs识别成功!

如何在Kernel上移植NOR Flash芯片?

1.确定硬件正常。在硬件产品方案已经得到正常的验证情况下,在板子上替换flash芯片,排查flash有无虚焊。

2.确定uboot启动正常,flash芯片能正常启动。

3.在kernel上修改源码,将flash芯片移植进来。

4.重新烧写kernel,确认flash芯片是否识别并正常跑通。

kernel上移植一个新的flash就更简单了,内核的驱动非常完善,将flash对应的id和一些特性加入内核中就可以了。

先找一下之前用的flash,在源码的哪个地方。

可以看到,是在drivers/mtd/spi-nor/spi-nor.c这个文件中,那么也是将这个芯片加进来就可以正常识别了。

diff --git a/linux-4.9/drivers/mtd/spi-nor/spi-nor.c b/linux-4.9/drivers/mtd/spi-nor/spi-nor.c
index 3fb4c23..3e4a28e 100755
--- a/linux-4.9/drivers/mtd/spi-nor/spi-nor.c
+++ b/linux-4.9/drivers/mtd/spi-nor/spi-nor.c
@@ -1150,6 +1150,9 @@ static const struct flash_info spi_nor_ids[] = {
        { "xm25qh64c", INFO(0x204017,  0, 64 * 1024, 128,
                SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
                FLASH_DEFAULT_CLOCK_FREQ)},
+       { "xm25qh256c", INFO(0x204019,  0, 64 * 1024, 512,
+               SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
+               FLASH_DEFAULT_CLOCK_FREQ)},
        { "nm25q128evb", INFO(0x522118, 0, 64 * 1024, 256,
                SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
                FLASH_DEFAULT_CLOCK_FREQ)},

重新烧录kernel后,在内核启动打印处查到flash芯片被正常识别加载!

------  END  ------

如果觉得有用请点个免费的赞

  您的支持就是我最大的动力,这对我很重要!!!

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐