RT1176 M4 LPSPI驱动移植到RT-THREAD(失败,原因未知)

调试内容:RT1176 LPSPI在RTT框架下,使用阻塞模式发送数据
开发环境:RTT Studio
测试工具:逻辑分析仪 Kingst LA5016
开发板: MIMXRT1170-EVK
使用引脚:LPSPI1
运行内核: M4
分別对应:
GPIO_AD_28 <-> LPSPI1_SCK
GPIO_AD_29 <-> LPSPI1_PCS0
GPIO_AD_30 <-> LPSPI1_SDO
GPIO_AD_31 <-> LPSPI1_SDI
在这里插入图片描述
在这里插入图片描述

步骤一 :引脚配置

思路:由底层往上逐层配置

  1. 先在MCUXpresso Config Tools上配置好SPI的引脚,分别是
    在这里插入图片描述
  2. 将fsl_lpspi.c添加构建
  3. 将drv_spi.c添加构建
  4. 将rt-thread/components/drivers/spi目录下的 spi_core.c添加构建

步骤二:RTT的配置

RTT有两处地方要配置

第一处

文件配置完成后,对 board/Kconfig进行修改,目的是打开 BSP_USING_SPI1的宏定义
drv_spi.c中默认有4路SPI,SPI有三种模式:阻塞,中断,DMA
先使用阻塞的模式
在这里插入图片描述
以下是Kconfig的代码

menuconfig BSP_USING_SPI
        bool "Enable SPI"
        select RT_USING_SPI
        default y
        
        if BSP_USING_SPI
            config BSP_USING_SPI1
                bool "Enable SPI1"
                default n

				config BSP_SPI1_USING_DMA
                    bool "Enable SPI1 DMA"
                    depends on BSP_USING_SPI1
                    select BSP_USING_DMA
                    select RT_SPI_USING_DMA
                    default n

                    config BSP_SPI1_TX_DMA_CHANNEL
                        depends on BSP_SPI1_USING_DMA
                        int "Set SPI1 TX DMA channel (0-32)"
                        default 0
                        
                    config BSP_SPI1_RX_DMA_CHANNEL
                        depends on BSP_SPI1_USING_DMA
                        int "Set SPI1 RX DMA channel (0-32)"
                        default 1    

            config BSP_USING_SPI2
                bool "Enable SPI2"
                default n
				
				 config BSP_SPI2_USING_DMA
                    bool "Enable SPI2 DMA"
                    depends on BSP_USING_SPI2
                    select BSP_USING_DMA
                    select RT_SPI_USING_DMA
                    default n

                    config BSP_SPI2_TX_DMA_CHANNEL
                        depends on BSP_SPI2_USING_DMA
                        int "Set SPI2 TX DMA channel (0-32)"
                        default 2
                        
                    config BSP_SPI2_RX_DMA_CHANNEL
                        depends on BSP_SPI2_USING_DMA
                        int "Set SPI2 RX DMA channel (0-32)"
                        default 3               
                        
            config BSP_USING_SPI3
                bool "Enable SPI3"
                default n
				
				 config BSP_SPI3_TX_USING_DMA
                    bool "Enable SPI3 TX DMA"
                    depends on BSP_USING_SPI3
                    select BSP_USING_DMA
                    select RT_SPI_USING_DMA
                    default n

                    config BSP_SPI3_TX_DMA_CHANNEL
                        depends on BSP_SPI3_TX_USING_DMA
                        int "Set SPI3 TX DMA channel (0-32)"
                        default 0
                        
                config BSP_SPI3_RX_USING_DMA
                    bool "Enable SPI3 RX DMA"
                    depends on BSP_USING_SPI3
                    select BSP_USING_DMA
                    select RT_SPI_USING_DMA
                    default n

                    config BSP_SPI3_RX_DMA_CHANNEL
                        depends on BSP_SPI3_RX_USING_DMA
                        int "Set SPI3 RX DMA channel (0-32)"
                        default 1
                        
			config BSP_USING_SPI4
                bool "Enable SPI4"
                default n
				
				 config BSP_SPI4_TX_USING_DMA
                    bool "Enable SPI4 TX DMA"
                    depends on BSP_USING_SPI4
                    select BSP_USING_DMA
                    select RT_SPI_USING_DMA
                    default n

                    config BSP_SPI4_TX_DMA_CHANNEL
                        depends on BSP_SPI4_TX_USING_DMA
                        int "Set SPI4 TX DMA channel (0-32)"
                        default 0
                        
                config BSP_SPI4_RX_USING_DMA
                    bool "Enable SPI4 RX DMA"
                    depends on BSP_USING_SPI4
                    select BSP_USING_DMA
                    select RT_SPI_USING_DMA
                    default n

                    config BSP_SPI4_RX_DMA_CHANNEL
                        depends on BSP_SPI4_RX_USING_DMA
                        int "Set SPI4 RX DMA channel (0-32)"
                        default 1                        
        endif
