Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Как уменьшить джиттер и нагрузку на ядро по прерыванию.


Как уменьшить джиттер и нагрузку на ядро по прерыванию.

Сообщений 1 страница 12 из 12

1

Хай всем! Сразу говорю вопрос на миллион! Нужно снизить значение джиттера и нагрузки на ядро путём отказа от прерываний по таймеру и переходу тактирования в главный цикл.

Кратко: сигнал в приёмника создаёт прерывание в процедуре снимаются значение таймера и таймер сбрасывается.
Для получения 1мс (но точность тут не важна +/- 20%) работает таймер и формирует прерывания но такт идёт через главный цикл.
Вот краткий код. Показывать весь код нет смысла там всё отлично, да и раскрывать секрета протокола я не могу.

Джиттер возникает я думаю вот на сколько хз, на тактовой частоте 4КГц он не важен, а вот на 8 или 16Кгц думаю даст знать не хило.
А вот откуда джиттер: при возникновении прерывания по таймеру тратятся ресурсы и пока это прерывание не завершится то timer1 продолжает работать и мотает время. Мне нужно как можно быстрее по возникновению прерывания зафиксировать время и позволить таймеру работать.

И такой вопрос сколько мкс занимает прерывание в котором присваивается значение 1 переменной типа bit на 20МГц но или сколько тактов на это тратится?

было:
do
If Sk1 = 1 Then                                             '1мсек
   Sk1 = 0
   1ms
end if

loop

end

RXdtd: 'внешние прерывание с приёмника.
  sk(1) = timer1
  timer1 = 0
  Frrvc2 = Pinb.2 
  gosub RXdata
return

Trm1tc: '1ms по таймеру
  Sk1 = 1
retrun

стало:
do
If timer3 >= 2500 then
   timer3 = 0
   1ms
end if
loop

end

При отсутствии сигнала (собственный шум приёмника, хотя при таком чутье он постоянно принимает шум с эфира) прерывания сыпятся с частотой до 30-40КГц но это не важно ресурсов хватает на такую частоту прерываний, при наличии полезного сигнала частота прерываний получается = тактовой.

Смогу ли я таким образом выигрывать время перехода к прерыванию?

Отредактировано RadioHAM-433 (2016-09-02 16:09:09)

0

2

слабо понятно, что вы пытаетесь получить
в первом варианте у вас должно работать быстрее (do/loop), чем во втором
впрочем, оно и так быстро работает, потому как вся производительность уходит на "1ms"
и вообще непонятно, зачем считывать значение таймера, если вы его сами же задаёте, там должно быть одно и тоже значение)

Отредактировано RDW (2016-09-02 16:24:42)

0

3

Это тактирование 1мс для отмеривания времени не связное с сигналом. Но что уходит там в главном цикле пофиг. Просто вопрос стоит остро про прерывание по таймеру, скажем оно возникает перед практически одновременно с сигналом с приёмника и оно будет отрабатываться это увеличивает погрешность и снижает разрешающую способность. Невозможно отличить 0 от 1 если разница между ними такая что они могут иметь одинаковую длительность!

Мне главное как можно быстрее переходить к прерыванию по смене сигнала. На сколько я понимаю что тратится в главном цикле не влияет на прерывания они то у нас в приоритете ведь?

Скажем на прерывание по таймеру тратится 30мкс, значит 30мкс мы можем получить лишнего времени работы таймера.

Вот как раз во втором варианте прерывания по таймеру уже нет на прерывание не тратится время, а проверка идет с главного цикла, там джиттер пофиг, там главное время отмерять, всё равно время выполнения всего кода не более 100мкс так что на 1мс хватает, да и точность тут так пофиг тоже.

В приоритете внешние прерывания. Я просто знаю что на прерывания тратится довольно много времени, а переход к прерыванию будет быстрее даже пусть в главном цикле будет полная загрузка.

У меня было надо вообще 10не ниже 7КГц для приёма UART такт, но я 10КГц прерывания сделал, тактировла так же через главный, но загрузка была пределаная, потом снизил до 1 КГц и стал тактировать UART на всю и загрузка стала на много меньше даже хватило время на параллельную обработка протокола Came/Nice или PT2262, а вот я и подумал если отказаться от прерываний с 1КГц пусть в главном критится.

Отредактировано RadioHAM-433 (2016-09-02 21:05:11)

0

4

Похоже нужны разные приоритеты для прерываний. Для INT выше чем для Timer. Чтобы INT мог прервать прерывание Timer. Если не ошибаюсь это поддерживается в XMega.

Можно конечно и на меге сделать, но есть вероятность сбоя.
В обработчике прерывания таймера разрешить прерывания.

Код:
Trm1tc: '1ms по таймеру
  !sei
  Pushall
  Sk1 = 1
  Popall
retrun

При назначении прерывания использовать команду Nosave

Код:
On Timer1 Trm1tc Nosave  ' Назначение подпрограммы прерываний от Timer1

Но как писал выше, это ненадежно т. к. теоретически могут возникнуть еще прерывания от таймера что приведет к переполнению стека.

Если необходима надежность, то следует перейти на XMega или др. контроллеры, например STM32.

0

5

RadioHAM-433 написал(а):

пусть в главном критится

Вы должны понимать, что такой подход/алгоритм будет работать только на вашем экземпляре, повторяемость может страдать...
Вы бы описали простым языком (без ошибок текста) или блок схемой основной идеи, а то я вижу один сумбур того, что вам надо и вообще не понимаю зачем это.)))
Или вы не русский и пользуетесь переводчиком? :D

