Я пытаюсь реализовать очень простую программу для вызова функции из прерывания 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
Код работает отлично, за исключением того, что часть systick получает галочку. Ваша точка вектора + 1 кажется правильным направлением.Для других вещей здесь мое объяснение: Проблема 1: Запуск кода работает. он правильно переходит к функции запуска в C. Я проверяю это с помощью gdb. Проблема 2 :: Мой компоновщик перечисляет смещение, но моя векторная таблица сохраняется в 0x08000000. Это тот адрес, где ожидается STM32F103rb (cortex-m3). Проблема 3: Это проблема, о которой я думаю. Я дам ему попробовать. Вопрос 4 :: Я рассмотрю это после того, как я попытаюсь решить проблему 3. – Ravi
1. Как вы проверяете, вызвана ли ваша функция systick? Это важно знать, потому что проверка может быть проблемой. 2. Ah, true, ваши векторы находятся в '.data', так что это может сработать. 6. Почему бы не печатать регистры systick в gdb и посмотреть, хотя бы он работает? – domen
Добавление +1 к адресным адресам. Просто добавьте, в примере нет необходимости копировать раздел данных в ОЗУ, поскольку в этом примере нет глобальных переменных, которые обновляются. Но да, если в пример добавлены какие-либо глобальные переменные, тогда необходимо будет поместить векторную таблицу в другой раздел, а раздел данных будет скопирован где-нибудь в ОЗУ. В этом случае также необходимо обновить файл компоновщика. – Ravi