|
Приоритет прерываний, и прерывание прерываний |
|
|
|
 |
Ответов
(1 - 83)
|
Aug 28 2008, 19:28
|
Частый гость
 
Группа: Участник
Сообщений: 149
Регистрация: 2-06-08
Из: Москва
Пользователь №: 38 003

|
Цитата(zltigo @ Aug 28 2008, 21:11)  Поскольку никакой аппаратной поддержки ни вложенности, ни приоритетов у AVR нет, то только руками - при входе в прерывания запретить индивидуально таймерные и затем поднять контроллеру флаг I автоматически сброшенный при входе в обработчик. Не забыть породелать обратную оперрацию при выходе. Это все лишние такты и критические секции, что для 250KHz-64такта не подарок.... Легко можете пролететь. По-моему, в ваш ответ вкралась некоторая неточность, не сочтите за наглость. Сам подход, конечно единственно правильный, но у автора темы задача прерывать не внешнее INT0 прерывание, а наоборот таймерные, поэтому нужно при входе в таймерные прерывания разрешать прерывание от инт0 вскинуть флаг разрешения общих, а вот в обработчике инт0 ничего делать по идее не нужно. Конечно, при таком подходе есть вероятность "пролететь" таймерные прерывания, во время обработки инт0.
|
|
|
|
|
Aug 28 2008, 19:40
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(smac @ Aug 28 2008, 21:28)  поэтому нужно при входе в таймерные прерывания разрешать прерывание от инт0 вскинуть флаг разрешения общих INT0 и так разрешено, а запретить нужно таймерные и прочие, кроме INT0, иначе они будут тоже прерывать текущее. Цитата(defunct @ Aug 28 2008, 21:28)  Если интервалы между таймерными прерываниями достаточно большие... Если их несколько, то их частота уже не имеет значения, ибо могут перекрыватся. Цитата(defunct @ Aug 28 2008, 21:28)  Если латентность каждого из них в отдельности будет меньше 64 тактов, то гарантированно ни один INT0 не потеряется. Нескольким подряд INT0 просто вообще хватит времени, если между ними вклинится 64 такта таймера. INT0 потеряется при обработке предыдущего INT0.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Aug 28 2008, 19:47
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(zltigo @ Aug 28 2008, 22:40)  Если их несколько, то их частота уже не имеет значения, ибо могут перекрыватся. вот и надо считать с учетом что их несколько. Напр. INT0 занимает 48 тактов на обработку (период - 64 такта) - 75% ресурса проца. T1 - 100 тактов (период - 10K тактов) T2 - 200 тактов. (период - 10K тактов) считаем. гарантированное время для обработчика T1 (при любых раскладах он получит столько времени до наступления следующего прерывания) - 10K * 0.25 - 200 = 2300 тактов, 2300 > 100 все Ок. гарантированное время для обработчика T2 соответвенно: 10K * 0.25 - 100 = 2400 (> 200). Не нравится одинаковый период, попробуем для разных: INT0 - 48 тактов (75%). T1 - 100 тактов (период - 10K тактов) T2 - 200 тактов. (период - 1K тактов) гарантированное время для обработки T1 = 10K * 0.25 - (10K/1K * 200) = 2500 - 2000 = 500 (> 100). для T2 без изменений 2400. И здесь все Ок. Цитата Нескольким подряд INT0 просто вообще не хватит времени, если между ними вклинится 64 такта таймера. хватит если как сказано выше не 64такта таймера, а гарантировано меньше 64-х (напр 63).
|
|
|
|
|
Aug 28 2008, 20:02
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(defunct @ Aug 28 2008, 21:47)  вот и надо считать с учетом что их несколько. Так считайте. Два с некратными периодами и что там будет при прерывании одного другим. Цитата хватит если как сказано выше не 64такта таймера, а гарантировано меньше 64-х (напр 63). Разумеется нет. Думайте, сколько времени остается обработчику INT0 после Ваших 63 тактов.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Aug 28 2008, 20:03
|
Частый гость
 
Группа: Участник
Сообщений: 149
Регистрация: 2-06-08
Из: Москва
Пользователь №: 38 003

