Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: LPC2364-KEIL-startup.s
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Цырен
Вообщем, стартап код начинается так:
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
dmyl
Посмотрите свежую еррату на чип, раздел МАМ.
Проверьте тоже самое с МАМ 1 или 0.

У меня этот глюк проявился почти сразу.
sensor_ua
Кайл 3.11 или другой?
Цырен
2 dmyl
Ок посмотрю, спасибо. Но ведь МАМ даже не успевает настроиться, МАМ настраивается в TargetResetInit, в начале входа в который и происходит аборт. Т.е. МАМ, как мне кажется не причем.
BL InitStack ;Initialize the stack
BL TargetResetInit ;Initialize the target board

2 sensor_ua
V3.50
dmyl
У меня после загрузки из иара МАМ ставится в 2. Наверное так лоадер сделан.
Andy Mozzhevilov
а если пошагово выполнять код, то все нормально или в аборт все же залетаем? Если залетаем, то смотреть, что делается в инструкции, по которой залетаем, там проц лезет к несуществующей физически области памяти.
Цырен
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, 16:17) *
2 Andy Mozzhevilov

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

b5f0 PUSH {R4-R7, LR} ;Переход сюда, хотя в прошлой
Посмотрите, куда указывает указатель стека перед выполнением этой инструкции.
Разберитесь, почему он указывает не туда, куда нужно, в каком месте и каким значением инициализируется.
a3r3
Цитата(Цырен @ 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
Цитата(a3r3 @ Jul 11 2007, 14:55) *
Это переключение в THUMB-режим. Все корректно.


Корректно? 07.gif Так оно и 2-м не кратно, или это именно так указывается что это переход на метку должен быть в THUMB режиме? wacko.gif
Цырен
Действительно, в стэк-поинтере адрес, который вообще не отражается на ОЗУ. Т.е. команда PUSH пытается засунуть данные в неопределенное место. Так значит надо в компиляторе разбираться, ведь этот стартап-код стандартный. Я конечно поэкспериметирую с настройками, но, упреждая неудачу, спрошу, может кто сталкивался с проблемой, когда компилятор создавал стэки в месте, где нет ОЗУ?
yeah.gif
Сергей Борщ
Цитата(Цырен @ Jul 11 2007, 16:35) *
спрошу, может кто сталкивался с проблемой, когда компилятор создавал стэки в месте, где нет ОЗУ?
Компилятор не причем. Разбирайтесь с линкером. Это он отвечает за размещение кода и данных в конкретные адреса. Смотрите какие данные вы ему даете. Возможно вы ему даете скрипт от другого процессора, который в этих адресах имеет ОЗУ.
sensor_ua
Цитата(Цырен @ 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. Должно очень помочьwink.gif
Цырен
Кажецца я всосал!!!
Дело в том, что компилятор инициализирует стэки в месте, где нет ОЗУ. При чем при инициализации, проблем нет, ведь при инициализации в стэкпоинты для различных режимов записываются начальные адреса соответствующих стэков. Потом, когда требуется вызвать функцию процессор обращается к стэку в адресе, где нет ОЗ. И как следствие, возникает ДатаАборт!
Короче нужно похоже править 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, 11:02) *
но интуитивно ясно, что надо править выделенное красным. Первое число - ясно адрес верхней ячейки (ведь обращение к ОЗУ идет сверху вниз), второе - размер стэка.
Вам надо было взять ник "Штирлиц" или "Конспиратор" или что-то в этом роде smile.gif На какие конкретно адреса у вас попадают указатели стеков? Я выделенную вами надпись интуитивно понял бы так - стеки размещать начиная с адреса 0x40008000(конец ОЗУ) минус 0x1800 (видимо суммарный размер всех стеков), т.е. с адреса 0x40006800. И если при этом стеки у вас выпадают за ОЗУ, значит вы где-то в установках выделили под какой-то из стеков слишком много места.
a3r3
Цитата(Юрий Санвальд @ Jul 11 2007, 16:47) *
Корректно? 07.gif Так оно и 2-м не кратно, или это именно так указывается что это переход на метку должен быть в THUMB режиме? wacko.gif

Именно так и указывается.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.