endmenu

第二处

在这里插入图片描述

步骤三 设备的初始化

step1 将设备挂载到总线上

按照RTT框架对SPI进行挂载
首先要区分RTT中 SPI设备,和SPI总线的区别
在console中分别是 SPI deviceSPI bus

SPI BUS不需要额外初始化,RTT已经帮你做好了

但SPI device需要自己挂载,因为 device 可以不止一个,可以有 spi11 spi12 等

比如下面的代码,就是将spi10设备挂载到 spi1总线上

 ret = rt_hw_spi_device_attach("spi1","spi10",pin_EVB_SPI1_CS);

step2 对设备进行设置

设置SPI的波特率,主从,MSB或LSB,数据宽度等
比如下面的代码,另外可以将该函数,用 INIT_DEVICE_EXPORT 添加到初始化段中,
到时RTT就会自己调用了

	struct rt_spi_configuration cfg;
    cfg.data_width = 8;
    cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
    cfg.max_hz = 12000000U;//12*1000*1000;//50 * 1000 *1000;    /* 20M */
    struct rt_spi_device *SPI1_EVB;

    SPI1_EVB = (struct rt_spi_device *)rt_device_find("spi10"); /*要用rt_device_find获取 spi10的句柄*/

    rt_spi_configure(SPI1_EVB, &cfg);

步骤四 :数据的发送

同样需要先找到设备的句柄,然后设置数据,最后调用 rt_spi_transfer_message()
需要注意的是,

  1. 这里的 length指的数据的字节数(非位数)
  2. 如果recv_buf 为 NULL,RTT会自动设置成 TX ONLY模式,会对SPI的寄存器中的RXMASK赋值为1
	#define TRANSFER_SIZE 8
	struct rt_spi_device *SPI1_Dev;
	uint8_t loopCount = 1;
	SPI1_Dev = (struct rt_spi_device *)rt_device_find("spi10");
	if (!SPI1_Dev)
	{
		rt_kprintf("can't find %s device!\n", SPI_BUSNAME_HC165);
	}
	else
	{
		/* 此处使用了MIMXRT1170-SDK_2_11_1的代码,目的是和SDK发同样的数据*/
		 /* Set up the transfer data */
        for (i = 0U; i < TRANSFER_SIZE; i++)
        {
            masterTxData[i] = (i + loopCount) % 256U;
            masterRxData[i] = 0U;
        }
		struct rt_spi_message msg;
		msg.send_buf   = masterTxData;
		msg.recv_buf   = RT_NULL;//&Rx_Buffer;
		msg.length     = 8;
		msg.cs_take    = 1;
		msg.cs_release = 1;
		msg.next       = RT_NULL;
		rt_spi_transfer_message(SPI1_Dev, &msg);
	}        

上机效果

BSP的运行结果
在这里插入图片描述在这里插入图片描述
可见上图中时钟SCK波形有杂讯,CS片选也被离奇拉起,MOSI的数据本应该是1

SDK的运行结果
在这里插入图片描述
在这里插入图片描述
时钟信号很干净

在这里插入图片描述
而且片选一切正常

Debug思路

步骤1 确定RTT的配置有无错误

首先确认RTT配置的代码,以及发送的代码有无问题:
同样的应用代码,在正点原子STM32F767的开发板上运行,
波形和数据一样,一切正常

