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

 
 
18 страниц V  « < 11 12 13 14 15 > »   
Reply to this topicStart new topic
> Начало работы with scmRTOS, Несколько вопросиков
a9d
сообщение Nov 11 2012, 02:22
Сообщение #181


Местный
***

Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532



Прямая уже готова.

Там четыре уровня прерываний. И возможно с ними будут проблемы, но я пока что их не заметил.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Nov 11 2012, 13:26
Сообщение #182


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(a9d @ Nov 11 2012, 04:22) *
Там четыре уровня прерываний. И возможно с ними будут проблемы, но я пока что их не заметил.


Допустим в программе задействованны два прерывания с разными приоритетами Int0 и Int1. Приоритет Int0 выше приоритета Int1.
В некоторый момент времени возникло прерывание Int1, процессор начал его отрабатывать. И затем возникает прерывание Int0,
которое вытесняет прерывание Int1. В конце прерывания Int0 выполняется ISR_Exit и если прерывание Int1 не успело инкрементировать
Kernel.ISR_NestCount, то начнётся выполнятся переключение контекста.
Прерывание Int1 потеряется и возможно будет заблокировано.
То есть Kernel.ISR_NestCount не может быть использован со схемой прямого переключения контекста, если контроллер прерываний поддерживает вложенные приоритетные прерывания.

Или я не прав?
Go to the top of the page
 
+Quote Post
a9d
сообщение Nov 11 2012, 13:34
Сообщение #183


Местный
***

Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532



Так крит. секция на выходе из обработчика разрешит прерывания. Значит прерывание не будет вытеснено.


Понял проблему нужно посмотреть что будет.


Это можно решить только запретом прерывания перед ISR_Enter и разрешением после.

Сообщение отредактировал a9d - Nov 11 2012, 13:44
Go to the top of the page
 
+Quote Post
ReAl
сообщение Nov 11 2012, 13:41
Сообщение #184


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(_Артём_ @ Nov 11 2012, 15:26) *
То есть Kernel.ISR_NestCount не может быть использован со схемой прямого переключения контекста, если контроллер прерываний поддерживает вложенные приоритетные прерывания.

Или я не прав?
Обязанность сделать это правильно лежит на авторе порта. TISRW определяется в OS_Target.h.
Если вложенных прерываний нет, то
Код
        INLINE void ISR_Enter()
        {
            Kernel.ISR_NestCount++;
        }
Если есть, то
Код
        INLINE void ISR_Enter()
        {
            // STM8 can (atomically) increment byte in memory, but IAR 1.20 and 1.30 - can't :-(
            TCritSect cs;
            Kernel.ISR_NestCount++;
        }
В данном конкретном случае STM8 можно было бы даже со вложенными прерываниями обойтись без крит. секции, но конкретные версии компилятора не умели использовать атомарную инструкцию инкремента байта в памяти. Более свежий компилятор не проверял, да и STM8 Discovery вернул хозяину. Да и времени нет.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Nov 11 2012, 14:18
Сообщение #185


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(a9d @ Nov 11 2012, 15:34) *
Это можно решить только запретом прерывания перед ISR_Enter и разрешением после.


Если возможно запретить - зависит от архитектуры и компилятора.

Цитата(ReAl @ Nov 11 2012, 15:41) *
В данном конкретном случае STM8 можно было бы даже со вложенными прерываниями обойтись без крит. секции, но конкретные версии компилятора не умели использовать атомарную инструкцию инкремента байта в памяти.

Перед этим "атомарным инкрементом" нет никаких других инструкций (push-ей, jump-ов и др)?
Тогда можно обойтись без критической секции (или запрета прерываний). Иначе и TCritSect не поможет.
Go to the top of the page
 
+Quote Post
a9d
сообщение Nov 11 2012, 14:19
Сообщение #186


Местный
***

Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532



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

С запретом прерывания тоже не работает. Даже если запрет стоит самым первым, то перед ним все равно есть код где в программный стек сохраняются регистры. Думаю как это исправить.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Nov 11 2012, 14:27
Сообщение #187


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(a9d @ Nov 11 2012, 16:19) *
С запретом прерывания тоже не работает. Даже если запрет стоит самым первым, то перед ним все равно есть код где в программный стек сохраняются регистры. Думаю как это исправить.

