Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: SAM7S. Sys Interrupt под UCOS
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Romario
проблема такая : в системном контроллере включен только DBGU. По прерыванию.
Если ISR DBGU не обрамляется UCOS функциями входа и выхода в прерывание вся система работает
идеально. Сейчас вот решил довать в данную ISR сигнал в задачу и обрамил ее функциями UCOS. ISR DBGU успевает передать пару байт при старте и система виснет. Убираю обрамление - все работает..
В проекте аналогично обрамлены еще 3 ISR (uart0,1 и таймер0). Они работают проблем нет. А этот Interrupt source 1 какой то "заколдованный", вроде бы от других не отличается. Что может быть?
AlexBoy
Цитата(Romario @ Jun 21 2007, 20:03) *
Если ISR DBGU не обрамляется UCOS функциями входа и выхода в прерывание вся система работает
идеально. Сейчас вот решил довать в данную ISR сигнал в задачу и обрамил ее функциями UCOS. ISR DBGU успевает передать пару байт при старте и система виснет. Убираю обрамление - все работает..
В проекте аналогично обрамлены еще 3 ISR (uart0,1 и таймер0). Они работают проблем нет. А этот Interrupt source 1 какой то "заколдованный", вроде бы от других не отличается. Что может быть?

Выложи кусок, где общий хандлер прерываний (который вызывается из асма) и хандлер системного прерывания.
Romario
Цитата(AlexBoy @ Jun 22 2007, 16:03) *
Выложи кусок, где общий хандлер прерываний (который вызывается из асма) и хандлер системного прерывания.



это из порта
Код
DbguUart_Irq_UCOS
        STMFD   SP!, {R1-R3}                  ; PUSH WORKING REGISTERS ONTO IRQ STACK
        MOV     R1, SP                        ; Save   IRQ stack pointer
        ADD     SP, SP,#12                    ; Adjust IRQ stack pointer
        SUB     R2, LR,#4                     ; Adjust PC for return address to task
        MRS     R3, SPSR                      ; Copy SPSR (i.e. interrupted task CPSR) to R3
        MSR     CPSR_c, #(NO_INT | SVC32_MODE); Change to SVC mode

                                              ; SAVE TASK CONTEXT ONTO TASK STACK
        STMFD   SP!, {R2}                     ;    Push task Return PC
        STMFD   SP!, {LR}                     ;    Push task LR
        STMFD   SP!, {R4-R12}              ;    Push task R12-R4

        LDMFD   R1!, {R4-R6}                ;    Move task R1-R3 from IRQ stack to SVC stack
        STMFD   SP!, {R4-R6}
        STMFD   SP!, {R0}                     ;    Push task R0    onto task stack
        STMFD   SP!, {R3}                     ;    Push task CPSR (i.e. IRQ SPSR)

        LDR     R4, =OSTCBCur              ;    OSTCBCur->OSTCBStkPtr = SP
        LDR     R5, [R4]
        STR     SP, [R5]                         ;
        
        MSR     CPSR_c, #(NO_INT | IRQ32_MODE); Change to IRQ mode (to use the IRQ stack to handle interrupt)
        BL        DbguUart_Irq                    ; OS_CPU_IRQ_ISR_Handler();
        MSR     CPSR_c, #(NO_INT | SVC32_MODE); Change to SVC mode
        BL        OSIntExitI                     ; OSIntExit();

                                              ; RESTORE NEW TASK CONTEXT
        LDMFD   SP!, {R4}                     ;    Pop new task CPSR
        MSR     SPSR_cxsf, R4
        LDMFD   SP!, {R0-R12,LR,PC}^          ;    Pop new task context




это ISR
Код
void DbguUart_Irq(void) {

REG_t u32_t dw        ;
REG_t u32_t csr       ;

       csr = SAM256_DBGU->SR;
   if (csr & UART_SR_RXRDY) {
       dw  = SAM256_DBGU->RHR;
      // putch0('r');
   }
   /////////////////////////////////////////////////
   if (csr & UART_SR_TXEMPTY) {
//     putch0('t');
     if (SAM256_DBGU->IMR & UART_SR_TXEMPTY) {
         SAM256_DBGU->THR  = 't';
     } else {
         SAM256_DBGU->IDR = UART_SR_TXEMPTY;
     }
   }
   /////////////////////////////////////////////////
   SAM256_AIC->EOICR = 0;
}



установка
Код
    SAM256_AIC->SMR[SYSC_PH_ID] = 0;    
    SAM256_AIC->SVR[SYSC_PH_ID] = (u32_t)&DbguUart_Irq_UCOS;



ну и вектора

