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

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> Возможность использования OS::channel в прерываниях
AHTOXA
сообщение Jan 19 2013, 04:43
Сообщение #31


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



USART_ClearITPendingBit(this->PORT,USART_IT_TXE); - бессмысленная операция. (как я уже писал выше, этот флаг не сбрасывается программно, он read-only).
USART_ClearITPendingBit(this->PORT,USART_IT_RXNE); - лучше перенести в ветку else.
Ну а вообще, OS::channel делает всё то же самое, так что это в некотором роде "закат солнца вручную":)
Цитата(abutorin @ Jan 19 2013, 00:52) *
канал больше предназначен для межпроцессного взаимодействия а не между процессом и прерыванием.

Можете обосновать это утверждение?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
abutorin
сообщение Jan 19 2013, 17:19
Сообщение #32


Участник
*

Группа: Участник
Сообщений: 40
Регистрация: 3-09-12
Пользователь №: 73 374



Цитата(AHTOXA @ Jan 19 2013, 08:43) *
USART_ClearITPendingBit(this->PORT,USART_IT_TXE); - бессмысленная операция. (как я уже писал выше, этот флаг не сбрасывается программно, он read-only).

Возможно, сейчас так сделал для однообразия и нехотелось разбиратся какой флаг сам сбрасывается, а какой нет.

Цитата(AHTOXA @ Jan 19 2013, 08:43) *
USART_ClearITPendingBit(this->PORT,USART_IT_RXNE); - лучше перенести в ветку else.

В какую ветку? Очистка флага нужно всегда когда прерываниеуже обработано.
Цитата(AHTOXA @ Jan 19 2013, 08:43) *
Ну а вообще, OS::channel делает всё то же самое, так что это в некотором роде "закат солнца вручную":)

Можете обосновать это утверждение?


У OS::channel есть дополнительные члены для хранения списка производителей и потребителей, у него более крупная процедура получения первого элемента. Это все годится для межпроцессного взаимодействия, в моем случае все проще и статичнее.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jan 19 2013, 17:42
Сообщение #33


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(abutorin @ Jan 19 2013, 23:19) *
В какую ветку? Очистка флага нужно всегда когда прерываниеуже обработано.

Код
            if (this->RxPool.get_free_size())
            {
                this->RxPool.push(USART_ReceiveData(this->PORT)); //  в этой ветке флаг сбрасывается вот этой строчкой
                this->RxNotEmpty.signal_isr();
            }
            else
            {
                //здесь должна быть обработка переполнения буфера
                USART_ClearITPendingBit(this->PORT,USART_IT_RXNE);  // << вот сюда
            }
            // USART_ClearITPendingBit(this->PORT,USART_IT_RXNE); // << отсюда.

Всё же почитайте документацию, использование библиотек не отменяет необходимости её читать. Тогда всё будет работать как надо.
Цитата(abutorin @ Jan 19 2013, 23:19) *
У OS::channel есть дополнительные члены для хранения списка производителей и потребителей, у него более крупная процедура получения первого элемента. Это все годится для межпроцессного взаимодействия, в моем случае все проще и статичнее.

Взамен этих членов вы завели пару штук OS::TEventFlag (TxNotFull, RxNotEmpty). Это явно тяжелее. С остальным тоже не согласен. Но это, конечно, дело вкуса.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
abutorin
сообщение Jan 19 2013, 17:56
Сообщение #34


Участник
*

Группа: Участник
Сообщений: 40
Регистрация: 3-09-12
Пользователь №: 73 374



Цитата(AHTOXA @ Jan 19 2013, 21:42) *
Код
            if (this->RxPool.get_free_size())
            {
                this->RxPool.push(USART_ReceiveData(this->PORT)); //  в этой ветке флаг сбрасывается вот этой строчкой
                this->RxNotEmpty.signal_isr();
            }
            else
            {
                //здесь должна быть обработка переполнения буфера
                USART_ClearITPendingBit(this->PORT,USART_IT_RXNE);  // << вот сюда
            }
            // USART_ClearITPendingBit(this->PORT,USART_IT_RXNE); // << отсюда.

Всё же почитайте документацию, использование библиотек не отменяет необходимости её читать. Тогда всё будет работать как надо.

Взамен этих членов вы завели пару штук OS::TEventFlag (TxNotFull, RxNotEmpty). Это явно тяжелее. С остальным тоже не согласен. Но это, конечно, дело вкуса.

В случае использования OS::channel в какой момент будет вызыватся перепланировка процессов?
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jan 19 2013, 18:13
Сообщение #35


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(abutorin @ Jan 19 2013, 19:56) *
В случае использования OS::channel в какой момент будет вызыватся перепланировка процессов?

Если речь о прерываниях, то перепланировка вызовется в ISR_Exit в любом случае.
Go to the top of the page
 
+Quote Post
abutorin
сообщение Jan 19 2013, 18:42
Сообщение #36


Участник
*

