Миландр

Ключевым подразделением нашей компании является Центр Проектирования интегральных микросхем
Текущее время: 2018-дек-19 03:14

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 14 ] 
Автор Сообщение
СообщениеДобавлено: 2018-фев-12 13:48 
Не в сети

Зарегистрирован: 2018-янв-23 21:37
Сообщения: 17
У меня вопрос по программным задержкам, реализуемым в библиотечных функциях при работе с EEPROM (“EEPROM_ProgramWord”, “EEPROM_ErasePage” и т.п. в файле “MDR32F9Qx_eeprom.h”):
почему число тактов, которое я наблюдаю с помощью SysTick, отличается от расчетного в два раза?

Мой код для проверки:
myloops = ((uint32_t)((double)(5) * 80 / 8 + 1.0));
SysTick->LOAD = (uint32_t)(10000);
SysTick->VAL = 0UL;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_ENABLE_Msk;
myProgramDelay(myloops);
timesystick = SysTick->VAL;
timesystick = 10000UL - timesystick;
SysTick->CTRL = 0;

Функция myProgramDelay (аналогично “ProgramDelay”):
__RAMFUNC static void myProgramDelay(uint32_t Loops)
{
volatile uint32_t i = Loops;
for (; i > 0; i--)
{
}
}

Так вот, если выполнить этот кусок кода в отладчике, то timesystick = 852,
а должно быть в районе 410 – 450 (51*8 + Tsrvs).
Почему такая разница?
Условия проведения эксперимента:
1. Отладочная плата “EVALUATION BOARD FOR MCU 1986VE91T Rev/4”.
2. Частота HCLK – 80 МГц.
3. JTAG отладчик – Segger.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-фев-13 08:10 
Не в сети

Зарегистрирован: 2010-авг-30 19:12
Сообщения: 407
Цитата:
Почему такая разница?

Смотрите, в какой набор инструкций ассемблера был преобразован ваш си-код. Часто зависит от степени оптимизации.
Кроме того volatile в данном случае лишний (мое мнение), как и сама переменная i.

_________________
О сколько нам открытий чудных
Готовит просвященья дух,
И опыт - сын ошибок трудных ... (Пушкин)

Пергаменты не утоляют жажду ("Фауст",Гете)


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-фев-13 09:56 
Не в сети

Зарегистрирован: 2018-янв-23 21:37
Сообщения: 17
Вот как выглядит ассемблерный набор команд
Вложение:
Assembler_ProgrammDelay.bmp
Assembler_ProgrammDelay.bmp [ 269.36 КБ | Просмотров: 2444 ]

Но как его пересчитать в число тактов?
Надо, наверно, учитывать очистку 3-х ступенчатого конвейера Cortex-M3 для условных операций…
Так, правильно ли я понимаю, что в операции расчета времени задержки в файле “MDR32F9Qx_eeprom.c” константу “DELAY_LOOP_CYCLES” необходимо умножить на 2?! (Я это уже проверил на практике, и тогда число тактов SysTick более соответствует ожидаемому значению)
Насчет того, что volatile и i –лишние, как они могут быть лишними? Это же прописано в функции в “ProgrammDelay” в файле “MDR32F9Qx_eeprom.c”, которую я и тестирую!
Или помимо ошибки константы “DELAY_LOOP_CYCLES” в файле “MDR32F9Qx_eeprom.c” необходимо исправить еще и саму функцию “ProgrammDelay”?!
Вложение:
Assembler_ProgrammDelay.bmp
Assembler_ProgrammDelay.bmp [ 269.36 КБ | Просмотров: 2444 ]


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-фев-13 10:56 
Не в сети

Зарегистрирован: 2017-апр-26 14:51
Сообщения: 202
Откуда: ПКК "Миландр"
Количество тактов на инструкцию можно посмотреть здесь - http://infocenter.arm.com/help/index.js ... DIGAC.html
В зависимости от выставленной оптимизации компилятора, количество циклов меняется (ассемблерный код разный).

Полагаю, что автор кода заложился в DELAY_LOOP_CYCLES на то, что при любой оптимизации, компилятор не сделает тело цикла меньше 8 тактов.
Больше - не критично, лучше передержать задержку, чем недодержать.

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

_________________
Отдел технической поддержки support@milandr.ru


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-фев-13 13:46 
Не в сети

Зарегистрирован: 2018-янв-23 21:37
Сообщения: 17
Спасибо!
Но хотел бы еще добавить, что я, все-таки, собрал и запустил простенький проект с этой функцией “ProgrammDelay” в другой среде – в Keil c ULINK2 (вообще, я пользуюсь Eclipse с Segger).
Ассемблерный код получился очень похожим:
Вложение:
Assembler_ProgrammDelay_Keil.jpg
Assembler_ProgrammDelay_Keil.jpg [ 18.66 КБ | Просмотров: 2421 ]

