Перейти к содержанию
    

Прерывания без ОС на EP9315

для армов 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.
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Я склоняюсь к тому, что redboot что-то в своих интересах инициализировал (или вовсе не инициализировал). На мой взгляд, если коллега действительно хочет именно с этим процессором работать, ему все равно под себя загузчик так и так придется написать. Тогда он будет владеть ситуацией, а не ситуация иметь его.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну да, еще стандартный 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все очень здорово, но надо же еще обучить процессор при возникновении прерывания с адреса 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 что-то в своих интересах инициализировал (или вовсе не инициализировал). На мой взгляд, если коллега действительно хочет именно с этим процессором работать, ему все равно под себя загузчик так и так придется написать. Тогда он будет владеть ситуацией, а не ситуация иметь его.
Спасибо на добром слове. Ладно, убью еще неделю...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Уважаемый toykhee_menky!

 

1. Так про то и речь, что твой обработчик прерывания (судя по дизассемблированному коду) странный и уж сильно не похож на известные примеры.

2. Правильно ли инициализирован VIC? Если неправильно, то и не будет ни хрена вызываться по адресу 0х18.

3. Правильно ли инициализирован Uart2. Разрешено ли ему вырабатывать прерывание?

 

Я это к тому, что причин много и их надо все последовательно проверить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

FIFO разрешено, после посылки восьми символов оттуда появляется битик прерывания в VIC1RawIntr, т.е. прерывание до VIC вроде бы доходит.

Да, а VICIRQStatus что говорит?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, а VICIRQStatus что говорит?

До:

VIC1RawIntr=0x00000008 VIC1IRQStatus=0x00000000 VIC1FIQStatus=0x00000000

После:

VIC1RawIntr=0x02000008 VIC1IRQStatus=0x02000000 VIC1FIQStatus=0x00000000

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

void fun(void)

{

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

while(1);чтобы тут и остаться

}

 

Эту функцию подставить под адрес 0х38 и тут уж однозначно будет ясно, попадаем мы на это прерывание или нет.

Плевое дело нескольких минут, а многое прояснится.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...