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

 
 
5 страниц V  « < 2 3 4 5 >  
Reply to this topicStart new topic
> scmRTOS. Вопросы и ответы.
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

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

 


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


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