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

 
 
5 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> scmRTOS. Вопросы и ответы.
alexander55
сообщение Oct 1 2007, 09:35
Сообщение #1


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Из-за того, что мои предложения повисли в воздухе, решил открыть тему здесь.
У меня вопросы по scmRTOS (извините, если они покажутся дилетанскими, я только начал мучить ОС). Раньше считал, что в uC OS лишняя заморочка, сейчас уже так не считаю.
Общие вопросы для общего развития. smile.gif
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 - замечательная вещь. a14.gif
Go to the top of the page
 
+Quote Post
dxp
сообщение Oct 1 2007, 11:11
Сообщение #2


Adept
******

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



Цитата(alexander55 @ Oct 1 2007, 16:35) *
1. Зачем понадобилось иметь порядок приоритетов сверху вниз (насколько я понял из-за Blackfin только). a&-a немногим проигрывает.

Не понял, что дает a & -a. У Blackfin'a есть специальная команда, которая сразу вычисляет позицию первого ненулевого бита. Оба порядка приоритетов сущестувуют, чтобы можно было оптимизировать операцию вычисления приоритета для конкретного процессора. Пока это только Blackfin. Но кто знает, может есть и еще какие. Кажется у FR32 (Fujitsu) тоже есть такая аппаратная возможность.

Цитата(alexander55 @ Oct 1 2007, 16:35) *
2. Я хочу ограничиться
#if scmRTOS_CONTEXT_SWITCH_SCHEME == 0,
т.е. использовать всегда программное прерывание.
Правильно ли это ?

Надо указать в конфиге:
#define scmRTOS_CONTEXT_SWITCH_SCHEME 1.

Цитата(alexander55 @ Oct 1 2007, 16:35) *
3. Про OS::TChannel сказано, что этот объект оставлен для совместимости с версией 1. Рекомендуется пользоваться OS::channel.
Мне же показалось, несмотря на универсальность OS::channel, применение его для байтовых каналов слишком расточительным. Я бы рассматривал бы как чистый FIFO буфер, как-то так
#define TFIFO OS::Channel
и изменил он нем представление как об атавизме. Или я чего-то не понял ?

Вы сравнили производительность OS::TChannel и OS::channel<byte> и она оказалась в пользу первого? Или на основании чего такая оценка?


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 1 2007, 11:42
Сообщение #3


Гуру
******

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



Цитата(alexander55 @ Oct 1 2007, 12:35) *
Из-за того, что мои предложения повисли в воздухе, решил открыть тему здесь.
А это всегда так. Чтобы что-то сдвинулось - надо сделать это самому smile.gif
Цитата(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) Пока не реализована поддержка вложенных прерываний. Я с трудом представляю, с какой стороны к этому подступиться. Если реализуете - не забудьте поделиться smile.gif
Других ограничений вроде как нет.

P.S. и не стесняйтесь склонять мою фамилию beer.gif


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
alexander55
сообщение Oct 1 2007, 12:49
Сообщение #4


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(dxp @ Oct 1 2007, 15:11) *
Вы сравнили производительность OS::TChannel и OS::channel<byte> и она оказалась в пользу первого? Или на основании чего такая оценка?

Приведите, пожалуйста, пример аналога Push-Pop для channel.
Go to the top of the page
 
+Quote Post
dxp
сообщение Oct 1 2007, 13:10
Сообщение #5


Adept
******

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



Цитата(alexander55 @ Oct 1 2007, 19:49) *
Приведите, пожалуйста, пример аналога Push-Pop для channel.

Не понял вопроса. В чем затруднение? Все аналогично:

Код
OS::channel<byte, 16> queue; // очередь на 16 байт

...
queue.push(10);

...

byte x;
queue.pop(x);

Отличия, конечно, имеются - OS::channel::pop(), в частности, поддерживает таймауты, поэтому будет работать чуть медленнее.

Мне не совсем понятна суть исходного вопроса. Если имеелось в виду, почему рекомендуется шаблонный сервис, то ответ такой:
  1. OS::TCannel использует макроподстановки, что не есть гуд.
  2. OS::channel имеет расширенную функциональность (таймауты и возможность, например, помещать элемент не только в конец очереди, но и в начало).
  3. Для единства стиля.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
alexander55
сообщение Oct 1 2007, 13:36
Сообщение #6


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(Сергей Борщ @ Oct 1 2007, 15:42) *
В третьей версии мы придумали простой способ объявлять pr0 самым высоким приоритетом вне зависимости от прямого/обратного порядка. Наверное нужно в следующем релизе поддержку обратного порядка из порта исключить

У меня нюх как у собаки. smile.gif

Цитата(Сергей Борщ @ 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) Пока не реализована поддержка вложенных прерываний. Я с трудом представляю, с какой стороны к этому подступиться. Если реализуете - не забудьте поделиться smile.gif
Других ограничений вроде как нет.

Насколько я знаю по Keil, вложенные прерывания реализуются через макросы при входе и выходе из прерывания, но т.к. на возврат используется один регистр приходится пользоваться стеком, чтобы не затереть. Вложенные прерывания, на мой взгляд, извращение (но я не догматик). Тем более создатели ARM, я надеюсь, солидарны со мной. smile.gif

Цитата(Сергей Борщ @ Oct 1 2007, 15:42) *
P.S. и не стесняйтесь склонять мою фамилию beer.gif

Спасибо dxp и Сергею Борщу за оперативность (я тоже исправляюсь). biggrin.gif

Цитата(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) *
Мне не совсем понятна суть исходного вопроса. Если имеелось в виду, почему рекомендуется шаблонный сервис, то ответ такой:
  1. OS::TCannel использует макроподстановки, что не есть гуд.
  2. OS::channel имеет расширенную функциональность (таймауты и возможность, например, помещать элемент не только в конец очереди, но и в начало).
  3. Для единства стиля.

А это как раз понятно. biggrin.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 1 2007, 14:53
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
alexander55
сообщение Oct 2 2007, 04:43
Сообщение #8


Бывалый
*****

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 2 2007, 07:57
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
alexander55
сообщение Oct 2 2007, 09:19
Сообщение #10


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



