Top.Mail.Ru
Уведомления
Очистить все

[Закреплено] Баги STM32 / STM32CubeMx / HAL Driver и не только

Aveal
(@aveal)
Top level Admin

В этой теме будем делиться выявленными багами и проблемами STM32CubeMx и не только во избежание потери нервных клеток и появления седых волос при разработке и отладке.

По мере развития темы это уже не только и не столько баги/ошибки инструментов/библиотек, но в том числе и личный опыт по отладке тех или иных процессов. Что также будет полезно к прочтению 👍 

Цитата
Topic starter Размещено : 29.06.2021 11:23
Тэги темы
Aveal
(@aveal)
Top level Admin

Баг, который обнаружил Александр, переношу из комментариев:

Столкнулся с неприятной проблемой.

Монтирование SD карты не производится в проекте сформированом в STM32CubeMX v6.1.0. (фирмваре STM32Cube_FW_L4_V1.16.0) и при этом тот же код нормально отрабатывает если проект сформирован в STM32CubeMX v5.4.0 (фирмваре STM32Cube_FW_L4_V1.14.0). Так же не работает монтирование если проект целиком сделан в STM32CubeIDE 1.6.1 (фирмваре STM32Cube_FW_L4_V1.17.0). Смотрел под отладкой. Не отрабатывает как надо res = find_volume(&path, &fs, 0); которая вызывается из f_mount().

Еще более запутывает дело что в STM32CubeMX610 сгенерил на базе фирмваре STM32Cube_FW_L4_V1.14.0 и не работает. И наоборот в В STM32CubeMX540 сгенерил на базе фирмваре STM32Cube_FW_L4_V1.16.0 — монтирует успешно.

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

 

ОтветитьЦитата
Topic starter Размещено : 29.06.2021 11:35
Эдуард
(@eduard)
Level 3 Moderator

Глюки со схемотехникой, маппингом портов и I2C. Опишу с чем столкнулся при разработке на STM32F030C8x и STM32F030CCx (Далее F030x8 и F030xC соответственно). Если посмотреть даташит, раздел 8 Ordering information, чтобы узнать что означают буковки:

 

Работая с другими сериями МК, я привык к тому, что цифра 8 и буква С, всего лишь размер флеша в серии. Ну и зачем далее то смотреть? А зря. Начались мои мучения.

У меня был МК F030x8, а F303xC в это время шли из Китая. Ну я разработал плату, впаял МК и начал программировать.
- Запуск тактового генератора. Всё в порядке (это я так думал).
- Работа с портами ввода/вывода. Всё в порядке. Светодиоды моргают. Всё пищит.
- Запускаю SPI. Подключаю дисплей. Пишу всякий вывод на него. Всё в порядке. Пора заканчивать с баловством.
- Пишу протокол обмена по RS485. Всё в порядке. Пишу статью.
- Пора запускать I2C и датчики прицепленные к нему.

Всё приехали. I2C не работает. Хоть тресни. Начал разбираться. По схеме я развёл I2C на выводы PF0-PF1, так как в этом проекте кварца у меня нет. Оказалось, что у F030x8 туда I2C не заходит. Ладно. Фиг с тобой. Займусь чем-нибудь другим, пока чипы не пришли.

Приходят чипы F030xC. Запаиваю, чип не запускается. Не знаю что и делать. Закупил 15 штук. Потом думаю, а что это у меня трассировка странная? На 35-36 выводы должно подаваться питание, а его нет. Смотрю даташит и обнаруживаю:

Это F030x8

 

Это F030xC

А так как я не использую PF6-PF7 они висят в воздухе. Запаял перемычки, чип определился и прошился. Отлично. Не придётся спор открывать. Далее геморрой с I2C.

Подключаю датчики - заработали с полтыка. Пора подключать AT24C16, начались проблемы. Приводить их здесь не буду, описание и решение приведено в статье. А тип проблем с AT24C16 описан в комментарии к статье. На сегодня хватит глюков, далее нас ждут глюки RCC и USART. А так как проект ещё не закончен, думаю найду ещё много интересного.

ОтветитьЦитата
Размещено : 23.11.2022 19:08
Aveal
(@aveal)
Top level Admin

@eduard у меня последнее время один вопрос - "а баг то где"? 😀 В документации же распиновка указана верная для разных контроллеров?

ОтветитьЦитата
Topic starter Размещено : 24.11.2022 11:22
Эдуард
(@eduard)
Level 3 Moderator

@aveal Это не баг. Это фича 🤣 

Просто я не сталкивался с таким раньше.

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

 

ОтветитьЦитата
Размещено : 24.11.2022 18:43
Эдуард
(@eduard)
Level 3 Moderator

Ошибки в RM0360 RCC на МК F030x8 и F030xC.

И так, новый чип F030xC запаян и запущен.

