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

 
 
6 страниц V  « < 3 4 5 6 >  
Reply to this topicStart new topic
> STM32F0 Время реакции и выполнения прерывания
jcxz
сообщение Jun 23 2016, 13:24
Сообщение #61


Гуру
******

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



Цитата(Влад Р. @ Jun 23 2016, 17:15) *
Сейчас как раз этим и занимаюсь. Не подскажите где посмотреть длительность каждой команды в машинных циклах?

Я уже Вам приводил ссылку. Там всё есть, и циклы тоже.
Go to the top of the page
 
+Quote Post
Влад Р.
сообщение Jun 23 2016, 13:54
Сообщение #62


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

Группа: Свой
Сообщений: 87
Регистрация: 9-12-10
Пользователь №: 61 511



Цитата(jcxz @ Jun 23 2016, 16:24) *
Я уже Вам приводил ссылку. Там всё есть, и циклы тоже.


Описание команд там есть. По нем и разбираюсь. Но где указана длительность не заметил. Можете тыкнуть носом? laughing.gif
Go to the top of the page
 
+Quote Post
Obam
сообщение Jun 23 2016, 14:25
Сообщение #63


Знающий
****

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



Цитата(Влад Р. @ Jun 23 2016, 17:54) *
Описание команд там есть. По нем и разбираюсь. Но где указана длительность не заметил.

Прикрепленный файл  DDI0432C_cortex_m0_r0p0_trm.pdf ( 461.17 килобайт ) Кол-во скачиваний: 101

Столбец Cycles
раздел 3.3 стр 3-4 и до горизонта


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
scifi
сообщение Jun 23 2016, 14:26
Сообщение #64


Гуру
******

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



Цитата(Влад Р. @ Jun 23 2016, 16:54) *
Можете тыкнуть носом? laughing.gif

Могу: тут.
Но имейте в виду: задержки флеша и доступа к периферии (GPIO) там не указаны.
Go to the top of the page
 
+Quote Post
IJAR
сообщение Jun 24 2016, 12:57
Сообщение #65


Местный
***

Группа: Свой
Сообщений: 232
Регистрация: 26-02-07
Из: г. Зеленоград
Пользователь №: 25 669



http://electronix.ru/forum/index.php?showt...869&hl=IJAR


--------------------
Вяжешь - вой, а поедешь - песни пой.
Между "хочу" и "можно" всегда есть дистанция
Go to the top of the page
 
+Quote Post
Влад Р.
сообщение Jun 24 2016, 13:46
Сообщение #66


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

Группа: Свой
Сообщений: 87
Регистрация: 9-12-10
Пользователь №: 61 511



Цитата(scifi @ Jun 23 2016, 17:26) *
Могу: тут.
Но имейте в виду: задержки флеша и доступа к периферии (GPIO) там не указаны.

При текущей частоте задержка флэш составляет 1 Wait State. Это значит что при выполнении кода из флеша к длительности всех команд можно добавить 1 машинный цикл? Как оценить на сколько в такой ситуации ускоряет выполнение буфер предварительной выборки? Задержка доступа к периферии определяется исключительно частотой шины, на которой она сидит, и собственными предделителями конкретной периферии? Или есть еще влияющие факторы?

Цитата(IJAR @ Jun 24 2016, 15:57) *

Спасибо за ссылку! Фейспалм мне, что ненагуглил эту тему раньше.

Написал в отдельном файле простой обработчик, который для начала будет просто устанавливать пин в единицу и сбрасывать флаг прерывания. Среда компилирует файл. Но не могу понять как задействовать его в основной программе?
CODE
EXTI_BASE EQU 0x40010400
GPIOA_BASE EQU 0x48000000
GPIOB_BASE EQU 0x48000400
GPIOC_BASE EQU 0x48000800

EXTI_PR_OFFSET EQU 0x14
GPIO_IDR_OFFSET EQU 0x10
GPIO_BSRR_OFFSET EQU 0x18