[quote name='Сергей Борщ' date='Oct 2 2007, 11:57' post='301622']
Нет, это не то. В scmRTOS под "программным прерыванием" понимается обычное прерывание, которое генерится из программы
[/quote]
Я считал "программным прерыванием" SWI. Отсюда вся путаница.
Теперь мне надо возвратиться в исходное и все продумать сначала. 07.gif

[quote name='Сергей Борщ' date='Oct 2 2007, 11:57' post='301622']
Его преимущество именно в том, что даже если его сгенерировать внутри прерывания, в обработчик мы попадем "с чистого листа", т.е. из фона, когда на стеке нет данных из обработчиков других прерываний.
[/quote]
Я считал, что в Supervisor (если не разрешать вложенные прерывания) можно попасть только из System режима (т.е. из фона). Т.е. SWI является отложенным прерыванием, хотя и с высоким приоритетом.
Опять какая-то неувязка. sad.gif
[/quote]

Теперь, еще один вопрос.
С каким приоритетом внутри VIC лучше использовать прерывание по системному таймеру ?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 2 2007, 09:49
Сообщение #11


Гуру
******

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



Цитата(alexander55 @ Oct 2 2007, 12:19) *
С каким приоритетом внутри VIC лучше использовать прерывание по системному таймеру ?
В идеале так: самый низкий приоритет у переключателя контекста, чуть выше - у системного таймера, остальные - еще выше. Подробно обсуждалось тут: http://caxapa.ru/98558.html


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
alexander55
сообщение Oct 3 2007, 06:28
Сообщение #12


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Вопрос. Как в scmRTOS организовать карусель скажем из трех процессов ?
Go to the top of the page
 
+Quote Post
dxp
сообщение Oct 3 2007, 07:24
Сообщение #13


Adept
******

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



Цитата(alexander55 @ Oct 3 2007, 13:28) *
Вопрос. Как в scmRTOS организовать карусель скажем из трех процессов ?

Никак. А зачем?


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
spf
сообщение Oct 3 2007, 07:28
Сообщение #14


Странник
****

Группа: Свой
Сообщений: 766
Регистрация: 29-08-05
Из: Екатеринбург
Пользователь №: 8 051



Цитата(alexander55 @ Oct 3 2007, 12:28) *
Вопрос. Как в scmRTOS организовать карусель скажем из трех процессов ?

В доке это написано wink.gif


--------------------
"Как много есть на свете вещей, которые мне не нужны!" Сократ
Go to the top of the page
 
+Quote Post
alexander55
сообщение Oct 3 2007, 07:40
Сообщение #15


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(dxp @ Oct 3 2007, 11:24) *
Никак. А зачем?

Вопрос, конечно, правильный.
Можно все завести в один процесс, но хочется для самообразования это знать.
Go to the top of the page
 
+Quote Post
alexander55
сообщение Oct 3 2007, 09:46
Сообщение #16


Бывалый
*****

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 3 2007, 10:38
Сообщение #17


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
alexander55
сообщение Oct 3 2007, 11:01
Сообщение #18


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(Сергей Борщ @ Oct 3 2007, 14:38) *
[code]OS::TEventFlag FL1(OS::TEventFlag::efOn);

Спасибо.
Go to the top of the page
 
+Quote Post
alexander55
сообщение Oct 4 2007, 07:34
Сообщение #19


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Правильно ли я понимаю, что
минимальный джентальментский набор средств межпроцессного взаимодействия (при этом сохраняя всю функциональность):
1.OS:message
2.OS::channel
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 4 2007, 10:00
Сообщение #20


Гуру
******

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



Цитата(alexander55 @ Oct 4 2007, 10:34) *
Правильно ли я понимаю, что
минимальный джентальментский набор средств межпроцессного взаимодействия (при этом сохраняя всю функциональность):
1.OS:message
2.OS::channel
Нет, OS::TService smile.gif Оно работает, но еще не готово к выпуску в широкие массы.
А если серьезно - вопрос философский. Я TEventFlag и TMutex использую чаще чем channel и message.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
alexander55
сообщение Oct 4 2007, 10:36
Сообщение #21


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(Сергей Борщ @ Oct 4 2007, 14:00) *
Нет, OS::TService smile.gif Оно работает, но еще не готово к выпуску в широкие массы.

И когда ждать? Я себя отношу к широким массам.

Цитата(Сергей Борщ @ Oct 4 2007, 14:00) *
А если серьезно - вопрос философский.

Вот меня и интересует философия scmRTOS. Мне казалось, автор хотел дать минимальный набор универсальных инструментов для решения максимального количества задач.
Go to the top of the page
 
+Quote Post
dxp
сообщение Oct 4 2007, 11:53
Сообщение #22


Adept
******

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



Цитата(alexander55 @ Oct 4 2007, 17:36) *
И когда ждать? Я себя отношу к широким массам.

Возьмите из репозитория и пробуйте себя в роли автора. smile.gif

Цитата(alexander55 @ Oct 4 2007, 17:36) *
Вот меня и интересует философия scmRTOS. Мне казалось, автор хотел дать минимальный набор универсальных инструментов для решения максимального количества задач.

Универсальных в полном смысле нет и быть не может. Как правило, наиболее часто используемые TEventFlag и TMutex. Исходная идея была, действительно, иметь минимально необходимый набор разнокачественных средств, но так, чтобы не страдала производительность и гибкость от недостатка оных. smile.gif Движение в сторону TService обусловлено тем, что все-таки есть случаи, когда кому-то хочется более специализированного поведения и функциональности, чем имеется в наборе.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
alexander55
сообщение Oct 8 2007, 05:44
Сообщение #23


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Спасибо всем за ответы.
Предлагаю выкладывать в этом топике ответы на вопросы по использованию встроенных средств межпроцессного взаимодействия в scmRTOS. Это будет интересно всем, кто использует scmRTOS.
Например (мой скромный вклад) biggrin.gif .
Вопрос. Как средствами scmRTOS организуется выполнение процесса с заданной частотой.
Ответ.
...
OS::TEventFlag FL3;
...
OS_PROCESS void TProc3::Exec()
{
for(;;)
{
FL3.Wait(100);
...
}
}
Пояснение. Процесс 3 запускается через 100 тактов системного таймера (период процесса 3 - 100 мс при периоде таймера 1 мс).
Go to the top of the page
 