+1

6

Вы должны понимать, что такой подход/алгоритм будет работать только на вашем экземпляре, повторяемость может страдать...

А чему там страдать если всё стабильно, просто в силу ограниченных ресурсов надо оптимизировать а пытаться брать силой.
А вот и фиг! Поставил так в 3-х девайсах всё отлично, с повторяемостью проблем не когда не было.

Да не разные приоритеты прерываний не нужны это вообще не про этот алгоритм! Я просто хочу выяснить как у меня будет меньше затрат времени на переход к прерыванию, вот и всё. Не каких извратов не надо нужна надёжность! Всегда все фантазируют а задача то элементарная, точнее просто выбрать самый лучший вариант из имеющихся и всё!!!

Меня интересовал один факт: сколько тактов или времени занимает прерывание? И сколько надо времени на переход к прерыванию из главного цикла вот и всё. Где требуется меньше времени тот вариант и остаётся. Но почему то мне думается что прерывание больше времени требует.

А я хочу получить максимум из возможного, но больше протоколов для обработки будет только плюсище.
Вообще это программа трансивера, передача данных, попытка попутно обрабатывать еще протоколы отличные от наших.
Какая нафиг блок схема тут. У нас алгоритм построен специфически, с распределением ресурсов, "стиль без зависаний", определённое время выполнения и тактирование с частотой ниже этого времени что гарантирует всегда стабильную реакцию, задачи распределяются. На ПК такое начал практиковать, что бы исключить зависание главного окна, и очень приятно не когда не видеть зависаний, но потоков туева хуча пришлось делать но зато красота! Гемор синхронизации еще тот.

Отредактировано RadioHAM-433 (2016-09-03 01:47:40)

0

7

RadioHAM-433 написал(а):

Меня интересовал один факт: сколько тактов или времени занимает прерывание? И сколько надо времени на переход к прерыванию из главного цикла вот и всё. Где требуется меньше времени тот вариант и остаётся. Но почему то мне думается что прерывание больше времени требует.


Если память МК <= 64 kb и просто поднять флаг ( dim флаг as byte = 1 )

Если память МК > 64 kb и просто поднять флаг ( dim флаг as byte = 1 ), будет дольше на 10 тактов (ASM) и 10 тактов (Bascom)


Если писать на ASM AVR:

Завершение текущей инструкции - 1...3 такта МК
Вход в прерывание - 5 (вычисление метки) + 3 (переход на метку) тактов МК
push R16 - 2 такта МК
ldi R16 , 1 = 1 такт МК
STS {флаг} , R16 = 2 такта МК
pop R16 - 2 такта МК
reti - Выход из прерывания = 4 такта МК

итого = 8 + 2 + 1 + 2 + 2 +4 = 19  + 1..3 такт МК



Если писать на Bascom:

Завершение текущей инструкции - 1...3 такта МК
Вход в прерывание - 5 (вычисление метки) + 3 (переход на метку) тактов МК
push all - 53 такта МК
флаг = 1 - 3 такта МК
pop all - 53 такта МК
return - Выход из прерывания = 4 такта МК

итого = 5 + 3 + 53 + 3 + 53 + 4 = 121 + 1..3 такт МК


Если память МК <= 64 kb и выполнять битовые операции в байте ( флаг.0 = 1 ), будет дольше на 5 тактов (ASM) и 5 тактов (Bascom)

Если память МК > 64 kb и выполнять битовые операции в байте ( флаг.0 = 1 ), будет дольше на 18 тактов (ASM) и 13 тактов (Bascom)



.......................

Отредактировано sasha_1973 (2016-09-03 03:20:46)

0

8

Если память МК > 64 kb и выполнять битовые операции в байте ( флаг.0 = 1 ), будет дольше на 18 тактов (ASM) и 13 тактов (Bascom)

Чёт непонятно, барсик быстрее асма ???

-1

9

-NMi- написал(а):

Чёт непонятно, барсик быстрее асма ???

Очень смешно ....

+1

10

А мне нет.

0

11

Да понятно лучше правда такт из главного цикла без прерываний. А вот такую инфу можете выдать про доступ к переменным?
Сколько тактов занимает присвоение значения цифровым переменным от bit до single? Но на сколько я понимаю Bit всех меньше по любому хотя ПЗУ больше занимает, массив из тех же Byte удобнее но медленнее так ведь?
Но и проверка 1 условия той же переменной.

Отредактировано RadioHAM-433 (2016-09-11 20:01:27)

0

12

Битовые и байтовые операции по скорости примерно равны.

По поводу  Single, переменная с размерностью 4 байта, выводы делайте сами.

В прерываниях быстрее всего оперировать байтовыми значениями, в крайнем случае Word или Integer.

При использовании логических вычислений, ОБЯЗАТЕЛЬНО сохранять SREG.

RadioHAM-433 написал(а):

Но на сколько я понимаю Bit всех меньше по любому хотя ПЗУ больше занимает, массив из тех же Byte удобнее но медленнее так ведь?
Но и проверка 1 условия той же переменной.


Всё зависит от ситуации. По времени примерно равны ± пару тактов.

Гляньте здесь

Отредактировано sasha_1973 (2016-09-12 06:50:13)

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Как уменьшить джиттер и нагрузку на ядро по прерыванию.