Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Пара вопросов по архитектуре
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
InsolentS
1) Как из супервизора обратиться к пользовательским CPSR и SP?
2) Можно ли как-нибудь отследить обращение пользователя к определенным адресам памяти?
Ассемблер и компилятор RV, ядро ARM7TDMI без MMU (SAM7..LPC).
Буду благодарен за любую информацию по теме.
defunct
1). CPRS у Вас будет в SPSR. А SP можно получить так - переключиться обратно в User mode сохранить SP и вернуться в режим супервизора. e.g:

.. сохранить R0 и R14

__asm{ MRS R0, CPSR};
__asm{ BIC R0, R0, #0x03 }; // Clear SV-mode bits
__asm{ MSR CPSR_c, R0 }; // Enter USER mode
// тут уже можно сохранять SP.
// Перейти из User mode в SV-mode - по SWI инструкции.
__asm{ MOV R0, R13 }; // store user SP
__asm{ SWI <код вашего обработчика> }; // call SV

2). Без MMU нельзя.
KRS
Цитата(defunct @ May 6 2008, 06:27) *
А SP можно получить так - переключиться обратно в User mode сохранить SP и вернуться в режим супервизора. e.g:

IMHO проще переключиться в SYSTEM, тогда обратно можно будет так же переключиться без SWI
amw
Цитата(InsolentS @ May 6 2008, 04:14) *
1) Как из супервизора обратиться к пользовательским CPSR и SP?

Вот тут приводил пример. Вроде работает.
http://electronix.ru/forum/index.php?showtopic=43839
defunct
Цитата(KRS @ May 6 2008, 09:40) *
IMHO проще переключиться в SYSTEM, тогда обратно можно будет так же переключиться без SWI

Да, действительно.
Rst7
Если не ошибаюсь, то метод получения USP в режиме супервизора таков
Код
SUB SP,SP,#4
MOV R1,SP
STMIA R1,{R13}^
LDMFD SP!,{R0}
KRS
Цитата(Rst7 @ May 6 2008, 14:51) *
Если не ошибаюсь, то метод получения USP в режиме супервизора таков
Код
SUB SP,SP,#4
MOV R1,SP
STMIA R1,{R13}^
LDMFD SP!,{R0}


А так нельзя?
Код
STMFD SP!,{R13}^
LDMFD SP!,{R0}
Rst7
Цитата
А так нельзя?


Пробовать надо. По поводу того, какой SP для адресации стека будет использован в первой команде (Usr или Svc) документация молчит. Так что если нету времени пробовать - мой вариант, есть время - может Ваш, а может мой wink.gif
InsolentS
Всем огромное спасибо!
Ещё небольшой вопрос - как современные оси, например, RTX отслеживают переполнение стека у пользовательской задачи без MMU?
aaarrr
Цитата(KRS @ May 6 2008, 15:24) *
А так нельзя?
Код
STMFD SP!,{R13}^
LDMFD SP!,{R0}

Нельзя:
Во-первых, нельзя модифицировать базовый регистр при работе с пользовательским банком.
Во-вторых, нельзя в следующей за тем инструкции пользоваться банкируемым регистром.

Можно так:
Код
stmdb    sp, {sp}^
mov      r0, r0
ldmdb    sp, {r0}


Но лучше так:
Код
sub        sp, sp, #0x04
stmia    sp, {sp}^
nop
ldmia    sp!, {r0}
Rst7
Цитата
А так нельзя?
Пробовать надо.


Для начала, надо внимательно читать документацию. Номер раз -
Цитата
Base register mode: For the purpose of address calculation, the base register is read from the current
processor mode registers, not the User mode registers.

Значит, годится STMxx SP,{R13}^

Но, имеем два -
Цитата
Banked registers: This instruction must not be followed by an instruction which accesses banked
registers (a following NOP is a good way to ensure this).


И три - нельзя writeback SP сделать

Значит, финальный вариант должен выглядеть так -
Код
SUB SP,SP,#4
STMEA SP,{R13}^
NOP
LDMFD SP!,{R0}


Цитата
Ещё небольшой вопрос - как современные оси, например, RTX отслеживают переполнение стека у пользовательской задачи без MMU?


