I'm trying to recreate a project we did in school on my stm32f4discovery-board. For some reason the teacher decided to load the program and the interrupt-vector into RAM. The interrupt-vector
should start at address 0x2001C000. I managed to load and run the program in RAM but I'm having trouble with the interrupt-vector when trying to use systick-interrupts. How do I correctly place and use the interrupt-vector? The code is not the whole school-project, just some pieces of it.
I have added the function relocate_irq_vectors()
. How the teacher relocated the vector, I don't know. I have tried the systick-setup in another program with a normally placed interrupt-vector, so I don't think that is the problem. The program should blink a led when the systick reach 1000.
#include "stm32f4xx.h"
#include "stm32f4xx_usart.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_tim.h"
#include "misc.h"
void led_init();
void bss_init(void);
void relocate_irq_vectors(void);
void systick_init(uint16_t frequency);
extern void SysTick_Handler(void);
void delay(__IO uint32_t c);
void startup(void) __attribute__((naked)) __attribute__((section (".start_section")) );
void startup(void) {
asm volatile(
" NOP\n"
" LDR SP,=0x2001C000\n" // Set stack
" BL relocate_irq_vectors\n"
" BL bss_init\n"
" BL main\n"
".L1: B .L1\n"
);
}
void relocate_irq_vectors() {
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x1c000);
}
void bss_init() {
asm volatile(
" ldr r2, =_sbss\n"
" b LoopFillZerobss\n"
"FillZerobss:\n"
" movs r3, #0\n"
" str r3, [r2], #4\n"
"LoopFillZerobss:\n"
" ldr r3, = _ebss\n"
" cmp r2, r3\n"
" bcc FillZerobss\n"
) ;
}
#define SYSTICK_VECTOR (0x2001C000+0x3C)
int main() {
led_init();
systick_init(1000);
while (1) {
GPIO_ToggleBits(GPIOD, GPIO_Pin_15);
delay(1048575);
}
return 0;
}
void systick_init(uint16_t frequency) {
RCC_ClocksTypeDef RCC_Clocks;
RCC_GetClocksFreq(&RCC_Clocks);
(void) SysTick_Config(RCC_Clocks.HCLK_Frequency / frequency);
*((void (**)(void) ) SYSTICK_VECTOR ) = SysTick_Handler;
}
volatile uint32_t ticks;
extern void SysTick_Handler(void) {
ticks++;
}
void delay(__IO uint32_t c) {
ticks = 0;
while(ticks < 1000);
// while(c--);
}
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);
}
}