VSP工程XIP使用指南*
在嵌入是系统中,为了减少对内存的占用,通常会使用 XIP(eXecute In Place)
技术。下面几个链接可以帮助了解 XIP
是个什么东西。
1. 开启XIP*
- MCU和DSP都可以使用XIP,
DSP 使用 XIP 必须同时开启 MCU 的 XIP
。 - XIP开关在编译配置中,打开
make menuconfig
中如下配置即可打开XIP,设置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的访问已停止。