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

 
 
7 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> STM32F407 + прерывание + время реакции, Меняется время реакции на внешнее событие
ШСА
сообщение Jul 26 2015, 19:07
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Дорогие коллеги!
Сталкивался ли кто нибудь с такой тонкой и непонятной мне проблемой - значительным изменением времени входа в обработчик прерывания по внешнему событию в зависимости от команд, выполняемых в этот момент в основной программе?
Конкретная ситуация: В микроконтроллере STM32F407 в main-е крутится некая большая программа. Когда наступает внешнее событие, а именно - отрицательный фронт на EXTI_Line1, вызывается обработчик прерывания void EXTI1_IRQHandler(void). В нём обнуляется таймер TIM6, тактируемый частотой 84 МГц, и начинается вывод информации в виде набора импульсов, привязанных к значениям TIM6. Когда вывод закончен - выходим из обработчика (TIM6 оставляем молотить впустую).
Замечено следующее: Время от момента внешнего события до появления первого импульса на выходе нестабильно и меняется (по осциллографу) более чем на 0,2 мкс при тактировании ядра 168 МГц. Иными словами, время вызова обработчика может увеличиваться (или уменьшаться) аж на 34 такта! Причём меняется оно в зависимости от кода, выполняемого в данный момент в main-е. Самое большое изменение этого времени (в сторону уменьшения) происходит при выполнении (в main-е) цикла очистки области памяти:
for(i = 0; i < 60768; i++) *j++ = Сonst;

А согласно описанию на Cortex-3 время вызова обработчика прерывания составляет от 6 до 11 тактов ядра. И уж никак не должно зависеть от содержания прерываемой программы (DMA не используется)! wacko.gif

В чём причина этого явления и как с ним бороться?
Буду признателен за любые идеи или информацию.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 26 2015, 19:29
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(ШСА @ Jul 26 2015, 22:07) *
...никак не должно зависеть от содержания прерываемой программы (DMA не используется)! wacko.gif

В некоторой степени все же зависит.

Цитата(ШСА @ Jul 26 2015, 22:07) *
В чём причина этого явления и как с ним бороться?
Буду признателен за любые идеи или информацию.

Непредсказуемую задержку может вносить работа кэш контроллера флеш-памяти.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jul 27 2015, 03:03
Сообщение #3


Универсальный солдатик
******

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



Может, нестабильную задержку создает перезапуск таймера, а не вход в прерывание. Задайте в прерывании дергание ножкой порта, для проверки.
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 27 2015, 05:46
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(aaarrr @ Jul 26 2015, 22:29) *
В некоторой степени все же зависит.


Непредсказуемую задержку может вносить работа кэш контроллера флеш-памяти.


Интересная мысль - а сколько может вносить, и чем можно на эту задержку влиять?
Вообще в STM32F4, если верить описанию, время отклика на событие прерывания составляет 12 тактов - если прерывается фоновая программа, 6 тактов - если прерывается другое низкоприоритетное прерывание, 18 тактов - если прерывание произошло в момент выхода из другого прерывания (выход из прерывания занимает 12 тактов). В итоге имеем максимально возможный шум (или биения) на выходе до: 18 - 6 = 12 тактов. Для тактовой частоты 168 МГц это составит 0,072 мкс. И это максимум! А у меня в реале - 0,2 мкс. Причём даже с отключёнными другими прерываниями.
Что касается зависимости от фоновой программы. Учитывая, что в STM32F407 организован аппаратный конвейер, влияние фоновой программы на обработчик, вернее на время его вызова, не должно быть вообще! А у меня оно есть, да ещё какое сильное!
Я уж даже думал, что столь короткий цикл в фоновой программе так меняет ток потребления МК, что не выдерживает стабилизатор питания, и поэтому сбивается PLL в STM32F4. Но это не подтвердилось - обвешанный большими ёмкостями МК ведёт себя точно также, как и в стандартном включении.
Go to the top of the page
 
+Quote Post
Огурцов
сообщение Jul 27 2015, 05:53
Сообщение #5


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



а если умножить на 5 тактов ожидания, то получится даже хуже вашего, или ваше в среднем
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 27 2015, 06:09
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(ViKo @ Jul 27 2015, 06:03) *
Может, нестабильную задержку создает перезапуск таймера, а не вход в прерывание. Задайте в прерывании дергание ножкой порта, для проверки.


Нет, это исключено. Период внешнего события - 64 мкс, а период перезапуска таймера вдвое больше (я по нему идентифицирую исчезновение внешнего сигнала). Сброс таймера в единственном месте - вторая команда обработчика прерывания.
Да и потом - даже если таймер что-то там делает, влияние на задержку реакции оказывает именно содержание фоновой программы. Это проверено: когда я закомментировал цикл очистки памяти в фоновой программе, это явление исчезло!

Цитата(Огурцов @ Jul 27 2015, 08:53) *
а если умножить на 5 тактов ожидания, то получится даже хуже вашего, или ваше в среднем


Не понял кто кого ждёт.
Все команды фоновой программы занимают по 1 такту. DMA нет. Реакция на внешнее событие определяется укладкой в стек информации о возврате и занимает от 6 до 18 тактов. Я отключал все другие прерывания, в этом случае реакция должна быть максимально стабильной - 12-13 тактов. Т.е. нестабильность реакции - 1 такт! А у меня в реальности ничего не меняется - фоновая программа непостижимым образом изменяет время реакции на прерывания до 34 тактов!


Цитата(Огурцов @ Jul 27 2015, 08:53) *
а если умножить на 5 тактов ожидания, то получится даже хуже вашего, или ваше в среднем


Не понял кто кого ждёт.
Все команды фоновой программы занимают по 1 такту. DMA нет. Реакция на внешнее событие определяется укладкой в стек информации о возврате и занимает от 6 до 18 тактов. Я отключал все другие прерывания, в этом случае реакция должна быть максимально стабильной - 12-13 тактов. Т.е. нестабильность реакции - 1 такт! А у меня в реальности ничего не меняется - фоновая программа непостижимым образом изменяет время реакции на прерывания до 34 тактов!
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 27 2015, 06:27
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Попробуйте сделать следующее:
1. Внешнее прерывание замените на прерывание от таймера с высокой тактовой частотой (84МГц). При входе в прерывание считывайте CNT. Так получите значительно более точное измерение времени входа.
2. Перенесите обработчик в RAM, сравните результаты.
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 27 2015, 06:41
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(aaarrr @ Jul 27 2015, 09:27) *
Попробуйте сделать следующее:
1. Внешнее прерывание замените на прерывание от таймера с высокой тактовой частотой (84МГц). При входе в прерывание считывайте CNT. Так получите значительно более точное измерение времени входа.
2. Перенесите обработчик в RAM, сравните результаты.


Маленькое уточнение - эти два пункта надо сделать одновременно или по одному?
Пункт 1, я понял, нужен, чтобы исключить биения внешней частоты и источника тактирования МК. Я это попробую сегодня сделать. А вот пункт 2 - поясните. Я такого никогда не делал и не знаю (пока) как это сделать. Но главное - зачем, ведь в описании на Cortex, насколько я помню, программа из RAM выполняется медленнее, чем из FLASH. А у меня и так МК едва успевает выполнять нужную работу, причём только после оптимизации компилятором. Если замедлить работу обработчика, работа программы развалится и уже ничего невозможно будет измерить.
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 27 2015, 06:49
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Вот тут расписано про задержку на входе в обработчик прерывания у Cortex-M3 и Cortex-M4: "between eight and 32 cycles if the floating point context in a Cortex-M4 with FPU is stacked immediately".
Кстати, у вас нигде прерывания не запрещаются? Атомарные операции и всё такое.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 27 2015, 06:52
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Интересно сравнить результаты при работе из флеш и RAM.
Про пункты:
1. Чтобы исключить осциллограф прежде всего sm.gif
2. Программа из RAM выполняется примерно с той же скоростью, что из "ускоренной" флеш. Немного медленнее, зато гораздо более предсказуемо.
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 27 2015, 07:00
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(aaarrr @ Jul 27 2015, 09:52) *
2. Программа из RAM выполняется примерно с той же скоростью, что из "ускоренной" флеш. Немного медленнее, зато гораздо более предсказуемо.

Всё не так просто. Можно разогнать программу в ОЗУ. Для этого код должен сидеть в куске ОЗУ 112 КБ (начинается с адреса 0x20000000), подключенном к I-bus, ОЗУ надо замапить на адрес 0, а данные расположить в CCM (64 КБ). В этом случае всё должно работать с нулевыми задержками.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 27 2015, 07:04
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(scifi @ Jul 27 2015, 10:00) *
Можно разогнать программу в ОЗУ.

Можно, просто для проверки предположения о влиянии "ускорителя" флеш это не нужно.
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 27 2015, 07:12
Сообщение #13


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(scifi @ Jul 27 2015, 09:49) *
Вот тут расписано про задержку на входе в обработчик прерывания у Cortex-M3 и Cortex-M4: "between eight and 32 cycles if the floating point context in a Cortex-M4 with FPU is stacked immediately".
Кстати, у вас нигде прерывания не запрещаются? Атомарные операции и всё такое.


Спасибо за ссылочку: на первый же взгляд вижу намёк на причину - на возможные такты ожидания при обращении к слову по частям. А ведь у меня этого много. Буду разбираться.
Прерывания не запрещаются. Флаги очищаются в конце обработчика, так что вложенные прерывания исключены.
Атомарные операции... Наверное, вы правы! Для экономии памяти я сплошь работаю с невыровненными данными в ОЗУ, а ведь это может приводить к аппаратным задержкам! Это похоже на правду, ведь цикл очистки массива у меня идёт по байтовому указателю.
Go to the top of the page
 
+Quote Post
Timmy
сообщение Jul 27 2015, 07:30
Сообщение #14


Знающий
****

Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515



