查看: 7148|回复: 17

[求助] KL8X或者K8X的QSPI flash如何使用

[复制链接]

该用户从未签到

2

主题

7

帖子

0

新手上路

Rank: 1

积分
36
最后登录
2017-1-18
发表于 2016-12-16 22:23:48 | 显示全部楼层 |阅读模式
您好!我这边使用KL81的芯片开发,由于它的内部Flash 才128K不够使用,所以我想用QSPI的功能扩展其flash。我不知道如何在keil5 环境中的.scf如何配置具体配置。
我知道答案 目前已有17人回答
回复

使用道具 举报

该用户从未签到

3

主题

90

帖子

0

中级会员

Rank: 3Rank: 3

积分
419
最后登录
1970-1-1
发表于 2016-12-17 09:02:06 | 显示全部楼层
本帖最后由 浪淘沙-407988 于 2016-12-17 09:15 编辑
飘荡的风1 发表于 2016-12-17 00:09
我也是很悲催,公司太小找原厂技术支持,没有人理,说只有新国都、百富这样的公司他们才会派遣调试,找代理 ...

代码跑在QSPI执行的时候需要注意一些细节,避免踩雷:
1. 时序特别敏感的代码不宜放在QSPI上执行,例如看门狗喂狗代码, RTOS的kernel。原因有二:(1). QSPI代码执行的时候,如果缓存未命中,QSPI 会直接从FLASH中读取,有可能满足不了WDOG unlock timing的要求,(2) QSPI读取的速度还是和内部FLASH有点差距的,特别是在没有cache的情况下,所以对于需要频繁执行的代码,不建议放在QSPI上。


2. 如果存在多master 例如,DMA和CPU core 同时访问QSPI Flash,注意合理的分配QSPI AHB buffer,ROM里默认分配的是所有访问都只用BUF3,在实际的应用中可能需要根据需要重新划分

3. 所有涉及到QSPI clock,寄存器的配置的操作都不能在QSPI FLASH上直接执行,可以copy到RAM里或者直接编译在内部FLASH上执行。


回复 支持 1 反对 0