所以排除是RTT应用代码的问题

步骤2 确定是否 NXP 的 fsl层驱动有问题

接下来确认是否NXP提供的 fsl层驱动有问题,于是我用SDK的例程,在RT1176开发板运行了一遍,得到波形正常(非常漂亮)
在这里插入图片描述

步骤3 怀疑是 RTT 提供的 drv_spi.c 有问题

于是我把SDK的代码复制到了RTT的工程里,并放置到了 rt_hw_board_init()中,
目的是跳过RTT的框架,将运行顺序变得和SDK一样
这是我复制的SDK的代码
在这里插入图片描述

以下是SDK的运行顺序
在这里插入图片描述
但是运行结果仍然和使用RTT框架一样,并无改善。

步骤4 怀疑点

对比了SDK和修改后的RTT工程,唯一区别的地方是 RTT的链接脚本 和 SDK的链接脚本,
所以目前还在研究两个链接脚本的区别,不知道是否对代码运行有影响
以下贴下两者链接脚本:

SDK的:
#!armclang --target=arm-arm-none-eabi -mcpu=cortex-m4 -E -x c
/*
** ###################################################################
**     Processors:          MIMXRT1176AVM8A_cm4
**                          MIMXRT1176CVM8A_cm4
**                          MIMXRT1176DVMAA_cm4
**
**     Compiler:            Keil ARM C/C++ Compiler
**     Reference manual:    IMXRT1170RM, Rev 1, 02/2021
**     Version:             rev. 1.0, 2020-12-29
**     Build:               b210709
**
**     Abstract:
**         Linker file for the Keil ARM C/C++ Compiler
**
**     Copyright 2016 Freescale Semiconductor, Inc.
**     Copyright 2016-2021 NXP
**     All rights reserved.
**
**     SPDX-License-Identifier: BSD-3-Clause
**
**     http:                 www.nxp.com
**     mail:                 support@nxp.com
**
** ###################################################################
*/

#if (defined(__ram_vector_table__))
  #define __ram_vector_table_size__    0x00000400
#else
  #define __ram_vector_table_size__    0x00000000
#endif

#define m_flash_config_start           0x08000400
#define m_flash_config_size            0x00000C00

#define m_ivt_start                    0x08001000
#define m_ivt_size                     0x00001000

#define m_interrupts_start             0x08002000
#define m_interrupts_size              0x00000400

#define m_text_start                   0x08002400
#define m_text_size                    0x00FFDC00

#define m_qacode_start                 0x1FFE0000
#define m_qacode_size                  0x00020000

#define m_interrupts_ram_start         0x20000000
#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                    (0x00020000 - m_interrupts_ram_size)

#define m_ncache_start                 0x20280000
#define m_ncache_size                  0x00040000

#define m_data2_start                  0x20240000
#define m_data2_size                   0x00040000