Цитата(ШСА @ Jul 26 2015, 22:07) *
Дорогие коллеги!
Сталкивался ли кто нибудь с такой тонкой и непонятной мне проблемой - значительным изменением времени входа в обработчик прерывания по внешнему событию в зависимости от команд, выполняемых в этот момент в основной программе?
Конкретная ситуация: В микроконтроллере STM32F407 в main-е крутится некая большая программа. Когда наступает внешнее событие, а именно - отрицательный фронт на EXTI_Line1, вызывается обработчик прерывания void EXTI1_IRQHandler(void). В нём обнуляется таймер TIM6, тактируемый частотой 84 МГц, и начинается вывод информации в виде набора импульсов, привязанных к значениям TIM6. Когда вывод закончен - выходим из обработчика (TIM6 оставляем молотить впустую).

Если вам надо обеспечить постоянное время реакции на фронт входного сигнала, то следует защёлкнуть этот фронт в capture unit, и привязать выходные сигналы к защёлкнутому времени таким образом, чтобы процессор всегда успевал среагировать. Правда, время реакции получится по-максимуму, зато стабильно. Если нужно совсем быструю реакцию, лучше использовать FPGA.
Время входа в прерывание можно сократить, если использовать FIQ, а не IRQ, но его на большинстве кортексов нет.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jul 27 2015, 07:49
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Флаги очищаются в конце обработчика, так что вложенные прерывания исключены.

Вроде это как раз гарантия создания повторного прерыванияsm.gif Вложенные прерывания у вас исключает NVIC, а вот очищенный в конце флаг может вызвать прерывание повторно из-за конвейеров, нужны будут барьеры на выходе.

Опять же ускоритель флешь, если вы попадаете не на 16 на 32 битные команды то ему больше 4 команд не выбрать, а частота выборки команд у него в почти 8 раз меньше, так что скакнув прерыванием в не закишированную область, да еще и попав на 32 битную команду, у вас все здорово притормозится, а в след раз вы можете попасть уже в область выбранную и сохраненную в ускорителе, а потом вы ее можете почистить и так по кругу, так что у вас там есть где набрать нестабильность ИМХО...

Цитата
ремя входа в прерывание можно сократить, если использовать FIQ, а не IRQ, но его на большинстве кортексов нет.

Я могу ошибаться, но вроде как в кортексах уже NVIC, и потому деления на быстрое и медленное уже нет ни в большинстве, а во всех кортексах...
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 27 2015, 08:04
Сообщение #16


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(Timmy @ Jul 27 2015, 10:30) *
Если вам надо обеспечить постоянное время реакции на фронт входного сигнала, то следует защёлкнуть этот фронт в capture unit, и привязать выходные сигналы к защёлкнутому времени таким образом, чтобы процессор всегда успевал среагировать. Правда, время реакции получится по-максимуму, зато стабильно.


Ну, собственно, мой обработчик IRQ это и делает, только без использования capture unit. По наступлении события таймер сбрасываем, а потом, следя за его изменением, пишем в выходной порт данные из ОЗУ. Время между началом события и первым выходным импульсом = 10,5 мкс. За это время я успеваю многое пересчитать и даже запустить АЦП. Во всяком случае две трети времени от этих 10,5 мкс занимает цикл ожидания.
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 27 2015, 08:08
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(ШСА @ Jul 27 2015, 11:04) *
Ну, собственно, мой обработчик IRQ это и делает, только без использования capture unit. По наступлении события таймер сбрасываем, а потом, следя за его изменением, пишем в выходной порт данные из ОЗУ. Время между началом события и первым выходным импульсом = 10,5 мкс. За это время я успеваю многое пересчитать и даже запустить АЦП. Во всяком случае две трети времени от этих 10,5 мкс занимает цикл ожидания.

А нельзя ли по событию сделать DMA для сброса таймера и запуск обработки прерывания для вычислений? У DMA джиттер поменьше должен быть.
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 27 2015, 08:18
Сообщение #18


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



[quote name='Golikov A.' date='Jul 27 2015, 10:49' post='1354043']
Вроде это как раз гарантия создания повторного прерыванияsm.gif Вложенные прерывания у вас исключает NVIC, а вот очищенный в конце флаг может вызвать прерывание повторно из-за конвейеров,

Это для меня новость. NVIC не будет вызывать прерывания, пока я в обработчике не сброшу флаг своего вектора. А я это делаю в конце. Как может быть вложенный вызов?

Опять же ускоритель флешь, если вы попадаете не на 16 на 32 битные команды то ему больше 4 команд не выбрать, а частота выборки команд у него в почти 8 раз меньше, так что скакнув прерыванием в не закишированную область, да еще и попав на 32 битную команду, у вас все здорово притормозится,

Так прерывание, как непредсказуемое событие, в принципе не может быть закэшировано. Так что конвейер должен быть перезагружен. Потому у STM32F4 время реакции = 6-12 тактов. Вернее должно быть, а вот у меня бывает более 34-х!
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 27 2015, 08:29
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(ШСА @ Jul 27 2015, 11:18) *
Так прерывание, как непредсказуемое событие, в принципе не может быть закэшировано.

Неправда. Если между двумя прерываниями процессор крутится в маленьком цикле (как у вас при очистке памяти), то он может не успеть выбросить из кэша код обработчика прерывания. Тогда вход в обработчик прерывания будет быстрее. Кстати, это легко проверить: на выходе из прерывания нужно сбрасывать кэш, есть для этого соответствующий регистр.
Go to the top of the page
 
+Quote Post
LightElf
сообщение Jul 27 2015, 08:29
Сообщение #20


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

Группа: Участник
Сообщений: 180
Регистрация: 5-04-09
Пользователь №: 47 205



QUOTE (ШСА @ Jul 27 2015, 11:18) *
Так прерывание, как непредсказуемое событие, в принципе не может быть закэшировано. Так что конвейер должен быть перезагружен. Потому у STM32F4 время реакции = 6-12 тактов. Вернее должно быть, а вот у меня бывает более 34-х!

Выборка 1 команды из флеш-памяти занимает 6 тактов процессора (для частоты 168МГц). При выполнении линейного куска кода флеш-акселератор скрывает эту задержку (потому что считывает по 128 бит). Когда происходит прерывание, флеш-акселератор помочь ничем не может и вы попадаете на максимальную задержку.
Для начала попробуйте перенести в ОЗУ таблицу векторов - получите экономию 5 тактов минимум.

Сообщение отредактировал LightElf - Jul 27 2015, 08:34
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 27 2015, 08:31
Сообщение #21


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(scifi @ Jul 27 2015, 11:08) *
А нельзя ли по событию сделать DMA для сброса таймера и запуск обработки прерывания для вычислений? У DMA джиттер поменьше должен быть.


Интересная мысль насчёт DMA. Как-то не думал о таком варианте. Вообще я DMA как-то побаиваюсь, потому что процессор может "уснуть" неизвестно когда. Но впрочем, это мои фобии. А джиттер в реальности слишком велик (34 такта - не кот чихнул), и блохи от DMA здесь не играют роли.
Ведь главное - понять необычность ситуации: фоновая программа влияет на скорость вызова обработчика. Ведь она не привязана к внешним событиям, чего-то там себе считает и считает. А у обработчика при этом плавает время реакции! Да плавает-то как - в три раза превышает допуск!
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jul 27 2015, 08:35
Сообщение #22


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

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



Мне кажется, что самый здравый совет был вот этот:
Цитата(ViKo @ Jul 27 2015, 08:03) *
Задайте в прерывании дергание ножкой порта, для проверки.

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


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Огурцов
сообщение Jul 27 2015, 08:36
Сообщение #23


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



Цитата(ШСА @ Jul 27 2015, 06:09) *
Не понял кто кого ждёт

флеш и кэш
выше правильное предложение - выполнять из озу, работать будет медленнее, но гораздо стабильнее
а ну да, можно загнать тактовую на 24 мгц с нулевым ожиданием и посмотреть на результат


Сообщение отредактировал Огурцов - Jul 27 2015, 08:38
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 27 2015, 08:40
Сообщение #24


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(scifi @ Jul 27 2015, 11:29) *
Неправда. Если между двумя прерываниями процессор крутится в маленьком цикле (как у вас при очистке памяти), то он может не успеть выбросить из кэша код обработчика прерывания. Тогда вход в обработчик прерывания будет быстрее. Кстати, это легко проверить: на выходе из прерывания нужно сбрасывать кэш, есть для этого соответствующий регистр.


Интересная мысль!!! А ведь у меня при очистке памяти время реакции именно уменьшается!
Чтобы мне не копаться, подскажите, как очистить кэш (желательно на языке СИ).
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 27 2015, 08:59
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(ШСА @ Jul 27 2015, 11:40) *
Интересная мысль!!! А ведь у меня при очистке памяти время реакции именно уменьшается!
Чтобы мне не копаться, подскажите, как очистить кэш (желательно на языке СИ).

Я углядел нужные биты в регистре FLASH_ACR. А дальше сами читайте, там вроде бы понятно написано.
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 27 2015, 09:02
Сообщение #26


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(Огурцов @ Jul 27 2015, 11:36) *
флеш и кэш
выше правильное предложение - выполнять из озу, работать будет медленнее, но гораздо стабильнее
а ну да, можно загнать тактовую на 24 мгц с нулевым ожиданием и посмотреть на результат


24 МГц можно попробовать, чтобы не переделывать программу. С единственной целью убедиться в исчезновении этого явления. Жаль только, что будет много паяльных работ, т.к. тактовая частота МК в моей системе имеет критическое значение.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jul 27 2015, 09:15
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



1. Можно отключить флэщ акселератор и тогда время будет стабильное, медленное, но стабильное.

2. По поводу
Цитата
так что конвейер должен быть перезагружен. Потому у STM32F4 время реакции = 6-12 тактов.
Там не только в конвейере дело, а еще в сохранении контекста

Цитата
Это для меня новость. NVIC не будет вызывать прерывания, пока я в обработчике не сброшу флаг своего вектора. А я это делаю в конце. Как может быть вложенный вызов?

