реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Прерывания без ОС на EP9315, обработчик не вызывается
Desenix
сообщение Jul 2 2008, 17:10
Сообщение #16


Частый гость
**

Группа: Новичок
Сообщений: 111
Регистрация: 23-06-04
Пользователь №: 141



для армов 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.
}
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jul 2 2008, 18:38
Сообщение #17


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Все очень здорово, но надо же еще обучить процессор при возникновении прерывания с адреса 0х00000018 уходить на обработку конкретной функции обработки прерывания. А по сути, какая разница ядро как-то разбирается с прерываниями или дополнительный контроллер? По мне, так главное, чтобы бастро, понятно и надежно работало.

Я склоняюсь к тому, что redboot что-то в своих интересах инициализировал (или вовсе не инициализировал). На мой взгляд, если коллега действительно хочет именно с этим процессором работать, ему все равно под себя загузчик так и так придется написать. Тогда он будет владеть ситуацией, а не ситуация иметь его.
Go to the top of the page
 
+Quote Post
Desenix
сообщение Jul 2 2008, 19:18
Сообщение #18


Частый гость
**

Группа: Новичок
Сообщений: 111
Регистрация: 23-06-04
Пользователь №: 141



ну да, еще стандартный 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
Go to the top of the page
 
+Quote Post
toykhee_menky
сообщение Jul 3 2008, 05:44
Сообщение #19





Группа: Новичок
Сообщений: 9
Регистрация: 30-06-08
Пользователь №: 38 654



Цитата(sergeeff @ Jul 3 2008, 00:38) *
Все очень здорово, но надо же еще обучить процессор при возникновении прерывания с адреса 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;

и он заносится, проверено.

Цитата(sergeeff @ Jul 3 2008, 00:38) *
Я склоняюсь к тому, что redboot что-то в своих интересах инициализировал (или вовсе не инициализировал). На мой взгляд, если коллега действительно хочет именно с этим процессором работать, ему все равно под себя загузчик так и так придется написать. Тогда он будет владеть ситуацией, а не ситуация иметь его.
Спасибо на добром слове. Ладно, убью еще неделю...
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jul 3 2008, 06:15
Сообщение #20


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Уважаемый toykhee_menky!

1. Так про то и речь, что твой обработчик прерывания (судя по дизассемблированному коду) странный и уж сильно не похож на известные примеры.
2. Правильно ли инициализирован VIC? Если неправильно, то и не будет ни хрена вызываться по адресу 0х18.
3. Правильно ли инициализирован Uart2. Разрешено ли ему вырабатывать прерывание?

Я это к тому, что причин много и их надо все последовательно проверить.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 3 2008, 08:25
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(toykhee_menky @ Jun 30 2008, 19:43) *
FIFO разрешено, после посылки восьми символов оттуда появляется битик прерывания в VIC1RawIntr, т.е. прерывание до VIC вроде бы доходит.

Да, а VICIRQStatus что говорит?
Go to the top of the page
 
+Quote Post
toykhee_menky
сообщение Jul 3 2008, 13:08
Сообщение #22





Группа: Новичок
Сообщений: 9
Регистрация: 30-06-08
Пользователь №: 38 654



Цитата(aaarrr @ Jul 3 2008, 14:25) *
Да, а VICIRQStatus что говорит?

До:
VIC1RawIntr=0x00000008 VIC1IRQStatus=0x00000000 VIC1FIQStatus=0x00000000
После:
VIC1RawIntr=0x02000008 VIC1IRQStatus=0x02000000 VIC1FIQStatus=0x00000000
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 3 2008, 13:15
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Значит на ядро прерывание передается, других вариантов нет.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jul 3 2008, 14:12
Сообщение #24


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Ну дак и осталось то, про что я уже говорил - написать простейшую функцию:

void fun(void)
{
включить LED - прямой записью "1" на выход соответствующего порта, без вызова всяких других функций, чтобы не трогать стек
while(1);чтобы тут и остаться
}

Эту функцию подставить под адрес 0х38 и тут уж однозначно будет ясно, попадаем мы на это прерывание или нет.
Плевое дело нескольких минут, а многое прояснится.
Go to the top of the page
 
+Quote Post
toykhee_menky
сообщение Jul 12 2008, 13:49
Сообщение #25





Группа: Новичок
Сообщений: 9
Регистрация: 30-06-08
Пользователь №: 38 654



Всем спасибо. Перешел на eCos.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jul 12 2008, 18:41
Сообщение #26


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Ну, флаг в руки!

Думаю там заморочек будет еще больше.
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 09:43
Рейтинг@Mail.ru


Страница сгенерированна за 0.0146 секунд с 7
ELECTRONIX ©2004-2016