|
发表于 2017-5-31 16:27:11
|
显示全部楼层
本帖最后由 Gorgon_Meducer 于 2017-5-31 16:35 编辑
首先,这个事情,如果我说你们的做法是错的,你们会说,我们用很多年了。考虑到存在即合理,我
这么说吧,你们的做法只是实现了功能,但是并不是最合理的。最合理的就是APP和Boot loader之间
的透明化——只不过因为你们觉得Bootloader开发会复杂一点,就觉得这是不可行的,你们不觉得这点
很值得商榷么?
然而,实际上,Bootloader在这个问题上的开发并不复杂,我这里放一个参考代码:
- //! 1. Disable interrupt response.
- __disable_irq();
- //! 2. Disable all enabled interrupts in NVIC.
- memset((uint32_t *)NVIC->ICER, 0xFF, sizeof(NVIC->ICER));
- /*! Disable all enabled peripherals which might generate interrupt requests.
- Clear all pending interrupt flags in those peripherals.
- This part is device-dependent, and you can write it by referring to device datasheet.
- */
- /*! Clear all pending interrupt requests in NVIC.
- */
- memset((uint32_t *)NVIC->ICPR, 0xFF, sizeof(NVIC->ICPR));
- //! 4. Disable SysTick and clear its exception pending bit.
- SysTick->CTRL = 0;
- SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk;
- //! 5. Load the vector table address of user application code in to VTOR.
- SCB->VTOR = USER_APPLICATION_VECTOR_TABLE_ADDRESS;
- //! 6. Use the MSP as the current SP.
- //! Set the MSP with the value from the vector table used by the application.
- __set_MSP( ((unsigned int *)(SCB->VTOR))[0] );
- //! In thread mode, enable privileged access and use the MSP as the current SP.
- __set_CONTROL( 0 );
- //! 7. Enable interrupts.
- __enable_irq();
- //! 8. The reset handler address could be found with following expression
- //! ((unsigned int *)(SCB->VTOR))[1]
复制代码
这是跳转到APP运行前推荐的要做的事情的伪代码。另外,你们的描述中,中断向量表
需要两块RAM让我觉得很诧异——首先不应该用FLASH来节省空间么?为什么要RAM?
其次,Bootloader理论上是可以不用完整的中断向量表的,你只要保留最基础的部分,
也就是头16个WORD就足够了——我比较激进,我的代码只保留了头4个。另外,很多
芯片可以通过Fuse设置默认的VTOR地址——对于这种芯片,直接把Bootloader的向量
放到Flash的尾部,把启动的VTOR设置成Bootloader的VTOR就行了。另外,即便是不
支持VTOR的M0,也有办法做到APP和Bootloader相互透明,不过时间太短,我就暂时
不在这里介绍了。
|
|