Diablo 0 16 апреля, 2012 Опубликовано 16 апреля, 2012 (изменено) · Жалоба Добрый вечер! Решил разобраться с работой прерываний на МК LPC 2294. Начал с самого простого - взял готовый пример поставляемый вместе со средой разработки, но он к сожалению оказался нерабочим. Выяснилось, что не работают прерывания, т.к. если убрать обработчики прерываний и формировать задержку простым счетом , то пример работает. В связи с этим у меня возникли несколько вопросов: 1) Почему не работают прерывания, в чем может быть причина? 2) Может быть что-то неправильно проинициализировано (не инициализировано вообще) для обработки прерываний в файле startup.s? 3) Можно ли обойтись в проекте без файла startup.s. (вопрос возник т.к. в прилагаемом проекте он отсутствовал). Возможно при сборке проекта прилинковывается стандартный файл в каталоге со средой, но подходит ли он для моего процессора? Насколько мне известно, в файле startup.s находится таблица векторов исключительных ситуаций и в нем же производится инициализация указателей стек для различных режимов работы, настройка какой-либо периферии (опционально), ну и передача управления функции main. Вместо файла начальной инициализации в настройках проекта указан файл с расширением *.icf (Linker configuration file), в котором указано расположение векторов исключительных ситуаций и размеры стеков. Может ли этот файл заменить startup код или же придется писать его ручками? 4) Если нет, то где можно подчерпнуть информацию по его написанию? В Keil всё очень просто и структура файла довольно понятна, да и в книге Тревора Мартина все подробно описано, а вот в IAR мне не совсем понятно как это делается. Заранее благодарю за ответ P.S. В качестве среды разработки используется IAR EWARM Изменено 16 апреля, 2012 пользователем Diablo Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mempfis_ 0 16 апреля, 2012 Опубликовано 16 апреля, 2012 · Жалоба Возьмите стартап и icf файл из примеров иара для вашего семейства процессоров. стартап пдключите к проекту, а в настройках линкера укажите путь к icf-файлу. Там же в примерах найдёте примеры инициализации VIC, инсталляции прерываний и их обработки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Diablo 0 16 апреля, 2012 Опубликовано 16 апреля, 2012 · Жалоба Собственно это я и сделал в первую очередь, весь код взят из примеров IARа, но в итоге прошивка работать не хочет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mempfis_ 0 16 апреля, 2012 Опубликовано 16 апреля, 2012 · Жалоба Собственно это я и сделал в первую очередь, весь код взят из примеров IARа, но в итоге прошивка работать не хочет. Выложите чтоли пример проекта который у Вас не идёт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Diablo 0 17 апреля, 2012 Опубликовано 17 апреля, 2012 · Жалоба Вот код основной программы 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. } } Вот, что касается обработки прерываний 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; } Файл конфигурации линкера /*###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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mempfis_ 0 17 апреля, 2012 Опубликовано 17 апреля, 2012 · Жалоба Сравнил 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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Diablo 0 17 апреля, 2012 Опубликовано 17 апреля, 2012 · Жалоба Отображение векторов производится на Flash Что касается удаления startup из проекта, то изначально его там и не было. Подставить решил, когда начал проверять работу прерываний, но эффекта все равно никакого нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Diablo 0 18 апреля, 2012 Опубликовано 18 апреля, 2012 · Жалоба Что-то я вообще ничего не понимаю! Зашил сегодня программу через JTAG и проследил выполнение по шагам - всё работает как надо. Но стоит только отключить JTAG и перезагрузить МК, программа работать перестаёт. Такое ощущение, что управление пользовательской программе не передаётся. Возможно задам глупый вопрос, но можно ли через JTAG посмотреть, куда попадает программа сразу после сброса? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 18 апреля, 2012 Опубликовано 18 апреля, 2012 · Жалоба Такое ощущение, что управление пользовательской программе не передаётся. Если у меня складывается такое ощущение, я первым делом проверяю, не попал ли контроллер в бут (флешмэджиком). Помогало неоднократно :-) Если оно так и есть, проверьте контрольную сумму (подробности - в user manual, искать "Criterion for valid user code") и уровень на соответствующей ноге. Возможно задам глупый вопрос, но можно ли через JTAG посмотреть, куда попадает программа сразу после сброса? Глупый или нет, но я ответ не знаю. У меня (keil) при старте отладки просто выставляет program counter = 0, и всё работает вне зависимости от загрузчика. Как посмотреть, что там с "настоящим" резетом, непонятно. Хотя нет, вру. В настройках отладчика есть выбор сброса контроллера. Возможно, какие-то варианты дадут нужный Вам результат. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Diablo 0 18 апреля, 2012 Опубликовано 18 апреля, 2012 · Жалоба Если у меня складывается такое ощущение, я первым делом проверяю, не попал ли контроллер в бут (флешмэджиком). Помогало неоднократно :-) А можете в двух словах объяснить как это сделать или дать ссылку на документацию по Flash Magic? Просто никогда им не пользовался :) И ещё, такое "непонятное" поведение микроконтроллера наблюдается только тогда, когда включаю обработку прерываний, если их убрать, то прошивка грузится и работает. Если же добавить код хотя бы инициализации VIC, то работать перестаёт. Т.е если бы контроллер попадал в бут или была бы неправильная КС, то прошивка не работала бы в обоих случаях. Или я не прав? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 18 апреля, 2012 Опубликовано 18 апреля, 2012 · Жалоба FlashMagic - это утилита для прошивки NXP'шных контроллеров через UART с помощью встроенного бутлоадера. Скачать можно по первой же ссылке в гугле. ...такое поведение наблюдается только тогда... Тогда, действительно, моя теория несостоятельна. Надо разбираться, что там по вектору IRQ лежит. Видимо, контроллер с первым же прерыванием улетает "не туда". А под JTAG'ом прерывания работают? Странно, вроде б должно быть одинаково. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Diablo 0 19 апреля, 2012 Опубликовано 19 апреля, 2012 · Жалоба Посмотрел я сегодня что и как располагается в памяти и вроде бы всё на своих местах. Вот таблица исключительных ситуаций, начинается как ей и положено с 0 адреса 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 функция-обработчик прерывания __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-ом и они совпадают. Поправьте меня пожалуйста если я что неправильно сказал, все-таки я совсем новичок в этом деле. Не может же быть чтобы все было правильно, но программа не работала. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 19 апреля, 2012 Опубликовано 19 апреля, 2012 · Жалоба Я ни разу не видел 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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Diablo 0 19 апреля, 2012 Опубликовано 19 апреля, 2012 · Жалоба Вот пожалуйста :) __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 верхняя граница. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 19 апреля, 2012 Опубликовано 19 апреля, 2012 · Жалоба А почему 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; в конце прерывания надо делать самостоятельно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться