|
|
  |
Вложенные прерывания ARM7 LPC-2478 |
|
|
|
Sep 12 2011, 07:15
|
Группа: Участник
Сообщений: 10
Регистрация: 22-08-11
Пользователь №: 66 820

|
Всем привет! У кого-нибудь есть работающий пример вложенных прерываний под LPC-2478? Облазил и форумы, и документацию - везде только общие рекомендации
|
|
|
|
|
Sep 12 2011, 07:26
|
Местный
  
Группа: Свой
Сообщений: 476
Регистрация: 3-07-07
Из: Санкт-Петербург
Пользователь №: 28 866

|
Ну вложенные прерывания аппаратно не поддерживаются, один из костылей приведен в книги Тревора Мартина. Макросы аля Код #define IENABLE __asm { MRS sysreg, SPSR; MSR CPSR_c, #SYS32Mode } #define IDISABLE __asm { MSR CPSR_c, #(IRQ32Mode|I_Bit); MSR SPSR_cxsf, sysreg }
--------------------
Ковырял чукча отверткой в ухе, звук в телевизоре и пропал.
|
|
|
|
|
Sep 12 2011, 10:23
|
Группа: Участник
Сообщений: 10
Регистрация: 22-08-11
Пользователь №: 66 820

|
Спасибо за ответ! В соответствии с общими указаниями сделано следующее: Так выглядит код внешнего прерывания: Код #define IENABLE __asm { MRS sysreg, SPSR; MSR CPSR_c, #SYS32Mode } #define IDISABLE __asm { MSR CPSR_c, #(IRQ32Mode|I_Bit); MSR SPSR_cxsf, sysreg } ... void UARTHandler (void) __irq { IENABLE; ... //тут происходит вызов функции, инициирующей срабатывание вложенного прерывания ... IDISABLE; VICVectAddr = 0; } В коде внутреннего прерывания никаких специальных действий не происходит. Оба прерывания зарегистрированы с высшим приоритетом. Документация по компилятору RealView, который я использую, утверждает, что адреса возврата сохранять не надо - компилятор-де делает это автоматически. Вопрос - почему во внутреннее прерывание не передается управление?
|
|
|
|
|
Sep 12 2011, 11:50
|
Группа: Участник
Сообщений: 10
Регистрация: 22-08-11
Пользователь №: 66 820

|
Цитата(GetSmart @ Sep 12 2011, 15:11)  Да потому, что при вызове первого прерывания глобально прерывания запрещаются и их нужно ручками разрешать (после IENABLE), а потом запрещать (перед IDISABLE). Сделал. Вторая версия кода: Код #define IENABLE __asm { MRS sysreg, SPSR; MSR CPSR_c, #SYS32Mode } #define IDISABLE __asm { MSR CPSR_c, #(IRQ32Mode|I_Bit); MSR SPSR_cxsf, sysreg } ... DWORD install_irq( DWORD IntNumber, void *HandlerAddr, DWORD Priority ) { DWORD *vect_addr; DWORD *vect_cntl; VICIntEnClr = 1 << IntNumber; if ( IntNumber >= VIC_SIZE ) { return ( FALSE ); } else { vect_addr = (DWORD *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + IntNumber*4); vect_cntl = (DWORD *)(VIC_BASE_ADDR + VECT_CNTL_INDEX + IntNumber*4); *vect_addr = (DWORD)HandlerAddr; *vect_cntl = Priority; VICIntEnable = 1 << IntNumber; return( TRUE ); } } ... void UARTHandler (void) __irq { IENABLE; install_irq(MCI_INT, (void*)MCI_IRQHandler, HIGHEST_PRIORITY);//включаем прерывание ... //тут происходит вызов функции, инициирующей срабатывание вложенного прерывания ... VICIntEnClr = 1 << IntNumber;//отключаем прерывание IDISABLE; VICVectAddr = 0; } Все равно не работает
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|