Так ведь всегда есть НО. У меня есть библиотека для DS18B20. Сделана на ногодрыге. Подключено три датчика. На F030x8 они работали, а на F030xC работает один датчик, да и тот периодически отваливается. Отлично, подключаем логический анализатор, выбираем протокол "сеть 1-wire" и видим, что в протоколе сплошные ошибки. Но при этом один датчик дышит. С таким уже сталкивался - задержки не в порядке, а так как функция delayMicros() даёт некоторую погрешность, решил проверить её. Проверил. Мда, хорошая погрешность. Думаю, ну-ка её нафиг. Напишу 1-Wire на USART с DMA как правильный программист. Тут я с USART хапанул горя. Его я опишу в следующий раз, но я обратил внимание, что скорость ниже в два раза. Запустил USART под HAL (пока без DMA) - работает правильно. Начал смотреть инициализацию USART у меня и у HAL. Под HAL передача идёт нормально.

Почесал репу, а дай-ка я гляну RCC, опа, приехали. Тактовый генератор F030x8:

Тактовый генератор F030xC:

Ну ладненько, лезем в референс мануал и смотрим биты, отвечающие за источник предделителя. Сначала CFGR - PLLSRC в RM0360 для нашего МК:

Как так? А как же мне подключать тактовый генератор по второй картинке? Лезем в HAL, он инициализирует тактовый через такие биты:

Странно, дай под отладчиком посмотрю. Да, в регистр пишется 0x8000. И в svd файле он есть, но в референсе нет. Он есть только в Reference Manual RM0091 от другого кристалла этой же серии.

Из этого следует, что в RM0360 ошибка в описании регистров, и это не последняя, я и раньше встречал, но не документировал. Теперь придётся документировать, иначе можно об этом забыть и вновь наступить на грабли.

ОтветитьЦитата
Размещено : 24.11.2022 18:54
Эдуард
(@eduard)
Level 3 Moderator

Связка USART - DMA

Сразу предупреждаю, здесь речь идёт о STM32F030CCT и только о нём.

Я раньше говорил о попытке запустить 1-Wire для DS18B20 на USART6 в полудуплексе. Почитал, что да как, и приступил. Накидал функцию reset(), запускаю, работает. DMA в этом случае не используется.

Накидываю функцию передачи байта с использованием DMA - не работает. Начинаю разбираться... Пошагово проверяю, что происходит в регистрах. Глюк. USART6 работает но в RCC не могу найти где бит USART6EN, в документации есть, в отладчике нет. Лезу в svd-файл, этот бит отсутствует как класс - правлю svd-файл.

Иду дальше. Решил проверить DMA под HAL - не работает, может что то не так делаю, может на самом деле там ошибка.

Как говорят "линуксоиды", если всё сломалось, и ничего не работает, курите "мануалы". Читаю референс в плане работы USART с DMA. F030xC, в отличие от других, имеет дополнительный регистр, в котором прописывается, к какому каналу DMA подключен USART. В описании DMA он есть, лезу в "хидеры" stm32f030xc.h CMSIS и нахожу:

typedef struct
{
  __IO uint32_t ISR; /*!< DMA interrupt status register, Address offset: 0x00 */
  __IO uint32_t IFCR; /*!< DMA interrupt flag clear register, Address offset: 0x04 */
  uint32_t RESERVED0[40];/*!< Reserved as declared by channel typedef 0x08 - 0xA4 */
  __IO uint32_t CSELR; /*!< Channel selection register, Address offset: 0xA8 */
} DMA_TypeDef;

Регистр CSELR, который и отвечает за подключения каналов именно на этом чипе. Причём в svd-файле его нет, соответственно в отладчике этого регистра тоже не видно.

Ладно, мы не гордые, правим svd-файл и регистр в отладчике появился. Прописываю в него всё как надо и DMA на передачу начал работать, но на приём - нет. Прошло 3 дня, ничего не работает. Думаю, плевать на DMA.

Делаю на чистом USART, смотрю на логическом анализаторе:

Первый байт, ушла команда. Второй байт, ушла команда. Третий байт, устройство ответило. Причём логический анализатор декодирует сигналы и говорит, что всё в порядке. Но USART же не принимает. Потерял 2 дня...

Кадр из отладчика. Ушёл байт 0xFF, должен вернуться или 0xFF, или 0xFC. Но RDR пуст.

Решил отцепить DS18B20, и приём пошёл - что передаю, то и получаю, цепляю обратно датчик... Приёма нет, хотя логический анализатор рапортует, что на шине присутствует правильный сигнал и декодируется и как 1-Wire, и как USART.

Я так понял, что DMA на приём не работало из-за этого же. Самое интересное, когда посылаю сигнал Reset, всё отрабатывает правильно, сигнал уходит и возвращается правильный ответ. Но остальное работать не хочет.