使用道具 举报

  • TA的每日心情

    2017-1-4 08:05
  • 签到天数: 11 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    85

    主题

    1629

    帖子

    1

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    2569

    优秀版主

    最后登录
    2019-3-28
    发表于 2016-12-16 22:57:29 | 显示全部楼层
    KL81支持SPIFI么?
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2017-1-4 08:05
  • 签到天数: 11 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    85

    主题

    1629

    帖子

    1

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    2569

    优秀版主

    最后登录
    2019-3-28
    发表于 2016-12-16 23:07:43 | 显示全部楼层

         scf文件,全名scatter file,中文名分散加载文件,是ARMlink的输入参数,如果你想把你的代码固定的放在存储器的某个特定的位置,用scf文件就特别方便。

         

    1. LOAD_ROM 0x10020000 0x1000      //加载区 名称 起始地址 地址范围  
    2. {  
    3.     EXEC_ROM 0x10020000 0x1000  //执行区 名称 起始地址 地址范围  
    4.     {  
    5.         * (RESET,+FIRST)    //将RESET代码放在区首,最开始执行 FIRST属性符表示放在最开始  
    6.         * (+RO)         //只读代码和数据放在此区域  
    7.     }  
    8.     STACK_TOP 0x20005000 UNINIT 0x0 //UNINIT的意思是没有初始化   栈顶 栈:操作系统自动申请和释放  
    9.     {  
    10.         startup.o (STACK_TOP)   //startup.o STACK_TOP放入此处  
    11.     }  
    12.     STACK 0x20005000 EMPTY -0x1000  //向下空0x1000大小  
    13.     {  
    14.     }  
    15.     HEAP_TOP ImageBase(STACK) UNINIT 0x0    //ImageBase(STACK)不是很懂 从栈底开始堆顶? 堆:程序员自己申请和释放  
    16.     {  
    17.         startup.o (HEAP_TOP)        //startup.o HEAP_TOP放入此处  
    18.     }  
    19.     HEAP ImageBase(STACK) EMPTY -0x0    //空0  
    20.     {  
    21.     }  
    22.     HEAP_BOTTOM ImageBase(HEAP) UNINIT 0x0  
    23.     {  
    24.         startup.o(HEAP_BOTTOM)      //startup.o HEAP_BOTTOM放入此处  
    25.     }  
    26.     DATA_UNINIT 0x20000140 UNINIT 0x40  
    27.     {  
    28.         *(NO_INIT)          //NO_INIT 放入此处  
    29.     }  
    30.     DATA 0x20000240 UNINIT(0x5000-0x240-ImageLength(STACK)-ImageLength(HEAP))  
    31.     {  
    32.         *(+RW,+ZI)          //RW,ZI 放入此处  
    33.     }  
    34. }  

    复制代码

    直接来一个scf文件的实例好了。


    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2017-1-4 08:05
  • 签到天数: 11 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    85

    主题

    1629

    帖子

    1

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    2569

    优秀版主

    最后登录
    2019-3-28
    发表于 2016-12-16 23:09:08 | 显示全部楼层
    看了一下支持XIP
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2017-1-4 08:05
  • 签到天数: 11 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    85

    主题

    1629

    帖子

    1

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    2569

    优秀版主

    最后登录
    2019-3-28
    发表于 2016-12-16 23:26:45 来自手机 | 显示全部楼层
    sdk里面有个demo对照着我给你的例子和片内flash的代码理解一下
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    2

    主题

    7

    帖子

    0

    新手上路

    Rank: 1

    积分
    36
    最后登录
    2017-1-18
     楼主| 发表于 2016-12-17 00:00:16 | 显示全部楼层
    boot 部分:
    #if (defined(__ram_vector_table__))
      #define __ram_vector_table_size__    0x00000140
    #else
      #define __ram_vector_table_size__    0x00000000
    #endif

    #define m_interrupts_start             0x00000000
    #define m_interrupts_size              0x00000140

    #define m_bootloader_config_start      0x000003C0
    #define m_bootloader_config_size       0x00000040

    #define m_flash_config_start           0x00000400
    #define m_flash_config_size            0x00000010

    #define m_text_start                   0x00000410
    #define m_text_size                    0x0001FBF0

    #define m_interrupts_ram_start         0x1FFFA000
    #define m_interrupts_ram_size          __ram_vector_table_size__

    #define m_data_start                   (m_interrupts_ram_start + m_interrupts_ram_size)
    #define m_data_size                    (0x00018000 - m_interrupts_ram_size)

    #if (defined(__usb_use_usbram__))
    #define m_usb_sram_start               0x40100000
    #define m_usb_sram_size                0x00000800
    #endif

    /* USB BDT size */
    #define usb_bdt_size                   0x200
    /* Sizes */
    #if (defined(__stack_size__))
      #define Stack_Size                   __stack_size__
    #else
      #define Stack_Size                   0x0400
    #endif

    #if (defined(__heap_size__))
      #define Heap_Size                    __heap_size__
    #else
      #define Heap_Size                    0x0400
    #endif

    LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_start { ; load region size_region
      VECTOR_ROM m_interrupts_start m_interrupts_size { ; load address = execution address
        * (RESET,+FIRST)
      }
      ER_m_bootloader_config m_bootloader_config_start FIXED m_bootloader_config_size { ; load address = execution address
        * (BootloaderConfig)
      }
      ER_m_flash_config m_flash_config_start FIXED m_flash_config_size { ; load address = execution address
        * (FlashConfig)
      }
      ER_m_text m_text_start m_text_size { ; load address = execution address
        * (InRoot$$Sections)
        .ANY (+RO)
      }

    #if (defined(__ram_vector_table__))
      VECTOR_RAM m_interrupts_ram_start EMPTY m_interrupts_ram_size {
      }
    #else
      VECTOR_RAM m_interrupts_start EMPTY 0 {
      }
    #endif
      RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size { ; RW data
        .ANY (+RW +ZI)
      }
      ARM_LIB_HEAP +0 EMPTY Heap_Size {    ; Heap region growing up
      }
      ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down
      }
    }

    #if (defined(__usb_use_usbram__))
    LR_m_usb_bdt m_usb_sram_start usb_bdt_size {
      ER_m_usb_bdt m_usb_sram_start UNINIT usb_bdt_size {
        * (m_usb_bdt)
      }
    }

    LR_m_usb_ram (m_usb_sram_start + usb_bdt_size) (m_usb_sram_size - usb_bdt_size) {
      ER_m_usb_ram (m_usb_sram_start + usb_bdt_size) UNINIT (m_usb_sram_size - usb_bdt_size) {
        * (m_usb_global)
      }
    }
    #endif
    App 部分:
    #if (defined(__ram_vector_table__))
      #define __ram_vector_table_size__    0x00000140
    #else
      #define __ram_vector_table_size__    0x00000000
    #endif

    #define m_interrupts_start             0x00010000
    #define m_interrupts_size              0x00000140

    #define m_bootloader_config_start      0x000103C0
    #define m_bootloader_config_size       0x00000040

    #define m_flash_config_start           0x00010400
    #define m_flash_config_size            0x00000010

    #define m_text_start                   0x00010410
    #define m_text_size                    0x0000FBF0

    #define m_interrupts_ram_start         0x1FFFA000
    #define m_interrupts_ram_size          __ram_vector_table_size__

    #define m_data_start                   (m_interrupts_ram_start + m_interrupts_ram_size)
    #define m_data_size                    (0x00018000 - m_interrupts_ram_size)

    #if (defined(__usb_use_usbram__))
    #define m_usb_sram_start               0x40100000
    #define m_usb_sram_size                0x00000800
    #endif

    /* USB BDT size */
    #define usb_bdt_size                   0x200
    /* Sizes */
    #if (defined(__stack_size__))
      #define Stack_Size                   __stack_size__
    #else
      #define Stack_Size                   0x0400
    #endif

    #if (defined(__heap_size__))
      #define Heap_Size                    __heap_size__
    #else
      #define Heap_Size                    0x0400
    #endif

    LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_start { ; load region size_region
      VECTOR_ROM m_interrupts_start m_interrupts_size { ; load address = execution address
        * (RESET,+FIRST)
      }
      ER_m_bootloader_config m_bootloader_config_start FIXED m_bootloader_config_size { ; load address = execution address
        * (BootloaderConfig)
      }
      ER_m_flash_config m_flash_config_start FIXED m_flash_config_size { ; load address = execution address
        * (FlashConfig)
      }
      ER_m_text m_text_start m_text_size { ; load address = execution address
        * (InRoot$$Sections)
        .ANY (+RO)
      }

    #if (defined(__ram_vector_table__))
      VECTOR_RAM m_interrupts_ram_start EMPTY m_interrupts_ram_size {
      }
    #else
      VECTOR_RAM m_interrupts_start EMPTY 0 {
      }
    #endif
      RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size { ; RW data
        .ANY (+RW +ZI)
      }
      ARM_LIB_HEAP +0 EMPTY Heap_Size {    ; Heap region growing up
      }
      ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down
      }
    }

    QSPI 0x68001000  0xFF000
    {
      *.o(.qspi);
    }

    #if (defined(__usb_use_usbram__))
    LR_m_usb_bdt m_usb_sram_start usb_bdt_size {
      ER_m_usb_bdt m_usb_sram_start UNINIT usb_bdt_size {
        * (m_usb_bdt)
      }
    }

    LR_m_usb_ram (m_usb_sram_start + usb_bdt_size) (m_usb_sram_size - usb_bdt_size) {
      ER_m_usb_ram (m_usb_sram_start + usb_bdt_size) UNINIT (m_usb_sram_size - usb_bdt_size) {
        * (m_usb_global)
      }
    }
    #endif

    需要下载到QSPI flash的代码:
    void __attribute__((section(".qspi"), noinline)) GpioToggle(void)
    {
    LED_Toggle(LED1);
    Delay(200);
    }

    main 中调用:
    GpioToggle();

    这种方式行的通吗?
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    2

    主题

    7

    帖子

    0

    新手上路

    Rank: 1

    积分
    36
    最后登录
    2017-1-18
     楼主| 发表于 2016-12-17 00:09:46 | 显示全部楼层
    我也是很悲催,公司太小找原厂技术支持,没有人理,说只有新国都、百富这样的公司他们才会派遣调试,找代理的技术支持他们不会使用。QSPI的bootloader 调试两个星期都没成功。实在是没有办法了
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    3

    主题

    90

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    419
    最后登录
    1970-1-1
    发表于 2016-12-17 09:00:29 | 显示全部楼层
    飘荡的风1 发表于 2016-12-17 00:09
    我也是很悲催,公司太小找原厂技术支持,没有人理,说只有新国都、百富这样的公司他们才会派遣调试,找代理 ...

    这位朋友, KL8x/K8x都直接支持从QSPI boot的,如果有相关的问题,请提供详细的失败步骤,我应该能帮到您
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    3

    主题

    90

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    419
    最后登录
    1970-1-1
    发表于 2016-12-17 09:00:48 | 显示全部楼层
    本帖最后由 浪淘沙-407988 于 2016-12-17 09:08 编辑
    飘荡的风1 发表于 2016-12-17 00:09
    我也是很悲催,公司太小找原厂技术支持,没有人理,说只有新国都、百富这样的公司他们才会派遣调试,找代理 ...

    您可以从www.nxp.com/kboot里下载 Kinetis Bootloader 2.0的发布包,里面也提供了详细的QSPI boot的文档,在压缩包的doc目录下(Kinetis Bootloader QuadSPI User's Guide.pdf),包括如何配置QSPI boot,QSPI boot的注意事项,也提供了配套的Demo 例程 (apps/demo_qspi/led_demo/targets/TWR-KL82Z72M 或 FRDM-KL82Z)。
    KL8x/K8x 的 BootROM是直接支持对QSPI Flash 进入编程的。

    如果有其他任何疑问,欢迎在这里提问,另外最好提供一下您用的QSPI Flash的型号,这样如果有问题我们能一起定位问题。

    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-9-6 15:29 , Processed in 0.106454 second(s), 30 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表