Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Interlocked Exchange
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Mikron
Первый раз столкнулся с такой проблемой.
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;
        }

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

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

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

Не понимаю, как такое может быть. Если скорость обработки ниже, чем скорость заполнения буфера, то каким бы огромным он ни был, рано или поздно заполнится. Кроме, конечно, предельного случая - именно бесконечно большого буфера. Можно даже не кольцевого...
Kabdim
Нужен кольцевой буфер размером = время тупления / время передачи байта.
smalcom
вот тутачки
http://electronix.ru/forum/index.php?showtopic=130807
про буфера написали
Сергей Борщ
Цитата(Herz @ Oct 29 2015, 17:25) *
Если скорость обработки ниже, чем скорость заполнения буфера, то каким бы огромным он ни был, рано или поздно заполнится.
Разумеется. Поэтому я написал, что тормозить можно на некоторых пакетах. А абсолютную гарантию даст только бесконечно большой буфер.
Dog Pawlowa
Цитата(Mikron @ Oct 29 2015, 15:53) *
Вопрос, как выйти из этой ситуации? Есть какие-нибудь атомарные операции, чтобы данные не бились. Спасибо

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