Stm32f4 Discovery прерывает работу программы в оперативной памяти - PullRequest
0 голосов
/ 20 сентября 2018

Я пытаюсь создать ОСРВ, которую мы использовали в школе, чтобы работать на моей доске открытий.В школе мы использовали некоммерческую плату, а ОСРВ была загружена в ОЗУ.Мне удалось загрузить его в оперативную память на плате обнаружения, но у меня проблемы с прерыванием по таймеру.Я не вижу нигде в RTOS-коде, где процессору приказано перейти на определенный адрес, когда таймер вызывает прерывание.Однако существуют адреса и указатели функций, инициализированные этими адресами.Но как процессор знает, как перейти на эти адреса?ОСРВ не использует SCB-> VTOR для перемещения вектора прерывания.

Я удалил весь ненужный (я думаю и надеюсь) код, чтобы показать проблему в меньшем файле.Чтобы упростить еще больше, я мигаю светодиодом на прерывании таймера.

Если я смогу заставить работать эту небольшую программу, то, возможно, я смогу заставить работать ОСРВ, поэтому любая помощь будет высоко цениться.Я сделал несколько комментариев в коде.Итак, чего не хватает в приведенном ниже коде для запуска обработчика прерываний?

#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);
}

СКРИПТ LINKER:

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 );
 }
...