Полная версия этой страницы:
LPC2364-KEIL-startup.s
Вообщем, стартап код начинается так:
Reset
LDR PC, ResetAddr (1*)
LDR PC, UndefinedAddr
LDR PC, SWI_Addr
LDR PC, PrefetchAddr
LDR PC, DataAbortAddr (2*)
DCD 0xb9205f80
;DCD 0xb9206e50
LDR PC, [PC, #-0x120] ; pc <- VICVectAddr using pc relative addressing (NEW)
LDR PC, FIQ_Addr
ResetAddr DCD ResetInit
UndefinedAddr DCD Undefined
SWI_Addr DCD SWInterrupt
PrefetchAddr DCD PrefetchAbort
DataAbortAddr DCD DataAbort
DCD 0
IRQ_Addr DCD 0
FIQ_Addr DCD FIQ_Exception
При дебагинге через JTAG процессор переходит по адресу 1* ResetAddr. В ней происходит следующее (инициализация стэков, инициализация системной периферии и вваливание в основной код):
ResetInit
BL InitStack ;Initialize the stack
BL TargetResetInit ;Initialize the target board
B __main ;Jump to the entry point of C program
ПРОБЛЕМА:
Процессор после обработки InitStack входит в режим DataAbort и переходит по метке 2* DataAbortAddr в соответствующий обработчик, где процессор ожидает вечный цикл. При этом PC успевает перейти на метку(функцию) TargetResetInit и прямо в начале этой функции проц уходит в режим DataAbort. Последнее понятно почему - скорее всего конвееризация обработки команд.
Что не так с InitStack?
InitStack
MOV R0, LR
;Build the SVC stack
MSR CPSR_c, #SVC32Mode
LDR SP, =StackSvc (размер 64*4 слов)
;Build the IRQ stack
MSR CPSR_c, #IRQ32Mode
LDR SP, =StackIrq (размер 256*4 слов)
;Build the FIQ stack
MSR CPSR_c, #FIQ32Mode
LDR SP, =StackFiq (размер 64*4 слов)
;Build the DATAABORT stack
MSR CPSR_c, #ABT32Mode
LDR SP, =StackAbt (размер 64*4 слов)
;Build the UDF stack
MSR CPSR_c, #UDF32Mode
LDR SP, =StackUnd (размер 64*4 слов)
;Build the SYS stack
MSR CPSR_c, #SYS32Mode
LDR SP, =StackUsr (размер 1024*4 слов) !!!!!!!!!!!!!!!! <- может слишком большой?
MOV PC, R0
Посмотрите свежую еррату на чип, раздел МАМ.
Проверьте тоже самое с МАМ 1 или 0.
У меня этот глюк проявился почти сразу.
sensor_ua
Jul 9 2007, 18:10
Кайл 3.11 или другой?
2 dmyl
Ок посмотрю, спасибо. Но ведь МАМ даже не успевает настроиться, МАМ настраивается в TargetResetInit, в начале входа в который и происходит аборт. Т.е. МАМ, как мне кажется не причем.
BL InitStack ;Initialize the stack
BL TargetResetInit ;Initialize the target board
2 sensor_ua
V3.50
У меня после загрузки из иара МАМ ставится в 2. Наверное так лоадер сделан.
Andy Mozzhevilov
Jul 10 2007, 11:01
а если пошагово выполнять код, то все нормально или в аборт все же залетаем? Если залетаем, то смотреть, что делается в инструкции, по которой залетаем, там проц лезет к несуществующей физически области памяти.
2 Andy Mozzhevilov
Помоему, действительно процу программа пытается вскормить адрес, которого нет. Вот ассемблеровка в той последовательности, которая имеет место быть в действительности (адрес, команда, аргументы):
0х00000000 LDR PC, [PC, #0x0018] идем к обработке события "резет"
->"Резет"
0x000000cc BL 0x00000094 ;переход к месту где выделяется память в ОЗУ для
;стэков...
;"функция" инициализации стэка
0x00000094 MOV R0, R14 ;Чтоб знать куда возвращаться
-> строим стэк
0х000000с4 LDR R13, [PC, #0x004c] ; и выходим обратно к "Резет"
"Резет"
0х000000с8 MOV PC, R0
"Инициализация системной периферии" ;реализовано в С-функции
0x000000d0 BL 0x0000fbc4 ;идем по метке зачем-то сюда?
скоооооооок!
0x0000fbc4 LDR R12, [PC] ;потом собственно в функцию.
0x0000fbc8 BX R12
0x0000fbcc DD 0x000045ef ;этож не кратно 4-м!? Может здесь проблема?
"Собственно сама функия инициализации"
0x000045ee b5f0 PUSH {R4-R7, LR} ;Переход сюда, хотя в прошлой
;команде было
;0x000045ef
и все...выкидыш - аборт, если по супостатски.
0x000045f0 LDR R0, [PC, #0x0150] ; вот что должно быть далее, может проблема та, что
;описана в ерраташите?:
<any instruction>
<STR, STMIA, PUSH> <---- data abort on this instruction
LDR rn, [pc,#offset]
Еслибы не одно "но". Я и в ARM режиме компилил прогу (менял настройку в КЕЙЛе. Options->Target->ARM mode)
Andy Mozzhevilov
Jul 11 2007, 10:41
Цитата(Цырен @ Jul 11 2007, 16:17)

2 Andy Mozzhevilov
Сложно проследить по этому тексту весь ход выполнения.
Но нет ничего проще поиска причины повторяющейся из раза в раз проблемы.
Попробуйте сами проанализировать, у вас явно не проблема MAM.2 из соседней ветки.
Просто какая-то программная ошибка.
b5f0 PUSH {R4-R7, LR} ;Переход сюда, хотя в прошлой
Посмотрите, куда указывает указатель стека перед выполнением этой инструкции.
Разберитесь, почему он указывает не туда, куда нужно, в каком месте и каким значением инициализируется.
Цитата(Цырен @ Jul 11 2007, 14:17)

...
0x0000fbc4 LDR R12, [PC] ;потом собственно в функцию.
0x0000fbc8 BX R12
0x0000fbcc DD 0x000045ef ;этож не кратно 4-м!? Может здесь проблема?
Это переключение в THUMB-режим. Все корректно.
Цитата(Цырен @ Jul 11 2007, 14:17)

"Собственно сама функия инициализации"
0x000045ee b5f0 PUSH {R4-R7, LR} ;Переход сюда, хотя в прошлой
;команде было
;0x000045ef
и все...выкидыш - аборт, если по супостатски.
Что у Вас в R13?
SanvaldYV
Jul 11 2007, 12:47
Цитата(a3r3 @ Jul 11 2007, 14:55)

Это переключение в THUMB-режим. Все корректно.
Корректно?

Так оно и 2-м не кратно, или это именно так указывается что это переход на метку должен быть в THUMB режиме?
Действительно, в стэк-поинтере адрес, который вообще не отражается на ОЗУ. Т.е. команда PUSH пытается засунуть данные в неопределенное место. Так значит надо в компиляторе разбираться, ведь этот стартап-код стандартный. Я конечно поэкспериметирую с настройками, но, упреждая неудачу, спрошу, может кто сталкивался с проблемой, когда компилятор создавал стэки в месте, где нет ОЗУ?
Сергей Борщ
Jul 11 2007, 14:01
Цитата(Цырен @ Jul 11 2007, 16:35)

спрошу, может кто сталкивался с проблемой, когда компилятор создавал стэки в месте, где нет ОЗУ?
Компилятор не причем. Разбирайтесь с линкером. Это он отвечает за размещение кода и данных в конкретные адреса. Смотрите какие данные вы ему даете. Возможно вы ему даете скрипт от другого процессора, который в этих адресах имеет ОЗУ.
sensor_ua
Jul 11 2007, 15:12
Цитата(Цырен @ Jul 10 2007, 09:57)

2 dmyl
Ок посмотрю, спасибо. Но ведь МАМ даже не успевает настроиться, МАМ настраивается в TargetResetInit, в начале входа в который и происходит аборт. Т.е. МАМ, как мне кажется не причем.
BL InitStack ;Initialize the stack
BL TargetResetInit ;Initialize the target board
2 sensor_ua
V3.50
Рекомендую всё-таки перейти на Keil 3.11 uVision 3.53. Должно очень помочь
Кажецца я всосал!!!
Дело в том, что компилятор инициализирует стэки в месте, где нет ОЗУ. При чем при инициализации, проблем нет, ведь при инициализации в стэкпоинты для различных режимов записываются начальные адреса соответствующих стэков. Потом, когда требуется вызвать функцию процессор обращается к стэку в адресе, где нет ОЗ. И как следствие, возникает ДатаАборт!
Короче нужно похоже править skatter file в опциях линкера. После нажатия на жмакалку Edit в окне редактора возникает листинг какого-то мне неизвестного скрипта, но интуитивно ясно, что надо править выделенное красным. Первое число - ясно адрес верхней ячейки (ведь обращение к ОЗУ идет сверху вниз), второе - размер стэка.
;/****************************************************************************
; * mem_rel.scf: Scatter file for Philips LPC230x/240x Family
; * Microprocessors
; *
; * Copyright© 2006, Philips Semiconductor
; * All rights reserved.
; *
; * History
; * 2005.10.01 ver 1.00 Prelimnary version, first Release
; *
;*****************************************************************************/
; code loaded to flash 0x00000000 for execution, build for release
ROM_LOAD 0x0
{
ROM_EXEC 0x00000000
{
Startup.o (vectors, +First)
* (+RO)
}
IRAM 0x40000000
{
* (+RW,+ZI)
}
HEAP +0 UNINIT
{
Startup.o (Heap)
}
STACKS 0x40008000-0x1800 UNINIT
{
Startup.o (Stacks)
}
}
Попробуем...
Сергей Борщ
Jul 12 2007, 10:27
Цитата(Цырен @ Jul 12 2007, 11:02)

но интуитивно ясно, что надо править выделенное красным. Первое число - ясно адрес верхней ячейки (ведь обращение к ОЗУ идет сверху вниз), второе - размер стэка.
Вам надо было взять ник "Штирлиц" или "Конспиратор" или что-то в этом роде

На какие конкретно адреса у вас попадают указатели стеков? Я выделенную вами надпись интуитивно понял бы так - стеки размещать начиная с адреса 0x40008000(конец ОЗУ) минус 0x1800 (видимо суммарный размер всех стеков), т.е. с адреса 0x40006800. И если при этом стеки у вас выпадают за ОЗУ, значит вы где-то в установках выделили под какой-то из стеков слишком много места.
Цитата(Юрий Санвальд @ Jul 11 2007, 16:47)

Корректно?

Так оно и 2-м не кратно, или это именно так указывается что это переход на метку должен быть в THUMB режиме?

Именно так и указывается.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.