Смотря где запрет поставить...
Как у CC25 выглядит таблица векторов?
Если как у классических 51-ых (на каждый вектор кажеется выделялось 8 байт, в которые можно было вставить короткий обработчик или переход на длинную функцию). Если так, то можно первой же командой сделать запрет а потом вызывать обработчик. Всё это на асме придётся делать, наверное.

PS. Нет ли в CC25 чего-нибудь наподобие xmeg-овского PMIC.STATUS? Может можно задействовать?
Go to the top of the page
 
+Quote Post
a9d
сообщение Nov 11 2012, 14:37
Сообщение #188


Местный
***

Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532



Я тоже подумал про таблицу векторов. Там 8байт дано. Сейчас думаю как перед джампами лочить глобальное прерывание.

Исправил таблицу векторов. Теперь проблемы с вытеснением точно нет.

Сообщение отредактировал a9d - Nov 11 2012, 19:38
Go to the top of the page
 
+Quote Post
ReAl
сообщение Nov 11 2012, 19:44
Сообщение #189


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(a9d @ Nov 11 2012, 16:19) *
Вариант с крит секцией не подходит да и работать он не будет как задумывалось. Ведь сначала будет сохраняться состояние и в этот момент может произойти вытеснение.
Речь идёт об TISRW ?
Самое худшее, что произойдёт, так это будет несколько большее использование стека. Но оно при вложенных прерываниях и так бывает.
Ну ещё дважды вызовется перепланировщик. Так он и так дважды вызовется, если во время отработки какого-то прерывания в очередь встанет следующее.

Пусть прерывания разрешены
  • работает какой-то процесс
  • прерывание
  • push-push-push
  • начало ISR_Enter. Тут может быть сохранение состояния прерываний от TCritSect, но ещё не запретили, инкрементировать вложенность не успели
    • Хопа! пошло другое прерывание
    • push-push
    • ISR_Enter - инкремент счётчика вложенности 0->1
    • обработка прерывания
    • ISR_Exit - декремент счётчика, 1->0, перепланировка, тут уже другие стек и PC, мы уже не из этого прерывания "возвращаемся". Может вообще не из прерывания, а из sleep() или event.wait(), а из этого прерывания "вернёмся", когда тот первый процесс будет самым приоритетным.
    • pop-pop-pop-pop
    • возврат
  • продолжение прерванного ISR_Enter - инкремент счётчика вложенности 0->1
  • обработка прерывания
  • ISR_Exit - декремент счётчика, 1->0, перепланировка
  • pop-pop
  • возврат
  • работа какого-то другого процесса

Пусть прерывания запрещены
  • работает какой-то процесс
  • прерывание
  • push-push-push
  • ISR_Enter - инкремент счётчика вложенности 0->1
  • обработка прерывания
  • ISR_Exit - декремент счётчика, 1->0, перепланировка
  • pop-pop
  • где-то тут перед концом возврата всё равно разрешение прерываний
  • пошло второе, ранее отложенное прерывание
  • push-push
  • ISR_Enter - инкремент счётчика вложенности 0->1
  • обработка прерывания
  • ISR_Exit - декремент счётчика, 1->0, перепланировка
  • pop-pop-pop-pop
  • "возврат"
  • работа


Что так, что так -- при наложении прерываний может оказаться две перепланировки.

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


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
a9d
сообщение Nov 11 2012, 20:19
Сообщение #190


Местный
***

Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532



Произойдет все немного по другому.

Вошли в первое прерывание.
До ISR_Enter вытеснили. Произошла перепланировка и мы влетаем повторно в первое прерывание. Ведь мы не успели сбросить флаг прерывания. И того у нас произошел ложный вызов прерывания. Это уже аварийная ситуация.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Nov 11 2012, 20:39
Сообщение #191


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Возможно я что-то забыл по 8051-ым.

Прервать текущее прерывание может только прерывание более высокого приоритета. Такого же -- не может.

