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

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

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

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

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

 

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

 

 

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


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

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

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

Ну, судя по тому, как вы спотыкаетесь на примитивной функции и можно сказать на ровном месте, то действительно вам не стоит пользоваться ни препроцессором ни чем-то еще более функциональным :smile3046:

Пожалуй, очень правильно, что вам кто-то строго настрого запретил пользоваться препроцессором, внушив, что, якобы, это злейшее зло.... Пусть уж лучше так :biggrin:

 

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

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

Трудно не согласиться :)

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


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

Чем дальше в лес, тем толще партизаны.

 

Сделал отладочный вывод в массив в озу и затем из него в UART.

Устройство подключается и определяестя.

Но когда начинается вывод через UART, устройство отваливается.

Через отладчик выяснил, что процессор падает в HardFault.

 

Падает на этой функции:

 

void up(void)
{
    volatile char *s = mem;
    for(;;)
    {
        while((USART1->SR & USART_SR_TXE) == 0);
        USART1->DR = *s++;
        if (*s == 0) break;
    }
}

mem - это массив с данными.

 

Если в отладчике зайти в эту фунцию и вручную шагать, то все работает. Если же сделать Step Over - HardFault.

 

Проект сгенерирован кубом. Он же правильно все тайминги выставляет? Задержка доступа к FLASH, частоты шин APB, AHB?

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


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

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

 

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

Покажите код, где вы это делаете.

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


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

Покажите код, где вы это делаете.

 

static char mem[16384]; 
static volatile uint32_t p;


void up(void)
{
    HAL_UART_Transmit(&huart1,(uint8_t *)mem,strlen(mem),100);
}

void dbgInit(void)
{
    memset(mem,0,16384);
    p = 0;
}

void UARTPrint(char *s)
{
    volatile uint32_t x;
    if(p > 16000) return;
  for(;;)
  {
        mem[p++] = *s++;
        if(*s == 0) break;
  }
}

 

в main:

 

dbgInit();

MX_USB_DEVICE_Init();

 

... задержка

 

up();

 

внутри перывания USB в самом начале

 

UARTPrint("\r\m-----IRQ");

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


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

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

Короче, этот код работает или виснет в некой up()?

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


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

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

Короче, этот код работает или виснет в некой up()?

 

Падает на этой функции:

 

void up(void)
{
    volatile char *s = mem;
    for(;;)
    {
        while((USART1->SR & USART_SR_TXE) == 0);
        USART1->DR = *s++;
        if (*s == 0) break;
    }
}

mem - это массив с данными.

 

Если в отладчике зайти в эту фунцию и вручную шагать, то все работает. Если же сделать Step Over - HardFault.

Изменено пользователем Chameleon

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


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

Падает на этой функции:
void up(void)
{
    volatile char *s = mem;
    for(;;)
    {
        while((USART1->SR & USART_SR_TXE) == 0);
        USART1->DR = *s++;
        if (*s == 0) break;
    }
}

Мля, я не про эту несчастную кривую функцию, которая не предназначенная для использования в прерываниях в принципе!

Я про тот набор текста, который приведен в посте #35. Оно работает как вам нужно или тоже типит?

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


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

Мля, я не про эту несчастную кривую функцию, которая не предназначенная для использования в прерываниях в принципе!

Я про тот набор текста, который приведен в посте #35. Оно работает как вам нужно или тоже типит?

 

Падает на up().

Изменено пользователем Chameleon

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


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

Дефайн __HAL_PCD_CLEAR_FLAG определен как

GINTSTS &= 0x40000000;

Но ведь для сброса флага прерывания в него надо записывать "1" ????

Т.е. делать так:

GINTSTS |= 0x40000000;

 

Вообще говоря, этот код работает.

В это место вы попадаете с установленным 30-м битом; он ещё раз умножается на 30-й бит и записывается обратно.

Вариант

GINTSTS |= 0x40000000;

неправильный, он лишние флажки поскидывает.

Простой и понятный вариант

GINTSTS = 0x40000000;

но для индусов это слишком просто.

 

По делу не помогу. Я это нагромождение дефайнов и абстракций не осилил. Заметно лучше, чем SPL, но для прикручивания своего протокола понадобилось бы переписать половину этой "библиотеки". Плюнул, взял libopencm3 - там тоже переписывать надо, но хотя бы структура прозрачная.

 

Мля, я не про эту несчастную кривую функцию, которая не предназначенная для использования в прерываниях в принципе!

 

У меня вопрос. Где граница, при превышении которой этот самый-лучший-в-мире стек упадёт нафиг? Убираем несчастную кривую функцию, добавляем два высокоприоритетных прерывания. Будет работать? Увеличиваем частоту прерываний на порядок. Будет работать?

 

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

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


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

Вероятно надо использовать HAL_UART_Transmit_IT или HAL_UART_Transmit_DMA для передачи по прерываниям или по DMA.

HAL_UART_Transmit передает по поллингу, эта функция блокирующая на все время передачи.

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


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

GINTSTS = 0x40000000;

но для индусов это слишком просто.

Так было сделано в одной из старых версий HAL, а щас стоит "&=". Видать, есть на то причины ...

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

 

 

По делу не помогу. Я это нагромождение дефайнов и абстракций не осилил.

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

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

 

