Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: freertos и его enter_critical
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > FreeRTOS
cebotor
Работал все время с ucos - клоном embos.
Решил протестировать freertos.

Сразу возник вопрос , как реализованы критические секции ?
в embos например

#define OS_EnterRegion() {OS_RegionCnt++; }

то есть при входе в участок увеличивается счетчик , и если он не нулевой ,
то не происходит переключение между задачами.

во фриртосе нашел

#define portENTER_CRITICAL() vPortEnterCritical()

void vPortEnterCritical( void )
{
/* Disable interrupts first! */
__disable_interrupt();

/* Now interrupts are disabled ulCriticalNesting can be accessed
directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
}

я правильно все понял ? прерывания запрещаються вообще? надо вызывать вложенные приложения в ручную ? не будут работать не только другие задачи , но и банальные обработчики таймеров и мастеров типа СПИ ?
zltigo
Цитата(cebotor @ May 4 2007, 10:40) *
я правильно все понял ? прерывания запрещаються вообще?

На то она и железобетонная критическая секция. Что не мешает делать Вам что-то свое. У меня, например FIQ не запрещаются.
Цитата
надо вызывать вложенные приложения в ручную ?

Ерунда какая-то - какие вложенные? Чего в ручную? Причем здесь критическая секция?
Цитата
не будут работать не только другие задачи , но и банальные обработчики таймеров и мастеров типа СПИ ?

Не запускать другие задачи это не "критческая секция" - это "остановить шедулер",
void vTaskSuspendAll() (в новых версиях переименовано в vTaskSuspendScheduler()), что естественно осуществляется без запретов прерываний. Причем во FreeRTOS при xTaskResumeScheduler() для простоявших задач восстановление делается максимально аккуратно.
cebotor
Цитата(zltigo @ May 4 2007, 11:53) *
На то она и железобетонная критическая секция. Что не мешает делать Вам что-то свое. У меня, например FIQ не запрещаются.

Ерунда какая-то - какие вложенные? Чего в ручную? Причем здесь критическая секция?

Не запускать другие задачи это не "критческая секция" - это "остановить шедулер",
void vTaskSuspendAll() (в новых версиях переименовано в vTaskSuspendScheduler()), что естественно осуществляется без запретов прерываний. Причем во FreeRTOS при xTaskResumeScheduler() для простоявших задач восстановление делается максимально аккуратно.

ну вобщем понятно . в ембосе под критической секцией понимается непереключение задач(как во фриртосе суспенд щедулер ) , а для "железобетона "есть
__disable_interrupts();

а во фриртосе , наоборот - критическая секция это запрет прерывания, а для непереключения стоп щедулера.

что более нужно неясно. я склюняюсь к тому что вариант ембоса - ибо когда мне нужен "железобетон"
я просто запрещу перрывания , а когда у меня критический сектор - я просто хочу , чтобы у меня приложения например не вызывали перекрестное обращение к какой нибудь общей переменной.
zltigo
Цитата(cebotor @ May 4 2007, 11:16) *
что более нужно неясно. я склюняюсь к тому что вариант ембоса - ибо когда мне нужен "железобетон"
я просто запрещу перрывания

1. "Просто" запретить/разрешить недостаточно для общего случая вложенных критических секций.
2. Описанный Вами вариант c OS_RegionCnt++ это и есть останов шедулера, только примитивный.
cebotor
Цитата(zltigo @ May 4 2007, 12:30) *
1. "Просто" запретить/разрешить недостаточно для общего случая вложенных критических секций.
2. Описанный Вами вариант c OS_RegionCnt++ это и есть останов шедулера, только примитивный.


1. спасибо большое все понял ! а не могли бы вы отосллать меня куда нить где можно почитать про то что такое нестед критикал в теории ? а то я ника не могу представить , как из одной критической ситуации можно "вложиться в другую", если прерывания и переключения задач запрещены .

2. да и ето я тоже уже сообразил , посмотрел как во фриртосе реализован суспенд_щедулер -- понравилось , хотя глазу приятнее OS_RegionCnt++ (простите за упрямство smile.gif
AlexBoy
Цитата(cebotor @ May 4 2007, 11:16) *
что более нужно неясно. я склюняюсь к тому что вариант ембоса - ибо когда мне нужен "железобетон"
я просто запрещу перрывания , а когда у меня критический сектор - я просто хочу , чтобы у меня приложения например не вызывали перекрестное обращение к какой нибудь общей переменной.

Вобщето для доступа к общим ресурсам есть более подходящие способы чем остановка шедулера, в UCOS например семафоры и мютексы, наверно и во freertos такое есть. Другие задачи при этом не останавливаются. Я использую для вызова malloc и доступа к sd карте.
zltigo
Цитата(cebotor @ May 4 2007, 11:42) *
а не могли бы вы отосллать меня куда нить где можно почитать про то что такое нестед критикал в теории ? а то я ника не могу представить , как из одной критической ситуации можно "вложиться в другую", если прерывания и переключения задач запрещены .

Да все очень просто - при тупом disable после него вызываем, подпрограмму которая тоже хочет себе тоже "просто" критическую секцию организовать disable .... enable и ... после enable "простая" критическая секция начатая в головной программе трагически закончилась sad.gif
Abo
Цитата(zltigo @ May 4 2007, 16:42) *
Да все очень просто - при тупом disable после него вызываем, подпрограмму которая тоже хочет себе тоже "просто" критическую секцию организовать disable .... enable и ... после enable "простая" критическая секция начатая в головной программе трагически закончилась sad.gif


Чтобы трагически не закончилась можно делать disable ... restore.
v_shamaev
Цитата(Abo @ May 4 2007, 16:13) *
Чтобы трагически не закончилась можно делать disable ... restore.

И вводить стек неизвестной длины? Со счетчиком проще. Можно, конечно, в статической переменной при входе в функцию запоминать состояние, но это неоправданный расход ресурсов, и централизация управления нарушается, к тому же операция должна быть атомарной. Хотя я лично себя с таким механизмом почему-то увереннее чувствую.
zltigo
Цитата(Abo @ May 4 2007, 15:13) *
Чтобы трагически не закончилась можно делать disable ... restore.

Это если restore()
1. вообще штатно реализовано;
2. реализовано, так, что не вносит дополнительных ограничений на использование.
Abo
Цитата(zltigo @ May 4 2007, 17:31) *
Это если restore()
1. вообще штатно реализовано;
2. реализовано, так, что не вносит дополнительных ограничений на использование.



Вот пример из CW help

Код
int s;

  // Disable IRQ and FIQ interrupts
  s = libarm_disable_irq_fiq();

  ...

  // Restore IRQ and FIQ interrupts
  libarm_restore_irq_fiq(s);

Вот реализация функций:
libarm_disable_irq_fiq:
       E10F0000   mrs r0, cpsr
       E3802080   orr r2, r0, #0x00000080
       E121F002   msr cpsr_c r2
       E38020C0   orr r2, r0, #0x000000c0
       E121F002   msr cpsr_c r2
       E12FFF1E   bx lr
libarm_restore_irq_fiq:
       E1A00000   mov r0, r0
       E121F000   msr cpsr_c r0
       E12FFF1E   bx lr



А использование одной локальной переменной не есть на мой взгляд транжирством стека.
И никаких дополнительных ограничений на использование
zltigo
Цитата(Abo @ May 5 2007, 10:54) *
А использование одной локальной переменной не есть на мой взгляд транжирством стека.
И никаких дополнительных ограничений на использование

Ограничение есть - disable() в одной функции а restore() в другой а то и в другой задаче.
Это ограничение.
Abo
Цитата(zltigo @ May 5 2007, 12:35) *
Ограничение есть - disable() в одной функции а restore() в другой а то и в другой задаче.
Это ограничение.


Это как это - запрещать прерывания в одной задаче и разрешать в другой - я правильно понял?
Если так - то не примите за хамство, но такой стиль программирования, на мой взгляд - просто извращение какое то.
Запрещать прерывания (входить в критическую секцию) я всегда предпочитал лишь для коротких, детерминированных участков кода. Например для LPC это код сброса WDT, который действительно нельзя прервать.

А вообще, по большому счету - на вкус и цвет ... , лишь бы в конце концов работало как требуеся.
DASM
Что-то ничего не понял. Ну хорошо, запретили мы прерывания, потом по ходу осоводили какой-нить event который тут же сделал более приоритетную задачу готовой и тут же перешли в её код. Вот и фсе. И нарушится вся логика, так как в той задаче куда перешли шедулер уже не выручит по таймеру в частности. ИМХО - запрет прерываний - вообще не должен быть доступен на уровне написания приложения.
zltigo
Цитата(Abo @ May 5 2007, 12:37) *
Это как это - запрещать прерывания в одной задаче и разрешать в другой - я правильно понял?

Да.
Цитата
Если так - то не примите за хамство, но такой стиль программирования, на мой взгляд - просто извращение какое то.

Обсуждались ограничения применения. Это ограничение. Стоит так бездумно делать? Нет конечно. Можно без такого обойитсь? Наверняка да. Но случаи бывают разными, особено при обработке нештатных ситуаций.
Что касается конкретики - у меня, например, система собирается с двумя вариантами в зависимости от необходимости - c сохранением CPSR в локальной переменной и со счетчиком запретов прерывания. И плюс два подварианта - с запретом FIQ и без.
Цитата
Запрещать прерывания (входить в критическую секцию) я всегда предпочитал лишь для коротких, детерминированных участков кода.

Это явные запрещения прерываний, которые Вы явно контролируете, но запрещения прерываний неявно используются и для внутрисистемных целей.
Цитата
А вообще, по большому счету - на вкус и цвет ... , лишь бы в конце концов работало как требуеся.

Только на "в конце концов" крайне желательно получить с минимальными затратами ресурсов, с минимальным количеством рекламаций и максимально сопровождаемый (и что греха таить и заплаточным способом тоже) в будующем.

Цитата(DASM @ May 5 2007, 12:50) *
ИМХО - запрет прерываний - вообще не должен быть доступен на уровне написания приложения.

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