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

 
 
> FIQ+FreeRTOS на LPC2146
meister
сообщение Jan 23 2008, 07:09
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 219
Регистрация: 20-11-07
Пользователь №: 32 484



Здравствуйте,

не могу заставить работать эту операционку с FIQ. С IRQ у меня все работает, но мне покоя не дает этот простаивающий ресурс, тем более, что большого запаса по производительности у меня нет.

Линковщик:
Код
-D_CSTACK_SIZE=4
-D_IRQ_STACK_SIZE=100
-D_FIR_STACK_SIZE=100
-D_SVC_STACK_SIZE=100
-D_ABT_STACK_SIZE=4
-D_UND_STACK_SIZE=4
-D_HEAP_SIZE=0

-Z(DATA)CSTACK+_CSTACK_SIZE=RAMSTART-RAMEND
-Z(DATA)IRQ_STACK+_IRQ_STACK_SIZE=RAMSTART-RAMEND
-Z(DATA)FIR_STACK+_FIR_STACK_SIZE=RAMSTART-RAMEND
-Z(DATA)SVC_STACK+_SVC_STACK_SIZE=RAMSTART-RAMEND
-Z(DATA)ABT_STACK+_ABT_STACK_SIZE=RAMSTART-RAMEND
-Z(DATA)UND_STACK+_UND_STACK_SIZE=RAMSTART-RAMEND
-Z(DATA)HEAP+_HEAP_SIZE=RAMSTART-RAMEND


Настройка стека:
Код
    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
    
    mrs     r0,cpsr                            ; Original PSR value
    bic     r0,r0,#MODE_BITS                   ; Clear the mode bits
    orr     r0,r0,#FIQ_MODE                    ; Set FIQ mode bits
    msr     cpsr_c,r0                          ; Change the mode
    ldr     sp,=SFE(FIR_STACK) & 0xFFFFFFF8    ; End of FIR_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

    bic     r0,r0,#MODE_BITS                   ; Clear the mode bits
    orr     r0,r0,#SVC_MODE                    ; Set System mode bits
    msr     cpsr_c,r0                          ; Change the mode
    ldr     sp,=SFE(SVC_STACK) & 0xFFFFFFF8    ; End of SVCSTACK


Вот так настраивается с IRQ (так работает):
Код
    void init_interrupts()
    {
        MEMMAP = 1;

        VICSoftIntClear = ~0;
        VICIntEnClear = ~0;
        VICIntSelect = 0;

        set_VICVectCntls(1, hw::VIC_CHANNEL_TIMER1, &irq_timer1_handler_asm);
        set_VICVectCntls(2, hw::VIC_CHANNEL_UART0, &irq_uart0_handler_asm);
        set_VICVectCntls(3, hw::VIC_CHANNEL_UART1, &irq_uart1_handler_asm);

        VICDefVectAddr = reinterpret_cast<unsigned long>(&non_vectored_handler_asm);
        
        VICIntEnable =
            BIT_(hw::VIC_CHANNEL_TIMER1) +
            BIT_(hw::VIC_CHANNEL_UART0) +
            BIT_(hw::VIC_CHANNEL_UART1);

        VICProtection = 1;
        VICVectAddr = 0;
    }


Вот так с FIQ (иногда работает, но очень редко, потом зависает в prefetch interrupt):
Код
    void init_interrupts()
    {
        MEMMAP = 1;

        VICSoftIntClear = ~0;
        VICIntEnClear = ~0;
        VICIntSelect = 0;

        set_VICVectCntls(2, hw::VIC_CHANNEL_UART0, &irq_uart0_handler_asm);
        set_VICVectCntls(3, hw::VIC_CHANNEL_UART1, &irq_uart1_handler_asm);

        VICDefVectAddr = reinterpret_cast<unsigned long>(&non_vectored_handler_asm);
        
        VICIntSelect = BIT_(hw::VIC_CHANNEL_TIMER1);
        
        VICIntEnable =
            BIT_(hw::VIC_CHANNEL_TIMER1) +
            BIT_(hw::VIC_CHANNEL_UART0) +
            BIT_(hw::VIC_CHANNEL_UART1);

        VICProtection = 1;
        VICVectAddr = 0;
    }


Таблица прерываний:
Код
    org    0x00
__program_start:        B           ?cstartup
        undefvec:        B           undef_handler_proxy
        swivec:            B           swi_handler_proxy
        pabtvec:        B           prefetch_handler_proxy
        dabtvec:        B           data_handler_proxy

    org 0x18
        irqvec:            LDR            PC, [PC, #-0xFF0]
        fiqvec:         B           fiq_handler_proxy


Прокси:
Код
undef_handler_proxy B undef_handler;
swi_handler_proxy B vPortYieldProcessor;
prefetch_handler_proxy B prefetch_handler;
data_handler_proxy B data_handler;
fiq_handler_proxy B fiq_handler_asm;


Обработчики прерываний (ASM)
Код
fiq_handler_asm:
    portSAVE_CONTEXT
    BL fiq_handler_impl;
    portRESTORE_CONTEXT

irq_timer1_handler_asm:
    portSAVE_CONTEXT
    BL irq_timer1_handler_impl;
    portRESTORE_CONTEXT


Обработчики прерываний (C++)
Код
extern "C" __arm void fiq_handler_impl(void)
{
    timer1_uart_isr_impl();
}

extern "C" __arm void irq_timer1_handler_impl(void)
{
    timer1_uart_isr_impl();
}


Спасибо.
Go to the top of the page
 
+Quote Post



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

 


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


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