+Quote Post
dxp
сообщение Oct 8 2007, 06:03
Сообщение #24


Adept
******

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



Цитата(alexander55 @ Oct 8 2007, 12:44) *
Спасибо всем за ответы.
Предлагаю выкладывать в этом топике ответы на вопросы по использованию встроенных средств межпроцессного взаимодействия в scmRTOS. Это будет интересно всем, кто использует scmRTOS.
Например (мой скромный вклад) biggrin.gif .
Вопрос. Как средствами scmRTOS организуется выполнение процесса с заданной частотой.
Ответ.
...
OS::TEventFlag FL3;
...
OS_PROCESS void TProc3::Exec()
{
for(;;)
{
FL3.Wait(100);
...
}
}
Пояснение. Процесс 3 запускается через 100 тактов системного таймера (период процесса 3 - 100 мс при периоде таймера 1 мс).

Код
OS_PROCESS void TProc3::Exec()
{
    for(;;)
    {
        Sleep(100);
        ...
    }
}


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
alexander55
сообщение Oct 8 2007, 07:46
Сообщение #25


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(dxp @ Oct 8 2007, 10:03) *
Код
OS_PROCESS void TProc3::Exec()
{
    for(;;)
    {
        Sleep(100);
        ...
    }
}

Спасибо, Ваш вариант лучше. a14.gif

Сообщение отредактировал alexander55 - Oct 8 2007, 07:52
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 8 2007, 08:05
Сообщение #26


Гуру
******

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



Цитата(alexander55 @ Oct 8 2007, 08:44) *
Как средствами scmRTOS организуется выполнение процесса с заданной частотой.
Оба варианта неправильные - не учитывают время исполнения самого процесса. По-честному надо бы считывать системное время, смотреть сколько осталось до "Часа Х" и засыпать уже на это время. Вот только есть одна грабля - если времени не осталось, то вместо исполнения без ожидания получим Sleep(0), т.е. навечно, а если не успели и "час Х" уже прошел - то опять же вместо исполнения без паузы получим ожидание на время переполнения системного таймера.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
alexander55
сообщение Oct 8 2007, 11:12
Сообщение #27


Бывалый
*****

Группа: Свой
Сообщений: 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. Так вроде чисто получается. yeah.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 8 2007, 11:27
Сообщение #28


Гуру
******

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



Цитата(alexander55 @ Oct 8 2007, 14:12) *
PS. Так вроде чисто получается. yeah.gif
Ну, совсем для красоты я бы сделал 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)
Go to the top of the page
 
+Quote Post
alexander55
сообщение Oct 8 2007, 11:58
Сообщение #29


Бывалый
*****

Группа: Свой
Сообщений: 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. Это потенциально опасно. sad.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 8 2007, 13:27
Сообщение #30


Гуру
******

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



Цитата(alexander55 @ Oct 8 2007, 14:58) *
Здесь есть подводный камень с инициализацией (хотя можно наследовать виртуально). Я бы не стал так делать.
Какой камень? Что-то я сегодня туго соображаю.
Цитата(alexander55 @ Oct 8 2007, 14:58) *
return 0;
Здесь будет выход из цикла for. Это потенциально опасно. sad.gif
Это только кусочек функции, которая возвращает количество принятых байт в пакете или 0 если прием не сложился. Этим куском я хотел продемонстрировать вычисление оставшегося тайм-аута и обход упомянутых в предыдущем сообщении "граблей"


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
alexander55
сообщение Oct 9 2007, 04:41
Сообщение #31


Бывалый
*****

Группа: Свой
Сообщений: 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 процесса. biggrin.gif
PS. Я вчера тоже под конец дня зациклился.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 9 2007, 10:24
Сообщение #32


Гуру
******

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



Цитата(alexander55 @ Oct 9 2007, 07:41) *
class TTimer : public OS::TEventFlag
Вчера был явно день торможения, хотя у меня, например, выходные прошли без возлияний wink.gif :
Код
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)
Go to the top of the page
 
+Quote Post
dxp
сообщение Oct 9 2007, 12:47
Сообщение #33


Adept
******

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



Цитата(Сергей Борщ @ Oct 9 2007, 17:24) *
Вчера был явно день торможения, хотя у меня, например, выходные прошли без возлияний wink.gif :
Код
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. Ведь она легче и быстрее, а флаг тянет за собой дополнительную функциональность, которая здесь не используется. Оверхед и загромождение кода.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
alexander55
сообщение Oct 9 2007, 13:05
Сообщение #34


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(dxp @ Oct 9 2007, 16:47) *
Мущщины, я в упор не понимаю, почему вы используете для генерации задержек флаг события, а не специально существующую для этого функцию Sleep. Ведь она легче и быстрее, а флаг тянет за собой дополнительную функциональность, которая здесь не используется. Оверхед и загромождение кода.

Вопрос стал о точном среднем выдерживании по времени процессных задач (ради чистого искусства).
PS. Предложение. Давайте обсудим какую-нибудь полезную тему типа "Обмен ModBus пакетами средствами scmRTOS".
Я знаю, у Сергея есть наработки, у меня тоже кое-что есть.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 9 2007, 14:24
Сообщение #35


Гуру
******

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



Цитата(alexander55 @ Oct 9 2007, 16:05) *
Я знаю, у Сергея есть наработки, у меня тоже кое-что есть.
Нету. С MODBUS никогда не работал.


Цитата(dxp @ Oct 9 2007, 15:47) *
Мущщины, я в упор не понимаю, почему вы используете для генерации задержек флаг события, а не специально существующую для этого функцию Sleep.
Мы всех окончательно запутали smile.gif Я в последних сообщениях обсуждал возможность использовать какой-либо сервис как члена какого-либо объекта. А против Sleep() не возражал, только отметил, что для периодического выполнения какого-либо куска время задержки надо бы рассчитывать, чтобы вычесть из него собственно время выполнения самого полезного кода.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
dxp
сообщение Oct 10 2007, 03:57
Сообщение #36


Adept
******

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



Цитата(alexander55 @ Oct 9 2007, 20:05) *
Вопрос стал о точном среднем выдерживании по времени процессных задач (ради чистого искусства).

