|
|
  |
Начало работы with scmRTOS, Несколько вопросиков |
|
|
|
Nov 11 2012, 13:26
|
Гуру
     
Группа: Свой
Сообщений: 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 не может быть использован со схемой прямого переключения контекста, если контроллер прерываний поддерживает вложенные приоритетные прерывания. Или я не прав?
|
|
|
|
|
Nov 11 2012, 13:41
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 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 вернул хозяину. Да и времени нет.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Nov 11 2012, 14:18
|
Гуру
     
Группа: Свой
Сообщений: 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 не поможет.
|
|
|
|
|
Nov 11 2012, 14:27
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(a9d @ Nov 11 2012, 16:19)  С запретом прерывания тоже не работает. Даже если запрет стоит самым первым, то перед ним все равно есть код где в программный стек сохраняются регистры. Думаю как это исправить. Смотря где запрет поставить... Как у CC25 выглядит таблица векторов? Если как у классических 51-ых (на каждый вектор кажеется выделялось 8 байт, в которые можно было вставить короткий обработчик или переход на длинную функцию). Если так, то можно первой же командой сделать запрет а потом вызывать обработчик. Всё это на асме придётся делать, наверное. PS. Нет ли в CC25 чего-нибудь наподобие xmeg-овского PMIC.STATUS? Может можно задействовать?
|
|
|
|
|
Nov 11 2012, 19:44
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 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
- "возврат"
- работа
Что так, что так -- при наложении прерываний может оказаться две перепланировки. Если бы в первом варианте второе прерывание пришло капельку позже, после инкремента счетчика вложенности, то перепланировка была бы одна. Но стек всё равно на два прерывания.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Nov 11 2012, 21:27
|
Гуру
     
Группа: Свой
Сообщений: 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)  а из этого прерывания "вернёмся", когда тот первый процесс будет самым приоритетным. То есть прерывание отложится на неизестное время и может вообще навсегда? А уровень так и будет заблокированным? Тагда это аварийная ситуация.
|
|
|
|
|
Nov 11 2012, 21:53
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 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-ыми играться.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|