在中断向量上遇到的坑

在工作中遇到一个坑,APP烧录在FLASH_BASE(0x08000000)地址,但是将APP烧录在指定地址(0x08006000)后正常程序可以运行,但是freertos无法启动调度器,在网上查阅资料后发现是中断向量的问题

什么是中断向量

  • 中断向量表实际上就是存放在Code区(也就是STM32内部的Flash区)从0x00000000地址开始的一个数组,数组的成员为4个字节,而且这些数组在启动文件的时候已经初始化好。
  • STM32根据内核和外设中断优先级,同一标号,标号越小,优先级越大。然后把内核和外设的中断服务函数的地址放在这个数组里面,数组的下标跟中断的优先级对应,我们也把这个中断的编号叫做中断向量。
  • 在启动文件执行的时候,内核和每个外设的中断服务函数的地址都是已经确定好的,地址就存放在中断向量表中,而且在启动文件里面已经写好了中断服务函数,只是这些中断服务函数为空,而且带[weak]弱定义,那么我们就需要在C文件里面重新实现这个中断服务函数,用户写这个中断服务函数的时候,函数名必须跟启动文件里面写的中断函数名对应,因为函数名对应的就是中断服务函数的地址,如果中断服务函数名和启动文件的名字不一样,就默认启动文件里面预先写好的空的中断服务函数,而且是一个死循环,程序就会一直卡死在中断服务函数里面。
  • 当中断来临的时候,首先取向量,每个中断的中断向量不一样,然后根据向量查询中断向量表,根据里面的地址找到中断服务函数,从而实现整个中断的响应过程。

为什么测试APP可以运行,但是rtos运行不起来

  • 测试APP在运行时,未涉及到中断,只有简单的入栈出栈调用,所以可以运行
  • 但是rtos调度器依赖于systick,将APP程序烧录在(0x08006000)后,芯片认为中断向量表还在(0x08000000)地址,因此找不到中断函数导致程序跑飞

如何解决

  • 在APP程序运行进入时,在汇编语言中会调用SystemInit默认更新中断向量表,我们在main函数首行重新更新中断向量表:nvic_vector_table_set(FLASH_BASE,0x6000);,这是AT32的使用方式,其他类型的32接口可能有所不同
文章目录