3.1 НВИК не будет повторно вызывать прерывание даже если вы сбросите в начале и оно опять случиться, пока не выйдете из этого прерывания повторный вызов того же приоритета не проихойдет
3.2. А вот сбрасывая флаг в конце вы имеете шанс выйти из прерывания до того как флаг реально сброситься, там что-то с конвейерами и перестановкой команд, и выйдя из прерывания НВИК ловит не сброшенный флаг и повторно входит в прерывание.
Так что вложенного вызова не будет, а вот повторный вполне может быть.
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 27 2015, 09:52
Сообщение #28


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(Golikov A. @ Jul 27 2015, 12:15) *
1. Можно отключить флэщ акселератор и тогда время будет стабильное, медленное, но стабильное.

2. По поводу Там не только в конвейере дело, а еще в сохранении контекста


3.1 НВИК не будет повторно вызывать прерывание даже если вы сбросите в начале и оно опять случиться, пока не выйдете из этого прерывания повторный вызов того же приоритета не проихойдет
3.2. А вот сбрасывая флаг в конце вы имеете шанс выйти из прерывания до того как флаг реально сброситься, там что-то с конвейерами и перестановкой команд, и выйдя из прерывания НВИК ловит не сброшенный флаг и повторно входит в прерывание.
Так что вложенного вызова не будет, а вот повторный вполне может быть.


Это важно, я это изучу. Спасибо.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 28 2015, 02:43
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Выключите сохранение контекста FPU при стэкинге (и резервирование места для него): FPCCR = 0;

Цитата(ШСА @ Jul 27 2015, 14:40) *
Интересная мысль!!! А ведь у меня при очистке памяти время реакции именно уменьшается!
Чтобы мне не копаться, подскажите, как очистить кэш (желательно на языке СИ).

Зачем его чистить? Перенесите ISR в ОЗУ как уже советовали. Причём начало его выровняйте на адрес, кратный размеру строки выборки команд CPU
(вроде STM407 выбирает команды строками по 128байт). И таблицу векторов - тоже в ОЗУ. Лучше - в CCM.

Но самое правильное решение - конечно использовать DMA, выставив ему приоритет доступа к шине выше чем CPU.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 28 2015, 06:37
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(jcxz @ Jul 28 2015, 05:43) *
Перенесите ISR в ОЗУ как уже советовали. Причём начало его выровняйте на адрес, кратный размеру строки выборки команд CPU
(вроде STM407 выбирает команды строками по 128байт).

Для ОЗУ выравнивать ничего не нужно - выборка строками по 128 бит идет только из флеш.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 28 2015, 09:17
Сообщение #31


Гуру
******

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



QUOTE (Golikov A. @ Jul 27 2015, 10:49) *
потому деления на быстрое и медленное уже нет ни в большинстве, а во всех кортексах...

Подсказка - "все кортексы" НЕ кончаются на букве М sm.gif sm.gif



--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jul 28 2015, 09:49
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Справедливо...
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 28 2015, 10:09
Сообщение #33


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(jcxz @ Jul 28 2015, 05:43) *
Выключите сохранение контекста FPU при стэкинге (и резервирование места для него): FPCCR = 0;

Зачем его чистить? Перенесите ISR в ОЗУ как уже советовали. Причём начало его выровняйте на адрес, кратный размеру строки выборки команд CPU
(вроде STM407 выбирает команды строками по 128байт). И таблицу векторов - тоже в ОЗУ. Лучше - в CCM.

Но самое правильное решение - конечно использовать DMA, выставив ему приоритет доступа к шине выше чем CPU.


Вы меня своим заявлением слегка контузили.
Я не знаю что такое контекст FPU и стэкинг. Аппаратный FPU (Floating Point Unit) у меня включён, и выключать его нельзя. Это всё, что я знаю про FPU.
Использовать DMA - что я выиграю, и главное - сколько? Ведь фаза выходного импульса плавает аж на 34 такта!
Перенести ISR в ОЗУ мне кажется здравой идеей, сейчас я продумываю как её осуществить, чтобы себе не сильно напортить.

Ребята! Давайте договоримся - если у кого есть идея, излагайте в таком порядке:
1. Гипотеза, объясняющая природу этого явления, а именно - каким образом фоновая программа может влиять на время реакции на внешнее событие, да ещё в таких масштабах;
2. Способ или механизм исключения или компенсации этих задержек;
3. Конкретные рекомендации;
В противном случае я вынужден по вашим рекомендациям гадать, в чём же заключается идея. А это плохо потому, что я не настолько глубоко знаю STM32F4, чтобы по намёку понять всё, что имелось в виду.
Кстати, если есть примеры как оформить ISR в ОЗУ, а тем более таблицу векторов в CCM, дайте ссылочку, чтобы мне поменьше пришлось наступать на грабли.
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 28 2015, 10:37
Сообщение #34


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(ШСА @ Jul 28 2015, 13:09) *
Ведь фаза выходного импульса плавает аж на 34 такта!

А это хорошо или плохо? Сколько надо? 10 хватит? А 30?
Телепаты в отпуске.

Цитата(ШСА @ Jul 28 2015, 13:09) *
Использовать DMA - что я выиграю, и главное - сколько?

Не очень понятно, что вы там ваяете, но суть предложения такова: сделать так, чтобы фазу формировал контроллер DMA, а не процессор с его неопределённым временем входа в обработчик прерывания. В общем, надеемся, и не без оснований, что у DMA джиттер поменьше, чем 34 такта.
Предвидя вопрос "как?", отвечаю: только вам ведомо, как работает эта ваша адская машина.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jul 28 2015, 11:33
Сообщение #35


Универсальный солдатик
******

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



Цитата(ШСА @ Jul 28 2015, 13:09) *
Ребята! Давайте договоримся - если у кого есть идея, излагайте в таком порядке:
1. Гипотеза, объясняющая природу этого явления...

А вы так и не попробовали дергать ногой в прерывании? Гипотеза в том, что у таймера есть предделитель и счетчик, которые (оба или один из них - вам читать в руководстве) могут перегружаться сразу, а могут, только, когда досчитают до конца. У вас как?
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 28 2015, 12:17
Сообщение #36


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(scifi @ Jul 28 2015, 13:37) *
А это хорошо или плохо? Сколько надо? 10 хватит? А 30?


Чтобы у вас не рисовались монстры в голове, расскажу, что это за машина. Эта штучка получает изображение от видеокамеры. Фоновая программа, никуда не спеша, рассматривает его, выявляет в нём разные особенности, а потом формирует своё изображение, которое, по её мнению, и должно появиться на экране. А выводом изображения как раз и занимается мой обработчик. И он очень спешит - его работа запускается телевизионными синхроимпульсами. Сама по себе начальная задержка не критична, а вот её "плавание" недопустимо. Допуск на фазовый шум планировался на уровне 4 тактов. По результатам испытаний стало ясно, что 10, от силы 12 тактов ещё можно терпеть. В процессе борьбы с шумами мы и выявили эту странную взаимосвязь фоновой программы и обработчика. Кстати, стало ясно, что и происхождение других мелких шумов, скорее всего имеют ту же природу. А вот с природой-то и пошли непонятки.


Цитата(ViKo @ Jul 28 2015, 14:33) *
А вы так и не попробовали дергать ногой в прерывании? Гипотеза в том, что у таймера есть предделитель и счетчик, которые (оба или один из них - вам читать в руководстве) могут перегружаться сразу, а могут, только, когда досчитают до конца. У вас как?


Мой обработчик, сообразуясь со таймером, пересылает данные на выходной порт. Так что дёрганья ног здесь более чем достаточно. Таймер сбрасывается в самом начале прерывания, чтобы "синхронизироваться" с внешним событием (в этом-то и ахиллесова пята алгоритма). До следующего события таймер перезагрузиться не успеет, а если это случилось, значит входной сигнал исчез, и можно "уснуть". Так что во время работы таймер никогда не может перезагружаться сам.
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 28 2015, 12:27
Сообщение #37


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(ViKo @ Jul 28 2015, 14:33) *
А вы так и не попробовали...

У меня тоже некоторый осадок остался по поводу "не пробовали". Тут уже несколько предложений было, которые можно было бы проверить, но, похоже, аффтар просто мотает на ус и ждёт, когда волшебник в голубом вертолёте привезёт готовое решение...
А если пробовали, но результат отрицательный, всё равно озвучьте - интересно ведь.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 28 2015, 12:33
Сообщение #38


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ШСА @ Jul 28 2015, 16:09) *
Я не знаю что такое контекст FPU и стэкинг. Аппаратный FPU (Floating Point Unit) у меня включён, и выключать его нельзя. Это всё, что я знаю про FPU.

Откройте мануал на CortexM, там есть описание что такое stacking. Это собственно - сохранение некоторых регистров CPU при входе в прерывание.
M4, в отличие от M3, умеет сохранять (или резервировать место для сохранения) также регистры FPU. Если у Вас выключено Lazy context save или МК посчитает что по каким-то причинам контекст
FPU тоже надо сохранить, то в стек вместо 8 слов запишется гораздо больше.
Т.е. - если как я понимаю Вы где-то в фоне использовали FPU, то это и произойдёт.

Цитата(ШСА @ Jul 28 2015, 16:09) *
Использовать DMA - что я выиграю, и главное - сколько? Ведь фаза выходного импульса плавает аж на 34 такта!

Не знаю какой выходной импульс Вы имеете в виду, но Вашу задачу - прерывание на входной импульс и сброс таймера в обработчике этого прерывания, может сделать DMA:
делаете запуск DMA-транзакции по этому самому импульсу, этой транзакцией обнуляете таймер. Задержка запуска DMA-транзакции будет неизмеримо меньше времени реакции на прерывание.
Не знаю правда - поддерживает ли такое DMA-контроллер STM32F407? Но в LPC17xx такое возможно. STM32F407 думаю тоже должен уметь.

