Chameleon 0 21 февраля, 2017 Опубликовано 21 февраля, 2017 · Жалоба Если человек вызывает такие функции (как в 5-м посте) из ISR ничтоже сумняшеся, то и в остальном коде он мог наделать очевидных глупостей. Например вызывать этот UARTPrint() из ISR и из фоновой задачи без блокировок. Переписывание этого под гал или чего-то другое ничего не даст. Если нет понимания как всё в сумме оно работает..... ЗЫ: теме место - в "помощи начинающему". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 18 21 февраля, 2017 Опубликовано 21 февраля, 2017 · Жалоба Про малоуловимые глюки в макросах и смысла нет говорить. А уж условная компиляция так помогает понять логику работы... Ну, судя по тому, как вы спотыкаетесь на примитивной функции и можно сказать на ровном месте, то действительно вам не стоит пользоваться ни препроцессором ни чем-то еще более функциональным :smile3046: Пожалуй, очень правильно, что вам кто-то строго настрого запретил пользоваться препроцессором, внушив, что, якобы, это злейшее зло.... Пусть уж лучше так Переписывание этого под гал или чего-то другое ничего не даст. Если нет понимания как всё в сумме оно работает..... ЗЫ: теме место - в "помощи начинающему". Трудно не согласиться :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Chameleon 0 22 февраля, 2017 Опубликовано 22 февраля, 2017 · Жалоба Чем дальше в лес, тем толще партизаны. Сделал отладочный вывод в массив в озу и затем из него в 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? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 18 22 февраля, 2017 Опубликовано 22 февраля, 2017 · Жалоба Правильно так: кидать байты строки в некую программную очередь и разрешать передачу, заранее настроив прерывания от USART. Так и делаю сейчас. Покажите код, где вы это делаете. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Chameleon 0 22 февраля, 2017 Опубликовано 22 февраля, 2017 · Жалоба Покажите код, где вы это делаете. 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"); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 18 22 февраля, 2017 Опубликовано 22 февраля, 2017 · Жалоба Я имел ввиду другое, гораздо более грамотное решение, связанное с обработчиком прерываний от USART, ну, да бог с ним, суть не в этом. Короче, этот код работает или виснет в некой up()? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Chameleon 0 22 февраля, 2017 Опубликовано 22 февраля, 2017 (изменено) · Жалоба Я имел ввиду другое, гораздо более грамотное решение, связанное с обработчиком прерываний от 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. Изменено 22 февраля, 2017 пользователем Chameleon Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 18 22 февраля, 2017 Опубликовано 22 февраля, 2017 · Жалоба Падает на этой функции: void up(void) { volatile char *s = mem; for(;;) { while((USART1->SR & USART_SR_TXE) == 0); USART1->DR = *s++; if (*s == 0) break; } } Мля, я не про эту несчастную кривую функцию, которая не предназначенная для использования в прерываниях в принципе! Я про тот набор текста, который приведен в посте #35. Оно работает как вам нужно или тоже типит? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Chameleon 0 22 февраля, 2017 Опубликовано 22 февраля, 2017 (изменено) · Жалоба Мля, я не про эту несчастную кривую функцию, которая не предназначенная для использования в прерываниях в принципе! Я про тот набор текста, который приведен в посте #35. Оно работает как вам нужно или тоже типит? Падает на up(). Изменено 22 февраля, 2017 пользователем Chameleon Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 5 22 февраля, 2017 Опубликовано 22 февраля, 2017 · Жалоба Дефайн __HAL_PCD_CLEAR_FLAG определен как GINTSTS &= 0x40000000; Но ведь для сброса флага прерывания в него надо записывать "1" ???? Т.е. делать так: GINTSTS |= 0x40000000; Вообще говоря, этот код работает. В это место вы попадаете с установленным 30-м битом; он ещё раз умножается на 30-й бит и записывается обратно. Вариант GINTSTS |= 0x40000000; неправильный, он лишние флажки поскидывает. Простой и понятный вариант GINTSTS = 0x40000000; но для индусов это слишком просто. По делу не помогу. Я это нагромождение дефайнов и абстракций не осилил. Заметно лучше, чем SPL, но для прикручивания своего протокола понадобилось бы переписать половину этой "библиотеки". Плюнул, взял libopencm3 - там тоже переписывать надо, но хотя бы структура прозрачная. Мля, я не про эту несчастную кривую функцию, которая не предназначенная для использования в прерываниях в принципе! У меня вопрос. Где граница, при превышении которой этот самый-лучший-в-мире стек упадёт нафиг? Убираем несчастную кривую функцию, добавляем два высокоприоритетных прерывания. Будет работать? Увеличиваем частоту прерываний на порядок. Будет работать? Стандартом заложено, что интерфейс может "подтормаживать". А библиотекописатели это не проверяли, у них в случае торможений всё вообще раком встаёт. Это проблема библиотеки, разве не так? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
uriy 5 22 февраля, 2017 Опубликовано 22 февраля, 2017 · Жалоба Вероятно надо использовать HAL_UART_Transmit_IT или HAL_UART_Transmit_DMA для передачи по прерываниям или по DMA. HAL_UART_Transmit передает по поллингу, эта функция блокирующая на все время передачи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 18 22 февраля, 2017 Опубликовано 22 февраля, 2017 · Жалоба 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: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Chameleon 0 22 февраля, 2017 Опубликовано 22 февраля, 2017 · Жалоба Вижу простое решение: отладить это чудо-код на ПУСТОМ проекте, добиться от него стабильной работы в разных ситуациях (банально тесты), и уже только после этого куда-то сувать. Спасибо, КЭП. Вы что, не понимаете, что это и есть ПУСТОЙ ПРОЕКТ. Только 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: Отличный совет - не получается? Как нибудь придумай обход. Прилепи костыль. Авось по другому прокатит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 18 22 февраля, 2017 Опубликовано 22 февраля, 2017 · Жалоба Спасибо, КЭП. Вы что, не понимаете, что это и есть ПУСТОЙ ПРОЕКТ. Только USB и UART. А что делает тут USB? Короче, ПУСТОЙ НОВЫЙ проект только для того, чтобы отладить ваши несчастные костыльные функции. Добейтесь тут от них нормальной работы в ПУСТОМ проекте. Поиграйтесь с размером стека (например). В конце концов, сделайте нормальный функционал БЕЗ поллинга! Что я и пытаюсь добиться стабильной работы в разных ситуациях? Да, да, передача строки по поллингу и есть СИТУАЦИЯ. И они должны работать вместе в любых комбинациях? Я не пойму, чего вы хотите добиться? Чтобы проект был сделан сразу нормально и без костылей или, просто, хотите что-то доказать себе или кому-то? Отличный совет - не получается? Как нибудь придумай обход. Прилепи костыль. Авось по другому прокатит. Костыль - это как раз ваша самодеятельная чудо-функция, использующая поллинг в прерывании. Я же говорю про готовое решение, которое отлажено за вас и отлично работает как раз с полпинка, благодаря наличию документации и тому, что это написано профессионалами, а не любителями-изобретателями. Если не хотите или не можете освоить готовые решения, так пользуйтесь и далее своими чудо-функциями, которая как вы говорите, "с полпинка работает на sam4s" и т. п. Короче, далее бейтесь о стену уже без моей помощи - все, чем я мог помочь, тут уже прозвучало и неоднократно и не только от меня. Удачи ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Chameleon 0 22 февраля, 2017 Опубликовано 22 февраля, 2017 · Жалоба А что делает тут USB? Короче, ПУСТОЙ НОВЫЙ проект только для того, чтобы отладить ваши несчастные костыльные функции. Добейтесь тут от них нормальной работы в ПУСТОМ проекте. Поиграйтесь с размером стека (например). В конце концов, сделайте нормальный функционал БЕЗ поллинга! Я не пойму, чего вы хотите добиться? Чтобы проект был сделан сразу нормально и без костылей или, просто, хотите что-то доказать себе или кому-то? Костыль - это как раз ваша самодеятельная чудо-функция, использующая поллинг в прерывании. Я же говорю про готовое решение, которое отлажено за вас и отлично работает как раз с полпинка, благодаря наличию документации и тому, что это написано профессионалами, а не любителями-изобретателями. Если не хотите или не можете освоить готовые решения, так пользуйтесь и далее своими чудо-функциями, которая как вы говорите, "с полпинка работает на sam4s" и т. п. Короче, далее бейтесь о стену уже без моей помощи - все, чем я мог помочь, тут уже прозвучало и неоднократно и не только от меня. Удачи ;) Вы вообще читаете, что я пишу? Какая от вас может быть помощь, если вы помните только то что было написано на первой странице поста? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться