|
|
 |
Ответов
|
Jan 18 2013, 18:52
|
Участник

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

|
Как обещал ранее выкладываю код который у меня работает. Код class usart_transport { private: usr::ring_buffer<uint8_t, 30, uint8_t> TxPool; usr::ring_buffer<uint8_t, 30, uint8_t> RxPool;
OS::TEventFlag TxNotFull; OS::TEventFlag RxNotEmpty;
public:
USART_TypeDef * PORT;
bool open (bool) { USART_ITConfig(this->PORT, USART_IT_RXNE, ENABLE); return true; }
INLINE void it_handler () { if (USART_GetITStatus(this->PORT,USART_IT_TXE) != RESET) { if(this->TxPool.get_count()) { USART_SendData(this->PORT,this->TxPool.pop()); this->TxNotFull.signal_isr(); } else { USART_ITConfig(this->PORT, USART_IT_TXE, DISABLE); } USART_ClearITPendingBit(this->PORT,USART_IT_TXE); }
if (USART_GetITStatus(this->PORT,USART_IT_RXNE) != RESET) { 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); }
}
INLINE bool full () { TCritSect cs;
return !this->TxPool.get_free_size();
} INLINE bool empty () { TCritSect cs;
return !this->RxPool.get_count(); }
void send(const uint8_t & data) { this->TxNotFull.clear();
while (this->full()) { this->TxNotFull.wait(); }
{ TCritSect cs; this->TxPool.push(data); }
USART_ITConfig(this->PORT, USART_IT_TXE, ENABLE); }
uint8_t get () { this->RxNotEmpty.clear();
while (this->empty()) { this->RxNotEmpty.wait(); }
TCritSect cs;
return this->RxPool.pop(); } }; Отказ от канала в результате вызван тем, что канал больше предназначен для межпроцессного взаимодействия а не между процессом и прерыванием. Инициализацию порта необходимо выполнять самостоятельно. Сразу хочу заметить что данная реализация сделана на коленке и имеет достаточный потенциал для улучшения, сразу видно что целесообразно сделать данный класс через шаблон со статичными членами, с указанием порта как параметра и использовать данные методы без создания экземпляра класса.
|
|
|
|
|
Jan 19 2013, 04:43
|

фанат дивана
     
Группа: Свой
Сообщений: 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)  канал больше предназначен для межпроцессного взаимодействия а не между процессом и прерыванием. Можете обосновать это утверждение?
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jan 19 2013, 17:19
|
Участник

Группа: Участник
Сообщений: 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 есть дополнительные члены для хранения списка производителей и потребителей, у него более крупная процедура получения первого элемента. Это все годится для межпроцессного взаимодействия, в моем случае все проще и статичнее.
|
|
|
|
|
Jan 19 2013, 17:42
|

фанат дивана
     
Группа: Свой
Сообщений: 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). Это явно тяжелее. С остальным тоже не согласен. Но это, конечно, дело вкуса.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jan 19 2013, 18:42
|
Участник

Группа: Участник
Сообщений: 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 байта.
|
|
|
|
|
Jan 19 2013, 19:19
|
Участник

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

|
Цитата(AHTOXA @ Jan 19 2013, 23:12)  У меня такой вариант работает нормально. Наверное какая-то мелочь осталась незамеченной. Например, забыли включить приём  Весь остальной код остался неизменный. Менял только код данного класса. Идея использовать готовый код для решения своих задач мне всгда нравится, я потому и поднял эту тему. После того как не смог с вашей помощью решить поставленную задачу попробовал сделать свой вариант. В результате оказалось что мой вариант получается несколько компактнее. Для законченности все же остается понять почему не работает. Вы какого размера пакеты отправляет и посылает? Я в свое время заметил что такой код работает нормально если посылаешь и принимаешь пакет меньше чем размер буфера то проблем нет. А вот как только объем больше то и происходят зависания.
Сообщение отредактировал abutorin - Jan 19 2013, 19:25
|
|
|
|
|
Jan 19 2013, 19:36
|

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

|
Насчёт компактности - думаю, что случайно так вышло. По ОЗУ должен быть паритет (У каждого EventFlag есть TProcessMap и TValue, а у каждого channel - два TProcessMap). А по коду - если вы будете использовать channel где-то ещё (а вероятность этого ~100%), то этот код всё равно добавится. С другой стороны, код у channel проверенный в плане межпроцессного взаимодействия (моменты запрещения прерываний, ожидание, и проч.). А с самодельным вариантом может всплыть что-то. Почему не работает - неясно. Вы как-то не совсем внятно объясняете, что именно не работает. Приём одного байта - работает? Тот код, который вы показали, содержит только функции записи/чтения одного символа. А вы пишете, что зависает при приёме блока.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
Сообщений в этой теме
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 Цитата(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, 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 5 2013, 08:33 Сергей Борщ QUOTE (сарматъ @ Sep 5 2013, 10:33) сдела... Sep 6 2013, 08:29 сарматъ ок, так и сделаю и потом выложу сюда что получилос... Sep 6 2013, 08:44
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|