Группа: Участник
Сообщений: 40
Регистрация: 3-09-12
Пользователь №: 73 374



Цитата(AHTOXA @ Jan 19 2013, 21:42) *
Код
            if (this->RxPool.get_free_size())
            {
                this->RxPool.push(USART_ReceiveData(this->PORT)); //  в этой ветке флаг сбрасывается вот этой строчкой
                this->RxNotEmpty.signal_isr();
            }
            else
            {
                //здесь должна быть обработка переполнения буфера
                USART_ClearITPendingBit(this->PORT,USART_IT_RXNE);  // << вот сюда
            }
            // USART_ClearITPendingBit(this->PORT,USART_IT_RXNE); // << отсюда.

Всё же почитайте документацию, использование библиотек не отменяет необходимости её читать. Тогда всё будет работать как надо.

Взамен этих членов вы завели пару штук OS::TEventFlag (TxNotFull, RxNotEmpty). Это явно тяжелее. С остальным тоже не согласен. Но это, конечно, дело вкуса.

Решил последовать вашим рекомендациям и проверить оба варианта, свой и с использовапние канала

Код
template <typename _Tp,typename BufSizeType,BufSizeType TxbufSize,BufSizeType RxbufSize>
class usart
{
private:
    OS::channel<_Tp, TxbufSize, BufSizeType> TxPool;
    OS::channel<_Tp, RxbufSize, BufSizeType> RxPool;

    bool RxBufferOverflow;

public:

    USART_TypeDef * PORT;

    INLINE bool overflow ()
    {
        return RxBufferOverflow;
    }

    bool open (bool)
    {
        USART_ITConfig(PORT, USART_IT_RXNE, ENABLE);
        return true;
    }

    INLINE void it_handler ()
    {
        OS::TISRW ISRW;

        if (USART_GetITStatus(PORT,USART_IT_TXE) != RESET)
        {
            if(TxPool.get_count())
            {
                _Tp data;
                TxPool.pop(data);
                USART_SendData(PORT,data);
            }
            else
            {
                USART_ITConfig(PORT, USART_IT_TXE, DISABLE);
            }
        }

        if (USART_GetITStatus(PORT,USART_IT_RXNE) != RESET)
        {
            if (RxPool.get_free_size())
            {
                RxPool.push(USART_ReceiveData(PORT));
            }
            else
            {
                RxBufferOverflow = true;
                USART_ClearITPendingBit(PORT,USART_IT_RXNE);
            }
        }

    }

    void send(const _Tp & data)
    {
        TxPool.push(data);
        USART_ITConfig(PORT, USART_IT_TXE, ENABLE);
    }

    _Tp get ()
    {
        _Tp data;
        RxPool.pop(data);
        return data;
    }
};

Из того что не делал ранее это добавил в обработчик прерывания OS::TISRW. С таким кодом передача работает нормально, а вот при попытке принять данные камень зависает. Сразу должен заметить что размер кода увеличился на 176 байт. Размер занимаемой RAMна 4 байта.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jan 19 2013, 19:12
Сообщение #37


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(abutorin @ Jan 20 2013, 00:42) *
С таким кодом передача работает нормально, а вот при попытке принять данные камень зависает.

У меня такой вариант работает нормально. Наверное какая-то мелочь осталась незамеченной. Например, забыли включить приёмsm.gif
Цитата(abutorin @ Jan 20 2013, 00:42) *
Сразу должен заметить что размер кода увеличился на 176 байт. Размер занимаемой RAMна 4 байта.

Ну, это мелочиsm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
abutorin
сообщение Jan 19 2013, 19:19
Сообщение #38


Участник
*

Группа: Участник
Сообщений: 40
Регистрация: 3-09-12
Пользователь №: 73 374



Цитата(AHTOXA @ Jan 19 2013, 23:12) *
У меня такой вариант работает нормально. Наверное какая-то мелочь осталась незамеченной. Например, забыли включить приёмsm.gif

Весь остальной код остался неизменный. Менял только код данного класса. Идея использовать готовый код для решения своих задач мне всгда нравится, я потому и поднял эту тему. После того как не смог с вашей помощью решить поставленную задачу попробовал сделать свой вариант. В результате оказалось что мой вариант получается несколько компактнее. Для законченности все же остается понять почему не работает.
Вы какого размера пакеты отправляет и посылает? Я в свое время заметил что такой код работает нормально если посылаешь и принимаешь пакет меньше чем размер буфера то проблем нет. А вот как только объем больше то и происходят зависания.

Сообщение отредактировал abutorin - Jan 19 2013, 19:25
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jan 19 2013, 19:36
Сообщение #39


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Насчёт компактности - думаю, что случайно так вышло. По ОЗУ должен быть паритет (У каждого EventFlag есть TProcessMap и TValue, а у каждого channel - два TProcessMap). А по коду - если вы будете использовать channel где-то ещё (а вероятность этого ~100%), то этот код всё равно добавится.
С другой стороны, код у channel проверенный в плане межпроцессного взаимодействия (моменты запрещения прерываний, ожидание, и проч.). А с самодельным вариантом может всплыть что-то.
Почему не работает - неясно. Вы как-то не совсем внятно объясняете, что именно не работает. Приём одного байта - работает?
Тот код, который вы показали, содержит только функции записи/чтения одного символа. А вы пишете, что зависает при приёме блока.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
abutorin
сообщение Jan 19 2013, 20:01
Сообщение #40