Ну, и пожалуйста - заверните Sleep в свой объект TTimer, внутри которого будут вычисляться точные значения аргумента Sleep, и все. Флаг события-то тут зачем?


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
alexander55
сообщение Oct 10 2007, 04:27
Сообщение #37


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(Сергей Борщ @ Oct 9 2007, 18:24) *
Нету. С MODBUS никогда не работал.

Хорошо, тогда предлагаемая тема для обсуждения "Обмен пакетами по RS485 с помощью средств scmRTOS".

Цитата(dxp @ Oct 10 2007, 07:57) *
Ну, и пожалуйста - заверните Sleep в свой объект TTimer, внутри которого будут вычисляться точные значения аргумента Sleep, и все. Флаг события-то тут зачем?

Идея ясна.
Go to the top of the page
 
+Quote Post
alexander55
сообщение Oct 11 2007, 05:52
Сообщение #38


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(alexander55 @ Oct 10 2007, 08:27) *
Хорошо, тогда предлагаемая тема для обсуждения "Обмен пакетами по RS485 с помощью средств scmRTOS".

Я так понял, что молчание - знак согласия. Ну тогда поехали.

Вопросы для обсуждения (хочется применительно к LPC).
Выскажу свое видение вопроса.
1. Приоритет прерывания по приему символов .
Для определенности. Выше системного таймера, но ниже, чем готовность данных ADC.
2. Для обработки принятого пакета - формирования пакета ответа - передачи подготовленного пакета организуется свой процесс (назовем процессом на передачу).
2.1. Запуск процесса на передачу для master.
- запуск процесса осуществляется по таймеру временных интервалов (пакет запроса с передачей);
- запуск процесса от органов управления (с передачей);
- обработка принятых данных от slave (без передачи).
2.2. Запуск процесса на передачу для slave.
- по истечению таймаута на отсутствие принятых символов (с передачей или без нее);
- по каким-то явным признакам прошедшего или сбойного пакета запроса (с передачей или без нее).
3. Прерывание по приему символов осуществляет запись в приемный буфер, с которым и производится работа в процессе на передачу.

Думаю, вопросов для начала обсуждения пока достаточно.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Nov 9 2007, 16:15
Сообщение #39


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



"UP" smile.gif

Цитата(dxp @ Oct 10 2007, 05:57) *
Ну, и пожалуйста - заверните Sleep в свой объект TTimer, внутри которого будут вычисляться точные значения аргумента Sleep, и все. Флаг события-то тут зачем?
+1
Более того - если от момента, когда время Sleep для данного процесса истекло (его занесли в готовые), до того, как он реально получит управление, проходит меньше времени одного системного тика - то вообще ничего не надо. В среднем будет всё нормально.
Конечно - если процесс по приоритету где-то внизу и старшие вечно толпятся - то будет проскакивать. Тогда действительно обернуть в класс с поведением "типа OCR += PERIOD".
А если задержки до "всплытия" процесса могут быть такими большими, что оставшееся время может
оказаться равно 0 - то оно и "отрицательным" может оказаться, тут уж переход к TEventFlag тоже ничего не даст.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
alexander55
сообщение Nov 12 2007, 07:04
Сообщение #40


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(ReAl @ Nov 9 2007, 19:15) *
А если задержки до "всплытия" процесса могут быть такими большими, что оставшееся время может
оказаться равно 0 - то оно и "отрицательным" может оказаться, тут уж переход к TEventFlag тоже ничего не даст.

Проблема решается на уровне соответствующего приоритета. А если приоритет низкий, то автор знает на что идет и, вероятно, это его устраивает. smile.gif
Go to the top of the page
 
+Quote Post
prottoss
сообщение Dec 8 2007, 14:37
Сообщение #41


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Привет всем!
решил поиграться с scmRTOS. Скачал исходники версии 3.0. Скомпилил - НО то ли день не мой, то ли дело не в бобине... smile.gif
Компилятор IAR 4.30A/W32 [Evaluation] (4.30.1.3). Попробовал поэмулировать ОС с примером из папки [3-Channel] в AVRStudio 4.12 SP2.
В конфиге scmRTOS_config.h установил
Код

#define  scmRTOS_CONTEXT_SWITCH_SCHEME      0

После запуска симулятор выдает предупреждение
Цитата
AVR Simulator: Invalid opcode 0xffff at address 0x00ffff

Это возникает после выхода из процедуры OS_Start(sp)
Где грабли, не пойму. Просвятите, плиз. Сенькс.


--------------------
Go to the top of the page
 
+Quote Post
dxp
сообщение Dec 8 2007, 15:29
Сообщение #42


Adept
******

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



Цитата(prottoss @ Dec 8 2007, 20:37) *
Это возникает после выхода из процедуры OS_Start(sp)
Где грабли, не пойму. Просвятите, плиз. Сенькс.

А разве оно должно выходить из этой функции? Оно в нее заходит и далее запускаются все процессы, никакого выхода быть не должно. Посмотрите код этой функции, он очень простой и короткий.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
prottoss
сообщение Dec 8 2007, 15:44
Сообщение #43


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(dxp @ Dec 8 2007, 22:29) *
А разве оно должно выходить из этой функции? Оно в нее заходит и далее запускаются все процессы, никакого выхода быть не должно. Посмотрите код этой функции, он очень простой и короткий.




Расскажу по порядку, что у меня происходит:

1. выполняется конструктор OS::Kernel

2. выполянется конструктор OS::PrioMaskTable

3. выполняются последовательно кострукторы 3-х процессов

4. вызывается OS::Run()

5. в OS::Run() вызывается OS_Start(sp)

6. Попадаем в OS_Target_asm.s90 на метку OS_Start:

7. Далее переход на метку L_RestoreContext:

8. После команды RET симулятор вываливает

Код
AVR Simulator: Invalid opcode 0xffff at address 0x00ffff


--------------------
Go to the top of the page
 
+Quote Post
prottoss
сообщение Dec 8 2007, 18:06
Сообщение #44


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Вроде бы нашел косяк:
Я использую в проекте ATmega128, под него и компилил проект. После мучительных размышлений на 1,7 кБайтами кода smile.gif попробовал сменить МК на м64 - все заработало!!! Сразу возникла мысль про RAMPZ!
В файле OS_Target_asm.s90 есть макросы #if HAS_RAMPZ == 1 ... #endif - так вот, они почемуто не хотятЪ работать:-( Сделал в данном файле принудительно #define HAS_RAMPZ 1 - все заработало... Я в тонкостях компиляторов не сильно силен, как победить баг?