|
Цитата(zltigo @ Aug 28 2008, 23:40)  INT0 и так разрешено, а запретить нужно таймерные и прочие, кроме INT0, иначе они будут тоже прерывать текущее. Да, Вы правы, меня бес попутал. А вообще задача похоже достаточно серьезная, на С, наверное, нужно будет очень глубоко вникнуть в суть кода. Вопрос к автору темы - а нет ли возможности считать импульсы с помощью таймера-счетчика?
|
|
|
|
|
Aug 28 2008, 20:23
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(zltigo @ Aug 28 2008, 22:40)  INT0 и так разрешено, а запретить нужно таймерные и прочие, кроме INT0, иначе они будут тоже прерывать текущее. Как правило, таймерные приходят с определённой периодичностью. Периодичность вполне высчитывается. Если их период превышает означенный период (4мс), то достаточно просто разрешить прерывание в таймерных обработчиках. Возможность 3 вложенных - не проблема. Это лишь незначительно увеличит время реакции на прерывание. Хотя здесь надо учитывать объём контекста для этих прерываний (при написании на Си). Важно также чтобы не использовались совместные переменные в прерываниях. Также необходимо увеличить размер стека (что естественно) Цитата Если их несколько, то их частота уже не имеет значения, ибо могут перекрыватся. Нескольким подряд INT0 просто вообще хватит времени, если между ними вклинится 64 такта таймера. INT0 потеряется при обработке предыдущего INT0. Не совсем понятно. Лишь бы не пришли одинаковые прерывания. То есть необходимо чтобы суммарное время обработки всех прерываний было меньше (с запасом) чем период найменьшего из прерываний. Есть ещё ограничения. Столкнулся недавно. Нельзя так обрабатывать те прерывания, флаг которых не сбрасывается автоматически при входе в прерывание. Либо надо их запрещать перед разрешением. Например при обработке USART_UDRE.
|
|
|
|
|
Aug 28 2008, 20:35
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(zltigo @ Aug 28 2008, 23:02)  Так считайте. Два с некратными периодами и что там будет при прерывании одного другим. так посчитал. что неустраивает в расчетах. И откуда у таймера будет некратный период. Цитата Разумеется нет. Думайте, сколько времени остается обработчику INT0 после Ваших 63 тактов. Очевидно - все оставшееся время. Таймер не сможет прервать INT0. Самое главное не пропустить ни одного INT, - влететь в обработчик INT0 до того как произойдет следующий INT0. Все остальное фиолетово, при условии что обработка самого INT0 занимает тоже строго меньше 64 тактов.
|
|
|
|
|
Aug 28 2008, 20:46
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(SasaVitebsk @ Aug 28 2008, 22:23)  Это лишь незначительно увеличит время реакции на прерывание. В этом и проблема, ибо хотят обрабатывать прерывания с частотой в 250KHz тут уже каждый такт для AVR становится значительным. Цитата(defunct @ Aug 28 2008, 22:35)  И откуда у таймера будет некратный период. Я что,не имею права запустить таймер, напимер, на 1000 и 10001 тик? Или любые другие нацело не деляющиеся...
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Aug 28 2008, 20:54
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(zltigo @ Aug 28 2008, 23:46)  В этом и проблема, ибо хотят обрабатывать прерывания с частотой в 250KHz тут уже каждый такт для AVR становится значительным. Именно, но необходимое и достаточное условие для того чтобы не терять события частоты F это: A ) обрабока события должна происходить строго быстрее 1/F. B ) Время между возникновением события и входом в обработчик должно быть сторого меньше 1/F. Вот от этого и плясать. "A" никак не зависит от обработчиков других прерываний. "B" зависит от обработчиков других прерываний и может быть достигнуто двумя путями - 1)разрешением прерываний внутри левых обработчиков 2)сокращением латентности обработчиков. Вот собсно и все. Все это легко считается по крайней мере для AVRки, т.к. кол-во тактов на обработчик известно, приоритеты обработчиков при одновременном возникновении нескольких прерываний - известны. Цитата Я что,не имею права запустить таймер, напимер, на 1000 и 10001 тик? Или любые другие нацело не деляющиеся... Имеете право конечно, но для простоты расчетов мы возмем минимальный период (или макс возможную частоту).
|
|
|
|
|
Aug 28 2008, 20:54
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(defunct @ Aug 28 2008, 22:35)  ...при условии что обработка самого INT0 занимает тоже строго меньше 64 тактов. Нет. третьи сутки идут "расстрельные" прерывания каждое длится по 63 такта. Периодически приходят несколько таймерных по 63 такта. Вопрос, что будет, если 1. таймерные не прерываются. 2.Если таймерные прерываются, но естественно, для программной реализации вложенности и приоритетов требуются критические секции. 3. Что-то мне подсказывает  что Автор поднял вопрос не уложив программу в несколько тактов
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Aug 28 2008, 21:10
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(zltigo @ Aug 28 2008, 23:54)  Нет. третьи сутки идут прерывания INT0 каждое длится по 63 такта. Периодически приходят несколько таймерных по 63 такта. Вопрос, что будет, если 1. таймерные не прерываются. очевидно таймерные будут курить бамбук, т.к. INT0 приоритетнее. Если же появится окно, когда INT0 не будет, тогда вызовется обработка таймера. А поскольку длительность обработчика таймера меньше периода INT0, то во время обработки таймерного прерывания два события INT0 произойти просто не успеют. Т.о. как только обработка таймера завершится мы влетим в INT0 и сбросится соотв. флаг, во время обработки придет следующее событие INT0 - сразу после выхода из обработчика, мы влетим обратно в обработчик INT0.. и т.д. Ни одного события INT0 мы гарантировано не потеряем. Цитата 2.Если таймерные прерываются, но естественно, для программной реализации вложенности и приоритетов требуются критические секции. Требуются, но можно обойтись и без них, если есть гарантия, что повторный вход в этот же обработчик никогда не успеет произойти. Цитата(zltigo @ Aug 28 2008, 23:54)  3. Что-то мне подсказывает  что Автор поднял вопрос не уложив программу в несколько тактов  Да - много неизвеcтных в его задаче. Нужно знать как минимум периоды T1, T2 и хотя бы приблизительное время обработки каждого из трех событий. Тогда можно советовать наверняка.
|
|
|
|
|
Aug 28 2008, 21:14
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(defunct @ Aug 28 2008, 23:03)  очевидно таймерные будут курить бамбук, т.к. INT0 приоритетнее. Поскольку Вы начали строить всевозможные предположения, то я специально в вопросе убрал INT0  , но Вы успели отцировать первоначальный copy-paste вариант Ж(. Цитата Требуются, но можно обойтись и без них, если есть гарантия, что повторный вход в этот же обработчик никогда не успеет произойти. Таких гарантий при нескольких источниках прерывания нет.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Aug 28 2008, 21:26
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(zltigo @ Aug 29 2008, 00:14)  Поскольку Вы начали строить всевозможные предположения, то я специально в вопросе убрал INT0  , но Вы успели отцировать первоначальный copy-paste вариант Ж(. не суть важно, по условию задачи нам нужно не пропустить ни одного INT0. О всех остальных автор умолчал ;> Преполагаем что они не важны и их пропускать можно. Цитата Таких гарантий при нескольких источниках прерывания нет. Заблуждение. И Вы сами это прекрасно понимаете, но не хотите сдаваться  Гарантии достигаются за счет опять же двух составляющих: - минимальный период; - макс время обработки каждого прерывания. Если время обработки == 0, гарантия 100%. Если период стремится к бесконечности - гарантия 100%. ну а для всех остальных случаев гарантии оцениваются/считаются.
|
|
|
|
|
Aug 28 2008, 21:48
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(defunct @ Aug 28 2008, 23:26)  не суть важно, по условию задачи.... Раз уж разговоры вышли за рамки задачи, то я намеренно ушел и от поминания конкретного прерывания. Цитата Гарантии достигаются за счет опять же двух составляющих: - минимальный период; - макс время обработки каждого прерывания. Повторяю последний раз. Ничего из вышеизложенного не гарантирует отсутствия вложенности вспомогательных прерываний. О повторном входе в обработчик и последствиях я речь вообще не вел и незачем подменять понятия. Однако, довести и до такого состояния систему которая прерывается каждые 64 такта на 63 такта ну очень легко  . Цитата(defunct @ Aug 28 2008, 23:26)  Если время обработки == 0, гарантия 100%. Ну очень хорошая программа - научите писать такие  Цитата ну а для всех остальных случаев гарантии оцениваются/считаются. Гарантия это НЕ ВЕРОЯТНОСТЬ. Гарантия либо она есть, либо ее НЕТ. Вот об отсутствии гарантий и веду речь.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Aug 28 2008, 21:59
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(zltigo @ Aug 29 2008, 00:48)  Повторяю последний раз. Ничего из вышеизложенного не гарантирует отсутствия вложенности вспомогательных прерываний. гм?! с этим утверждением я не спорю и не спорил. Цитата О повторном входе в обработчик и последствиях я речь вообще не вел и незачем подменять понятия. Почему же, как раз об этом и стоит говорить, т.к. только возможность повторного входа в тот же обработчик может привести к фатальным последствиям. А вспомогательные прерывания - Бог с ними, они не мешают. Цитата Ну очень хорошая программа - научите писать такие  в теории можно всё  Цитата Гарантия это НЕ ВЕРОЯТНОСТЬ. Гарантия либо она есть, либо ее НЕТ. Вот об отсутствии гарантий и веду речь. Я о гарантии, не о вероятности. Могу доказать на примере в системе с несколькими прерываниями, что есть гарантия того, что повторный вход в любой обработчик никогда не успеет произойти.
|
|
|
|
|
Aug 28 2008, 23:11
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(PhX @ Aug 28 2008, 15:53)  как сделать так, чтобы прерывание INT0 имело наивысший приоритет и прерывало обработчики остальных прерываний? В остальных прерываниях ставите разрешение прерываний (sei) как можно ближе к точке входе, да и всё. Однако, поскольку период появления INT0 может быть достаточно маленьким, всего 4 мкс, эффективность работы вашей сишной программы (в смысле загрузки процессора) находится под большим вопросом. Пмсм вам надо пересмотреть принцип обработки прерываний от энкодера. Что если один выход энкодера подключить к счётчику0, а второй к счётчику2? Ёмкость счётчиков не позволит потерять ни одного импульса, а анализ показаний счётчиков даст возможность определить направление вращения.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Aug 28 2008, 23:23
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(=GM= @ Aug 29 2008, 01:11)  ..да и всё. или нет  Цитата Пмсм вам надо пересмотреть принцип обработки прерываний от енкодера. А вот это точно.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Aug 29 2008, 00:19
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(zltigo @ Aug 29 2008, 01:37)  Ладно, допустим, что я забыл Ваши примеры с таймерами. А что не так с примерами-то? Они всего лишь показывают, что ресурса процессора хватит на обработку всех прерываний в real-time. Цитата Тогда все остальное я просто не читаю, поскольку не знаю, с кем Вы спорите - похоже с собой Я не спорю, а утверждаю, что задачу автора ветки Цитата Есть три обработчика прерываний: От Timer1 от INT0 и допустим от Timer2 Прерывание от INT0 наиважнейшее не обработается вовремя расстрел (считает импульсы энкодера максимальная частота 250 КГц). Вопрос как сделать так, чтобы это прерывание имело наивысший приоритет и прерывало обработчики остальных прерываний? можно решить двумя путями: 1) разрешать прерывания (sei) сразу на входе в обработчиках таймеров. 2) сократить латентность всех без исключения обработчиков до (Fclk / 250kHz) - (2 * Tcall + 1) тактов.
|
|
|
|
|
Aug 29 2008, 08:18
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(defunct @ Aug 29 2008, 02:19)  Они всего лишь показывают... Устал я об одном и том-же.... Цитата ...утверждаю, что задачу автора ветки можно решить двумя путями: Не двумя путями, а ЕЩЕ двумя путями Цитата 1) разрешать прерывания (sei) сразу на входе в обработчиках таймеров. 2) сократить латентность всех без исключения обработчиков до (Fclk / 250kHz) - (2 * Tcall + 1) тактов. -При этом первый путь тянет за собой многократную вложенность прерываний, пожирание стека, потенциальную возможность повторного входа в обработчик прерывания (да, да, да я уже устал слышать, что сейчас мы напишем ну такие короткие обработчики, а прочие прерывания сделаем такими редкими, что этого будет никогда). -А второй путь вообще сродни совету в ответ на жалобы на проблемы - ну а почему-бы Вам не быть богатым и здоровым? Все.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Aug 29 2008, 11:00
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(zltigo @ Aug 29 2008, 11:18)  -При этом первый путь тянет за собой многократную вложенность прерываний, пожирание стека, Любой путь с разрешением прерываний в обработчиках тянет за собой все это, в т.ч. и предложенный Вами в #2. Цитата потенциальную возможность повторного входа в обработчик прерывания (да, да, да я уже устал слышать, что сейчас мы напишем ну такие короткие обработчики, а прочие прерывания сделаем такими редкими, что этого не будет никогда). Эта возможность пресекается. Это не ARM, здесь очень прогнозируемый КП. Цитата -А второй путь вообще сродни совету в ответ на жалобы на проблемы - ну а почему-бы Вам не быть богатым и здоровым? посмотреть листинги обработчиков, которых всего три и посчитать время их выполнения. Вынести обработку в основной цикл программы. Что мешает обработчики того же таймера построить как-то так: Код ISR_T1() { T1Event = TRUE; T1Counter += 1; }
ISR_T2() { T2Event = TRUE; T2Counter += 1; }
main() { ...
for(;;) { sleep();
if (T1Event) { T1Event = FALSE; Handle_T1Event(T1Counter); } if (T2Event) { T2Event = FALSE; Handle_T2Event(T2Counter); } } }
|
|
|
|
|
Aug 29 2008, 17:52
|

