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

 
 
2 страниц V   1 2 >  
Closed TopicStart new topic
> Странное поведение STM32F745
Денис555
сообщение Jan 14 2016, 16:17
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 29-09-06
Из: Самара
Пользователь №: 20 827



Доброго времени суток!
Столкнулся с проблемой при использовании STM32F745.
Элементарная программа:
В main в бесконечном цикле происходит постоянный вызов процедуры, в которой следующее:
1. выставили лог. 1 на GPIO
2. пустой цикл задержки
3. сбросили пин GPIO (лог. 0)
4. пустой цикл задержки
...
и далее повторение пунктов 1-4 4 раза.
Все пустые циклы сделал ассемблерными вставками (чтобы наверняка, компилятор проглатывает как есть).
На осциллографе 3 первых получившихся импульса и пауз между ними одинаковые, а четвертый импульс растянут раз в 5 больше. Эффект независим от длительности импульсов.
При добавлении кол-ва импульсов этот эффект может проявиться где угодно в разных импульсах и паузах 1 и более раз.
Тактирование PLL - 200 МГц от внешнего генератора 25 МГц. Пробовал и c HAL-ом и без него. Кроме GPIO и RCC (тактирование) ничего не включено. Все прерывания отключены. Питание норм.
Что это может быть? Уже всю голову сломал и уже не я один.
Приветствуются любые предложения.
Спасибо!
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jan 14 2016, 16:43
Сообщение #2


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

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



Если в Кейле, то можно в отладчике пройтись по ассемблерным командам. Там и такты считаются, и время.
Если не в Кейле, то ассемблерный листинг все равно можно посмотреть.
Go to the top of the page
 
+Quote Post
Денис555
сообщение Jan 14 2016, 16:55
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 29-09-06
Из: Самара
Пользователь №: 20 827



Пишу в Keil-е. В ассемблерном листинге все ровно как и хотелось, компилятор оставляет всавки как есть. В отладке все красиво пробегает. Все по порядку, ни шагу в лево ни шагу вправо.
На практике чудеса...
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Jan 14 2016, 17:05
Сообщение #4


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(Денис555 @ Jan 14 2016, 18:17) *
Приветствуются любые предложения.


Есть предложение выложить проект сюда.
Go to the top of the page
 
+Quote Post
Денис555
сообщение Jan 14 2016, 17:28
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 29-09-06
Из: Самара
Пользователь №: 20 827



CODE
/* Includes ------------------------------------------------------------------*/
#include "stm32f7xx_hal.h"
#include "gpio.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);

/* USER CODE BEGIN PFP */
void TDC12(void);
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */

int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();

/* Initialize all configured peripherals */
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */

SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; //Disable IRQ SysTick
SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //Disable SysTick
__disable_irq ();
while (1)
{
TDC12();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
__PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 12;
RCC_OscInitStruct.PLL.PLLN = 192;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 2;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
HAL_PWREx_ActivateOverDrive();
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_6);
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/* USER CODE BEGIN 4 */
void TDC12(void)
{
register uint32_t adr __asm("r4");
register uint32_t portb __asm("r5");
register uint32_t portc __asm("r6");
register uint32_t portd __asm("r7");
register uint32_t porte __asm("r8");
register uint32_t win1 __asm("r9");
register uint32_t win2 __asm("r10");
register uint32_t win3 __asm("r11");
register uint32_t win4 __asm("r12");
adr=0;
portb=0x40020400;
portc=0x40020800;
portd=0x40020c00;
porte=0x40021000;
win1=100;
win2=100;
win3=100;
win4=100;
__asm {
MOV temp,#0x00000010
STR temp,[portc,#0x18]
MOV adr,#0x00000000
lab1:
ADDS adr,adr,#1
CMP adr,win1
BCC lab1 }

__asm {
MOV temp,#0x00100000
STR temp,[portc,#0x18]
MOV adr,#0x00000000
Lab2:
ADDS adr,adr,#1
CMP adr,win2
BCC lab2 }

__asm {
MOV temp,#0x00000010
STR temp,[portc,#0x18]
MOV adr,#0x00000000
Lab3:
ADDS adr,adr,#1
CMP adr,win3
BCC lab3 }

__asm {
MOV temp,#0x00100000
STR temp,[portc,#0x18]
MOV adr,#0x00000000
Lab4:
ADDS adr,adr,#1
CMP adr,win4
BCC lab4 }
}

/* USER CODE END 4 */
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif


Это с использованием HAL есть и без HAL-а, сейчас не под рукой, но результат одинаковый.
Процедуру урезал до 2-х импульсов, что бы не нагромождать.
Что бы на таком простом коде были у STM32F7 такие непонятные явления, очень странно...

Сообщение отредактировал IgorKossak - Jan 14 2016, 19:33
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jan 14 2016, 18:37
Сообщение #6


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

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



Думаю, надо присмотреться к кэшу. Шина Flash у STM32F745 64-битовая. Латентность большая.
Go to the top of the page
 
+Quote Post
alx125
сообщение Jan 15 2016, 02:54
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 202
Регистрация: 18-05-09
Из: Novosibirsk
Пользователь №: 49 204



Рискну предположить, что Вы ранее имели дело с микроконтроллерами без конвеера и кэш.
Там функцию точной задержки можно было написать простым циклом.
В ахитектуре ARM используется конвеер и значит многие вещи стали не детерминированными по времени!
Если Вам нужно точную задержку в ARM - необходимо использовать таймер+прерывание
Go to the top of the page
 
+Quote Post
arhiv6
сообщение Jan 15 2016, 03:57
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 633
Регистрация: 21-05-10
Из: Томск
Пользователь №: 57 423



Цитата(alx125 @ Jan 15 2016, 08:54) *
Если Вам нужно точную задержку в ARM - необходимо использовать таймер+прерывание

Даже если все перифирийные таймеры заняты, в самом ARM ядре есть системный таймер который для этого можно использовать. Вот пример.

Сообщение отредактировал arhiv6 - Jan 15 2016, 03:58


--------------------
Go to the top of the page
 
+Quote Post
Денис555
сообщение Jan 15 2016, 07:07
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 29-09-06
Из: Самара
Пользователь №: 20 827



Про SysTick и про DWT - это все понятно, можно, но не для моей реализации.
Нужно решить именно эту задачу.
Что такое конвейер тоже в курсе, работал. Добавленный акселерометр должен ускорять, а не тормозить процесс.
Пробовал отключать и включать акселерометр, не помогает.
Отключение ICash к изменению результата не приводит.

Даже если решить эту проблему другим образом, встретить в программе подряд идущих несколько циклов, не обязательно задержек, очень легко.
И представьте, что МК, ни с того ни с сего, будет выполнять один из циклов в 5 раз дольше... Это нормально? Я понял бы если +- 20 - 50 тактов куда то уходило...
Но столько...

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

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

Кратно 32, 64 байта...

Сообщение отредактировал Денис555 - Jan 15 2016, 05:38
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jan 15 2016, 07:47
Сообщение #10


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

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



У вас конвейер 7-ступенчатый! maniac.gif Задумайтесь. Если программа куда-то перескакивает (в начало цикла), конвейер переписывается.
Можно проверить. Понизить тактовую частоту, изменить латентность конвейера.
Акселерометр != Акселератор. rolleyes.gif
Go to the top of the page
 
+Quote Post
mantech
сообщение Jan 15 2016, 08:32
Сообщение #11


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(ViKo @ Jan 15 2016, 10:47) *
У вас конвейер 7-ступенчатый! maniac.gif Задумайтесь. Если программа куда-то перескакивает (в начало цикла), конвейер переписывается.
Можно проверить. Понизить тактовую частоту, изменить латентность конвейера.
Акселерометр != Акселератор. rolleyes.gif


Когда-то тоже делал подобное, пробовал линейно сделать 10 или 20 переключений пина и только потом переходил снова к первому, при переходе, действительно возникала 3х кратная задержка, чем длиннее линейная составляющая - тем точнее длительность. Плюс еще накладывалось ожидание готовности периферийной шины, а она заметно медленнее, чем процессорная.
Проверьте...

Сообщение отредактировал mantech - Jan 15 2016, 08:33
Go to the top of the page
 
+Quote Post
Денис555
сообщение Jan 15 2016, 08:57
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 29-09-06
Из: Самара
Пользователь №: 20 827



Цитата(ViKo @ Jan 15 2016, 11:47) *
У вас конвейер 7-ступенчатый! maniac.gif Задумайтесь. Если программа куда-то перескакивает (в начало цикла), конвейер переписывается.
Можно проверить. Понизить тактовую частоту, изменить латентность конвейера.
Акселерометр != Акселератор. rolleyes.gif

Да да, очепятка, акселератор... rolleyes.gif
А что Вы имеете ввиду под изменить латентность? Таковая частота понизится и должно быть все тоже самое, только растянется по времени...
По поводу перезаписи конвейера:
Если так случится, что к примеру ему пришлось переписАться, то была бы аддитивная задержка в начале одного цикла на несколько тактов, но не постоянно же...?
Конвейер - 6 ступенчатый rolleyes.gif
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jan 15 2016, 09:17
Сообщение #13


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

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



Цитата(Денис555 @ Jan 15 2016, 11:57) *
Да да, очепятка, акселератор... rolleyes.gif
А что Вы имеете ввиду под изменить латентность? Таковая частота понизится и должно быть все тоже самое, только растянется по времени...

Доступ к флэш-памяти. Чем меньше тактовая частота, тем меньше тактов можно задать для доступа. Там табличка есть, в референс руководстве, в разделе Flash.
Go to the top of the page
 
+Quote Post
Денис555
сообщение Jan 15 2016, 10:15
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 29-09-06
Из: Самара
Пользователь №: 20 827



Цитата(ViKo @ Jan 15 2016, 13:17) *
Доступ к флэш-памяти. Чем меньше тактовая частота, тем меньше тактов можно задать для доступа. Там табличка есть, в референс руководстве, в разделе Flash.

Это да, сейчас wait state стоит 7 тактов (для моих 200 МГц). При уменьшении тактирования и соответственно wait state уменьшится, но и частота всех шин тоже.
Но чем черт не шутит, попробую, хотя сомневаюсь. Спасибо!
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jan 15 2016, 10:18
Сообщение #15


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

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



Сама латентность не уменьшится с понижением тактовой частоты, а будет столько, сколько зададите. sm.gif
Go to the top of the page
 
+Quote Post

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

 


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


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