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

 
 
4 страниц V  « < 2 3 4  
Reply to this topicStart new topic
> Возможность использования OS::channel в прерываниях
_Артём_
сообщение Sep 4 2013, 21:41
Сообщение #46


Гуру
******

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



Цитата(сарматъ @ Sep 4 2013, 23:26) *
я так и не понял, а функции типа push_isr() не нужны?и если не нужны то почему?


Не нужны.


Код
void OS::TChannel::push(uint8_t x)
{
    TCritSect cs;

    while (!Cbuf.get_free_size())
    {
        // channel is full, suspend current process
        suspend(ProducersProcessMap);
    }

////.....


В случае, если кончилось место для записи в фифо, процесс который пишет в буфер засыпает (channel is full, suspend current process). Если запись происходит в прерывании и место кончилось, то кого усыплять-то? Такая ситуация говорит о том что либо буфер мал, либо данные поступают слишком быстро, либо данные читаются слишком медленно.




Go to the top of the page
 
+Quote Post
сарматъ
сообщение Sep 5 2013, 05:39
Сообщение #47


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

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



там могло бы быть что либо такого плана

CODE
template<typename T, uint16_t Size, typename S>
void OS::channel<T, Size, S>::push_isr(const T& item)
{
  TCritSect cs;
if(pool.get_free_size_isr())
{
pool.push_back_isr(item);
resume_all_isr(ConsumersProcessMap);
}
}


Сообщение отредактировал сарматъ - Sep 5 2013, 05:41
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 5 2013, 06:10
Сообщение #48


Гуру
******

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



QUOTE (сарматъ @ Sep 5 2013, 07:39) *
там могло бы быть что либо такого плана
Всего предусмотреть невозможно. Но выход есть:
CODE
template<typename T, uint16_t Size, typename S = uint8_t>
class my_channel_with_isr : public channel<T, Size, S>
{
public:
      void push_isr(const T& item);
}


--------------------
На любой вопрос даю любой ответ
"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
сарматъ
сообщение Sep 5 2013, 06:24
Сообщение #49


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

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



да я уже подумал над этим правда придется не наследовать а копировать шаблон - чтоб в него поместить уже наследника от ring_buffer иначе внутри my_channel_with_isr будет два объекта типа ring_buffer, а если править непосредственно текст системы то совместимость пропадет(
Go to the top of the page
 
+Quote Post
dxp
сообщение Sep 5 2013, 07:21
Сообщение #50


Adept
******

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



QUOTE (сарматъ @ Sep 5 2013, 13:24) *
да я уже подумал над этим правда придется не наследовать а копировать шаблон - чтоб в него поместить уже наследника от ring_buffer иначе внутри my_channel_with_isr будет два объекта типа ring_buffer, а если править непосредственно текст системы то совместимость пропадет(

Почему два ring_buffer? Наследование не размножает потроха предка.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
сарматъ
сообщение Sep 5 2013, 07:37
Сообщение #51


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

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



потому что нужен вот такой вот пул и если я его добавляю в наследника канала то в нем о тпредка еще родной ring_buffer будет сидеть

CODE
namespace usr
{
template<typename T, uint16_t Size, typename S = uint8_t>
class ring_buffer_isr : public ring_buffer<T, Size, S>
{
public:
INLINE bool push_back_isr(const T item);
};
}


или я что то путаю? (повторюсь я очень не силен в плюсах)

ругается на инлайн(... а это эклипс ругается gcc скомпилировал

Сообщение отредактировал сарматъ - Sep 5 2013, 08:12
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 5 2013, 08:25
Сообщение #52


Гуру
******

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



QUOTE (сарматъ @ Sep 5 2013, 09:37) *
потому что нужен вот такой вот пул
Честно говоря, не понимаю - что вы пытаетесь создать. У нас есть класс канала, который вас устраивает всем, кроме отсутствия функции-члена посылки из прерывания. Я предложил вам создать новый класс, наследник канала в котором реализовать недостающую функцию. То есть все остальные функции канала, а также собственно буфер и прочие необходимые переменные используются от родителя и лишь недостающая добавлена в наследнике. Зачем тут начинать все заново с ring_buffer - совершенно непонятно.

QUOTE (сарматъ @ Sep 5 2013, 09:37) *
и если я его добавляю в наследника канала то в нем о тпредка еще родной ring_buffer будет сидеть
Опять же непонятно - зачем добавлять еще один ring_buffer в наследника? Надо использовать родительский. Или я снова не понял вопроса.


--------------------
На любой вопрос даю любой ответ
"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
сарматъ
сообщение Sep 5 2013, 08:33
Сообщение #53


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

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



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

то же самое и с буфером хочется чтобы вот эта функция push_back_isr была бы инлайновой

сделал пока так но без ковыряния исходников все равно не обошлось - в ринг буфере заменил секцию приват на протектед самую последнюю с переменными

CODE
/*
* classes_isr.h
*
* Created on: 05 сент. 2013 г.
*/

#ifndef CLASSES_ISR_H_
#define CLASSES_ISR_H_

#include "usrlib.h"

namespace usr
{
template<typename T, uint16_t Size, typename S = uint8_t>
class ring_buffer_isr : public ring_buffer<T, Size, S>
{
public:
INLINE bool push_back_isr(const T item);
INLINE S get_free_size_isr() const { return Size - this->Count; }
private:
INLINE void push_item_isr(const T item);
};
}
namespace OS
{
template<typename T, uint16_t Size, typename S = uint8_t>
class channel_isr : public TService
{
public:
INLINE channel_isr() : ProducersProcessMap(0)
, ConsumersProcessMap(0)
, pool()
{
}

//----------------------------------------------------------------
//
// Data transfer functions
//
void write(const T* data, const S cnt);
bool read (T* const data, const S cnt, timeout_t timeout = 0);

void push (const T& item);
INLINE void push_isr (const T& item);
void push_front(const T& item);

bool pop (T& item, timeout_t timeout = 0);
bool pop_back(T& item, timeout_t timeout = 0);


//----------------------------------------------------------------
//
// Service functions
//
INLINE S get_count() const { TCritSect cs; return pool.get_count(); }
INLINE S get_free_size() const { TCritSect cs; return pool.get_free_size(); }
void flush();

protected:
volatile TProcessMap ProducersProcessMap;
volatile TProcessMap ConsumersProcessMap;
usr::ring_buffer_isr<T, Size, S> pool;
};
}
template<typename T, uint16_t Size, typename S>
INLINE bool usr::ring_buffer_isr<T, Size, S>::push_back_isr(const T item){
if(this->Count == Size)
return false;

push_item_isr(item);
return true;
}
template<typename T, uint16_t Size, typename S>
INLINE void usr::ring_buffer_isr<T, Size, S>::push_item_isr(const T item){
this->Buf[this->Last] = item;
this->Last++;
this->Count++;

if(this->Last == Size)
this->Last = 0;

}

//------------------------------------------------------------------------------
template<typename T, uint16_t Size, typename S>
void OS::channel_isr<T, Size, S>::push(const T& item)
{
TCritSect cs;

while(!pool.get_free_size())
{
// channel is full, suspend current process until data removed
suspend(ProducersProcessMap);
}

pool.push_back(item);
resume_all(ConsumersProcessMap);
}
//------------------------------------------------------------------------------
template<typename T, uint16_t Size, typename S>
INLINE void OS::channel_isr<T, Size, S>::push_isr(const T& item)
{
TCritSect cs;

if(pool.get_free_size_isr())
{
pool.push_back_isr(item);
resume_all_isr(ConsumersProcessMap);
}

}
//------------------------------------------------------------------------------
template<typename T, uint16_t Size, typename S>
void OS::channel_isr<T, Size, S>::push_front(const T& item)
{
TCritSect cs;

while(!pool.get_free_size())
{
// channel is full, suspend current process until data removed
suspend(ProducersProcessMap);
}

pool.push_front(item);
resume_all(ConsumersProcessMap);

}
//------------------------------------------------------------------------------
template<typename T, uint16_t Size, typename S>
bool OS::channel_isr<T, Size, S>::pop(T& item, timeout_t timeout)
{
TCritSect cs;

if(pool.get_count())
{
item = pool.pop();
resume_all(ProducersProcessMap);
return true;
}
else
{
cur_proc_timeout() = timeout;

for(;;)
{
// channel is empty, suspend current process until data received or timeout
suspend(ConsumersProcessMap);
if(is_timeouted(ConsumersProcessMap))
return false;

if(pool.get_count())
{
cur_proc_timeout() = 0;
item = pool.pop();
resume_all(ProducersProcessMap);
return true;
}
// otherwise another process caught data
}
}
}
//------------------------------------------------------------------------------
template<typename T, uint16_t Size, typename S>
bool OS::channel_isr<T, Size, S>::pop_back(T& item, timeout_t timeout)
{
TCritSect cs;

if(pool.get_count())
{
item = pool.pop_back();
resume_all(ProducersProcessMap);
return true;
}
else
{
cur_proc_timeout() = timeout;

for(;;)
{
// channel is empty, suspend current process until data received or timeout
suspend(ConsumersProcessMap);
if(is_timeouted(ConsumersProcessMap))
return false;

if(pool.get_count())
{
cur_proc_timeout() = 0;
item = pool.pop_back();
resume_all(ProducersProcessMap);
return true;
}
// otherwise another process caught data
}
}
}
//------------------------------------------------------------------------------
template<typename T, uint16_t Size, typename S>
void OS::channel_isr<T, Size, S>::flush()
{
TCritSect cs;
pool.flush();
resume_all(ProducersProcessMap);
}
//------------------------------------------------------------------------------
template<typename T, uint16_t Size, typename S>
void OS::channel_isr<T, Size, S>::write(const T* data, const S count)
{
TCritSect cs;

while(pool.get_free_size() < count)
{
// channel does not have enough space, suspend current process until data removed
suspend(ProducersProcessMap);
}

pool.write(data, count);
resume_all(ConsumersProcessMap);

}
//------------------------------------------------------------------------------
template<typename T, uint16_t Size, typename S>
bool OS::channel_isr<T, Size, S>::read(T* const data, const S count, timeout_t timeout)
{
TCritSect cs;

cur_proc_timeout() = timeout;

while(pool.get_count() < count)
{
// channel doesn't contain enough data, suspend current process until data received or timeout
suspend(ConsumersProcessMap);
if(is_timeouted(ConsumersProcessMap))
return false;
}

cur_proc_timeout() = 0;
pool.read(data, count);
resume_all(ProducersProcessMap);

return true;
}
//------------------------------------------------------------------------------


#endif /* CLASSES_ISR_H_ */


работает примерно так же как и ивент если судить по количеству потерянных пакетов, теперь вопрос: если исходники все равно ковырял то лучше изменения все в них внести чтобы код не дублировать понапрасну?

Сообщение отредактировал сарматъ - Sep 5 2013, 12:26
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 6 2013, 08:29
Сообщение #54


Гуру
******

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



QUOTE (сарматъ @ Sep 5 2013, 10:33) *
сделал пока так но без ковыряния исходников все равно не обошлось - в ринг буфере заменил секцию приват на протектед самую последнюю с переменными
Боюсь, вы пошли несколько неправильным путем - вы в своем производном классе практически продублировали весь код функций родителя ради добавления INLINE. Я бы сделал новые inline - функции в родителе и в родителе же используя их же сделал бы не-inline версии:
CODE
template<typename T, uint16_t Size, typename S = uint8_t>
class ring_buffer
{
public:
ring_buffer() : Count(0), First(0), Last(0) { }

//----------------------------------------------------------------
//
// Data transfer functions
//
bool write(const T* data, const S cnt);
void read(T* const data, const S cnt);

INLINE bool push_back_inline(const T item);
INLINE bool push_front_inline(const T item);
bool push_back(const T item);
bool push_front(const T item);
......

template<typename T, uint16_t Size, typename S>
bool usr::ring_buffer<T, Size, S>::push_back_inline(const T item)
{
if(Count == Size)
return false;

push_item(item);
return true;
}

template<typename T, uint16_t Size, typename S>
bool usr::ring_buffer<T, Size, S>::push_back(const T item)
{
return push_back_inline(item);
}
Таким образом полностью исключил бы дублирование кода и получил возможность в наследниках использовать и inline и не-inline варианты. И это никак бы не повлияло на старые проекты - вот такое изменение вполне можно было бы внести в официальные исходники ОС.


--------------------
На любой вопрос даю любой ответ
"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
сарматъ
сообщение Sep 6 2013, 08:44
Сообщение #55


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

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



ок, так и сделаю и потом выложу сюда что получилось
собственно результат в прикрепленном файле

все равно наследника сделать не получилось - на что то ругается поэтому функцию push_isr_empty добавил в класс канала, она добавляет в пустой канал задачу внутри тела прерывания (в пустой - у меня то что вызывается из прерывания вызывается всегда когда в канал добавляется задача, поэтому дублировать задачи из прерывания смысла нет)

Сообщение отредактировал сарматъ - Sep 6 2013, 11:41
Прикрепленные файлы
Прикрепленный файл  usrlib.h.tar.gz ( 2.6 килобайт ) Кол-во скачиваний: 20
Прикрепленный файл  OS_Services.h.tar.gz ( 4.19 килобайт ) Кол-во скачиваний: 22
 
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd June 2025 - 20:00
Рейтинг@Mail.ru


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