Местный
  
Группа: Свой
Сообщений: 482
Регистрация: 5-07-05
Из: Санкт-Петербург
Пользователь №: 6 528

|
Цитата(PhX @ Aug 28 2008, 20:53)  Прерывание от INT0 наиважнейшее не обработается вовремя расстрел (считает импульсы энкодера максимальная частота 250 КГц). Если в задачи int0 входит только тупой подсчёт импульсов, то не проще ли, я бы да же сказал рациональнее, было бы завести данный сигнал не на int0, а на счётный вход таймера, который аппатарно будет считать импульсы, и не спеша далее делать свои дела. Да же на C все можно следать при таком подходе.
--------------------
Для связи email: info собака qbit.su
|
|
|
|
|
Aug 29 2008, 18:48
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Взгляд со стороны. Ибо в жаркой дискусси я неучвствовал, хотя все постинги прочитал. Попробую объяснить на пальцах. 1. Возмите у жены/сестры/матери сантиметр (хотя, там все 150 сантиметров! Почему они его сантиметром называют -- отдельный вопрос.) -- это будет шкала времени. Пусть 10 сантиметров (длины) будут равены 1 мс. 2. Теперь прикиньте, сколько времени потребуется для обрабтки INT0. Допустим, 2 мс. Эквивалентная длина 20 сантимов. Нарежьте несколько полосок цветной бумаги (или провода) этой длины. Из условия задачи мы знаем, что INT0 прет с частотой 250 кГц. Значит, INT0 будет возникать через каждые 4 мс. Теперь, разложите цветные полоски на шкале времени через каждые 40 сантиметров. Это время занято. 3. Проделайте те же действия с плолосками бумаги другого цвета для проерываний от таймеров. Разложите "таймерные" полоски на свободном месте, с учетом примерной периодичности поступления этих прерываний. 4. Если есть еще какие-то процессы -- добавьте еще бумаги. Понятно, что какие-то из полосок придется сдвигать вправо по оси времени. Сейчас главное уяснить два вопроса: 1) А хватит-ли вообще процессорного МК времени для обработки прерываний? 2) То, на сколько может сдвинуться полоска (обработка), это будет дрожжание обработчика -- ждиттер. Нужно прикинуть, оценить величину этого дрожжания. Если после раскладки полосок остается еще достаточно времени (например более половины) и допустим джиттер, то задачу впринципе можно решить. Если плоски наезжают друг на друга, разумеется, -- нет. Итак, дело за автором топика: внесите ясность. ЗЫ Для прерываний, которые не привязаны жестко ко времени (у которых полоски бумаги допустимо сдвигать) можно предложить следующий способ обработки. Обнаруженное, но необработанное событие (postpone) можно зафиксировать не в переменной-флаге, а в переменной-счетчике. Т.е. возникло прерывание, уходим в обработчик, инкрементируем счетчик, выходим. Все! Достаточно быстро, ничего лишнего, никакой обработки. Обработка будет потом. В основном цикле программы, если какой-то счетчик больше нуля вызываем соответствующую функцию-обработчик события. В этой функции производим декремент счетчика. Тут правда есть подводные камни. У AVR отсутствуют команды, котрые позволяют производить операцию инкремента/декремента в памяти. Значит, что бы декрементировать счетчик нужно сначала переменную считать в регистр, затем декрементировать, а после этого записать обратнно в память. Т.е. нарушается принцип атомарности операции. Что произойдет, если мы считали переменную в регистр, а в это время произошло прерывание, где эта же переменная успешно будет инкрементирована. Получается так, что после окончания прерывания, значение в регистре будет не верным. картина Репина "А мужики-то не знают!" Для решения этого придется эту переменную либо размещать в регистре (расточительно и небезопасно), либо обрамлять тройку команд (ld-dec-st) командами разрешения/запрещения прерываний. Т.е. нужен нам нужен какой-то семафор. У АВР есть хорошая атомарная команда swap. Можно поиграться сней. Но я, кажись, увлекся... Извините
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Aug 29 2008, 19:15
|
Частый гость
 
