|
Работа с переменными в прерывании и основном теле, жутко неудобно выходит |
|
|
|
Oct 3 2015, 19:40
|

Практикующий маг
     
Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576

|
Добрый вечер Что имеем: 8 битный проц, программа в прерывании читает из кольцевого буфера, указатель чтения -просто индекс массива, двухбайтное число. В основном теле мне приходит поток байт, который я контролирую (запускаю/останавливаю поток) и размещаю байты в этом же кольцевом буфере по другому указателю -указателю записи (тоже индекс массива). До этих пор все замечательно, но чтобы управлять потоком мне нужно знать сколько байт содержится в буфере, для этого я беру разницу между указателями записи и чтения и побитно умножаю ее на (размер_массива - 1). Эту разницу приходится брать в нескольких местах программы, при этом на время вычисления нужно блокировать прерывание, поскольку операция не атомарная, а одна из переменных модифицируется в прерывании. Если этого не делать происходит глюк, если делать -появляется задержка обработки прерывания, а это нехорошо, т.к в нем происходит формирования аудио сигнала. Да и некрасиво это и неудобно -следить какую перменную обрабатываю, нужно или нет блокировать прерывание, ну и поскольку кольцевой буфер используется в различных прерываниях нужно еще и учитывать какое именно прерывание блокировать Может это както по-другому можно делать, подскажите.
|
|
|
|
|
 |
Ответов
|
Oct 9 2015, 18:19
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Так зачем "чутка освободится..."? Сделайте 2 буфера. В один принимаете, из другого кидаете в ШИМ. Когда в том, что в ШИМ, данные закончатся, переключаетесь на тот, в который принимали. Он уже будет весь забит. И т.д. По-моему, это называется "двойная буферизация". А принимайте тоже по прерыванию, только приоритет задайте ниже, чем у таймера выкидывания. И... это, зачем большие буфера?
|
|
|
|
|
Oct 10 2015, 11:19
|

Практикующий маг
     
Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576

|
Цитата(ViKo @ Oct 9 2015, 22:19)  Так зачем "чутка освободится..."? Сделайте 2 буфера. В один принимаете, из другого кидаете в ШИМ. Когда в том, что в ШИМ, данные закончатся, переключаетесь на тот, в который принимали. Он уже будет весь забит. И т.д. По-моему, это называется "двойная буферизация". А принимайте тоже по прерыванию, только приоритет задайте ниже, чем у таймера выкидывания. И... это, зачем большие буфера?  Это не будет работать. Если один источник пишет быстрее, чем другой читает, то рано или поздно (сколько бы у вас ни было буферов) произойдет переполнение буфера. Скорости обоих процессов должны быть в среднем одинаковы. А по поводу прерывания. Если приоритеты обоих одинаковы, то получаем джиттер в виде задержки входа в прерывание ШИМ равное по времени выполнению прерывания UART. В случае если прерывание UART имеет меньший приоритет по сравнению с ШИМ, то будет тоже самое в плане критических секций - придется в прерывании UART временно блокировать прерывание ШИМ. Цитата(rudy_b @ Oct 10 2015, 03:08)  Большой размер буфера иногда нужен при работе с писюком для разравнивания данных - он иногда любит отключать задачу чуть не на секунду. Именно поэтому использую почти всю встроенную память, а чего ее жалеть ради хорошего дела  Цитата(rudy_b @ Oct 10 2015, 03:08)  Джиттера все равно не избежать, можно только снизить его до минимума, если сделать прерывание считывания более высокоуровневым (т.е. разрешить ему прерывать прерывание записи). Но тогда это будет работать также, как если UART будет в основном теле. Цитата(rudy_b @ Oct 10 2015, 03:08)  Тогда есть два варианта. Можно аккуратно работать с указатем записи (кратковременный запрет прерываний) - но это джиттер, хоть и малый. Сейчас так и делаю. Причем что интересно полностью избежать запрета прерываний нельзя - его можно избежать когда в основном теле читаем переменную, изменяемую в прерывании -тут помогает метод двух чтений, который предложил Pasha. А вот в случае когда в прерывании читается переменная, изменяемая в основном теле (это нужно чтобы определить не нагнало ли чтение запись) этот метод не поможет. Цитата(rudy_b @ Oct 10 2015, 03:08)  А можно и без запрета прерываний. ... Периодически происходит синхронизация этих указателей в старшем прерывании - для определения остатка свободного места в буфере. ... Для синхронизации, младшее прерывание меняет свой указатель поэтапно, каждый раз выставляя и снимая бит валидности в отдельной переменной. Т.е., перед изменением оно сначала снимает бит валидности, затем меняет указатель, затем ставит бит валидности. Это можно делать и для каждого байта по отдельности. Старший приоритет синхронизирует свой указатель только если стоит бит валидности. Это, практически, критическая секция, но специфическая, с пропуском, но без зависания. ...Аналогичное взаимодействие можно организовать и между main loop и прерыванием считывания. Посмотрите, что я писал в сообщении #27, но то мое предложение оплевали и посоветовали выкинуть в утиль  . Это не сложно, но опять-таки не универсальное решение, потому как требует персональной корректировки функций по работе с кольцевым буфером под конкретную задачу. Цитата(Dog Pawlowa @ Oct 10 2015, 07:51)  Какие компоненты в систему заложишь, так она и поплывет.
PC + восьмибитник + требование к джиттеру = бульк Не согласен с Вами. Восьмибитник отлично справляется, да у него нет канала DMA который можно накрутить в ШИМ имея какойнибудь Кортекс, но для моей задачи вполне хватает. И потом эта работа -мое хобби, а мне 8-битники нравятся гораздо больше, чем 32разрядные монстры с DMA контроллерами, ускорителями памяти и прочим и прочим. Имеющихся аппаратных возможностей контроллера более чем достаточно для этой задачи.
|
|
|
|
|
Oct 10 2015, 11:39
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(Alexashka @ Oct 10 2015, 14:19)  Это не будет работать. Если один источник пишет быстрее, чем другой читает, то рано или поздно (сколько бы у вас ни было буферов) произойдет переполнение буфера. Скорости обоих процессов должны быть в среднем одинаковы. Так вы порциями (размером с целый буфер) выкидывайте с PC, по команде от вашего устройства. Как только один буфер использовали, переходите на другой, и давайте команду PC передавать данных на целый буфер (в который только что освободился). И не надо ломать голову, когда притормаживать, когда "газовать". И сравнивать указатели, кто кого догоняет, не придется. Просто проходите по буферу от начала до конца. Один указатель записи, бежит по одному буферу, другой указатель чтения, бежит по другому. Красиво? Указатель записи дойдет до конца раньше и притихнет (в это время его можно на начало другого буфера переключить, но писать пока нечего). Когда указатель чтения дойдет до конца, переключаете его на другой буфер, и даете команду компьютеру выдать новую порцию.
|
|
|
|
|
Oct 10 2015, 12:09
|