Проблему так и не решил. То ли руки кривые, то ли ещё что-то не так, ушёл опять на ногодрыг. Позже буду писать прошивку на STM32F303CCT*, посмотрю как там будет. Смогу запустить 1-Wire на DMA+USART или опять на грабли наступлю.

ОтветитьЦитата
Размещено : 24.11.2022 18:57
Aveal
(@aveal)
Top level Admin
От: @eduard

@aveal Это не баг. Это фича 🤣 

Просто я не сталкивался с таким раньше.

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

 

🙂

ОтветитьЦитата
Topic starter Размещено : 24.11.2022 19:01
Эдуард
(@eduard)
Level 3 Moderator

Сегодня запускал RS485 на USART3 (чип F030CCx), не заработало. Потом вспомнил, был глюк, если I2C запустить раньше, чем любую другую периферию, ничего не будет работать кроме I2C.

Переставил инициализацию USART3 раньше, чем I2C - всё заработало. С чем это связано, так и не понял. Раньше этот глюк наблюдал, но не придал значения, подозреваю, что неудачная попытка запустить USART+DMA связана тоже с этим.

На данный момент в проекте используется SPI, USART3 и I2C. Если I2C инициализировать раньше, чем остальное, ничего работать не будет. Под отладчиком проверено не раз, I2C ничего криминального не делает.

Кроме этого столкнулся с альтернативными функциями.

#define GPIO_AF0_EVENTOUT     ((uint8_t)0x00U)  /*!< AF0: EVENTOUT Alternate Function mapping  */
#define GPIO_AF0_SWDIO        ((uint8_t)0x00U)  /*!< AF0: SWDIO Alternate Function mapping     */
#define GPIO_AF0_SWCLK        ((uint8_t)0x00U)  /*!< AF0: SWCLK Alternate Function mapping     */
#define GPIO_AF0_MCO          ((uint8_t)0x00U)  /*!< AF0: MCO Alternate Function mapping       */
#define GPIO_AF0_IR           ((uint8_t)0x00U)  /*!< AF0: IR Alternate Function mapping        */
#define GPIO_AF0_SPI1         ((uint8_t)0x00U)  /*!< AF0: SPI1 Alternate Function mapping      */
#define GPIO_AF0_SPI2         ((uint8_t)0x00U)  /*!< AF0: SPI2 Alternate Function mapping      */
#define GPIO_AF0_TIM3         ((uint8_t)0x00U)  /*!< AF0: TIM3 Alternate Function mapping      */
#define GPIO_AF0_TIM14        ((uint8_t)0x00U)  /*!< AF0: TIM14 Alternate Function mapping     */
#define GPIO_AF0_TIM15        ((uint8_t)0x00U)  /*!< AF0: TIM15 Alternate Function mapping     */
#define GPIO_AF0_TIM17        ((uint8_t)0x00U)  /*!< AF0: TIM17 Alternate Function mapping     */
#define GPIO_AF0_USART1       ((uint8_t)0x00U)  /*!< AF0: USART1 Alternate Function mapping    */
#define GPIO_AF0_USART4       ((uint8_t)0x00U)  /*!< AF0: USART4 Alternate Function mapping    */

/* AF 1 */
#define GPIO_AF1_TIM3         ((uint8_t)0x01U)  /*!< AF1: TIM3 Alternate Function mapping      */
#define GPIO_AF1_TIM15        ((uint8_t)0x01U)  /*!< AF1: TIM15 Alternate Function mapping     */
#define GPIO_AF1_USART1       ((uint8_t)0x01U)  /*!< AF1: USART1 Alternate Function mapping    */
#define GPIO_AF1_USART2       ((uint8_t)0x01U)  /*!< AF1: USART2 Alternate Function mapping    */
#define GPIO_AF1_USART3       ((uint8_t)0x01U)  /*!< AF1: USART3 Alternate Function mapping    */
#define GPIO_AF1_IR           ((uint8_t)0x01U)  /*!< AF1: IR Alternate Function mapping        */
#define GPIO_AF1_EVENTOUT     ((uint8_t)0x01U)  /*!< AF1: EVENTOUT Alternate Function mapping  */
#define GPIO_AF1_I2C1         ((uint8_t)0x01U)  /*!< AF1: I2C1 Alternate Function mapping      */
#define GPIO_AF1_I2C2         ((uint8_t)0x01U)  /*!< AF1: I2C2 Alternate Function mapping      */
#define GPIO_AF1_SPI2         ((uint8_t)0x01U)  /*!< AF1: SPI2 Alternate Function mapping      */

Это из HAL. USART1 имеет два описания, как AF0_USART1 и AF1_USART1. И что мне использовать на самом деле?

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

Прикол в том, что столько глюков я отловил только на одном МК, на других такого не было.

 

 

ОтветитьЦитата
Размещено : 25.11.2022 21:19
Поделиться: