2013-09-17 3 views
6

В настоящее время я работаю над загрузчиком для ARM Cortex M3.C-код, вызывающий процедуру сборки - ARM

У меня есть две функции, одна в C и один в сборке но когда я пытаюсь вызвать функцию Ассамблеи моя программа зависает и генерирует какие-то ошибки.

функции следующим образом,

C:

extern void asmJump(void* Address) __attribute__((noreturn)); 

void load(void* Address) 
{ 
    asmJump(Address); 
} 

Монтаж:

.section .text 

.global asmJump 

asmJump:     @ Accepts the address of the Vector Table 
          @ as its first parameter (passed in r0) 

    ldr r2, [r0]   @ Move the stack pointer addr. to a temp register. 
    ldr r3, [r0, #4]  @ Move the reset vector addr. to a temp register. 

    mov sp, r2    @ Set the stack pointer 

    bx r3     @ Jump to the reset vector 

И моя проблема заключается в следующем:

Кодовые печатает " Привет "ove r, а затем вызывает load. Загруженный код печатает «Good Bye», а затем сбрасывает чип.

Если я медленно прохожу через ту часть, где load звонки asmJump все работает отлично. Однако, когда я позволяю коду запускать свой код, возникает ошибка «Ошибка памяти». Я знаю, что это ошибка памяти, поскольку она вызывает Hard Fault в некотором роде (бесконечный цикл цикла Hard Fault выполняет цикл, когда я делаю паузу через 4 или 5 секунд).

Неужели кто-нибудь испытал этот вопрос раньше? Если да, можете ли вы сообщить мне, как его решить?

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

Edit:

Спасибо @JoeHass за ваш ответ, и @MartinRosenau за ваш комментарий, я с тех пор пошел дальше, чтобы найти this SO answer, что было очень подробное объяснение того, почему мне нужен этот ярлык. Это очень долго читается, но стоит того.

+1

Если у вас есть разные процедуры прерывания для загрузчика и приложения: были ли вы отключены прерывания и заменили VTOR (регистр смещения таблицы векторов) на векторную таблицу второй программы? Это нужно сделать, прежде чем устанавливать указатель стека. – user694733

+2

1) Вы уверены, что указатель стека правильный? 2) Если ваш код - код THUMB, тогда r3 не должен быть адресом кода, а адресом кода плюс 1! –

+1

Попробуйте очистить * буфер записи *, * dcache * и * icache * до вашего вызова. Вы где-то скопировали код? Это звучит как проблема * code * '! =' * Data * или конвейер; который объясняет, что он работает при приостановке в отладчике. –

ответ

7

Я думаю, вам нужно сказать ассемблеру, чтобы использовать унифицированный синтаксис и явно объявить вашу функцию функцией большого пальца. Ассемблер GNU имеет директивы для этого:

.syntax unified 
    .section .text 
    .thumb_func 
    .global asmJump 
asmJump: 

директива .syntax unified сообщает ассемблеру, что вы используете современный синтаксис для сборки кода. Я думаю, что это неудачная реликвия какого-то старого синтаксиса.

Директива .thumb_func сообщает ассемблеру, что эта функция будет выполняться в режиме большого пальца, поэтому значение, которое используется для символа asmJump, имеет свой LSB, установленный в один. Когда Cortex-M выполняет ветвь, он проверяет LSB целевого адреса, чтобы узнать, является ли он одним. Если это так, то целевой код выполняется в режиме большого пальца. Поскольку это единственный режим, поддерживаемый Cortex-M, он будет работать, если LSB целевого адреса равен нулю.

+0

Это сработало! Я собираюсь найти, почему это сработало, но если вы чувствуете себя щедрым и расширяете свой ответ, это мне очень поможет. Независимо, вы решили мою проблему, спасибо! – nonsensickle

+0

Еще раз спасибо. Я нашел объяснение этому в другом вопросе SO здесь: http://stackoverflow.com/questions/9368360/arm-thumb-using-bx-in-thumb-code-to-call-a-thumb-functionor или -to-jump-to-a-thu – nonsensickle

+0

Я пробовал использовать код без '.syntax unified', но он, похоже, терпит неудачу. Я не знаю, почему это так. Не могли бы вы включить объяснение в свой ответ, если у вас его есть? – nonsensickle

0

Если это ваш код. Я полагаю, что ваша смена SP вызвала ошибку сегмента или что-то в этом роде. Вы должны сохранить свой SP перед его заменой и восстановить после использования.

ldr r6, =registerbackup 
str sp, [r6] 
#your code 
... 
ldr r6, =registerbackup 
ldr sp, [r6] 
+0

Обычно вы правы. Но поскольку это загрузчик, я намеренно устанавливаю указатель стека без опции резервного копирования. Новый адрес указателя стека - это то, что я прочитал из таблицы векторов кода, который я пытаюсь загрузить. Извините, если я не сделал это яснее. – nonsensickle

+0

Таким образом, проблема заключалась в том, что рука вызывала функцию большого пальца. Вот так. Великий u нашел основную причину. – TwoCode

1

Поскольку вы упоминаете, что у вас работает отладчик, используйте его!

Посмотрите на регистры состояния неисправности на determine the fault source. Возможно, это не ошибка asmJump, а код, который вы вызываете.

+0

спасибо, и я это сделаю. Я занимался настройкой обработчиков ошибок, чтобы я мог точно определить ошибку. – nonsensickle

Смежные вопросы