adnega 11 13 октября, 2021 Опубликовано 13 октября, 2021 · Жалоба 1 час назад, jcxz сказал: Если IAR, то достаточно в таких местах приводить не к u64, а к __packed u64 - и всё наладится. Это gcc и структуры, помогает __attribute__((packed)), но в некачественном исходнике нужно искать все места с потенциальной проблемой. Сейчас включил UsageFault для невыровненных данных и ключем "-mno-unaligned-access" попросил компилятор не использовать фичу Cortex-M по работе с невыровнеными данными. Отключил сторожевой таймер. Гоняю - жду дампов от UsageFault. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 173 13 октября, 2021 Опубликовано 13 октября, 2021 · Жалоба 1 час назад, jcxz сказал: ...я обычно всегда ставил инструкцию DMB. Но на STM32 она не помогает почему-то в таких случаях... Тут дело в том, где архитектурно заложен так называемый буфер записи. CPU своими инструкциями барьеров может повлиять только на буфер записи, реализованный на его шинном интерфейсе. Если, например, буфер записи есть еще и на самих мостах AHB/APB - то все эти DSB/DMB бесполезны. Об этом вкратце можно глянуть тут. Несколько сложнее обстоят дела в Cortex-M7 с его AXI, который умеет переупорядочивать доступы и параллелить ожидающие передачи. Во где красота P.S. Кстати, их пример (что в приведенной мною ссылке) Цитата void Timer_IRQHandler (void) { PortD->PTOR |= 1<<0; /* Toggle output on port D0 */ Timer->MSR |= TIMER_MASK; /* Clear timer interrupt */ Timeout_counter++; /* Count timeout & insure IRQ clear */ } может не помочь, если Timeout_counter не volatile (но кем надо быть, чтобы так делать, я не знаю). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 13 октября, 2021 Опубликовано 13 октября, 2021 · Жалоба 41 минуту назад, adnega сказал: Сейчас включил UsageFault для невыровненных данных и ключем "-mno-unaligned-access" попросил компилятор не использовать фичу Cortex-M по работе с невыровнеными данными. Отключил сторожевой таймер. Гоняю - жду дампов от UsageFault. Так можно долго ждать и никогда не дождаться. Если оно происходит только при определённых условиях. Разумнее (имхо) - по листингу отыскивать все LDRD/STRD, LDM/STM, LDREX/STREX и т.п. и смотреть - возможен ли там невыровненный адрес или нет? Сложнее будет с PUSH/POP - ведь их будет дофига, глазами не просмотришь, и если накосячено и с указателями стека..... 12 минут назад, Arlleex сказал: Тут дело в том, где архитектурно заложен так называемый буфер записи. CPU своими инструкциями барьеров может повлиять только на буфер записи, реализованный на его шинном интерфейсе Я знаю про буфер записи. Именно поэтому и борюсь с ним обратным чтением. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 173 13 октября, 2021 Опубликовано 13 октября, 2021 · Жалоба 2 минуты назад, jcxz сказал: Я знаю про буфер записи. Именно поэтому и борюсь с ним обратным чтением. Не понятно только, почему STM-щики не могут указать в RM на свои контроллеры некоторые сведения system-level design, где и описали бы, мол так и так, тут есть буфер записи, будьте осторожны, не наступите на грабли. Нет же - все только опытным путем. Самому тоже приходилось наступать Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 13 октября, 2021 Опубликовано 13 октября, 2021 · Жалоба 21 минуту назад, jcxz сказал: Разумнее (имхо) - по листингу отыскивать все LDRD/STRD, LDM/STM, LDREX/STREX и т.п. и смотреть - возможен ли там невыровненный адрес или нет? Это не гарантирует, что при следующей сборке не появятся новые LDRD и компания. Проще в исходнике искать приведение к типу "(some_type *)". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 22 13 октября, 2021 Опубликовано 13 октября, 2021 · Жалоба 9 minutes ago, adnega said: Проще в исходнике искать приведение к типу "(some_type *)". Еще проще в исходника вообще избегать приведений типа в С-стиле В плюсовом стиле проще искать такие места в коде. Вот и вот про это. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 13 октября, 2021 Опубликовано 13 октября, 2021 · Жалоба 53 минуты назад, adnega сказал: Это не гарантирует, что при следующей сборке не появятся новые LDRD и компания. Проще в исходнике искать приведение к типу "(some_type *)". Какой-то странный у вас метод - вместо отыскания наличия определённых команд (приводящих к проблеме), сидеть и пытаться по исходнику угадать в каком месте они могут возникнуть и ещё и привести к проблеме. Примерно то же самое, что если б для определения достаточно ли горячие дома батареи отопления, вместо того чтобы просто их потрогать, бежать в котельную и смотреть сколько угля кочегары бросают в топку и угадывать температуру у себя в батарее. Предположу, что никогда не угадаете все возможные случаи возникновения LDRD/STRD/LDM/STM по исходнику. Да даже те, что можно угадать - и то по исходнику намного сложнее будет сделать, чем по листингу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 13 октября, 2021 Опубликовано 13 октября, 2021 · Жалоба 11 минут назад, jcxz сказал: Какой-то странный у вас метод Везде, где в исходнике есть приведение типов, если может получиться невыровненный доступ нужно ставить соответствующий атрибут структурам. Точнее, если выравнивание не гарантируется, то ставить packed. Дальше уже дело компилятора это правильно трактовать, и с этим проблем не замечено. В подавляющем большинстве случаев в данном исходнике к какой-то части пакета некого протокола осуществляется доступ через указатель на структуру. У всех этих структур просто нужно добавить packed. В другом наборе случаев данные организованы так, что они принципиально выровненные и тут править ничего не надо. Я отлавливаю какие-то промежуточные варианты: например, структура с настройками выровнена и сами настройки хранятся выровненными, но по протоколу могут прилететь настройки уже не выровненные в памяти. Как поступать в таких случаях? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 13 октября, 2021 Опубликовано 13 октября, 2021 · Жалоба 1 час назад, adnega сказал: Я отлавливаю какие-то промежуточные варианты: например, структура с настройками выровнена и сами настройки хранятся выровненными, но по протоколу могут прилететь настройки уже не выровненные в памяти. Как поступать в таких случаях? Ну так если к этим "настройкам прилетевшим по протоколу" обращение идёт через указатель на структуру, то эту структуру и сделать __packed. Сами же это сказали. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 13 октября, 2021 Опубликовано 13 октября, 2021 · Жалоба 5 минут назад, jcxz сказал: Ну так если к этим "настройкам прилетевшим по протоколу" обращение идёт через указатель на структуру, то эту структуру и сделать __packed. Сами же это сказали. По протоколу настройки прилетают крайне редко. А с самими настройками работа очень интенсивная. Если я тупо добавлю packed, то все многобайтные типы будут побайтово собираться - а мне так не надо (на самом деле для Cortex-M3 и выше можно сборки избежать в расчете на лишний такт при обращении к невыровненным данным). Я могу в протокол добавить фиктивных байтиков перед структурой настройки, чтобы они уже получались выровненными. Я могу для протокола выделить тип-близнец настроек, но с packed. Могу просто memcpy устроить или присвоение структуры. Вариантов много и не все так очевидно. Очевидно одно, что исходник плохой и его нужно править. Собственно, я весь этот разговор затеял в контексте того, что исходник нужно писать так, чтобы от уровня оптимизации, компилятора, слишком быстрого или медленного исполнения - результат не зависел и всегда был корректным. Кста, исходник мой, но 10-летней давности. Все это время биарник работал без нареканий в большом количестве изделий 24/7 и вообще считался отлаженным (светодиодные информационные остановочные табло). Собирал когда-то сборкой от klen. Сейчас пользуюсь ланчпадовской сборкой, lto и прочими плюшками - вот и повылезало при переносе на новое железо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 13 октября, 2021 Опубликовано 13 октября, 2021 · Жалоба 3 минуты назад, adnega сказал: По протоколу настройки прилетают крайне редко. А с самими настройками работа очень интенсивная. Если я тупо добавлю packed, то все многобайтные типы будут побайтово собираться С чего бы это? Какой компилятор так компилит??? IAR точно такой глупости не делает. Он знает что CPU умеет невыровненный доступ для LDR\STR\LDRH\STRH, поэтому применяет их и для обращений к __packed типам 16- и 32-разрядным. А уж сколько получится тактов при этом обращении - зависит от того как реально лежит: реально лежит ровно? -> значит и будет минимально возможное число тактов. 3 минуты назад, adnega сказал: Я могу в протокол добавить фиктивных байтиков перед структурой настройки, чтобы они уже получались выровненными. Я могу для протокола выделить тип-близнец настроек, но с packed. Могу просто memcpy устроить или присвоение структуры. Имхо - Вы всё излишне усложняете. __packed помогает избежать LDRD/STRD/LDM/STM/..., а больше ничего и не нужно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 13 октября, 2021 Опубликовано 13 октября, 2021 · Жалоба 13 минут назад, jcxz сказал: С чего бы это? Какой компилятор так компилит??? gcc с ключем "-mno-unaligned-access" (принуждает packed собирать побайтово). По-умолчанию, для Cortex-M3 он использует невыровненый доступ и для него использует ldr вместо побайтовой сборки. Но я ручками в МК включил исключение для невыровненого доступа, чтобы знать потенциально опасные места. Разумеется, начал спотыкаться на всех невыровненных данных, даже на содержащих атрибут packed. После этого добавил packed, где нужно, чтобы не словить там ldrd. После этого можно генерацию исключения отключать как и ключ "-mno-unaligned-access". 13 минут назад, jcxz сказал: Имхо - Вы всё излишне усложняете. __packed помогает избежать LDRD/STRD/LDM/STM/..., а больше ничего и не нужно. Согласен. Тут я больше из-за академического интереса переборщил. Столкнулся с этим первый раз и решил в дебри погрузиться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
a123-flex 0 5 ноября, 2021 Опубликовано 5 ноября, 2021 · Жалоба 15.06.2021 в 13:22, Vasily_ сказал: Потому что это Китай и сюрпризы вам точно гарантированны! Когда-то были клоны пиков, тоже были гораздо дешевле оригинала, и один мой знакомый применил это чудо для работы с монетоприемником, думаю дальше сами догадаетесь что они поимели. Ух. Оптимист большой этот Ваш знакомый Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 26 сентября, 2022 Опубликовано 26 сентября, 2022 · Жалоба В 07.10.2021 в 14:15, Сергей Борщ сказал: У меня прошивка для STM32F100 завелась на GD32F103 вся кроме записи в option bytes - потребовался __DSB() между записью ключа в FLASH->OPTKEYR и проверкой OPTWRE в FLASH->CR. В проекте используются USART1, USART2, USART3, DMA, SPI2, TIM2, TIM4, АЦП. Потребовалось штучно повторить старое изделие на STM32F407. В проекте используются эзернет, USB_FS в режиме device, I2C, АЦП, таймера. Эзернет заработал сразу. В I2C в одной из веток алгоритма не сбрасывался аналог бита I2C_SR1.ADDR. По описанию он сбрасывается чтением I2C_SR2 после чтения I2C_SR1. Я после чтения SR1 в этой ветке алгоритма перед чтением SR2 читал-писал CR1 и CR2. Вроде бы не запрещается и на STM32 работало. На GD32 потребовалось перед чтением SR2 добавить принудительное чтение SR1. В USB не удалось добиться установки аналога бита OTG_FS_GINTSTS.SRQINT при втыкании кабеля USB. Он должен выставляться и вызывать прерывание когда напряжение на VBUS достигает допустимого значения. Причем аналог бита USB_FS_GOTGCTL.BSVLD выставляется. Пока обошелся опросом VBUS в режиме цифрового входа и вызовом соответствующего обработчика прерывания вручную. А в АЦП не оказалось функциональности Injected sample. Просто нет этих битов в описании, а по факту после установки JSWSTART взводится JSTRT, а вот JEOC уже нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 173 26 сентября, 2022 Опубликовано 26 сентября, 2022 · Жалоба 2 часа назад, Сергей Борщ сказал: Просто нет этих битов в описании, а по факту после установки JSWSTART взводится JSTRT, а вот JEOC уже нет. Вот это печально Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться