跳转至

VSP工程XIP使用指南*

在嵌入是系统中,为了减少对内存的占用,通常会使用 XIP(eXecute In Place) 技术。下面几个链接可以帮助了解 XIP 是个什么东西。

1. 开启XIP*

  • MCU和DSP都可以使用XIP, DSP 使用 XIP 必须同时开启 MCU 的 XIP
  • XIP开关在编译配置中,打开make menuconfig中如下配置即可打开XIP,设置XIP 空间大小 VSP_MCU_XIP编译配置 VSP_DSP_XIP编译配置

2. XIP的size与地址*

  • MCU 中 XIP数据 地址为数据在flash中的地址加 MCU_FLASH_XIP_BASE, MCU_FLASH_XIP_BASE 默认为 0x30000000,相关定义如下
    // XIP BASE
    #define MCU_FLASH_XIP_BASE        0x30000000
    ...
    #define CONFIG_STAGE2_XIP_BASE      (MCU_FLASH_XIP_BASE + CONFIG_STAGE1_IRAM_SIZE)
    #define CONFIG_STAGE2_XIP_SIZE      0x100000 // 1M flash for .stage2_text segment
    ...
    # define STAGE1_SRAM_TEXT_LMA  AT(0)
    # define STAGE1_SRAM_DATA_LMA  AT(SIZEOF(.stage1_sram_text))
    # ifdef CONFIG_MCU_ENABLE_XIP
    #  define STAGE2_XIP_TEXT_LMA  AT(LENGTH(stage1_dram)-4)
    

3. DSP 地址映射*

  • DSP 中 XIP数据 地址为数据在flash中的地址加 DSP_XIP_OFFSET, DSP_XIP_OFFSET 默认为 0x10000000,相关宏定义如下
    ifeq ($(CONFIG_DSP_ENABLE_XIP), y)
    #DSP_HEAD_SIZE is VSP_FIRMWARE_DSP_HEADER struct size.DSP_XIP_BASE must 64 align
    DSP_HEADER_SIZE = 0x40
    DSP_XIP_OFFSET  = 0x10000000
    DSP_XIP_BASE    = $$(( $(DSP_FW_OFFSET) + $(DSP_HEADER_SIZE) + $(DSP_XIP_OFFSET) ))
    DSP_XIP_SIZE    = $$(( $(CONFIG_DSP_XIP_SIZE_KB) * 1024 ))
    DSP_XIP_END     = $$(( $(DSP_XIP_BASE) + $(DSP_XIP_SIZE) - 1 ))
    
    LSP_CPP_FLAGS  += -DCONFIG_DSP_XIP_BASE=$(shell printf "0x%x" $(DSP_XIP_BASE))
    LSP_CPP_FLAGS  += -DCONFIG_DSP_XIP_SIZE=$(shell printf "0x%x" $(DSP_XIP_SIZE))
    LSP_CPP_FLAGS  += -DCONFIG_DSP_XIP_END=$(shell printf "0x%x" $(DSP_XIP_END))
    endif
    

4. 参考编译配置*

  • configs/nationalchip_public_version/8008c_wukong_prime_v1.4_xip_demo.config
    

5. DSP 将代码或数据放到 XIP*

  • 使用如下的宏进行修饰即可将对应的变量或函数放到XIP
    #define XIP_TEXT_ATTR      __attribute__((section(".xip.text")))
    #define XIP_RODATA_ATTR    __attribute__((section(".xip.rodata")))
    
  • 代码片段
    #ifdef CONFIG_VSP_VPA_XIP_EXAMPLE_RODATA
    const unsigned char s_test_data[] XIP_RODATA_ATTR = 
    #else
    const unsigned char s_test_data[] = 
    #endif
    {
    0x00, 0x00, 0x42, 0x01, 0x83, 0x02, 0xc5, 0x03, 0x06, 0x05, 0x48, 0x06,
    ...
    0xfa, 0xfa, 0x3b, 0xfc, 0x7d, 0xfd, 0xbe, 0xfe
    };
    unsigned int s_test_data_size = 1280;
    
    #ifdef VSP_VPA_XIP_EXAMPLE_TEXT
    XIP_TEXT_ATTR static int _show_test_data()
    #else
    static int _show_test_data()
    #endif
    {
    ...
    }
    
  • demo 输出:
    ...                 
    [MAIN]VMT_MD_HELLO                                                                                               
    _show_test_data: 0x10020060                                                                                      
    s_test_data: 0x33800                                                                                             
    0x0,0x0,0x42,0x1,0x83,0x2,0xc5,0x3,0x6,0x5,0x48,0x6,0x89,0x7,0xca,0x8, 
    ... 
    

6. MCU 将代码或数据放到 XIP*

  • 使用如下的宏进行修饰即可将对应的变量或函数放到XIP
    #define SECTION_XIP_TEXT     __attribute__((section(".xip.text")))
    #define SECTION_XIP_RODATA   __attribute__((section(".xip.rodata")))
    
  • 代码片段:
    #ifdef CONFIG_VSP_CUSTOMIZE_FUNCTION_XIP_DEMO_V1_0_RODATA 
    const unsigned char s_test_data[] SECTION_XIP_RODATA = 
    #else
    const unsigned char s_test_data[] = 
    #endif
    {
    0x00, 0x00, 0x42, 0x01, 0x83, 0x02, 0xc5, 0x03, 0x06, 0x05, 0x48, 0x06,
    ...
    0xfa, 0xfa, 0x3b, 0xfc, 0x7d, 0xfd, 0xbe, 0xfe
    };
    unsigned int s_test_data_size = 1280;
    
    #ifdef CONFIG_VSP_CUSTOMIZE_FUNCTION_XIP_DEMO_V1_0_TEXT
    SECTION_XIP_TEXT static int _show_test_data()
    #else
    static int _show_test_data()
    #endif
    {
    ...
    }
    
  • demo 输出:
    ...                                                       
    _show_test_data: 0x30004000                                                     
    s_test_data: 0x30004048                                                         
    0x0,0x0,0x42,0x1,0x83,0x2,0xc5,0x3,0x6,0x5,0x48,0x6,0x89,0x7,0xca,0x8,          
    ...
    

7. 注意事项*

  • XIP地址只读。
  • 使用XIP时不可使用flash驱动等其他方式访问flash,如有需要请通过关中断等方式确保XIP的访问已停止。