我正在尝试将中断向量移动到DTCMRAM。测试代码是简单的定时器中断 Flink LED。在那里我更改了.isr_vector的加载地址:
MEMORY
{
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
}
/* Define output sections */
SECTIONS
{
_sivector = LOADADDR(.isr_vector);
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
_svector = .;
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
_evector = .;
} >ITCMRAM AT> FLASH
之后我在启动的main调用(根据.data
copier生成)前添加了数据copyer:
ldr r0, =_svector
ldr r1, =_evector
ldr r2, =_sivector
movs r3, #0
b LoopCopyVectorInit
CopyVectorInit:
ldr r4, [r2, r3]
str r4, [r0, r3]
adds r3, r3, #4
LoopCopyVectorInit:
adds r4, r0, r3
cmp r4, r1
bcc CopyVectorInit
现在,我想告诉MCU,根据here,使用SCR-〉VTOR可以获得新的向量表。
下面是主代码:
extern uint32_t _sivector;
extern uint32_t _svector;
extern uint32_t _evector;
int main(void)
{
/* USER CODE BEGIN 1 */
__disable_irq();
SCB->VTOR = (uint32_t)*_sivector;
__DSB();
__enable_irq();
但在这种情况下,调试器显示_svector和_sivector等于0x24080000
和_evector= 0x504f105
。
重新初始化VTOR的代码行导致错误。显然_svector和_sivector地址错误。为什么?即使注解ITCMRAM AT>
,_* 向量变量也携带错误的值。
2条答案
按热度按时间o7jaxewo1#
这样下去是行不通的。
当uC启动时,它在标准位置(这是必需的)没有中断向量表,因此您以故障结束。稍后您可以复制中断向量表并将其设置在您想要的位置。
因此,您的启动代码将永远不会执行,因为重置向量没有设置为任何有意义的值。
或
x一个一个一个一个x一个一个二个x
顺便说一句,装配文件中的副本不再需要了。
eufgjt7s2#
所以,显而易见的问题是,为什么这些值是不正确的。
我认为你需要获取这些变量的地址。
SCB->VTOR = (uint32_t)&_sivector
,而不是星号。你想要的是那个变量的地址,而不是它的内容(btw中未定义的)作为一个指针被取消引用并转换到uint32_t。这与将变量放入数据节的逻辑完全相同,链接器脚本中的变量没有可用的值,它们需要作为地址指针,所以就像你使用&_stackstart或任何你称之为它的东西一样,类似的事情应该适用于这里。
编辑:我使用“变量”这个词有点太随意了。链接器脚本定义了一个符号。没有定义的值与它相关联。