firstvald 24 23 августа Опубликовано 23 августа · Жалоба 2 hours ago, EdgeAligned said: А, да, это от настроек компилятора зависит. Стандарт не задает однозначности. В принципе, переопределения uint32_t для того и придуманы, чтобы была однозначность. Ладно, но static тогда зачем? Да и сама переменная тоже как бы не нужна. В принципе, я вот сколько не пытался понять этот код, всё время путался в закомменченных строках. Ну и я как бы не понимаю назначение этой функции, названной modbus_usart_5(). Вообще, осмысленные названия функций для того и придуманы, чтобы отражать назначение и выполняемые действия. Небрежность в оформлении и форматировании кода затрудняет его просмотр и отладку. а вот это серьезно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Sergey_Aleksandrovi4 2 23 августа Опубликовано 23 августа · Жалоба On 8/21/2024 at 11:42 PM, firstvald said: Продолжаем разговор. Опять всплыла бяка с hard fault. //функция работающая в прерывани от последовательного порта void modbus_usart_5(void) { static unsigned char rx_flag=0; static unsigned char tx_flag=0; // static short unsigned int rx_reg; static long unsigned int usart_sr_my=0; static long unsigned int usart_rdr_my=0; rx_flag=0; tx_flag=0; if((UART5->ISR & USART_ISR_PE) != 0){//по ошибке паритета UART5->ICR |= USART_ICR_PECF; } if((UART5->ISR & USART_ISR_FE) != 0){//по ошибке кадрирования UART5->ICR |= USART_ICR_FECF; } if((UART5->ISR & USART_ISR_NE) != 0){//по шуму в посылке UART5->ICR |= USART_ICR_NCF; } if((UART5->ISR & USART_ISR_ORE) != 0){//принятые данные не успели прочитать UART5->ICR |= USART_ICR_ORECF; } if((UART5->ISR & USART_ISR_IDLE) != 0){//на линии долго ничего нет //выставляется при обычном обмене UART5->ICR |= USART_ICR_IDLECF; } if((UART5->ISR & USART_ISR_LBDF) != 0){//на линии длинный логический ноль UART5->ICR |= USART_ICR_LBDCF ; } if((UART5->ISR & USART_ISR_RTOF) != 0){//тайм аут по приему UART5->ICR |= USART_ICR_RTOCF ; } if((UART5->ISR & USART_ISR_EOBF) != 0){//конец блока - при работе со смарт картами //выставляется при обычном обмене UART5->ICR |= USART_ICR_EOBCF ; } if((UART5->ISR & USART_ISR_BUSY) != 0){// идет прием байта - флаг выставляется и сбрасывается аппаратно //UART5->ICR = USART_ICR_EOBCF ; __NOP();// } if((UART5->ISR & USART_ISR_CTSIF) != 0){// CTS interrupt flag - флаг выставляется и сбрасывается аппаратно UART5->ICR |= USART_ICR_CTSCF ; __NOP();// } if((UART5->ISR & USART_ISR_CTS) != 0){// CTS flag - флаг выставляется и сбрасывается аппаратно //UART5->ICR = USART_ICR_EOBCF ; __NOP();// } if((UART5->ISR & USART_ISR_ABRE) != 0){// Auto-Baud Rate Error - флаг выставляется и сбрасывается аппаратно UART5->CR3 |= USART_RQR_ABRRQ ; __NOP();// } if((UART5->ISR & USART_ISR_CMF) != 0){// Character Match Flag - флаг выставляется аппаратно UART5->ICR |= USART_ICR_CMCF ; //выставляется при обычном обмене __NOP();// } if((UART5->ISR & USART_ISR_SBKF) != 0){// Send Break Flag - флаг выставляется программно и сбрасывается аппаратно //UART5->ICR = USART_ICR_EOBCF ; __NOP();// } if((UART5->ISR & USART_ISR_RWU) != 0){// Receive Wake Up from mute mode Flag - флаг выставляется и сбрасывается аппаратно //UART5->ICR = USART_ICR_EOBCF ; //выставляется при обычном обмене __NOP();// } if((UART5->ISR & USART_ISR_WUF) != 0){// Wake Up from stop mode Flag - флаг выставляется аппаратно UART5->ICR |= USART_ICR_WUCF ; //выставляется при обычном обмене __NOP();// } if((UART5->ISR & USART_ISR_TEACK) != 0){// Transmit Enable Acknowledge Flag - флаг выставляется и сбрасывается аппаратно //UART5->ICR = USART_ICR_EOBCF ; //выставляется при обычном обмене __NOP();// } if((UART5->ISR & USART_ISR_REACK) != 0){// Receive Enable Acknowledge Flag - флаг выставляется и сбрасывается аппаратно //UART5->ICR = USART_ICR_EOBCF ; __NOP();// } usart_sr_my = UART5->ISR; usart_rdr_my = UART5->RDR;//прочитали байт и при этом //должен был сбросится флаг прерывания RXNE if((usart_sr_my & USART_ISR_TXE) != 0){//по передаче //данные передались в сдвиговый регистр //UART5->ISR &= ~USART_SR_TC; // UART5->ICR |= USART_ICR_TCCF ;//сбросим флаг UART5->RQR |= USART_RQR_TXFRQ ;//сбросим USART_SR_TXE // tx_flag=1; __nop(); } if((usart_sr_my & USART_ISR_TC) != 0){//по передаче //данные передались из сдвигового регистра //UART5->ISR &= ~USART_SR_TC; UART5->ICR |= USART_ICR_TCCF ;//сбросим флаг // UART5->RQR |= USART_RQR_TXFRQ ;//сбросим USART_SR_TXE tx_flag=1; } if((usart_sr_my & USART_ISR_RXNE) != 0){//по приему rx_flag=1; //UART5->SR &= ~USART_SR_RXNE; UART5->RQR |= USART_RQR_RXFRQ;//**сбросим флаг RXNE явно //rx_reg = UART5->RDR;//прочитали байт //rx_reg = (UART5->DR);//прочитали байт } if(tx_flag==1){//по передаче tx_flag=0; ... }//по передаче if(rx_flag==1){//по приему rx_flag=0; ... }//по приему // заремарим сброс - вдруг какое то прерывание возникает повторно UART5->ICR = 0xFFFF;//сбросим все флаги UART5->ICR |= USART_ICR_PECF; UART5->ICR |= USART_ICR_FECF; UART5->ICR |= USART_ICR_NCF; UART5->ICR |= USART_ICR_ORECF; UART5->ICR |= USART_ICR_IDLECF; UART5->ICR |= USART_ICR_LBDCF ; UART5->ICR |= USART_ICR_RTOCF ; } @firstvald 1. Покажите код внутри тела условного оператора if(rx_flag==1) скрытое под многоточием 2. Проверьте логическим анализатором/осциллографом частоту вызова функции modbus_usart_5() во время сбоя перед сваливанием в hardfault PS Это не мой код, я причесал портянку firstvald выложенную на 6 странице топика. Не задавайте мне вопросов по поводу этого ужаса) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 45 24 августа Опубликовано 24 августа · Жалоба 9 hours ago, Sergey_Aleksandrovi4 said: void modbus_usart_5(void) { И так для _каждого_ UART? ППЦ. Передавать указатель на структуру USART_TypeDef не пробовали? 9 hours ago, Sergey_Aleksandrovi4 said: static unsigned char rx_flag=0; static unsigned char tx_flag=0; Это зачем так, static? Вы обожаете стрелять себе по ногам? 9 hours ago, Sergey_Aleksandrovi4 said: usart_sr_my = UART5->ISR; Так это копия SR или ISR? С такой кашей в голове вы далеко не уедите. По UART и Модбас была хорошая статья на Хабре, плюс на форумах всё жёвано-пережёвано. В вашем МК немного другой UART, кастрированный, поэтому придётся принимать не по RTO, а по IDLE, а так всё однотипно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 86 24 августа Опубликовано 24 августа · Жалоба Где логика, где логика... И этот господин еще утверждает, что оператор switch, по его мнению, говнокод. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
firstvald 24 26 августа Опубликовано 26 августа · Жалоба On 8/23/2024 at 11:55 PM, Sergey_Aleksandrovi4 said: //функция работающая в прерывани от последовательного порта void modbus_usart_5(void) { static unsigned char rx_flag=0; static unsigned char tx_flag=0; // static short unsigned int rx_reg; static long unsigned int usart_sr_my=0; static long unsigned int usart_rdr_my=0; rx_flag=0; tx_flag=0; if((UART5->ISR & USART_ISR_PE) != 0){//по ошибке паритета UART5->ICR |= USART_ICR_PECF; } if((UART5->ISR & USART_ISR_FE) != 0){//по ошибке кадрирования UART5->ICR |= USART_ICR_FECF; } if((UART5->ISR & USART_ISR_NE) != 0){//по шуму в посылке UART5->ICR |= USART_ICR_NCF; } if((UART5->ISR & USART_ISR_ORE) != 0){//принятые данные не успели прочитать UART5->ICR |= USART_ICR_ORECF; } if((UART5->ISR & USART_ISR_IDLE) != 0){//на линии долго ничего нет //выставляется при обычном обмене UART5->ICR |= USART_ICR_IDLECF; } if((UART5->ISR & USART_ISR_LBDF) != 0){//на линии длинный логический ноль UART5->ICR |= USART_ICR_LBDCF ; } if((UART5->ISR & USART_ISR_RTOF) != 0){//тайм аут по приему UART5->ICR |= USART_ICR_RTOCF ; } if((UART5->ISR & USART_ISR_EOBF) != 0){//конец блока - при работе со смарт картами //выставляется при обычном обмене UART5->ICR |= USART_ICR_EOBCF ; } if((UART5->ISR & USART_ISR_BUSY) != 0){// идет прием байта - флаг выставляется и сбрасывается аппаратно //UART5->ICR = USART_ICR_EOBCF ; __NOP();// } if((UART5->ISR & USART_ISR_CTSIF) != 0){// CTS interrupt flag - флаг выставляется и сбрасывается аппаратно UART5->ICR |= USART_ICR_CTSCF ; __NOP();// } if((UART5->ISR & USART_ISR_CTS) != 0){// CTS flag - флаг выставляется и сбрасывается аппаратно //UART5->ICR = USART_ICR_EOBCF ; __NOP();// } if((UART5->ISR & USART_ISR_ABRE) != 0){// Auto-Baud Rate Error - флаг выставляется и сбрасывается аппаратно UART5->CR3 |= USART_RQR_ABRRQ ; __NOP();// } if((UART5->ISR & USART_ISR_CMF) != 0){// Character Match Flag - флаг выставляется аппаратно UART5->ICR |= USART_ICR_CMCF ; //выставляется при обычном обмене __NOP();// } if((UART5->ISR & USART_ISR_SBKF) != 0){// Send Break Flag - флаг выставляется программно и сбрасывается аппаратно //UART5->ICR = USART_ICR_EOBCF ; __NOP();// } if((UART5->ISR & USART_ISR_RWU) != 0){// Receive Wake Up from mute mode Flag - флаг выставляется и сбрасывается аппаратно //UART5->ICR = USART_ICR_EOBCF ; //выставляется при обычном обмене __NOP();// } if((UART5->ISR & USART_ISR_WUF) != 0){// Wake Up from stop mode Flag - флаг выставляется аппаратно UART5->ICR |= USART_ICR_WUCF ; //выставляется при обычном обмене __NOP();// } if((UART5->ISR & USART_ISR_TEACK) != 0){// Transmit Enable Acknowledge Flag - флаг выставляется и сбрасывается аппаратно //UART5->ICR = USART_ICR_EOBCF ; //выставляется при обычном обмене __NOP();// } if((UART5->ISR & USART_ISR_REACK) != 0){// Receive Enable Acknowledge Flag - флаг выставляется и сбрасывается аппаратно //UART5->ICR = USART_ICR_EOBCF ; __NOP();// } usart_sr_my = UART5->ISR; usart_rdr_my = UART5->RDR;//прочитали байт и при этом //должен был сбросится флаг прерывания RXNE if((usart_sr_my & USART_ISR_TXE) != 0){//по передаче //данные передались в сдвиговый регистр //UART5->ISR &= ~USART_SR_TC; // UART5->ICR |= USART_ICR_TCCF ;//сбросим флаг UART5->RQR |= USART_RQR_TXFRQ ;//сбросим USART_SR_TXE // tx_flag=1; __nop(); } if((usart_sr_my & USART_ISR_TC) != 0){//по передаче //данные передались из сдвигового регистра //UART5->ISR &= ~USART_SR_TC; UART5->ICR |= USART_ICR_TCCF ;//сбросим флаг // UART5->RQR |= USART_RQR_TXFRQ ;//сбросим USART_SR_TXE tx_flag=1; } if((usart_sr_my & USART_ISR_RXNE) != 0){//по приему rx_flag=1; //UART5->SR &= ~USART_SR_RXNE; UART5->RQR |= USART_RQR_RXFRQ;//**сбросим флаг RXNE явно //rx_reg = UART5->RDR;//прочитали байт //rx_reg = (UART5->DR);//прочитали байт } if(tx_flag==1){//по передаче tx_flag=0; ... }//по передаче if(rx_flag==1){//по приему rx_flag=0; ... }//по приему // заремарим сброс - вдруг какое то прерывание возникает повторно UART5->ICR = 0xFFFF;//сбросим все флаги UART5->ICR |= USART_ICR_PECF; UART5->ICR |= USART_ICR_FECF; UART5->ICR |= USART_ICR_NCF; UART5->ICR |= USART_ICR_ORECF; UART5->ICR |= USART_ICR_IDLECF; UART5->ICR |= USART_ICR_LBDCF ; UART5->ICR |= USART_ICR_RTOCF ; } @firstvald 1. Покажите код внутри тела условного оператора if(rx_flag==1) скрытое под многоточием 2. Проверьте логическим анализатором/осциллографом частоту вызова функции modbus_usart_5() во время сбоя перед сваливанием в hardfault PS Это не мой код, я причесал портянку firstvald выложенную на 6 странице топика. Не задавайте мне вопросов по поводу этого ужаса) там дальше в обработчике принятого при шуме в линии в рассчете контрольной суммы выезжал массив. но! это происходит ровно при шуме или если идет обращение на скорости через две на третью от настроенной. абсолютно четко соблюдается. это сильно указывало на что то в уарте. но оказывается может быть вот так. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 86 26 августа Опубликовано 26 августа · Жалоба А зачем вообще менять скорость во время коммуникации? Скорость передатчика и приемника в этом случае может быть несогласованной. При смене скорости обычно передается последовательность автодетектирования скорости. У вас же вообще не реализован НИ ОДИН обработчик флагов - нет ни обработки ошибки фрейма, ни обнаружения Idle, ни чего, акромя тупо принятого байта. Мануал то читали хоть краем глаза? Написана какая-то ерунда, почему-то написаны проверки флагов, которые в текущем режиме работы вообще никогда не выставляются. Некоторые флаги просто NOP-нуты, а самые нужные флаги просто забыты. Перепутано все что только можно. Микроконтроллер то хоть какой? Что-то уровня H7хх чтоль? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 26 августа Опубликовано 26 августа · Жалоба 58 минут назад, EdgeAligned сказал: У вас же вообще не реализован НИ ОДИН обработчик флагов - нет ни обработки ошибки фрейма, ни обнаружения Idle, ни чего, акромя тупо принятого байта. Мануал то читали хоть краем глаза? Там и обработки флагов-то по факту нет никакой. Одни баги. 58 минут назад, EdgeAligned сказал: Микроконтроллер то хоть какой? Что-то уровня H7хх чтоль? Я так понял - что-то из L-серии STM. Хотя - раз автор не указал какой именно - мы имеем полное право подразумевать любой. PS: А вообще - за вопросы по конкретным МК, без точного указания - о каком конкретно МК идёт речь - давно пора минусовать по полной. Так как в таком случае это скорее не технический вопрос, а попытка разжигания флейма. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 86 26 августа Опубликовано 26 августа · Жалоба Мне что кажется, что это H743/H750, потому что UART5 представлен в виде UART, а не USART. Впрочем, глядя на все это, поднимается рука к лицу в очередной раз - автор кода просто вообще не понимает ни-че-го и даже не пытается понять Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 86 28 августа Опубликовано 28 августа · Жалоба Цитата if((usart_sr_my & USART_ISR_TXE) != 0){//по передаче Ключевой ошибкой в этой записи является то, что вообще-то флаг TXE установлен всегда, за исключением одного случая. А теперь представим, что в прерывание USART попадаем например по флагу RXNE. И когда доходим до проверки флага TXE, а он оказывается установлен (передача не выполняется), то будет выполняться код внутри показанного if(), то есть, будет записан регистр TDR байтом для передачи. Отсюда - ложный запуск передачи в момент чтения принятого байта. И получаем вот такую картину: Казалось бы, мы запретили прерывание от TXE, оставив только RXNE, но передача запускается после каждого принятого байта (здесь в схеме TX соединен с RX перемычкой). Но стоит только добавить одно маленькое дополнительное условие в проверку if, как тут же все встает на свои места. Всё, что написано в том коде дальше - плод слепого тыкания наугад. UART5->RQR |= USART_RQR_TXFRQ ;//сбросим USART_SR_TXE вообще не имеет отношения к рассматриваемому случаю, поскольку работает либо в смарткард-режиме, либо с FIFO, и не сбрасывает TXE, а наоборот устанавливает его. Тут можно сказать только одно - RTFM, то есть, "рид зе факинь мануал". Я не знаю, как это всё там работало (как утверждает автор), видимо, на честном слове по чистой случайности. В общем, того, кто писал тот текст, следует отстегать розгами на полном серьезе. Ошибки - буквально в каждой строчке, без преувеличения. Я уже не говорю о том, что специфические тайминги и завершающие символы модбаса в этом УАРТе могут обрабатываться аппаратно. А при смене скорости коммуникации приемник должен включить режим автодетектирования скорости, а передатчик должен передать синхронизирующую посылку. Например, несколько раз 0x55. При этом в приемнике автоматически заносится в BRR вычисленное значение скорости. Но я не встречал случаев, чтобы во время сеанса обмена скорость УАРТа неожиданно менялась. Во избежание конфликтов всё подключенное к линии оборудование должно работать на одной и той же скорости. Тем более, адресный модбас. Флаги, которые не могут устанавливаться в текущем режиме работы, опрашивать НЕ нужно. То есть, флаги, относящиеся к смарткард-режиму, они не могут быть установлены в режиме базового UART. А вот флаги ошибок не следует "NOP-ать" и сбрасывать, они ж как раз и предназначены для обнаружения событий, а не просто для того, чтоб были. Кароч, RTFM (реад тхе фукинг мануал). И надавать по рукам тому, кто писал ту портянку. Совершенно безграмотно, ни одной правильной строчки, ни одной! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 60 28 августа Опубликовано 28 августа · Жалоба 5 minutes ago, EdgeAligned said: Ключевой ошибкой в этой записи является то, что Нужно проверять вместе с флагом разрешения прерывания по TXE и фатальной ошибки не будет. А можно взять текст от HAL и изучить с карандашом (это всё для ТС) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 86 28 августа Опубликовано 28 августа · Жалоба 7 минут назад, x893 сказал: вместе с флагом разрешения прерывания по TXE что я выше, соппсна и написал /*в закомментированном тексте*/. Я просто хотел показать, к чему реально приводит пренебрежение такой проверкой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 60 28 августа Опубликовано 28 августа · Жалоба 26 minutes ago, EdgeAligned said: что я выше, соппсна и написал /*в закомментированном тексте*/. Я просто хотел показать, к чему реально приводит пренебрежение такой проверкой. Полностью согласен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 190 28 августа Опубликовано 28 августа · Жалоба 1 час назад, EdgeAligned сказал: что я выше, соппсна и написал /*в закомментированном тексте*/. Я просто хотел показать, к чему реально приводит пренебрежение такой проверкой. Просто однажды что-то кое-какерски работающее перетаскивается из проекта в проект. Вот потом и вылезает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 28 августа Опубликовано 28 августа · Жалоба 44 минуты назад, Arlleex сказал: Просто однажды что-то кое-какерски работающее перетаскивается из проекта в проект. Вот потом и вылезает. Там, судя по тексту - плод "труда" коллектива авторов. И коллектив этот работал в том же стиле, что известные персонажи при написании письма из Простоквашино: "То лапы ломит, то хвост отваливается…" Каждый добавлял в меру своих способностей.... А ведь коллектив этот вполне может работать под соусом какого-нить нац.проекта. А потом и падают, сляпанные такими коллективами, "Луны-25" и "Фобос-в-грунты".... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 190 28 августа Опубликовано 28 августа · Жалоба 2 минуты назад, jcxz сказал: Там, судя по тексту - плод "труда" коллектива авторов. И коллектив этот работал в том же стиле, что известные персонажи при написании письма из Простоквашино: "То лапы ломит, то хвост отваливается…" Каждый добавлял в меру своих способностей.... Лично я доставшийся "проблемный" проект под МК сразу начинаю заново, если он объективно простой. Но, к сожалению, зачастую в таких случаях проблем набирается с другой стороны - с аппаратной: то ШИМ выведен на обычный пин, то SPI ногодрыгом завели, то еще чего-нибудь. Емкие по объему кода проекты стараюсь допиливать как есть. Некоторые модули просто переписываю, не ломая код основной логики. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться