реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> Выход из handler-mode в cortex-m3
1113
сообщение May 11 2014, 11:50
Сообщение #16


Знающий
****

Группа: Свой
Сообщений: 604
Регистрация: 24-02-06
Из: Москва
Пользователь №: 14 658



имхо это не влияет. у вас оно равно 0 потому что прерываний ещё не было. по идее уже разобрались - LR должен содержать конкретные значения, записываемые в него ядром по умолчанию, то есть их не надо изменять. кроме битов режима.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 11 2014, 13:42
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



А правильно я понимаю что LR служит для того чтобы определить откуда мы попали в прерывание и не более того? То есть на самом деле для задачи LR не имеет смысла.
в нем может храниться всего 3 разных значения
0xFFFFFFF1 -return handler mode
0xFFFFFFF9 -return thread mode используя MSP
0xFFFFFFFD -retrun thread mode используя PSP
и запись значения LR в PC просто запускает процесс возврата. То есть если нет вложенных прерываний, и вы всегда попадаете в ваше прерывание из подзадачи, вы можете просто в PC заносить одно из 3 значений выше (какой режим вам нужен) и забыть про LR вообще?


Go to the top of the page
 
+Quote Post
1113
сообщение May 11 2014, 14:16
Сообщение #18


Знающий
****

Группа: Свой
Сообщений: 604
Регистрация: 24-02-06
Из: Москва
Пользователь №: 14 658



Цитата(Golikov A. @ May 11 2014, 16:42) *
А правильно я понимаю что LR служит для того чтобы определить откуда мы попали в прерывание и не более того? То есть на самом деле для задачи LR не имеет смысла.
в нем может храниться всего 3 разных значения
0xFFFFFFF1 -return handler mode
0xFFFFFFF9 -return thread mode используя MSP
0xFFFFFFFD -retrun thread mode используя PSP
и запись значения LR в PC просто запускает процесс возврата. То есть если нет вложенных прерываний, и вы всегда попадаете в ваше прерывание из подзадачи, вы можете просто в PC заносить одно из 3 значений выше (какой режим вам нужен) и забыть про LR вообще?
верна лишь логика, потому PC тут вообще не причём. определяющим регистром является не PC а LR. если LR имеет одно из указанных значений, процессор вместо тупого перехода по адресу [LR] обновляет его из стэка и только потом переходит.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 11 2014, 14:56
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



а я вот доки почитал повнимательнее...

если говорить про конртекс м3
значение счетчика команд для возврата из прерывания храниться в СТЕКЕ! И восстанавливается во время процедуры выхода из прерывания.
в LR сохраняется режим из которого мы попали в прерывание

команда загрузки LR в PC - это не задание адреса выхода, это кодовая команда запуска процедуры выхода. и в зависимости от кода что лежит в LR, будет из разных мест восстановлен контекст задачи...
то есть другими словами выйти из прерывания можно явно загрузив в PC коды
0xFFFFFFF1, 0xFFFFFFF9, 0xFFFFFFFD.

если загрузим код ....1, то контекст будет восстановлен из MSP, и выйдем мы в hedlre режим
если загрузим код ....9, то контекст будет восстановлен из MSP, но выйдем в thread режим, и дальше будет использоваться как указатель стэка MSP
если код ....D? то как в 9, только PSP.


другими словами понимая задачу ТС, надо делать вот как.

1. Задачи надо запустить с использованием PSP, по умолчанию после ресета все работают на MSP.
2. Во время возникновения прерывания таймера для смены задачи, вам надо сохранить значение PSP, при этом поскольку вы в прерывании у вас используется MSP, в него и сохраняйте PSP прерванной задачи.
3. задать новое значение в PSP для новой задачи
4. записать в PC значение 0xFFFFFFFD, это запустить выход из прерывания с использованием PSP, при этом поскольку вы его подменили на PSP новой задачи, выйдете вы в новую задачу.


Важный момент это создание контекста задачи первый раз, я себе это вижу так. Каждая задача добавляется таким образом
1. Вы переводите работу задачи на PSP, сохраняете в ее стэк все ее локальные переменные,
2. вызываете прерывание смены задачи, или ждете таймера, первый вход в прерывание смены задачи сохранит контекст, и в задачу можно будет попадать по переключению. До первого перехода в прерывание в задачу попасть нельзя, она должна быть запущена явна.


Go to the top of the page
 
+Quote Post
1113
сообщение May 11 2014, 15:18
Сообщение #20


Знающий
****

Группа: Свой
Сообщений: 604
Регистрация: 24-02-06
Из: Москва
Пользователь №: 14 658