--------------------
Go to the top of the page
 
+Quote Post
dxp
сообщение Dec 8 2007, 20:12
Сообщение #45


Adept
******

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



Цитата(prottoss @ Dec 9 2007, 00:06) *
В файле OS_Target_asm.s90 есть макросы #if HAS_RAMPZ == 1 ... #endif - так вот, они почемуто не хотятЪ работать:-( Сделал в данном файле принудительно #define HAS_RAMPZ 1 - все заработало... Я в тонкостях компиляторов не сильно силен, как победить баг?

Макрос HAS_RAMPZ генерируется компилятором из заданного процессора. Но это компилятором. А ассемблер, насколько помню, не поддерживает задание конкретного типа процессора, там все опции целевого процессора надо задавать через -v и -m опции. Соответственно, означенный макрос ассемблер не генерирует, поэтому его надо задавать руками. Удобно сделать это через опции проекта, а не править исходник. Если сборка идет из командной строки (makefile etc), то задать макрос через ключ командной строки -D, если из оболочки, что в опциях проекта, в разделе асма, во вкладке define указать макрос.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
prottoss
сообщение Dec 9 2007, 09:43
Сообщение #46


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(dxp @ Dec 9 2007, 03:12) *
Макрос HAS_RAMPZ генерируется компилятором из заданного процессора. Но это компилятором. А ассемблер, насколько помню, не поддерживает задание конкретного типа процессора, там все опции целевого процессора надо задавать через -v и -m опции. Соответственно, означенный макрос ассемблер не генерирует, поэтому его надо задавать руками. Удобно сделать это через опции проекта, а не править исходник. Если сборка идет из командной строки (makefile etc), то задать макрос через ключ командной строки -D, если из оболочки, что в опциях проекта, в разделе асма, во вкладке define указать макрос.
Да, наверное так и надо... НО, думаю тогда надо вписать данное предупреждение в начале S90-файла, типа /* ... Warning! bla-bla-bla ... */ smile.gif


--------------------
Go to the top of the page
 
+Quote Post
ReAl
сообщение Dec 13 2007, 10:07
Сообщение #47


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