Цитата(ШСА @ Jul 28 2015, 18:17) *
Мой обработчик, сообразуясь со таймером, пересылает данные на выходной порт. Так что дёрганья ног здесь более чем достаточно. Таймер сбрасывается в самом начале прерывания, чтобы "синхронизироваться" с внешним событием (в этом-то и ахиллесова пята алгоритма). До следующего события таймер перезагрузиться не успеет, а если это случилось, значит входной сигнал исчез, и можно "уснуть". Так что во время работы таймер никогда не может перезагружаться сам.

Имхо - в таком случае вообще программно ничего делать не нужно. Всё должен делать DMA, получающий синхрособытия от таймера, который по этим событиям будет класть данные в порт.
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 28 2015, 13:03
Сообщение #39


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(jcxz @ Jul 28 2015, 15:33) *
Имхо - в таком случае вообще программно ничего делать не нужно. Всё должен делать DMA, получающий синхрособытия от таймера, который по этим событиям будет класть данные в порт.


Интересная идея, но её надо обсчитать: вывод должен происходить каждые 20 тактов ( для таймера от 84 МГц - 10 тактов). Но выводиться должна только половина байта по очереди старший - младший, или младший - старший.
Т.о. за двадцать тактов нужно успеть: "достать" нужный байт, "перевернуть" его как надо, выделить нужную половинку и отправить на выходной порт. Да, ещё следить, когда включить-выключить таймер.

А вот ваша идея насчёт FPU меня потрясла. Действительно, во время короткого цикла очистки памяти в фоне FPU не используется и время реакции на прерывание уменьшается. А в остальных местах программы FPU занято на всю катушку, и время реакции увеличивается. Я посмотрю свои настройки, надеюсь, уж если не решить проблему, то хотя бы уменьшить.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jul 28 2015, 15:45
Сообщение #40


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



вы в какой среде пишите? Если в Keil, то для переноса функций в РАМ, вам надо правой кнопкой в С файл с функциями тыкнуть, и сказать чтобы они запустились из РАМ, все остальное сделает кеил за вас сам.

Регистры FPU надо сохранять в стэк, только если в прерываниях вы будите использовать модуль FPU, если нет, то пусть они лежат где лежать, и вход будет быстрее в прерывание и проблем не будет.

Идея с ДМА вам видится не верно. Вам надо подготовить массив для вывода, так чтобы ДМА просто перекладывало данные на порт, с заданной частотой. Пусть ваша фоновая неспешная программа подготавливая файл делает его как раз того вида, чтобы ДМА осталось его только выплюнуть. ДМА сможет спокойно запускаться по таймеру с заданными интервалами и без каких либо плаваний времянки (если ему поставить приоритет повыше) все делать. А ядро в это время сможет продолжать заниматься своими делами....
Go to the top of the page
 
+Quote Post
bugdesigner
сообщение Jul 28 2015, 16:26
Сообщение #41


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

Группа: Участник
Сообщений: 123
Регистрация: 12-06-15
Из: Земля
Пользователь №: 87 133



А можно одно уточнение? У Вас таймер считает импульсы 84 МГц без прескалера? Я правильно понял?
Не могли бы Вы показать в студию код обработчика прерывания и код инициализации таймера? Может что-то прояснится...
И последнее, я присоединюсь к мнению коллег насчёт дернуть ногой при входе в обработчик. Может всё же какая-то логическая ошибка закралась. Тогда уж точно можно будет утверждать, что имеет место джиттер входа в обработчик или нет.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 29 2015, 03:03
Сообщение #42


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ШСА @ Jul 28 2015, 19:03) *
Интересная идея, но её надо обсчитать: вывод должен происходить каждые 20 тактов ( для таймера от 84 МГц - 10 тактов). Но выводиться должна только половина байта по очереди старший - младший, или младший - старший.
Т.о. за двадцать тактов нужно успеть: "достать" нужный байт, "перевернуть" его как надо, выделить нужную половинку и отправить на выходной порт. Да, ещё следить, когда включить-выключить таймер.

Вы видно плохо представляете как работает DMA...
Я не очень хорошо знаю периферию STM32, но для LPC17xx сделал бы так:
Таймер1 программирую в режим счётчика импульсов на ноге МК (Ваши стартовые импульсы подаю на эту ногу). Предел счёта для него ==1. По этому пределу программирую стоп таймера1 и выдачу события на DMA-канал1. DMA-канал1 программирует Таймер2, запускает его с периодом ==10 тактов. Таймер2 по достижении величины периода (10) перезапускается и выдаёт событие на DMA-канал2.
DMA-канал2 выполняет пересылки из заранее подготовленного массива тетрад в порт каждые 10 тактов таймера2 (по каждому его перезапуску). Это - первый блок пересылки DMA-канала2
(он находится в режиме передачи свЯзных списков (linked list)). Размер первого блока linked list равен размеру пересылаемого массива тетрад. После завершения первого блока, DMA-канал2 вторым
блоком пересылки выключает таймер2. Третьим блоком пересылки DMA-канал2 включает и программрует таймер1 на ожидание след. входного импульса.
После этого DMA-канал2 переходит на начало связного списка своих блоков передач (готов к обработке след. входного импульса).
Если STM32 позволяет запускать DMA от перепада на внешнем пине, то можно обойтись без таймера, а запускать DMA-канал1 от пина.

Цитата(ШСА @ Jul 28 2015, 19:03) *
А вот ваша идея насчёт FPU меня потрясла. Действительно, во время короткого цикла очистки памяти в фоне FPU не используется и время реакции на прерывание уменьшается. А в остальных местах программы FPU занято на всю катушку, и время реакции увеличивается. Я посмотрю свои настройки, надеюсь, уж если не решить проблему, то хотя бы уменьшить.

Достаточно просто выключить это сохранение контекста FPU раз у Вас FPU не используется в ISR. Это надо делать всегда, хотя-бы для того, чтобы уменьшить расход стека.

Но по уму надо делать через DMA, раз у Вас такие требования к временным интервалам, что всё в тактах считаете. DMA более детерминирован по времени чем выполнение кода в CPU.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jul 29 2015, 05:50
Сообщение #43


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(ШСА @ Jul 28 2015, 16:03) *
вывод должен происходить каждые 20 тактов ( для таймера от 84 МГц - 10 тактов).

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

Но если по теме, то раз речь идёт о 20 тактах, то всё же задачу требуется решать аппаратно. То есть фоновая задача может отсчитываться процессором, а, этот Ваш вывод, должен выполняться аппаратно. Аппаратно либо средствами процессора, либо внешними аппаратными средствами.

На мой взгляд, это очевидно. Данный процессор, как раз не предназначен для формирования временных диаграмм. Для этих целей требуются процессора с чётко определённым временем выполнения команд, то есть без кэш, без механизмов предвыборки и так далее. Типа AVR, PIC, а так как они по быстродействию не укладываются, то плисину какую-нибудь применить. А процессор должен выполнять свою задачу асинхронно к данному событию. Чем раньше Вы это осмыслите, переделаете железо, тем быстрее решите задачу. Иначе всё равно к этому вернётесь. Моё мнение.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 29 2015, 07:38
Сообщение #44


Гуру
******

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



Цитата(SasaVitebsk @ Jul 29 2015, 08:50) *
На мой взгляд, это очевидно. Данный процессор, как раз не предназначен для формирования временных диаграмм.
Ой, не смешите. Завести массив в ОЗУ, неспешно прописать в него состояния порта через одинаковые промежутки времени, таймер настроить на эти промежутки и пусть DMA от этого таймера циклически пихает этот массив в порт (или через bitband в ногу/несколько соседних ног порта). Прекрасные времянки получаются.


--------------------
На любой вопрос даю любой ответ
"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
jcxz
сообщение Jul 29 2015, 08:11
Сообщение #45


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Сергей Борщ @ Jul 29 2015, 13:38) *
Ой, не смешите. Завести массив в ОЗУ, неспешно прописать в него состояния порта через одинаковые промежутки времени, таймер настроить на эти промежутки и пусть DMA от этого таймера циклически пихает этот массив в порт (или через bitband в ногу/несколько соседних ног порта). Прекрасные времянки получаются.

Не забыть ещё приоритет доступа к шине для DMA поставить повыше чем у CPU.
Go to the top of the page
 
+Quote Post
Tanya
сообщение Jul 29 2015, 08:33
Сообщение #46


Гуру
******

Группа: Модераторы
Сообщений: 8 752
Регистрация: 6-01-06
Пользователь №: 12 883



Цитата(Сергей Борщ @ Jul 29 2015, 10:38) *
. Прекрасные времянки получаются.

Либо записать в массив параметры таймера и отдать процесс записи DMA.
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 29 2015, 15:54
Сообщение #47


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(Golikov A. @ Jul 28 2015, 18:45) *
вы в какой среде пишите? Если в Keil, то для переноса функций в РАМ, вам надо правой кнопкой в С файл с функциями тыкнуть, и сказать чтобы они запустились из РАМ, все остальное сделает кеил за вас сам.
Регистры FPU надо сохранять в стэк, только если в прерываниях вы будите использовать модуль FPU, если нет, то пусть они лежат где лежать, и вход будет быстрее в прерывание и проблем не будет.
Идея с ДМА вам видится не верно.


Простите за долгое отсутствие - текучка и изучение мануала по наводке jcxz. Оказывается, я многое упустил в своё время...
Среда у меня, к сожалению, CooCox. Keil прекрасная штука, но мне не по карману, а программа слишком велика для бесплатной версии.
В прерываниях FPU нигде не используется, только в фоне. Ищу способ запретить сохранять FPU регистры в стек - а их там 32, если не ошибаюсь. Если даже по 1 такту на каждого - это уже масштаб моих флуктуаций!
Идея с DMA мною не отброшена. Я её проработаю, но позже. А пока мне надо научиться отключать Lazy context save - я даже это ещё не могу заставить сделать свой кокос.

