Функция прерывания Systick не вызывается на ядро ​​платы stm32F103RB

Я пытаюсь реализовать очень простую программу для вызова функции из прерывания systick на плате stm32f103rb. Программа работает нормально, но никогда не вызывает функцию прерывания. Я прошел через много четыре раза и экспериментировал с различными значениями регистра, но я не уверен, что мне здесь не хватает. Моя программа запуска и тестовая программа ниже:

startup.s::

         .data 
arr:    .4byte 0x20001000        @ Read-only array of bytes
        .4byte start+1     
        .4byte reset1
        .4byte reset2
        .4byte reset3
        .4byte reset4
        .4byte reset5
        .4byte reset6
        .4byte reset7
        .4byte reset8
        .4byte reset9
        .4byte reset10
        .4byte reset11
        .4byte reset12
        .4byte reset13
        .4byte reset14
        .4byte reset15
        .4byte reset16
eoa: 
        .text
reset1: b reset1
reset2: b reset2
reset3: b reset3
reset4: b reset4
reset5: b reset5
reset6: b reset6
reset7: b reset7
reset8: b reset8
reset9: b reset9
reset10: b reset10
reset11: b sysTickFunc
reset12: b sysTickFunc
reset13: b sysTickFunc
reset14: b sysTickFunc
reset15: b sysTickFunc
reset16: b sysTickFunc
start:                           @ Label, not really required
        mov   r4, #4             @ Load register r0 with the value 5
        mov   r5, #5             @ Load register r1 with the value 4
        add   r6, r4, r5         @ Add r0 and r1 and store in r2
        ldr   r4, =0x40021000
        str   r1, [r4]
        cpsie i
        b test_func
stop:   b stop                   @ Infinite loop to stop execution

Test.c - реализация тестовой функции и функции systick::

#define SYSTICK_CTRL     (volatile unsigned int *)( 0xE000E010 )
#define SYSTICK_LOAD     (volatile unsigned int *)( 0xE000E014 )
#define SYSTICK_VAL      (volatile unsigned int *)( 0xE000E018 )

#define PORT_C_CRL   (volatile unsigned int *)( 0x40011000 )
#define PORT_C_CRH   (volatile unsigned int *)( 0x40011004 )
#define PORT_C_ODR   (volatile unsigned int *)( 0x4001100C )
#define APB2         (volatile unsigned int *)( 0x40021018 )
#define AHB          (volatile unsigned int *)( 0x40021014 )

void sysTickFunc(void);
void test_func(void)
{
    volatile unsigned int * p;
    unsigned int x;
    p = SYSTICK_CTRL;
    *p = 7;   /*CLKSRC to processor clock, TICK INT is 1, COUNTER ENABLE is 1  */
    p = SYSTICK_LOAD;
    *p = 20;
    p = (volatile unsigned int *)( 0xE000E01C );
    *p = 0x00002328;
    x = 0;
    /* loop in while and check if systick function is called */
    while(1)
    {

       x++;
    }       
}


void sysTickFunc(void)
{
    while(1)
    {
        asm("mov r0,0xCCCCCCCC;");
        asm("mov r1,0xDDDDDDDD;");
        asm("mov r2,0xBBBBBBBB;");
        asm("mov r3,0x11111111;");
        asm("mov r4,0x22222222;");
        asm("mov r5,0x33333333;");
        asm("mov r6,0x44444444;");
    }
}

Файл компоновщика:

SECTIONS {
   . = 0x08000000;
   .data : { * (.data)}
   . = 0x08003000;
   .text : {* (.text)} 
}

скрипт сборки:

arm-none-eabi-gcc -nostdlib -mcpu=cortex-m3 -mthumb -g -o add.elf -T stm.ld test.c startup.s
arm-none-eabi-objcopy -O binary add.elf add.bin
dd if=/dev/zero of=flash.bin bs=4096 count=4096
dd if=add.bin of=flash.bin bs=4096 conv=notrunc

Может кто-нибудь помочь мне, что не так в моем коде? Когда я запускаю его с arm gdb в Ubuntu, мне никогда не вызывается функция systick. (Я знаю, что я поместил функцию systick во многих местах в векторной таблице. Это была попытка проверить возможность того, что sysTickFunction не находится в правильном месте в векторной таблице.)

Спасибо рави

1 ответ

№ 1

Как вы проверяете, был ли вызван шприц? Глядя на код, вы просто устанавливаете несколько регистров, поэтому я предполагаю, что вы их проверяете.

Это не будет работать, как вы думаете, так как запись исключения будет хранить r0-r3 (и некоторые другие регистры) в стеке. Вы можете прочитать Техническое справочное руководство Cortex-M3 (глава об исключениях) для подробностей.

Выпуск № 2

Ваши списки файлов компоновщика .text по смещению. Это не будет работать, так как векторы сброса должны быть в начале. Вы хотите поместить векторы сброса в отдельный раздел, который идет в начале FLASH, а затем поместить .text а также .data, Не забудьте также поставить .data а также .bss в оперативную память

Выпуск № 3

За start Вы сохраняете указатель +1 (код большого пальца), но для других векторов вы этого не делаете.

Выпуск № 4

Возможно, вам также понадобится включить соответствующие часы перед использованием регистров типа "systick" и разрешить прерывания глобально и через NVIC для фактического получения прерываний.


Я бы также посоветовал вам написать более понятный код - он облегчит вам и нам, которые пытаются его прочитать.

Другие вопросы по тегам