在全志V3/V3s和索智S3/S3L上调试32MB NorFlash

Posted ka布

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在全志V3/V3s和索智S3/S3L上调试32MB NorFlash相关的知识,希望对你有一定的参考价值。

选取MX25L25635F作为调试对象,其他型号的NorFlash开发调试原理基本一致。为了使V3/V3s/S3/S3L识别32MB NorFlash并正常工作,主要针对以下三个部分进行开发和调试。下文将针对这三个部分的开发进行说明。

  1. U-Boot
  2. Linux Kernel
  3. System Configuration

 

第一部分,U-boot

原始的SDK包支持3线模式,但没有支持4线模式,因此,必须在引导过程中加入4线模式。简单解释一下,3线模式是指NorFlash支持3x8位地址线,可以访问的地址空间是16MB(2^24/1024/1024),4线模式支持4x8位地址线,可以访问比16MB大的地址空间。找到源码文件drivers/spinor/sunxi_spinor.c,增加4线模式的使能函数。

static void spinor_enter_4bytes_addr(int enable)
{
    int command = 0;
    if(spinor_4bytes_addr_mode == 1 && enable == 1)
        command = 0xB7;
    else if(spinor_4bytes_addr_mode == 1 && enable == 0)
        command = 0xE9;
else return ;
#ifdef CONFIG_ARCH_SUN8IW8P1 spic_config_dual_mode(
0, 0, 0, 1); #endif spic_rw(1, (void*)&command, 0, 0); return; }

需要注意的是,0xB7和0xE9不代码所有32MB NorFlash的4线模式进入/退出命令,应从datasheet中获取相应的命令值。接下来,找到spinor_init函数,回复flash size大于16MB的处理。

if(spi_size > 16*1024*1024/512)
{
    spinor_4bytes_addr_mode = 1;
    spinor_enter_4bytes_addr(ENABLE_4BYTES);
}

找到NorFlash读写函数__spinor_pp和__spinor_sector_normal_read,增加4线模式的数据读写代码片段。

------------if(spinor_4bytes_addr_mode == 0)
{
    txnum = len+4;
    sdata[0]  =  SPINOR_PP;
    sdata[1]  = (page_addr >> 16) & 0xff;
    sdata[2]  = (page_addr >> 8 ) & 0xff;
    sdata[3]  =  page_addr        & 0xff;
    memcpy((void *)(sdata+4), buf, len);
}
else if(spinor_4bytes_addr_mode == 1)
{
    txnum = len+5;
    sdata[0]  =  SPINOR_PP;
    sdata[1]  = (page_addr >> 24) & 0xff;
    sdata[2]  = (page_addr >> 16) & 0xff;
    sdata[3]  = (page_addr >> 8 ) & 0xff;
    sdata[4]  =  page_addr        & 0xff;
    memcpy((void *)(sdata+5), buf, len);
}
------------if(spinor_4bytes_addr_mode == 0)
{
    txnum = 4;
    sdata[0]  =  SPINOR_READ;
    sdata[1]  = (page_addr >> 16) & 0xff;
    sdata[2]  = (page_addr >> 8 ) & 0xff;
    sdata[3]  =  page_addr        & 0xff;
}
else if(spinor_4bytes_addr_mode == 1)
{
    txnum = 5;
    sdata[0]  =  SPINOR_READ;
    sdata[1]  = (page_addr >> 24) & 0xff;
    sdata[2]  = (page_addr >> 16) & 0xff;
    sdata[3]  = (page_addr >> 8 ) & 0xff;
    sdata[4]  =  page_addr        & 0xff;
}

最后需要在spinor_datafinish_card函数最后退出4线模式,这样做,刷机结束后,系统启动时才可以正确得到boot0,否则会重复刷机。

 

第二部分,Linux Kernel

内核部分的修改比较简单,在NorFlash设备驱动drivers/mtd/devices/m25p80.c中加入针对MX25L25635F这款32MB NorFlash的支持,如下:

--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -724,7 +724,7 @@ static const struct spi_device_id m25p_ids[] = {
        { "mx25l1606e",  INFO(0xc22015, 0, 64 * 1024,  32, SECT_4K) },
        { "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, 0) },
        { "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, 0) },
-       { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
+       { "mx25l12805f", INFO(0xc22018, 0, 64 * 1024, 512, 0) },
        { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
        { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
        { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
@@ -1136,6 +1136,22 @@ static int __devexit m25p_remove(struct spi_device *spi)
 }
 
 
+static int  m25p_shutdown(struct spi_device *spi)
+{
+       struct m25p     *flash = dev_get_drvdata(&spi->dev);
+       const struct spi_device_id      *id = spi_get_device_id(spi);
+       struct flash_info               *info;
+    printk("m25p: spinor shutdown\n");
+
+       if(flash->addr_width == 4)
+       {
+               info = (void *)id->driver_data;
+               set_4byte(flash, info->jedec_id, 0);
+       }
+       return 0;
+}
+
+
 static struct spi_driver m25p80_driver = {
        .driver = {
                .name   = "m25p80",
@@ -1144,6 +1160,7 @@ static struct spi_driver m25p80_driver = {
        .id_table       = m25p_ids,
        .probe  = m25p_probe,
        .remove = __devexit_p(m25p_remove),
+       .shutdown = m25p_shutdown,
 
        /* REVISIT: many of these chips have deep power-down modes, which
         * should clearly be entered on suspend() to minimize power use.

 

第三部分,System Configuration

V3/V3s/S3/S3L这4个平台的SDK里面,U-Boot和Kernel都会调用sys_config.fex的Nor配置,需要将Nor Flash的大小修改成32,意思是32MB。

@@ -301,7 +298,8 @@ max_speed_hz  = 50000000
 bus_num       = 0
 chip_select   = 0
 mode          = 0
-sflash_size             = 16
+sflash_size   = 32

 

完成上述三个环节的修改以后,依次编译U-Boot,Linux Kernel,最后打包Firmware,烧录到设备。

以上是关于在全志V3/V3s和索智S3/S3L上调试32MB NorFlash的主要内容,如果未能解决你的问题,请参考以下文章

仅用5000行代码,在全志V853上AI渲染出一亿幅山水画

Yolov5s模型在全志V853平台上的部署方法和应用

全志V853的NPU的demo试玩

嵌入式AI全志 R329 板子跑 mobilenetv2

全志Uboot fdt修改DTS进行临时调试的方法

全志 Tina Linux 系统调试 使用指南 GDB gdbserver coredump perf strace valgind