За всех не отвечу, Nucleos при сборке с контролем стека банально внутри каждой ОСовской функции проверяет, не вышел ли стек за границу. Все. Полумера конечно, но бывает спасает.
InsolentS
Цитата(Rst7 @ May 6 2008, 18:00) *
Значит, финальный вариант должен выглядеть так -
Код
SUB SP,SP,#4
STMEA SP,{R13}^
NOP
LDMFD SP!,{R0}

Если честно, не совсем понял как работает этот код wacko.gif . Не могли бы Вы прокомментировать? Можно ли таким же макером достать пользовательский LR ?
Rst7
Цитата
Можно ли таким же макером достать пользовательский LR ?


Конечно. Только меняем {R13} на {R14}.
KRS
Цитата(InsolentS @ May 9 2008, 10:42) *
Если честно, не совсем понял как работает этот код wacko.gif . Не могли бы Вы прокомментировать? Можно ли таким же макером достать пользовательский LR ?

используется команда STM для сохранения списка регистров в память и LDM для чтения списка регистров из памяти (память выделяется в стеке, но моможно использовать и статически выделенную область), плюс используются некоторые особенности ее работы о которых лучше почитать в ARM architecture reference manual. Конечно можно таким образом и LR достать, а проще сразу все необходимые регистры за один раз
Код
  SUB SP, SP, #8
  STMIA SP, {R13,R14}
  NOP
  LDMFD SP!,{R0,R1}
Rst7
Цитата
STMIA SP, {R13,R14}


забыли ^

Код
STMIA SP, {R13,R14}^


Без нее будут регистры супервизора, в ней самая соль.
InsolentS
Цитата(Rst7 @ May 10 2008, 01:31) *
Без нее будут регистры супервизора, в ней самая соль.

А, теперь дошло, спасибо beer.gif
InsolentS
Есть ещё одна проблема, не стал создавать новую ветку.
Если прерывание возникает во время команды безусловного перехода ( B ), в LR сохраняется адрес следующей команды, а не той куда указывает B, т.е. прерывание как бы возникает по середине команды перехода, когда она уже загрузилась в конвейер, но ещё не выполнилась. Чувствую что надо поставить NOP чтобы прогнать конвейер, но не пойму где, посоветуйте пожалуйста как решить проблему эту 07.gif
aaarrr
Все правильно: в LR_irq сохраняется адрес возврата + 0x04, в обработчике адрес модифицируется. Никаких NOP'ов не нужно.
Rst7
Цитата
Если прерывание возникает во время команды безусловного перехода ( B ), в LR сохраняется адрес следующей команды


Не волнуйтесь. Костыль там уже вставлен на уровне ядра wink.gif В LRirq сохраняется именно адрес комманды на который происходит переход, точнее, +4. Хотя точно сейчас посмотрю даташит.

Да. Все правильно. Вот так надо возвращаться и из IRQ, и из FIQ.
Код
SUBS PC, R14, #4
InsolentS
Да, спасибо большое, разобрался :-)
Более внимательно прочтение даташита на ядро показало, что когда возвращаемся из PABT, FIQ, IRQ, надо из LR вычитать 4, а если из DABT то 8.
amw
Цитата(InsolentS @ May 12 2008, 12:45) *
Есть ещё одна проблема, не стал создавать новую ветку.
Если прерывание возникает во время команды безусловного перехода ( B ), в LR сохраняется адрес следующей команды, а не той куда указывает B, т.е. прерывание как бы возникает по середине команды перехода, когда она уже загрузилась в конвейер, но ещё не выполнилась. Чувствую что надо поставить NOP чтобы прогнать конвейер, но не пойму где, посоветуйте пожалуйста как решить проблему эту 07.gif

Либо компилятор вставит сам нужные команды, либо Вы вручную вставляете что-то типа
Код
@ Adjust and save LR_irq to IRQ stack
    sub    lr, lr, #4
    stmdb    sp!, {r0, r1, lr}    @ Save IRQ mode registers
...........
@ Restore adjusted LR_irq from IRQ stack directly in the PC
    ldmia    sp!, {r0, r1, pc}^    @ Restore IRQ mode registers

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