|
|
 |
Ответов
|
Sep 5 2013, 08:33
|
Частый гость
 
Группа: Участник
Сообщений: 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
|
|
|
|
|
Sep 6 2013, 08:29
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
Сообщений в этой теме
abutorin Возможность использования OS::channel в прерываниях Jan 13 2013, 19:25 AHTOXA Использовать канал в прерывании можно. Учтите толь... Jan 13 2013, 20:45 abutorin Спасибо, проверку заполнености, проверку пустоты я... Jan 14 2013, 02:40 abutorin Цитата(AHTOXA @ Jan 14 2013, 00:45) Испол... Jan 15 2013, 19:16  _Артём_ Не знаю почему зависает, наверное что-то неправиль... Jan 15 2013, 19:26   abutorin Цитата(_Артём_ @ Jan 15 2013, 23:26) Не з... Jan 15 2013, 19:31    _Артём_ Цитата(abutorin @ Jan 15 2013, 21:31) Объ... Jan 15 2013, 20:10    Сергей Борщ QUOTE (abutorin @ Jan 15 2013, 21:31) Суд... Jan 15 2013, 22:46     abutorin Цитата(Сергей Борщ @ Jan 16 2013, 02:46) ... Jan 16 2013, 03:29      _Артём_ Цитата(abutorin @ Jan 16 2013, 05:29) А в... Jan 16 2013, 04:45       AHTOXA TXE очищается записью в DR. Вручную его чистить не... Jan 16 2013, 05:05      Сергей Борщ QUOTE (abutorin @ Jan 16 2013, 05:29) USA... Jan 16 2013, 08:54       AHTOXA Цитата(Сергей Борщ @ Jan 16 2013, 14:54) ... Jan 16 2013, 10:18        Сергей Борщ QUOTE (AHTOXA @ Jan 16 2013, 12:18) А это... Jan 16 2013, 11:27         AHTOXA Цитата(Сергей Борщ @ Jan 16 2013, 17:27) ... Jan 16 2013, 13:52       abutorin Цитата(Сергей Борщ @ Jan 16 2013, 12:54) ... Jan 16 2013, 11:33        Сергей Борщ QUOTE (abutorin @ Jan 16 2013, 13:33) Есл... Jan 17 2013, 10:15         abutorin Цитата(Сергей Борщ @ Jan 17 2013, 14:15) ... Jan 17 2013, 12:25          Сергей Борщ QUOTE (abutorin @ Jan 17 2013, 14:25) Пло... Jan 17 2013, 13:12           abutorin Цитата(Сергей Борщ @ Jan 17 2013, 17:12) ... Jan 17 2013, 13:20            AHTOXA Насчёт работы с UART по DMA вот вам три темы:
раз... Jan 17 2013, 18:31             abutorin Цитата(AHTOXA @ Jan 17 2013, 22:31) Насчё... Jan 18 2013, 05:37              Сергей Борщ QUOTE (abutorin @ Jan 18 2013, 07:37) Спа... Jan 18 2013, 07:41               abutorin Цитата(Сергей Борщ @ Jan 18 2013, 11:41) ... Jan 18 2013, 09:14 Vasya777 Мне кажется для обмена по интерфейсам связи лучше ... Jan 15 2013, 15:07 abutorin Проблему решил использовав События:
Кодclass usart... Jan 15 2013, 20:14 _Артём_ Цитата(abutorin @ Jan 15 2013, 22:14) есл... Jan 15 2013, 20:20  abutorin Цитата(_Артём_ @ Jan 16 2013, 00:20) На ч... Jan 15 2013, 20:24   _Артём_ Цитата(abutorin @ Jan 15 2013, 22:24) Вто... Jan 15 2013, 20:52 abutorin Как обещал ранее выкладываю код который у меня раб... Jan 18 2013, 18:52 AHTOXA USART_ClearITPendingBit(this->PORT,USART_IT_TXE... Jan 19 2013, 04:43  abutorin Цитата(AHTOXA @ Jan 19 2013, 08:43) USART... Jan 19 2013, 17:19   AHTOXA Цитата(abutorin @ Jan 19 2013, 23:19) В к... Jan 19 2013, 17:42    abutorin Цитата(AHTOXA @ Jan 19 2013, 21:42) Код ... Jan 19 2013, 17:56     _Артём_ Цитата(abutorin @ Jan 19 2013, 19:56) В с... Jan 19 2013, 18:13    abutorin Цитата(AHTOXA @ Jan 19 2013, 21:42) Код ... Jan 19 2013, 18:42     AHTOXA Цитата(abutorin @ Jan 20 2013, 00:42) С т... Jan 19 2013, 19:12      abutorin Цитата(AHTOXA @ Jan 19 2013, 23:12) У мен... Jan 19 2013, 19:19       AHTOXA Насчёт компактности - думаю, что случайно так вышл... Jan 19 2013, 19:36        abutorin Цитата(AHTOXA @ Jan 19 2013, 23:36) А по ... Jan 19 2013, 20:01         AHTOXA Цитата(abutorin @ Jan 20 2013, 02:01) Есл... Jan 19 2013, 20:21          abutorin Цитата(AHTOXA @ Jan 20 2013, 00:21) А уве... Jan 19 2013, 20:42           AHTOXA Ну, с тех пор что-то же поменялось. Так что это бы... Jan 20 2013, 05:31            abutorin Цитата(AHTOXA @ Jan 20 2013, 09:31) В общ... Jan 20 2013, 05:57 сарматъ я так и не понял, а функции типа push_isr() не нуж... Sep 4 2013, 20:26 _Артём_ Цитата(сарматъ @ Sep 4 2013, 23:26) я так... Sep 4 2013, 21:41  сарматъ там могло бы быть что либо такого плана
CODEtempl... Sep 5 2013, 05:39   Сергей Борщ QUOTE (сарматъ @ Sep 5 2013, 07:39) там м... Sep 5 2013, 06:10 сарматъ да я уже подумал над этим правда придется не насле... Sep 5 2013, 06:24 dxp QUOTE (сарматъ @ Sep 5 2013, 13:24) да я ... Sep 5 2013, 07:21  сарматъ потому что нужен вот такой вот пул и если я его до... Sep 5 2013, 07:37   Сергей Борщ QUOTE (сарматъ @ Sep 5 2013, 09:37) потом... Sep 5 2013, 08:25 сарматъ ок, так и сделаю и потом выложу сюда что получилос... Sep 6 2013, 08:44
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|