logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[LPC2103] Jak poprawnie zaimplementować przerwania FIQ w LPC2103 z użyciem OpenOCD?

majster256 15 Lis 2010 19:49 1395 6
REKLAMA
  • #1 8747897
    majster256
    Poziom 21  
    Posty: 582
    Ocena: 8
    W mim projekcie używałem przerwań IRQ z timera0 i wszystko ładnie działało. Jako, że tych przerwań jest naprawdę sporo, procesor traci dużo czasu na wywołanie przerwania, dlatego postanowiłem zrobić przerwania FIQ. Moim przewodnikiem jest książka luciana bryndza.

    przerwanie wygląda tak:

    
    void FiqTimerHandler(void) __attribute__ ((interrupt("FIQ")));
    void FiqTimerHandler(void)
    {
    // obsługa przerwania
    
    
    //Kasuj zrodlo przerwania
    	T0IR = T0IR_MR0;
    
    }
    

    włączenie przerwań, wygląda tak:
    
    		//Zalaczenie przerwania
    			T0IR = T0IR_MR0;
    			VICIntSelect |= TIMER0_VIC;
    			Uart0NIPuts("L3\r\n");
    
    			VICIntEnable = TIMER0_VIC;
    			Uart0NIPuts("L4\r\n");
    
    		//Zalacz FIQ
    			enable_fiq();
    			Uart0NIPuts("L5\r\n");
    


    obsługa timera 0:
    //Licznik zlicza impulsy z czestotliwoscia 15Hz
    			T0PR = 17900;
    		//Gdy warunek spelniony zeruj Timer i zglaszaj przerwanie
    			T0MCR |= T0MCR_Interrupt_on_MR0 | T0MCR_Reset_on_MR0;
    		//Przeladowanie licznika co..
    			T0MR0 = 15;
    		//Zeruj licznik i preskaler
    			T0TCR = T0TCR_Counter_Reset;
    		//Zalacz licznik T0
    			T0TCR = T0TCR_Counter_Enable;
    


    nic nie przerabiałem po przejscu z IRQ w timerze0 a sądzę ze gdzieś w nim jest błąd bo gdy podczas uruchamiania przerwań, zmienie
    VICIntEnable = TIMER0_VIC;
    na
    VICIntEnable = 32;
    to przerwania sie zainicjują(32 to nie zainicjowany timer1, timer0 to 16), w przeciwnym wypadku program dojdzie tylko do wysłania do
    Uart0NIPuts("L3\r\n");
    jako, że nie mam żadnego LCD wysyłam sobie po RS na kompa różne dane 'diagnostyczne' w powyższym kodzie jest właśnie wysłanie na ekran L3, będącego znacznikiem dokąd dochodzi program.

    to juz moje drugie podejście do tematu po dłuższej przerwie i ciągle nie mogę przeskoczyć tego przerwania :cry:
    pomóżcie proszę :D

    edit:
    znalazłem też stary post Freddie chopin'a gdzie opisywany był podobny problem, jednak mój make file ma optymalizacje 0 tego z thumbem też nie ma
  • REKLAMA
  • #2 8748009
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    A jesteś pewny, że Twoja funkcja została umieszczona w wektorach przerwań? Osobiście wątpię, bo to nie chodzi o atrybut tylko o nazwę funkcji (zakładając, że tablica wektorów zawiera odwołania typu "weak").

    4\/3!!
  • REKLAMA
  • #3 8748186
    majster256
    Poziom 21  
    Posty: 582
    Ocena: 8
    a co mam zrobić aby została umieszczona w tych wektorach?

    edit:
    masz racje to coś z wywoływaniem przerwania :) jak zwiększyłem czas w timerze to doszedł do końca ustawiania przerwania i dopiero pozniej sie zawiesił- bo nie umiał wywołać przerwania :)

    to jak mam ustawić zeby to działało dobrze?
  • #4 8748622
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    Jak mogę Ci pomóc, skoro nie wiem jak wygląda reszta plików, a konkretnie tablica wektorów?

    Albo musisz wstawić swoją nazwę funkcji do tablicy, albo nazwać funkcję tak jak nazywa się funkcja z tablicy wektorów (jeśli ma atrybut "weak").

    4\/3!!
  • REKLAMA
  • #5 8748662
    majster256
    Poziom 21  
    Posty: 582
    Ocena: 8
    pliki vectors.s i startup.s mam od Ciebie

    /******************************************************************************
    * author: Freddie Chopin, http://www.freddiechopin.info/
    * file: vectors.S
    * last change: 2010-04-08
    *
    * chip: LPC2103
    * compiler: arm-none-eabi-gcc (Sourcery G++ Lite 2009q3-68) 4.4.1
    *
    * description:
    * LPC2103 vector table and __Default_Handler()
    ******************************************************************************/
    
    /*
    +=============================================================================+
    | Default interrupt handler, used for interrupts that don't have their own
    | handler defined. On ARMv4 architecture it cannot return, as each interrupt
    | has its own return method!
    +=============================================================================+
    */
    
    .text
    .balign 2
    .syntax unified
    .arm
    .func __Default_Handler
    .global __Default_Handler
    
    __Default_Handler:
    	b .
    
    .endfunc
    
    /*
    +=============================================================================+
    | assign all unhandled interrupts to the default handler
    +=============================================================================+
    */
    
    // Undefined instruction
    .weak	Undefined_Handler
    .global	Undefined_Handler
    .set	Undefined_Handler, __Default_Handler
    
    // Software interrupt (SWI)
    .weak	SWI_Handler
    .global	SWI_Handler
    .set	SWI_Handler, __Default_Handler
    
    // Prefetch Abort (instruction fetch memory abort)
    .weak	Prefetch_Abort_Handler
    .global	Prefetch_Abort_Handler
    .set	Prefetch_Abort_Handler, __Default_Handler
    
    // Data Abort (data access memory abort)
    .weak	Data_Abort_Handler
    .global	Data_Abort_Handler
    .set	Data_Abort_Handler, __Default_Handler
    
    // FIQ (fast interrupt)
    .weak	FIQ_Handler
    .global	FIQ_Handler
    .set	FIQ_Handler, __Default_Handler
    
    /*
    +=============================================================================+
    | Vector table
    +=============================================================================+
    */
    
    // VIC IRQ vector for older LPCs (where &VICVectAddr = 0xFFFFF030, e.g. LPC2103):
    //		ldr		pc, [pc, #-0xFF0]
    // VIC IRQ vector for newer LPCs (where &VICAddress = 0xFFFFFF00, e.g. LPC2478):
    //		ldr		pc, [pc, #-0x120]
    
    .section .vectors
    .balign 2
    .syntax unified
    .arm
    __vectors:
    
    	ldr		pc, =Reset_Handler				// Reset exception
    	ldr		pc, =Undefined_Handler			// Undefined Instruction exception
    	ldr		pc, =SWI_Handler				// Software Interrupt exception
    	ldr		pc, =Prefetch_Abort_Handler		// Prefetch Abort exception
    	ldr		pc, =Data_Abort_Handler			// Data Abort exception
    	nop										// reserved for code signature
    	ldr		pc, [pc, #-0xFF0]				// Interrupt exception -> VIC
    	ldr		pc, =FIQ_Handler				// Fast Interrupt exception
    
    /******************************************************************************
    * END OF FILE
    ******************************************************************************/
    


    
    
    /******************************************************************************
    * author: Freddie Chopin, http://www.freddiechopin.info/
    * file: startup.S
    * last change: 2010-04-08
    *
    * chip: ARMv4 (ARM7TDMI)
    * compiler: arm-none-eabi-gcc (Sourcery G++ Lite 2009q3-68) 4.4.1
    *
    * description:
    * ARMv4 (ARM7TDMI) assembly startup code
    ******************************************************************************/
    
    /*
    +=============================================================================+
    | includes
    +=============================================================================+
    */
    
    #include "hdr/hdr_cpsr.h"
    
    /*
    +=============================================================================+
    | ARMv4 (ARM7TDMI) startup code
    +=============================================================================+
    */
    
    .text
    .balign 2
    .syntax unified
    .arm
    .func   Reset_Handler
    .global Reset_Handler
    
    Reset_Handler:
    
    /*
    +-----------------------------------------------------------------------------+
    | Stack setup
    +-----------------------------------------------------------------------------+
    */
    
    	// after reset the core is in Supervisor mode with IRQ & FIQ disabled
    	ldr   sp, =__supervisor_stack_end;				// set the stack for Supervisor mode
    	msr   CPSR_c, #FIQ_MODE | CPSR_I | CPSR_F		// switch to FIQ mode, IRQ & FIQ disabled
    	ldr   sp, =__fiq_stack_end;						// set the stack for FIQ mode
    	msr   CPSR_c, #IRQ_MODE | CPSR_I | CPSR_F 		// switch to IRQ mode, IRQ & FIQ disabled
    	ldr   sp, =__irq_stack_end;						// set the stack for IRQ mode
    	msr   CPSR_c, #ABORT_MODE | CPSR_I | CPSR_F		// switch to Abort mode, IRQ & FIQ disabled
    	ldr   sp, =__abort_stack_end;					// set the stack for Abort mode
    	msr   CPSR_c, #UNDEFINED_MODE | CPSR_I | CPSR_F	// switch to Undefined mode, IRQ & FIQ disabled
    	ldr   sp, =__undefined_stack_end;				// set the stack for Undefined mode
    	msr   CPSR_c, #SYSTEM_MODE					 	// switch to System mode, IRQ & FIQ enabled
    	ldr   sp, =__user_system_stack_end;				// set the stack for User and System mode
    
    /*
    +-----------------------------------------------------------------------------+
    | Branch to low_level_init_0() function (.data and .bss are not initialized!)
    +-----------------------------------------------------------------------------+
    */
    
    	ldr		r0, =low_level_init_0
    	mov		lr, pc
    	bx		r0
    
    /*
    +-----------------------------------------------------------------------------+
    | Initialize .data section
    +-----------------------------------------------------------------------------+
    */
    
    	ldr     r1, =__data_init_start
    	ldr     r2, =__data_start
    	ldr     r3, =__data_end
    1:	cmp     r2, r3
    	ldrlo   r0, [r1], #4
    	strlo   r0, [r2], #4
    	blo     1b
    
    /*
    +-----------------------------------------------------------------------------+
    | Zero-init .bss section
    +-----------------------------------------------------------------------------+
    */
    
    	mov     r0, #0
    	ldr     r1, =__bss_start
    	ldr     r2, =__bss_end
    1:	cmp     r1, r2
    	strlo   r0, [r1], #4
    	blo     1b
    
    /*
    +-----------------------------------------------------------------------------+
    | Call C++ constructors for global and static objects
    +-----------------------------------------------------------------------------+
    */
    #ifdef __USES_CXX
    	ldr		r0, =__libc_init_array
    	mov		lr, pc
    	bx		r0
    #endif
    
    /*
    +-----------------------------------------------------------------------------+
    | Branch to low_level_init_1() function
    +-----------------------------------------------------------------------------+
    */
    
    	ldr		r0, =low_level_init_1
    	mov		lr, pc
    	bx		r0
    
    /*
    +-----------------------------------------------------------------------------+
    | Branch to main() with link
    +-----------------------------------------------------------------------------+
    */
    
    	ldr		r0, =main
    	mov		lr, pc
    	bx		r0
    
    /*
    +-----------------------------------------------------------------------------+
    | Call C++ destructors for global and static objects
    +-----------------------------------------------------------------------------+
    */
    #ifdef __USES_CXX
    	ldr		r0, =__libc_fini_array
    	mov		lr, pc
    	bx		r0
    #endif
    
    /*
    +-----------------------------------------------------------------------------+
    | On return - loop till the end of the world
    +-----------------------------------------------------------------------------+
    */
    
    	b		.
    
    .endfunc
    
    /*
    +=============================================================================+
    | __default_low_level_init() - replacement for undefined low_level_init_0()
    | and/or low_level_init_1(). This function just returns.
    +=============================================================================+
    */
    
    .text
    .balign 2
    .syntax unified
    .arm
    .func   __default_low_level_init
    .global __default_low_level_init
    
    __default_low_level_init:
    	bx		lr
    
    .endfunc
    
    /*
    +=============================================================================+
    | assign undefined low_level_init_0() and/or low_level_init_1() to
    | __default_low_level_init()
    +=============================================================================+
    */
    
    .weak	low_level_init_0
    .global	low_level_init_0
    .set	low_level_init_0, __default_low_level_init
    
    .weak	low_level_init_1
    .global	low_level_init_1
    .set	low_level_init_1, __default_low_level_init
    
    /******************************************************************************
    * END OF FILE
    ******************************************************************************/
    


    wiec co musze miec tak:
    void FiqTimerHandler(void) __attribute__ ((interrupt("FIQ_Handler")));
    void FiqTimerHandler(void)

    niestety dalej nie działa
  • Pomocny post
    #6 8748805
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    Nie nie nie nie... Swoją funkcję musisz po prostu nazwać tak jak jest w tablicy wektorów, czyli:

    void FIQ_Handler(void) __attribute__ ((interrupt("FIQ")));
    void FIQ_Handler(void)
    {
    ...

    i już.

    4\/3!!
  • REKLAMA
  • #7 8748850
    majster256
    Poziom 21  
    Posty: 582
    Ocena: 8
    haaaaa to działa :)

    dzieki freddie :)

Podsumowanie tematu

✨ W dyskusji poruszono problem implementacji przerwań FIQ w mikrokontrolerze LPC2103 z użyciem OpenOCD. Użytkownik, który wcześniej korzystał z przerwań IRQ, zauważył, że procesor traci czas na ich wywołanie, co skłoniło go do przejścia na przerwania FIQ. W odpowiedziach zasugerowano, aby funkcja obsługi przerwania była poprawnie umieszczona w tablicy wektorów, co można osiągnąć przez nadanie jej odpowiedniej nazwy. Po zastosowaniu wskazówek, użytkownik potwierdził, że rozwiązanie działa poprawnie.
Wygenerowane przez model językowy.
REKLAMA