У меня вопрос. Где граница, при превышении которой этот самый-лучший-в-мире стек упадёт нафиг? Убираем несчастную кривую функцию, добавляем два высокоприоритетных прерывания. Будет работать? Увеличиваем частоту прерываний на порядок. Будет работать?

Речь тут не про HAL/CUBE и т. п, а про совсем другое - про банальное нарушение базового правила кода под МК: заходить в прерывания можно только для того, чтобы "отметиться" и что-то просемафорить наружу в основной код.

А число-дробилки и циклы ожидания выносятся наружу в основной код. Иначе жди беды!

 

 

 

 

Вероятно надо использовать HAL_UART_Transmit_IT или HAL_UART_Transmit_DMA для передачи по прерываниям или по DMA.

HAL_UART_Transmit передает по поллингу, эта функция блокирующая на все время передачи.

Дык, с самого начала этой темы тока об этом и говорю, но что-то очень туго это доходит :1111493779:

 

 

Падает на up().

Вижу простое решение: отладить это чудо-код на ПУСТОМ проекте, добиться от него стабильной работы в разных ситуациях (банально тесты), и уже только после этого куда-то сувать.

 

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

Для этого достаточно уже существующего SWD или JTAG: https://electronix.ru/forum/index.php?s=&am...t&p=1482569

Таких тормозов нет и в помине. Работает как раз с полпинка, но обладает в сотни раз бОльшим функционалом. Бесплатно, исходники открыты.

 

Но коли нравиться изобретать велосипед, то конечно же продолжайте в том же духе:

void UARTPrint(char *s)
{
    for(;;)
    {
        while((USART1->SR & USART_SR_TXE) == 0);
        USART1->DR = *s++;
        if (*s == 0) break;
    }
}

 

:rolleyes:

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


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

Вижу простое решение: отладить это чудо-код на ПУСТОМ проекте, добиться от него стабильной работы в разных ситуациях (банально тесты), и уже только после этого куда-то сувать.

 

Спасибо, КЭП.

 

Вы что, не понимаете, что это и есть ПУСТОЙ ПРОЕКТ. Только USB и UART. Что я и пытаюсь добиться стабильной работы в разных ситуациях? Да, да, передача строки по поллингу и есть СИТУАЦИЯ. И они должны работать вместе в любых комбинациях?

 

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

Для этого достаточно уже существующего SWD или JTAG: https://electronix.ru/forum/index.php?s=&am...t&p=1482569

Таких тормозов нет и в помине. Работает как раз с полпинка, но обладает в сотни раз бОльшим функционалом. Бесплатно, исходники открыты.

 

Но коли нравиться изобретать велосипед, то продолжайте в том же духе:

void UARTPrint(char *s)
{
    for(;;)
    {
        while((USART1->SR & USART_SR_TXE) == 0);
        USART1->DR = *s++;
        if (*s == 0) break;
    }
}

 

:rolleyes:

 

Отличный совет - не получается? Как нибудь придумай обход. Прилепи костыль. Авось по другому прокатит.

 

 

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


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

Спасибо, КЭП.

 

Вы что, не понимаете, что это и есть ПУСТОЙ ПРОЕКТ. Только USB и UART.

А что делает тут USB?

Короче, ПУСТОЙ НОВЫЙ проект только для того, чтобы отладить ваши несчастные костыльные функции.

Добейтесь тут от них нормальной работы в ПУСТОМ проекте. Поиграйтесь с размером стека (например).

В конце концов, сделайте нормальный функционал БЕЗ поллинга!

 

Что я и пытаюсь добиться стабильной работы в разных ситуациях? Да, да, передача строки по поллингу и есть СИТУАЦИЯ. И они должны работать вместе в любых комбинациях?

Я не пойму, чего вы хотите добиться? Чтобы проект был сделан сразу нормально и без костылей или, просто, хотите что-то доказать себе или кому-то?

 

Отличный совет - не получается? Как нибудь придумай обход. Прилепи костыль. Авось по другому прокатит.

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

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

Если не хотите или не можете освоить готовые решения, так пользуйтесь и далее своими чудо-функциями, которая как вы говорите, "с полпинка работает на sam4s" и т. п.

 

Короче, далее бейтесь о стену уже без моей помощи - все, чем я мог помочь, тут уже прозвучало и неоднократно и не только от меня. Удачи ;)

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


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

А что делает тут USB?

Короче, ПУСТОЙ НОВЫЙ проект только для того, чтобы отладить ваши несчастные костыльные функции.

Добейтесь тут от них нормальной работы в ПУСТОМ проекте. Поиграйтесь с размером стека (например).

В конце концов, сделайте нормальный функционал БЕЗ поллинга!

 

 

Я не пойму, чего вы хотите добиться? Чтобы проект был сделан сразу нормально и без костылей или, просто, хотите что-то доказать себе или кому-то?

 

 

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

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

Если не хотите или не можете освоить готовые решения, так пользуйтесь и далее своими чудо-функциями, которая как вы говорите, "с полпинка работает на sam4s" и т. п.

 

Короче, далее бейтесь о стену уже без моей помощи - все, чем я мог помочь, тут уже прозвучало и неоднократно и не только от меня. Удачи ;)

 

Вы вообще читаете, что я пишу? Какая от вас может быть помощь, если вы помните только то что было написано на первой странице поста?

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


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

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

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

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

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

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

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

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

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

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