Участник
*

Группа: Участник
Сообщений: 40
Регистрация: 3-09-12
Пользователь №: 73 374



Цитата(AHTOXA @ Jan 19 2013, 23:36) *
А по коду - если вы будете использовать channel где-то ещё (а вероятность этого ~100%), то этот код всё равно добавится.

Если параметры шаблано отличаются, то код начинает дублироватся. Так что тут код всегда будет больше.

Цитата(AHTOXA @ Jan 19 2013, 23:36) *
С другой стороны, код у channel проверенный в плане межпроцессного взаимодействия (моменты запрещения прерываний, ожидание, и проч.). А с самодельным вариантом может всплыть что-то.

Неверное использование проверенного кода тоже может вызвать проблемы.

Цитата(AHTOXA @ Jan 19 2013, 23:36) *
Почему не работает - неясно. Вы как-то не совсем внятно объясняете, что именно не работает.

Есть некий проект (кода много чтобы выкладывать), пробую использовать оба варианта класса который описывал. Еще раз повторю, для чисторы эксперимента меняю только код данного класса, все остальное остается прежним. Так вот при использовании канала похоже чтокамень на чемто зависает, сказать где не могу, знаю только что процесс с наивысшим приоритетом перестает работать.
Цитата(AHTOXA @ Jan 19 2013, 23:36) *
Приём одного байта - работает?

По одному байту не использую.

Цитата(AHTOXA @ Jan 19 2013, 23:36) *
Тот код, который вы показали, содержит только функции записи/чтения одного символа. А вы пишете, что зависает при приёме блока.


Блок передаю в цикле по одному байту.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jan 19 2013, 20:21
Сообщение #41


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(abutorin @ Jan 20 2013, 02:01) *
Если параметры шаблано отличаются, то код начинает дублироватся. Так что тут код всегда будет больше.

А если не отличаются, то не начнёт. Значит - не всегдаsm.gif
Ну да ладно, в любом случае мне плевать на такой прирост кода.
Цитата(abutorin @ Jan 20 2013, 02:01) *
Неверное использование проверенного кода тоже может вызвать проблемы.

Поэтому я и заинтересовался. Если есть проблемы с использованием OS::channel в прерываниях, то я очень хочу знать про них.
Цитата(abutorin @ Jan 20 2013, 02:01) *
Так вот при использовании канала похоже чтокамень на чемто зависает, сказать где не могу, знаю только что процесс с наивысшим приоритетом перестает работать.

А увеличение размера буфера больше размера максимального пакета избавляет от зависаний?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
abutorin
сообщение Jan 19 2013, 20:42
Сообщение #42


Участник
*

Группа: Участник
Сообщений: 40
Регистрация: 3-09-12
Пользователь №: 73 374



Цитата(AHTOXA @ Jan 20 2013, 00:21) *
А увеличение размера буфера больше размера максимального пакета избавляет от зависаний?

Да.
Я писал про это на второй странице помоему.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jan 20 2013, 05:31
Сообщение #43


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Ну, с тех пор что-то же поменялось. Так что это было неочевидно.
В общем, я не знаю, чем помочь. Может быть вы сделаете минимальный проект, где проблема проявляется, и выложите его?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
abutorin
сообщение Jan 20 2013, 05:57
Сообщение #44


Участник
*

Группа: Участник
Сообщений: 40
Регистрация: 3-09-12
Пользователь №: 73 374



Цитата(AHTOXA @ Jan 20 2013, 09:31) *
В общем, я не знаю, чем помочь. Может быть вы сделаете минимальный проект, где проблема проявляется, и выложите его?

Тогда пока предлагаю отложить этот вопрос.
Резюме по теме можно сделать такое:
По мнению разработчиков OS:channel можно использовать в прерываниях с некоторыми замечаниями "обязательна проверка на наличие свободного места или данных для для получения из него".
Лично у меня использовать его не получилось по неустановленным причинам. На мой субъективный взгляд использование OS:channel является более накладным (по размеру кода) чем использование собсвтенного кольцевого буфера (из библиотеки usrlib) и двух OS::TEventFlag.

PS. забыл как на форуме можно подправить название темы, чтобы вписать в нее "решено"

Сообщение отредактировал abutorin - Jan 20 2013, 06:39
Go to the top of the page
 
+Quote Post
сарматъ
сообщение Sep 4 2013, 20:26
Сообщение #45


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

Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463



я так и не понял, а функции типа push_isr() не нужны?и если не нужны то почему?
Go to the top of the page
 
+Quote Post

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

 


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


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