|
scmRTOS. Вопросы и ответы. |
|
|
|
Oct 1 2007, 09:35
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Из-за того, что мои предложения повисли в воздухе, решил открыть тему здесь. У меня вопросы по scmRTOS (извините, если они покажутся дилетанскими, я только начал мучить ОС). Раньше считал, что в uC OS лишняя заморочка, сейчас уже так не считаю. Общие вопросы для общего развития. 1. Зачем понадобилось иметь порядок приоритетов сверху вниз (насколько я понял из-за Blackfin только). a&-a немногим проигрывает. 2. Я хочу ограничиться #if scmRTOS_CONTEXT_SWITCH_SCHEME == 0, т.е. использовать всегда программное прерывание. Правильно ли это ? 3. Про OS::TChannel сказано, что этот объект оставлен для совместимости с версией 1. Рекомендуется пользоваться OS::channel. Мне же показалось, несмотря на универсальность OS::channel, применение его для байтовых каналов слишком расточительным. Я бы рассматривал бы как чистый FIFO буфер, как-то так #define TFIFO OS::Channel и изменил он нем представление как об атавизме. Или я чего-то не понял ? Платформозависимые вопросы. Я использую LPC2148 с IAR 5.10. Использовал порт Сергея Борщ с незначительными собственными доработками. 1. Интересует особенности использования векторных прерываний, кроме системного времени. На что следует обращать внимание. 2. Или их использовать нежелательно. PS. Не считайте мои вопросы наездом, scmRTOS - замечательная вещь.
|
|
|
|
|
 |
