Перейти к содержанию
    

STM32 OTG USB проблема с отладкой

У кортекса есть вложенные прерывания? Надо их запрещать? Может вызваться новое прерывание, пока не завершилость предыдущее?

Если разрешено соотв. прерывание от USART, то в данном случае может произойти все что угодно.

Покажите вашу инициализацию USART.

 

И все же не помешает по-курить базовую матчасть по кортексам и его NVIC :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если разрешено соотв. прерывание от USART, то в данном случае может произойти все что угодно.

Покажите вашу инициализацию USART.

 

И все же не помешает по-курить базовую матчасть по кортексам и его NVIC :)

 

USART кубом настроен, прерывания выключены, я там ничего не трогал.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

USART кубом настроен, прерывания выключены, я там ничего не трогал.

Нужно, точно локализовать источник косяка. Пока что все упирается в вашу функцию. Копайте в этом направлении.

Например, подряд в основном коде вызвать ее несколько раз или более радикально - гонять в бесконечном цикле, но не в прерываниях.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

USART кубом настроен, прерывания выключены, я там ничего не трогал.

А включить USART не забыли?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если разрешено соотв. прерывание от USART, то в данном случае может произойти все что угодно.

Покажите вашу инициализацию USART.

 

И все же не помешает по-курить базовую матчасть по кортексам и его NVIC :)

 

На sam4s код юсб от sam7 завелся с пол-оборота. Тот же кортекс. И такая же отладка была.

 

Весь код инициализации прерываний

 

NVIC_ClearPendingIRQ((IRQn_Type) ID_UDP);
NVIC_SetPriority((IRQn_Type) ID_UDP, 0);
NVIC_EnableIRQ((IRQn_Type) ID_UDP);

 

Что тут курить-то?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На sam4s код юсб от sam7 завелся с пол-оборота. Тот же кортекс. И такая же отладка была.

А тогда чего вы полезли на STM32, коли на sam4s все "заводится с пол-оборота"? ;)

 

Весь код инициализации прерываний

NVIC_ClearPendingIRQ((IRQn_Type) ID_UDP);
NVIC_SetPriority((IRQn_Type) ID_UDP, 0);
NVIC_EnableIRQ((IRQn_Type) ID_UDP);

А что такое ID_UDP?

 

И покажите наконец-то код инициализации USART.

 

Что тут курить-то?

 

В целях общего ознакомления, ибо без понятия базовых основ NVIC настроить правильно прерывания будет весьма затруднительно.

Ну, и советую отучиться от дурной привычки - вызывать толстые функции в прерываниях, иначе однажды это сыграет злую шутку ...

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А тогда чего вы полезли на STM32, коли на sam4s все "заводится с пол-оборота"? ;)

 

Потому что sam4s не толерантный к 5 вольтам. И труднопокупаемый. А STM32 как грязи на любом развале.

А что такое ID_UDP?

 

UDP = USB Device port

 

И покажите наконец-то код инициализации USART.

 

static void MX_USART1_UART_Init(void)
{
 huart1.Instance = USART1;
 huart1.Init.BaudRate = 115200;
 huart1.Init.WordLength = UART_WORDLENGTH_8B;
 huart1.Init.StopBits = UART_STOPBITS_1;
 huart1.Init.Parity = UART_PARITY_NONE;
 huart1.Init.Mode = UART_MODE_TX_RX;
 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart1.Init.OverSampling = UART_OVERSAMPLING_16;
 if (HAL_UART_Init(&huart1) != HAL_OK)
 {
Error_Handler();
 }
}