Цитата(bugdesigner @ Jul 28 2015, 19:26) *
А можно одно уточнение? У Вас таймер считает импульсы 84 МГц без прескалера? Я правильно понял?
Не могли бы Вы показать в студию код обработчика прерывания и код инициализации таймера? Может что-то прояснится...
И последнее, я присоединюсь к мнению коллег насчёт дернуть ногой при входе в обработчик. Может всё же какая-то логическая ошибка закралась.


Да, таймер считает без прескалера. Инициализируеется так:

Код
    /*------------------Инициализация TIM6 - строчный таймер-*/
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //включаем тактирование
//Частота шины APB1 42 МГц, на таймер - 84 Мгц
    TIM6->PSC = 0; //Настройка предделителя на 84 "такта" в микросекунду
    TIM6->ARR = 10080; //10080 период - почти две строки 120 мкс 5600
    TIM6->DIER &= ~TIM_DIER_UIE; //запрет прерывания от таймера
    TIM6->CR1 |= TIM_CR1_CEN; //включаем таймер - пусть молотит непрерывно
// прерывания от TIM6 не будет
//TIM6_CNT — текущее значение счётчика для чтения/записи;

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

Код
    Tim6_Count = TIM6->CNT; //длительность предыдущей строки
        TIM6->CNT = 0; //начало измерения строк - сбрасываем таймер
//подготовимся к скоростному выводу данных
                Td = Tdelt; //1 шаг = 10 тактов TIM6 - шаг
                Ts = T_Nath - Td;//начальная задержка 10,5 мкс
                Kt = KolBytStr; //число байт в строке
//Начали вывод активной строки. Пока не кончится активная строка, не выйдем отсюда
                if (Zerkalo) { //вывод "зеркально" - со старшего полубайта последнего байта массива строки
                    Video_Adres_Th0 = (Nstr - NomerNath) * KolBytStr + KolBytStr + Video_Adres; //адрес первого байта
//это адрес текущих 2 точек вывода - последний байт строки
                    while (TIM6->CNT < Ts)continue;//ждём момента для вывода 1 точки
                    GPIO_SetBits(PORT_OUT1_ON_OSD, OUT1_ON_OSD);//вкл. сигнала видео
                    Vt = (uint32_t)(*--Video_Adres_Th0) << SDWIG_RGBT; //первые две точки
                    while (Kt--) {
                        Vt1 = Vt;
                        Vt = Vt >> 4; //спустим старший полубайт
                        Ts += Td; //время следующей точки
                        while (TIM6->CNT < Ts)
                            continue; //ждём момента для вывода точки
                        PORT_RGBT->ODR = Vt; //вывод старшего полубайта
                        Ts += Td; //время следующей четной точки
                        Vt = (uint32_t)(*--Video_Adres_Th0) << SDWIG_RGBT; //следующий байт на разложение на точки
                        while (TIM6->CNT < Ts)continue; //ждём момента для вывода точки
                        PORT_RGBT->ODR = Vt1; //вывод младшего полубайта
                    }
                } else { //вывод "прямо"

Поясню, что строка, где "//ждём момента для вывода 1 точки" это и есть интервал от начала прерывания до начала вывода. Вот он то и "плавает". Кстати следующая строка и есть ваше "дернуть ногой".

Сообщение отредактировал IgorKossak - Jul 29 2015, 17:16
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 29 2015, 17:03
Сообщение #48


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(Сергей Борщ @ Jul 29 2015, 10:38) *
Ой, не смешите. Завести массив в ОЗУ, неспешно прописать в него состояния порта через одинаковые промежутки времени, таймер настроить... Прекрасные времянки получаются.


Конечно! Если удастся уменьшить флуктуации до 4 тактов, их уже никто не заметит при 168 МГц. А вот с ОЗУ напряжёнка: Там две страницы видеополя находятся - формируемая и отображаемая. Так что особо не разбежишься.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 30 2015, 03:15
Сообщение #49


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ШСА @ Jul 29 2015, 21:54) *
В прерываниях FPU нигде не используется, только в фоне. Ищу способ запретить сохранять FPU регистры в стек - а их там 32, если не ошибаюсь. Если даже по 1 такту на каждого - это уже масштаб моих флуктуаций!
Идея с DMA мною не отброшена. Я её проработаю, но позже. А пока мне надо научиться отключать Lazy context save - я даже это ещё не могу заставить сделать свой кокос.

Вы как-то странно мануал читаете.... wacko.gif
Lazy context save Вам отключать не надо, он никак не увеличивает время входа, а наоборот - предназначен для уменьшения времени входа в ISR (резервирует место в стеке, но не пишет).
Но так как у Вас FPU в фоне используется, а где-то не используется, то из-за Lazy context save у Вас в этих местах и будет разница во времени входа (но место в стеке при стэкинге всё равно
будет выделяться одинаково!). А вот если Вы, как я советовал, вообще отключите автоматическое сохранение контекста FPU при входе в ISR, то всегда на стек будет сохраняться как в M3 только
8 регистров. Это можно сделать, если в ISR-ах у Вас не используется FPU. Но если есть операционка и FPU используется в разных задачах, то в переключателе задач ОС (программном) надо сделать
сохранение контектса FPU ручками.
У нас в наших изделиях я так и делаю, но не для уменьшения времени входа в ISR, а для экономии стеков задач (делаю FPCCR = 0, а потом сохраняю или не сохраняю контекст FPU в
переключателе задач ручками, в зависимости от того - использует данная задача FPU или нет).

И как это сделать - я Вам уже выше писал: FPCCR = 0. Вы как-то читаете выборочно sm.gif
И от компилятора это никак не зависит, это Вам надо открыть мануал на ядро M4 и найти там FPCCR.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 30 2015, 05:09
Сообщение #50


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ШСА @ Jul 29 2015, 23:03) *
А вот с ОЗУ напряжёнка: Там две страницы видеополя находятся - формируемая и отображаемая. Так что особо не разбежишься.

Советую всё-таки открыть мануал на используемый процессор и поискать там что-нить типа Quad-SPI или SDIO. Они позволяют до 4 линий параллельно выводить.
Тогда возможно каждый байт памяти будет использоваться полностью, а не одна тетрада. Да и загрузка шины при DMA-передаче на такой интерфейс
будет ниже чем при передаче DMA->GPIO.
По крайней мере на Tiva (TM4C129), который я сейчас использую, связка Quad-SSI+DMA идеальна для Вашей задачи.
Даже если Вы не будете использовать DMA, то лучше использовать Quad-SPI чем тот ногодрыг, что Вы сейчас пытаетесь сделать.
О ногодрыге вообще стоит забывать сразу после перехода на ARM. Оставить его AVR-щикам.
SPI Вам жёстко даст ту времянку, которую Вы запрограммируете ему, вместо болтанки с программным таймером и ногодрыгом.
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 30 2015, 17:13
Сообщение #51


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Наконец сегодня дошли руки проверить хоть какие-то гипотезы. Собственно, рабочих гипотез осталось две.
Начну с первой. jcxz предположил, что причиной влияния фоновой программы на время реакции обработчика и является сохранение в стеке регистров FPU и предложил его запретить. Такой запрет не помешал бы работе системы, поскольку FPU в обработчиках прерываний не используется, а значит и состояние FPU от прерывания не изменилось бы.
В STM32F4 это делается просто: FPU->FPCCR &= ~((1U << FPU_FPCCR_ASPEN_Pos) | (1U << FPU_FPCCR_LSPEN_Pos));
В результате явление не исчезло, ну существенно уменьшилось. Т.е влияние фоновой программы на прерывания осталось, но флуктуации времени запуска обработчика прерываний снизились не менее чем в два раза.
Мораль: Количество сохраняемых в стеке регистров ЦП при прерывании зависит не от того, выполняло или нет в этот момент FPU какую нибудь команду, а от того, что записано в регистре CONTROL с помощью FPU->FPCCR.
Поэтому запрещая сохранение регистров FPU можно изменить среднее время реакции обработчиков на внешние события и изменить интенсивность использования стека. Но к флуктуациям времени вызова обработчика в зависимости от команды, выполняемой в этот момент фоновой программой, это не имеет отношения.

Осталась вторая гипотеза. scifi полагал, что время реакции обработчика зависит от длины кэша команд МК. Т.е. механизм такой: если фоновая программа выполняет длительный короткий цикл, в течение которого происходит несколько прерываний, то после первого прерывания из кэша не вытесняется начало обработчика прерывания и все последующие прерывания происходят быстрее.
Чтобы проверить эту идею нужно было очистить кэш команд перед выходом из обработчика.
Я не нашёл (да пока и не искал) такой команды, но чтобы проверить эту идею в фоновой программе внутри короткого цикла вставил вызов небольшой функции, которая ничего полезного не делала, но и ничего не портила. Фактически, цикл перестал быть коротким. Результат - эти флуктуации исчезли!
Мораль сногсшибательная: кэш команд в STM32F4, который так здорово "разгоняет" ЦП, может быть причиной непредсказуемых флуктуаций времени реакции обработчиков на внешние события. Причём флуктуаций весьма чувствительных - до 400 нс, когда используется FPU и включено сохранение его регистров в стеке (это происходит по умолчанию при включении FPU), и когда различные прерывания конкурируют между собой. А управлять этой непредсказуемостью будет фоновая программа!

Так что мой обработчик придётся выбросить.
Всем, кто принял участие в этом мозговом штурме ОГРОМНОЕ СПАСИБО!
И, конечно, jcxz и scifi от меня особая благодарность, за активизацию моих мозгов.


Цитата(jcxz @ Jul 30 2015, 08:09) *
Советую поискать там что-нить типа Quad-SPI или SDIO. Они позволяют до 4 линий параллельно выводить.


У STM32F407 есть одна неприятная особенность - пины SDIO пересекаются с пинами видеокамеры DCMI. Придётся выбирать. А Quad-SPI там нет.