AREA EXTI, CODE, READONLY
EXTI4_15_IRQHandler PROC
LDR r0, =GPIOB_BASE ; загрузить в регистр r0 адрес порта GPIOB
MOVS r1, #0x01 ; копировать в регистр r1 значение 0x01
LSLS r2, r1, #12 ; логический сдвиг влево на 12 бит значения в регистре r1 и сохранение результата в регистр r2
STR r2, [r0, #GPIO_BSRR_OFFSET] ; сохранить слово из регистра r2 в регистр GPIOB->BSRR
LDR r0, =EXTI_BASE ; загрузить в регистр r0 адрес модуля EXTI
LSLS r1, #8 ; логический сдвиг влево на 8 бит значения в регистре r1
STR r1, [r0, #EXTI_PR_OFFSET] ; сохранить слово из регистра r1 в регистр EXTI->PR
BX LR
ENDP
END
Go to the top of the page
 
+Quote Post
Obam
сообщение Jun 24 2016, 13:56
Сообщение #67


Знающий
****

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



IARом пользуетесь? Тогда "IAR C/C++ Development Guide" главу "Assembler language interface" курить до просветления wink.gif


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
Влад Р.
сообщение Jun 24 2016, 14:00
Сообщение #68


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

Группа: Свой
Сообщений: 87
Регистрация: 9-12-10
Пользователь №: 61 511



Цитата(Obam @ Jun 24 2016, 16:56) *
IARом пользуетесь? Тогда "IAR C/C++ Development Guide" главу "Assembler language interface" курить до просветления wink.gif


Keil
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 24 2016, 15:58
Сообщение #69


.
******

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



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

Цитата(GetSmart @ Jun 23 2016, 01:32) *
Но первое же преджложение "Т.к. bit-banding есть опция СМ0+" на каких документах от АРМ основано - не ясно.
Точнее будет перевод "Т.к. bit-band регион есть опция ARM CM0+...". Но в открытой документации от ARM не было bit-band региона для этих ядер и эта формулировка тоже некорректна. Во многих реализациях ARMv6-M от NXP в регионе 0x200000000 было ОЗУ с дополнительными фичами самого NXP. Например IOHandler, USB буфер и прочее. У Фрискейла там тоже ОЗУ с дополнительной логикой. Похожей на bit-band. Написали бы <опция Кортексов или ARM>, а не так спорно.

На счёт ядра ошибся. SRAM работают с ядром через локальные шины. NVIC, MPU, кэш (которого нет у v6-M) и (какие-то) отладочные узлы встроены в ядро.

Ради эксперимента взял LPC435x, у которого на блок-схеме нарисованы отдельные ядра CM4 и CM0 (без плюса), а вся память и периферия общая. Ядро CM0 при обращении к региону 0x22000000 (bit-band) падает в Hard Fault. Хотя почти без накладных расходов и для удобства юзера логичнее было сделать этот регион общим. Но и тогда bit-banding было бы опцией (любого) процессора, а не архитектуры ARMv6-M или (под)группы.

Цитата
Но имейте в виду: задержки флеша и доступа к периферии (GPIO) там не указаны.

Можно сказать шире: в инструкциях чтения и записи внеядерного адресного пространства могут быть дополнительные такты задержек. Которые ARM не знает и не может указывать. И сами разработчики кристаллов все нюансы часто не описывают.

Сообщение отредактировал GetSmart - Jun 25 2016, 00:32


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 24 2016, 20:25
Сообщение #70


Гуру
******

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



Цитата(Влад Р. @ Jun 24 2016, 19:46) *
При текущей частоте задержка флэш составляет 1 Wait State. Это значит что при выполнении кода из флеша к длительности всех команд можно добавить 1 машинный цикл? Как оценить на сколько в такой ситуации ускоряет выполнение буфер предварительной выборки?

Нет. Задержка добавляется при отсутствии следующей для выполнения команды в буфере предвыборки.
Например: после перехода буфер опустошается. Через 2 такта он будет заполнен 4-мя байтами (если верно, что ширина шины выборки команд == 32 бита как тут ранее писали).
Если в этих 4-х байтах 2 команды и нет перехода, то за время пока они выполняются, буфер предвыборки может успеть прочитать ещё 32 бита (если шина к данной области памяти не занята).
Если же в этих 4-байтах команда 4-байтовая и её длительность в циклах ==1 (не знаю - есть-ли такие в M0?), то тогда да - опять будет опустошение предвыборки и приостановка на такт декодера команд.
Или если буфер предвыборки не успел прочитать след. байты из-за занятости шины (если был доступ CPU к данным в этом-же регионе памяти, или был доступ к данному региону другого bus-mastera по этой-же шине).
В общем - на линейном коде без ветвлений и если в данном регионе находится только исполняемый код, скорей всего никаких дополнительных тактов ожидания не будет.
На переходах будут приостановки. Хотя - может в Вашем МК буфер предыворки содержит несколько строк кеша? Но в Вашем вряд-ли. В некоторых МК буфер предвыборки имеет ёмкость в неск. сток кеша (в Tiva например).
Ещё дополнительные приостановки предвыборки могут быть если целевой адрес перехода не кратен 4. Имхо - буфер предвыборки скорей всего работает с выровненными адресами, а значит при невыровненном на 4 целевом адресе перехода, за первый доступ считает только максимум одну 2-байтовую команду, и если её длительность ==1 икл, то опять будет stall на дополнительный цикл на выборку следующих 32 бит.
Хотя всё это я описал для M3/M4, но думаю в M0 - аналогично.

Совет: там где у Вас switch, используйте табличный переход LDR PC,[Rx] - это сделает все ветвления case одинаковой длительности и избавит от необходимости if (!(db & (0x01 << 12))) {.
Go to the top of the page
 
+Quote Post
Влад Р.
сообщение Jun 24 2016, 21:18
Сообщение #71


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

Группа: Свой
Сообщений: 87
Регистрация: 9-12-10
Пользователь №: 61 511



Цитата(jcxz @ Jun 24 2016, 23:25) *
Нет. Задержка добавляется при отсутствии следующей для выполнения команды в буфере предвыборки.
Например: после перехода буфер опустошается. Через 2 такта он будет заполнен 4-мя байтами (если верно, что ширина шины выборки команд == 32 бита как тут ранее писали).

В Reference manual сказано так: "The prefetch buffer is 3 blocks wide where each block consists of 4 bytes." Видимо как раз те самые 32 бита.

Цитата(jcxz @ Jun 24 2016, 23:25) *
На переходах будут приостановки. Хотя - может в Вашем МК буфер предыворки содержит несколько строк кеша? Но в Вашем вряд-ли. В некоторых МК буфер предвыборки имеет ёмкость в неск. сток кеша (в Tiva например).

В STM32F0 кэша точно нет.

Цитата(jcxz @ Jun 24 2016, 23:25) *
Ещё дополнительные приостановки предвыборки могут быть если целевой адрес перехода не кратен 4. Имхо - буфер предвыборки скорей всего работает с выровненными адресами, а значит при невыровненном на 4 целевом адресе перехода, за первый доступ считает только максимум одну 2-байтовую команду, и если её длительность ==1 икл, то опять будет stall на дополнительный цикл на выборку следующих 32 бит.

Тут типа намекают, что адреса переходов лучше делать кратными 8 байтам:
"The implementation of this prefetch buffer makes a faster CPU execution possible as the CPU fetches one word at a time with the next word readily available in the prefetch buffer. This implies that the acceleration ratio will be of the order of 2 assuming that the code is aligned at a 64-bit boundary for the jumps."

Цитата(jcxz @ Jun 24 2016, 23:25) *
Совет: там где у Вас switch, используйте табличный переход LDR PC,[Rx] - это сделает все ветвления case одинаковой длительности и избавит от необходимости if (!(db & (0x01 << 12))) {.

ОК, как слеплю окончательный код, выложу на суд.

Пока разобрался как задействовать код из asm-файла. Не хватало всего одной директивы:
EXPORT EXTI4_15_IRQHandler
Очень помогло: Mixing C, C++, and Assembly Language
Вот, целиком в текущем виде:
CODE
EXTI_BASE EQU 0x40010400
GPIOA_BASE EQU 0x48000000
GPIOB_BASE EQU 0x48000400
GPIOC_BASE EQU 0x48000800

EXTI_PR_OFFSET EQU 0x14
GPIO_IDR_OFFSET EQU 0x10
GPIO_BSRR_OFFSET EQU 0x18

AREA ASMEXTI, CODE, READONLY
EXTI4_15_IRQHandler PROC
EXPORT EXTI4_15_IRQHandler
LDR r0, =GPIOB_BASE ; загрузить в регистр r0 адрес порта GPIOB
MOVS r1, #0x01 ; копировать в регистр r1 значение 0x01
LSLS r2, r1, #12 ; логический сдвиг влево на 12 бит значения в регистре r1 и сохранение результата в регистр r2
STR r2, [r0, #GPIO_BSRR_OFFSET] ; сохранить слово из регистра r2 в регистр GPIOB->BSRR
LDR r0, =EXTI_BASE ; загрузить в регистр r0 адрес модуля EXTI
LSLS r1, #8 ; логический сдвиг влево на 8 бит значения в регистре r1
STR r1, [r0, #EXTI_PR_OFFSET] ; сохранить слово из регистра r1 в регистр EXTI->PR
BX lr
ENDP
END
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 25 2016, 02:07
Сообщение #72


.
******

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



Цитата(jcxz @ Jun 25 2016, 00:25) *
Хотя всё это я описал для M3/M4, но думаю в M0 - аналогично.

У СМ0 один канал подгрузки данных (шина), У СМ3 (и старше) две или даже три. СМ0 выполняя инструкцию обращения к памяти будет отнимать эту шину от подгрузки кода.

Цитата(Влад Р. @ Jun 25 2016, 01:18) *
Пока разобрался как задействовать код из asm-файла.

После сброса периферии, вызвавшей обработчик нужно несколько тактов ожидания. Можно просто NOP-ов. Если после STR выполнить сразу BX lr, то будет сразу же повторный "залёт" в обработчик. Обычно нужно 3-10 тактов ожидания. Сколько конкретно - ведомо разве что разработчику всего чипа. Можно определить тестируя в железе. Лучше делать с запасом. Можно использовать инструкции DSB, т.к. у СМ0 DSB всегда константной длительности. Но инструкция шириной как два NOPa (32 bit).

Сообщение отредактировал GetSmart - Jun 25 2016, 02:08


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Влад Р.
сообщение Jun 25 2016, 04:15
Сообщение #73


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

Группа: Свой
Сообщений: 87
Регистрация: 9-12-10
Пользователь №: 61 511



Цитата(GetSmart @ Jun 25 2016, 05:07) *
После сброса периферии, вызвавшей обработчик нужно несколько тактов ожидания. Можно просто NOP-ов. Если после STR выполнить сразу BX lr, то будет сразу же повторный "залёт" в обработчик. Обычно нужно 3-10 тактов ожидания. Сколько конкретно - ведомо разве что разработчику всего чипа. Можно определить тестируя в железе. Лучше делать с запасом. Можно использовать инструкции DSB, т.к. у СМ0 DSB всегда константной длительности. Но инструкция шириной как два NOPa (32 bit).

Что-то я подобного не замечал. Написал то же самое на Си и скомпилировал, никакие дополнительные регистры не стекируются (только те, что автоматом). При этом в полученном коде инструкция BX следует сразу за STR.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 25 2016, 15:38
Сообщение #74


.
******

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



Цитата(Влад Р. @ Jun 25 2016, 08:15) *
Что-то я подобного не замечал. Написал то же самое на Си и скомпилировал, никакие дополнительные регистры не стекируются (только те, что автоматом). При этом в полученном коде инструкция BX следует сразу за STR.

Компилятор делает оптимально. Суть не в этом. Если у Вас в асм-коде вторая STR сбрасывает сигнал, идущий от перефирии к NVIC, то в общем случае (хоть в Си хоть в асм) нежелательно это делать в самом конце IRQ. Можно либо нопы вставлять, либо какое-то другое действие обработчика в самый конец перенести, особенно когда на асме (видны все инструкции).

Но за STM32 не берусь утверждать. На NXP (17хх, 13хх) эти дополнительные задержки нужны были точно. Странно, если NXP сделал свою часть чипа так, что от периферии сигнал снятия запроса прерывания доходил до NVIC с большой задержкой, которой нет у STM32. В доках NXP нужность задержек даже не описана. Так что приходилось их использовать для большей безопасности портирования кода. Может они эту граблю специально продемонстрировали чтобы программер был осторожней и сбрасывал запрос чуть раньше выхода из IRQ.

Сообщение отредактировал GetSmart - Jun 26 2016, 04:16


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 27 2016, 04:57
Сообщение #75


Гуру
******

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



Цитата(Влад Р. @ Jun 25 2016, 03:18) *
В Reference manual сказано так: "The prefetch buffer is 3 blocks wide where each block consists of 4 bytes." Видимо как раз те самые 32 бита.
В STM32F0 кэша точно нет.

Ну собственно эти "3 blocks" по 32 бита и есть миникеш. Пока из одного блока идёт декодирование команды, другие могут заполняться.
В Tiva так же примерно, только размер блока ==256бит (по ширине шины предвыборки) и их кол-во больше. И в LPC17xx так же.

Цитата(Влад Р. @ Jun 25 2016, 03:18) *
Тут типа намекают, что адреса переходов лучше делать кратными 8 байтам:
"The implementation of this prefetch buffer makes a faster CPU execution possible as the CPU fetches one word at a time with the next word readily available in the prefetch buffer. This implies that the acceleration ratio will be of the order of 2 assuming that the code is aligned at a 64-bit boundary for the jumps."

Хм... похоже что ширина шины предвыборки скорей всего == 64 бита всё-таки. Раз за такт выбирается одно слово + второе слово оказывается уже в буфере предвыборки за тот же такт.

Цитата(Влад Р. @ Jun 25 2016, 03:18) *
Пока разобрался как задействовать код из asm-файла. Не хватало всего одной директивы:
EXPORT EXTI4_15_IRQHandler

Обычно чтобы символьные имена из асм-файла были видимы в других исходных файлах (си и асм), нужно это символьное имя объявить в директиве PUBLIC.
Ну и, естественно, прописать прототип в си-хидере.
И наоборот: чтобы в асм-файле были видимы имена из других объектных файлов, нужно их указать в директиве EXTERN.
EXPORT я не использую нигде.

Цитата(GetSmart @ Jun 25 2016, 08:07) *
После сброса периферии, вызвавшей обработчик нужно несколько тактов ожидания. Можно просто NOP-ов. Если после STR выполнить сразу BX lr, то будет сразу же повторный "залёт" в обработчик. Обычно нужно 3-10 тактов ожидания. Сколько конкретно - ведомо разве что разработчику всего чипа. Можно определить тестируя в железе. Лучше делать с запасом. Можно использовать инструкции DSB, т.к. у СМ0 DSB всегда константной длительности. Но инструкция шириной как два NOPa (32 bit).

Можно это квитирование прерывания просто поставить в начале ISR, сразу после входа. Я так и делаю обычно.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 20th June 2025 - 09:11
Рейтинг@Mail.ru


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