/**
 * @brief  Initializes the UART mode according to the specified parameters in
 *		 the UART_InitTypeDef and create the associated handle.
 * @param  huart: pointer to a UART_HandleTypeDef structure that contains
 *				the configuration information for the specified UART module.
 * @retval HAL status
 */
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
{
 /* Check the UART handle allocation */
 if(huart == NULL)
 {
return HAL_ERROR;
 }

 /* Check the parameters */
 if(huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
 { 
/* The hardware flow control is available only for USART1, USART2, USART3 and USART6 */
assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
 }
 else
 {
assert_param(IS_UART_INSTANCE(huart->Instance));
 }
 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));

 if(huart->gState == HAL_UART_STATE_RESET)
 {  
/* Allocate lock resource and initialize it */
huart->Lock = HAL_UNLOCKED;
/* Init the low level hardware */
HAL_UART_MspInit(huart);
 }

 huart->gState = HAL_UART_STATE_BUSY;

 /* Disable the peripheral */
 __HAL_UART_DISABLE(huart);

 /* Set the UART Communication parameters */
 UART_SetConfig(huart);

 /* In asynchronous mode, the following bits must be kept cleared: 
 - LINEN and CLKEN bits in the USART_CR2 register,
 - SCEN, HDSEL and IREN  bits in the USART_CR3 register.*/
 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));

 /* Enable the peripheral */
 __HAL_UART_ENABLE(huart);

 /* Initialize the UART state */
 huart->ErrorCode = HAL_UART_ERROR_NONE;
 huart->gState= HAL_UART_STATE_READY;
 huart->RxState= HAL_UART_STATE_READY;

 return HAL_OK;
}

/**
 * @brief  Initializes the half-duplex mode according to the specified
 *		 parameters in the UART_InitTypeDef and create the associated handle.
 * @param  huart: pointer to a UART_HandleTypeDef structure that contains
 *				the configuration information for the specified UART module.
 * @retval HAL status
 */
HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
{
 /* Check the UART handle allocation */
 if(huart == NULL)
 {
return HAL_ERROR;
 }

 /* Check the parameters */ 
 assert_param(IS_UART_INSTANCE(huart->Instance));
 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));

 if(huart->gState == HAL_UART_STATE_RESET)
 { 
/* Allocate lock resource and initialize it */
huart->Lock = HAL_UNLOCKED;
/* Init the low level hardware */
HAL_UART_MspInit(huart);
 }

 huart->gState = HAL_UART_STATE_BUSY;

 /* Disable the peripheral */
 __HAL_UART_DISABLE(huart);

 /* Set the UART Communication parameters */
 UART_SetConfig(huart);

 /* In half-duplex mode, the following bits must be kept cleared: 
 - LINEN and CLKEN bits in the USART_CR2 register,
 - SCEN and IREN bits in the USART_CR3 register.*/
 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN));

 /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
 SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL);

 /* Enable the peripheral */
 __HAL_UART_ENABLE(huart);

 /* Initialize the UART state*/
 huart->ErrorCode = HAL_UART_ERROR_NONE;
 huart->gState= HAL_UART_STATE_READY;
 huart->RxState= HAL_UART_STATE_READY;

 return HAL_OK;
}

В целях общего ознакомления, ибо без понятия базовых основ NVIC настроить правильно прерывания будет весьма затруднительно.

Ну, и советую отучиться от дурной привычки - вызывать толстые функции в прерываниях, иначе однажды это сыграет злую шутку ...

 

Я не собираюсь их там оставлять. После отладки кода все они удаляются.

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А STM32 как грязи на любом развале.

В таком случае все же придется изучать матчасть и иногда копаться в даташитах )))

 

 

Посмотрите наконец-то post #5 на первой странице.

Там нет кода инициализации USART. Вы вообще понимаете смысл слова "инициализация"?

Короче, покажите код, где USART настраивается на роботу, где настраиваются его регистры и т.п.

 

 

Я не собираюсь их там оставлять. После отладки кода все они удаляются.

Отладочный код (DEBUG) должен работать практически одинаково с финальным (RELEASE). В крайнем случае он как минимум должен хотя бы работать, в обоих случаях ;)

Я лишь предостерег от граблей, на которые сам наступал в свое время.

Кстати, нет никакой нужды удалять отладочный код, для этого есть встроенный в любой компилятор препроцессор (#ifdef #endif и т. п.)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

В таком случае все же придется изучать матчасть и иногда копаться в даташитах )))

 

 

 

Там нет кода инициализации USART. Вы вообще понимаете смысл слова "инициализация"?

Короче, покажите код, где USART настраивается на роботу, где настраиваются его регистры и т.п.

 

Исправил.

 

Отладочный код (DEBUG) должен работать практически одинаково с финальным (RELEASE). В крайнем случае он как минимум должен хотя бы работать, в обоих случаях ;)

Я лишь предостерег от граблей, на которые сам наступал в свое время.

Кстати, нет никакой нужды удалять отладочный код, для этого есть встроенный в любой компилятор препроцессор (#ifdef #endif и т. п.)

 

 

Препроцессор - зло. Он не нужен.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }

 

Коли вы используете HAL в инициализации USART, то советую и в других функциях по работе с USART использовать HAL.

Рекомендую посмотреть в сторону HAL_UART_Transmit

 

Кстати, вызов этой вашей толстой функции происходит только в одном месте или раскидан по всему проекту?

Если это так, то срочно переписывайте вашу функцию-самодеятельность под HAL полностью (подробности см. в реализации HAL_UART_Transmit).

 

 

 

Препроцессор - зло. Он не нужен.

 

Это кто ж такой умный сказал вам такую абсолютную глупость? :cranky:

#define - это тоже препроцессор, неужели ваша религия не позволяет им тоже пользоваться? :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Коли вы используете HAL в инициализации USART, то советую и в других функциях по работе с USART использовать HAL.

Рекомендую посмотреть в сторону HAL_UART_Transmit

 

Кстати, вызов этой вашей толстой функции происходит только в одном месте или раскидан по всему проекту?

Если это так, то срочно переписывайте вашу функцию-самодеятельность под HAL полностью (подробности см. в реализации HAL_UART_Transmit).

 

Это кто ж такой умный сказал вам такую абсолютную глупость? :cranky:

 

Я в первую очередь пробовал через HAL_UART_Transmit, нет разницы. Вызовы только в обработчике USB_OTG_Handler. Но я пробовал оставлять только единственный вызов в начале обработчика. Тоже не работает.

 

Препроцессор зло, это аксиома. Не требует доказательств.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я в первую очередь пробовал через HAL_UART_Transmit, нет разницы.

В основном коде ВНЕ прерываний эта функция работает? В бесконечном цикле.

 

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

Правильно так: кидать байты строки в некую программную очередь и разрешать передачу, заранее настроив прерывания от USART.

Можно даже извратиться на DMA, но это уже детали, не относящиеся к делу...

 

Препроцессор зло, это аксиома. Не требует доказательств.
Весьма сочувствую вашему "вероисповеданию" ... :crying:

Тонны "магических цифр" по коду - это самый страшный кошмар любого программиста.

Поэтому мне всегда грустно видеть, как некоторые "программисты" этот кошмар сознательно воплощают в своей реальности, отказываясь даже от безобидных #define ....

 

Короче, сначала в пустом проекте отладьте нормально работу этой вашей "отладочной" функции и уже потом суйте ее куда планировали.

В противном случае все это - бесконечный пинг-понг ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

См. Post #5 выше.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В основном коде ВНЕ прерываний эта функция работает? В бесконечном цикле.

 

Да.

 

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

Правильно так: кидать байты строки в некую программную очередь и разрешать передачу, заранее настроив прерывания от USART.

 

Так и делаю сейчас.

 

Можно даже извратиться на DMA, но это уже детали, не относящиеся к делу...

 

Весьма сочувствую вашему "вероисповеданию" ... :crying:

Тонны "магических цифр" по коду - это самый страшный кошмар любого программиста.

Поэтому мне всегда грустно видеть, как некоторые "программисты" этот кошмар сознательно воплощают в своей реальности, отказываясь даже от безобидных #define ....

 

#define - > #define -> #define .. еще раз десять вложенных #define и в конце a = 5;

Это конечно лучше.

Про малоуловимые глюки в макросах и смысла нет говорить.

А уж условная компиляция так помогает понять логику работы...

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кстати, вызов этой вашей толстой функции происходит только в одном месте или раскидан по всему проекту?

Если это так, то срочно переписывайте вашу функцию-самодеятельность под HAL полностью (подробности см. в реализации HAL_UART_Transmit).

Если человек вызывает такие функции (как в 5-м посте) из ISR ничтоже сумняшеся, то и в остальном коде он мог наделать очевидных глупостей.

Например вызывать этот UARTPrint() из ISR и из фоновой задачи без блокировок.

Переписывание этого под гал или чего-то другое ничего не даст. Если нет понимания как всё в сумме оно работает.....

 

ЗЫ: теме место - в "помощи начинающему".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...