Сообщение отредактировал ШСА - Jul 30 2015, 19:02
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 31 2015, 02:35
Сообщение #52


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ШСА @ Jul 30 2015, 23:13) *
Мораль: Количество сохраняемых в стеке регистров ЦП при прерывании зависит не от того, выполняло или нет в этот момент FPU какую нибудь команду, а от того, что записано в регистре CONTROL с помощью FPU->FPCCR.

Думаю что всё-же зависит если включено Lazy context save. При этом если FPU не использовался, то место просто резервируется в стеке без реальной записи, а на это такты не тратятся, только память.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jul 31 2015, 04:46
Сообщение #53


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(ШСА @ Jul 30 2015, 20:13) *
Мораль: Количество сохраняемых в стеке регистров ЦП при прерывании зависит не от того, выполняло или нет в этот момент FPU какую нибудь команду, а от того, что записано в регистре CONTROL с помощью FPU->FPCCR.

Вы хотя бы задумались. А как может быть по другому?!
Какая разница где именно в фоновой задече используется FPU? Если имеется шанс запортить используемые регистры, то их надо сохранять!
Здесь на крайняк, может компилятор грамотно обсчитывать имеется ли в Ваших прерываниях работа с FPU. Но учитывая как работает компилятор, и этого не получается.
Например Вы можете вызвать из прерывания ф-цию, которая использует FPU. Или Вы можете написать обработчик на ассемблере и компилятор даже знать не будет о том, что Вы в прерывании используете FPU. Поэтому действия разработчиков процессора единственно верны.

Цитата
Мораль сногсшибательная: кэш команд в STM32F4, который так здорово "разгоняет" ЦП, может быть причиной непредсказуемых флуктуаций времени реакции обработчиков на внешние события. Причём флуктуаций весьма чувствительных - до 400 нс, когда используется FPU и включено сохранение его регистров в стеке (это происходит по умолчанию при включении FPU), и когда различные прерывания конкурируют между собой. А управлять этой непредсказуемостью будет фоновая программа!

А здесь Вы просто капитан очевидность! biggrin.gif
Именно за счёт этого и получен выигрыш в быстродействии. Я вообще не понимаю что Вас удивляет? Так работают все процы CISC, в частности. И совершенно очевидно, что в Cortex-M7 джитер будет ещё выше.
Он будет в любом процессоре. В процах без кэша он будет меняться на разницу в времени исполнения команд, которые Вы используете в фоновой задаче. Например в AVR, при применении умножения +1 такт.

Поэтому Вам несколько раз настойчиво советуют использовать аппаратные средства либо самого процессора либо внешнего устройства.
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 31 2015, 07:04
Сообщение #54


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(SasaVitebsk @ Jul 31 2015, 07:46) *
Поэтому действия разработчиков процессора единственно верны.
Именно за счёт этого и получен выигрыш в быстродействии. Я вообще не понимаю что Вас удивляет?


А кто говорит, что разработчики из ST что-то сделали неправильно? STM32F4 - серия шикарных микроконтроллеров! Но, как всё шикарное, требуют аккуратного обращения.
А удивляет меня не задержка вызова прерываний, и не джиттер при разборках обработчиков между собой. Это всё общеизвестно. А вот то, что на время вызова обработчика может влиять содержимое фоновой программы - для меня открытие. Я с таким никогда не встречался и не читал о таком. Результат проведённого исследования - понимание механизма взаимовлияния фона на реактивность системы, которое позволит осознаннее выбирать программные средства. Правильно заметил jcxz, что от AVR-ные подходы для ARM-ов не всегда годятся.
И понять это явление помогло именно включённое FPU, которое на порядок увеличило этот эффект, и заставило разбираться до конца.
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 31 2015, 08:05
Сообщение #55


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(ШСА @ Jul 31 2015, 10:04) *
А вот то, что на время вызова обработчика может влиять содержимое фоновой программы - для меня открытие...
Правильно заметил jcxz, что от AVR-ные подходы для ARM-ов не всегда годятся.

Нет-нет, рано класть AVR-ные подходы на дальнюю полку. Возьмите многоядерный МК типа LPC4370. Там 3 процессора. Один из них можно натравить на узкую задачу с жёсткой времянкой - и дело в шляпе :-)
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jul 31 2015, 08:33
Сообщение #56


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



любой проц можно поставить на жесткую времянку, только для этого надо правильно написать программу.

У вас проц молотит на частое за 100 МГц, при этом из флеши можно выбирать команды на частоте порядка 20 МГц, и должно стать ежу понятно что никакие увеличения шины выбора команд не смогут решить эту разность частот, за исключением линейных участков кода....

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

АВР просто не превысила по своей скорости, скорость флешь, потому там такого и не было. Возьмите АРМ, перепихайте всю программу в ОЗУ и погнали...
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 31 2015, 10:05
Сообщение #57


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(scifi @ Jul 31 2015, 14:05) *
Возьмите многоядерный МК типа LPC4370. Там 3 процессора. Один из них можно натравить на узкую задачу с жёсткой времянкой - и дело в шляпе :-)

Кстати - всё хотелось узнать поподробнее про эти многоядерные LPC: а как там память программ и данных организована?
Общая или для каждого ядра своя? И как шины к памяти проложены?
Можно-ли написать ПО так, чтобы каждое ядро работало со своим набором регионов памяти/шин доступа к ним, оставив только один общий регион для межпроцессорного обмена?
Если всё-таки там ядра конкурируют за какие-либо ресурсы (регионы памяти, шины), или программа так написана, что имеется много
конфликтов по ресурсам, то ядра будут влиять друг на друга (на скорость выполнения кода друг друга).
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 31 2015, 10:26
Сообщение #58


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(jcxz @ Jul 31 2015, 13:05) *
Кстати - всё хотелось узнать поподробнее про эти многоядерные LPC: а как там память программ и данных организована?
Общая или для каждого ядра своя? И как шины к памяти проложены?

Конкретно в LPC4370 нет наботной флеши, но есть несколько банков ОЗУ, подключенных разнообразными способами к многопортовому шинному коммутатору. Так что да, там есть возможность распределить банки памяти так, чтобы процессоры трудились, не мешая друг другу.
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 31 2015, 19:00
Сообщение #59


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(Golikov A. @ Jul 31 2015, 11:33) *
А обдумав этот факт становится понятно что вид программы с точки зрения переходов, должен влиять на времянку выполнения программы.


Согласен. И хотя вы все будете смеяться, но я опять чего-то недопонимаю.
Чтобы не связываться с DMA, решил попытаться использовать захват сигнала через таймер. Но перед этим, чтобы быть уверенным в конечном результате, решил проверить экспериментально верность нашей "гениальной теории".
Способ мне пришёл в голову очень простой: Вызов обработчика происходит по переднему фронту синхроимпульса, и пусть флуктуации вызова обработчика достигают 0,2 мкс. Поскольку длительность этого внешнего синхроимпульса равна 4,7 мкс, то очевидно, что его задний фронт будет гарантированно в то время, когда обработчик уже будет вовсю работать. Значит, если вставить цикл ожидания окончания синхроимпульса и сбрасывать таймер после этого, я должен получить гарантированное избавление от зависимости от времени вызова обработчика, а значит, и от содержимого фоновой программы.
Но эксперимент (критерий истины) показал, что эффект влияния фоновой программы остался! Хотя, величина флуктуаций фазы первого выводимого импульса стала значительно меньше, чем раньше (на глазок - в 2,5 - 3 раза).


Цитата(scifi @ Jul 31 2015, 13:26) *
Конкретно в LPC4370 нет наботной флеши,


А что это такое "наботная?"

Сообщение отредактировал ШСА - Jul 31 2015, 18:31
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jul 31 2015, 19:09
Сообщение #60


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



набортная, на борту проца....
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 31 2015, 19:11
Сообщение #61


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(ШСА @ Jul 31 2015, 22:00) *
Значит, если вставить цикл ожидания окончания синхроимпульса...

И сколько тактов длится итерация цикла?
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jul 31 2015, 19:18
Сообщение #62


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Но эксперимент (критерий истины) показал, что эффект влияния фоновой программы остался! Хотя, величина флуктуаций фазы первого выводимого импульса стала значительно меньше, чем раньше (на глазок - в 2,5 - 3 раза).


внимание вопрос, а вы ногу то как ждете? не через цикл ли со сравнением? А она у вас не цепочка в несколько команд? То есть не получается так что в зависимости от того когда мы вошли в прерывание (а это у нас продолжает плавать), задний фронт может попасть на любую из нескольких команд цепочки цикла проверки, и следовательно время до очередной проверки с переходом разное....
а теперь смотрите сколько у вас команд в вашем цикле проверки...

Ну и работу ускорителей для циклов с переходами тоже никто не отменял.... кто его знает как оно там команды выбирает и хеширует, то у него есть кусок куда переход, то нет... Это же не полноценный кэш, там банки строк в 4-8 команд, да еще поди и с выравниванием....

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



Цитата
И сколько тактов длится итерация цикла?

ну вот пока ехидно разжевывал, опередили%)))))
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 1 2015, 06:10
Сообщение #63


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ШСА @ Aug 1 2015, 01:00) *
Но эксперимент (критерий истины) показал, что эффект влияния фоновой программы остался! Хотя, величина флуктуаций фазы первого выводимого импульса стала значительно меньше, чем раньше (на глазок - в 2,5 - 3 раза).

Раз такое делаете, располагать это надо в ОЗУ (ещё лучше - CCM, если есть) и писать на ассемблере с учётом межкомандных времянок.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 1 2015, 07:10
Сообщение #64


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



ассемблер тут не причем, человека беспокоит не время, а девиации времени начала исполнения. Расположить в РАМ - да, ассемблер - нет необходимости
Go to the top of the page
 
+Quote Post
ШСА
сообщение Aug 1 2015, 15:39
Сообщение #65


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(Golikov A. @ Jul 31 2015, 11:33) *
любой проц можно поставить на жесткую времянку, только для этого надо правильно написать программу.


