Перейти к содержанию
    

LPC2294 + IAR + Прерывания

Добрый вечер!

 

Решил разобраться с работой прерываний на МК 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возьмите стартап и icf файл из примеров иара для вашего семейства процессоров. стартап пдключите к проекту, а в настройках линкера укажите путь к icf-файлу. Там же в примерах найдёте примеры инициализации VIC, инсталляции прерываний и их обработки.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Собственно это я и сделал в первую очередь, весь код взят из примеров IARа, но в итоге прошивка работать не хочет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Собственно это я и сделал в первую очередь, весь код взят из примеров IARа, но в итоге прошивка работать не хочет.

 

Выложите чтоли пример проекта который у Вас не идёт.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот код основной программы

 

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

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сравнил 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


Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Отображение векторов производится на Flash

 

Что касается удаления startup из проекта, то изначально его там и не было. Подставить решил, когда начал проверять работу прерываний, но эффекта все равно никакого нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что-то я вообще ничего не понимаю!

 

Зашил сегодня программу через JTAG и проследил выполнение по шагам - всё работает как надо. Но стоит только отключить JTAG и перезагрузить МК, программа работать перестаёт. Такое ощущение, что управление пользовательской программе не передаётся.

 

Возможно задам глупый вопрос, но можно ли через JTAG посмотреть, куда попадает программа сразу после сброса?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Такое ощущение, что управление пользовательской программе не передаётся.

 

Если у меня складывается такое ощущение, я первым делом проверяю, не попал ли контроллер в бут (флешмэджиком). Помогало неоднократно :-)

 

Если оно так и есть, проверьте контрольную сумму (подробности - в user manual, искать "Criterion for valid user code") и уровень на соответствующей ноге.

 

 

Возможно задам глупый вопрос, но можно ли через JTAG посмотреть, куда попадает программа сразу после сброса?

Глупый или нет, но я ответ не знаю. У меня (keil) при старте отладки просто выставляет program counter = 0, и всё работает вне зависимости от загрузчика. Как посмотреть, что там с "настоящим" резетом, непонятно.

 

Хотя нет, вру. В настройках отладчика есть выбор сброса контроллера. Возможно, какие-то варианты дадут нужный Вам результат.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если у меня складывается такое ощущение, я первым делом проверяю, не попал ли контроллер в бут (флешмэджиком). Помогало неоднократно :-)

А можете в двух словах объяснить как это сделать или дать ссылку на документацию по Flash Magic? Просто никогда им не пользовался :)

 

И ещё, такое "непонятное" поведение микроконтроллера наблюдается только тогда, когда включаю обработку прерываний, если их убрать, то прошивка грузится и работает. Если же добавить код хотя бы инициализации VIC, то работать перестаёт. Т.е если бы контроллер попадал в бут или была бы неправильная КС, то прошивка не работала бы в обоих случаях. Или я не прав?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

FlashMagic - это утилита для прошивки NXP'шных контроллеров через UART с помощью встроенного бутлоадера.

Скачать можно по первой же ссылке в гугле.

 

 

...такое поведение наблюдается только тогда...

Тогда, действительно, моя теория несостоятельна.

 

Надо разбираться, что там по вектору IRQ лежит. Видимо, контроллер с первым же прерыванием улетает "не туда".

А под JTAG'ом прерывания работают? Странно, вроде б должно быть одинаково.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Посмотрел я сегодня что и как располагается в памяти и вроде бы всё на своих местах.

 

Вот таблица исключительных ситуаций, начинается как ей и положено с 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-ом и они совпадают.

 

Поправьте меня пожалуйста если я что неправильно сказал, все-таки я совсем новичок в этом деле. Не может же быть чтобы все было правильно, но программа не работала.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я ни разу не видел 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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот пожалуйста :)

__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 верхняя граница.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А почему 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; в конце прерывания надо делать самостоятельно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...