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

 
 
 
Reply to this topicStart new topic
> AT91SAM9XE и инициализация FIQ
taoga
сообщение Jun 20 2011, 18:30
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 51
Регистрация: 8-10-09
Пользователь №: 52 809



Здравствуйте! Мне нужен файл board_cstartup_iar.s с (IAR 5.xx) с инициализацией обработчика по умолчанию для FIQ и соответствующего стека. Чтобы он функционально был аналогичен файлу Cstartup.s79 из примера AT91SAM7S32-Interrupt-IAR4_11A-1_1-FIQ.zip. Я не настолько хорошо владею предметом, чтобы легко менять .s файлы.
Код который я написал в основной программе работает для прерывания IRQ1, но перестает работать когда я меняю IRQ1 на FIQ. Вызывается обработчик FIQ_Handler, который не делает ничего.
Спасибо.

board_cstartup_iar.s:
CODE

/*
IAR startup file for AT91SAM9XE microcontrollers.
*/

MODULE ?cstartup

;; Forward declaration of sections.
SECTION IRQ_STACK:DATA:NOROOT(2)
SECTION CSTACK:DATA:NOROOT(3)

//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------

#define __ASSEMBLY__
#include "board.h"

//------------------------------------------------------------------------------
// Definitions
//------------------------------------------------------------------------------

#define ARM_MODE_ABT 0x17
#define ARM_MODE_FIQ 0x11
#define ARM_MODE_IRQ 0x12
#define ARM_MODE_SVC 0x13
#define ARM_MODE_SYS 0x1F

#define I_BIT 0x80
#define F_BIT 0x40

//------------------------------------------------------------------------------
// Startup routine
//------------------------------------------------------------------------------

/*
Exception vectors
*/
SECTION .vectors:CODE:NOROOT(2)

PUBLIC resetVector
PUBLIC irqHandler

EXTERN Undefined_Handler
EXTERN SWI_Handler
EXTERN Prefetch_Handler
EXTERN Abort_Handler
EXTERN FIQ_Handler

ARM

__iar_init$$done: ; The interrupt vector is not needed
; until after copy initialization is done

resetVector:
; All default exception handlers (except reset) are
; defined as weak symbol definitions.
; If a handler is defined by the application it will take precedence.
LDR pc, =resetHandler ; Reset
LDR pc, Undefined_Addr ; Undefined instructions
LDR pc, SWI_Addr ; Software interrupt (SWI/SYS)
LDR pc, Prefetch_Addr ; Prefetch abort
LDR pc, Abort_Addr ; Data abort
B . ; RESERVED
LDR pc, =irqHandler ; IRQ
LDR pc, FIQ_Addr ; FIQ

Undefined_Addr: DCD Undefined_Handler
SWI_Addr: DCD SWI_Handler
Prefetch_Addr: DCD Prefetch_Handler
Abort_Addr: DCD Abort_Handler
FIQ_Addr: DCD FIQ_Handler

/*
Handles incoming interrupt requests by branching to the corresponding
handler, as defined in the AIC. Supports interrupt nesting.
*/
irqHandler:
/* Save interrupt context on the stack to allow nesting */
SUB lr, lr, #4
STMFD sp!, {lr}
MRS lr, SPSR
STMFD sp!, {r0, lr}