Группа: Новичок
Сообщений: 83
Регистрация: 25-08-08
Пользователь №: 39 801

|
Вот кстати ещё тема с похожей тематикой (касающаяся гимора с отстутствием к AVR как таковых приоритетов прерываний)
|
|
|
|
|
Aug 30 2008, 06:26
|

Местный
  
Группа: Свой
Сообщений: 473
Регистрация: 10-09-06
Из: Тольятти. Самарская обл.
Пользователь №: 20 249

|
Честно говоря не ожидал, что проблема вызоет такую дискуссию. На первый взгляд можно сделать следующий вывод: необходимо упростить задачу, поскольку чем больше сложность, тем дольше этап отладки. Поэтому прерывание от Timer2 необходимо убрать. Господин zhevak предложил очень интнремный способ планирования задачи. Спасибо, но поскольку боюсь ножниц, воспользуюсь карандашом. Цитата(bzx @ Aug 29 2008, 22:52)  завести данный сигнал не на int0, а на счётный вход таймера... К большому сожалению считывание импульсов с энкодера несколько сложнее чем просто суммирование импульсов, об этом на форуме уже проводилась дискуссия. На более развитых нежели AVR контроллерах обработчик энкодера железно включен в перифирию, однако у AVR к сожалению этого нет. Приведу код обработчика INT0 Код // Внешнее прерывание INT0 // На вход INT0 приходят импульсы от выхода A энкодера // На вход PD0 приходят импульсы от выхода B энкодера ISR(INT0_vect) { Rot = (PIND & 0x01 == 0x01); if (Rot) pos++; else pos--; } Обработчик прерывания от Timer1 должно прерываться прерыванием от ISR0. Как ли это делается в WinAVR? Код ISR(TIMER1_OVF_vect) { sei(); // Разрешаем прерывания // Что-то сюда еще наверное нужно вставить чтобы впускать только прерывания от INT0 if (PORTC < 0x08) PORTC<<=1; else PORTC = 0x01; TCNT1 = 0x10000 - 62500 / Frq; }
--------------------
Если все, то не я...
|
|
|
|
|
Aug 30 2008, 08:31
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Дам пару советов. Во первых, код написать таким образом (правда, это для IAR, но для гнуся все остается в силе) Код #pragma vector=INT0_vect __interrupt void INT0_proc(void) { unsigned char t=pos-1; if (PIND&0x01) t+=2; pos=t; }
#pragma vector=TIMER1_OVF_vect __interrupt void T1_proc(void) { unsigned char t; __enable_interrupt(); t=PORTC; t<<=1; if (PORTC&0x08) t=1; PORTC=t; TCNT1 = 0x10000 - 62500 / Frq; } Общая идея в том, чтобы не работать с глобальными переменными, а работать с регистровыми. Например, обработчик INT0 после переделки занимает 27 тактов со всеми входами и выходами (это результат IAR'а). Далее, если Вы боитесь, что в прерывании от переполнения Timer1 возможен второй вход - поставьте его в режим Clear On Compare Match и в OCR1 занесите 1. В результате, после переполнения, произойдет прерывание, а таймер дальше не пойдет, его все время Compare Match будет сбрасывать. Как только Вы занесете в таймер значение больше 1 - опять начнется отсчет.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Aug 30 2008, 08:42
|

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