В порте для avr-gcc с этим проще. Тип процессора передаётся и ассемблеру, достаточно включить <avr/io.h> и символ RAMPZ определён только для тех процессоров, у которых он есть. После чего #ifdef RAMPZ что в С, что в асме.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
prottoss
сообщение Dec 13 2007, 12:18
Сообщение #48


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(ReAl @ Dec 13 2007, 17:07) *
В порте для avr-gcc с этим проще. Тип процессора передаётся и ассемблеру, достаточно включить <avr/io.h> и символ RAMPZ определён только для тех процессоров, у которых он есть. После чего #ifdef RAMPZ что в С, что в асме.
кстати, в ассемблер на IAR тоже можно включать C-шные хедеры, так что я думаю, что можно побороть эту проблему. К сожалению,я счас загружен по макушку проектом, и не могу все это попробовать:-(


--------------------
Go to the top of the page
 
+Quote Post
bus16
сообщение Dec 27 2007, 07:28
Сообщение #49


Частый гость
**

Группа: Свой
Сообщений: 78
Регистрация: 10-01-07
Пользователь №: 24 270



Вот тоже появилось пара вопросов по мютексам:
1 Ситуация: несколько процессов стоят в очереди - ждут захваченный mutex. Процесс, который этот mutex захватил - освобождает его. Перейдет-ли все процессы, ожидавшие его в активное состояние или управление получит только процесс с наивысшим приоритетом (стр. 61 описания "Если семафора ожидали несколько процессов, то управление получит самый приоритетный из них ")
2 "Мягкий" захват mutex-а. Ситуация: mutex захвачен. Какой-то процесс пытается его "мягко" захватить. В случае с "жестким" захватом - ситуация ясна - процесс перейдёт в неактивное состояние до разблокировки mutex-а. А что произойдёт в случае "мягкого" захвата? TMutex::LockSoftly(); просто проскочит? Но ведь за блокировкой всегда следует обращение к защищённому ресурсу. Что делать в такой ситуации? Может проще вызвать TMutex::IsLocked(); и не париться?
Go to the top of the page
 
+Quote Post
jorikdima
сообщение Dec 27 2007, 09:32
Сообщение #50


тут может быть ваша реклама
*****

Группа: Свой
Сообщений: 1 164
Регистрация: 15-03-06
Из: Санкт-Петербург/CA
Пользователь №: 15 280



Цитата(bus16 @ Dec 27 2007, 10:28) *
Вот тоже появилось пара вопросов по мютексам:
1 Ситуация: несколько процессов стоят в очереди - ждут захваченный mutex. Процесс, который этот mutex захватил - освобождает его. Перейдет-ли все процессы, ожидавшие его в активное состояние или управление получит только процесс с наивысшим приоритетом (стр. 61 описания "Если семафора ожидали несколько процессов, то управление получит самый приоритетный из них ")
2 "Мягкий" захват mutex-а. Ситуация: mutex захвачен. Какой-то процесс пытается его "мягко" захватить. В случае с "жестким" захватом - ситуация ясна - процесс перейдёт в неактивное состояние до разблокировки mutex-а. А что произойдёт в случае "мягкого" захвата? TMutex::LockSoftly(); просто проскочит? Но ведь за блокировкой всегда следует обращение к защищённому ресурсу. Что делать в такой ситуации? Может проще вызвать TMutex::IsLocked(); и не париться?

1. В активное состояние перейдет процесс с наивысшим приоритетом. В приведенной цитате все четко написано. Остальные так и будут спать.

2. За блокировкой идет то, что вы напишете, а не захват ресурса. И если вы проверите результат TMutex::LockSoftly() на правду/ложь и будете захватывать ресурс только в случае true, то все будет в порядке.
Go to the top of the page
 
+Quote Post
bus16
сообщение Dec 27 2007, 09:45
Сообщение #51


Частый гость
**

Группа: Свой
Сообщений: 78
Регистрация: 10-01-07
Пользователь №: 24 270



С 1 - понятно, хотел просто уточнить.
Цитата(jorikdima @ Dec 27 2007, 12:32) *
2. За блокировкой идет то, что вы напишете, а не захват ресурса. И если вы проверите результат TMutex::LockSoftly() на правду/ложь и будете захватывать ресурс только в случае true, то все будет в порядке.

Mutex-ом как-раз блокируют используемый ресурс, просто-так блокировку вызывать бессмысленно, так-что за блокировкой всегда идёт именно работа с ресурсом.
TMutex::LockSoftly() - не возвращает значение, она "мягко" блокирует. Вот как именно "мягко" я и хочу понять
Go to the top of the page
 
+Quote Post
dxp
сообщение Dec 27 2007, 13:24
Сообщение #52


Adept
******

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



Цитата(bus16 @ Dec 27 2007, 15:45) *
Mutex-ом как-раз блокируют используемый ресурс, просто-так блокировку вызывать бессмысленно, так-что за блокировкой всегда идёт именно работа с ресурсом.
TMutex::LockSoftly() - не возвращает значение, она "мягко" блокирует. Вот как именно "мягко" я и хочу понять

Код
INLINE bool LockSoftly()     { TCritSect cs; if(ValueTag) return false; else Lock(); return true; }


как видно, функция возврящает bool. Если вернула true, то семафор захвачен, можно работать с ресурсом, если false, то семафор уже был захвачен другим процессом, тут его захватить не удалось, работать с ресурсом нельзя - можно заняться чем-то другим.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
jorikdima
сообщение Dec 27 2007, 13:27
Сообщение #53


тут может быть ваша реклама
*****

Группа: Свой
Сообщений: 1 164
Регистрация: 15-03-06
Из: Санкт-Петербург/CA
Пользователь №: 15 280



В том изаключается мягкость, что если ресурс уже заблокирован, то программисту дается возможность не ждать в спячке разблокировки, а поделоть что либо другое, естественно без использования упомянутого ресурса, ибо он занят. Чтобы дать разработчику понять захватился ли мютекс мягко или нет и придумано возвращения значения функции LockSoftly(). Если правда, то все хорошо, ресурс залочен - пользуйтесь. А если ложь, то сообщается, что ресурс занят можешь делать что либо другое. Если вам не нужна такая функциональность, то пользуйтесь Lock(). За блокировкой действительно всегда идет работа с ресурсом. Но я имел в виду, что по проверки условия возвращаемого значения можно и не идти на работу с ресурсом, а пойти по другим делам, если таковые имеются.
Go to the top of the page
 
+Quote Post
LessNik
сообщение Jan 17 2008, 07:35
Сообщение #54


Частый гость
**

Группа: Свой
Сообщений: 107
Регистрация: 6-09-06
Из: Москва
Пользователь №: 20 118



Возник вопрос по обработке прерываний от системной периферии под ARM7 (AT91SAM7x256):

Как известно прерывания от DBGU и PIT совмещены. PIT- системный таймер. По DBGU приходят данные со скоростью 9600 почти без перерыва. Полученные данные записываются в к-либо буфер и обрабатываются.

Как лучше это сделать?
Может лучше в качестве системного таймера использовать TC0?

Код
void OS::SystemTimerUserHook()
{
if(AT91C_BASE_DBGU->DBGU_CSR&(AT91C_US_RXRDY|AT91C_US_OVRE))
  {                                                                  
     volatile unsigned int dummy = AT91C_BASE_DBGU->DBGU_CSR;      
     AT91C_BASE_DBGU->DBGU_CR=AT91C_US_RSTSTA;
     Buf=(AT91C_BASE_DBGU->DBGU_RHR);
     If (Buf==...)     FDbguDataReceived.SignalISR();
     AT91C_BASE_AIC->AIC_IVR = 1;   // ?
     AT91C_BASE_AIC->AIC_EOICR = 1; // ?
  }
}


Перестаёт срабатывать прерывание системного таймера OS::SystemTimer_ISR при активности DBGU, причём даже в условие не заходит ниразу.

P.S. В пошаговом режиме заходит в условие.

Сообщение отредактировал LessNik - Jan 17 2008, 07:49
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 17 2008, 08:59
Сообщение #55


Гуру
******

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



Цитата(LessNik @ Jan 17 2008, 09:35) *
Перестаёт срабатывать прерывание системного таймера OS::SystemTimer_ISR при активности DBGU, причём даже в условие не заходит ниразу.
Что-то сразу не соображу, где может быть засада. Делал обмен по DBGU, правда, короткими пакетами. 115200.
Код
void OS::SystemTimerUserHook()
{
    pUpLink->Handler();
}
template<uint8_t rx_size, uint8_t tx_size>
void uart_t<rx_size, tx_size>::Handler()
{
    uint32_t Flags = pUART->US_CSR;
    Flags &= pUART->US_IMR;

    if(Flags & AT91C_US_TXRDY)
    {
        if(TxBuffer.get_count())
        {
            uint8_t Data;
            TxBuffer.pop(Data, 1);
            pUART->US_THR = Data;
        }
        else
            pUART->US_IDR = AT91C_US_TXRDY;
    }

    if(Flags & AT91C_US_RXRDY)
    {
        uint8_t Data = pUART->US_RHR;       // read anyway
        pUART->US_CR = AT91C_US_RSTSTA;     // clear errors if any
        if(RxBuffer.get_free_size())
            RxBuffer.push(Data);

    }
}
Посмотрел, как в OS_Target_cpp.cpp сделан обработчик прерывания - там баг, который я исправил в своем проекте, но не перенес исправление в репозиторий. В вашем коде SystemTimerUserHook(); вызывается только если прерывание пришло от таймера. Надо сделать такое изменнение:
Код
inline __arm void OS::SystemTimer_Handler()
{
    Kernel.SystemTimer();
}

OS_INTERRUPT void OS::SystemTimer_ISR()
{
    scmRTOS_ISRW_TYPE ISR;

    SYSTEM_TIMER_HANDLER();

#if scmRTOS_SYSTIMER_HOOK_ENABLE == 1
    SystemTimerUserHook();
#endif

    IRQ_DONE();
}
Спасибо, что нашли эту багу - сейсчас поправлю.

Посмотрел внимательнее ваш код - запись AT91C_BASE_AIC->AIC_EOICR = 1; // ? не нужна, это делается в самом обработчике, в макросе IRQ_DONE. А что вы хотели получить записью AT91C_BASE_AIC->AIC_IVR = 1; // ? мне совсем непонятно.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
LessNik
сообщение Jan 17 2008, 13:07
Сообщение #56


Частый гость
**

Группа: Свой
Сообщений: 107
Регистрация: 6-09-06
Из: Москва
Пользователь №: 20 118



a14.gif

Всё заработало. Пока ещё не смог сломать smile.gif

Цитата(Сергей Борщ @ Jan 17 2008, 11:59) *
А что вы хотели получить записью AT91C_BASE_AIC->AIC_IVR = 1; // ? мне совсем непонятно.


Это скопировал из другого проекта.
Использовал при отладке. Предварительно перешел в Protect Mode.

Но в этом проекте не использую Protect Mode. Надо удалить будет
Go to the top of the page
 
+Quote Post
LessNik
сообщение Jan 18 2008, 07:07
Сообщение #57


Частый гость
**

Группа: Свой
Сообщений: 107
Регистрация: 6-09-06
Из: Москва
Пользователь №: 20 118



Цитата
Посмотрел, как в OS_Target_cpp.cpp сделан обработчик прерывания - там баг, который я исправил в своем проекте, но не перенес исправление в репозиторий. В вашем коде SystemTimerUserHook(); вызывается только если прерывание пришло от таймера. Надо сделать такое изменнение:
...


Может там ещё нужно где-то поправить? У меня периодически отваливаются прерывания от системного таймера при большой активности DBGU. Программа постоянно сидит в void OS::IdleProcessUserHook() {}

Если не трудно, можно выложить обновление здесь?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 18 2008, 09:19
Сообщение #58


Гуру
******

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



Цитата(LessNik @ Jan 18 2008, 09:07) *
Может там ещё нужно где-то поправить? У меня периодически отваливаются прерывания от системного таймера при большой активности DBGU.
DBGU при этом продолжает работать?Стека для прерываний достаточно выделено?
Цитата(LessNik @ Jan 18 2008, 09:07) *
Программа постоянно сидит в void OS::IdleProcessUserHook() {}
Это нормально, если ей больше нечего делать.
Цитата(LessNik @ Jan 18 2008, 09:07) *
Если не трудно, можно выложить обновление здесь?
Да там только приведенные выше две функции OS::SystemTimer_Handler() и OS::SystemTimer_ISR() изменились. http://scmrtos.svn.sourceforge.net/viewvc/...1=71&r2=105


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
LessNik
сообщение Jan 18 2008, 14:36
Сообщение #59


Частый гость
**

Группа: Свой
Сообщений: 107
Регистрация: 6-09-06
Из: Москва
Пользователь №: 20 118



Цитата(Сергей Борщ @ Jan 18 2008, 12:19) *
DBGU при этом продолжает работать?Стека для прерываний достаточно выделено?Это нормально, если ей больше нечего делать.Да там только приведенные выше две функции OS::SystemTimer_Handler() и OS::SystemTimer_ISR() изменились. http://scmrtos.svn.sourceforge.net/viewvc/...1=71&r2=105


GBGU перестаёт работать и перестаёт вызываться системное прерывание вообще OS_INTERRUPT void OS::SystemTimer_ISR() и Программа постоянно сидит в void OS::IdleProcessUserHook() {}, периодически реагируя на прерывание от другого таймера TC0.

Для верности объявил:
typedef OS::process<OS::pr0, 1000> TDBGUProc;
всё равно не работает.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 19 2008, 00:47
Сообщение #60


Гуру
******

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



Цитата(LessNik @ Jan 18 2008, 16:36) *
GBGU перестаёт работать и перестаёт вызываться системное прерывание вообще OS_INTERRUPT void OS::SystemTimer_ISR() и Программа постоянно сидит в void OS::IdleProcessUserHook() {}, периодически реагируя на прерывание от другого таймера TC0.
Очень похоже, что ваша программа некорректно (без записи в AIC_EOICR) завершает какое-то из прерываний. При этом перестают вызываться прерывания с таким же и более низкими приоритетами. На это косвенно указывет и то, что программа крутится в Idle,т.е. не вызывается и переключатель контекста. Возможно, в каком-то из прерываний вы забыли завести объект OS:TISRW, в деструкторе которого и выпоняется эта запись. Если какое-либо ваше прерывание не использет никакие сервисы ОС, то можно не заводить в нем объект OS:TISRW, но тогда вы должны сами в конце этого прерывания вручную прописать AIC_EOICR.

Вот такая версия. Надеюсь, что ОС в данном случае не виновата. Но если вы все же найдете в ней недоработку-обязательно сообщите. И даже если не в ОС дело-все равно отпишитесь здесь, интересно же wink.gif

Цитата(prottoss @ Dec 13 2007, 14:18) *
кстати, в ассемблер на IAR тоже можно включать C-шные хедеры, так что я думаю, что можно побороть эту проблему.
Увы, насколько я понял рассматривая заголовочные файлы компилятора, __HAS_RAMPZ__ определяется не в заголовочном файле (который подключен к OS_Target_asm.s90), а самим компилятором на основе указанного ему типа процессора. А вот в ассемблере аналогичное определение они почем-то не сделали sad.gif Выход есть - написать в начале файла свой большой #if defined (__ATMEGA128__) и определить в нем __HAS_RAMPZ__ для всех процессоров, в которых он есть.

Надо занести это в трекер, чтобы не забыть сделать к ближайшему релизу


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
LessNik
сообщение Jan 22 2008, 06:40
Сообщение #61


Частый гость
**

Группа: Свой
Сообщений: 107
Регистрация: 6-09-06
Из: Москва
Пользователь №: 20 118



Цитата(Сергей Борщ @ Jan 19 2008, 03:47) *
Очень похоже, что ваша программа некорректно (без записи в AIC_EOICR) завершает какое-то из прерываний. При этом перестают вызываться прерывания с таким же и более низкими приоритетами. На это косвенно указывет и то, что программа крутится в Idle,т.е. не вызывается и переключатель контекста. Возможно, в каком-то из прерываний вы забыли завести объект OS:TISRW, в деструкторе которого и выпоняется эта запись. Если какое-либо ваше прерывание не использет никакие сервисы ОС, то можно не заводить в нем объект OS:TISRW, но тогда вы должны сами в конце этого прерывания вручную прописать AIC_EOICR.


Получается, если я завожу объект OS:TISRW, то мне не нужно прописывать AIC_EOICR?
Я не нашел в деструкторе этого объекта записи в AIC_EOICR. Я обычно прописывал AT91C_BASE_AIC->AIC_EOICR = 0; И в примере тоже вручную прописывали:
Код
OS_INTERRUPT void Timer_ISR()
{
    OS::TISRW ISRW;
    volatile dword Tmp = AT91C_BASE_TCB->TCB_TC0.TC_SR;   // read to clear int flag

    AT91C_BASE_PIOA->PIO_SODR = (1 << 0);
    Timer_Ovf.SignalISR();

    AT91C_BASE_AIC->AIC_EOICR = 0;
}


Если не дописывать, то прерывание больше не вызывается

Попробовал так:
Код
OS_INTERRUPT void TimerCounter0Interrupt(void)
{
  OS::TISRW ISRW;
  volatile dword Tmp = AT91C_BASE_TCB->TCB_TC0.TC_SR;   // read to clear int flag

//    AT91C_BASE_AIC->AIC_EOICR = 0; без этой строчки не работает

}
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 22 2008, 08:05
Сообщение #62


Гуру
******

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



Цитата(LessNik @ Jan 22 2008, 08:40) *
Получается, если я завожу объект OS:TISRW, то мне не нужно прописывать AIC_EOICR?
Я не нашел в деструкторе этого объекта записи в AIC_EOICR.
Да, ошибся. Извините. Это в схеме 0 прописывать не надо - там это делается в ассемблерной "обертке". Надо будет и в схеме 1 ввести эту запись в деструктор, для однообразия


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
LessNik
сообщение Jan 31 2008, 10:24
Сообщение #63


Частый гость
**

Группа: Свой
Сообщений: 107
Регистрация: 6-09-06
Из: Москва
Пользователь №: 20 118



Цитата(Сергей Борщ @ Jan 19 2008, 03:47) *
Надеюсь, что ОС в данном случае не виновата. Но если вы все же найдете в ней недоработку-обязательно сообщите. И даже если не в ОС дело-все равно отпишитесь здесь, интересно же wink.gif


Нашёл!

При настройке AIC, нужно использовать не AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE, как было в примере, а AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL. Тогда всё работает стабильно:

Код
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL/*AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE*/ | AT91C_AIC_PRIOR_LOWEST + 1;
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 31 2008, 13:02
Сообщение #64


Гуру
******

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



Цитата(LessNik @ Jan 31 2008, 12:24) *
При настройке AIC, нужно использовать не AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE, как было в примере, а AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL. Тогда всё работает стабильно:
Угу. Действительно. В моем проекте, где используется DBGU тоже стоит AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL. Внесу изменения в примеры ОСи. Спасибо!
Интересно, кто-нибудь знает, зачем я там делал EDGE?

P.S. гляньте вот сюда: ветка на сахаре. Обнаружился баг в TEeventFlag, там идет обсуждение путей его ликвидации.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
spf
сообщение Feb 2 2008, 03:25
Сообщение #65


Странник
****

Группа: Свой
Сообщений: 766
Регистрация: 29-08-05
Из: Екатеринбург
Пользователь №: 8 051



Цитата(Сергей Борщ @ Jan 31 2008, 18:02) *
P.S. гляньте вот сюда: ветка на сахаре. Обнаружился баг в TEeventFlag, там идет обсуждение путей его ликвидации.

И туда: [АНОНС] Для централизованного общения по теме scmRTOS создана "группа Google"


--------------------
"Как много есть на свете вещей, которые мне не нужны!" Сократ
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Feb 3 2008, 10:33
Сообщение #66


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(spf @ Feb 2 2008, 05:25) *

Ошибка!
Невозможно найти удаленный сервер
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 3 2008, 10:47
Сообщение #67


Гуру
******

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



Цитата(IgorKossak @ Feb 3 2008, 13:33) *
Невозможно найти удаленный сервер

Вчера еще дышал, я даже письмишко написал.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 3 2008, 11:30
Сообщение #68


Гуру
******

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



Цитата(IgorKossak @ Feb 3 2008, 12:33) *
Ошибка!
Невозможно найти удаленный сервер
У меня провайдер в целях борьбы с порнухой режет и некоторые безобидные сайты (в том числе и groops.google.com). Вместо требуемой показывает страницу от IE "The page cannot be displayed". Возможно многие и верят, но я хожу из-под Оперы. Пойду к ним в понедельник пообщаюсь.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
spf
сообщение Feb 4 2008, 15:21
Сообщение #69


Странник
****

Группа: Свой
Сообщений: 766
Регистрация: 29-08-05
Из: Екатеринбург
Пользователь №: 8 051



Цитата(IgorKossak @ Feb 3 2008, 15:33) *
Невозможно найти удаленный сервер

Все работает, народ подтягивается.


--------------------
"Как много есть на свете вещей, которые мне не нужны!" Сократ
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Feb 5 2008, 06:11
Сообщение #70


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(spf @ Feb 4 2008, 17:21) *
Все работает, народ подтягивается.

По данной ссылке http://index.php/?showtopic=42800&hl= так и не могу зайти.
Ссылка правильная?

PS Нашёл правильную ссылку в соседней ветке.
Go to the top of the page
 
+Quote Post
spf
сообщение Feb 5 2008, 08:31
Сообщение #71


Странник
****

Группа: Свой
Сообщений: 766
Регистрация: 29-08-05
Из: Екатеринбург
Пользователь №: 8 051



Цитата(IgorKossak @ Feb 5 2008, 11:11) *
По данной ссылке http://index.php/?showtopic=42800&hl= так и не могу зайти.
Ссылка правильная?

ну... видимо что-то потерялось:
http://electronix.ru/forum/index.php?s=&am...st&p=359121


--------------------
"Как много есть на свете вещей, которые мне не нужны!" Сократ
Go to the top of the page
 
+Quote Post

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

 


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


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