Jump to content

    

Neo_Matrix

Участник
  • Content Count

    136
  • Joined

  • Last visited

Everything posted by Neo_Matrix


  1. В даташите сказано, что последовательное чтение регистров SR - > DR очищает флаг прерывания. У вас между этими чтениями происходит чтение регистра CR1 в условии if. Это точно правильно? Ст. 1009 допустим:
  2. Попробую, но как-то не уверен, что поможет, не может же быть, что какой-то флаг установлен, а дебагер его не отображает. С флагом ОРЕ должна быть другая обработка, текущий байт ведь в порядке, потерян следующий. Завтра сделаю скрины с дебагера, в случае зависания порта.
  3. До того, как выше посоветовали внести обработку ошибок, код был где-то таким: 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); } } } ......................................... }
  4. Да, я выше отписал, что внес изменения. Просто сейчас нет с собой последнего кода. По поводу обработки ошибок посмотрите, на скриншот. https://electronix.ru/forum/uploads/monthly_2019_05/image.png.9b928738676a71ba399fd46b3b49b619.png Там есть 2 варианта прерываний на ошибки(EIE, RXNEIE при этом флаг ORE может вызывать прерывание в обоих случаях). Один из них это выключить прерывание по приему и включить прерывания на ошибки, тогда подвиснем в прерывании навечно(до выставления флага RXNE так точно). Потому прерывания ошибок обрабатываю отдельно. Но это не суть. В случае зависания в отладчике эти флаги не выставлены, т.е. не выставлен не один из всех возможных флагов прерываний кроме LBD
  5. Ну и где же регистр SR читается не первым? Имеете ввиду CR1, CR3. Как же без их чтения узнать включено ли прерывание в данный момент по определенному событию? Кроме того DR там и читается только при условии, что RXNE установлен при включенном соответствующем прерывании, в других случаях он читается только для очистки флагов ошибок и об этом явным образом написано в даташите.
  6. DMA не использую, так как скорость 9600, максимальная посылка байтов 100 от силы, в основном по 5-10 байт, периодичность посылок 100мс а то и более. Как видите в ДМА нет резона. Вот обработчик прерывания, правда не последней версии. Но глючит в любом из них.(Немного отредактировал пост) 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 tmp_error = CLEAR; union { uint8_t data_8[2]; uint16_t data_16; } tmp_data = {0}; union { uint8_t *pdata_8; uint16_t *pdata_16; void *data_void; } tmp_pdata; uart_data = get_uart_port_data(uart_number); cr3_reg = read_reg(uart_data->uart_typedef, CR3); cr1_reg = read_reg(uart_data->uart_typedef, CR1); sr_reg = read_reg(uart_data->uart_typedef, SR); if((read_bit(cr1_reg, LL_USART_CR1_PEIE) != (CLEAR)) && \ (read_bit(sr_reg, LL_USART_SR_PE) != (CLEAR))) { tmp_error |= UART_ERROR_PE; } if(read_bit(cr3_reg, LL_USART_CR3_EIE) != (CLEAR)) { if(read_bit(sr_reg, USART_SR_ORE) != (CLEAR)) { tmp_error |= UART_ERROR_ORE; } if(read_bit(sr_reg, LL_USART_SR_FE) != (CLEAR)) { tmp_error |= UART_ERROR_FE; } if(read_bit(sr_reg, LL_USART_SR_NE) != (CLEAR)) { tmp_error |= UART_ERROR_NE; } } if((read_bit(cr1_reg, USART_CR1_RXNEIE) != (CLEAR))) { if(read_bit(sr_reg, USART_SR_ORE) != (CLEAR)) { tmp_error |= UART_ERROR_ORE; } if(read_bit(sr_reg, USART_SR_RXNE) != (CLEAR)) { if(read_bit(cr1_reg, USART_CR1_M) != (CLEAR)) { tmp_data.data_16 = (uint16_t)(read_bit_reg(uart_data->uart_typedef, DR, USART_DR_DR)); tmp_pdata.data_void = (void *)&tmp_data.data_16; } else { tmp_data.data_8[1] = (uint8_t)(read_bit_reg(uart_data->uart_typedef, DR, USART_DR_DR)); tmp_pdata.data_void = (void *)&tmp_data.data_8; } drv_rx_from_isr(uart_data->driver_data, tmp_pdata.data_void); } } if(tmp_error != CLEAR) { tmp_reg = read_reg(uart_data->uart_typedef, SR); (void)tmp_reg; tmp_reg = read_reg(uart_data->uart_typedef, DR); (void)tmp_reg; //tmp_data.data_8[0] |= tmp_error; drv_err_from_isr(uart_data->driver_data, tmp_error); } if((read_bit(cr1_reg, USART_CR1_TXEIE) != (CLEAR)) && \ (read_bit(sr_reg, USART_SR_TXE) != (CLEAR))) { tmp_pdata.data_void = uart_data->uart_tx_data; if(read_bit(cr1_reg, USART_CR1_M) != (CLEAR)) { write_reg(uart_data->uart_typedef, DR, (*tmp_pdata.pdata_16 & 0x01FFU)); if(--uart_data->uart_tx_data_len == 0U) { clear_bit_reg(uart_data->uart_typedef, CR1, USART_CR1_TXEIE); set_bit_reg(uart_data->uart_typedef, CR1, USART_CR1_TCIE); } else { tmp_pdata.pdata_16++; uart_data->uart_tx_data = tmp_pdata.data_void; } } else { write_reg(uart_data->uart_typedef, DR, (*tmp_pdata.pdata_8 & 0xFFU)); if(--uart_data->uart_tx_data_len == 0U) { clear_bit_reg(uart_data->uart_typedef, CR1, USART_CR1_TXEIE); set_bit_reg(uart_data->uart_typedef, CR1, USART_CR1_TCIE); } else { tmp_pdata.pdata_8++; uart_data->uart_tx_data = tmp_pdata.data_void; } } //return; } if((read_bit(cr1_reg, LL_USART_CR1_TCIE) != (CLEAR)) && \ (read_bit(sr_reg, LL_USART_SR_TC) != (CLEAR))) { clear_bit_reg(uart_data->uart_typedef, SR, USART_SR_TC); clear_bit_reg(uart_data->uart_typedef, CR1, USART_CR1_TCIE); drv_tx_from_isr(uart_data->driver_data); //return; } }
  7. Уезжал на праздники, потому долго не отвечал. Ну, LBD у меня при нормальном приеме данных не выставляется(если кабель не дергать на горячую), или я не замечал. FE точно не выставляется, прикрепил скриншот к сообщению, там написано, что этот флаг работает только в мультибуферном режиме . А что за флаг OVR, не нашел такого? Не смог найти нечего специального, ткните носом плиз.
  8. Не вижу повода для сарказма. Приведите пруфы удачного взлома этого камня(stm32f407).
  9. F4 серия пока не взломана, по крайней мере за разумные деньги, иначе выгодней сделать свое устройство, а не клонировать и тем более не для перехвата трафика.
  10. Добавил проверку ошибок UART по принципу проверили флаг -> напечатали принтом ошибку -> сбросили флаг. Несколько раз при горячем отключении ошибки проскакивали, но UART от их обработки виснуть не перестал.
  11. ORE - проверяю, на остальные прерывания отключены. В дебагере четко видно, что ни один из флагов(FE и т.д.) в момент зависания приема - не выставлен, кроме того, как объяснить продолжение нормальной работы после записи в регистр DR(чтение этого регистра проблему не убирает!)
  12. Просмотрел еррату, есть похожая ошибка, но она проявляет себя только при аппаратном контроле потока, который у меня выключен. В итоге непонятно.
  13. Столкнулся со странным поведение периферии UART4(на других не замечено), а точнее подвисанием. Итак имеется 2 устройства одно из них мое второе третьей стороны, оба устройства подключены по RS232. С моей стороны стоит процессор STM32F407 за ним MAX3232(питание от 3.3вольта) с сапрессорами с другой стороны находится такая же MAX3232 с сапрессорами далее уходит на проц(не смотрел какой). Так вот недалекий обслуживающий персонал частенько вынимает коннектор RS232 "на горячую", поскольку мое устройство питается от блока питания стороннего устройства земли(GND) у них в этот момент не разрываются, но конструкция разъема такова, что при попадании на металлический корпус коннектора RX, TX могут на него замкнуть(от этого защищают резисторы и сапрессоры). Теперь суть проблемы: В момент отключения кабеля посылка данных приходящих ко мне может быть принята не полностью, на что мой софт отвечает NACK(0x15), по непонятной мне причине в этот момент может выставится флаг LBD, который используется если настроить порт как LIN, но я не использую этот самый LIN и он не активен и прерываний от него нет, именно в такие моменты периферия подвисает. Если потом вернуть разъем на место, то прерывания RXNE, TXE более не срабатывают, а софт моей задачи вылетает по таймауту. В начале попробовал сбрасывать сам флаг LBD - флаг нормально сбрасывается но передача не возобновляется. Нашел 2 способа решить проблему костылем: 1) Сбросить ЮАРТ периферию и заново перенастроить. 2) При появлении флага LBD в регистре DR содержится(в случае зависания всегда) значение 0x0015(Мой ответ NACK). Если произвести запись в регистр любых данных все начинает снова работать, даже не нужно сбрасывать LBD. LBD - продолжаю сбрасывать для того что бы хоть как то отследить повторение зависания. Еще раз повторюсь функционал LIN Не используется мной, а отслеживание флага LBD сделано для работы костыля. Так же повторюсь, что прерывания после такой ситуации именно перестают срабатывать, а не ПО подвисает в прерывании. Использую следующую инициализацию порта: LL_USART_DisableRTSHWFlowCtrl(UART4); LL_USART_DisableCTSHWFlowCtrl(UART4); LL_USART_DisableLIN(UART4); LL_USART_DisableSCLKOutput(UART4); LL_USART_DisableSmartcard(UART4); LL_USART_DisableIrda(UART4); LL_USART_DisableHalfDuplex(UART4); LL_USART_SetTransferDirection(UART4, LL_USART_DIRECTION_TX_RX); LL_USART_SetParity(UART4, LL_USART_PARITY_NONE); LL_USART_SetDataWidth(UART4, LL_USART_DATAWIDTH_8B); LL_USART_SetStopBitsLength(UART4, LL_USART_STOPBITS_1); LL_USART_SetOverSampling(UART4, LL_USART_OVERSAMPLING_16); LL_USART_SetBaudRate(UART4, RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())), LL_USART_OVERSAMPLING_16, baudrate); LL_USART_Enable(UART4); LL_USART_EnableIT_RXNE(UART4); Может кто то сталкивался с такой ситуацией? Так как 2 вышеописанных метода решения это "костыли" чистой воды, прошу помочь проблему более правильно.
  14. Рекомендую прикрутить Percepio Tracealyzer и посмотреть все что происходит с ОСью, в частности будет видно кто что вызывает. Где-то на форуме проскакивала "не жадная" версия. И попробуйте функцию отправки изменить на: void USART_putc(int c) { char xC = (char) c; GPIO_set_HIGH(GPIO_LED); xQueueSendToBack(hal_USART.xTX, &xC, pdMS_TO_TICKS(1)); USART3->CR1 |= USART_CR1_TXEIE; GPIO_set_LOW(GPIO_LED); }
  15. На M4F с АРМ компилятором 6-версии нечего не ломается с включенным LTO. По правде абсолютно не вижу смысла в LTO, размер кода уменьшается на сущие копейки, а в скорости и вовсе нет прибавки.
  16. Апноуты весьма интересны особенно про керамические конденсаторы. Благодарю!
  17. Не вижу смысла удалять неиспользуемые функции, все что не используется нормально выпиливается встроенными макросами ОСи. Относительно атрибута used для LTO есть более правильное решение с точки зрения "красивости кода" оно описано в тикете под номером 90. А вот изменяя файлы порта есть большой шанс что то сломать. Если используется Кеил, у него многоие обработчики прерывания описаны в стартап файле, и если вы попадете в один из них отладчик не может показать где он сейчас находится(по крайней мере джетлинк). Допустим такой: BusFault_Handler\ PROC EXPORT BusFault_Handler [WEAK] B . ENDP ПС: Перед написанием комментария не обновил страницу.... Потому несколько устаревший
  18. Достаточно долго работаю с FreeRTOS и могу вас заверить, что критических ошибок приводящих к мертвым зависаниям в ней нет(с версии 8 точно). То, что после обновления ОС, ошибка пропала, скорее всего говорит о том, что ошибка была "скрыта", а не решена. Скорее всего при следующих правках кода ошибка снова проявит себя. Посмотрите в сторону прерываний hard_fault, bus_fault и им подобным(они включены в не зависимости от хотелок), предположу: при зависании вылетает в них. ПС: В "обновляторе прошивок" использую только очереди, даже при приеме данных с модема в прерывании(оверхед эпичный), но даже в таком режиме(а данных пересылается достаточно много) никогда нечего не висло. Кроме того внутри одной задачи используется парсер пришедших данных и они раскладываются по разным очередям а после этой же задачей вычитываются(не хотелось добавлять левые буферы) и даже такое издевательство не вешает контроллер.
  19. Спасибо за ответы! Она выпускается в нескольких вариантах с фиксированным напряжением и с настраиваемым. Конкретно LD29300P2MTR с настраиваемым, у остальных другие индексы. Модем должен быть включен постоянно, это часть ТЗ. Все остальное уже запитано от другого стабилизатора на NCP... Посмотрел даташиты на BISS транзисторы - они идеально подходят для данной задачи. Схему немного переделаю, так как ноги МК недоступны, можно сказать модуль модема внешний и имеет только линии RX, TX, GND, VCC(3.4 - 4.2 или 4.4). Еще раз спасибо за пинок в правильном направлении - BISS.
  20. Спасибо за содержательный пост, завтра просмотрю документацию по микросхемам. Проблем с покупкой LD29300 несколько. Поскольку изделия нам делают под ключ, два изготовителя написали о проблемах с их поставками. К сожалению e-find - это российский поисковик, а наши поставщики(изготовители) работают с Европой или Китаем. Эти микросхемы есть с фиксированным напряжением и подстраиваемым, с первыми проблем нет, со вторыми есть(Можете сами убедится посмотрев эту позицию на МАУСЕРе).
  21. А вот выдержка из даташита другого LDO. Всегда при выборе компонентов для производства более нескольких штук - стоит финансовая составляющая. Думаю, что никто в здравом уме не будет использовать дорогущие интегральные изоляторы в том месте где можно обойтись оптопарой. Думаю, что и резисторы высокой точности никто не поставит на подтяжку ЖПИО. Про сложность достать микросхемы я не преувеличивал, время поставки вплоть до 19ти недель. Собственно мой вопрос и был относительно опыта других, а не рекомендаций по выбору АКБ, как это было в первых постах. Данный вопрос(хотя контекст несколько другой "как 3мя AAA запитать СИМ800", но суть та же) уже подымался на других форумах, но ответ так еще никто и не предложил.
  22. LDO на основе ПТ часто уходят в возбуд особенно если нагрузка не стабильная. Эффект "нестабильности" можно наблюдать у LDO серии MIC29xxx при малом токе потребления эта серия выдает на выходе напряжение которое выше установленного с помощью пина ADJ. При небольшом увеличении тока все сразу приходит в норму.
  23. LDO очень не стабильны, потому хотелось проверенное решение, а не делать велосипед, а после ехать на нем по граблям.
  24. В общем, поскольку, обсуждение приходит к руслу: "у вас все неправильно" или "поменяйте АКБ" предлагаю для начала изучить: 1) Суть проблемы. 2) Применяемую микросхему заряда, ее скриншот прикреплен выше. 3) Модемный модуль отдельное устройство и в основную часть устройства вмешиватся никто не будет. Считаем что оно опломбировано. 4) Модемный модуль который применялся ранее имел более широкий диапазон напряжений, сейчас он снят с производства. На его замену был выбран СИМ800 и альтернатив по соотношению цена\качество сети\EAT у него попросту нет.