/* Write in the IVR to support Protect Mode */
LDR lr, =AT91C_BASE_AIC
LDR r0, [r14, #AIC_IVR]
STR lr, [r14, #AIC_IVR]

/* Branch to interrupt handler in Supervisor mode */
MSR CPSR_c, #ARM_MODE_SYS
STMFD sp!, {r1-r3, r4, r12, lr}
BLX r0
LDMIA sp!, {r1-r3, r4, r12, lr}
MSR CPSR_c, #ARM_MODE_IRQ | I_BIT

/* Acknowledge interrupt */
LDR lr, =AT91C_BASE_AIC
STR lr, [r14, #AIC_EOICR]

/* Restore interrupt context and branch back to calling code */
LDMIA sp!, {r0, lr}
MSR SPSR_cxsf, lr
LDMIA sp!, {pc}^


/*
After a reset, execution starts here, the mode is ARM, supervisor
with interrupts disabled.
Initializes the chip and branches to the main() function.
*/
SECTION .cstartup:CODE:NOROOT(2)

PUBLIC resetHandler
EXTERN LowLevelInit
EXTERN ?main
REQUIRE resetVector
ARM

resetHandler:

/* Set pc to actual code location (i.e. not in remap zone) */
LDR pc, =label

/* Perform low-level initialization of the chip using LowLevelInit() */
label:
LDR r0, =LowLevelInit
LDR r4, =SFE(CSTACK)
MOV sp, r4
BLX r0

/* Set up the interrupt stack pointer. */
MSR cpsr_c, #ARM_MODE_IRQ | I_BIT | F_BIT ; Change the mode
LDR sp, =SFE(IRQ_STACK)

/* Set up the SYS stack pointer. */
MSR cpsr_c, #ARM_MODE_SYS | F_BIT ; Change the mode
LDR sp, =SFE(CSTACK)

/* Branch to main() */
LDR r0, =?main
BLX r0

/* Loop indefinitely when program is finished */
loop4:
B loop4

END




Cstartup.s79:

;------------------------------------------------------------------------------
;- ATMEL Microcontroller Software Support - ROUSSET -
;------------------------------------------------------------------------------
; The software is delivered "AS IS" without warranty or condition of any
; kind, either express, implied or statutory. This includes without
; limitation any warranty or condition with respect to merchantability or
; fitness for any particular purpose, or against the infringements of
; intellectual property rights of others.
;-----------------------------------------------------------------------------
;- File source : Cstartup.s79
;- Object : Generic CStartup for IAR No Use REMAP
;- Compilation flag : None
;-
;- 1.0 15/Jun/04 JPP : Creation
;- 1.1 01/Apr/05 JPP : save SPSR
;------------------------------------------------------------------------------

#include "AT91SAM7S32_inc.h"

;------------------------------------------------------------------------------
;- Area Definition
;------------------------------------------------------------------------------

;---------------------------------------------------------------
; ?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.
;-------------------------------------------------------------

PROGRAM ?RESET
RSEG INTRAMSTART_REMAP
RSEG INTRAMEND_REMAP

RSEG ICODE:CODE:ROOT(2)
CODE32 ; Always ARM mode after reset
org 0
reset
;------------------------------------------------------------------------------
;- Exception vectors
;--------------------
;- These vectors can be read at address 0 or at RAM address
;- They ABSOLUTELY requires to be in relative addresssing mode in order to
;- guarantee a valid jump. For the moment, all are just looping.
;- If an exception occurs before remap, this would result in an infinite loop.
;- To ensure if a exeption occurs before start application to infinite loop.
;------------------------------------------------------------------------------

B InitReset ; 0x00 Reset handler
undefvec:
B undefvec ; 0x04 Undefined Instruction
swivec:
B swivec ; 0x08 Software Interrupt
pabtvec:
B pabtvec ; 0x0C Prefetch Abort
dabtvec:
B dabtvec ; 0x10 Data Abort
rsvdvec:
B rsvdvec ; 0x14 reserved
irqvec:
B IRQ_Handler_Entry ; 0x18 IRQ
fiqvec: ; 0x1c FIQ
;------------------------------------------------------------------------------
;- Function : FIQ_Handler_Entry
;- Treatments : FIQ Controller Interrupt Handler.
;- Called Functions : AIC_FVR[interrupt]
;------------------------------------------------------------------------------

FIQ_Handler_Entry:

;- Switch in SVC/User Mode to allow User Stack access for C code
; because the FIQ is not yet acknowledged

;- Save and r0 in FIQ_Register
mov r9,r0
ldr r0 , [r8, #AIC_FVR]
msr CPSR_c,#I_BIT | F_BIT | ARM_MODE_SVC
;- Save scratch/used registers and LR in User Stack
stmfd sp!, { r1-r3, r12, lr}

;- Branch to the routine pointed by the AIC_FVR
mov r14, pc
bx r0

;- Restore scratch/used registers and LR from User Stack
ldmia sp!, { r1-r3, r12, lr}

;- Leave Interrupts disabled and switch back in FIQ mode
msr CPSR_c, #I_BIT | F_BIT | ARM_MODE_FIQ

;- Restore the R0 ARM_MODE_SVC register
mov r0,r9

;- Restore the Program Counter using the LR_fiq directly in the PC
subs pc,lr,#4


InitReset:
;------------------------------------------------------------------------------
;- Low level Init (PMC, AIC, ? ....) by C function AT91F_LowLevelInit
;------------------------------------------------------------------------------
EXTERN AT91F_LowLevelInit

#define __iramend SFB(INTRAMEND_REMAP)

;- minumum C initialization
;- call AT91F_LowLevelInit( void)

ldr r13,=__iramend ; temporary stack in internal RAM
;--Call Low level init function in ABSOLUTE through the Interworking
ldr r0,=AT91F_LowLevelInit
mov lr, pc
bx r0

;------------------------------------------------------------------------------
;- Stack Sizes Definition
;------------------------
;- Interrupt Stack requires 2 words x 8 priority level x 4 bytes when using
;- the vectoring. This assume that the IRQ management.
;- The Interrupt Stack must be adjusted depending on the interrupt handlers.
;- Fast Interrupt not requires stack If in your application it required you must
;- be definehere.
;- The System stack size is not defined and is limited by the free internal
;- SRAM.
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
;- Top of Stack Definition
;-------------------------
;- Interrupt and Supervisor Stack are located at the top of internal memory in
;- order to speed the exception handling context saving and restoring.
;- ARM_MODE_SVC (Application, C) Stack is located at the top of the external memory.
;------------------------------------------------------------------------------

IRQ_STACK_SIZE EQU (3*8*4) ; 3 words per interrupt priority level

ARM_MODE_FIQ EQU 0x11
ARM_MODE_IRQ EQU 0x12
ARM_MODE_SVC EQU 0x13

I_BIT EQU 0x80
F_BIT EQU 0x40

;------------------------------------------------------------------------------
;- Setup the stack for each mode
;-------------------------------
ldr r0, =__iramend

;- Set up Fast Interrupt Mode and set FIQ Mode Stack
msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT
;- Init the FIQ register
ldr r8, =AT91C_BASE_AIC

;- Set up Interrupt Mode and set IRQ Mode Stack
msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT
mov r13, r0 ; Init stack IRQ
sub r0, r0, #IRQ_STACK_SIZE

;- Enable interrupt & Set up Supervisor Mode and set Supervisor Mode Stack
msr CPSR_c, #ARM_MODE_SVC
mov r13, r0


;---------------------------------------------------------------
; ?CSTARTUP
;---------------------------------------------------------------
EXTERN __segment_init
EXTERN main
; Initialize segments.
; __segment_init is assumed to use
; instruction set and to be reachable by BL from the ICODE segment
; (it is safest to link them in segment ICODE).
ldr r0,=__segment_init
mov lr, pc
bx r0

PUBLIC __main
?jump_to_main:
ldr lr,=?call_exit
ldr r0,=main
__main:
bx r0

;------------------------------------------------------------------------------
;- Loop for ever
;---------------
;- End of application. Normally, never occur.
;- Could jump on Software Reset ( B 0x0 ).
;------------------------------------------------------------------------------
?call_exit:
End
b End


;------------------------------------------------------------------------------
;- Manage exception
;---------------
;- This module The exception must be ensure in ARM mode
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;- Function : IRQ_Handler_Entry
;- Treatments : IRQ Controller Interrupt Handler.
;- Called Functions : AIC_IVR[interrupt]
;------------------------------------------------------------------------------
IRQ_Handler_Entry:

;- Manage Exception Entry
;- Adjust and save LR_irq in IRQ stack
sub lr, lr, #4
stmfd sp!, {lr}

;- Save SPSR need to be saved for nested interrupt
mrs r14, SPSR
stmfd sp!, {r14}

;- Save and r0 in IRQ stack
stmfd sp!, {r0}

;- Write in the IVR to support Protect Mode
;- No effect in Normal Mode
;- De-assert the NIRQ and clear the source in Protect Mode
ldr r14, =AT91C_BASE_AIC
ldr r0 , [r14, #AIC_IVR]
str r14, [r14, #AIC_IVR]

;- Enable Interrupt and Switch in Supervisor Mode
msr CPSR_c, #ARM_MODE_SVC

;- Save scratch/used registers and LR in User Stack
stmfd sp!, { r1-r3, r12, r14}

;- Branch to the routine pointed by the AIC_IVR
mov r14, pc
bx r0

;- Restore scratch/used registers and LR from User Stack
ldmia sp!, { r1-r3, r12, r14}

;- Disable Interrupt and switch back in IRQ mode
msr CPSR_c, #I_BIT | ARM_MODE_IRQ

;- Mark the End of Interrupt on the AIC
ldr r14, =AT91C_BASE_AIC
str r14, [r14, #AIC_EOICR]

;- Restore R0
ldmia sp!, {r0}

;- Restore SPSR_irq and r0 from IRQ stack
ldmia sp!, {r14}
msr SPSR_cxsf, r14

;- Restore adjusted LR_irq from IRQ stack directly in the PC
ldmia sp!, {pc}^
;---------------------------------------------------------------
; ?EXEPTION_VECTOR
; This module is only linked if needed for closing files.
;---------------------------------------------------------------
PUBLIC AT91F_Default_FIQ_handler
PUBLIC AT91F_Default_IRQ_handler
PUBLIC AT91F_Spurious_handler

CODE32 ; Always ARM mode after exeption

AT91F_Default_FIQ_handler
b AT91F_Default_FIQ_handler

AT91F_Default_IRQ_handler
b AT91F_Default_IRQ_handler

AT91F_Spurious_handler
b AT91F_Spurious_handler

ENDMOD

END


Сообщение отредактировал IgorKossak - Jun 26 2011, 15:39
Причина редактирования: научитесь оформлять в [codebox]
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 20 2011, 20:59
Сообщение #2


Гуру
******

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



Цитата(taoga @ Jun 20 2011, 22:30) *
Мне нужен файл board_cstartup_iar.s с (IAR 5.xx) с инициализацией обработчика по умолчанию для FIQ и соответствующего стека. Чтобы он функционально был аналогичен файлу Cstartup.s79 из примера AT91SAM7S32-Interrupt-IAR4_11A-1_1-FIQ.zip.

Если хотите получить аналог, просто скопируйте в свой стартап FIQ_Handler_Entry, заменив в нем ARM_MODE_SVC на ARM_MODE_SYS, и добавьте к инициализации стеков
Код
;- Set up Fast Interrupt Mode and set FIQ Mode Stack
                msr     CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT
;- Init the FIQ register
                ldr     r8, =AT91C_BASE_AIC

В строке "FIQ_Addr: DCD FIQ_Handler" замените FIQ_Handler на FIQ_Handler_Entry.


А вообще, это пример того, как не надо работать с FIQ. Правильно будет добавить инициализацию стека FIQ (в примере используется SVC), дурацкую обертку FIQ_Handler_Entry упразднить как класс, код разместить начиная непосредственно с адреса вектора.
Go to the top of the page
 
+Quote Post
taoga
сообщение Jun 21 2011, 07:47
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 51
Регистрация: 8-10-09
Пользователь №: 52 809



добавьте к инициализации стеков
Код
;- Set up Fast Interrupt Mode and set FIQ Mode Stack
                msr     CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT
;- Init the FIQ register
                ldr     r8, =AT91C_BASE_AIC

В строке "FIQ_Addr: DCD FIQ_Handler" замените FIQ_Handler на FIQ_Handler_Entry.


Добавил этот код к инициализации стека, получил ошибку.
Код
label:
        LDR     r0, =LowLevelInit
        LDR     r4, =SFE(CSTACK)
        MOV     sp, r4
        MOV     lr, pc
        BX      r0

        /* Set up Fast Interrupt Mode and set FIQ Mode Stack */
        msr     CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT
        /* Init the FIQ register */
        ldr     r8, =AT91C_BASE_AIC
                
        /* Set up the interrupt stack pointer. */
        MSR     cpsr_c, #ARM_MODE_IRQ | I_BIT | F_BIT     ; Change the mode
        LDR     sp, =SFE(IRQ_STACK)

        /* Set up the SVC stack pointer. */
        MSR     cpsr_c, #ARM_MODE_SVC | F_BIT             ; Change the mode
        LDR     sp, =SFE(CSTACK)


Building configuration: at91sam9xe-ek - at91sam9xe256_sram
Updating build tree...
board_cstartup_iar.s
Linking
Error[Lp002]: relocation failed: out of range or illegal value
     Kind    : R_ARM_LDR_PC_G0[0x4]
     Location: mem:0x304ff4
               "resetHandler" + 0x1c
               Module:  D:\Stas\Atmel\cc2400_arm9_1\at91sam9xe-ek\usb-device-core-project\ewp\at91sam9xe256_sram\Obj\board_cstartup_iar.o
               Section: 9 (.cstartup)
               Offset:  0x1c
     Target  : mem:0x300000
               "resetVector"
               Module:  D:\Stas\Atmel\cc2400_arm9_1\at91sam9xe-ek\usb-device-core-project\ewp\at91sam9xe256_sram\Obj\board_cstartup_iar.o
               Section: 8 (.vectors)
               Offset:  0x0
Error while running Linker

В документации и на форуме, написано, что нужно добавить в board_cstartup_iar.s этот код
Код
ldr     PC, [PC,# -0xF20]      ;AIC direct

Я это сделал, стал вызываться нужный обработчик прерывания, но после него программа уходит на перезагрузку. Как правильно оформить обработчик в этом случае?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 21 2011, 12:28
Сообщение #4


Гуру
******

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



Цитата(taoga @ Jun 21 2011, 11:47) *
Добавил этот код к инициализации стека, получил ошибку.

Надо полагать, он ругается на AT91C_BASE_AIC. Добавьте соответствующий ".inc"

Цитата(taoga @ Jun 21 2011, 11:47) *
В документации и на форуме, написано, что нужно добавить в board_cstartup_iar.s этот код
Код
ldr     PC, [PC,# -0xF20]     ;AIC direct

Я это сделал, стал вызываться нужный обработчик прерывания, но после него программа уходит на перезагрузку. Как правильно оформить обработчик в этом случае?

Оформление обработчиков прерываний посмотрите в IAR'овской документации. Не помню, правда, "умеет" ли он FIQ, или там общий вариант IRQ/FIQ. В последнем случае часть преимуществ режима FIQ сходит на нет.
Go to the top of the page
 
+Quote Post
taoga
сообщение Jun 22 2011, 05:48
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 51
Регистрация: 8-10-09
Пользователь №: 52 809



[quote name='aaarrr' date='Jun 21 2011, 16:28' post='942726']
Надо полагать, он ругается на AT91C_BASE_AIC. Добавьте соответствующий ".inc"

Ругается не на AT91C_BASE_AIC. В irqHandler уже используется данный идентификатор.
Go to the top of the page
 
+Quote Post
taoga
сообщение Jun 23 2011, 18:34
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 51
Регистрация: 8-10-09
Пользователь №: 52 809



В 5-м Iar'e у меня возникли проблемы со стандартным драйвером USB. Пример basic-usb... скорость передачи на хост в 4 раза меньше обычной для full speed usb. Поставил iar 6.3, загрузил тот же пример, проблемы со скоростью USB исчезли.
Добавил в таблицу векторов стартапа "ldr PC, [PC,# -0xF20] ;AIC direct" для FIQ. Оформил обработчик прерывания макросами __fiq __arm. Прерывание вручную генерируется, от внешнего источника никак. Обработчик прерывания отрабатывает нормально. Плюнул. Переделал схему на IRQ2, прерывание срабатывает от внешнего источника. Только частота срабатывания прерывания 1 МГц оказалась не по зубам этому контроллеру. Поэтому запустил второй SPI для непрерывного приема данных с использованием PDC. Принятые данные дальше передаются по USB. Так вот при начале передачи по USB гробится прием данных по SPI1. Взял исходный код для работы с USB из проекта для ARM7, без использования прерываний, все заработало. Поэтому вопрос: У всех такие грабли с sam9xe или его никто не использует? Нужно сообщать о найденных проблемах в Atmel?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 23 2011, 20:55
Сообщение #7


Гуру
******

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



Цитата(taoga @ Jun 23 2011, 22:34) *
Нужно сообщать о найденных проблемах в Atmel?

А они разве найдены? Формулировка "при начале передачи по USB гробится прием данных по SPI1" их явно не устроит.
Ищите источник проблем в своем софте.
Go to the top of the page
 
+Quote Post
taoga
сообщение Jun 24 2011, 18:15
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 51
Регистрация: 8-10-09
Пользователь №: 52 809



Цитата(aaarrr @ Jun 24 2011, 00:55) *
А они разве найдены? Формулировка "при начале передачи по USB гробится прием данных по SPI1" их явно не устроит.
Ищите источник проблем в своем софте.

Может вы подскажите?
У меня SPI0 используется для управления приемопередатчиком, по SPI1 с использованием PDC, принимаются данные. Когда я не передаю принятые данные по USB все работает без сбоев. Вставляю код драйвера USB (не знаю чьей разработки Atmel, IAR ...) непрерывный прием прекращается. По USB передается только первый принятый буфер, хотя установлены в PDC два буфера, соответственно срабатывает только одно прерывание ENDRX, и не приходит прерывание RXBUF, хотя если прием прервался, то должно. Убираю код драйвера, вставляю код из старого проекта для IAR 4.x и sam7s, данные непрерывно принимаются и передаются по USB. Код в общем то почти совпадает, за исключением того, что в новом драйвере используются прерывания, и добавлен соответствующий код в обработчик прерываний. И где ошибки в моем коде, когда я никоим образом в своих обработчиках не касаюсь регистров контроллера прерывания (за исключением кода из обработчика в стартапе, который я не менял).
Лично мной бы ценились практические советы, подкрепленные соответствующим кодом, а не теоретические изыскания. Если бы в примерах на sam9xe были отображены такие простые вопросы как использование прерывания FIQ, то я бы не задавал дурацкие вопросы вам, службе поддержки Atmel (которая отправила меня на www.at91.com) и at91.com, в котором меня отправили обратно к примерам и документации от Atmel.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 24 2011, 18:56
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (taoga @ Jun 24 2011, 21:15) *
Может вы подскажите?
...
Лично мной бы ценились практические советы..

Начните изучение с написания СВОЕГО кода. Пусть это будет мигалка светодиодом, но такая, что-бы Вы ПОЛНОСТЬЮ понимали, как все это делается и работает. Сваливание в кучу мусора из интернета, который Вы не понимаете есть путь в никуда.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

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

 


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


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