Но timesystick = 696 – действительно изменилось, но всеравно значительно больше расчетного значения (450).
Вообще, конечно, это всё не критично, но просто придется (на всякий случай) для таймера ожидания ответа в программе на ПК устанавливать время с большим запасом!


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-фев-13 14:31 
Не в сети

Зарегистрирован: 2016-окт-14 19:39
Сообщения: 44
Откуда: СПБ
1986BE1 Series Errata Notice ошибка 0011 - не это? У 1986ВЕ9x, похоже, такая же проблема.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-фев-13 14:46 
Не в сети

Зарегистрирован: 2018-янв-23 21:37
Сообщения: 17
azimuth писал(а):
1986BE1 Series Errata Notice ошибка 0011 - не это? У 1986ВЕ9x, похоже, такая же проблема.

Вроде, нет. Так как таймер, который запускался на компьютере для ожидания загрузки данных во Flash, показывал примерно такое же время, что и SysTick. Мое замечание вообще и родилось из-за того, что реальное время процесса загрузки всех данных во Flash было примерно в 2 раза больше рассчетного.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-фев-13 15:19 
Не в сети

Зарегистрирован: 2010-сен-21 12:57
Сообщения: 672
Откуда: г. Санкт-Петербург
Для 1986ве9х удобно использовать счетчик DWT(часть ядра Cortex M3).
К сожалению у 1986ВЕ1 такой возможности нет.

Открыть
Код:
void DWT_Init()
{
   CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
   DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}
void DWT_DeInit()
{
   CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk;
   DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk;
}
void delay_dwt(int idwt) // задержка на idwt тактов ядра.
{
DWT_Type* dwt = DWT;
   dwt->CYCCNT = 0;
   while(dwt->CYCCNT < idwt);
}
Закрыть


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-фев-13 17:20 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1189
Откуда: Тула
user_1983 писал(а):
Спасибо!
Но хотел бы еще добавить, что я, все-таки, собрал и запустил простенький проект с этой функцией “ProgrammDelay” в другой среде – в Keil c ULINK2 (вообще, я пользуюсь Eclipse с Segger).
Ассемблерный код получился очень похожим:
Вложение:
Assembler_ProgrammDelay_Keil.jpg

Но timesystick = 696 – действительно изменилось, но всеравно значительно больше расчетного значения (450).
Вообще, конечно, это всё не критично, но просто придется (на всякий случай) для таймера ожидания ответа в программе на ПК устанавливать время с большим запасом!

Разница так же может быть обусловлена исполнением функции из flash-памяти, против исполнения из ОЗУ в сообщении выше.

_________________
сочувствующий…


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-фев-13 21:12 
Не в сети

Зарегистрирован: 2018-янв-23 21:37
Сообщения: 17
Возможно. Но тогда в ассемблерном наборе команд были бы команды "nop" для ожидания очердных инструкций на исполнение в cpu.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-фев-13 22:31 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1189
Откуда: Тула
user_1983 писал(а):
Возможно. Но тогда в ассемблерном наборе команд были бы команды "nop" для ожидания очердных инструкций на исполнение в cpu.

Когда тогда? Просто ядро встанет пока не появятся нужные данные.
Пример - внешняя шина - можете настраивать времянку на десяти тактов медленнее ядра и всё равно работать не учитывая этого всего. Да и с флеш та же ерунда. Нету тут спекулятивного исполнения.

_________________
сочувствующий…


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-фев-14 08:22 
Не в сети

Зарегистрирован: 2018-янв-23 21:37
Сообщения: 17
Про ограничение скорости доступа к ОЗУ (в отличие от Flash) в спецификации на 1986ВЕ9х ничего не сказано:
Вложение:
Screenshot_20180214-081615_1.jpg
Screenshot_20180214-081615_1.jpg [ 144.15 КБ | Просмотров: 2366 ]


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-фев-14 09:50 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1189
Откуда: Тула
user_1983 писал(а):
Про ограничение скорости доступа к ОЗУ (в отличие от Flash) в спецификации на 1986ВЕ9х ничего не сказано

Да там много чего не сказано.
Голова на что? SRAM разделяемый ресурс? Да. Работа ДМА, чтение кода команд и чтение/запись данных ядром в общем случае могут происходить одновременно. Соответственно чтение кода команд и чтение/запись данных при выполнении команд будут происходить последовательно и могут тормозить ядро.

_________________
сочувствующий…


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-фев-15 23:40 
Не в сети

Зарегистрирован: 2016-окт-14 19:39
Сообщения: 44
Откуда: СПБ
Вообще, для формирования задержек при работе с EEPROM я использовал SysTick. Мне кажется, так надежнее.

Еще, к слову, наблюдение. В какой-то версии Keil, компилятор может таки соптимизировать локальную переменную в функции volatile.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 14 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 6


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB