【.Net Micro Framework PortingKit - 04】修改启动代码&重写向量表
在上三篇《移植初步:环境搭建》《STM3210E平台构建》《调试初步:点亮LED灯》文章中,我们介绍了如何搭建开发环境,并初步写了测试代码,下一步我们将根据Cortex-M3的架构特点,修改启动代码和重写中断向量表。
Cortex-M3的中断架构非常有特色,芯片内建一个嵌套向量中断控制器NVIC(Nested Vectored Interrupt Controller),它与内核是紧耦合的,提供如下的功能:可嵌套中断支持,向量中断支持,动态优先级调整支持,中断延迟大大缩短,中断可屏蔽。NVIC 支持240 个优先级可动态配置的中断,每个中断的优先级有256 个选择。低延迟的中断处理可以通过紧耦合的NVIC 和处理器内核接口来实现,让新进的中断可以得到有效的处理。NVIC通过时刻关注压栈(嵌套)中断来实现中断的末尾连锁(tail-chaining)。
.Net Micro Framework的中断处理构建在Cortex-M3的中断架构之上,将大大提升的.Net Micro Framework的实时性能,不过由于架构全新,需要大幅度改写.Net Micro Framework原有中断处理代码,不破不立,这对性能有所诟病的.Net Micro Framework也许是个好事情。
下面就新中断架构,进行代码改写。
1、修改FirstEntry.s代码
由于废弃了.\devicecode\cores\arm\assemblycode\thumb2\rvd_s\VectorsHanlers.s 所以为了编译通过,我们要在同目录下的FirstEntry.s中添加一些代码,
在文件头添加如下代码:
EXPORT HARD_Breakpoint
;IMPORT HARD_Breakpoint_Handler ; HARD_Breakpoint_Handler(unsigned int*, unsigned int, unsigned int)
在文件尾“END”命令前添加如下代码:
;AREA ||i.HARD_Breakpoint||, CODE, READONLY ; void HARD_Breakpoint()
HARD_Breakpoint
; on entry, were are being called from C/C++ in system mode
;b HARD_Breakpoint_Handler ; address of vector routine in C to jump to, never expect to return
2、重写中断向量表(VectorsTrampolines.s)
重写同目录下的VectorsTrampolines.s文件为如下内容:
; 导入异常或中断处理程序
IMPORT NMIException
IMPORT HardFaultException
IMPORT MemManageException
IMPORT BusFaultException
IMPORT UsageFaultException
IMPORT SVCHandler
IMPORT DebugMonitor
IMPORT PendSVC
IMPORT SysTickHandler
IMPORT WWDG_IRQHandler
IMPORT PVD_IRQHandler
IMPORT TAMPER_IRQHandler
IMPORT RTC_IRQHandler
IMPORT FLASH_IRQHandler
IMPORT RCC_IRQHandler
IMPORT EXTI0_IRQHandler
IMPORT EXTI1_IRQHandler
IMPORT EXTI2_IRQHandler
IMPORT EXTI3_IRQHandler
IMPORT EXTI4_IRQHandler
IMPORT DMA1_Channel1_IRQHandler
IMPORT DMA1_Channel2_IRQHandler
IMPORT DMA1_Channel3_IRQHandler
IMPORT DMA1_Channel4_IRQHandler
IMPORT DMA1_Channel5_IRQHandler
IMPORT DMA1_Channel6_IRQHandler
IMPORT DMA1_Channel7_IRQHandler
IMPORT ADC1_2_IRQHandler
IMPORT USB_HP_CAN_TX_IRQHandler
IMPORT USB_LP_CAN_RX0_IRQHandler
IMPORT CAN_RX1_IRQHandler
IMPORT CAN_SCE_IRQHandler
IMPORT EXTI9_5_IRQHandler
IMPORT TIM1_BRK_IRQHandler
IMPORT TIM1_UP_IRQHandler
IMPORT TIM1_TRG_COM_IRQHandler
IMPORT TIM1_CC_IRQHandler
IMPORT TIM2_IRQHandler
IMPORT TIM3_IRQHandler
IMPORT TIM4_IRQHandler
IMPORT I2C1_EV_IRQHandler
IMPORT I2C1_ER_IRQHandler
IMPORT I2C2_EV_IRQHandler
IMPORT I2C2_ER_IRQHandler
IMPORT SPI1_IRQHandler
IMPORT SPI2_IRQHandler
IMPORT USART1_IRQHandler
IMPORT USART2_IRQHandler
IMPORT USART3_IRQHandler
IMPORT EXTI15_10_IRQHandler
IMPORT RTCAlarm_IRQHandler
IMPORT USBWakeUp_IRQHandler
IMPORT TIM8_BRK_IRQHandler
IMPORT TIM8_UP_IRQHandler
IMPORT TIM8_TRG_COM_IRQHandler
IMPORT TIM8_CC_IRQHandler
IMPORT ADC3_IRQHandler
IMPORT FSMC_IRQHandler
IMPORT SDIO_IRQHandler
IMPORT TIM5_IRQHandler
IMPORT SPI3_IRQHandler
IMPORT UART4_IRQHandler
IMPORT UART5_IRQHandler
IMPORT TIM6_IRQHandler
IMPORT TIM7_IRQHandler
IMPORT DMA2_Channel1_IRQHandler
IMPORT DMA2_Channel2_IRQHandler
IMPORT DMA2_Channel3_IRQHandler
IMPORT DMA2_Channel4_5_IRQHandler
EXPORT ARM_Vectors
IMPORT StackTop
IMPORT EntryPoint
;*****************************************************************************
AREA |.text|, CODE, READONLY
;向量表
ARM_Vectors
DCD StackTop ; Top of Stack 栈顶
DCD EntryPoint ; 复位
DCD NMIException
DCD HardFaultException
DCD MemManageException
DCD BusFaultException
DCD UsageFaultException
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVCHandler
DCD DebugMonitor
DCD 0 ; Reserved
DCD PendSVC
DCD SysTickHandler
DCD WWDG_IRQHandler
DCD PVD_IRQHandler
DCD TAMPER_IRQHandler
DCD RTC_IRQHandler
DCD FLASH_IRQHandler
DCD RCC_IRQHandler
DCD EXTI0_IRQHandler
DCD EXTI1_IRQHandler
DCD EXTI2_IRQHandler
DCD EXTI3_IRQHandler
DCD EXTI4_IRQHandler
DCD DMA1_Channel1_IRQHandler
DCD DMA1_Channel2_IRQHandler
DCD DMA1_Channel3_IRQHandler
DCD DMA1_Channel4_IRQHandler
DCD DMA1_Channel5_IRQHandler
DCD DMA1_Channel6_IRQHandler
DCD DMA1_Channel7_IRQHandler
DCD ADC1_2_IRQHandler
DCD USB_HP_CAN_TX_IRQHandler
DCD USB_LP_CAN_RX0_IRQHandler
DCD CAN_RX1_IRQHandler
DCD CAN_SCE_IRQHandler
DCD EXTI9_5_IRQHandler
DCD TIM1_BRK_IRQHandler
DCD TIM1_UP_IRQHandler
DCD TIM1_TRG_COM_IRQHandler
DCD TIM1_CC_IRQHandler
DCD TIM2_IRQHandler
DCD TIM3_IRQHandler
DCD TIM4_IRQHandler
DCD I2C1_EV_IRQHandler
DCD I2C1_ER_IRQHandler
DCD I2C2_EV_IRQHandler
DCD I2C2_ER_IRQHandler
DCD SPI1_IRQHandler
DCD SPI2_IRQHandler
DCD USART1_IRQHandler
DCD USART2_IRQHandler
DCD USART3_IRQHandler
DCD EXTI15_10_IRQHandler
DCD RTCAlarm_IRQHandler
DCD USBWakeUp_IRQHandler
DCD TIM8_BRK_IRQHandler
DCD TIM8_UP_IRQHandler
DCD TIM8_TRG_COM_IRQHandler
DCD TIM8_CC_IRQHandler
DCD ADC3_IRQHandler
DCD FSMC_IRQHandler
DCD SDIO_IRQHandler
DCD TIM5_IRQHandler
DCD SPI3_IRQHandler
DCD UART4_IRQHandler
DCD UART5_IRQHandler
DCD TIM6_IRQHandler
DCD TIM7_IRQHandler
DCD DMA2_Channel1_IRQHandler
DCD DMA2_Channel2_IRQHandler
DCD DMA2_Channel3_IRQHandler
DCD DMA2_Channel4_5_IRQHandler
;*****************************************************************************
END
3、新建VectorsHandler_Temp库文件
在.\DeviceCode\Targets\Native\CortexM3\DeviceCode目录下,新建目录VectorsHandler_Temp,并新建两个文件dotNetMF.proj(编译配置,可参见其它同类文件),VectorsHandler_Temp.c(空的中断处理函数)。
VectorsHandler_Temp.c的内容如下:
void NMIException(void) {}
void HardFaultException(void){while (1);}
void MemManageException(void){while (1);}
void BusFaultException(void){while (1);}
void UsageFaultException(void){while (1);}
void DebugMonitor(void){}
void SVCHandler(void){}
// 省略部分代码 .....
void TIM6_IRQHandler(void){}
void TIM7_IRQHandler(void){}
void DMA2_Channel1_IRQHandler(void){}
void DMA2_Channel2_IRQHandler(void){}
void DMA2_Channel3_IRQHandler(void){}
void DMA2_Channel4_5_IRQHandler(void){}
以上函数为暂且为空,以后我们在根据需要再添加相应的中断处理代码。
4、dotNetMF.proj文件调整
(1)对.\DeviceCode\cores\arm\dotNetMF.proj文件做如下调整:
<ItemGroup Condition="'$(INSTRUCTION_SET)'=='thumb2'">
<Compile Include="AssemblyCode\thumb2\$(AS_SUBDIR)\FirstEntry.s" />
<Compile Include="AssemblyCode\thumb2\$(AS_SUBDIR)\IDelayLoop.s" />
<Compile Include="AssemblyCode\thumb2\$(AS_SUBDIR)\Sampling_Profiler_RAM.s" />
<Compile Include="AssemblyCode\thumb2\$(AS_SUBDIR)\VectorsHandlers.s" />
<Compile Include="AssemblyCode\thumb2\$(AS_SUBDIR)\VectorsTrampolines.s" />
</ItemGroup>
修改为:
<ItemGroup Condition="'$(INSTRUCTION_SET)'=='thumb2'">
<Compile Include="AssemblyCode\thumb2\$(AS_SUBDIR)\FirstEntry.s" />
<Compile Include="AssemblyCode\thumb2\$(AS_SUBDIR)\VectorsTrampolines.s" />
</ItemGroup>
<ItemGroup>
<HFiles Include="..\..\Initialization\MasterConfig.h" />
<Compile Include="Diagnostics\Aborts.cpp" />
<Compile Include="Diagnostics\FIQ_Profiler.cpp" />
<Compile Include="Diagnostics\RamTest.cpp" />
<Compile Include="Diagnostics\RamTest.h" />
<LIB_FIRSTENTRY_OBJ Include="$(OBJ_DIR)\FirstEntry.$(OBJ_EXT)" />
</ItemGroup>
修改为:
<ItemGroup>
<LIB_FIRSTENTRY_OBJ Include="$(OBJ_DIR)\FirstEntry.$(OBJ_EXT)" />
</ItemGroup>
(2)在.\Solutions\STM3210E\NativeSample\NativeSample.proj文件中添加如下内容:
<ItemGroup>
<RequiredProjects Include="$(SPOCLIENT)\DeviceCode\Targets\Native\CortexM3\DeviceCode\VectorsHandler_Temp\dotNetMF.proj" />
<DriverLibs Include="VectorsHandler_Temp.$(LIB_EXT)" />
</ItemGroup>
5、编译
编译我们的代码,看看是否能编译成功。编译成功后,在用MDK下载的开发板试一试,如果运行正常,这一步工作将告一段落。下一步我们将编写SRAM初始化代码和设置NVIC中断表偏移。