我正在尝试制作一个我们在学校使用的RTOS,以便在我的发现板上工作。在学校里,我们使用了非商用板,并且将RTOS加载到RAM中。我已经成功加载 它进入发现板的RAM中,但定时器中断有麻烦。 我无法在RTOS代码的任何地方看到当计时器引起中断时告诉处理器跳转到特定地址的地方。但是,存在地址和使用这些地址初始化的函数指针。但是处理器如何知道如何跳转到这些地址? RTOS没有使用SCB-> VTOR重新定位中断向量。
我删除了所有不必要的代码(我认为并希望),以较小的文件显示问题。 为了简化操作,我在计时器中断时闪烁了一个led。
如果我可以使这个较小的程序起作用,那么也许我就可以使RTOS起作用,因此,非常感谢您的帮助。 我在代码中做了一些注释。 那么,下面的代码中缺少什么来触发中断处理程序?
#include "stm32f4xx.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_tim.h"
void timer5_init(void);
void led_init();
void init_all(void);
void startup(void) __attribute__((naked)) __attribute__((section (".start_section")) );
#define TIM5_IRQ_VECTOR (0x2001C000+0x108)
#define TIMER5_INTERRUPT void vect_TIM5( void )
TIMER5_INTERRUPT;
void startup(void) {
asm volatile(
" NOP\n"
" LDR SP,=0x2001C000\n" // Set stack
" BL main\n"
".L1: B .L1\n"
);
}
void main() {
init_all();
while (1) {
// Toggle blue led
GPIO_ToggleBits(GPIOD, GPIO_Pin_15); // This works.
ms_delay2(250);
}
}
void init_all() {
led_init();
timer5_init();
}
TIMER5_INTERRUPT {
if (TIM_GetITStatus(TIM5, TIM_IT_Update)) {
// Toggle orange led
GPIO_ToggleBits(GPIOD, GPIO_Pin_13);
TIM_ClearITPendingBit(TIM5, TIM_IT_Update);
}
}
void timer5_init() {
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM5, ENABLE);
RCC_APB1PeriphClockLPModeCmd( RCC_APB1Periph_TIM5, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_DeInit(TIM5);
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStructure);
TIM_TimeBaseInitStructure.TIM_Prescaler = 840-1;
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseInitStructure);
*((void (**)(void) ) TIM5_IRQ_VECTOR ) = vect_TIM5;// Why are they using vect_TIM5 here,
// instead of TIMER5_INTERRUPT?
// Insn't vect_TIM5 just the definition
// of the macro? Why is this working?
NVIC_SetPriority( TIM5_IRQn, 0x00);
NVIC_EnableIRQ( TIM5_IRQn);
TIM_SetCounter(TIM5, 0);
TIM_Cmd( TIM5, ENABLE);
TIM_ITConfig( TIM5, TIM_IT_CC1, ENABLE);
}
void led_init() {
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitTypeDef GPIO_InitDef;
GPIO_InitDef.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitDef.GPIO_OType = GPIO_OType_PP;
GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitDef.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitDef);
}
链接器脚本:
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 112K
}
SECTIONS
{
.text :
{
. = ALIGN(4);
*(.start_section)
*(.text)
*(.text.*)
*(.rodata)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
. = ALIGN(4);
} >RAM
.data :
{
. = ALIGN(4);
*(.data)
*(.data.*)
. = ALIGN(4);
} >RAM
.bss :
{
. = ALIGN(4);
_sbss = .;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = . ;
} >RAM
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
}