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

|
Цитата(zltigo @ Apr 19 2006, 21:27)  Цитата(sensor_ua @ Apr 19 2006, 13:14)  А вот FreeRTOS после анализа этих самых критических кусочков пришлось забраковать.
??? Что такое жуткое вскрылось при анализе? Сразу оговорюсь, что сам не программист, потому прошу сильно не пинать. В TNKernel наблюдаю int tn_cpu_save_sr(void); void tn_cpu_restore_sr(int sr); #define tn_disable_interrupt() tn_save_status_reg = tn_cpu_save_sr() #define tn_enable_interrupt() tn_cpu_restore_sr(tn_save_status_reg) Во FreeRTOS /* The code generated by the Keil compiler does not maintain separate stack and frame pointers. The portENTER_CRITICAL macro cannot therefore use the stack as per other ports. Instead a variable is used to keep track of the critical section nesting. This necessitates the use of a function in place of the macro. */ void vPortEnterCritical( void ){...} void vPortExitCritical( void ){...} В uCOS-II, IMHO, подобное называлось уровнем (паранойи?  )) то ли 1, то ли 2, а теперь прописано, что пользуют уровень 3 - практически то же по асму, что и в предпоследней TNKernel (в последней заменили (в tn_cpu_save_sr() и tn_cpu_restore_sr(..)) bx, lr на mov pc,lr Мне решение в TNKernel и uCOS-II кажется обоснованным и разумным.
--------------------
aka Vit
|
|
|
|
|
Apr 20 2006, 10:15
|
Участник

Группа: Участник
Сообщений: 30
Регистрация: 17-01-05
Пользователь №: 1 995

|
Цитата(dxp @ Apr 20 2006, 10:30)  Цитата(alogvinov @ Apr 20 2006, 12:26)  Под программым таймером подразумевается структура, одним из полей которой является указатель на функцию. Эта функция вызывается через заданное пользователем число квантов ОС.
И на каком уровне эта функция реально вызывается - на уровне прерываний или на уровне задач? Если на уровне задач, то в контексте какой задачи она выполняется (в чьем стеке работает)? Функция выполняется в контексте прерывания, со всеми вытекающими отсюда ограничениями.
|
|
|
|
|
Apr 20 2006, 16:44
|

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

