2016-11-13 1 views
1

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

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

Linker файл:

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 

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

Благодаря Ravi

ответ

0

Issue # 1

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

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

Выпуск № 2

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

Выпуск № 3

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

Выпуск № 4

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


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

+0

Код работает отлично, за исключением того, что часть systick получает галочку. Ваша точка вектора + 1 кажется правильным направлением.Для других вещей здесь мое объяснение: Проблема 1: Запуск кода работает. он правильно переходит к функции запуска в C. Я проверяю это с помощью gdb. Проблема 2 :: Мой компоновщик перечисляет смещение, но моя векторная таблица сохраняется в 0x08000000. Это тот адрес, где ожидается STM32F103rb (cortex-m3). Проблема 3: Это проблема, о которой я думаю. Я дам ему попробовать. Вопрос 4 :: Я рассмотрю это после того, как я попытаюсь решить проблему 3. – Ravi

+0

1. Как вы проверяете, вызвана ли ваша функция systick? Это важно знать, потому что проверка может быть проблемой. 2. Ah, true, ваши векторы находятся в '.data', так что это может сработать. 6. Почему бы не печатать регистры systick в gdb и посмотреть, хотя бы он работает? – domen

+0

Добавление +1 к адресным адресам. Просто добавьте, в примере нет необходимости копировать раздел данных в ОЗУ, поскольку в этом примере нет глобальных переменных, которые обновляются. Но да, если в пример добавлены какие-либо глобальные переменные, тогда необходимо будет поместить векторную таблицу в другой раздел, а раздел данных будет скопирован где-нибудь в ОЗУ. В этом случае также необходимо обновить файл компоновщика. – Ravi

Смежные вопросы