/* 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

#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1)
LR_m_text m_flash_config_start m_text_start+m_text_size-m_flash_config_start {   ; load region size_region
  RW_m_config_text m_flash_config_start FIXED m_flash_config_size { ; load address = execution address
    * (.boot_hdr.conf, +FIRST)
  }

  RW_m_ivt_text m_ivt_start FIXED m_ivt_size { ; load address = execution address
    * (.boot_hdr.ivt, +FIRST)
    * (.boot_hdr.boot_data)
    * (.boot_hdr.dcd_data)
  }
#else
LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_start {   ; load region size_region
#endif
  VECTOR_ROM m_interrupts_start FIXED m_interrupts_size { ; load address = execution address
    * (.isr_vector,+FIRST)
  }
  ER_m_text m_text_start FIXED 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
#if (defined(__heap_noncacheable__))
  RW_m_data m_data_start m_data_size-Stack_Size { ; RW data
#else
  RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size { ; RW data
#endif
    .ANY (+RW +ZI)
    * (RamFunction)
    * (DataQuickAccess)
  }
#if (!defined(__heap_noncacheable__))
  ARM_LIB_HEAP +0 EMPTY Heap_Size {    ; Heap region growing up
  }
#endif
  ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down
  }
  RW_m_ram_text m_qacode_start m_qacode_size { ;
    * (CodeQuickAccess)
  }
#if (defined(__heap_noncacheable__))
  RW_m_ncache m_ncache_start m_ncache_size - Heap_Size { ; ncache data
#else
  RW_m_ncache m_ncache_start m_ncache_size { ; ncache data
#endif
    * (NonCacheable.init)
    * (*NonCacheable)
  }
#if (defined(__heap_noncacheable__))
  ARM_LIB_HEAP +0 EMPTY Heap_Size {    ; Heap region growing up
  }
  RW_m_ncache_unused +0 EMPTY m_ncache_size-ImageLength(RW_m_ncache)-Heap_Size { ; Empty region added for MPU configuration
#else
  RW_m_ncache_unused +0 EMPTY m_ncache_size-ImageLength(RW_m_ncache) { ; Empty region added for MPU configuration
#endif
  }
}

RTT工程的:
/*
** ###################################################################
**     Processors:          MIMXRT1052CVL5A
**                          MIMXRT1052DVL6A
**
**     Compiler:            GNU C Compiler
**     Reference manual:    IMXRT1050RM Rev.C, 08/2017
**     Version:             rev. 0.1, 2017-01-10
**     Build:               b170927
**
**     Abstract:
**         Linker file for the GNU C Compiler
**
**     Copyright 2016 Freescale Semiconductor, Inc.
**     Copyright 2016-2017 NXP
**     Redistribution and use in source and binary forms, with or without modification,
**     are permitted provided that the following conditions are met:
**
**     1. Redistributions of source code must retain the above copyright notice, this list
**       of conditions and the following disclaimer.
**
**     2. Redistributions in binary form must reproduce the above copyright notice, this
**       list of conditions and the following disclaimer in the documentation and/or
**       other materials provided with the distribution.
**
**     3. Neither the name of the copyright holder nor the names of its
**       contributors may be used to endorse or promote products derived from this
**       software without specific prior written permission.
**
**     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
**     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
**     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
**     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
**     ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
**     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
**     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
**     ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
**     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
**     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
**     http:                 www.nxp.com
**     mail:                 support@nxp.com
**
** ###################################################################
*/

/* Entry Point */
ENTRY(Reset_Handler)

HEAP_SIZE  = DEFINED(__heap_size__)  ? __heap_size__  : 0x0400;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400;

/* Specify the memory areas */
MEMORY
{
  m_boot_hdr            (RX)  : ORIGIN = 0x30000000, LENGTH = 0x00000400  
  m_boot_data           (RX)  : ORIGIN = 0x30000400, LENGTH = 0x00000C00
  m_image_vertor_table  (RX)  : ORIGIN = 0x30001000, LENGTH = 0x00001000

/*m_interrupts          (RX)  : ORIGIN = 0x00000000, LENGTH = 0x00000400 */
  m_interrupts          (RX)  : ORIGIN = 0x30002000, LENGTH = 0x00000400 
  m_text                (RX)  : ORIGIN = 0x30002400, LENGTH = 0x1F7FDC00  

/*m_core1_image         (RX)  : ORIGIN = 0x30FC0000, LENGTH = 0x00040000*/ /*256Kb*/

/*m_itcm                (RW)  : ORIGIN = 0x00000000, LENGTH = 0x00040000  */  /*256Kbyte itcm*/
  m_itcm_Vector         (RX)  : ORIGIN = 0x00000000, LENGTH = 0x00000400  /*1Kbyte itcm for vector*/
  m_itcm_Vector_End     (RX)  : ORIGIN = 0x00000400, LENGTH = 0x00000000  
  m_itcm                (RW)  : ORIGIN = 0x00000400, LENGTH = 0x0003FC00  /*(256-1)Kbyte itcm*/    
  m_dtcm                (RW)  : ORIGIN = 0x20000000, LENGTH = 0x00040000  /*256Kbyte dtcm*/  

  /*m_ocram               (RW)  : ORIGIN = 0x20200000, LENGTH = 0x00040000 */

  m_ocram1              (RW)  : ORIGIN = 0x20240000, LENGTH = 0x00080000  /*512Kbyte SRAM_OC1*/
  m_ocram2              (RW)  : ORIGIN = 0x202c0000, LENGTH = 0x00040000  /*256Kbyte SRAM_OC2*/  

  m_nocache             (RW)  : ORIGIN = 0x81E00000, LENGTH = 0x00040000
  /*m_nocache           (RW)  : ORIGIN = 0x20300000, LENGTH = 0x00040000  256Kbyte NCACHE_REGION*/

  m_ocecc1              (RW)  : ORIGIN = 0x20340000, LENGTH = 0x00010000  /* 64Kbyte SRAM_OC_ECC1*/
  m_ocecc2              (RW)  : ORIGIN = 0x20350000, LENGTH = 0x00010000  /* 64Kbyte SRAM_OC_ECC2*/

  m_sdram0              (RW)  : ORIGIN = 0x80000000, LENGTH = 0x10000000  /*256Mbyte BOARD_SDRAM SEMC0*/
  m_sdram1              (RW)  : ORIGIN = 0x90000000, LENGTH = 0x10000000  /*256Mbyte BOARD_SDRAM SEMC1*/
  m_sdram2              (RW)  : ORIGIN = 0xA0000000, LENGTH = 0x20000000  /*256Mbyte BOARD_SDRAM SEMC2*/
  m_sdram3              (RW)  : ORIGIN = 0xC0000000, LENGTH = 0x20000000  /*256Mbyte BOARD_SDRAM SEMC3*/      
}