Цитата(Golikov A. @ May 11 2014, 17:56) *
а я вот доки почитал повнимательнее...

в LR сохраняется режим из которого мы попали в прерывание
не так. вот оригинал:
Цитата
The processor performs a vector fetch that reads the exception handler start address from the vector table. When stacking is complete, the processor starts executing the exception handler. At the same time, the processor writes an EXC_RETURN value to the LR. This indicates which stack pointer corresponds to the stack frame and what operation mode the processor was in before the entry occurred.
таким образом в начале выполнения эксепшена в LR ничего кроме "волшебного значения" нет и никогда не будет не зависимо ни от чего.
Цитата(Golikov A. @ May 11 2014, 17:56) *
До первого перехода в прерывание в задачу попасть нельзя, она должна быть запущена явна.
нет - стэк этой задачи не будет изолирован от стэка ядра. надо просто в стэке задачи установить сохранённый PC как адрес main`а этой задачи.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 11 2014, 16:03
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
This indicates which stack pointer corresponds to the stack frame and what operation mode the processor was in before the entry occurred.


если исходить что в задачах используем PSP, то если мы попадем в прерывание из задачи в LR будет лежать магическое число говорящая что выходить надо через PSP, если же вложенное прерывание то мы попадем из hendler режима, в котором будет только MSP.
Если бы в LR лежало магическое значение которое не от чего не зависит, то его не надо было бы делать. Зависимость есть. А в других кортексах вариантов больше....

так что как не крути в LR сохраняется режим из которого мы попали в прерывание, а так как в этом режиме еще указан какой из стэков использовать для возвращения, то подмена LR может вообще либо все загадить либо вернуть нас не туда!

задача -> прерывание -> вложенное прерывание, если вернутся по коду с 9 или D на конце мы из вложенного прерывания выйдем в задачу, а не в прошлое прерывание, и будет ваще беда! кусок кода потеряется, и стэк раздуется, если так делать часто он ваще кончится...


Цитата
нет - стэк этой задачи не будет изолирован от стэка ядра.

в данном случая я имею ввиду что если основной метод переключения задач, это задание PSP на стэк задачи и выход из прерывания, то так можно делать только если начальный стэк задачи проинициализирован в состояние которое он принимает при заходе в прерывание. Самый простой способ инициализации - войти в прерывание, хотя наверное нереальный, и все таки придется это сделать ручками
Go to the top of the page
 
+Quote Post
1113
сообщение May 11 2014, 16:10
Сообщение #22


Знающий
****

Группа: Свой
Сообщений: 604
Регистрация: 24-02-06
Из: Москва
Пользователь №: 14 658



Цитата(Golikov A. @ May 11 2014, 19:03) *
Самый простой способ инициализации - войти в прерывание, хотя наверное нереальный, и все таки придется это сделать ручками
тогда шедулер должен знать и проверять, в первый или не в первый раз он переключает эту задачу. делать такие проверки 10 тыщ раз в секунду не разумно по сравнению с единовременной инициализацией стэка задачи десятком слов.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 11 2014, 16:50
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



вот и я о том же думаю...
но с другой стороны он все равно проверяет активна ли задача, придержана и так далее... , флаг инициализации может быть среди них...
какой-то контроль все равно должен быть
Go to the top of the page
 
+Quote Post
Omnicake
сообщение May 12 2014, 02:32
Сообщение #24


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 12-01-14
Из: Омск
Пользователь №: 80 002



Перепробовал вчера такие варианты:
1) Запись в LR или PC значения EXC_RETURN уводит в HardFault исключение, то есть он воспринимает это как просто переход в неадреуемую область.
2) Проверил, что пишется в стэк при простом выходе из прерывания (то есть в шедулере оставил просто команду BX LR), и скопировал записанные значения в стэк задачи. Результат тот же, значения он не подцепил. Хотя в стэк были записаны и PC регистры и LR и значение FFFFFFF9(EXC_RETURN).
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 12 2014, 04:47
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Запись в LR или PC значения EXC_RETURN уводит в HardFault исключение

а в стэке в этот момент было записано куда вернуться из прерывания? Вы находились в handler режиме?

Цитата
Проверил, что пишется в стэк при простом выходе из прерывания

пишется в стэк не при выходе, а при входе, при выходе из стэка читается куда выйти. А значение FFFFFFF9 проводит выход по стеку не задачи, а главному стэку. Надо было выходить по FFFFFFFD, при этом в LR ничего писать не надо, только в PC


надо попробовать
1. войти в прерывание,
2. в обработчике записать в маин стэк данные как будто-то вошли из какой-то известной функции
3. записать в PC значение FFFFFFF9


утверждаю что после этого попадете в эту функцию...
Go to the top of the page
 
+Quote Post
Omnicake
сообщение May 12 2014, 05:03
Сообщение #26


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 12-01-14
Из: Омск
Пользователь №: 80 002



Да, находился в Handler mode. Под "простым выходом из прерывания" я имел ввиду процесс входа в прерывание и выход на ту же функцию, откуда оно было вызвано, потому что при таком режиме все работало нормально. Сейчас нет возможности проверить ваш способ, вечером попробую. Спасибо за совет.
Go to the top of the page
 
+Quote Post
Omnicake
сообщение May 12 2014, 12:29
Сообщение #27


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 12-01-14
Из: Омск
Пользователь №: 80 002



Цитата
надо попробовать
1. войти в прерывание,
2. в обработчике записать в маин стэк данные как будто-то вошли из какой-то известной функции
3. записать в PC значение FFFFFFF9

Попробовал сделать такое после входа в обработчик
Код
        LDR    r0,    =TaskPointer
    LDR     r0, [r0]
    LDR     r0, [r0]
    MOV     r1,  r0
    LDR sp, [r1,#24];Загрузил стэк программы
    MOVW R2,#0x00d0; в котором по адресу 0x200000d0
    MOVT R2,#0x2000; положил число 0xFFFFFFF9
    LDR pc, [r2]; Загрузил его в PC

И улетел на HardFault. Что я не так сделал?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 12 2014, 13:54
Сообщение #28


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Omnicake @ May 12 2014, 15:29) *
И улетел на HardFault. Что я не так сделал?
Какой стек используется, MSP или PSP? Есть подозрение, что используется PSP, тогда как в момент возврата по вашему магическому числу сотояние восстанавливается из PSP.

Прочитал ветку (каюсь, по диагонали). Не могу понять - зачем вы чешете правое ухо левой ногой? После входа в обработчик у вас в LR уже лежит нужное для выхода магическое число. Хотите подменить адрес возврата - меняйте его в сохраненном на стеке в момент входа в обработчик контексте. Потом стандартный возврат из любой функции - bx LR. Все. Если вам нужно сходить из обработчика куда-то еще - делайте push lr, ходите как обычно и в конце делайте pop pc. Остальной механизм при этом сработает сам, без всяких сохранений магического числа по магическому адресу 0x200000d0. Кстати, а по этому адресу действительно лежит нужное число? Не может там случайно оказаться мусор?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Omnicake
сообщение May 12 2014, 14:16
Сообщение #29


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 12-01-14
Из: Омск
Пользователь №: 80 002



Используется MSP, число там лежит точно, так как в симуляторе я могу свободно просматривать память и пошагово следить за программой. После входа в прерывание у меня лежит LR возврата на main, а мне нужно из прерывания уйти в другую задачу, я и меняю LR внутри обработчика но по выходу на задачу процессор остается в обработке прерывания.
Go to the top of the page
 
+Quote Post
adnega
сообщение May 12 2014, 15:44
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(Omnicake @ May 12 2014, 18:16) *
Используется MSP, число там лежит точно, так как в симуляторе я могу свободно просматривать память и пошагово следить за программой. После входа в прерывание у меня лежит LR возврата на main, а мне нужно из прерывания уйти в другую задачу, я и меняю LR внутри обработчика но по выходу на задачу процессор остается в обработке прерывания.

В соседней Вашей ветке про переключение задач Вам подробно ответили. Что-то еще не ясно?
Вероятно, что нет точного понимания.
Регистр PC не так прост, как в других архитектурах. Используется для переходов, но не только для них.
Как Вы узнаете, что прерывание нужно завершить, если нет аналога reti?
Если обработчик нужно закончить и передать управление в другое место, то меняйте данные в стековом кадре -
после записи магического EXC_RETURN в PC будет произведен выход и PC перезапишется восстановленным со стека (измененным) значением.
Но если там находится не стековый кадр main, а стековый кадр вложенного прерывания (main->ISRx->Systick), то поимем при таком подходе,
мягко говоря, не то что ожидалось: вместо подмены адреса возврата в main, переключимся на main, не закончив ISRx.
Использование PendSV с низшим приоритетом очень помогает (упрощает жизнь).
Какую задачу Вы решаете?
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 21:20
Рейтинг@Mail.ru


Страница сгенерированна за 0.01476 секунд с 7
ELECTRONIX ©2004-2016