Похоже, я приближаюсь к пониманию причин флуктуаций фазы выходного сигнала моего STM32F407, хотя до конца ещё не понимаю. Я провёл очередной эксперимент, и теперь пытаюсь его интерпретировать.
У этого МК имеется две области ОЗУ - процессорная CCM (64К) и присоединённая SRAM (128К), которая ещё сама поделена на две неравные части SRAM1 и SRAM2.
Сначала расскажу как было до сегодняшнего дня.
Использовалась ОЗУ у меня так: в SRAM находились 3 массива - 2 больших видеостраницы и 1 промежуточный массив поменьше (все они байтовые). Все остальные переменные лежали в CCM и использовались как фоновой программой, так и всеми обработчиками. Так вот, когда происходила очистка одной из видеостраниц в коротком цикле фона, переменная цикла и указатель оказывались в CCM, а очищаемые элементы - в SRAM. В этот момент и происходил бросок фазы выходного сигнала МК. Причём бросок на опережение - изображение на мониторе подёргивалось влево.
Теперь сегодня я изменил использование памяти. Одну видеостраницу отправил в CCM, а в SRAM остались только другая видеостраница с пром. массивом.
Картина радикально поменялась. Теперь изображение на мониторе просто перепрыгивает - то левее, то правее в соответствии с переключением отображаемой страницы! Получается, что задержка вывода из CCM и из SRAM отличается очень сильно, а именно на 190 нс. С похожей проблемой столкнулся ещё один страдалец (http://cliffle.com/article/2015/06/11/matrix/#how-to-mess-up-an-entire-scanline). Он свои проблемы объяснил конфликтом шин в Multi-AHB матрице! Если правильно понимаю - к CCM ЦП имеет доступ непосредственно, а к SRAM - через шину AHB3 и матрицу. А порты подключены к AHB1 и подключаются к ЦП через матрицу. Получается, где-то там какой-то конфликт? В общем, STM32F407 скучать не даёт!

Цитата(aaarrr @ Jul 31 2015, 22:11) *
И сколько тактов длится итерация цикла?


Четыре такта (если Вы о цикле ожидания).

Сообщение отредактировал ШСА - Aug 1 2015, 15:42
Go to the top of the page
 
+Quote Post
ШСА
сообщение Aug 1 2015, 16:47
Сообщение #66


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(Golikov A. @ Jul 31 2015, 22:18) *
отдавайте контроль железным блокам с более четкой времянкой....


Это будет последнее средство...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 1 2015, 16:56
Сообщение #67


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(ШСА @ Aug 1 2015, 18:39) *
Четыре такта (если Вы о цикле ожидания).

Можно увидеть этот цикл в дизассемблированном виде? Не очень представляю, как он может уложиться в четыре такта.
Go to the top of the page
 
+Quote Post
ШСА
сообщение Aug 1 2015, 17:04
Сообщение #68


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Покажу, но уже не сегодня.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 1 2015, 18:05
Сообщение #69


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



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

Переводить на железо это не последние, а правильное решение. Надо дма подтягивать....

Вы не совсем так как надо используете проц, потому у вас много чего интересного вылезает.

У вас есть осцилограф? Очень рекомендую разные моменты повыводить на ноги и поглядеть реальные времянки, сколько проц выбирает данные из памяти, сколько делает переход по условию. Первый и второй раз. АРМы не так просты, их долго разрабатывали, они хороши
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 1 2015, 18:14
Сообщение #70


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Golikov A. @ Aug 1 2015, 21:05) *
Маски и адреса в регистрах уже, в целом можно, но думаю реально там больше.

Загрузка - 2 такта, сравнение - 1, переход - 2. У меня получается минимум 5.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 1 2015, 18:28
Сообщение #71


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Не вижу возможности вам не верить), а почему загрузка 2?
Go to the top of the page
 
+Quote Post
ШСА
сообщение Aug 1 2015, 18:29
Сообщение #72


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(Golikov A. @ Aug 1 2015, 21:05) *
Взять порт
Взять маску
Если ноль прыгнуть
Прыгнуть на взять порт.
Маски и адреса в регистрах...
Очень рекомендую разные моменты повыводить на ноги и поглядеть реальные времянки


Да, что-то такое там и было - все константы и указатели в регистрах, сам цикл в кэше... Скорее всего вы правы.
Вообще-то я не заморачивался на этом и такты по тексту не считал. Включил оптимизацию компилятора, взял осциллограф и измерил. Давно это было. Измеренные значения и показали - флуктуации - до 4 тактов.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 1 2015, 18:44
Сообщение #73


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Golikov A. @ Aug 1 2015, 13:10) *
ассемблер тут не причем, человека беспокоит не время, а девиации времени начала исполнения. Расположить в РАМ - да, ассемблер - нет необходимости

Причём. Если уж пошёл считать такты, которые зависят от команд, то надо зафиксировать эту последовательность команд, чего не сделать в си (смена компилятора, ключей оптимизации, изменение соседнего участка кода и т.п.).
А девиация времени начала исполнения (для его алгоритма со входом в ISR по фронту сигнала, и ожиданием в цикле спада сигнала) будет равна длине (в тактах) цикла опроса пина порта.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 1 2015, 18:50
Сообщение #74


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Golikov A. @ Aug 1 2015, 21:28) *
Не вижу возможности вам не верить), а почему загрузка 2?

Одиночная LDR выполняется два такта; последовательность из двух LDR может быть выполнена за три такта (а из трех за четыре и т.д.), если адрес для последующей инструкции не зависит от результата предыдущей.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 1 2015, 19:16
Сообщение #75


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Ваша правда, другое дело пока лдр искал, нашел что переходы условные бывают 1 такт, правда не вдавался в чем дело.
Ну значит 5 тактов...
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 1 2015, 21:18
Сообщение #76


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Когда дело доходит до подсчёта тактов при работе с периферией, тут однозначно надо искать аппаратные пути решения. Только так, имхо.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Aug 2 2015, 07:42
Сообщение #77


Универсальный солдатик
******

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



Цитата(aaarrr @ Aug 1 2015, 21:14) *
Загрузка - 2 такта, сравнение - 1, переход - 2. У меня получается минимум 5.

Кейл показывает, что переход длится 1 такт, недавно смотрел для STM32F303.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 2 2015, 08:30
Сообщение #78


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(ViKo @ Aug 2 2015, 10:42) *
Кейл показывает, что переход длится 1 такт, недавно смотрел для STM32F303.

А TRM говорит, что не меньше двух, и ему я почему-то доверяю больше:
Цитата
Branches take one cycle for instruction and then pipeline reload for target instruction. Non-taken branches are 1 cycle total.
Taken branches with an immediate are normally 1 cycle of pipeline reload (2 cycles total). Taken branches with register
operand are normally 2 cycles of pipeline reload (3 cycles total). Pipeline reload islonger when branching to unaligned 32-bit
instructions in addition to accesses to slower memory. A branch hint is emitted to the code bus that permits a slower system
to pre-load. This can reduce the branch target penalty for slower memory, but never less than shown here.
Go to the top of the page
 
+Quote Post
ШСА
сообщение Aug 2 2015, 18:05
Сообщение #79


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(ШСА @ Jul 31 2015, 22:00) *
Но эксперимент (критерий истины) показал, что эффект влияния фоновой программы остался!


Придётся мне покритиковать самого себя. Неправда это, Явление исчезло!
А этот результат, оказывается, произошёл оттого, что я в процессе экспериментов отключил кэш команд, а потом забыл включить! Извините за дезинформацию.

Цитата(ШСА @ Aug 1 2015, 18:39) *
Теперь изображение на мониторе просто перепрыгивает - то левее, то правее в соответствии с переключением отображаемой страницы! Получается, что задержка вывода из CCM и из SRAM отличается очень сильно, а именно на 190 нс.


Величина "прыжка" однозначно зависит от частоты тактирования шин. Когда я повысил частоту тактирования шины AHB1 вдвое (до 168 МГц), "прыжок" уменьшился ровно вдвое.

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

Сообщение отредактировал ШСА - Aug 2 2015, 18:09
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 3 2015, 03:58
Сообщение #80


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ШСА @ Aug 3 2015, 00:05) *
Чем больше вожусь с этой системой, тем больше хочется задействовать DMA. Но как в этом случае организовать вывод байтов по тетрадам?

1.Выбрать другой МК со свободным Quad-SPI либо SDIO либо каким другим интерфейсом, на котором можно такое сделать.
2.Сгородить внешнюю схему мультиплексора.
3.Выбрать МК с бОльшим кол-вом ОЗУ и писать тетрадные буфера.
Go to the top of the page
 
+Quote Post
ШСА
сообщение Aug 3 2015, 04:09
Сообщение #81


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Спасибо. Но ведь и здесь пока есть варианты, например такой - На вывод отправлять не не всю видеостраницу, состоящую из тетрад, а только одну строку, уже в виде целых байтов. Главное, успевать за 10 мкс. их обновлять.

Сообщение отредактировал ШСА - Aug 3 2015, 04:09
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 3 2015, 05:50
Сообщение #82


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Мы же не знаем куда у вас там подключены ножки, и доступен ли этот адрес из ДМА. Также мы не знаем сколько бит вам надо в паралель выплевывать наружу.

Там даже есть вариант по ДМА грузить интервалы таймера, а тот чтобы ногой дергал, в режиме ШИМ... Более подробно скажите что там куда выпихивается...
Go to the top of the page
 
+Quote Post
ШСА
сообщение Aug 3 2015, 07:32
Сообщение #83


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(Golikov A. @ Aug 3 2015, 08:50) *
Мы же не знаем куда у вас там подключены ножки, и доступен ли этот адрес из ДМА. Также мы не знаем сколько бит вам надо в паралель выплевывать наружу.


Впараллель надо выплёвывать 4 бита - это видеосигнал (там ещё множество управляющих сигналов, но они однобитовые). А с доступностью то какие проблемы? DMA работает с устройствами и памятью. А у АРМ-ов все порты отображены на адресное пространство. Так что плеваться надо "память - память".
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 3 2015, 07:36
Сообщение #84


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