Ответов
|
Oct 1 2007, 11:42
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(alexander55 @ Oct 1 2007, 12:35)  Из-за того, что мои предложения повисли в воздухе, решил открыть тему здесь. А это всегда так. Чтобы что-то сдвинулось - надо сделать это самому Цитата(alexander55 @ Oct 1 2007, 12:35)  1. Зачем понадобилось иметь порядок приоритетов сверху вниз (насколько я понял из-за Blackfin только). a&-a немногим проигрывает. Не только для blackfin. Это для любого процессора, у которого есть встроенная инструкция clz - подсчета количества ведущийх нулей. Тогда нахождение самого приоритетного процесса, ожидающего выполнения сводится к одной этой команде. Такой же подход, если не изменяет память, реализован в порте для фуджиков. Ядро ARM имеет такую команду начиная с v5, поэтому для таких ARMов обратный порядок приоритетов будет давать выигрыш в объеме кода и, главное, времени переключения контекста. В текущем порте для ARM поддержка обратного порядка приоритетов является атавизмом, тянущемся со второй версии, когда для обратного порядка приоритетов pr0 был самым низкоприоритетным процессом. Тогда я реализовал поддержку обратного порядка для упрощения портирования между платформами. В третьей версии мы придумали простой способ объявлять pr0 самым высоким приоритетом вне зависимости от прямого/обратного порядка. Наверное нужно в следующем релизе поддержку обратного порядка из порта исключить, а задание scmRTOS_PRIORITY_ORDER перенести из пользовательских исходников в исходники порта, тем более что для количества процессов меньше 6 GetPrioTag() вычисляется таблично и разницы нет ни по времени, ни по объему, а для большего кол-ва процессов вычисление для прямого порядка компилируется в более эффективный код. Цитата(alexander55 @ Oct 1 2007, 12:35)  2. Я хочу ограничиться #if scmRTOS_CONTEXT_SWITCH_SCHEME == 0, т.е. использовать всегда программное прерывание. Правильно ли это ? Программное прерывание это #define scmRTOS_CONTEXT_SWITCH_SCHEME 1. Да, это более эффективный метод - весь контекст сохранятется/восстанавливается только когда необходимо перепланирование, а не в каждом прерывании - но, к сожалению, он не работает на кристаллах без контроллера прерываний (ADuC). В любом случае вы всегда можете его изменить, сравнить результаты и выбрать более подходящий. Про TCannel лучше ответит dxp. Цитата(alexander55 @ Oct 1 2007, 12:35)  Платформозависимые вопросы. 1. Интересует особенности использования векторных прерываний, кроме системного времени. На что следует обращать внимание. 1)Не забывать в прерываниях, которые используют сервисы ОС заводить в начале обработчика объект типа OS::TISRW 2) Не забывать, что некоторые сервисы (тот же channel) при отсутствии/избытке данных могут захотеть перевести текущий процесс в спячку, что для прерывания невозможно. 3) Пока не реализована поддержка вложенных прерываний. Я с трудом представляю, с какой стороны к этому подступиться. Если реализуете - не забудьте поделиться Других ограничений вроде как нет. P.S. и не стесняйтесь склонять мою фамилию
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 1 2007, 13:36
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(Сергей Борщ @ Oct 1 2007, 15:42)  В третьей версии мы придумали простой способ объявлять pr0 самым высоким приоритетом вне зависимости от прямого/обратного порядка. Наверное нужно в следующем релизе поддержку обратного порядка из порта исключить У меня нюх как у собаки. Цитата(Сергей Борщ @ Oct 1 2007, 15:42)  Программное прерывание это #define scmRTOS_CONTEXT_SWITCH_SCHEME 1. Я считал также, но в Вашем порте сделано наоборот, поэтому я так и решил. Но это не принципиально. Цитата(Сергей Борщ @ Oct 1 2007, 15:42)  Да, это более эффективный метод - весь контекст сохранятется/восстанавливается только когда необходимо перепланирование, а не в каждом прерывании - но, к сожалению, он не работает на кристаллах без контроллера прерываний (ADuC). В любом случае вы всегда можете его изменить, сравнить результаты и выбрать более подходящий. Это соответствует моим представлениям. Цитата(Сергей Борщ @ Oct 1 2007, 15:42)  1)Не забывать в прерываниях, которые используют сервисы ОС заводить в начале обработчика объект типа OS::TISRW Понял, также как с системным таймером. Цитата(Сергей Борщ @ Oct 1 2007, 15:42)  2) Не забывать, что некоторые сервисы (тот же channel) при отсутствии/избытке данных могут захотеть перевести текущий процесс в спячку, что для прерывания невозможно. Хочется поподробнее осветить этот момент. Цитата(Сергей Борщ @ Oct 1 2007, 15:42)  3) Пока не реализована поддержка вложенных прерываний. Я с трудом представляю, с какой стороны к этому подступиться. Если реализуете - не забудьте поделиться Других ограничений вроде как нет. Насколько я знаю по Keil, вложенные прерывания реализуются через макросы при входе и выходе из прерывания, но т.к. на возврат используется один регистр приходится пользоваться стеком, чтобы не затереть. Вложенные прерывания, на мой взгляд, извращение (но я не догматик). Тем более создатели ARM, я надеюсь, солидарны со мной. Цитата(Сергей Борщ @ Oct 1 2007, 15:42)  P.S. и не стесняйтесь склонять мою фамилию  Спасибо dxp и Сергею Борщу за оперативность (я тоже исправляюсь).  Цитата(dxp @ Oct 1 2007, 17:10)  Не понял вопроса. В чем затруднение? Все аналогично: Код OS::channel<byte, 16> queue; // очередь на 16 байт
... queue.push(10);
...
byte x; queue.pop(x); Отличия, конечно, имеются - OS::channel::pop(), в частности, поддерживает таймауты, поэтому будет работать чуть медленнее. Понял, это мой глюк. Цитата(dxp @ Oct 1 2007, 17:10)  Мне не совсем понятна суть исходного вопроса. Если имеелось в виду, почему рекомендуется шаблонный сервис, то ответ такой: - OS::TCannel использует макроподстановки, что не есть гуд.
- OS::channel имеет расширенную функциональность (таймауты и возможность, например, помещать элемент не только в конец очереди, но и в начало).
- Для единства стиля.
А это как раз понятно.
|
|
|
|
|
Oct 1 2007, 14:53
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(alexander55 @ Oct 1 2007, 16:36)  Хочется поподробнее осветить этот момент. Ну например прерывание передачи по UART забирает данные из OS:channel<uint8_t>. А данные там кончились... В этом случае pop() попытается передать управление другой задаче, и это приведет к краху. Поэтому прежде чем вызвать pop() надо проверить - а есть ли данные. Аналогично для push(). Для TEventFlag есть специальная функция SignalISR() - ее можно использовать в прерываниях без опаски. Она при необходимости может поставить какую-либо задачу в очередь готовых к выполнению, но саму перепланировку не выполняет - перепланировка будет выполнена после выхода из прерывания. Цитата(alexander55 @ Oct 1 2007, 16:36)  Я считал также, но в Вашем порте сделано наоборот, поэтому я так и решил. Но это не принципиально. В каком месте? Покажите, может там ошибка...
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 2 2007, 04:43
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(Сергей Борщ @ Oct 1 2007, 18:53)  Ну например прерывание передачи по UART забирает данные из OS:channel<uint8_t>. А данные там кончились... В этом случае pop() попытается передать управление другой задаче, и это приведет к краху. Поэтому прежде чем вызвать pop() надо проверить - а есть ли данные. Аналогично для push(). Для TEventFlag есть специальная функция SignalISR() - ее можно использовать в прерываниях без опаски. Она при необходимости может поставить какую-либо задачу в очередь готовых к выполнению, но саму перепланировку не выполняет - перепланировка будет выполнена после выхода из прерывания. Понял. Цитата(Сергей Борщ @ Oct 1 2007, 18:53)  В каком месте? Покажите, может там ошибка... Откуда я залил уже не помню. Файл OS_Target_asm.s79 Дата файла от 08.02.07 //****************************************************************************** //* //* FULLNAME: Single-Chip Microcontroller Real-Time Operating System //* //* NICKNAME: scmRTOS //* //* PROCESSOR: ARM7 //* //* TOOLKIT: EWARM (IAR Systems) //* //* PURPOSE: Target Dependent Low-Level Stuff //* //* Version: 3.00-beta //* //* $Revision: 31 $ //* $Date: 2007-02-08 18:51:14 +0600 (╨є╤й, 08 ╤д╨╡╨▓ 2007) $ //* //* Copyright © 2003-2006, Harry E. Zhurov //* //* Permission is hereby granted, free of charge, to any person //* obtaining a copy of this software and associated documentation //* files (the "Software"), to deal in the Software without restriction, //* including without limitation the rights to use, copy, modify, merge, //* publish, distribute, sublicense, and/or sell copies of the Software, //* and to permit persons to whom the Software is furnished to do so, //* subject to the following conditions: //* //* The above copyright notice and this permission notice shall be included //* in all copies or substantial portions of the Software. //* //* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, //* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF //* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. //* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY //* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, //* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH //* THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. //* //* ================================================================= //* See http://scmrtos.sourceforge.net for documentation, latest //* information, license and contact details. //* ================================================================= //* //****************************************************************************** //* ARM port by Sergey A. Borshch, Copyright © 2006 #include "scmRTOS_CONFIG.h" #include "scmRTOS_TARGET_CFG.h" #include "OS_Target_core.h" module scmRTOS_Asm #define MODE_USER 0x10 #define MODE_FIQ 0x11 #define MODE_IRQ 0x12 #define MODE_SVC 0x13 #define MODE_ABORT 0x17 #define MODE_UND 0x1B #define MODE_SYS 0x1F #define NIRQ (1<<7) #define NFIQ (1<<6) #define THUMB (1<<5) // Context structure: // lo address // CPSR // R14 (LR) // R0 // R1 // R2 // R3 // R4 // R5 // R6 // R7 // R8 // R9 // R10 // R11 // R12 // Process interrupt point (return address) // hi address CODE32 ;------------------------------------------------------------------------------- #if scmRTOS_CONTEXT_SWITCH_SCHEME == 0 COMMON INTVEC:CODE:ROOT org 0x00000008 LDR PC, Context_Switcher_Adr ; Branch to swi_handler org 0x00000018 LDR PC, IRQ_Wrapper_Adr org 0x00000020 org 0x00000028 Context_Switcher_Adr: DC32 Context_Switcher org 0x00000038 IRQ_Wrapper_Adr: DC32 IRQ_Wrapper ;------------------------------------------------------------------------------- RSEG ICODE:CODE IRQ_Wrapper: MSR CPSR_c, #(NIRQ | MODE_SYS) ; switching to System mode, because context has to be saved ; on top of user mode stack, enable FIQ STMFD SP!, {R0-R12,LR} ; store R0_R12, dummy store LR to reserve space in context STMFD SP!, {R1,LR} ; reserve space for CPSR, store LR_user on top of context MOV R0, SP ; store context pointer in non-banked register MSR CPSR_c, #(NIRQ | MODE_IRQ) ; switching back to IRQ mode SUB LR, LR, #4 ; adjusting return address STR LR, [R0, #4*15] ; store return address in reserved space (instead of saved LR_user) MRS R1, SPSR ; move stored CPSR of process to non-banked register STR R1, [R0] ; store SPSR in reserved space (instead of saved R1) IRQ_SWITCH ; call IRQ handler MSR CPSR_c, #(NIRQ | MODE_SYS) ; switching to System mode, because context has to be restored ; from user mode stack, enable FIQ MOV R0, SP B ContextRestore ; restore saved IRQ context RSEG ICODE:CODE PUBLIC SaveSP PUBLIC Set_New_SP SaveSP: // __arm void SaveSP(TStackItem** Curr_SP) MSR CPSR_c, #(NIRQ | MODE_SYS) ; switching to System mode, to get access to sp_user STR SP, [R0] MSR CPSR_c, #(NIRQ | MODE_IRQ) ; switching back to IRQ mode BX LR Set_New_SP: // __arm void SetNewSP(TStackItem* New_SP) MSR CPSR_c, #(NIRQ | MODE_SYS) ; switching to System mode, to get access to sp_user MOV SP, R0 MSR CPSR_c, #(NIRQ | MODE_IRQ) ; switching back to IRQ mode BX LR ;------------------------------------------------------------------------------- // __swi __arm void OS_ContextSwitcher(TStackItem** Curr_SP, TStackItem* Next_SP); Context_Switcher: MSR CPSR_c, #(NIRQ | MODE_SYS) ; switching to System mode, because context has to be saved ; on top of user mode stack, enable FIQ STMFD SP!, {R0-R12,LR} ; store R0_R12, dummy store LR to reserve space in context SUB R2, SP, #4*2 ; store context pointer in non-banked register (reserve space for CPSR, LR) MSR CPSR_c, #(NIRQ | MODE_SVC) ; switching back to supervisor mode STR LR, [R2, #4*15] ; store return address in reserved space (instead of saved LR_user) MRS R3, SPSR ; move stored CPSR of process to non-banked register MSR CPSR_c, #(NIRQ | MODE_SYS) ; switching back to System mode STMFD SP!, {R3,LR} ; store CPSR, LR_user on top of context and adjust SP_user STR SP,[R0] MOV R0, R1 ContextRestore LDMFD R0!, {R1, LR} ; restoring LR_user, saved CPSR_user ADD SP, R0, #4*14 ; set process SP MSR CPSR_c, #(NIRQ | MODE_IRQ) ; switch to IRQ mode to get access to SPSR_irq MSR SPSR_cxsf, R1 ; store process CPSR to SPSR_irq to restore at return from irq LDMFD R0, {R0-R12,PC}^ ; restoring remaining context, CPSR and reti #else //if scmRTOS_CONTEXT_SWITCH_SCHEME == 1; ------------------------------------------------------------------------------- COMMON INTVEC:CODE:ROOT org 0x00000018 IRQ_SWITCH ; ∩σ≡σ⌡εΣ ∩ε αΣ≡σ±≤ Φτ ΓσΩ≥ε≡φεπε Ωεφ≥≡εδδσ≡α ;------------------------------------------------------------------------------- RSEG ICODE:CODE // TStackItem* OS_ContextSwitchHook(TStackItem* sp); EXTERN OS_ContextSwitchHook PUBLIC ContextSwitcher_ISR ContextSwitcher_ISR: MSR CPSR_c, #(NIRQ | MODE_SYS) ; switching to System mode, because context has to be saved ; on top of user mode stack, enable FIQ STMFD SP!, {R0-R12,LR} ; store R0_R12, dummy store LR to reserve space in context SUB R0, SP, #4*2 ; store context pointer in non-banked register (reserve space for CPSR, LR) MSR CPSR_c, #(NIRQ | MODE_IRQ) ; switching back to IRQ mode SUB LR, LR, #4 ; adjusting return address STR LR, [R0, #4*15] ; store return address in reserved space (instead of saved LR_user) MRS R1, SPSR ; move stored CPSR of process to non-banked register MSR CPSR_c, #(NIRQ | MODE_SYS) ; switching back to System mode STMFD SP!, {R1,LR} ; store CPSR, LR_user on top of context and adjust SP_user ; to use process stack in OS_ContextSwitchHook _BLF OS_ContextSwitchHook, Hook_Relay ; store context pointer(R0), get new context pointer(R0) IRQ_DONE ; reset interrupt controller ContextRestore LDMFD R0!, {R1, LR} ; restoring LR_user, saved CPSR_user ADD SP, R0, #4*14 ; set process SP MSR CPSR_c, #(NIRQ | MODE_IRQ) ; switch to IRQ mode to get access to SPSR_irq MSR SPSR_cxsf, R1 ; store process CPSR to SPSR_irq to restore at return from irq LDMFD R0, {R0-R12,PC}^ ; restoring remining context, CPSR and reti RSEG ICODE:CODE Hook_Relay: LDR R1, =OS_ContextSwitchHook ; call Thumb mode routine BX R1 #endif ;------------------------------------------------------------------------------- RSEG CSTACK:DATA RSEG ICODE:CODE // Set SP_irq to main() stack, restore context referenced by R0 // void OS_Start(TStackItem* sp); PUBLIC OS_Start OS_Start: MSR CPSR_c, #(NIRQ | NFIQ | MODE_IRQ) ; switching to IRQ mode, disable FIQ & IRQ LDR SP, =SFE(CSTACK) & 0xFFFFFFF8 ; End of CSTACK MSR CPSR_c, #(NIRQ | NFIQ | MODE_SYS) ; switching back to System mode, disable FIQ & IRQ ; ContextRestore typically called from System mode B ContextRestore ; Restore context = run process ;------------------------------------------------------------------------------- ENDMOD END PS. Я в тесте выделил красным и зеленым цветом места. Я текст исходный.
Сообщение отредактировал alexander55 - Oct 2 2007, 04:48
|
|
|
|
|
Oct 2 2007, 07:57
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(alexander55 @ Oct 2 2007, 07:43)  PS. Я в тесте выделил красным и зеленым цветом места. Нет, это не то. В scmRTOS под "программным прерыванием" понимается обычное прерывание, которое генерится из программы: Код #if scmRTOS_CONTEXT_SWITCH_SCHEME == 1 // #define used instead of inline function to ensure inlining to both ARM and THUMB functions. #define RaiseContextSwitch() \ do \ { \ AT91C_BASE_AIC->AIC_ISCR = (1<<CONTEXT_SWITCH_INT); \ } \ while (0) // set flag and enable interrupt #endif ... #else //if scmRTOS_CONTEXT_SWITCH_SCHEME == 1 ;------------------------------------------------------------------------------- PUBLIC ContextSwitcher_ISR ContextSwitcher_ISR: MSR CPSR_c, #(NIRQ | MODE_SYS) ; switching to System mode, because context has to be saved ; on top of user mode stack, enable FIQ Его преимущество именно в том, что даже если его сгенерировать внутри прерывания, в обработчик мы попадем "с чистого листа", т.е. из фона, когда на стеке нет данных из обработчиков других прерываний. Это сильно упрощает процесс переключения контекста. Поскольку swi не маскируется - его использовать для этой цели не получилось. А в нулевом варианте swi используется просто как быстрый способ вызвать функцию с переходом в ARM-режим.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 2 2007, 09:19
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
[quote name='Сергей Борщ' date='Oct 2 2007, 11:57' post='301622'] Нет, это не то. В scmRTOS под "программным прерыванием" понимается обычное прерывание, которое генерится из программы [/quote] Я считал "программным прерыванием" SWI. Отсюда вся путаница. Теперь мне надо возвратиться в исходное и все продумать сначала. [quote name='Сергей Борщ' date='Oct 2 2007, 11:57' post='301622'] Его преимущество именно в том, что даже если его сгенерировать внутри прерывания, в обработчик мы попадем "с чистого листа", т.е. из фона, когда на стеке нет данных из обработчиков других прерываний. [/quote] Я считал, что в Supervisor (если не разрешать вложенные прерывания) можно попасть только из System режима (т.е. из фона). Т.е. SWI является отложенным прерыванием, хотя и с высоким приоритетом. Опять какая-то неувязка. [/quote] Теперь, еще один вопрос. С каким приоритетом внутри VIC лучше использовать прерывание по системному таймеру ?
|
|
|
|
|
Oct 3 2007, 09:46
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(alexander55 @ Oct 3 2007, 11:40)  Вопрос, конечно, правильный. Можно все завести в один процесс, но хочется для самообразования это знать. Вопрос решил так. OS::TEventFlag FL1; OS::TEventFlag FL2; OS::TEventFlag FL3; //--------------------------------------------------------------------------- OS_PROCESS void TProc1::Exec() { FL1.Signal(); for(;;) { if(FL1.Wait()) { ... FL2.Signal(); } } } //--------------------------------------------------------------------------- OS_PROCESS void TProc2::Exec() { for(;;) { if(FL2.Wait()) { ... FL3.Signal(); } } } //--------------------------------------------------------------------------- OS_PROCESS void TProc3::Exec() { for(;;) { if(FL3.Wait()) { ... FL1.Signal(); } } } //--------------------------------------------------------------------------- Хочу увидеть критику и ценные замечания.
Сообщение отредактировал alexander55 - Oct 3 2007, 09:47
|
|
|
|
|
Oct 3 2007, 10:38
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(alexander55 @ Oct 3 2007, 12:46)  Хочу увидеть критику и ценные замечания. Код OS::TEventFlag FL1(OS::TEventFlag::efOn); OS_PROCESS void TProc1::Exec() { for(;;) Но это шлифовка. В остальном должно работать.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 4 2007, 10:00
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(alexander55 @ Oct 4 2007, 10:34)  Правильно ли я понимаю, что минимальный джентальментский набор средств межпроцессного взаимодействия (при этом сохраняя всю функциональность): 1.OS:message 2.OS::channel Нет, OS::TService  Оно работает, но еще не готово к выпуску в широкие массы. А если серьезно - вопрос философский. Я TEventFlag и TMutex использую чаще чем channel и message.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 4 2007, 10:36
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(Сергей Борщ @ Oct 4 2007, 14:00)  Нет, OS::TService  Оно работает, но еще не готово к выпуску в широкие массы. И когда ждать? Я себя отношу к широким массам. Цитата(Сергей Борщ @ Oct 4 2007, 14:00)  А если серьезно - вопрос философский. Вот меня и интересует философия scmRTOS. Мне казалось, автор хотел дать минимальный набор универсальных инструментов для решения максимального количества задач.
|
|
|
|
|
Oct 4 2007, 11:53
|

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

|
Цитата(alexander55 @ Oct 4 2007, 17:36)  И когда ждать? Я себя отношу к широким массам. Возьмите из репозитория и пробуйте себя в роли автора.  Цитата(alexander55 @ Oct 4 2007, 17:36)  Вот меня и интересует философия scmRTOS. Мне казалось, автор хотел дать минимальный набор универсальных инструментов для решения максимального количества задач. Универсальных в полном смысле нет и быть не может. Как правило, наиболее часто используемые TEventFlag и TMutex. Исходная идея была, действительно, иметь минимально необходимый набор разнокачественных средств, но так, чтобы не страдала производительность и гибкость от недостатка оных.  Движение в сторону TService обусловлено тем, что все-таки есть случаи, когда кому-то хочется более специализированного поведения и функциональности, чем имеется в наборе.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Oct 8 2007, 05:44
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Спасибо всем за ответы. Предлагаю выкладывать в этом топике ответы на вопросы по использованию встроенных средств межпроцессного взаимодействия в scmRTOS. Это будет интересно всем, кто использует scmRTOS. Например (мой скромный вклад)  . Вопрос. Как средствами scmRTOS организуется выполнение процесса с заданной частотой. Ответ. ... OS::TEventFlag FL3; ... OS_PROCESS void TProc3::Exec() { for(;;) { FL3.Wait(100); ... } } Пояснение. Процесс 3 запускается через 100 тактов системного таймера (период процесса 3 - 100 мс при периоде таймера 1 мс).
|
|
|
|
|
Oct 8 2007, 11:12
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(Сергей Борщ @ Oct 8 2007, 12:05)  Оба варианта неправильные - не учитывают время исполнения самого процесса. По-честному надо бы считывать системное время, смотреть сколько осталось до "Часа Х" и засыпать уже на это время. Вот только есть одна грабля - если времени не осталось, то вместо исполнения без ожидания получим Sleep(0), т.е. навечно, а если не успели и "час Х" уже прошел - то опять же вместо исполнения без паузы получим ожидание на время переполнения системного таймера. Вы правы Сергей. Если понадобится точное время, я могу предложить такой вариант. //------------------------------------------------- class TTimer { int Delay; int Setting; public: TTimer(x) { Setting=x;Delay=x;}; void Run(void) { if(--!Delay) {Delay=Setting; FL.Signal();};}; }; //-------------------------------------------------- TTimer Tim100(100); ... И где-то в системном таймере ... Tim100.Run(); ... //-------------------------------------------------- Ну а в процессе OS::TEventFlag FL3; ... OS_PROCESS void TProc3::Exec() { for(;;) { FL.Wait(); ... } } PS. Так вроде чисто получается.
|
|
|
|
|
Oct 8 2007, 11:27
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(alexander55 @ Oct 8 2007, 14:12)  PS. Так вроде чисто получается.  Ну, совсем для красоты я бы сделал FL3 членом TTImer. Инкапсуляция, так сказать. А сам решаю так: Код typedef TTimeout timeout_t; timeout_t Time_X = OS::GetTickCount() + timeout; // now + timeout
for(;;) { timeout_t Timeout = Time_X - OS::GetTickCount(); if((timeout_t)(Timeout - 1) > timeout ) return 0; if(!pUART->getchar(RxData, Timeout)) // timeout, packet broken return 0;
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 8 2007, 11:58
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(Сергей Борщ @ Oct 8 2007, 15:27)  Ну, совсем для красоты я бы сделал FL3 членом TTImer. Здесь есть подводный камень с инициализацией (хотя можно наследовать виртуально). Я бы не стал так делать. Цитата(Сергей Борщ @ Oct 8 2007, 15:27)  Код typedef TTimeout timeout_t; timeout_t Time_X = OS::GetTickCount() + timeout; // now + timeout
for(;;) { timeout_t Timeout = Time_X - OS::GetTickCount(); if((timeout_t)(Timeout - 1) > timeout ) return 0; if(!pUART->getchar(RxData, Timeout)) // timeout, packet broken return 0; return 0; Здесь будет выход из цикла for. Это потенциально опасно.
|
|
|
|
|
Oct 8 2007, 13:27
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(alexander55 @ Oct 8 2007, 14:58)  Здесь есть подводный камень с инициализацией (хотя можно наследовать виртуально). Я бы не стал так делать. Какой камень? Что-то я сегодня туго соображаю. Цитата(alexander55 @ Oct 8 2007, 14:58)  return 0; Здесь будет выход из цикла for. Это потенциально опасно.  Это только кусочек функции, которая возвращает количество принятых байт в пакете или 0 если прием не сложился. Этим куском я хотел продемонстрировать вычисление оставшегося тайм-аута и обход упомянутых в предыдущем сообщении "граблей"
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 9 2007, 04:41
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(Сергей Борщ @ Oct 8 2007, 17:27)  Какой камень? Что-то я сегодня туго соображаю. Ну допустим //------------------------------------------------- class TTimer : public OS::TEventFlag { int Delay; int Setting; public: TTimer(x) { Setting=x;Delay=x;}; void Run(void) { if(--!Delay) {Delay=Setting; FL.Signal();};}; }; TTimer Tim100(100); Все нормально, но мы откажемся от возможности начальной инициализации TEventFlag (только по умолчанию). Но это не страшно. Цитата(Сергей Борщ @ Oct 8 2007, 17:27)  Это только кусочек функции, которая возвращает количество принятых байт в пакете или 0 если прием не сложился. Этим куском я хотел продемонстрировать вычисление оставшегося тайм-аута и обход упомянутых в предыдущем сообщении "граблей" Понятно. Я почему-то подумал про for процесса. PS. Я вчера тоже под конец дня зациклился.
|
|
|
|
|
Oct 9 2007, 10:24
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(alexander55 @ Oct 9 2007, 07:41)  class TTimer : public OS::TEventFlag Вчера был явно день торможения, хотя у меня, например, выходные прошли без возлияний  : Код class TTimer { int Delay; int Setting; OS::TEventFlag Flag; public: TTimer(x) : Flag(OS::TEventFlag::efOff) { Setting=x;Delay=x;} void Run(void) { if(--!Delay) {Delay=Setting; Flag.Signal();}} bool Wait() { return Flag.Wait(); } };
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 9 2007, 12:47
|

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

|
Цитата(Сергей Борщ @ Oct 9 2007, 17:24)  Вчера был явно день торможения, хотя у меня, например, выходные прошли без возлияний  : Код class TTimer { int Delay; int Setting; OS::TEventFlag Flag; public: TTimer(x) : Flag(OS::TEventFlag::efOff) { Setting=x;Delay=x;} void Run(void) { if(--!Delay) {Delay=Setting; Flag.Signal();}} bool Wait() { return Flag.Wait(); } }; Мущщины, я в упор не понимаю, почему вы используете для генерации задержек флаг события, а не специально существующую для этого функцию Sleep. Ведь она легче и быстрее, а флаг тянет за собой дополнительную функциональность, которая здесь не используется. Оверхед и загромождение кода.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
Сообщений в этой теме
alexander55 scmRTOS. Вопросы и ответы. Oct 1 2007, 09:35 dxp Цитата(alexander55 @ Oct 1 2007, 16:35) 1... Oct 1 2007, 11:11 alexander55 Цитата(dxp @ Oct 1 2007, 15:11) Вы сравни... Oct 1 2007, 12:49  dxp Цитата(alexander55 @ Oct 1 2007, 19:49) П... Oct 1 2007, 13:10                  dxp Цитата(alexander55 @ Oct 8 2007, 12:44) С... Oct 8 2007, 06:03                   alexander55 Цитата(dxp @ Oct 8 2007, 10:03) КодOS_PRO... Oct 8 2007, 07:46                          alexander55 Цитата(dxp @ Oct 9 2007, 16:47) Мущщины, ... Oct 9 2007, 13:05                           Сергей Борщ Цитата(alexander55 @ Oct 9 2007, 16:05) Я... Oct 9 2007, 14:24                            alexander55 Цитата(Сергей Борщ @ Oct 9 2007, 18:24) Н... Oct 10 2007, 04:27                             alexander55 Цитата(alexander55 @ Oct 10 2007, 08:27) ... Oct 11 2007, 05:52                           dxp Цитата(alexander55 @ Oct 9 2007, 20:05) В... Oct 10 2007, 03:57                            ReAl "UP"
Цитата(dxp @ Oct 10 2007, ... Nov 9 2007, 16:15                             alexander55 Цитата(ReAl @ Nov 9 2007, 19:15) А если з... Nov 12 2007, 07:04        spf Цитата(alexander55 @ Oct 3 2007, 12:28) В... Oct 3 2007, 07:28 prottoss Привет всем!
решил поиграться с scmRTOS. Скача... Dec 8 2007, 14:37 dxp Цитата(prottoss @ Dec 8 2007, 20:37) Это ... Dec 8 2007, 15:29  prottoss Цитата(dxp @ Dec 8 2007, 22:29) А разве о... Dec 8 2007, 15:44 prottoss Вроде бы нашел косяк:
Я использую в проекте ATmega... Dec 8 2007, 18:06 dxp Цитата(prottoss @ Dec 9 2007, 00:06) В фа... Dec 8 2007, 20:12  prottoss Цитата(dxp @ Dec 9 2007, 03:12) Макрос HA... Dec 9 2007, 09:43 ReAl В порте для avr-gcc с этим проще. Тип процессора п... Dec 13 2007, 10:07 prottoss Цитата(ReAl @ Dec 13 2007, 17:07) В порте... Dec 13 2007, 12:18 bus16 Вот тоже появилось пара вопросов по мютексам:
1 Си... Dec 27 2007, 07:28 jorikdima Цитата(bus16 @ Dec 27 2007, 10:28) Вот то... Dec 27 2007, 09:32  bus16 С 1 - понятно, хотел просто уточнить.
Цитата(jorik... Dec 27 2007, 09:45   dxp Цитата(bus16 @ Dec 27 2007, 15:45) Mutex-... Dec 27 2007, 13:24 jorikdima В том изаключается мягкость, что если ресурс уже з... Dec 27 2007, 13:27 LessNik Возник вопрос по обработке прерываний от системной... Jan 17 2008, 07:35 Сергей Борщ Цитата(LessNik @ Jan 17 2008, 09:35) Пере... Jan 17 2008, 08:59  LessNik Всё заработало. Пока ещё не смог сломать
Цитат... Jan 17 2008, 13:07 LessNik ЦитатаПосмотрел, как в OS_Target_cpp.cpp сделан об... Jan 18 2008, 07:07 Сергей Борщ Цитата(LessNik @ Jan 18 2008, 09:07) Може... Jan 18 2008, 09:19  LessNik Цитата(Сергей Борщ @ Jan 18 2008, 12:19) ... Jan 18 2008, 14:36   Сергей Борщ Цитата(LessNik @ Jan 18 2008, 16:36) GBGU... Jan 19 2008, 00:47    LessNik Цитата(Сергей Борщ @ Jan 19 2008, 03:47) ... Jan 22 2008, 06:40     Сергей Борщ Цитата(LessNik @ Jan 22 2008, 08:40) Полу... Jan 22 2008, 08:05    LessNik Цитата(Сергей Борщ @ Jan 19 2008, 03:47) ... Jan 31 2008, 10:24     Сергей Борщ Цитата(LessNik @ Jan 31 2008, 12:24) При ... Jan 31 2008, 13:02      spf Цитата(Сергей Борщ @ Jan 31 2008, 18:02) ... Feb 2 2008, 03:25       IgorKossak Цитата(spf @ Feb 2 2008, 05:25) И туда: [... Feb 3 2008, 10:33        zltigo Цитата(IgorKossak @ Feb 3 2008, 13:33) Не... Feb 3 2008, 10:47        Сергей Борщ Цитата(IgorKossak @ Feb 3 2008, 12:33) Ош... Feb 3 2008, 11:30        spf Цитата(IgorKossak @ Feb 3 2008, 15:33) Не... Feb 4 2008, 15:21         IgorKossak Цитата(spf @ Feb 4 2008, 17:21) Все работ... Feb 5 2008, 06:11          spf Цитата(IgorKossak @ Feb 5 2008, 11:11) По... Feb 5 2008, 08:31
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|