/* Define output sections */
SECTIONS
{
  __NCACHE_REGION_START = ORIGIN(m_nocache);  /*灏唌_nocache鐨勮捣濮嬪湴鍧�璧嬪�肩粰__NCACHE_REGION_START */
  __NCACHE_REGION_SIZE  = 0x00040000;         /*__NCACHE_REGION_SIZE璧嬪��0*/

  /* The startup code goes first into internal RAM */  
  .boot_data :
  {
    KEEP(*(.boot_hdr.conf))
  } > m_boot_data

  .image_vertor_table :
  {
    KEEP(*(.boot_hdr.ivt))
    KEEP(*(.boot_hdr.boot_data))
    KEEP(*(.boot_hdr.dcd_data))
  } > m_image_vertor_table

  .itcm_interrupts :
  {
    __VECTOR_RAM_START = .;
    . = ALIGN(4);
    KEEP(*(.itcm_vector))     /* Startup code */
    . = ALIGN(4);
  } > m_itcm_Vector

  .itcm_interruptsEnd :
  {
    __VECTOR_RAM_END = .;
  } > m_itcm_Vector_End  

  /* The startup code goes first into internal RAM */
  .interrupts :
  {
    __VECTOR_TABLE = .;
    . = ALIGN(4);
    KEEP(*(.isr_vector))     /* Startup code */
    . = ALIGN(4);
  } > m_interrupts
 
  __VECTOR_RAM = __VECTOR_TABLE;
  __VectorTable = __VECTOR_TABLE;

  __RAM_VECTOR_TABLE_SIZE_BYTES = 0x400;/*0x0;*/

  /* The program code and other data goes into internal RAM */
  .text :
  {
    _stext = .;    
    . = ALIGN(4);
    *(.text)                 /* .text sections (code) */
    *(.text*)                /* .text* sections (code) */
    *(.rodata)               /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)              /* .rodata* sections (constants, strings, etc.) */
    *(.glue_7)               /* glue arm to thumb code */
    *(.glue_7t)              /* glue thumb to arm code */
    *(.eh_frame)
    KEEP (*(.init))
    KEEP (*(.fini))
    . = ALIGN(4);

    /* section information for utest */
    . = ALIGN(4);
    __rt_utest_tc_tab_start = .;
    KEEP(*(UtestTcTab))
    __rt_utest_tc_tab_end = .;       

    /* section information for finsh shell */
    . = ALIGN(4);
    __fsymtab_start = .;
    KEEP(*(FSymTab))
    __fsymtab_end = .;
    . = ALIGN(4);
    __vsymtab_start = .;
    KEEP(*(VSymTab))
    __vsymtab_end = .;
    . = ALIGN(4);

    /* section information for initial. */
    . = ALIGN(4);
    __rt_init_start = .;
    KEEP(*(SORT(.rti_fn*)))
    __rt_init_end = .;
  } > m_text

  .ARM.extab :
  {
    *(.ARM.extab* .gnu.linkonce.armextab.*)
  } > m_text

  .ARM :
  {
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
  } > m_text

 .ctors :
  {
    PROVIDE(__ctors_start__ = .);
    /* __CTOR_LIST__ = .; */
    /* gcc uses crtbegin.o to find the start of
       the constructors, so we make sure it is
       first.  Because this is a wildcard, it
       doesn't matter if the user does not
       actually link against crtbegin.o; the
       linker won't look for a file to match a
       wildcard.  The wildcard also means that it
       doesn't matter which directory crtbegin.o
       is in.  */
    KEEP (*crtbegin.o(.ctors))
    KEEP (*crtbegin?.o(.ctors))
    /* We don't want to include the .ctor section from
       from the crtend.o file until after the sorted ctors.
       The .ctor section from the crtend file contains the
       end of ctors marker and it must be last */
    KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
    /* __CTOR_END__ = .; */
    PROVIDE(__ctors_end__ = .);
  } > m_text

  .dtors :
  {
    PROVIDE(__dtors_start__ = .);
    /* __DTOR_LIST__ = .; */
    KEEP (*crtbegin.o(.dtors))
    KEEP (*crtbegin?.o(.dtors))
    KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
    /* __DTOR_END__ = .; */
    PROVIDE(__dtors_end__ = .);
  } > m_text

  .preinit_array :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } > m_text

  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } > m_text

  .fini_array :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
  } > m_text

    .core1_image :
  {
    . = ALIGN(4);    
    *(.core1_code)
    KEEP (*(.core1_code))   
  } > m_text 
  
  /*m_core1_image*/

  __etext = .;    /* define a global symbol at end of code */
  __DATA_ROM = .; /* Symbol is used by startup for data initialization */

  .data : AT(__DATA_ROM)
  {
    . = ALIGN(4);
    __DATA_RAM = .;
    __data_start__ = .;      /* create a global symbol at data start */
    *(m_usb_dma_init_data)
    *(.data)                 /* .data sections */
    *(.data*)                /* .data* sections */
    KEEP(*(.jcr*))
    . = ALIGN(4);
    __data_end__ = .;        /* define a global symbol at data end */
  } > m_dtcm

  __NDATA_ROM = __DATA_ROM + (__data_end__ - __data_start__);
  .ncache.init : AT(__NDATA_ROM)
  {
    __noncachedata_start__ = .;   /* create a global symbol at ncache data start */
    *(NonCacheable.init)
    . = ALIGN(4);
    __noncachedata_init_end__ = .;   /* create a global symbol at initialized ncache data end */
  } > m_nocache
  . = __noncachedata_init_end__;
  .ncache :
  {
    *(NonCacheable)
    . = ALIGN(4);
    __noncachedata_end__ = .;     /* define a global symbol at ncache data end */
  } > m_nocache

  __DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_start__);
  text_end = ORIGIN(m_text) + LENGTH(m_text);
  ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data")

  /* Uninitialized data section */
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss section */
    . = ALIGN(4);
    __START_BSS = .;
    __bss_start__ = .;
    *(m_usb_dma_noninit_data)
    *(.bss)
    *(.bss*)
    *(COMMON)
    . = ALIGN(4);
    __bss_end__ = .;
    __END_BSS = .;
  } > m_dtcm

  .stack :
  {
    . = ALIGN(8);
    stack_start = .;
    . += STACK_SIZE;
    stack_end = .;
    __StackTop = .;
  } > m_dtcm
  
  .RTT_HEAP :
  {
    heap_start = .;
    . = ALIGN(8);
  } > m_dtcm

  PROVIDE(heap_end = ORIGIN(m_dtcm) + LENGTH(m_dtcm));

  .ARM.attributes 0 : { *(.ARM.attributes) }

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值