если 4 биты порта в памяти рядом (в пределах байта) и остальные биты порта неважны. А иначе надо лезть через спец регистры установки снятия бит, и тут встает вопрос есть ли к ним доступ ДМА, скорее всего есть, но надо проверить.

Ну и самое простое это по 4 бита, дополнить до байта 1 и 2 поле, и их выплевывать по очереди. Причем ДМА можно настроить циклически, и тогда он будет просто по кругу гнать картинку, даже не трогая проц, до тех пор пока картинку не поменяете, его даже перезапускать не надо будет.
Go to the top of the page
 
+Quote Post
ШСА
сообщение Aug 3 2015, 07:46
Сообщение #85


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Ну да, а как иначе? В STM32F4 нет никаких видеосредств, все АЦП и ЦАП довольно медленные.

Цитата(Golikov A. @ Aug 3 2015, 10:36) *
Причем ДМА можно настроить циклически, и тогда он будет просто по кругу гнать картинку, даже не трогая проц, до тех пор пока картинку не поменяете, его даже перезапускать не надо будет.


А вот это заманчиво, но хватит ли ОЗУ? Там 2 видеостраницы находятся плотно упакованные, каждая по 58К. Для ещё одной полной видеостраницы в байтовом формате (т.е. по байту на точку) тут нет места. А вот сделать 1-2 строки и обновлять за 10 мкс и переключать их каждые 64 мкс - это можно. Вот как это организовать я и думаю.

Сообщение отредактировал ШСА - Aug 3 2015, 07:57
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 3 2015, 07:55
Сообщение #86


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Ну ДМА может гнать по кругу, и оно имеет прерывание половина прошла.
Делаете буфер размером 4 строки, запускаете ДМА, а по прерыванию Половину прошло, все прошло, подменяете данные в первой и второй половине буфере.
А ДМА будет их выпихивать со строгой времянкой.

Размер буфера можно сделать больше строк, чтобы было больше времени на обновление....

а почему там 4 бита? еще какая-то синхронизация что ли? или это 16 уровней сигнала?
Go to the top of the page
 
+Quote Post
ШСА
сообщение Aug 3 2015, 08:22
Сообщение #87


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(Golikov A. @ Aug 3 2015, 10:55) *
Делаете буфер размером 4 строки, запускаете ДМА, а по прерыванию Половину прошло, все прошло, подменяете данные в первой и второй половине буфере.
А ДМА будет их выпихивать со строгой времянкой.

Размер буфера можно сделать больше строк, чтобы было больше времени на обновление....

а почему там 4 бита? еще какая-то синхронизация что ли? или это 16 уровней сигнала?


Ну, хорошо. Но строка не выводится непрерывно. Из 64 мкс часть времени идёт вывод, а потом заткнуться до прихода следующего синхроимпульса. Это время, я полагал, и можно использовать для подмены строки. А как сделать вывод нескольких строк, каждая из которых то выводится, то нет, что-то я слабо представляю.

4 бита - это цвета раскраски и надписей изображения + тень.

Сообщение отредактировал ШСА - Aug 3 2015, 08:36
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 3 2015, 08:57
Сообщение #88


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



ДМА запускается по таймеру, таймер запускается по внешнему синхроимпульсу.

Значит ДМА выводит 1 строку, по прерыванию дма отработало, перенастраиваете на следующую строку.
Вывод очередного значение контролирует таймер (интервалы между точками)
Запуск таймера по внешнему синхросигналу
и всех делов.

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

более того можно сделать цепочку таймеров, и несколько каналов ДМА взять, и они смогут даже по сложной схеме друг друга запускать
Go to the top of the page
 
+Quote Post
ШСА
сообщение Aug 3 2015, 09:08
Сообщение #89


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Отлично. Спасибо.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Sep 10 2015, 23:41
Сообщение #90


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(aaarrr @ Aug 1 2015, 22:50) *
Одиночная LDR выполняется два такта; последовательность из двух LDR может быть выполнена за три такта (а из трех за четыре и т.д.), если адрес для последующей инструкции не зависит от результата предыдущей.

Подскажите пожалуйста название документа, в котором описаны такие нюансы растактовки.
На сайте ARMа есть что-то вроде для Cortex-M0, в котором почему-то нет зависимостей. Может зависимости (индивидуально к кажому ядру) описываются в другом документе? Интересуют нюансы двух видов - изменение аргумента текущей инструкции в предыдущей инструкции и задержки связанные с обращением к памяти, в том числе чередования чтения/записи, а так же одновременной подгрузке кода, особенно для M0, у которого одна общая шина.

Сообщение отредактировал GetSmart - Sep 11 2015, 02:36


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Sep 11 2015, 10:22
Сообщение #91


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(GetSmart @ Sep 11 2015, 02:41) *
Подскажите пожалуйста название документа, в котором описаны такие нюансы растактовки.

Cortex-M3 Technical Reference Manual, раздел Load-store timings. У M0, полагаю, такой особенности (pipelined LDR) нет.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Sep 11 2015, 14:26
Сообщение #92


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(aaarrr @ Sep 11 2015, 14:22) *
Cortex-M3 Technical Reference Manual, раздел Load-store timings. У M0, полагаю, такой особенности (pipelined LDR) нет.

Другие зависимости (как минимум из мной озвученных) у М3 и М0 Вам известны?

Методом тыка я нашёл кое-что, увеличивающее на такт следующую команду. Настолько неочевидное, что сперва хочется узнать все описанные зависимости М0/М3. На ранее обозначенной таблице таймингов и на этой для М3 она не указана.

Сообщение отредактировал GetSmart - Sep 11 2015, 14:33


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Sep 11 2015, 14:54
Сообщение #93


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(GetSmart @ Sep 11 2015, 17:26) *
Другие зависимости (как минимум из мной озвученных) у М3 и М0 Вам известны?

Нет, не известны.

Поделитесь наблюдениями, это интересно.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Sep 21 2015, 12:25
Сообщение #94


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Время до сих пор не нашёл для полноценного тестирования на разных камнях. По результатам отпишусь. Заметил на М0. Думал зависимость от предыдущей инструкции, но оказалась зависимость другая. Для чистоты эксперимента остальные подробности потом.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
ШСА
сообщение Sep 23 2015, 19:32
Сообщение #95


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(GetSmart @ Sep 21 2015, 15:25) *
Время до сих пор не нашёл для полноценного тестирования на разных камнях...


А не проще ли просто описать ситуацию, в которой происходит непонятка? Тестировать, как и "ловить блох", можно бесконечно. Мне же, как и другим, я думаю, интересен практический опыт.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Sep 23 2015, 19:39
Сообщение #96


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(ШСА @ Sep 23 2015, 23:32) *
Тестировать, как и "ловить блох", можно бесконечно.

На одном камне всё протестировано. Джиттера нет. Так что если Ваша программа работает, то нервничать не о чем. Программирование с точностью до такта интересует только "параноиков", которые не спешат.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 25 2015, 08:54
Сообщение #97


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Потестил на LPC4357 и LPC11U37/501. У обоих ядра M0 r0p0. Эффект наблюдается на обоих. У LPC11U37 есть три региона SRAM доступных для исполнения кода и хранения данных. У LPC4357 ещё больше регионов. Если команда STR/STM находится на нечётном адресе (маска 0x02) и адрес записи нах-ся в этом же регионе SRAM, то команда будет исполняться на такт дольше. Для STM добавочный только 1 такт независимо от кол-ва сохраняемых регистров. Отличие у LPC4357 есть в том, что хоть регион 0x20000000..0x2000ffff разбит ещё на 4 региона по 16 КБ и общение с разными этими регионами разных ядер не вызывает тормозов друг друга, но в описываемом выше эффекте весь этот регион для M0 как буд-то один и исполнение кода из допустим 0x200000000 с записью в регион 0x20008000 будет вызывать 1 такт тормозов.

У процессоров с одним регионом SRAM эффект должен наблюдаться всегда.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 26 2015, 11:57
Сообщение #98


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(GetSmart @ Oct 25 2015, 12:54) *
У процессоров с одним регионом SRAM эффект должен наблюдаться всегда.

Ессно при исполнении кода из SRAM. Именно так в LPC111x. Этим способом можно было бы косвенно проверять внутреннее разделение рамы на регионы в одноядерных процессорах. Если адресные линии не отключены в логике, как в LPC43xx, у которого, по моему предположению, из-за наличия цельного 40 КБ региона SRAM пришлось отключить линии A14 и A15 при сравнении в M0-ядре адресов кода и данных.

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

Сообщение отредактировал GetSmart - Oct 27 2015, 03:49


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 29 2015, 19:20
Сообщение #99


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Проверил ещё на LPC1227 (M0+ r0p0). Этого эффекта нет. Странно, что по CPUID ядра не отличить M0 от M0+.

Цитата
...из-за наличия цельного 40 КБ региона SRAM...

Вторая возможная причина в отсутствии пустот в регионе адресов 0x2000xxxx LPC43xx.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 5 2015, 17:22
Сообщение #100


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(GetSmart @ Oct 29 2015, 23:20) *
Проверил ещё на LPC1227 (M0+ r0p0). Этого эффекта нет. Странно, что по CPUID ядра не отличить M0 от M0+.

Ошибся. LPC1227 это M0 без плюса. Так что CPUID корректный. Но растактовка STR/STM у него отличается от остальных M0 камней NXP. Отличий растактовки LPC1227 от "официальной" ARM пока не нашёл.

Цитата(aaarrr)
Cortex-M3 Technical Reference Manual, раздел Load-store timings. У M0, полагаю, такой особенности (pipelined LDR) нет.

В юзер мануале LPC43xx указано, что pipelined есть и у LDR и у STR.
На бумаге распечатал на всякий случай.

Сообщение отредактировал GetSmart - Nov 5 2015, 19:57


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 24th July 2025 - 12:46
Рейтинг@Mail.ru


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