|
LPC2294 + IAR + Прерывания |
|
|
|
Apr 16 2012, 15:58
|
Группа: Участник
Сообщений: 14
Регистрация: 6-02-12
Пользователь №: 70 116

|
Добрый вечер!
Решил разобраться с работой прерываний на МК LPC 2294. Начал с самого простого - взял готовый пример поставляемый вместе со средой разработки, но он к сожалению оказался нерабочим. Выяснилось, что не работают прерывания, т.к. если убрать обработчики прерываний и формировать задержку простым счетом , то пример работает.
В связи с этим у меня возникли несколько вопросов:
1) Почему не работают прерывания, в чем может быть причина? 2) Может быть что-то неправильно проинициализировано (не инициализировано вообще) для обработки прерываний в файле startup.s? 3) Можно ли обойтись в проекте без файла startup.s. (вопрос возник т.к. в прилагаемом проекте он отсутствовал). Возможно при сборке проекта прилинковывается стандартный файл в каталоге со средой, но подходит ли он для моего процессора? Насколько мне известно, в файле startup.s находится таблица векторов исключительных ситуаций и в нем же производится инициализация указателей стек для различных режимов работы, настройка какой-либо периферии (опционально), ну и передача управления функции main. Вместо файла начальной инициализации в настройках проекта указан файл с расширением *.icf (Linker configuration file), в котором указано расположение векторов исключительных ситуаций и размеры стеков. Может ли этот файл заменить startup код или же придется писать его ручками?
4) Если нет, то где можно подчерпнуть информацию по его написанию? В Keil всё очень просто и структура файла довольно понятна, да и в книге Тревора Мартина все подробно описано, а вот в IAR мне не совсем понятно как это делается.
Заранее благодарю за ответ
P.S. В качестве среды разработки используется IAR EWARM
Сообщение отредактировал Diablo - Apr 16 2012, 16:02
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 20)
|
Apr 16 2012, 17:14
|
Группа: Участник
Сообщений: 14
Регистрация: 6-02-12
Пользователь №: 70 116

|
Собственно это я и сделал в первую очередь, весь код взят из примеров IARа, но в итоге прошивка работать не хочет.
|
|
|
|
|
Apr 17 2012, 16:12
|
Группа: Участник
Сообщений: 14
Регистрация: 6-02-12
Пользователь №: 70 116

