Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема FIQ + IRQ
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
b-volkov
Существуют ли какие-то хитрости при одновременной работе IRQ и FIQ в LPC21x?
Есть два таймера. Т0 просто отсчитывает миллисекундные интервалы. Т1 должен формировать с помощью компараторов (MATCH) довольно сложную последовательность синхроимпульсов, но в примере он просто крутится и дергает ногу. Если прерывания от обоих таймеров заведены на IRQ, то все нормально работает. Если прерывания от Т1 заводятся на FIQ, а прерывание от Т0 запрещено (других прерываний вообще нет), то тоже все работает. А вот если разрешить и IRQ и FIQ, то программа работает долю секунды и «улетает». Если отладчик остановить, то РС оказывается в районе 0х00000004 - 0х00000010.
Работаю в ИАР 4.41. Проект размещается в RAM. Стартап из какого-то ИАРовского примера без доработок, инициализация стека FIQ там вроде есть. Код инициализации VIC и обработчиков также взят из примеров.
от куски программы:

/////////////////////////////////////
void InerruptInit(void)
{

VICIntEnClear = 0xFFFFFFFF;
VICProtection = 0;

VICVectAddr = 0;
VICProtection = 0;

//VICIntSelect &= (1<<VIC_TIMER1); // так работает
VICIntSelect |= (1<<VIC_TIMER1); // так нет
VICVectAddr0 = (unsigned int)&TIMER1_ISR;
VICVectCntl0 = 0x20 | VIC_TIMER1;
VICIntEnable |= (1<<VIC_TIMER1);

VICIntSelect &= ~(1<<VIC_TIMER0);
VICVectAddr2 = (unsigned int)&TIMER0_ISR;
VICVectCntl2 = 0x20 | VIC_TIMER0;
VICIntEnable |= (1<<VIC_TIMER0);

}


/////////////////////////////////////

#pragma vector=0x18
__irq __arm void IRQ_ISR_Handler (void)
{
void (*interrupt_function)();
unsigned int vector;
vector = VICVectAddr;
interrupt_function = (void(*)())vector;
(*interrupt_function)();
VICVectAddr = 0;

}

////////////////////////////////////
#pragma vector=0x1c
__fiq __arm void FIQ_ISR_Handler (void)
{
TIMER1_ISR();
}

///////////////////////////////////
void TIMER0_ISR()
{
T0IR = 0x0f;
IO0PIN ^= (1<<20);
Delay (100);
}

//////////////////////////////////

void TIMER1_ISR()
{
T1IR = 0x0f;
IO0PIN ^= (1<<21);
}

//////////////////////////////////

void main()
{

CLOCK_Init();
MEM_Init();
InerruptInit();
IOPinInit();

T0TCR = 0;
T0IR=0xFF;
T0MR0=SysTimerCnt;
T0MCR_bit.MR0INT=1;
T0MCR_bit.MR0RES=1;



T1TCR = 0;
T1IR=0xFF;
T1MR0=3000;
T1MCR_bit.MR0INT=1;
T1MCR_bit.MR0RES=1;

__enable_interrupt(); // Global interrupt enable

T0TCR = 1;
T1TCR = 1;


while(TRUE)
{
IO0PIN ^= (1<<19);
Delay (100);
}
}
Calculator
Разберитесь со стартапом, у ИАРа часто в примерах косяки бывают. Возможно стеки IRQ и FIQ друг на друга накладываются
Perepic
В новом IAR 5.10 обнаружена неприятная вещь, касающаяся размещения IRQ_Handler, FIQ_Handler.
Поддержку #pragma vector они убрали, вместо этого предлагается пользоваться переопределением приведенных выше функций. Так вот грабли в том, что при использовании С++ преобразование имен происходит как-попало и пользовательская IRQ_Handler после компиляции не подставляется вместо библиотечной, а обрабатывается как отдельная фаунция и зачастую вообще линкером игнорируется. Решение - не использовать С++ или пользоваться преобразованием имен:
Код
extern "C"
__irq __arm void IRQ_Handler()  {...};
С IAR-ом я связывался, обещали внести это в новый мануал на компиллер.
b-volkov
Цитата(Calculator @ Dec 13 2007, 08:17) *
Разберитесь со стартапом, у ИАРа часто в примерах косяки бывают. Возможно стеки IRQ и FIQ друг на друга накладываются

Спасибо за наводку, заработало! Стартап оказался нормальным, а вот в .XCL размер стеков был маловат.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.