|
Цитата(sensor_ua @ Apr 20 2006, 12:36)  В TNKernel наблюдаю
int tn_cpu_save_sr(void); void tn_cpu_restore_sr(int sr); #define tn_disable_interrupt() tn_save_status_reg = tn_cpu_save_sr() #define tn_enable_interrupt() tn_cpu_restore_sr(tn_save_status_reg)
Во FreeRTOS
void vPortEnterCritical( void ){...}
void vPortExitCritical( void ){...}
Мне решение в TNKernel и uCOS-II кажется обоснованным и разумным. Цитата В TNKernel и uCOS-II сохраняется регистр статуса и это видно по коду, а во FreeRTOS эти функции void. Может оно там тоже как-то сохраняется, но я не смог увидеть куда Самый странный критерий выбора операционной системы, какой я только встречал на данный момент. Или я чего-то не понял :-( В TNKernel много чего хорошего, но реализация ограждения критических секций более чем спорная. Для сохрания состояния используется персональная поименованная переменная и за этим необходимо следить глазами и руками. Не дай бог вам пару раз подряд вызвать tn_cpu_save_sr() с сохранением в одну и ту-же переменную. А макросами tn_disable_interrupt() и tn_enable_interrupt() вообще находясь в здравом уме и твердой памяти пользоваться нельзя, ибо при вложенном вызове их критической секции еще одной критической секции кирдык в виде запрещенных навсегда прерываний наступит незамедлительно. Несимметричное количество вызовов тоже черевано. Теперь о FreeRTOS: void vPortEnterCritical() void vPortExitCritical() Имеют исходники. Они просты, как лом, откомментированы, и так-же надежно работают. Код 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++; } void vPortExitCritical( void ) { if( ulCriticalNesting > portNO_CRITICAL_NESTING ) { /* Decrement the nesting count as we are leaving a critical section. */ ulCriticalNesting--;
/* If the nesting level has reached zero then interrupts should be re-enabled. */ if( ulCriticalNesting == portNO_CRITICAL_NESTING ) { __enable_interrupt(); } } } При входе прерывания безусловно запрещаются и наращивается обезличеный счетчик запретов. При выходе разрешаются если счетчик запретов равен 0. Никаких проблем с реализацией вложений. Хранения состояния не нужно, переменная для блокировок всего одна.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Apr 20 2006, 17:50
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Специально скачал последнюю FreeRTOS 4.0.1, а то рассматривал 3.2.4, а там то, что теперь прозрачно, было написано асмовыми вставками - мне такое было тяжело читать  Насчет Цитата Для сохрания состояния используется персональная поименованная переменная Ваши замечания мне пришлось учесть (немного раньше, чем сегодня  - макросы модифицировать открывающими/закрывающими фигурными скобками, побороться с "персональностью" переменной, соответственно ввести Цитата обезличеный счетчик запретов Параноидальные требования возникли от безысходности - пишу дрова (в широком смысле - зачатки ОСи тоже) для имеющихся программистов - ребята попались с большими амбициями, непредсказуемым стилем программирования и тяжелым наследием незнания железа (непочитания дейташитов) - я завидую белой завистью их пофигизму, но работу делать надо. Пришлось положить избыточность в 500% в ресурсы железа(может больше - меги128 без внешнего ОЗУ на частоте 3.68МГц хватало) и... А насчет Цитата просты, как лом, откомментированы, и так-же надежно работают ещё раз скажу - в uCOS-II такой вариант имелся как самый низкий уровень паранойи - он понятен, имеет свои плюсы, но от него постарались отказаться.
--------------------
aka Vit
|
|
|
|
|
Apr 20 2006, 18:54
|

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

|
Цитата(sensor_ua @ Apr 20 2006, 20:50)  самый низкий уровень паранойи - он понятен, имеет свои плюсы, но от него постарались отказаться. Ну а причины отказа? Я теряюсь в догадках! Цитата Специально скачал последнюю FreeRTOS 4.0.1, а то рассматривал 3.2.4, а там то, что теперь прозрачно, было написано асмовыми вставками - мне такое было тяжело читать А аналогичный по назначению ASM код TNKernel 'легко'??? Да и где там ASM удалось углядеть? Там такой 'С' код испокон веку, я даже сам себе не поверил и заклянул в 3.2.3..... Все сказанное Вами по отношению к TNKernel прямо противоречит написанному вами-же: Цитата пишу дрова (в широком смысле - зачатки ОСи тоже) для имеющихся программистов - ребята попались с большими амбициями, непредсказуемым стилем программирования и тяжелым наследием незнания железа (непочитания дейташитов) - я завидую белой завистью их пофигизму, но работу делать надо. Я бы понял, если Вы заговорили-бы об некоторой времени в асмописаных обрамителях критических секций и чем-то подобном. Но то, что написано НЕ ВЯЖЕТСЯ с АККУРАТНО написанной, но более НЕЖНОЙ в использовании, да и менее обкатанной NTKernel. Практически по тем-же причинам (постороние писатели прикладных программ произвольной квалификации) мною был сделан прямо противоположный вывод.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Apr 20 2006, 19:04
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата(zltigo @ Apr 20 2006, 21:54)  Цитата(sensor_ua @ Apr 20 2006, 20:50)  самый низкий уровень паранойи - он понятен, имеет свои плюсы, но от него постарались отказаться.
Ну а причины отказа? Я теряюсь в догадках! Вот выдранное из os_cpu.h /* ******************************************************************************** ************************* * ARM * * Method #1: Disable/Enable interrupts using simple instructions. After critical section, interrupts * will be enabled even if they were disabled before entering the critical section. * NOT IMPLEMENTED * * Method #2: Disable/Enable interrupts by preserving the state of interrupts. In other words, if * interrupts were disabled before entering the critical section, they will be disabled when * leaving the critical section. * NOT IMPLEMENTED * * Method #3: Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you * would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then * disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II's functions that need to * disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr' * into the CPU's status register. ******************************************************************************** ************************* */ Цитата Специально скачал последнюю FreeRTOS 4.0.1, а то рассматривал 3.2.4, а там то, что теперь прозрачно, было написано асмовыми вставками - мне такое было тяжело читать А аналогичный по назначению ASM код TNKernel 'легко'??? Да, без переводчика и без проблем. Все сказанное Вами по отношению к TNKernel прямо противоречит написанному вами-же: Цитата пишу дрова (в широком смысле - зачатки ОСи тоже) для имеющихся программистов - ребята попались с большими амбициями, непредсказуемым стилем программирования и тяжелым наследием незнания железа (непочитания дейташитов) - я завидую белой завистью их пофигизму, но работу делать надо. Я бы понял, если Вы заговорили-бы об некоторой времени в асмописаных обрамителях критических секций и чем-то подобном. Но то, что написано НЕ ВЯЖЕТСЯ с АККУРАТНО написанной, но более НЕЖНОЙ в использовании, да и менее обкатанной NTKernel. Практически по тем-же причинам (постороние писатели прикладных программ произвольной квалификации) мною был сделан прямо противоположный вывод. Если насчёт TNKernel применить вааще, то задача не применить ОС, а именно не дать этого увидеть  )) товаришчам
--------------------
aka Vit
|
|
|
|
|
Apr 20 2006, 20:12
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата(zltigo @ Apr 20 2006, 22:28)  Цитата(sensor_ua @ Apr 20 2006, 22:04)  Ну а причины отказа? Я теряюсь в догадках!
Вот выдранное из os_cpu.h /* ..... */
Если о 'параное', но 'наивысший уровень' в TNKernel реализован сложнее и ненадежнее, нежели в той-же FreeRTOS. Вот такие дела. Простое запрещение прерываний вообще никому не запрещено пременять с умом, естественно. Насчет "сложнее и ненадежнее", то интересны аргументы. Если только "персональность" переменной для хранения статуса, то уже обсуждали. А насчет "Простое запрещение прерываний" хотелось бы отклониться в сторону - например, вспомнить spurious interrupt - AN10414 от Philips - ИМХО, это вообще сложный вопрос, и его действительно нужно решать "с умом, естественно".
--------------------
aka Vit
|
|
|
|
|
Apr 20 2006, 20:51
|

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

