|
|
  |
Требуется совет по выбору RTOS, программист я хреновый |
|
|
|
Apr 21 2006, 17:05
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата(zltigo @ Apr 21 2006, 19:32)  Цитата(sensor_ua @ Apr 21 2006, 19:23)  Я о варианте, когда в основной программе прерывания в какой-то прекрасный момент выключены не в критической секции. Как быть с разрешением в подпрограмме коллеги?
Мне казалось, что я ответил. У меня, тогда больше нет слов для обьяснения :-(. Попробуйте перечитать написанное в моем предыдущем посте. ИМХО, Вы приняли как за оскорбление мое мнение об критической секции в конкретной ОС - FreeRTOS и, рассказав о недостатках реализации в другой ОС- TNKernel (а точнее других, потому как ассемблерная часть в uCOS-II и TNKernel совпадает, вероятно и в других ОС) пытаетесь доказать, что сам механизм выбран неверно, а я от Вас пытаюсь получить четкие пояснения преимуществ/недостатков механизма, который в коммерческой ОС uCOS-II не применяется, хотя написано, что о нем хорошо знают. Я не понимаю как можно не проверив, было ли разрешено прерывание перед входом в критическую секцию, после окончания таковой его взводить. Вы же мне о Вашем мнении об разных ОС и макрообертках
--------------------
aka Vit
|
|
|
|
|
Apr 21 2006, 17:15
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата(yuri_t @ Apr 21 2006, 19:36)  To sensor_ua -------------------
Учитывая Ваш искренний интерес и желание все понять "до последнего винтика", отвечу:
Во первых,такое выражение просто не будет работать:
#define tn_disable_interrupt() { int tn_save_status_reg = tn_cpu_save_sr() #define tn_enable_interrupt() tn_cpu_restore_sr(tn_save_status_reg); }
Если следовать этим путем, то должно быть, наверное, так:
#define tn_disable_interrupt() { int tn_save_status_reg = tn_cpu_save_sr(); } #define tn_enable_interrupt() { tn_cpu_restore_sr(tn_save_status_reg); }
Теперь, если Вы вызовете это выражение внутри одной функции несколько раз, то согласно стандарта на язык С, локальная переменная int tn_save_status_reg будет видна только внутри блока, где она объявлена, следовательно, сколько раз вы вызвали tn_disable_interrupt(), столько раз она и будет создаваться. Далее, при вызове tn_enable_interrupt() компилятор не увидит tn_save_status_reg - блок, где было определение, уже завершился. (а если бы не завершился - то пришлось бы иметь несколько переменных с одним именем - что всех бы запутало(и компилятор, и программиста) и поэтому невозможно).
Поэтому давайте оставим это место в коде так, как оно существует сейчас.
И в заключение - при использовании ОС стоит работать на уровне семафоров, очередей и т.д. ОС для того и создается,чтобы избавить пользователя от всей этой возни с сохранением регистров, запрещением/разрешением преываний, etc.
C уважением, yuri_t Во-первых, работает  RVDMK2.5. Без ОС как таковой Макрос, открывающий блок и объявлящий/определяющий локальную переменную #define tn_disable_interrupt() { int tn_save_status_reg = tn_cpu_save_sr() ну и макрос, закрывающий блок #define tn_enable_interrupt() tn_cpu_restore_sr(tn_save_status_reg); } после него, естественно, о переменной, локальной для блока, забываем Насчет "в заключение" - спасибо за совет - подучусь, почитаю и уж тогда...
--------------------
aka Vit
|
|
|
|
|
Apr 21 2006, 18:07
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата(yuri_t @ Apr 21 2006, 20:33)  To sensor_ua -------------------
Ситуация, когда компилятор не полностью следует ANSI стандарту, хорошо известна. Например Visual C/C++ 6 (Microsoft) видит все локальные переменные, объявленные внутри блока и далее вниз по тексту, а Borland C/C++ 5 (CBuilder) - не видит.
IMHO, eсли Вы хотите писать переносимый код, то следует придерживаться ANSI стандарта. Простите, под рукой нет стандарта (где-то был только C99), но есть справочник Шилдта 4-е издание. В разделе "Переменные", подразделе "Локальные переменные" есть следующее: /-------- Из соображений удобства и в силу устоявшейся традиции все локальные переменные функции чаще всего объявляются в самом начале функции, сразу после открывающейся фигурной скобки. Однако можно объявить локальную переменную и внутри блока программы (блок функции - это частный случай блока программы. . . . В стандарте C89 все локальные переменные должны быть объявлены в начале блока, до любого выполнимого оператора. . . . Однако в C99 ... локальная переменная может быть объявлена в любом месте блока до ее первого использования. ---------/ Не встречал случая "невидимости" локальной переменной внутри блока и не знаком с такой возможностью.
--------------------
aka Vit
|
|
|
|
|
Apr 21 2006, 18:24
|
Частый гость
 
Группа: Свой
Сообщений: 163
Регистрация: 24-08-05
Пользователь №: 7 937

|
Когда я писал "Например Visual C/C++ 6 (Microsoft) видит все локальные переменные, объявленные внутри блока и далее вниз по тексту, а Borland C/C++ 5 (CBuilder) - не видит.", я имел ввиду, что Visual C/C++ 6 (Microsoft) видит все локальные переменные, объявленные внутри блока и далее вниз по тексту, когда блок уже завершился, что не соответствует ANSI стандарту, a Borland C/C++ 5 strictly supports ANSI (хотя ,заметим, и генерит код худшего качества). <pre> void my_func(void) { int i = 0; { int a1 =3; }
{ a1 = i+3; //-- Microsoft Visual C считает что a1 уже определена //-- а Borland C (and any another strictly ANSI compiler) будет ругаться //-- что a1 не описана. } } </pre>
By the way, TNKernel компилировалась на 8 различных компиляторах.
Дaвайте на этом и завершим разговор о макросах,компиляторах и прочей "ветвистой пшенице"(с).
C уважением, yuri_t
Сообщение отредактировал yuri_t - Apr 21 2006, 18:39
|
|
|
|
|
Apr 21 2006, 19:06
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(sensor_ua @ Apr 21 2006, 20:05)  Я не понимаю как можно не проверив, было ли разрешено прерывание перед входом в критическую секцию, после окончания таковой его взводить. Зачем нести очевидный бред - не понимаю :-( Цитата ИМХО, Вы приняли как за оскорбление мое мнение об критической секции в конкретной ОС - FreeRTOS и, рассказав о недостатках реализации в другой ОС- TNKernel (а точнее других, потому как ассемблерная часть в uCOS-II и TNKernel совпадает, вероятно и в других ОС) пытаетесь доказать, что сам механизм выбран неверно Оскорбление? :-) Похоже проблемы с пониманием письменного текста :-(. Нет, механизмы близки между собой настолько, что ни о какой непригодности FreeRTOSного речи идти не может. Что-же касается неимоверно косноязычно изложенной 'проблемы', то для ее решения вообще не надо пользоватся вышеупомянутыми механизмами вне зависимости от их реализации. Либо спуститься на уровень ниже и с умом оперировать элементарными запретами/разрешениями либо наоборот использовать исключительно высокоуровневые системные средства (к этому Вас призывают целых два Автора операционных систем не считая 'прочих').
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Apr 21 2006, 19:45
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата(zltigo @ Apr 21 2006, 22:06)  Цитата(sensor_ua @ Apr 21 2006, 20:05)  Я не понимаю как можно не проверив, было ли разрешено прерывание перед входом в критическую секцию, после окончания таковой его взводить.
Зачем нести очевидный бред - не понимаю :-( Цитата ИМХО, Вы приняли как за оскорбление мое мнение об критической секции в конкретной ОС - FreeRTOS и, рассказав о недостатках реализации в другой ОС- TNKernel (а точнее других, потому как ассемблерная часть в uCOS-II и TNKernel совпадает, вероятно и в других ОС) пытаетесь доказать, что сам механизм выбран неверно Оскорбление? :-) Похоже проблемы с пониманием письменного текста :-(. Нет, механизмы близки между собой настолько, что ни о какой непригодности FreeRTOSного речи идти не может. Что-же касается неимоверно косноязычно изложенной 'проблемы', то для ее решения вообще не надо пользоватся вышеупомянутыми механизмами вне зависимости от их реализации. Либо спуститься на уровень ниже и с умом оперировать элементарными запретами/разрешениями либо наоборот использовать исключительно высокоуровневые системные средства (к этому Вас призывают целых два Автора операционных систем не считая 'прочих'). Жаль, что Вы не хотите агументированного обсуждения. И грубите. IMNHO, сами ответить на очевидный свой промах в рассуждениях не желаете априори. Цитата(yuri_t @ Apr 21 2006, 21:24)  Когда я писал "Например Visual C/C++ 6 (Microsoft) видит все локальные переменные, объявленные внутри блока и далее вниз по тексту, а Borland C/C++ 5 (CBuilder) - не видит.", я имел ввиду, что Visual C/C++ 6 (Microsoft) видит все локальные переменные, объявленные внутри блока и далее вниз по тексту, когда блок уже завершился, что не соответствует ANSI стандарту, a Borland C/C++ 5 strictly supports ANSI (хотя ,заметим, и генерит код худшего качества). <pre> void my_func(void) { int i = 0; { int a1 =3; }
{ a1 = i+3; //-- Microsoft Visual C считает что a1 уже определена //-- а Borland C (and any another strictly ANSI compiler) будет ругаться //-- что a1 не описана. } } </pre>
By the way, TNKernel компилировалась на 8 различных компиляторах.
Дaвайте на этом и завершим разговор о макросах,компиляторах и прочей "ветвистой пшенице"(с).
C уважением, yuri_t Спасибо, разъяснили.
--------------------
aka Vit
|
|
|
|
|
Apr 21 2006, 21:00
|

учащийся
    
Группа: Свой
Сообщений: 1 065
Регистрация: 29-10-05
Из: города контрастов
Пользователь №: 10 249

|
А почему то никто и не обратился к Ляброссу и не сприсил у него , какого же фига он там наворотил? И все таки не смотря на эпитеты "меньшее зло" и "фуфло по сравнению с Билом Куцым" смею привести предложение из опуса многоуважаемого капиталиста : The question is thus, which one is better? Well, that all depends on what you are willing to sacrifice. If you don’t care in your application whether interrupts are enabled after calling a μC/OS-II service then, you should opt for the first method because of performance. If you want to preserve the interrupt disable status across μC/OS-II service cal
Первый вартиант нравится многим и он здесь присутствует :
#if OS_CRITICAL_METHOD == 1 #define OS_ENTER_CRITICAL() _CLI() /* Disable interrupts */ #define OS_EXIT_CRITICAL() _SEI() /* Enable interrupts */ #endif
А третий вариант ставший предметом помидоромеетания описывается так : #if OS_CRITICAL_METHOD == 3 #define OS_ENTER_CRITICAL() (cpu_sr = OS_CPU_SR_Save()) /* Disable interrupts */ #define OS_EXIT_CRITICAL() (OS_CPU_SR_Restore(cpu_sr)) /* Enable interrupts */ #endif
OS_CPU_SR_Save: IN R16,SREG ; Get current state of interrupts disable flag CLI ; Disable interrupts RET OS_CPU_SR_Restore: OUT SREG,R16 ; Restore SREG RET
То есть как пишет Ля или Лабросс третый вариант после OS_EXIT_CRITICAL() дает нам состояние прерывания (запрешенное или разрешенное) кототое было перед тем как вызывалась функция OS_ENTER_CRITICAL()
Теперь, почему я у себя в программе использую 3ий вариант . У меня есть код который увеличивает значение семафора работая из ISR. To есть мне нравится вызывать функцию OSSemPost() когда прерывания запрешены . Если посмотреть на код OSSemPost() то там можно увидеть:
INT8U OSSemPost (OS_EVENT *pevent) { .... OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0) { /* See if any task waiting for semaphore*/ (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM); /* Ready HPT waiting on event */ OS_EXIT_CRITICAL(); .... }
из вышеприведенного получается что при использовании варианта 1 , я получаю разрешение прерывания при выполнении функции OSSemPost() то есть находясь в ISR и могу получить вложенное прерывание , с которым у меня свидание лишь после выполнения ISR но не до него . Используя вариант 3 у меня с этим проблем не возникнет . Надеюсь сказанное как то снимает вину с вышеупомянутого товарисча белогвардейца Лябросса.
Надеюсь мое занудство вам не надоело
--------------------
Зачем лаять на караван , когда на него можно плюнуть?
|
|
|
|
|
Jun 19 2006, 11:47
|
Участник

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

|
А на AT91 никто примеров для ARTX не видел
Сообщение отредактировал e-tarasov - Jun 19 2006, 11:50
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|