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

 
 
 
Reply to this topicStart new topic
> TN-kernel: поддержка critical section для CM3
megajohn
сообщение Jul 25 2012, 11:33
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143



собтсвенно сабж. Интересует правильная реализация.

Кстати, сообщество не созрело создать подфорум по этой RTOS ?!


--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
Go to the top of the page
 
+Quote Post
VslavX
сообщение Jul 25 2012, 14:46
Сообщение #2


embarrassed systems engineer
*****

Группа: Свой
Сообщений: 1 083
Регистрация: 24-10-05
Из: Осокорки
Пользователь №: 10 038



Цитата(megajohn @ Jul 25 2012, 14:33) *
собтсвенно сабж. Интересует правильная реализация.

Что именно понимается под critical sections?
tn_disable_interrupt() и tn_enable_interrupt() недостаточно?
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jul 25 2012, 15:18
Сообщение #3


Гуру
******

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



Цитата(VslavX @ Jul 25 2012, 17:46) *
Что именно понимается под critical sections?
tn_disable_interrupt() и tn_enable_interrupt() недостаточно?

Странная секция какая-то: если она вложенная, то как тогда?

Правильней так (пример от IAR-а)
Код
oldState = __save_interrupt();
__disable_interrupt();
/* Critical section goes here */


__restore_interrupt(oldState);
Go to the top of the page
 
+Quote Post
VslavX
сообщение Jul 25 2012, 16:35
Сообщение #4


embarrassed systems engineer
*****

Группа: Свой
Сообщений: 1 083
Регистрация: 24-10-05
Из: Осокорки
Пользователь №: 10 038



Цитата(_Артём_ @ Jul 25 2012, 18:18) *
Правильней так (пример от IAR-а)

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

Go to the top of the page
 
+Quote Post
msalov
сообщение Jul 26 2012, 05:41
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Код
TN_INTSAVE_DATA
tn_disable_interrupt();
...
{
  // Вложенная
  TN_INTSAVE_DATA
  tn_disable_interrupt();
  ...
  tn_enable_interrupt();
}
...
tn_enable_interrupt();

Всё потому что
Код
#define  TN_INTSAVE_DATA_INT     unsigned int tn_save_status_reg = 0;
#define  TN_INTSAVE_DATA         unsigned int tn_save_status_reg = 0;
#define  tn_disable_interrupt()  tn_save_status_reg = tn_cpu_save_sr()
#define  tn_enable_interrupt()   tn_cpu_restore_sr(tn_save_status_reg)

#define  tn_idisable_interrupt() tn_save_status_reg = tn_icpu_save_sr()
#define  tn_ienable_interrupt()  tn_icpu_restore_sr(tn_save_status_reg)

tn_cpu_save_sr() - запрещает прерывания и возвращает статус разрешения прерываний до запрещения
tn_cpu_restore_sr() - разрешает прерывания если параметр != 0 и запрещает, если == 0
Go to the top of the page
 
+Quote Post
megajohn
сообщение Jul 26 2012, 06:49
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143



чой та не понимаю.
Зачем отключать вообще прерывания ? Нужно всего лишь дать знать шедуллеру чтобы покамест не переключал задачи. А блокировать ВСЕ - это уже блокировка и на уровне драйверов, которые входящие данные складывают в циклический буфер.

или мои представления о РТОС ошибочны ?!


--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
Go to the top of the page
 
+Quote Post
msalov
сообщение Jul 26 2012, 07:36
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(megajohn @ Jul 26 2012, 09:49) *
чой та не понимаю.
Зачем отключать вообще прерывания ? Нужно всего лишь дать знать шедуллеру чтобы покамест не переключал задачи. А блокировать ВСЕ - это уже блокировка и на уровне драйверов, которые входящие данные складывают в циклический буфер.

или мои представления о РТОС ошибочны ?!


Так как переключение контекста происходит в прерывании с наименьшим возможным приоритетом (PendSV с приоритетом 0xFF), то можно не запрещать прерывания, а поднять нижнюю границу обслуживаемых прерываний. Тем самым оставив прерывания включёнными, но запретив переключение контекста. Как это делается для Cortex-M3, увы не скажу.
Будет что-то типа:
Код
int tn_disable_context_switch(void)
{
  int state = get_priority_level();
  if (state == 0xFF) // all interrupt are accepted
  {
    set_priority_level(0xFF - 1); // accept all, except PendSV
  }
  // else - do nothing, since PendSV is not acceptable already
  return state;
}

void tn_enable_context_switch(int state)
{
  set_priority_level(state);
}

На счёт представлений ничего не скажу sad.gif Сам бы хотел получить ответ на этот вопрос. По крайней мере внутри системных вызовов ОСи используется именно запрещение прерываний, для исключения проблем с реентерабельностью, судя по всему.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jul 26 2012, 08:09
Сообщение #8


Гуру
******

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



Цитата(gotty @ Jul 26 2012, 10:36) *
По крайней мере внутри системных вызовов ОСи используется именно запрещение прерываний, для исключения проблем с реентерабельностью, судя по всему.

А реентерабельность тут причём?
Go to the top of the page
 
+Quote Post
msalov
сообщение Jul 26 2012, 08:13
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(_Артём_ @ Jul 26 2012, 11:09) *
А реентерабельность тут причём?

Реентерабельность системных вызовов конечно. Ведь они могут вызываться как из задач, так и из прерываний, и работа в них ведётся с одними и теми же внутренними структурами ОС.
Go to the top of the page
 
+Quote Post
VslavX
сообщение Jul 26 2012, 08:48
Сообщение #10


embarrassed systems engineer
*****

Группа: Свой
Сообщений: 1 083
Регистрация: 24-10-05
Из: Осокорки
Пользователь №: 10 038



Цитата(gotty @ Jul 26 2012, 10:36) *
Так как переключение контекста происходит в прерывании с наименьшим возможным приоритетом (PendSV с приоритетом 0xFF), то можно не запрещать прерывания, а поднять нижнюю границу обслуживаемых прерываний.

Дело в том что часто критическая секция именно организуется для защиты данных разделяемых с обработчиком прерываний - тут только запрет прерываний и поможет. Если данные в критической секции разделяются только между задачами - то лучше уже использовать синхрообъекты RTOS - мутексы, семафоры или события. Еще, иногда, если код в критической секции очень быстрый и короткий, то из соображений быстродействия вполне можно критическую секцию организовать на tn_interrupt_xxxx(). Пример (не самый удачный для Cortex с его ldrex/strex):
CODE

HAL_SYSTEM_CALL
DWORD
HAL_CALL_OPTION
hal_interlocked_inc(
PDWORD var)
{
DWORD lock, ret;
lock = hal_lock_interrupt();
ret = *var + 1;
*var = ret;
hal_unlock_interrupt(lock);
return ret;
}

Запрет переключения между задачами тоже можно реализовать независимо от порта - через tn_task_change_priority() (банально задрать приритет до максимального в системе), но оверхед обычно больше чем на мутексе, например. Не говоря уже о interrupt_xxxx().
Go to the top of the page
 
+Quote Post

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

 


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


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