|
Цитата(sensor_ua @ Apr 20 2006, 23:12)  Насчет "сложнее и ненадежнее", то интересны аргументы. Если только "персональность" переменной для хранения статуса, то уже обсуждали. Еще раз повторить? 1. Сложнее - вместо простейшей обертки над стандартной де-факто библиотечной функции гарантированно работающей на любом процессоре. Писанная на асме чисто армовсая, да еще с заточкой под ARM Mode 2. Ненадежнее - легко ошибиться (особенно не зная потрохов и соответствено границ применимости) при использовании вложеных критических секций. Про macros писал - ну просто подстава чистейшей воды. Практически использование недалеко ушло от аккуратного использования пресловутого запрещения прерывания. Цитата А насчет "Простое запрещение прерываний" хотелось бы отклониться в сторону А ненадо отклоняться, ибо все равно оно имеет место быть. Это TNKernel: Код tn_cpu_save_sr:
mrs r0,CPSR orr r1,r0,#NOINT msr CPSR_c,r1 ;-- Atmel add-on mrs r1,CPSR ;-- Check CPSR for correct contents and r1,r1,#NOINT cmp r1,#NOINT bne tn_cpu_save_sr ;-- Not disabled - loop to try again ;--------
bx lr Это кусок IARовской библиотеки: Код cfi_ARM_BLOCK_start disableInterrupt_a CODE32 ??DiI_a mrs r12,CPSR orr r12,r12,#0xC0 msr CPSR_c,r12
mrs r12,CPSR ands r12,r12,#+0xC0 beq ??DiI_a
bx lr
cfi_ARM_BLOCK_end disableInterrupt_a Как Вам разница?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Apr 21 2006, 05:42
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(zltigo @ Apr 20 2006, 23:44)  Теперь о FreeRTOS: void vPortEnterCritical() void vPortExitCritical() Имеют исходники. Они просты, как лом, откомментированы, и так-же надежно работают. Код void vPortEnterCritical( void ) { /* Disable interrupts first! */
[...skipped...]
} } При входе прерывания безусловно запрещаются и наращивается обезличеный счетчик запретов. При выходе разрешаются если счетчик запретов равен 0. Никаких проблем с реализацией вложений. Хранения состояния не нужно, переменная для блокировок всего одна. А зачем такие навороты с подсчетом входов, анализом их при выходе и т.д.? Тут, насколько я понимаю: во-первых, прилично кода - накладные расходы, т.е. во-вторых, а если при первом вызове прерывания были по какой-то причине запрещены? Ведь при выходе они будут разрешены, что есть нарушение логики работы программы. Почему бы не использовать простую схему (псевдокод): Код CritEnter() { SaveInterruptState(); DisableInterrupt(); }
CritExit() { RestoreInterruptState(); } Все, ничего подсчитывать и анализировать не надо и логическая целостность программы не нарушается. Единственное требование - это необходимо жестко соблюдать комплементарность вызвовов этих функиций, но это надо делать при любом подходе. На С, к сожалению, это приходится делать руками, тут ничего не поделать. К счастью, на С++ этот момент поддается автоматизации, поэтому использование критических секций там тривиально и совершенно безопасно. :-)
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|