1 对uvisor进行移植,官方参考硬件平台有K64F、STM32F429,目标平台为STM32F411RE。移植参考文档为:https://github.com/ARMmbed/uvisor/blob/master/docs/core/PORTING.md#uvisor-porting-guide-for-mbed-os
2 移植步骤2.1 执行 1) 执行
$ mbed new code #建立code工程
2) 执行
$ cd ~/code $ git clone git@github.com:ARMMbed/uvisor.git
3)~/code/uvisor/platform/stm32/inc/configurations.h 没有修改configurations.h设置,默认设置。
4)~/code/uvisor/platform/stm32/Makefile.configurations
# MPU architecture ARCH_MPU:=ARMv7M # Family configurations CONFIGURATIONS:=\ CONFIGURATION_STM32_CORTEX_M4_0x10000000_0x0
5)对uvisor文件进行编译
$ cd ~/code/uvisor $ make
结果:
make[2]: Leaving directory '~/code/uvisor' make[1]: Leaving directory '~/code/uvisor'
2.2 对mbed-os操作1) 配置STM32F411的uvisor信息 ①pwd: ~/code/mbed-os/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/ device/TOOLCHAIN_GCC_ARM ②startup_stm32f411xe.S 加入uvisor_init初始化;
#if defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED) ldr r0, =uvisor_init /* [*] Insert this. */ blx r0 /* [*] Insert this. */ #endif /* defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED) */
③STM32F411XE.ld 配置内存分配信息,设置uvisor在STM32F411RE中的内存分配; ④~/features/FEATURE_UVISOR/importer/Makefile 设置目标板SMT32F4.stm32,因为和原始设置一样,所以并没有改动,同时有个疑问,本身STM32F429可行,但是设置完了之后STM32F429也不可行了。 ⑤配置完了之后,建立测试空main()进行测试(没有uvisor功能),单独编译没有问题。
3) 对~/features/FEATURE_UVISOR/importer 进行编译
$ make
cp TARGET_IGNORE/uvisor/docs/api/QUICKSTART.md ..//README.md cp:无法获取'TARGET_IGNORE/uvisor/docs/api/QUICKSTART.md' 的文件状态(stat):没有那个文件或目录 Makefile:59: recipe for target 'rsync' failed banmake: *** [rsync] Error 1
3)回到~code/添加mbed_app.json 进行设置,决定工程中是否使用uvisor
{ "target_overrides": { "*": { "target.features_add": ["UVISOR"], "target.extra_labels_add":["UVISOR_SUPPORTED"], } }, "macros": [ "FEATURE_UVISOR", "TARGET_UVISOR_SUPPORTED" ]
2.3 编译
$ mbed compile -m NUCLEO_F411RE -t GCC_ARM –c
Compile [ 0.3%]: AnalogIn.cpp [Error] cmsis_vectab_virtual.h@22,37: conflicting declaration of C function 'void vIRQ_SetVector(IRQn_Type, uint32_t)' [Error] cmsis_vectab_virtual.h@23,37: conflicting declaration of C function 'uint32_t vIRQ_GetVector(IRQn_Type)' [ERROR] In file included from ./mbed-os/cmsis/core_cm4.h:1536:0,
Thanks, 原来是这样,还是非常感谢您们及时回复。 谢谢!
Hello,uVisor专家组最近修复了你上面提到的bug,最终版本会更新在mbed os 5.5版本里。如果你不着急的话,可以等mbed os 5.5版本正式发布之后再重新尝试以上步骤,应该这个月就会发布。
非常感谢你的问题!
Thanks,太好了,我等新版本下来之后再尝试,谢谢!
多谢Maggie
测试后,比之前好了很多,但还是发现一个bug,不能通过。
Compile [ 82.1%]: disabled.c[Error] core_generic.h@36,2: #error "Unknown MPU architecture. Check your Makefile."[Error] hardware_support.h@75,2: #error "Unsupported ARM core. Make sure CORE_* is defined in your workspace."[Error] core_generic.h@90,2: #error "Unsupported ARM core. Make sure CORE_* is defined in your workspace."[Error] virq.h@27,39: 'NVIC_VECTORS' undeclared here (not in a function)[Error] disabled.c@67,6: array index in non-array initializer[Error] virq_exports.h@39,21: array index in initializer not of integer type
但是我在Makefile中发现系统幽默认,并且和指导文件一样。
$~/code/uvisor/platform/stm32
ARCH_CORE:=CORE_ARMv7MARCH_MPU:=MPU_ARMv7M
CONFIGURATIONS:=\ CONFIGURATION_STM32_CORTEX_M4_0x10000000_0x0
是系统没有适配STM32F411吧。
Maggie离开了,我去问问别的工程师你的问题
好的 谢谢啦
不客气
根据移植参考文档中说明,The uVisor configurations 需要特别适配一下的,在您之前描述中没有看到相应改动;如果不是很明确文档中的解释的话,建议用比较工具比较下 ./Platform/下面几个不同平台的配置区别,对照着https://developer.mbed.org/platforms/ 下面平台规格看更清晰,关注配置表格中相关的信息即可:
FLASH_ORIGIN
FLASH_OFFSET
SRAM_ORIGIN
SRAM_OFFSET
FLASH_LENGTH_MIN
FLASH_LENGTH(i)
i
SRAM_LENGTH_MIN
SRAM_LENGTH(i)
NVIC_VECTORS
NVIC_VECTORS(i)
CORE_*
CORE_CORTEX_M3
你好。
你说的是我的2.2中的第三步吧,
" ③STM32F411XE.ld 配置内存分配信息,设置uvisor在STM32F411RE中的内存分配; "
因为篇幅原因所以没有放上来。现在如下所示:
$~/code/mbed-os/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_GCC_ARM/STM32F411XE.ld
/* Linker script to configure memory regions. */ /* Specify the memory areas. */ M_VECTOR_RAM_SIZE = 0x400; /* With the RTOS in use, this does not affect the main stack size. The size of * the stack where main runs is determined via the RTOS. */ STACK_SIZE = 0x400; /* This is the guaranteed minimum available heap size for an application. When * uVisor is enabled, this is also the maximum available heap size. The * HEAP_SIZE value is set by uVisor porters to balance the size of the legacy * heap and the page heap in uVisor applications. */ HEAP_SIZE = 0x400; #if !defined(MBED_APP_START) #define MBED_APP_START 0x08000000 #endif #if !defined(MBED_APP_SIZE) #define MBED_APP_SIZE 2048k #endif MEMORY { VECTORS(rx) : ORIGIN = MBED_APP_START, LENGTH = 0x400 FLASH (rx) : ORIGIN = MBED_APP_START - 0x400, LENGTH = 512K RAM (rwx) : ORIGIN = 0x20000198, LENGTH = 128k-0x198 } /* Linker script to place sections and symbol values. Should be used together * with other linker script that defines memory regions FLASH and RAM. * It references following symbols, which must be defined in code: * Reset_Handler : Entry of reset handler * * It defines following symbols, which code can use without definition: * __exidx_start * __exidx_end * __etext * __data_start__ * __preinit_array_start * __preinit_array_end * __init_array_start * __init_array_end * __fini_array_start * __fini_array_end * __data_end__ * __bss_start__ * __bss_end__ * __end__ * end * __HeapLimit * __StackLimit * __StackTop * __stack * _estack */ ENTRY(Reset_Handler) SECTIONS { .isr_vector : { __vector_table = .; KEEP(*(.isr_vector)) . = ALIGN(4); } > VECTORS /* Note: The uVisor expects this section at a fixed location, as specified * by the porting process configuration parameter: * FLASH_OFFSET. */ __UVISOR_FLASH_OFFSET = 0x400; __UVISOR_FLASH_START = ORIGIN(VECTORS) + __UVISOR_FLASH_OFFSET; .text __UVISOR_FLASH_START : { /* uVisor code and data */ . = ALIGN(4); __uvisor_main_start = .; *(.uvisor.main) __uvisor_main_end = .; *(.text*) KEEP(*(.init)) KEEP(*(.fini)) /* .ctors */ *crtbegin.o(.ctors) *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) *(SORT(.ctors.*)) *(.ctors) /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) *(.rodata*) KEEP(*(.eh_frame*)) } > FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > FLASH __exidx_start = .; .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > FLASH __exidx_end = .; __etext = .; _sidata = .; .interrupts_ram : { . = ALIGN(4); __VECTOR_RAM__ = .; __interrupts_ram_start__ = .; /* Create a global symbol at data start */ *(.m_interrupts_ram) /* This is a user defined section */ . += M_VECTOR_RAM_SIZE; . = ALIGN(4); __interrupts_ram_end__ = .; /* Define a global symbol at data end */ } > RAM /* uVisor own memory and private box memories /* Note: The uVisor expects this section at a fixed location, as specified by the porting process configuration parameter: SRAM_OFFSET. */ __UVISOR_SRAM_OFFSET = 0x0; __UVISOR_SRAM_START = ORIGIN(RAM) + __UVISOR_SRAM_OFFSET; .uvisor.bss __UVISOR_SRAM_START (NOLOAD): { . = ALIGN(32); __uvisor_bss_start = .; /* Protected uVisor own BSS section */ . = ALIGN(32); __uvisor_bss_main_start = .; KEEP(*(.keep.uvisor.bss.main)) . = ALIGN(32); __uvisor_bss_main_end = .; /* Protected uVisor boxes' static memories */ . = ALIGN(32); __uvisor_bss_boxes_start = .; KEEP(*(.keep.uvisor.bss.boxes)) . = ALIGN(32); __uvisor_bss_boxes_end = .; . = ALIGN(32); __uvisor_bss_end = .; } > RAM /* Heap space for the page allocator /* If uVisor shares the SRAM with the OS/app, ensure that this section is * the first one after the uVisor BSS section. Otherwise, ensure it is the * first one after the VTOR relocation section. */ .page_heap (NOLOAD) : { . = ALIGN(32); __uvisor_page_start = .; KEEP(*(.keep.uvisor.page_heap)) . = ALIGN((1 << LOG2CEIL(LENGTH(RAM))) / 8); __uvisor_page_end = .; } > RAM .data : { PROVIDE( __etext = LOADADDR(.data) ); __data_start__ = .; _sdata = .; *(vtable) *(.data*) . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); KEEP(*(.jcr*)) . = ALIGN(4); /* All data end */ __data_end__ = .; _edata = .; } > RAM AT > FLASH /* uVisor configuration section * This section must be located after all other flash regions. */ .uvisor.secure : { . = ALIGN(32); __uvisor_secure_start = .; /* uVisor secure boxes configuration tables */ . = ALIGN(32); __uvisor_cfgtbl_start = .; KEEP(*(.keep.uvisor.cfgtbl)) . = ALIGN(32); __uvisor_cfgtbl_end = .; /* Pointers to the uVisor secure boxes configuration tables */ /* Note: Do not add any further alignment here, as uVisor will need to * have access to the exact list of pointers. */ __uvisor_cfgtbl_ptr_start = .; KEEP(*(.keep.uvisor.cfgtbl_ptr_first)) KEEP(*(.keep.uvisor.cfgtbl_ptr)) __uvisor_cfgtbl_ptr_end = .; /* Pointers to all boxes register gateways. These are grouped here to allow discoverability and firmware verification. */ __uvisor_register_gateway_ptr_start = .; KEEP(*(.keep.uvisor.register_gateway_ptr)) __uvisor_register_gateway_ptr_end = .; . = ALIGN(32); __uvisor_secure_end = .; } > FLASH /* Uninitialized data section * This region is not initialized by the C/C++ library and can be used to * store state across soft reboots. */ .uninitialized (NOLOAD): { . = ALIGN(32); __uninitialized_start = .; *(.uninitialized) KEEP(*(.keep.uninitialized)) . = ALIGN(32); __uninitialized_end = .; } > RAM .bss (NOLOAD): { . = ALIGN(4); __bss_start__ = .; _sbss = .; *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; _ebss = .; } > RAM .heap (NOLOAD): { __uvisor_heap_start = .; __end__ = .; end = __end__; . += HEAP_SIZE; __HeapLimit = .; __uvisor_heap_end = .; } > RAM __StackTop = ORIGIN(RAM) + LENGTH(RAM); _estack = __StackTop; __stack = __StackTop; __StackLimit = __StackTop - STACK_SIZE; PROVIDE(__stack = __StackTop); ASSERT(__StackLimit >= __HeapLimit, "Region RAM overflowed with stack and heap") /* Provide physical memory boundaries for uVisor. */ __uvisor_flash_start = ORIGIN(VECTORS); __uvisor_flash_end = ORIGIN(FLASH) + LENGTH(FLASH); __uvisor_sram_start = ORIGIN(FLASH); __uvisor_sram_end = ORIGIN(FLASH) + LENGTH(FLASH); __uvisor_public_sram_start = ORIGIN(RAM); __uvisor_public_sram_end = ORIGIN(RAM) + LENGTH(RAM); }
还有就是内存分配参考的是STM32F429 官方配置。
1. 针对于你遇到的编译问题,可否在编译的时候打开 -vv 检查 ARCH_MPU_ARMv7M 是否有定义? 这个宏是通过如下位置定义合成:
Search · ARCH_MPU
platform/efm32/Makefile.configurations
2. 针对内存配置,则包含两部分,一部分是在 mbed-os 中的配置,一部分是在uvisor 中的配置。 429 和411 的FLASH 及 SRAM 差异很大,无法通用, 相关信息可在 网站平台页面查到:
https://developer.mbed.org/platforms/ST-Nucleo-F411RE/
你好。针对你的回复我先回答你的建议。
1、我的平台是STM32F411RE("在最开始提问的第一句话"),而你的建议宏的地址是platform/efm32/Makefile.configurations
Makefile。efm32平台?不明白什么意思。同时我在上一次回复中已经写到,宏地址定义在
“$~/code/uvisor/platform/stm32/”。同时本身文件已经有了预定义,具体是什么,请参考我上一次回复。
2、针对内存分配建议。①参考,指参证有关材料来帮助研究和了解;在研究或处理某些事情时,把另外的资料或数据拿来对照。(from:百度百科);②关于内存大小配置,我不明白你发两次mbed器件什么意思,内存配置参考这个?同时,我参考的是STM32F411RE数据手册!Memory mapping P53。以及相关数据手册说明,就不一一细说。
最后,uvisor porting 的参考https://github.com/ARMmbed/uvisor/blob/master/docs/core/PORTING.md#uvisor-porting-guide-for-mbed-os,也是第一次提问给出的官方网址。在最新mbed更新后,编译错误也已经指出,确实比最开始好了很多(第一次,只进行到0.3%),但是问题仍旧存在,而且发现指导文件和最新工程存在不匹配的地方。是没有对指导文件进行更新?
补充:感谢前后工程师们的回答,我觉得有必要贵公司亲自按照指导说明亲自测试一遍。