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

 
 
> Interlocked Exchange, проблема с массивом данных
Mikron
сообщение Oct 29 2015, 12:53
Сообщение #1


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

Группа: Участник
Сообщений: 82
Регистрация: 1-03-10
Пользователь №: 55 731



Первый раз столкнулся с такой проблемой.
stm32f407
В прерываниях по usart заполняю массив данными. Данных всегда одинаковое количество. Когда принимаю последний байт, выставляю флаг и данные разбираю в общем цикле.

Код
        if(cnt<MAX_STRLEN){
            received_string[cnt-1] = t;
        }
        else if(cnt == MAX_STRLEN){
            received_string[cnt-1] = t;
            cnt = 0;
            flag_p = 1;
        }

Но прерывание может возникнуть снова в тот момент, когда я еще не успел разобрать данные, соответственно они могут испортиться.
Вопрос, как выйти из этой ситуации? Есть ли какие-нибудь атомарные операции, чтобы данные не бились. Спасибо
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 8)
AHTOXA
сообщение Oct 29 2015, 13:14
Сообщение #2


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

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



Заведите два массива, и заполняйте их по очереди.
Заполнили один - переключили указатель записи на другой, записали в спец. переменную номер готового массива, и только после этого взводите флаг.

Ну или обрабатывайте массив быстрее, чем скорость приёма символаsm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Mikron
сообщение Oct 29 2015, 13:23
Сообщение #3


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

Группа: Участник
Сообщений: 82
Регистрация: 1-03-10
Пользователь №: 55 731



а если я заполню второй массив раньше чем обработаю данные в первом? Отключать прерывния? тогда данные будут теряться.

Обрабатываю я вроде быстро, но туплю либо я либо мк) Хотелось бы вообще исключить даже теоретическую возможность побитых данных
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 29 2015, 13:53
Сообщение #4


Гуру
******

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



Цитата(Mikron @ Oct 29 2015, 16:23) *
Хотелось бы вообще исключить даже теоретическую возможность побитых данных
Тогда заведите бесконечно большой кольцевой буфер, пусть прерывание УСАПП складывает принятые данные в него, а процедура обработки вынимает из него и обрабатывает. Чем больше размер буфера, тем дольше можно задумываться над некоторыми пакетами.


--------------------
На любой вопрос даю любой ответ
"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
Herz
сообщение Oct 29 2015, 14:25
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 10 983
Регистрация: 23-11-05
Пользователь №: 11 287



Цитата(Сергей Борщ @ Oct 29 2015, 15:53) *
Тогда заведите бесконечно большой кольцевой буфер, пусть прерывание УСАПП складывает принятые данные в него, а процедура обработки вынимает из него и обрабатывает. Чем больше размер буфера, тем дольше можно задумываться над некоторыми пакетами.

Не понимаю, как такое может быть. Если скорость обработки ниже, чем скорость заполнения буфера, то каким бы огромным он ни был, рано или поздно заполнится. Кроме, конечно, предельного случая - именно бесконечно большого буфера. Можно даже не кольцевого...
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Oct 29 2015, 14:45
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Нужен кольцевой буфер размером = время тупления / время передачи байта.
Go to the top of the page
 
+Quote Post
smalcom
сообщение Oct 29 2015, 17:48
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 292
Регистрация: 26-06-07
Пользователь №: 28 718



вот тутачки
http://electronix.ru/forum/index.php?showtopic=130807
про буфера написали
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 29 2015, 18:13
Сообщение #8


Гуру
******

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



Цитата(Herz @ Oct 29 2015, 17:25) *
Если скорость обработки ниже, чем скорость заполнения буфера, то каким бы огромным он ни был, рано или поздно заполнится.
Разумеется. Поэтому я написал, что тормозить можно на некоторых пакетах. А абсолютную гарантию даст только бесконечно большой буфер.


--------------------
На любой вопрос даю любой ответ
"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
Dog Pawlowa
сообщение Oct 30 2015, 04:54
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(Mikron @ Oct 29 2015, 15:53) *
Вопрос, как выйти из этой ситуации? Есть какие-нибудь атомарные операции, чтобы данные не бились. Спасибо

Самый простой способ выйти из ситуации - не заходить в нее (КО)
В данном случае - протоколом обмена информацией должен быть предусмотрен тайм-аут между пакетами, достаточный для разбора одного пакета.
Или на этапе ДО начала написания кода должно быть предусмотрено разрешение подобных коллизий - например, короткий ответ "Я занят".
Если ничего это не сделано, то легко сделать "атомарную операцию, чтобы данные не бились" - запретить прерывания по интерфейсу на время разбора буфера. Рано или поздно операция закончится, прием начнется. Часть данных может быть утеряна, но Вы ведь знали про это, предусмотрели подтверждения в протоколе, правда?
wink.gif


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 18:34
Рейтинг@Mail.ru


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