Desenix 0 2 июля, 2008 Опубликовано 2 июля, 2008 · Жалоба для армов EP9312, S3C2410, LPC2368 всегда писал и инициализировал обработчики прерывания сам, а не полагался на среду разработки, и не имел проблем. Если вы не хотите изучать тонкости процессора, то зачем вы взялись его программировать ? Отдайте эту задачу системному программисту, а сами пишите только пользовательский уровень. Изучите как работает контроллер прерываний, как и что в нем надо инициализировать, как надо построить обработчик прерываний, что надо инициализировать в переферии для разрешения прерываний итд. На самом деле контроллер в ARM хоть и "крутой", но мне кажется немного не доинтегрирован в ядро, в идеале надо было, чтоб не обработчик обрабатывал переход по адресу, а само ядро аппаратно. на всякий случай кусок кода, правда там таймер и Ethernet, но думаю суть понятна будет, главное что камень EP9312 // Interrupt handlers. void TimerInterrupt() { (*timer_function)(); // Call timer callback function. Timer3Clear = 0x0; // Clear timer 3 interrupt line. } // IRQ interrupt handler. // Only the timer interrupt is used by this example. __irq __arm void irq_handler(void) { void (*interrupt_function)(); unsigned int vector; // Called at 1000 Hz rate. vector = VIC2VectAddr; // Get interrupt vector. interrupt_function = (void(*)())vector; (*interrupt_function)(); // Call vectored interrupt function. VIC2VectAddr = 0; // Clear interrupt in VIC. } // Interrupt functions. void EP9312InitInterrupt(void(*timer_func)()) { // Setup timer callback function. timer_function = timer_func; // Setup interrupt controller. VIC1Protection = 0; VIC2Protection = 0; // Disable all interrupts VIC1IntEnClear = 0xffffffff; VIC2IntEnClear = 0xffffffff; VIC2IntSelect &= ~TC3OI_bit; // IRQ on timer 3 line. VIC2VectAddr0 = (unsigned int)&TimerInterrupt; VIC2VectCntl0 = 0x20 | VIC2_TC3OI; // Enable vector interrupt for timer 3. VIC2IntEnable |= TC3OI_bit; // Enable timer 3 interrupt. VIC2IntSelect &= ~TC39OI_bit; // IRQ on MAC line. VIC2VectAddr1 = (unsigned int)&InterruptMac; VIC2VectCntl1 = 0x20 | VIC2_INT_MAC; // Enable vector interrupt for MAC. VIC2IntEnable |= TC39OI_bit; // Enable MAC interrupt. } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 2 июля, 2008 Опубликовано 2 июля, 2008 · Жалоба Все очень здорово, но надо же еще обучить процессор при возникновении прерывания с адреса 0х00000018 уходить на обработку конкретной функции обработки прерывания. А по сути, какая разница ядро как-то разбирается с прерываниями или дополнительный контроллер? По мне, так главное, чтобы бастро, понятно и надежно работало. Я склоняюсь к тому, что redboot что-то в своих интересах инициализировал (или вовсе не инициализировал). На мой взгляд, если коллега действительно хочет именно с этим процессором работать, ему все равно под себя загузчик так и так придется написать. Тогда он будет владеть ситуацией, а не ситуация иметь его. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Desenix 0 2 июля, 2008 Опубликовано 2 июля, 2008 · Жалоба ну да, еще стандартный startup забыл приложить, забыл сказать, использовал IAR ;----------------------------------------------------------------------------- ; This file contains the startup code used by the ICCARM C compiler. ; ; The modules in this file are included in the libraries, and may be replaced ; by any user-defined modules that define the PUBLIC symbol _program_start or ; a user defined start symbol. ; To override the cstartup defined in the library, simply add your modified ; version to the workbench project. ; ; All code in the modules (except ?RESET) will be placed in the ICODE segment. ; ; $Revision: 1.2 $ ; ;----------------------------------------------------------------------------- ; ; Naming covention of labels in this file: ; ; ?xxx - External labels only accessed from assembler. ; __xxx - External labels accessed from or defined in C. ; xxx - Labels local to one module (note: this file contains ; several modules). ; main - The starting point of the user program. ; ;--------------------------------------------------------------- ; Macros and definitions for the whole file ;--------------------------------------------------------------- ; Mode, correspords to bits 0-5 in CPSR MODE_BITS DEFINE 0x1F ; Bit mask for mode bits in CPSR USR_MODE DEFINE 0x10 ; User mode FIQ_MODE DEFINE 0x11 ; Fast Interrupt Request mode IRQ_MODE DEFINE 0x12 ; Interrupt Request mode SVC_MODE DEFINE 0x13 ; Supervisor mode ABT_MODE DEFINE 0x17 ; Abort mode UND_MODE DEFINE 0x1B ; Undefined Instruction mode SYS_MODE DEFINE 0x1F ; System mode ;--------------------------------------------------------------- ; ?RESET ; Reset Vector. ; Normally, segment INTVEC is linked at address 0. ; For debugging purposes, INTVEC may be placed at other ; addresses. ; A debugger that honors the entry point will start the ; program in a normal way even if INTVEC is not at address 0. ;--------------------------------------------------------------- MODULE ?RESET COMMON INTVEC:CODE:NOROOT(2) PUBLIC __program_start EXTERN ?cstartup ; EXTERN undef_handler, swi_handler, prefetch_handler ; EXTERN data_handler, fiq_handler EXTERN irq_handler CODE32; Always ARM mode after reset org 0x00 __program_start ldr pc,=?cstartup ; Absolute jump can reach 4 GByte ; ldr b,?cstartup ; Relative branch allows remap, limited to 32 MByte org 0x04 undef_handler ldr pc,=undef_handler org 0x08 swi_handler ldr pc,=swi_handler org 0x0c prefetch_handler ldr pc,=prefetch_handler org 0x10 data_handler ldr pc,=data_handler org 0x18 ldr pc,=irq_handler org 0x1c fiq_handler ldr pc,=fiq_handler ; Constant table entries (for ldr pc) will be placed at 0x20 org 0x20 LTORG ; ENDMOD __program_start ENDMOD ;--------------------------------------------------------------- ; ?CSTARTUP ;--------------------------------------------------------------- MODULE ?CSTARTUP RSEG IRQ_STACK:DATA(2) RSEG SVC_STACK:DATA:NOROOT(2) RSEG CSTACK:DATA(2) RSEG ICODE:CODE:NOROOT(4) PUBLIC ?cstartup EXTERN ?main ; Execution starts here. ; After a reset, the mode is ARM, Supervisor, interrupts disabled. CODE32 ?cstartup ; Add initialization nedded before setup of stackpointers here ; Initialize the stack pointers. ; The pattern below can be used for any of the exception stacks: ; FIQ, IRQ, SVC, ABT, UND, SYS. ; The USR mode uses the same stack as SYS. ; The stack segments must be defined in the linker command file, ; and be declared above. mrs r0,cpsr ; Original PSR value bic r0,r0,#MODE_BITS ; Clear the mode bits orr r0,r0,#IRQ_MODE ; Set IRQ mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(IRQ_STACK) & 0xFFFFFFF8 ; End of IRQ_STACK bic r0,r0,#MODE_BITS ; Clear the mode bits orr r0,r0,#SYS_MODE ; Set System mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(CSTACK) & 0xFFFFFFF8 ; End of CSTACK #ifdef __ARMVFP__ ; Enable the VFP coprocessor. mov r0, #0x40000000 ; Set EN bit in VFP fmxr fpexc, r0 ; FPEXC, clear others. ; Disable underflow exceptions by setting flush to zero mode. ; For full IEEE 754 underflow compliance this code should be removed ; and the appropriate exception handler installed. mov r0, #0x01000000 ; Set FZ bit in VFP fmxr fpscr, r0 ; FPSCR, clear others. #endif ; Add more initialization here ; Continue to ?main for more IAR specific system startup ldr r0,=?main bx r0 LTORG ENDMOD END Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toykhee_menky 0 3 июля, 2008 Опубликовано 3 июля, 2008 · Жалоба Все очень здорово, но надо же еще обучить процессор при возникновении прерывания с адреса 0х00000018 уходить на обработку конкретной функции обработки прерывания.Вообще-то процессор умеет это делать, так как исполняет инструкцию, находящуюся по адресу 0x18. Я уже приводил содержимое этого слова: 00000010: 18 F0 9F E5 00 00 00 00 18 F0 9F E5 18 F0 9F E5 |................| ^^^^^^^^^^^ Разумеется, информация в таком виде представлена для удобства(или, скорее, возможности) прочтения ее человеком. Процессор же интерпретирует ее как команду. Опять же, невозможно адекватно отобразить, что видит процессор по адресу 0x18, но если представить это слово как команду, получается 18: e59ff018 ldr pc, [pc, #18]; 0x38 Перевожу с ассемблера на русский: загрузить в счетчик программы (фактически, передать управление) на адрес, значение которого хранится на 0x18 (#18) больше, чем текущее значение счетчика. 0x38 здесь образуется из трех слагаемых: 0x18 - адрес инструкции, и начальное значение PC; второй 0x18 - смещение из кода команды; 8 - значение задано неявно особенностями архитектуры ARM (набежало за время прохождения конвейера). На основании этого не вижу необходимости править команду по адресу 0x18, так как ничего лучше и придумать нельзя. Вместо этого я определяю адрес своего обработчика путем занесения его по адресу 0x38: unsigned int old_0x38; unsigned int *ptr_0x38=(unsigned int *)0x38; old_0x38= *ptr_0x38; *ptr_0x38 = (unsigned int)irq_handler; и он заносится, проверено. Я склоняюсь к тому, что redboot что-то в своих интересах инициализировал (или вовсе не инициализировал). На мой взгляд, если коллега действительно хочет именно с этим процессором работать, ему все равно под себя загузчик так и так придется написать. Тогда он будет владеть ситуацией, а не ситуация иметь его.Спасибо на добром слове. Ладно, убью еще неделю... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 3 июля, 2008 Опубликовано 3 июля, 2008 · Жалоба Уважаемый toykhee_menky! 1. Так про то и речь, что твой обработчик прерывания (судя по дизассемблированному коду) странный и уж сильно не похож на известные примеры. 2. Правильно ли инициализирован VIC? Если неправильно, то и не будет ни хрена вызываться по адресу 0х18. 3. Правильно ли инициализирован Uart2. Разрешено ли ему вырабатывать прерывание? Я это к тому, что причин много и их надо все последовательно проверить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 3 июля, 2008 Опубликовано 3 июля, 2008 · Жалоба FIFO разрешено, после посылки восьми символов оттуда появляется битик прерывания в VIC1RawIntr, т.е. прерывание до VIC вроде бы доходит. Да, а VICIRQStatus что говорит? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toykhee_menky 0 3 июля, 2008 Опубликовано 3 июля, 2008 · Жалоба Да, а VICIRQStatus что говорит? До: VIC1RawIntr=0x00000008 VIC1IRQStatus=0x00000000 VIC1FIQStatus=0x00000000 После: VIC1RawIntr=0x02000008 VIC1IRQStatus=0x02000000 VIC1FIQStatus=0x00000000 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 3 июля, 2008 Опубликовано 3 июля, 2008 · Жалоба Значит на ядро прерывание передается, других вариантов нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 3 июля, 2008 Опубликовано 3 июля, 2008 · Жалоба Ну дак и осталось то, про что я уже говорил - написать простейшую функцию: void fun(void) { включить LED - прямой записью "1" на выход соответствующего порта, без вызова всяких других функций, чтобы не трогать стек while(1);чтобы тут и остаться } Эту функцию подставить под адрес 0х38 и тут уж однозначно будет ясно, попадаем мы на это прерывание или нет. Плевое дело нескольких минут, а многое прояснится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toykhee_menky 0 12 июля, 2008 Опубликовано 12 июля, 2008 · Жалоба Всем спасибо. Перешел на eCos. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 12 июля, 2008 Опубликовано 12 июля, 2008 · Жалоба Ну, флаг в руки! Думаю там заморочек будет еще больше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться