Jump to content

    

Neo_Matrix

Участник
  • Content Count

    99
  • Joined

  • Last visited

Community Reputation

0 Обычный

About Neo_Matrix

  • Rank
    Частый гость

Recent Profile Visitors

519 profile views
  1. Сама проблема была описана ранее(в первом посте). Переферийный модуль UART4 вис намертво пока не записать в DR любую инфу. На остальных юартах этой проблемы не наблюдалось. Как раз на старой партии этот костыль и нужен, на новой все хорошо, естественно бинарники шились одинаковые. Начиная с новой партии сменили поставщика компонентов и монтажную организацию, потому вполне вероятно, что ранее процы были с браком или списанный брак с завода привезли нам. При переброске проца между старой и новой партией глюк кочует вместе с процом.
  2. Лажа таки в МК была, добавил костыль в код, для "отвисания". Проверено на всей новой партии более 100шт, такого глюка нет.
  3. Я в курсе, что такое "индусский код". Просто стек популярный и достаточно навороченный, при своей нетребовательности к ресурсам(тут конечно все относительно). Причина проблемы полностью выяснена. Виной странная партия процов. Как и писал ранее в новой партии устройств данной проблемы нет, потому я просто перекинул процы между 2мя устройствами, глюк перекочевал на другую плату вместе с процом, старая же плата с новым процом заработала нормально. Ревизия процов везде "2". Внешне процессора имеют небольшое отличие, глючные имеют блестящие выводы(похоже на покрытие ПОС), новые имеют более коричневый оттенок выводов(возможно иммерсионное золото, но не уверен).
  4. С тактированием все нормально, уже проверял. Косвенно можно судить о нормальном тактировании по ЮСБ который достаточно критичен к частоте. Задежки чтения флеша тоже правильные. Буду надеяться, что проблема решена. Есть еще вероятность, что в прошлой партии неправильно смонтажили компоненты, допустим керамику вокруг проца. Но выпаивать все и проверять - пока не готов.
  5. Итак проблема решена. Решение оказалось весьма тривиальным, на новой партии устройств были установлены процессора с другой датой выпуска, этого прикола на них не наблюдается. Судя по всему бракованная партия, так как ревизия процессоров совпадает.
  6. В итоге упростил обработчик, написал его на голом доступе к регистрам, по рекомендациям выше. В итоге абсолютно нечего не изменилось. При этом, если тот же код использовать на USART2 - все отлично работает и "подвесить" периферию не получается. Вкрадываются подозрения, что это связано с разными модулями периферии APB2\APB1. ПС: А с чего вдруг lwip стал внезапно индусским?
  7. Я абсолютно не спорю. Но подобный подход использую не только я, пример: Так же подобный код можно встретить, кажется, в LWIP. При наличии неиспользуемых переменных.
  8. Вы меня не так поняли. Такой подход как у вас у меня тоже используется в драйвере i2c. Я пытался сказать, что не вижу других способов кроме как использовать указатель на структуру или просто номер. Для меня номер в данном случае был предпочтительнее. Но на самом деле изначальный вопрос несколько иной
  9. Как и в ответе выше, у всех подход свой и у всех он разный. Мне показалось, что ваша структура содержит слишком много данных, но для вас это в самый раз. Так что здесь каждому свое. Мне вспомнился подобный подход в портах под разные отладочные платы, которые пишет СТМ(не утверждаю что это плохо или хорошо).
  10. Нечего необычного в этом нет, это стандартный набор макросов из CMSIS, просто маленькими буквами. Неужели не видели? #define read_reg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) #define SET_BIT(REG, BIT) ((REG) |= (BIT)) #define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT)) #define READ_BIT(REG, BIT) ((REG) & (BIT)) #define CLEAR_REG(REG) ((REG) = (0x0)) #define WRITE_REG(REG, VAL) ((REG) = (VAL)) #define READ_REG(REG) ((REG)) А volatile перед tmp_reg нужен для того что бы оптимизатор не выкинул пустое чтение регистра, которое необходимо для очистки флагов, попробуйте без него и будете потом долго искать почему флаги не сбрасываются, так что меня терзают сомнения, что у вас код намного лучше моего. А вот эта конструкция (void)tmp_reg; необходима для того, что бы анализаторы кода не давали ложных варнингов, потому как переменная нигде не используется. Удается ли добиться многим зависание порта незнаю, возможно просто этому не придают значения. У меня все хорошо работало на многих точках(300+) с закрытыми коннекторами на протяжении почти 2х лет. проблемы возникли только после установки на новое оборудование с коннекторами, которые могут дотронутся своим RX TX до металлического корпуса устройства тем самым посадив линии в ноль. Корпус устройства заземлен и соединен с минусом питания. Здесь согласен на 100%, но тогда структура должна быть глобальной и видимой во всех файлах, которые ее используют. Так как она используется и в прерывании тоже. Мне наглядней использовать номер порта, как это сделано в стандартном PPP стеке LWIP. Это к сожалению уже личные предпочтения каждого и у всех фломастеры разные на вкус.
  11. А как переписать универсально под все порты, не применяя номера портов или указатели на структуры? Я выбрал номер и создал массив структур, в которых хранится доп инфа, допустим указатели на буферы РТОСа, а номер передается в качестве индекса массива. Я не нашел других простых подходов. Лично для меня код хорошо читаем, при компиляции с включенной оптимизацией собирается в достаточно компактный вид, другого мне не нужно. Функции на подобие read_bit() это обычные макросы, в которых описано, что и у вас в условии if.
  12. У меня есть юарты работающие только на прием и только на передачу(точнее такой был раньше).
  13. В даташите сказано, что последовательное чтение регистров SR - > DR очищает флаг прерывания. У вас между этими чтениями происходит чтение регистра CR1 в условии if. Это точно правильно? Ст. 1009 допустим:
  14. Попробую, но как-то не уверен, что поможет, не может же быть, что какой-то флаг установлен, а дебагер его не отображает. С флагом ОРЕ должна быть другая обработка, текущий байт ведь в порядке, потерян следующий. Завтра сделаю скрины с дебагера, в случае зависания порта.
  15. До того, как выше посоветовали внести обработку ошибок, код был где-то таким: void uart_irq_handler(uint32_t uart_number) { uart_data_t *uart_data; volatile uint32_t tmp_reg; uint32_t cr3_reg; uint32_t cr1_reg; uint32_t sr_reg; uint8_t data; uart_data = get_uart_port_data(uart_number); cr1_reg = read_reg(uart_data->uart_typedef, CR1); sr_reg = read_reg(uart_data->uart_typedef, SR); if((read_bit(cr1_reg, USART_CR1_RXNEIE) != (CLEAR))) { if(read_bit(sr_reg, USART_SR_ORE) != (CLEAR)) { tmp_reg = read_reg(uart_data->uart_typedef, SR); // Clear error (void)tmp_reg; tmp_reg = read_reg(uart_data->uart_typedef, DR); (void)tmp_reg; } else { if(read_bit(sr_reg, USART_SR_RXNE) != (CLEAR)) { // Save data data = (uint8_t)(read_bit_reg(uart_data->uart_typedef, DR, USART_DR_DR)); drv_rx_from_isr(uart_data->driver_data, tmp_pdata.data_void); } } } ......................................... }