|
Цитата(PhX @ Aug 30 2008, 09:26)  Как ли это делается в WinAVR? Позволю себе поправить: Код ISR(TIMER1_OVF_vect) { uint8_t TIMSK_save = TIMSK; TIMSK = 0; // Что-то сюда еще наверное нужно вставить чтобы аналогично запретить остальные прерывания кроме INT0
sei(); // Разрешаем прерывания // первым делом обновляем счетчик таймера. Если мы сделаем это позже, // то возможна ситуация, когда при обновлении счетчик "перепрыгнет" нулевое значение и прерывание будет потеряно. // с момента возникновения прерывания таймер мог уже что-то насчитать, поэтому для // увеличения точности не присвоение, а сложение TCNT1 += 0x10000 - 62500 / Frq; if (!(PORTC & (1 << 3))) // это компилится в одну инструкцию sbis вместо in, and, jne PORTC<<=1; else PORTC = 0x01; cli(); TIMSK = TIMSK_save; }
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Aug 30 2008, 09:27
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата if (!(PORTC & (1 << 3))) // это компилится в одну инструкцию sbis вместо in, and, jne PORTC<<=1; else PORTC = 0x01; Вот не согласен. Есть же else  Так что лучше написать так, как у меня (у меня можно проверить и регистр, но IAR почему-то не хочет компилить SBRS, хотя SBIS изготавливает влет). Цитата TCNT1 += 0x10000 - 62500 / Frq; Это надо бы делать до SEI. А вообще данное место зависит от необходимой точности частоты прерываний от таймера. Точно будет только при использовании Clear On Compare Match и прерывания по Compare.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Aug 30 2008, 09:45
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Цитата(Сергей Борщ @ Aug 30 2008, 12:38)  Нет. Эта операция довольно долгая (16-битный таймер как-никак), до sei() она будет увеличивать латентность. А в этом месте прерывания от таймеров остались запрещены, поэтому делать ее в этом месте вполне безопасно. Если можно вообще говорить о безопасности при доступе к 16-битному работающему таймеру на 8-битной машине. Насчет Clear On Compare Match абсолютно согласен. Опасения конечно есть, но при чтении с 16-ти битных регистров у АВР предусмотрен временный регистр. При чтении сначала младший байт помещается в тмп, после этого производится чтение. ИАР это делает правильно.
Сообщение отредактировал sKWO - Aug 30 2008, 09:48
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
Aug 30 2008, 10:14
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата оэтому делать ее в этом месте вполне безопасно. Не, я про то, что если возникнет прерывание между чтением TCNT1 и установкой - будет уж очень большая погрешность. Тогда уж лучше так: Код __interrupt void T1_proc(void) { unsigned char t; __enable_interrupt(); t=PORTC; __disable_interrupt(); TCNT1+=_ADJUST_T1_+0x10000 - 62500 / Frq; __enable_interrupt(); t<<=1; if (PORTC&0x08) t=1; PORTC=t; __disable_interrupt(); TCNT1 = 0x10000 - 62500 / Frq; } _ADJUST_T1_ - это поправочная константа на время между чтением TCNT1 и записью. Ее надо выбрать по результирующему коду обработчика. А чтобы не бояться повторного входа, установить заранее OCR1 на число меньшее, чем заносится в TCNT1 (или, например, неплохо будет занести туда время, которое допустимо между вызовами прерывания). По флагу OCF1 можно ориентироваться, что произошло гуано в генерации частоты. На самом деле это хорошо работает, если прескаллер равен 1. Кстати, я надеюсь у автора Frq - константа? Если нет, то расчет значения для занесения в таймер надо убирать из прерывания.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Aug 30 2008, 17:52
|
Частый гость
 
Группа: Новичок
Сообщений: 83
Регистрация: 25-08-08
Пользователь №: 39 801

|
Цитата(PhX @ Aug 28 2008, 20:53)  Есть три обработчика прерываний: От Timer1 от INT0 и допустим от Timer2 Прерывание от INT0 наиважнейшее не обработается вовремя расстрел (считает импульсы энкодера максимальная частота 250 КГц). Вопрос как сделать так, чтобы это прерывание имело наивысший приоритет и прерывало обработчики остальных прерываний? Компилятор WinAVR. Дык в ATmega-х прерывание INT0 и так "наиважнейшее" поэтому его вектор стоит на самом 1-м месте. Просто при входе в обработчики таймерных прерываний делайте глобальное разрешение прерываний командой SEI и проектируйте систему так, чтобы не было вложенных обработчиков( ну когда обработчик не успел ещё одно прерывание отработать, а уже наступило следующее).. А если вложенные обработчики Вас не пугают и Вы анализируете флаг повторной входимости, тогда вообще Ноу Проблем
Сообщение отредактировал Боинг749 - Aug 30 2008, 17:57
|
|
|
|
|
Aug 30 2008, 21:08
|
Частый гость
 
Группа: Новичок
Сообщений: 83
Регистрация: 25-08-08
Пользователь №: 39 801

|
Цитата(defunct @ Aug 31 2008, 00:59)  выбросить все манипуляции с TCNT. Работать нужно только с OCR, и пользовать CTC режим. А причём тут это? Какое отношение Ваши реплики имеют к вопросу темы? НАПОМИНАЮ, вопрос темы звучал так: Цитата(PhX @ Aug 28 2008, 20:53)  как сделать так, чтобы это прерывание <INT0>{прим.Боинг749} имело наивысший приоритет и прерывало обработчики остальных прерываний? И КОНКРЕТНО на этот вопрос я ответил чуть выше
Сообщение отредактировал Боинг749 - Aug 30 2008, 21:13
|
|
|
|
|
Aug 31 2008, 06:43
|

Местный
  
Группа: Свой
Сообщений: 473
Регистрация: 10-09-06
Из: Тольятти. Самарская обл.
Пользователь №: 20 249

|
Цитата(defunct @ Aug 31 2008, 01:59)  выбросить все манипуляции с TCNT. Работать нужно только с OCR, и пользовать CTC режим. Абсолютно согласен. Уже попробывал моргание светодиодом.  Просто с AVR знаком 3-й день не знаю всех особенностей. Текущий проект удалось упростить до использования 2-х прерываний, так что проблем быть не должно. А вообще, с теоретической точки зрения, интересный вопрос, для более сложных проектов весьма актуальный.
--------------------
Если все, то не я...
|
|
|
|
|
Aug 31 2008, 07:40
|
Частый гость
 
Группа: Новичок
Сообщений: 83
Регистрация: 25-08-08
Пользователь №: 39 801

|
Цитата(defunct @ Aug 31 2008, 11:34)  Прямое - минимизация латентности обработчиков прерываний. Почитайте весь топик. Дык я же ответил: просто надо сразу при входе в обработчик таймера разрешать прерывания командой SEI. Причём тут режимы работы таймера?
|
|
|
|
|
Aug 31 2008, 14:14
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата с какого момента вы были наделены правами и обязанностями модератора? Свят-свят... Только дохтура нам модератором не хватало... Кстати, а что правила говорят о повторной регистрации? Явно ж клиент на бан. Пардон за офтоп.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Aug 31 2008, 22:01
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Rst7 @ Aug 30 2008, 07:31)  Общая идея в том, чтобы не работать с глобальными переменными, а работать с регистровыми. Например, обработчик INT0 после переделки занимает 27 тактов со всеми входами и выходами (это результат IAR'а) Интересно бы взглянуть на код. Хотя по смыслу переменные t, pos должны быть 16-битными, если не 32-битными. У меня для целых (16-битных) на асме получилось 18 тактов. А вообще вывод неутешительный, время выполнения двух прерываний порядка 83 тактов, явно подпадает под расстрельную статью...
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Sep 1 2008, 05:49
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата Интересно бы взглянуть на код Код RSEG CODE:CODE:NOROOT(1) // 147 __interrupt void INT0_proc(void) INT0_proc: // 148 { ST -Y, R17 ST -Y, R16 IN R17, 0x3F // 149 unsigned char t=pos-1; LDS R16, pos DEC R16 // 150 if (PIND&0x01) t+=2; SBIC 0x09, 0x00 SUBI R16, 254 // 151 pos=t; ??INT0_proc_0: STS pos, R16 // 152 } OUT 0x3F, R17 LD R16, Y+ LD R17, Y+ RETI REQUIRE _A_PIND // 153 // 154 #pragma vector=TIMER1_OVF_vect
RSEG CODE:CODE:NOROOT(1) // 155 __interrupt void T1_proc(void) T1_proc: // 156 { ST -Y, R18 ST -Y, R17 ST -Y, R16 IN R18, 0x3F // 157 unsigned char t; // 158 __enable_interrupt(); SEI // 159 t=PORTC; IN R16, 0x08 // 160 t<<=1; LSL R16 // 161 if (PORTC&0x08) t=1; SBIC 0x08, 0x03 LDI R16, 1 // 162 PORTC=t; ??T1_proc_0: OUT 0x08, R16 // 163 TCNT1 = 0x10000 - 62500 / Frq; LDI R16, 250 LDI R17, 255 STS 133, R17 STS 132, R16 // 164 } OUT 0x3F, R18 LD R16, Y+ LD R17, Y+ LD R18, Y+ RETI REQUIRE _A_TCNT1 REQUIRE _A_PORTC А старший байт pos (если надо) - лучше править не в процедуре прерывания, а отдельно.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Sep 1 2008, 08:07
|

Местный
  
Группа: Свой
Сообщений: 473
Регистрация: 10-09-06
Из: Тольятти. Самарская обл.
Пользователь №: 20 249

|
Цитата(Dog Pawlowa @ Sep 1 2008, 12:36)  Ну не знаю, кто как, но я зарекся делать системы без запаса 50%. Само собой, 250 кГц, для текущего проека, это запас примерно 1000%. 250 кГц были определены среднепотолочным методом, просто с учетом планов на будущее. Реально прерывания от таймера "шлепают" с частотой 12 кГц, а от INT0 с частотой около 30 кГц, причем это тоже, вероятно с запасом.  p.s. А в WinAVR можно результат работы компилятора как в посте Rst7, да и где взять время выполнения команд? Вообщем как можно быстро расчитать время обработки прерывания?
--------------------
Если все, то не я...
|
|
|
|
|
Sep 1 2008, 09:49
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата И как вы себе представляете правку старшего байта вне прерывания? Вполне просто. Изредка запускаем проверку, не изменился ли старший бит pos и если изменился - меняем старший байт. Заодно там, где необходимо значение pos тоже выполняем такую проверку. Цитата Из вашего кода у меня получилось 28 тактов, да ещё без sei. Код для INT0 не предусматривал SEI. Тактов, кстати, 27, если RJMP c вектора. Цитата Не могу понять почему компайлер у вас не сохраняет SREG? А порт 0x3F - это что по Вашему? Цитата Нельзя ли посмотреть на код с 16-битными t и pos? А смысл? Цитата Ваш код какой-то левый. Выбирайте выражения. ...Чуть позже... С банальной проверкой старшего бита я погорячился малость, там надо проверять изменение 2х старших бит из 00 в 11 и наоборот. Это и будет обозначать инкремент или декремент старшего байта. Но не суть, такую проверку можно выполнить один раз на, скажем, 50 прерываний INT0. Цитата А в WinAVR можно результат работы компилятора как в посте Rst7 Как-то там через зопу. Смотрите elfdump или objdump. Запускаете его с ключиком (не помню каким, в хелпе глянете) и он дампит выходной эльф-файл с включением строк исходника. Цитата да и где взять время выполнения команд? В даташите на контроллер. В табличке с набором команд. Цитата Вообщем как можно быстро расчитать время обработки прерывания? Я руками считаю. Навык, выработанный годами
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Sep 1 2008, 09:52
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Rst7 @ Sep 1 2008, 08:35)  Вполне просто. Изредка запускаем проверку, не изменился ли старший бит pos и если изменился - меняем старший байт. Заодно там, где необходимо значение pos тоже выполняем такую проверку То есть был 127, стал 128 - меняем старший байт? А как тогда быть с полным 16-битным pos? В 7 бите pos будет знак? Да и что значит изредка? А вдруг пропустим, а пропуск означает катастрофу. Цитата(Rst7 @ Sep 1 2008, 08:35)  А порт 0x3F - это что по Вашему? Прошу пардону, слона-то я и не приметил.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Sep 1 2008, 09:53
|

