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

Вообщем, стартап код начинается так:

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.

 

У меня этот глюк проявился почти сразу.

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


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

2 dmyl

Ок посмотрю, спасибо. Но ведь МАМ даже не успевает настроиться, МАМ настраивается в TargetResetInit, в начале входа в который и происходит аборт. Т.е. МАМ, как мне кажется не причем.

BL InitStack ;Initialize the stack

BL TargetResetInit ;Initialize the target board

 

2 sensor_ua

V3.50

Изменено пользователем Цырен

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


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

а если пошагово выполнять код, то все нормально или в аборт все же залетаем? Если залетаем, то смотреть, что делается в инструкции, по которой залетаем, там проц лезет к несуществующей физически области памяти.

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


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

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)

Изменено пользователем Цырен

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


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

2 Andy Mozzhevilov

Сложно проследить по этому тексту весь ход выполнения.

Но нет ничего проще поиска причины повторяющейся из раза в раз проблемы.

Попробуйте сами проанализировать, у вас явно не проблема MAM.2 из соседней ветки.

Просто какая-то программная ошибка.

 

b5f0 PUSH {R4-R7, LR} ;Переход сюда, хотя в прошлой

Посмотрите, куда указывает указатель стека перед выполнением этой инструкции.

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

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


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

...

0x0000fbc4 LDR R12, [PC] ;потом собственно в функцию.

0x0000fbc8 BX R12

0x0000fbcc DD 0x000045ef ;этож не кратно 4-м!? Может здесь проблема?

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

 

"Собственно сама функия инициализации"

0x000045ee b5f0 PUSH {R4-R7, LR} ;Переход сюда, хотя в прошлой

;команде было

;0x000045ef

и все...выкидыш - аборт, если по супостатски.

Что у Вас в R13?

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


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

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

 

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

Изменено пользователем Юрий Санвальд

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


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

Действительно, в стэк-поинтере адрес, который вообще не отражается на ОЗУ. Т.е. команда PUSH пытается засунуть данные в неопределенное место. Так значит надо в компиляторе разбираться, ведь этот стартап-код стандартный. Я конечно поэкспериметирую с настройками, но, упреждая неудачу, спрошу, может кто сталкивался с проблемой, когда компилятор создавал стэки в месте, где нет ОЗУ?

:yeah:

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


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

спрошу, может кто сталкивался с проблемой, когда компилятор создавал стэки в месте, где нет ОЗУ?
Компилятор не причем. Разбирайтесь с линкером. Это он отвечает за размещение кода и данных в конкретные адреса. Смотрите какие данные вы ему даете. Возможно вы ему даете скрипт от другого процессора, который в этих адресах имеет ОЗУ.

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


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

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)

}

}

 

Попробуем...

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


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

но интуитивно ясно, что надо править выделенное красным. Первое число - ясно адрес верхней ячейки (ведь обращение к ОЗУ идет сверху вниз), второе - размер стэка.
Вам надо было взять ник "Штирлиц" или "Конспиратор" или что-то в этом роде :) На какие конкретно адреса у вас попадают указатели стеков? Я выделенную вами надпись интуитивно понял бы так - стеки размещать начиная с адреса 0x40008000(конец ОЗУ) минус 0x1800 (видимо суммарный размер всех стеков), т.е. с адреса 0x40006800. И если при этом стеки у вас выпадают за ОЗУ, значит вы где-то в установках выделили под какой-то из стеков слишком много места.

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


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

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

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

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

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

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

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

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

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

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