Код
        LDR     PC, Reset_Addr
        LDR     PC, Undefined_Addr
        LDR     PC, SWI_Addr
        LDR     PC, Prefetch_Addr
        LDR     PC, Abort_Addr
        NOP                            ; Reserved vector
        LDR     PC, [PC,#-0xF20]       ; IRQ_Addr
        LDR     PC, FIQ_Addr



т.е. с этим портом на LPC ни одной проблемы не было, в SAM7 на другиx источниках прерываний тоже
проблем нет, а если на прерывание 1, но стразу завис.
AlexBoy
У меня другой порт UCOS, там вызывается общий для всех прерываний асмовский кусок и он отличается от твоего DbguUart_Irq_UCOS.
Из асма идет передача на общий сишный хандлер и дальше на конкретное устройство.
И еще на системной прерывании может сидеть системный таймер (у меня так сделано).
Вобщем скидываю свой вариант порта.
...добавил еще пару файлов для полной картины (cfg.zip)
Romario
написал такой тест:

Код
void DbguUart_Irq(void) {

       if (isr_cnt) {
            putch0('*');
       }


       isr_cnt = 1;
      
       .............
      
       isr_cnt = 0;
     SAM256_AIC->EOICR = 0;
}


выдает '*'!!! хм...буду выяснять почему

только я не пойму что происходит, все остальные ISR работают, а тут я еще заметил такую штуку -
увеличиваю стек под ту задачу (она у меня сейчас вообще одна и даже системный таймер остановлен), задача состоит из while(1).
Эта ISR "держиться" дольше (принимает больше символов по прерыванию), уменьшаю стек - соответственно меньше...
...через некоторое время крах полный...
AlexBoy
Цитата(Romario @ Jun 22 2007, 18:45) *
выдает '*'!!! хм...буду выяснять почему

Глянул какой флаг использую для передачи, оказалось не TXEMPTY, а TXRDY и это работает. Попробуй у себя поменять.
Код
    status = pCOM->US_CSR;
    
    // Есть принятый байт
    if (status & AT91C_US_RXRDY)
      {
        data = pCOM->US_RHR;
        if (!(status & AT91C_US_FRAME))
          {
            QueueAdd(RxQueue, data);
          }
      }
      
    // Регистр передачи пуст
    if (status & AT91C_US_TXRDY)
      {
        // Есть данные для передачи?
        if (QueueCount(TxQueue))
          {
            QueueGet(TxQueue, &data);
            pCOM->US_THR = data;
          }
         else
          {
            pCOM->US_IDR = AT91C_US_TXRDY;
          }  
      }
    // очистить признаки ошибок
    pCOM->US_CR = AT91C_US_RSTSTA;
Romario
НАШЕЛ КОСЯК!!!!!!!!!!!!! фуф...ну рассказываю по порядку.

Среда ADS1.2
Во первых, я немного слукавил, ибо ISR у меня называется не DbguUart_Irq, а GpsUart_Irq. Это Важно!!!:)

Решил-ка я нажать ALT-F7 и глянуть дизасм.
Код
void GpsUart_Irq(void) {
       ..............
}

    GpsUart_Irq
        0x0000008c:    e92d5070    pP-.    STMFD    r13!,{r4-r6,r12,r14}
        0x00000090:    e59f6340    @c..    LDR      r6,0x3d8
        0x00000094:    e92d000f    ..-.    STMFD    r13!,{r0-r3}
        0x00000098:    e5d60000    ....    LDRB     r0,[r6,#0]
        0x0000009c:    e24dd004    ..M.    SUB      r13,r13,#4
        0x000000a0:    e3500000    ..P.    CMP      r0,#0
        0x000000a4:    13a0002a    *...    MOVNE    r0,#0x2a
        0x000000a8:    1bfffffe    ....    BLNE     _putch0
        0x000000ac:    e3a00001    ....    MOV      r0,#1
        0x000000b0:    e5c60000    ....    STRB     r0,[r6,#0]
        0x000000b4:    e3a05000    .P..    MOV      r5,#0
        0x000000b8:    e5154dec    .M..    LDR      r4,[r5,#-0xdec]
        0x000000bc:    e3a0002e    ....    MOV      r0,#0x2e
        0x000000c0:    ebfffffe    ....    BL       _putch0
        0x000000c4:    e3140001    ....    TST      r4,#1
        0x000000c8:    0a000002    ....    BEQ      {pc} + 0x10; 0xd8
        0x000000cc:    e3a00072    r...    MOV      r0,#0x72
        0x000000d0:    ebfffffe    ....    BL       _putch0
        0x000000d4:    e5150de8    ....    LDR      r0,[r5,#-0xde8]
        0x000000d8:    e3a00f80    ....    MOV      r0,#0x200
        0x000000dc:    e5050df4    ....    STR      r0,[r5,#-0xdf4]
        0x000000e0:    e5c65000    .P..    STRB     r5,[r6,#0]
        0x000000e4:    e5055ed0    .^..    STR      r5,[r5,#-0xed0]
        0x000000e8:    e28dd004    ....    ADD      r13,r13,#4
       [b] 0x000000ec:    e8bd001f    ....    LDMFD    r13!,{r0-r4}
        0x000000f0:    e8bd5060    `P..    LDMFD    r13!,{r5,r6,r12,r14}
        0x000000f4:    e25ef004    ..^.    SUBS     pc,r14,#4[/b]


добавляю я к объявлению ISR ключевое слово "__irq" и смотрю дизасм, тоже самое!
т.е. функция GpsUart_Irq компилируется одинаково что с __irq что без! А именно
как с __irq!!!!....нихрена себе!
Изменил я название функции GpsUart_Irq на GpsUart_Irq2 и все заработало!

а теперь почему это происходит,
я не зря сказал внечале про назвние функций, дело в том, что я корректирую проект для другого девайса на базе SAM7 с проекта девайса на базе LPC. А там, у меня эта функция была как __irq.

Ну и чтобы не создавать проект заново и добавлять файлы, я просто создал новую директорию, перекопировал туда проект под LPC и уже потом начал изменять в соответствии с периферией SAM7.
И решил в новом проекте сделать в этой GpsUart_Irq сигнал в задачу.
Так вот, ADS этот видимо чтото не "почистил" в проекте и упорно компилит ее как __irq, видимо гдето
у него в проектных файлах это засело, не знаю. remove object code не помогает. все пути вроде исправил - пофиг.

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