Местный
  
Группа: Свой
Сообщений: 473
Регистрация: 10-09-06
Из: Тольятти. Самарская обл.
Пользователь №: 20 249

|
Цитата(Rst7 @ Sep 1 2008, 14:49)  А смысл? С точки зрения технических требований задачи переменная pos должна быть 32 битной.
--------------------
Если все, то не я...
|
|
|
|
|
Sep 1 2008, 10:02
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата То есть был 127, стал 128 - меняем старший байт? Я исправился  дописал еще, причем другим постом, дабы пришло уведомление. Цитата Да и что значит изредка? Изредка - это значит при максимальной частоте входного сигнала не реже чем 64 прерывания (вот я и взял с потолка число 50). Вполне можно запустить флаг задачи от таймерного прерывания. Цитата С точки зрения технических требований задачи переменная pos должна быть 32 битной. Ну изменяйте 3 дополнительных байта, не суть. Не надо их в каждом прерывании носить туда-сюда, вот я о чем.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Sep 1 2008, 10:43
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(PhX @ Sep 1 2008, 11:07)  Реально прерывания от таймера "шлепают" с частотой 12 кГц, а от INT0 с частотой около 30 кГц, причем это тоже, вероятно с запасом.  Ft / Fi = 2/5 Если пропорция между частотой таймера и INT0 сохранится при INT0 = 250kHz. То 83 такта достаточно. Система не потеряет ни одного прерывания. используя цифры приведенные уважаемыми форумчанами выше обработка INT0 - 27 тактов, INT0 + таймера = 83 такта, мин. период Fosc / Fint0 = 16Mhz/0.25Mhz = 64 такта. Получаем: 64 * 5 = 320 всего тактов на 7 событий. обработка этих событий: 83 * 2 + 27 * 3 = 166 + 81 = 247. 247 / 320 = 77% загрузка процессора.
|
|
|
|
|
Sep 1 2008, 11:00
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(PhX @ Sep 1 2008, 11:07)  p.s. А в WinAVR можно результат работы компилятора как в посте Rst7, да и где взять время выполнения команд? Вообщем как можно быстро расчитать время обработки прерывания? Код avr-gcc ключи_как_при_компиляции -S foo.c Получите файл foo.S, который можно при большом желании подредактировать отдать avr-as на обработку (что и делает gcc без ключа -S). Либо в ключи компиляции добавить Код -Wa,-ahlmsd=$(<:.c=.lst) это если оно пойдёт в правило в makefile, а если вручную, то тогда Код -Wa,-ahlmsd=foo.lst для файла foo. Это будет именно листинг, а не ассемблерный исходник. Предупреждаю сразу, мелкий обработчик прерывания после avr-gcc выглядит несколько грустнее, чем после IAR - avr-gcc делает лишнее для мелкого обработчика сохранение/восстановление __temp_reg__ и сохранение/очистку/восстановление __zero_reg__ (в мелких обработчиках они, как правило, невостребованы, так как являются "нижними" регистрами и с ними не всё можно сделать). Этот десяток циклов avr-gcc-шный обработчик и проиграет IAR-овскому. Я бы рекомендовал очень критичные обработчики писать на асме в отдельном асм-файле. Да, Rst7 праивльно напомнил ещё и про avr-objdump Это даст листинг полностью собранной программы вместе со стартапом и библиотеками да вдобавок с реальными адресами. Код avr-objdump -d -S project.elf >project.dump Как правило достаточно посмореть выдачу компилятора по -S либо листинг одного файла, как указано выше, но иногда бывает нужно потрошить содержимое после линковки.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Sep 1 2008, 11:03
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(defunct @ Sep 1 2008, 09:43)  Если пропорция между частотой таймера и INT0 сохранится при INT0 = 250kHz. То 83 такта достаточно. Система не потеряет ни одного прерывания Вывод такой, если прерывания int0 возникают каждые 64 такта, то само прерывание int0 не должно выполняться более, чем за 64-9=55 тактов. 9 тактов нужны, чтобы войти в прерывание от таймера и разрешить остальные прерывания. При подсчёте тактов не учитывался джиттер от завершения команды перед входом в прерывание. Автору следует посчитать время выполнения int0, особенно в свете новых сведений, что переменная pos должна быть 32-битной.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Sep 1 2008, 11:07
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата 77% загрузка процессора. Необходимо учесть еще периодический вызов проверки переполнения счетчика энкодера и коррекции старшей части. Но это, в принципе, будет пыль. Кстати, где вы там нашли 83 такта на все? 27+36, а если сделать через таймерное прерывание через OCR, то еще меньше. Цитата Автору следует посчитать время выполнения int0, особенно в свете новых сведений, что переменная pos должна быть 32-битной. Не надо трогать все 32 бита
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Sep 1 2008, 11:20
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(Rst7 @ Sep 1 2008, 14:02)  Кстати, не пора ли любителям гнуся озаботиться патчем для него, дабы он смотрел, востребованы ли в обработчике эти регистры? Да давно пора, но некому :-( Я вон обещал потестить один патч и то утонул на несколько недель, даже на форумы почти не заглядывал. Что-то тормозить голова начинает :-( Куда уж в потрохах разбираться. А тот небольшой коллектив, который что-то реальное делает - просто не успевает всё.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Sep 1 2008, 11:34
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(PhX @ Sep 1 2008, 11:07)  p.s. А в WinAVR можно результат работы компилятора как в посте Rst7, да и где взять время выполнения команд? Вообщем как можно быстро расчитать время обработки прерывания? Проэмулировать прерывание в AVR-Studio. Запускаем отладку, открываем окно дизассемблера. Запускаем выполнение программы. Жмем паузу. убеждаемся что стоим не на команде ®JMP/®CALL/RET. Ставим точку останова на сл. команду. Выставляем условия для возбуждения проверяемого обработчика. Запоминаем показания счетчика циклов в отладчике как C0. жмем "run". считываем показания счетчика циклов как C1. Время выполнения обработчика соответвенно (C1 - C0) + 4 такта макс длинная команда во время выполнения которой произошло прерывание. еще вариант: Открываем дизассемблер в отладчике, ставим break point на вектор интересующего прерывания. Запускаем отладку. Запоминаем C0 когда отладчик остановится, по шагам проходим обработчик прерывания пока из него не выйдем, тогда запоминаем C1. Время работы обработчика будет C1 - C0 + Tcall + 3такта => C1 - C0 + 8 PS: Cycle Counter находится в view->toolbars->processor. Цитата(Rst7 @ Sep 1 2008, 14:07)  Кстати, где вы там нашли 83 такта на все? 27+36, а если сделать через таймерное прерывание через OCR, то еще меньше. Это не я нашел, это =GM= нашел в #46, его спросите  Если меньше тогда вообще никаких вопросов.
|
|
|
|
|
Sep 1 2008, 11:40
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Rst7 @ Sep 1 2008, 10:24)  Дык пользуйте вменяемые компиляторы  А я на асме, по старинке (:-). Хочется тратить время на задачу, а не на борьбу с компилятором, пусть и вменяемым. К примеру, у вас прерывание выполняется за 27 тактов для 8-битных переменных, а у меня на асме - за 17 для 16-битных, прямо в лоб, даже без оптимизации. Потому и спрашивал код для 16-битных. А уж что будет для 32-битных, даже не могу представить.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Sep 1 2008, 11:45
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата К примеру, у вас прерывание выполняется за 27 тактов для 8-битных переменных, а у меня на асме - за 17 для 16-битных, прямо в лоб, даже без оптимизации. Ага, знаем. Значения уже в регистрах, читать их из ОЗУ не надо, SREG сохраняем прямо в отведенный только для этих целей регистр. Я так тоже могу. Только неспортивно. Добавьте все сохранение/восстановление - и резултат будет тем-же.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Sep 1 2008, 11:50
|

Местный
  
Группа: Свой
Сообщений: 473
Регистрация: 10-09-06
Из: Тольятти. Самарская обл.
Пользователь №: 20 249

|
Цитата(Rst7 @ Sep 1 2008, 16:24)  Дык пользуйте вменяемые компиляторы  Если не жалко пульните в PM ссылку где можно скачать свежий пролеченный IAR, а то на ftp какой-то старенький лежит. Цитата А я на асме, по старинке (:-). Асм это хорошо, но голова одна, а разновидностей процессоров все больше и больше...
--------------------
Если все, то не я...
|
|
|
|
|
Sep 1 2008, 12:05
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Rst7 @ Sep 1 2008, 10:45)  Значения уже в регистрах, читать их из ОЗУ не надо, SREG сохраняем прямо в отведенный только для этих целей регистр. Я так тоже могу. Только неспортивно. Добавьте все сохранение/восстановление - и результат будет тем-же При чём здесь вы? Это должен делать компилятор, причём во всех мыслимых и немыслимых ситуациях, тогда так и быть, буду его использовать. Спортивно, неспортивно...чтобы прочувствовать разницу между 17 тактами и 27, представьте вашу зарплату 17000 или 27000 гривен...
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Sep 1 2008, 12:18
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата Это должен делать компилятор, причём во всех мыслимых и немыслимых ситуациях, тогда так и быть, буду его использовать. Хорошее желание. Вот только качество кода, когда будет отнято минимум 2 верхних регистра у остальной программы оставит желать лучшего... Цитата чтобы прочувствовать разницу между 17 тактами и 27, представьте вашу зарплату 17000 или 27000 гривен... Именно. За 27 тактов я заработаю 27000 гривен. Потому как кроме этого прерывания есть еще остальная программа, наверняка намного объемнее. И ее я буду очень долго ваять на асме. Было бы всего 30 строк - нет проблем... Обычная проблема time-to-market. Давайте не будем спорить C vs Asm...
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Sep 1 2008, 12:56
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(PhX @ Sep 1 2008, 10:50)  Асм это хорошо, но голова одна, а разновидностей процессоров все больше и больше... То-то все сишники то и дело рассматривают ассемблерный код (:-). А чего на него смотреть, если вы пишете на си? Или вот, попробуйте перенести ваш сишный код двух прерываний на пик18. Думаете не надо будет ничего делать? Как бы не так. Или вы думаете, заменив одни трудности другими, будет легче? Вот на вскидку два сообщения о глюках в компиляторе иар http://electronix.ru/forum/index.php?showtopic=40698, http://electronix.ru/forum/index.php?showtopic=40231. Ещё раз повторю, хочется тратить время на задачу, а не на борьбу с компилятором.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Sep 1 2008, 13:12
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(=GM= @ Sep 1 2008, 15:56)  То-то все сишники то и дело рассматривают ассемблерный код (:-). А чего на него смотреть, если вы пишете на си? Вообще-то это очень редкое занятие. Я например в своих проектах практически никогда не рассматриваю асм код, про причине "нахренненужности" © zltigo. На глаз видно потянет или не потянет тот или иной проц, ту или иную задачу. Цитата Или вот, попробуйте перенести ваш сишный код двух прерываний на пик18. Думаете не надо будет ничего делать? Как бы не так. Конечно настройку периферии нужно будет переделать. А в остальном (при организации программы, как приводил выше в #24 ничего менять не придется). Цитата Или вы думаете, заменив одни трудности другими, будет легче? Определенно.
|
|
|
|
|
Sep 1 2008, 15:19
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Цитата(PhX @ Sep 1 2008, 14:50)  Если не жалко пульните ссылку где можно скачать свежий IAR пулька на полную рабочую с к-р-я-к-о-м внутри
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
Sep 1 2008, 15:25
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(defunct @ Sep 1 2008, 12:12)  Определенно Ну, прекрасно, раз трудностей нет. Предлагаю в качестве эксперимента написать для авр на си программную выдачу 37-бит данных, сопровождаемых стробом: 1) смена бита на линии D 2) выждатьТо 3) строб=1 на линии C 4) выждать 2*То 5) строб=0 на линии C 6) выждатьТо 7) повторить пп1-6 N=37 раз Простая задача, раз плюнуть. А потом перенести сишный код на другую платформу - ЦСП TMS320F2808, To=50нс. Вот мой код для референса Код sndbit: mov *xar5,ah mov @th,ah nop nop or @th,#0x0002 mov *xar5,t lsr ah,#1 lsl64 acc:p,#1 rpt #6-2 ||nop and @th,#~0x0002 mov *xar5,t banz sndbit,ar0-- tset *xar5,#2 Клок 100 МГц, 1такт=10нс, 20 тактов на бит, битовая скорость 5Мбит/с. Для авр 20 МГц клок ожидается 5=100/20 раз меньшую скорость, т.е. 1 МГц.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Sep 1 2008, 15:47
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(=GM= @ Sep 1 2008, 18:25)  Ну, прекрасно, раз трудностей нет. Предлагаю в качестве эксперимента написать для авр на си программную выдачу 37-бит данных, сопровождаемых стробом:
Клок 100 МГц, 1такт=10нс, 20 тактов на бит, битовая скорость 5Мбит/с. Для авр 20 МГц клок ожидается 5=100/20 раз меньшую скорость, т.е. 1 МГц. ОК  Что может быть проще. Берем M8515 @16Mhz. Включаем внешнюю шину. Стоит ли продолжать?  Код // сразу 8 каналов, скорость порядка 4Mbps void IO_Transfer( U8 *p ) { U8 size = 37;
__disable_interrupt(); while(size--) { *(volatile U8 *)0x8000 = *p++; delay_cycles( еще и тормозить придется чтобы 1Mbps получить); } __enable_interrupt(); } предварительно заполняем массив из 37 элементов данными которые хотим слать и передаем указатель на этот массив в IO_Transfer. PC7 - признак работы нашего "serial" канала. Строб снимаем с сигнала W. Данные с ШД.
|
|
|
|
|
Sep 1 2008, 16:25
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(=GM= @ Sep 1 2008, 18:14)  ...как быть? Думать. В каждом конкретном случае - думать. И написав десяток строк даже самых лучших строк на ASM не закрывать глаза и уши на то, что программы по нынешним временам не состоят из нескольких десятков команд и занимаются не только ногомаханием. И контроллеров вокруг изрядное количество всяких и выбирать нужно подходящий не только по приципу знакомого ASM. P.S. Сейчас глянул, какой максимальный функциональный кусок на ASM я написал за последние несколько лет - ровно 50 команд  . Причем это не из-за скоростных наворотов - это минимальный обработчик exceptions для ARM. На алгоритмических языках такое просто нормально не пишется.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Sep 1 2008, 16:38
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(=GM= @ Sep 1 2008, 19:14)  Ну, а если перенести на другой проц, будет та же самая программа? А там ШД нет, и W тоже нет, как быть? Задачи такого рода, можно сказать классический пример задач для FPGA/CPLD. Отдавать всю производительность МК под эмуляцию железа конечно можно, но это не всега будет рациональным решением. Если эта функция - самоцель (i.e. это ВСЯ или значительная часть работы которую должен делать МК), то я не побрезгую написать всю такую небольшую программу на асм'е. Если же это только 1% или меньше от всего задания, я предпочту аппаратное решение интерфейса и простую программную обертку на C.
|
|
|
|
|
Sep 1 2008, 20:32
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Краткие выводы из всех наших долгих разговоров.
1) Эксперимент показал (Юра, извини), что сишные программы не так уж и переносимы, как принято думать. 2) На переносимость влияет не только периферия, но и архитектура процессора. Например, один из самых простых алгоритмов в моём проекте - вычисление комплексного спектра аналитической функции - практически невозможно переложить с си-программы авр на си-программу дсп, ручками придётся добиваться "адекватности" алгоритма системе команд и архитектуре. 3) Из порядка 100 файлов проекта примерно 70 написаны на асме, причем последние занимают 90% процессорного времени. Поэтому каждую асм-программу приходилось тщательно вылизывать. 4) Применение аппаратных решений в виде FPGA приветствуется, но дорого, особенно для больших серий. 5) Пожелание начинающим имбеддерам: знание ассемблера применённого проца обязательно. 6) Из моего опыта. Все асм-программы я оформляю в соответствии с конвенциями вызова из си-программы, очень удобно, не надо беспокоиться, из какой программы они вызываются.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Sep 1 2008, 21:50
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(=GM= @ Sep 1 2008, 22:32)  3) Из порядка 100 файлов проекта примерно 70 написаны на асме, причем последние занимают 90% процессорного времени. Поэтому каждую асм-программу приходилось тщательно вылизывать. Из 138 файлов текущего проекта c размером бинарника 202623 байта работающего на контроллере ценою менее 6USD на ASM писаны три: - стартап; - переключатель контекста; - memcpy/memmove/memset (на самои деле традиция оставшиеся со времен хреновенькой библиотеки IAR V4 - убрать можно) В сумме байт 300. Процентов 55 проекта это просто ранее работавший код на 51, 186 контроллерах и 486 под линуксом. Остальной просто новый  . Дописав/переписав не более 1000 строк из 65333 я перенесу его на, практически любой приличный контроллер. Вот такие выводы  , понимаш.... Посему с очередными рассуждениями о писательстве на ASM, тем более в совершенно не для этого созданной ветке завязываем.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Sep 2 2008, 12:17
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(SasaVitebsk @ Sep 2 2008, 08:58)  В связи с этим необходимо осмыслить необходимость вылизывания задачи до уровня загрузки проца 99%, что приведёт к некоторым сложностям по развитию проекта. А попробовать разбить задачу на несколько. Либо подобрать такой МК, который будет соответствовать решаемой задаче с некоторым запасом производительности Вообще, так и делалось. Сначала был выбран TMS320F2812, 150 МГц такт, 128 Кб флеши, потом по мере выработки и устаканивания концепции плавно опустились до TMS320F2810 и TMS320F2808, и наконец, до TMS320F2801, куда планируется заливать фирменный софт, уже масочный. Даже в последнем проце ресурсы задействованы примерно на 80%. По стоимости первый проц и последний различаются раза в 4. А вылизывания особого не было, как писалось, так и писалось, с максимальным быстродействием по возможности.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|