Практикующий маг
     
Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576

|
Цитата(ViKo @ Oct 10 2015, 15:39)  Красиво? Да, качели из двух буферов тоже вариант. Но переделывать сильно много надо, теперь уже не буду, возможно в следующий раз так и сделаю. Цитата(Tanya @ Oct 10 2015, 15:47)  Вот Вы уже (и другие...) потратили на это обсуждение столько времени, что его цена многократно перекрывает разницу в цене между монстром и достаточным контроллером. Если бы Вы планировали миллионную серию, это имело бы смысл. А так - нет. Таня, Вы меня удивляете!  Какая цена, о чем Вы говорите? Деньги не имеют ровным счетом никакого значения. Я не планирую ничего выпускать, хобби -это для удовольствия, тут дело в самом процессе. Хотя конечно согласен, результат тоже хочется получить. И освоить очередной камень. Но я консерватор  и больше люблю то, к чему привык. Так что извиняйте, я буду делать на том, что у меня сейчас. Как говорят рыбаки -время за рыбалкой (и я бы сказал - за паяльником) в счет жизни не входит  Жаль если Вы этого не понимаете.
|
|
|
|
|
Oct 10 2015, 15:31
|

Практикующий маг
     
Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576

|
Цитата(Tanya @ Oct 10 2015, 16:19)  Понимаю, что Вам не результат нужен, а процесс борьбы. Таня, общение с профессионалами это всегда борьба полезно, я много для себя почерпнул. Наверное все варианты решения уже озвучены (и самый яркий из них -поменять контроллер  ). Лично мне больше нравится простой и надежный как автомат Калашникова вариант с двумя буферами предложенный Viko. Думаю вопрос можно считать решенным. Еще раз всем спасибо за обсуждение!
|
|
|
|
Сообщений в этой теме
Alexashka Работа с переменными в прерывании и основном теле Oct 3 2015, 19:40 gerber Цитата(Alexashka @ Oct 3 2015, 22:40) Мож... Oct 3 2015, 19:44 Alexashka Цитата(gerber @ Oct 3 2015, 22:44) Заведи... Oct 3 2015, 19:49  jcxz Цитата(Alexashka @ Oct 4 2015, 01:49) неа... Oct 4 2015, 07:47   _Pasha Цитата(jcxz @ Oct 4 2015, 10:47) Неужто з... Oct 4 2015, 11:27    ViKo Цитата(_Pasha @ Oct 4 2015, 14:27) Кодvol... Oct 8 2015, 09:31     _Pasha Цитата(ViKo @ Oct 8 2015, 12:31) Читать и... Oct 8 2015, 16:55   Alexashka Цитата(jcxz @ Oct 4 2015, 10:47) Конечно ... Oct 4 2015, 21:53    jcxz Цитата(Alexashka @ Oct 5 2015, 03:53) Зап... Oct 5 2015, 04:12     Alexashka Цитата(jcxz @ Oct 5 2015, 07:12) ЗАЧЕМ???... Oct 5 2015, 12:25      jcxz Цитата(Alexashka @ Oct 5 2015, 18:25) -пр... Oct 5 2015, 12:51      Сергей Борщ Цитата(Alexashka @ Oct 5 2015, 15:25) сли... Oct 5 2015, 12:53      jcxz Цитата(Alexashka @ Oct 5 2015, 18:25) Пос... Oct 5 2015, 12:58       Alexashka Цитата(jcxz @ Oct 5 2015, 15:58) Там где ... Oct 6 2015, 07:29        jcxz Цитата(Alexashka @ Oct 6 2015, 13:29) Да ... Oct 6 2015, 08:10         Alexashka Цитата(jcxz @ Oct 6 2015, 11:10) просто т... Oct 6 2015, 08:41        _Pasha Цитата(Alexashka @ Oct 6 2015, 10:29) Доб... Oct 6 2015, 11:51         Alexashka Цитата(_Pasha @ Oct 6 2015, 14:51) Ну я к... Oct 6 2015, 16:36     MrYuran Цитата(jcxz @ Oct 5 2015, 07:12) Это то ж... Oct 6 2015, 10:49      jcxz Цитата(MrYuran @ Oct 6 2015, 16:49) Преим... Oct 7 2015, 02:41    _Pasha Цитата(Alexashka @ Oct 5 2015, 00:53) Поя... Oct 5 2015, 13:36 gerber Значит, можно сделать порог кратным 256 и ограничи... Oct 3 2015, 20:05 Alexashka ЦитатаЗначит, можно сделать порог кратным 256 и ог... Oct 3 2015, 22:28 aaarrr Разделите свой большой буфер на N маленьких и опер... Oct 3 2015, 20:14 smalcom ЦитатаРазделите свой большой буфер на N маленьких ... Oct 3 2015, 21:43 Valentine Loginov Вариант с так называемым "nonatomic" по-... Oct 7 2015, 07:13 zltigo QUOTE (Valentine Loginov @ Oct 7 2015, 10... Oct 7 2015, 07:25 Valentine Loginov Идея в том, что атомарный флаг делается тоже через... Oct 8 2015, 07:35 Alexashka Цитата(Valentine Loginov @ Oct 8 2015, 11... Oct 8 2015, 07:58  jcxz Цитата(Alexashka @ Oct 8 2015, 13:58) Ест... Oct 8 2015, 09:09   Alexashka Цитата(jcxz @ Oct 8 2015, 13:09) Есть вер... Oct 8 2015, 18:17    jcxz Цитата(Alexashka @ Oct 9 2015, 00:17) Да ... Oct 9 2015, 03:18    ASN Alexashka
Так и не понял, почему запрет прерываний... Oct 9 2015, 06:05 zltigo QUOTE (Valentine Loginov @ Oct 8 2015, 10... Oct 8 2015, 09:13 Valentine Loginov Вообще долгая работа с данными в прерывании плохо.... Oct 9 2015, 06:51 Alexashka Цитата(Valentine Loginov @ Oct 9 2015, 10... Oct 9 2015, 07:40  zltigo QUOTE (Alexashka @ Oct 9 2015, 10:40) Я х... Oct 9 2015, 08:33   Alexashka Цитата(zltigo @ Oct 9 2015, 12:33) Лучше ... Oct 9 2015, 13:09    zltigo QUOTE (Alexashka @ Oct 9 2015, 16:09) А к... Oct 9 2015, 13:42 rudy_b Цитата(Alexashka @ Oct 3 2015, 22:40) Доб... Oct 9 2015, 13:19 Alexashka Цитата(rudy_b @ Oct 9 2015, 17:19) Как-то... Oct 9 2015, 17:09 rudy_b Цитата(ViKo @ Oct 9 2015, 21:19) Так заче... Oct 9 2015, 23:08  Dog Pawlowa Какие компоненты в систему заложишь, так она и поп... Oct 10 2015, 03:51      _Pasha Цитата(Alexashka @ Oct 10 2015, 18:31) Ду... Oct 10 2015, 18:06  Tanya Цитата(Alexashka @ Oct 10 2015, 14:19) И ... Oct 10 2015, 11:47 ViKo Можно и одним буфером обойтись, если разбить его н... Oct 10 2015, 13:57 smalcom тогда будет ограничение на размер буфера. Oct 10 2015, 18:56 zltigo QUOTE (smalcom @ Oct 10 2015, 21:56) тогд... Oct 10 2015, 19:04  Alexashka Цитата(zltigo @ Oct 10 2015, 23:04) Вам у... Oct 11 2015, 20:56   zltigo QUOTE (Alexashka @ Oct 11 2015, 23:56) Вы... Oct 11 2015, 21:01    Alexashka Цитата(zltigo @ Oct 12 2015, 01:01) Если ... Oct 12 2015, 06:38 smalcom а? Oct 10 2015, 20:09 ViKo Да, для 8-битников 16 256-байтовых буферов будет л... Oct 12 2015, 05:45 smalcom для этого используйте 3, 4 и т.д. буферов. Oct 12 2015, 08:00
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|