|
Вот код основной программы CODE int main (void) { // System initialization, this will map the exception vectors. LPC2294SystemInit();
// Set up peripheral registers. LPC2294InitPIO();
// First disable interrupts. __disable_interrupt();
// Setup interrupt controller. LPC2294InitVIC(); LPC2294InitTimerInterrupt(TimerBeat);
// Periodic timer initialization. LPC2294InitTimer();
// Enable interrupts. __enable_interrupt();
// Start periodic timer. LPC2294StartTimer();
// Loop forever. for (;;) { LPC2294LedSet(); Sleep(200); // Display for 65 ms. LPC2294LedClear(); Sleep(200); // Display for 65 ms. } } Вот, что касается обработки прерываний CODE static void (*timer_function)(void);
static void TimerInterrupt(void) { (*timer_function)(); // Call timer callback function.
T0IR = 0xff; // Clear timer 0 interrupt line. }
__irq __arm void irq_handler(void) { void (*interrupt_function)(); unsigned int vector;
vector = VICVectAddr; // Get interrupt vector. interrupt_function = (void(*)())vector; (*interrupt_function)(); // Call vectored interrupt function.
VICVectAddr = 0; // Clear interrupt in VIC. }
void LPC2294InitVIC() { // Setup interrupt controller. VICProtection = 0; // Disable all interrupts VICIntEnClear = 0xffffffff; VICDefVectAddr = (unsigned int)&DefDummyInterrupt; }
void LPC2294InitTimerInterrupt(void(*timer_func)()) { // Setup timer callback function. timer_function = timer_func;
VICIntSelect &= ~VIC_TIMER0_bit; // IRQ on timer 0 line. VICVectAddr1 = (unsigned int)&TimerInterrupt; VICVectCntl1 = 0x20 | VIC_TIMER0; // Enable vector interrupt for timer 0. VICIntEnable = VIC_TIMER0_bit; // Enable timer 0 interrupt. }
static volatile int ms_ctr = 0;
// Timer interrupt callback void TimerBeat(void) { // Called at 1000 Hz rate. ms_ctr++; // Sleep counter. }
void Sleep(int milliseconds) { while (ms_ctr < milliseconds) ; ms_ctr = 0; }
Файл конфигурации линкера CODE /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x00000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x00000080; define symbol __ICFEDIT_region_ROM_end__ = 0x0003FDFF; define symbol __ICFEDIT_region_RAM_start__ = 0x40000040; define symbol __ICFEDIT_region_RAM_end__ = 0x40003FDF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x2000; define symbol __ICFEDIT_size_svcstack__ = 0x10; define symbol __ICFEDIT_size_irqstack__ = 0x100; define symbol __ICFEDIT_size_fiqstack__ = 0x0; define symbol __ICFEDIT_size_undstack__ = 0x0; define symbol __ICFEDIT_size_abtstack__ = 0x0; define symbol __ICFEDIT_size_heap__ = 0x1000; /**** End of ICF editor section. ###ICF###*/
define symbol __CRP_start__ = 0x000001FC; define symbol __CRP_end__ = 0x00000204;/*0x000001FF*/
/* Memory used by RealMonitor*/ define symbol __RM_start__ = 0x40000040; define symbol __RM_end__ = 0x4000011F;
define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__] - mem:[from __CRP_start__ to __CRP_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__] - mem:[from __RM_start__ to __RM_end__]; define region CRP_region = mem:[from __CRP_start__ to __CRP_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block SVC_STACK with alignment = 8, size = __ICFEDIT_size_svcstack__ { }; define block IRQ_STACK with alignment = 8, size = __ICFEDIT_size_irqstack__ { }; define block FIQ_STACK with alignment = 8, size = __ICFEDIT_size_fiqstack__ { }; define block UND_STACK with alignment = 8, size = __ICFEDIT_size_undstack__ { }; define block ABT_STACK with alignment = 8, size = __ICFEDIT_size_abtstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite }; do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block SVC_STACK, block IRQ_STACK, block FIQ_STACK, block UND_STACK, block ABT_STACK, block HEAP }; place in CRP_region { section .crp }; Файл startup.s CODE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Part one of the system initialization code, ;; contains low-level ;; initialization. ;; ;; Copyright 2006 IAR Systems. All rights reserved. ;; ;; $Revision: 47021 $ ;;
MODULE ?cstartup
;; Forward declaration of sections. SECTION IRQ_STACK:DATA:NOROOT(3) SECTION FIQ_STACK:DATA:NOROOT(3) SECTION ABT_STACK:DATA:NOROOT(3) SECTION SVC_STACK:DATA:NOROOT(3) SECTION UND_STACK:DATA:NOROOT(3) SECTION CSTACK:DATA:NOROOT(3)
; ; The module in this file are included in the libraries, and may be ; replaced by any user-defined modules that define the PUBLIC symbol ; __iar_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.
SECTION .intvec:CODE:NOROOT(2)
PUBLIC __vector PUBLIC __vector_0x14 PUBLIC __iar_program_start EXTERN irq_handler,fiq_handler
ARM __vector: ;; ldr pc,[pc,#+24] ;; Reset B . ;; Undefined instructions B . ;; Software interrupt (SWI/SVC) B . ;; Prefetch abort B . ;; Data abort __vector_0x14: DC32 0 ;; RESERVED ldr pc,[pc,#+24] ;; IRQ ldr pc,[pc,#+24] ;; FIQ
DC32 __iar_program_start ;; Reset DC32 0 ;; Undefined instructions DC32 0 ;; Software interrupt (SWI/SVC) DC32 0 ;; Prefetch abort DC32 0 ;; Data abort DC32 0 ;; RESERVED DC32 irq_handler ;; IRQ DC32 fiq_handler ;; FIQ
; -------------------------------------------------- ; ?cstartup -- low-level system initialization code. ; ; After a reser execution starts here, the mode is ARM, supervisor ; with interrupts disabled. ;
SECTION .text:CODE:NOROOT(2)
; PUBLIC ?cstartup EXTERN ?main REQUIRE __vector
ARM
__iar_program_start: ?cstartup:
; ; Add initialization needed before setup of stackpointers here. ; ; LPC2148 Errata ; Date: August 5, 2005 ; Document Release: Version 1.0 ; Device Affected: LPC2148 ; Incorrect read of data from SRAM after Reset and MAM is not enabled or partially enabled MAM.1 ; Init MAM before acsses to SRAM MAMCR DEFINE 0xE01FC000 ; MAM Control Register MAMTIM DEFINE 0xE01FC004 ; MAM Timing register
ldr r0,=MAMCR ldr r1,=MAMTIM ldr r2,=0 str r2,[r0] ldr r2,=7 str r2,[r1] ldr r2,=2 str r2,[r0]
; ; 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. ; ; -------------------- ; Mode, correspords to bits 0-5 in CPSR
MODE_MSK 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
mrs r0,cpsr ; Original PSR value bic r0,r0,#MODE_MSK ; Clear the mode bits orr r0,r0,#SVC_MODE ; Set Supervisor mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(SVC_STACK) ; End of SVC_STACK
bic r0,r0,#MODE_MSK ; Clear the mode bits orr r0,r0,#ABT_MODE ; Set Abort mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(ABT_STACK) ; End of ABT_STACK
bic r0,r0,#MODE_MSK ; Clear the mode bits orr r0,r0,#UND_MODE ; Set Undefined mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(UND_STACK) ; End of UND_STACK
bic r0,r0,#MODE_MSK ; Clear the mode bits orr r0,r0,#FIQ_MODE ; Set FIR mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(FIQ_STACK) ; End of FIR_STACK
bic r0,r0,#MODE_MSK ; 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) ; End of IRQ_STACK
bic r0,r0,#MODE_MSK ; Clear the mode bits orr r0,r0,#SYS_MODE ; Set System mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(CSTACK) ; 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
#ifndef __RAM_DEBUG SECTION .crp:CODE:ROOT(2) DATA /* Code Read Protection CRP 0x87654321 - Read Memory is disabled. - Write to RAM is disabled. - Go command is disabled. - Copy RAM to Flash is disabled. - JTAG is disabled. */ DCD 0xFFFFFFFF #endif
END
|
|
|
|
|
Apr 17 2012, 17:56
|

Профессионал
    
Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409

|
Сравнил lpc22 с lpc23/lpc17 (с которыми я работал) - есть существенные отличия. Если предположить что код из примера рабочий, то уточните вот что. В процедуре Код // System initialization. // void LPC2294SystemInit(void) { #ifdef iRAM MEMMAP = 2; // Map interrupt vectors to internal ram #else #ifdef iFLASH // Map interrupt vectors to internal flash MEMMAP = 1; #else BCFG0 = 0x20003CE3; // BCFG0: Flash Bus Configuration BCFG1 = 0x20003CE3; // BCFG1: Ram Bus Configuration PINSEL2 = 0x0E6149E4; // PINSEL2: CS0, CS1, CS2, OE, WE, BLS0..3, D0..31, A2..23, JTAG #ifdef xFLASH MEMMAP = 3; // Map interrupt vectors to the first external device (flash in this case) #else MEMMAP = 2; // Map interrupt vectors to internal ram for debugging from external ram #endif #endif #endif } производится отображение таблицы векторов на flash или ram. Вы определили константу iFLASH тобы все ваши вектора были отображены на flash? в icf файле вроде ничего криминального нет - размер flash/ram соответствует lpc2294, также размер стека достаточный. Стартап вроде нормальный. Могу предложить вообще удалить его из проекта - пусть иар подставит дефолтный для данного семейства. Привожу для сравнения стартап для lpc23xx CODE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Part one of the system initialization code, ;; contains low-level ;; initialization. ;; ;; Copyright 2006 IAR Systems. All rights reserved. ;; ;; $Revision: 30870 $ ;;
MODULE ?cstartup
;; Forward declaration of sections. SECTION IRQ_STACK:DATA:NOROOT(3) SECTION FIQ_STACK:DATA:NOROOT(3) SECTION SVC_STACK:DATA:NOROOT(3) SECTION ABT_STACK:DATA:NOROOT(3) SECTION UND_STACK:DATA:NOROOT(3) SECTION CSTACK:DATA:NOROOT(3)
; ; The module in this file are included in the libraries, and may be ; replaced by any user-defined modules that define the PUBLIC symbol ; __iar_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.
SECTION .intvec:CODE:NOROOT(2)
PUBLIC __vector PUBLIC __iar_program_start PUBLIC __vector_0x14 EXTERN undef_handler, swi_handler, prefetch_handler EXTERN data_handler, irq_handler, fiq_handler ARM ; Always ARM mode after reset __vector: ldr pc,[pc,#24] ; Absolute jump can reach 4 GByte __undef_handler: ldr pc,[pc,#24] ; Branch to undef_handler __swi_handler: ldr pc,[pc,#24] ; Branch to swi_handler __prefetch_handler: ldr pc,[pc,#24] ; Branch to prefetch_handler __data_handler ldr pc,[pc,#24] ; Branch to data_handler __vector_0x14 dc32 0xFFFFFFFF __irq_handler: ldr pc,[pc, #-0x0120] ; Branch to irq_handler __fiq_handler: ldr pc,[pc,#24] ; Branch to fiq_handler
; Constant table entries (for ldr pc) will be placed at 0x20 dc32 __iar_program_start dc32 __undef_handler dc32 __swi_handler dc32 __prefetch_handler dc32 __data_handler dc32 0xFFFFFFFF dc32 0xFFFFFFFF dc32 __fiq_handler
; -------------------- ; Mode, correspords to bits 0-5 in CPSR
MODE_MSK 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
CP_DIS_MASK DEFINE 0xFFFFFFF2
SECTION .text:CODE:NOROOT(2)
EXTERN ?main REQUIRE __vector EXTERN low_level_init
ARM
__iar_program_start: ?cstartup:
I_Bit DEFINE 0x80 ; when I bit is set, IRQ is disabled F_Bit DEFINE 0x40 ; when F bit is set, FIQ is disabled
#define VIC_INT_ENABLE 0xFFFFF014 ; Disable all interrupts ldr r0,=VIC_INT_ENABLE mov r1,#0xFFFFFFFF str r1,[r0]
; Execution starts here. ; After a reset, the mode is ARM, Supervisor, interrupts disabled. ; 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_MSK ; Clear the mode bits orr r0,r0,#SVC_MODE ; Set Supervisor mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(SVC_STACK) ; End of SVC_STACK bic r0,r0,#MODE_MSK ; Clear the mode bits orr r0,r0,#UND_MODE ; Set Undefined mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(UND_STACK) ; End of UND_MODE bic r0,r0,#MODE_MSK ; Clear the mode bits orr r0,r0,#ABT_MODE ; Set Data abort mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(ABT_STACK) ; End of ABT_STACK bic r0,r0,#MODE_MSK ; Clear the mode bits orr r0,r0,#FIQ_MODE ; Set FIR mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(FIQ_STACK) ; End of FIQ_STACK bic r0,r0,#MODE_MSK ; 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) ; End of IRQ_STACK bic r0,r0,#MODE_MSK | I_Bit | F_Bit ; Clear the mode bits orr r0,r0,#SYS_MODE ; Set System mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(CSTACK) ; End of CSTACK
#ifdef __ARMVFP__ ; Enable the VFP coprocessor. mov r0, #BASE_ARD_EIM ; 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
END
|
|
|
|
|
Apr 17 2012, 18:05
|
Группа: Участник
Сообщений: 14
Регистрация: 6-02-12
Пользователь №: 70 116

|
Отображение векторов производится на Flash
Что касается удаления startup из проекта, то изначально его там и не было. Подставить решил, когда начал проверять работу прерываний, но эффекта все равно никакого нет.
|
|
|
|
|
Apr 18 2012, 14:45
|
Группа: Участник
Сообщений: 14
Регистрация: 6-02-12
Пользователь №: 70 116

|
Что-то я вообще ничего не понимаю!
Зашил сегодня программу через JTAG и проследил выполнение по шагам - всё работает как надо. Но стоит только отключить JTAG и перезагрузить МК, программа работать перестаёт. Такое ощущение, что управление пользовательской программе не передаётся.
Возможно задам глупый вопрос, но можно ли через JTAG посмотреть, куда попадает программа сразу после сброса?
|
|
|
|
|
Apr 18 2012, 15:27
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Цитата Такое ощущение, что управление пользовательской программе не передаётся. Если у меня складывается такое ощущение, я первым делом проверяю, не попал ли контроллер в бут (флешмэджиком). Помогало неоднократно :-) Если оно так и есть, проверьте контрольную сумму (подробности - в user manual, искать "Criterion for valid user code") и уровень на соответствующей ноге. Цитата Возможно задам глупый вопрос, но можно ли через JTAG посмотреть, куда попадает программа сразу после сброса? Глупый или нет, но я ответ не знаю. У меня (keil) при старте отладки просто выставляет program counter = 0, и всё работает вне зависимости от загрузчика. Как посмотреть, что там с "настоящим" резетом, непонятно. Хотя нет, вру. В настройках отладчика есть выбор сброса контроллера. Возможно, какие-то варианты дадут нужный Вам результат.
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Apr 18 2012, 16:17
|
Группа: Участник
Сообщений: 14
Регистрация: 6-02-12
Пользователь №: 70 116

|
Цитата Если у меня складывается такое ощущение, я первым делом проверяю, не попал ли контроллер в бут (флешмэджиком). Помогало неоднократно :-) А можете в двух словах объяснить как это сделать или дать ссылку на документацию по Flash Magic? Просто никогда им не пользовался  И ещё, такое "непонятное" поведение микроконтроллера наблюдается только тогда, когда включаю обработку прерываний, если их убрать, то прошивка грузится и работает. Если же добавить код хотя бы инициализации VIC, то работать перестаёт. Т.е если бы контроллер попадал в бут или была бы неправильная КС, то прошивка не работала бы в обоих случаях. Или я не прав?
|
|
|
|
|
Apr 18 2012, 20:31
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
FlashMagic - это утилита для прошивки NXP'шных контроллеров через UART с помощью встроенного бутлоадера. Скачать можно по первой же ссылке в гугле. Цитата ...такое поведение наблюдается только тогда... Тогда, действительно, моя теория несостоятельна. Надо разбираться, что там по вектору IRQ лежит. Видимо, контроллер с первым же прерыванием улетает "не туда". А под JTAG'ом прерывания работают? Странно, вроде б должно быть одинаково.
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Apr 19 2012, 16:19
|
Группа: Участник
Сообщений: 14
Регистрация: 6-02-12
Пользователь №: 70 116

|
Посмотрел я сегодня что и как располагается в памяти и вроде бы всё на своих местах. Вот таблица исключительных ситуаций, начинается как ей и положено с 0 адреса CODE 0x0: 0xe59ff018 LDR PC, [PC, #0x18] ; [0x20] ?cstartup 0x4: 0xeafffffe B 0x4 0x8: 0xeafffffe B 0x8 0xc: 0xeafffffe B 0xc FIQ_MODE: USR_MODE: 0x10: 0xeafffffe B FIQ_MODE ; 0x10 __vector_0x14: 0x14: 0xa3202fc0 [ARM instr] 0x18: 0xe59ff018 LDR PC, [PC, #0x18] ; [0x38] irq_handler 0x1c: 0xe59ff018 LDR PC, [PC, #0x18] ; [0x3c] fiq_handler 0x20: 0x00000284 ANDEQ R0, R0, R4, LSL #5 0x24: 0x00000000 ANDEQ R0, R0, R0 0x28: 0x00000000 ANDEQ R0, R0, R0 0x2c: 0x00000000 ANDEQ R0, R0, R0 0x30: 0x00000000 ANDEQ R0, R0, R0 0x34: 0x00000000 ANDEQ R0, R0, R0 0x38: 0x00000080 ANDEQ R0, R0, R0, LSL #1 0x3c: 0x000000b8 STRHEQ R0, [R0], -R8
После рестарта выполняем инструкцию PC, [PC, #0x18], т.е загружаем в PC значение, находящееся по адресу 0х20. При возникновении прерывания переходим к выполнению функции по адресу 0х80. По 284 адресу у меня находится startup, а по 80 функция-обработчик прерывания CODE __irq __arm void irq_handler(void) { irq_handler: 0x80: 0xe24ee004 SUB LR, LR, #4 0x84: 0xe92d503f PUSH {R0-R5, R12, LR} vector = VICVectAddr; // Get interrupt vector. .....
?cstartup: __iar_program_start: 0x284: 0xe59f0084 LDR R0, _?0 ; MAMCR ldr r1,=MAMTIM 0x288: 0xe59f1084 LDR R1, _?1 ; MAMTIM ldr r2,=0 .....
Сравнивал дизассемблированный код, работающий под JTAG и файл прошивки, который заливал Flash Magic-ом и они совпадают. Поправьте меня пожалуйста если я что неправильно сказал, все-таки я совсем новичок в этом деле. Не может же быть чтобы все было правильно, но программа не работала.
|
|
|
|
|
Apr 19 2012, 17:16
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Я ни разу не видел IAR ARM. Покажите, пожалуйста, irq_handler. Просто интересно. А в остальном... Наверное, кто-то затирает MEMMAP, и в случае прерывания всё пропадает. Почему под JTAG'ом это не происходит, не знаю. Попробуйте опросить MEMMAP прямо перед разрешением прерывания. Там должна быть единичка. Разглядывал даташит "по диагонали", и не разобрался, что за ноги BOOT0/BOOT1. С ними всё правильно? Хотя, по идее, в противном случае совсем бы не работало. И дурацкий вопрос: другое прерывание пробовали? Вот ещё: Цитата define symbol __ICFEDIT_region_RAM_start__ = 0x40000040; define symbol __ICFEDIT_region_RAM_end__ = 0x40003FDF; В даташите указан диапазон 0x40000000 - 0x40002FFF. Если первое значение как-то пофиг (хотя зачем закладывать место на ремап векторов, если этого не делать?), то со вторым явный косяк. И ещё чЮдная цитата из errata: Pin TD1 (pin 22, H2) must not be driven LOW during reset. If LOW on reset the device behavior is undetermined.
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Apr 19 2012, 17:35
|
Группа: Участник
Сообщений: 14
Регистрация: 6-02-12
Пользователь №: 70 116

|
Вот пожалуйста  CODE __irq __arm void irq_handler(void) { void (*interrupt_function)(); unsigned int vector;
vector = VICVectAddr; // Get interrupt vector. interrupt_function = (void(*)())vector; (*interrupt_function)(); // Call vectored interrupt function.
VICVectAddr = 0; // Clear interrupt in VIC.
}
Насчет MEMMAP не знаю, надо будет посмотреть. Другое прерывание пробовал, та же история. А почему 0x40002FFF? В доках на микроконтроллер 0x40003FFF верхняя граница.
|
|
|
|
|
Apr 19 2012, 18:07
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Цитата А почему 0x40002FFF? В доках на микроконтроллер 0x40003FFF верхняя граница. Потому что я не задумываясь привёл цифру из UserManual, Table 17. LPC21xx and LPC22xx memory and peripheral configuration. Там десяток опечаток - для всех контроллеров с 16 килобайт ОЗУ указано это значение. Если верить на слово, что там всё-таки 16 килобайт, то Ваша цифра правильнее. А обработчик прерывания у IAR'а дурацкий :-) Кейл даёт следующий стартап: Код ; Exception Vectors Mapped to Address 0. ; Absolute addressing mode must be used. Vectors LDR PC, Reset_Addr LDR PC, Undef_Addr LDR PC, SWI_Addr LDR PC, PAbt_Addr LDR PC, DAbt_Addr NOP ; Reserved Vector LDR PC, [PC, #-0x0FF0] ; Vector from VicVectAddr LDR PC, FIQ_Addr В этом случае сразу же одной командой загружается адрес прерывания из соответствующего регистра (он не просто так расположен в самом конце адресного пространства!). VICVectAddr = 0; в конце прерывания надо делать самостоятельно.
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Apr 19 2012, 18:17
|
Группа: Участник
Сообщений: 14
Регистрация: 6-02-12
Пользователь №: 70 116

|
Keil вообще намного проще для освоения для новичка, как мне кажется. Но ничего не поделаешь, надо пользоваться IARом
|
|
|
|
|
Apr 20 2012, 14:47
|
Группа: Участник
Сообщений: 14
Регистрация: 6-02-12
Пользователь №: 70 116

|
To mempfis_ Спасибо огромное, обязательно попробую этот пример. Что касается книги, то сам начал её недавно читать, очень доступно написано, кстати есть уже и на русском языке. To esaulenka Цитата Ну попробуйте переделать эту Вашу программу на кейл, может, проблема и всплывёт... Пробовал, проекты отличались только стартапом. Переносил недостающие части и Кейловского файла в свой, но увы... Цитата Наверное, кто-то затирает MEMMAP И вы совершенно правы  Сегодня посмотрел JTAGом содержимое регистров после рестарта микроконтроллера. Значение MEMMAP = 3, т.е. режим использование внешней памяти, после записи в него 1 программа продолжает работу. Только мне в связи с этим непонятен один момент, если сразу после рестарта происходит ремап векторов во внешнюю память, то почему без проблем выполняется программа без использования прерываний?
|
|
|
|
|
Apr 20 2012, 15:29
|
Группа: Участник
Сообщений: 14
Регистрация: 6-02-12
Пользователь №: 70 116

|
Цитата При работе без прерываний не возникает исключительных ситуаций (FIQ, IRQ, Data Abort (пусть меня поправят гуру)), поэтому всё работет Я тоже точно не знаю, но по моему переотображается вся таблица векторов исключительных ситуация с 0x0 по 0x1C и пусть меня тоже поправят гуру если я не прав.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|