reti в конце прерывания более высокого приоритета очищает тот уровень прерывания, данный не очищает.

После возврата в данное прерывание флаг-то не сброшен, но и уровень этого прерывания не очищен, так что повторного входа не произойдет. Иначе бы без никаких ОС сразу после ljmp из вектора мы бы заново входили в данное прерывание.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
a9d
сообщение Nov 11 2012, 21:03
Сообщение #192


Местный
***

Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532



Провел эксперимент.


Повысил прерывание WDT.
В системном таймере до обвертки вызываю прерывание WDT. Таки да повторного прерывания не происходит. Но контекст восстанавливается неправильно.

Если произвести вытеснение после обвертки. То контекст восстанавливается верно.

Сообщение отредактировал a9d - Nov 11 2012, 21:03
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Nov 11 2012, 21:27
Сообщение #193


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(ReAl @ Nov 11 2012, 21:44) *
Пусть прерывания разрешены
  • работает какой-то процесс
  • прерывание
  • push-push-push
  • начало ISR_Enter. Тут может быть сохранение состояния прерываний от TCritSect, но ещё не запретили, инкрементировать вложенность не успели
    • Хопа! пошло другое прерывание
    • push-push
    • ISR_Enter - инкремент счётчика вложенности 0->1
    • обработка прерывания
    • ISR_Exit - декремент счётчика, 1->0, перепланировка, тут уже другие стек и PC, мы уже не из этого прерывания "возвращаемся". Может вообще не из прерывания, а из sleep() или event.wait(), а из этого прерывания "вернёмся", когда тот первый процесс будет самым приоритетным.
    • pop-pop-pop-pop
    • возврат
  • продолжение прерванного ISR_Enter - инкремент счётчика вложенности 0->1
  • обработка прерывания
  • ISR_Exit - декремент счётчика, 1->0, перепланировка
  • pop-pop
  • возврат
  • работа какого-то другого процесса

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

Цитата(ReAl @ Nov 11 2012, 21:44) *
а из этого прерывания "вернёмся", когда тот первый процесс будет самым приоритетным.

То есть прерывание отложится на неизестное время и может вообще навсегда? А уровень так и будет заблокированным? Тагда это аварийная ситуация.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Nov 11 2012, 21:53
Сообщение #194


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(_Артём_ @ Nov 11 2012, 23:27) *
То есть прерывание отложится на неизестное время и может вообще навсегда? А уровень так и будет заблокированным? Тагда это аварийная ситуация.
Возврат из прерывания. Само-то прерывание отработали и нужные флаги сбросило.
А вот дальше...

У STM8 уровень (всё запрещено и три уровня разрешённости) записан в двух битах статусного регистра.

Для MCS51 с аппаратным отслеживанием по reti тут, похоже, таки бяка. Для рассмотрения и вложенные прерывания не нужны.
Разблокировать может только выход по reti из любого переключения контекста.
Но переключение может быть на возврат из some_event.wait() (и прерывание этот event и подняло), а там по дороге только ret.
Хотя почему только ret? Собственно переключатель-то на асме написан, там можно и reti написать.

Или делать переключение свободным отложенным прерыванием. Тогда из всех тех прерыываний вышли, все уровни очистили и только потом пойдёт прерывание переключения, кторое тоже за собой почистит.

Цитата(a9d @ Nov 11 2012, 23:03) *
В системном таймере до обвертки вызываю прерывание WDT. Таки да повторного прерывания не происходит. Но контекст восстанавливается неправильно.
Если произвести вытеснение после обвертки. То контекст восстанавливается верно.
Ну тут помочь не могу. Это нужно бы копаться с живой платой и компилятором, а у меня нет ни времени, ни желания ни ещё одну версию IAR в виртуалбоксе ставить, ни с 51-ыми играться.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
a9d
сообщение Nov 11 2012, 22:18
Сообщение #195


Местный
***

Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532



Определил причину. Из-за лишних переключений контекста происходило переполнение софтварного стека процесса Idle.

Go to the top of the page
 
+Quote Post

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

 


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


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