|
|
  |
scmRTOS. Вопросы и ответы. |
|
|
|
Dec 9 2007, 09:43
|

Гуру
     
Группа: Свой
Сообщений: 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 ... */
--------------------
|
|
|
|
|
Dec 13 2007, 12:18
|

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

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

|
С 1 - понятно, хотел просто уточнить. Цитата(jorikdima @ Dec 27 2007, 12:32)  2. За блокировкой идет то, что вы напишете, а не захват ресурса. И если вы проверите результат TMutex::LockSoftly() на правду/ложь и будете захватывать ресурс только в случае true, то все будет в порядке. Mutex-ом как-раз блокируют используемый ресурс, просто-так блокировку вызывать бессмысленно, так-что за блокировкой всегда идёт именно работа с ресурсом. TMutex::LockSoftly() - не возвращает значение, она "мягко" блокирует. Вот как именно "мягко" я и хочу понять
|
|
|
|
|
Dec 27 2007, 13:24
|

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, то семафор уже был захвачен другим процессом, тут его захватить не удалось, работать с ресурсом нельзя - можно заняться чем-то другим.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Dec 27 2007, 13:27
|

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

|
В том изаключается мягкость, что если ресурс уже заблокирован, то программисту дается возможность не ждать в спячке разблокировки, а поделоть что либо другое, естественно без использования упомянутого ресурса, ибо он занят. Чтобы дать разработчику понять захватился ли мютекс мягко или нет и придумано возвращения значения функции LockSoftly(). Если правда, то все хорошо, ресурс залочен - пользуйтесь. А если ложь, то сообщается, что ресурс занят можешь делать что либо другое. Если вам не нужна такая функциональность, то пользуйтесь Lock(). За блокировкой действительно всегда идет работа с ресурсом. Но я имел в виду, что по проверки условия возвращаемого значения можно и не идти на работу с ресурсом, а пойти по другим делам, если таковые имеются.
|
|
|
|
|
Jan 17 2008, 07:35
|

Частый гость
 
Группа: Свой
Сообщений: 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
|
|
|
|
|
Jan 17 2008, 08:59
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Jan 17 2008, 13:07
|

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

|
Всё заработало. Пока ещё не смог сломать Цитата(Сергей Борщ @ Jan 17 2008, 11:59)  А что вы хотели получить записью AT91C_BASE_AIC->AIC_IVR = 1; // ? мне совсем непонятно. Это скопировал из другого проекта. Использовал при отладке. Предварительно перешел в Protect Mode. Но в этом проекте не использую Protect Mode. Надо удалить будет
|
|
|
|
|
Jan 18 2008, 07:07
|

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

|
Цитата Посмотрел, как в OS_Target_cpp.cpp сделан обработчик прерывания - там баг, который я исправил в своем проекте, но не перенес исправление в репозиторий. В вашем коде SystemTimerUserHook(); вызывается только если прерывание пришло от таймера. Надо сделать такое изменнение: ... Может там ещё нужно где-то поправить? У меня периодически отваливаются прерывания от системного таймера при большой активности DBGU. Программа постоянно сидит в void OS::IdleProcessUserHook() {} Если не трудно, можно выложить обновление здесь?
|
|
|
|
|
Jan 18 2008, 09:19
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Jan 18 2008, 14:36
|

Частый гость
 
Группа: Свой
Сообщений: 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=105GBGU перестаёт работать и перестаёт вызываться системное прерывание вообще OS_INTERRUPT void OS::SystemTimer_ISR() и Программа постоянно сидит в void OS::IdleProcessUserHook() {}, периодически реагируя на прерывание от другого таймера TC0. Для верности объявил: typedef OS::process<OS::pr0, 1000> TDBGUProc; всё равно не работает.
|
|
|
|
|
Jan 19 2008, 00:47
|

Гуру
     
Группа: Модераторы
Сообщений: 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. Вот такая версия. Надеюсь, что ОС в данном случае не виновата. Но если вы все же найдете в ней недоработку-обязательно сообщите. И даже если не в ОС дело-все равно отпишитесь здесь, интересно же  Цитата(prottoss @ Dec 13 2007, 14:18)  кстати, в ассемблер на IAR тоже можно включать C-шные хедеры, так что я думаю, что можно побороть эту проблему. Увы, насколько я понял рассматривая заголовочные файлы компилятора, __HAS_RAMPZ__ определяется не в заголовочном файле (который подключен к OS_Target_asm.s90), а самим компилятором на основе указанного ему типа процессора. А вот в ассемблере аналогичное определение они почем-то не сделали  Выход есть - написать в начале файла свой большой #if defined (__ATMEGA128__) и определить в нем __HAS_RAMPZ__ для всех процессоров, в которых он есть. Надо занести это в трекер, чтобы не забыть сделать к ближайшему релизу
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|