Сергей Борщ 119 13 июля, 2020 Опубликовано 13 июля, 2020 · Жалоба 18 минут назад, jcxz сказал: А где-ж ещё её вставлять? Ну, по-хорошему надо не только вставить, но и со считанным что-то делать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 13 июля, 2020 Опубликовано 13 июля, 2020 · Жалоба 2 hours ago, jcxz said: А где-ж ещё её вставлять? Вроде в начале - это как бы само собой разумеется. "Не точный" - это мягко сказано. У меня на плате с али (STM32F103R8T6) частота HSI по дефолту == ~6.326 МГц. Прикол в том, что вставив команду чтения SR я, фактически, обеспечил считываяние его дважды: процедура bufio_IRQHandler(&FIFO); в результате вызывает что-то такое (см ниже), где и происходит " смысловое" считывание SR и анализ его битов. То есть, каким-то образом двойное считывание обеспечивает правильную работу, словно происходит синхронизация одного тактового домена с другим. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // // Reading DR // static uint16_t Read_RX(void) { uint16_t st = READ_BIT(STDIO_DEVICE->SR, USART_RX_FLAGS), dr = USART_GET_DR(STDIO_DEVICE); if (st) // any RX related flag { if (READ_BIT(st, USART_FLAG_FE) && dr == 0) // BREAK - prepare for DMX { bufio_PurgeRX(stdioFIFO()); } } return dr; } А уверены, что на плате стоит натуральный F103, а не китайский G... как его там? Вообще-то с RC я до сих пор проблем не имел, UARTы работают достаточно стабильно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 13 июля, 2020 Опубликовано 13 июля, 2020 · Жалоба 16 минут назад, KnightIgor сказал: То есть, каким-то образом двойное считывание обеспечивает правильную работу, словно происходит синхронизация одного тактового домена с другим. Двойное считывание в Вашем случае лишь прикрывает последствия бага, спрятанного где-то еще. С UART-ами там все четко Мой обработчик (скелет) для приема/передачи UARTISR() { u32 sr = PUART->SR; u32 cr = PUART->CR1; if(cr & sr & USART_SR_RXNE) { u8 b = PUART->DR; ... } if(cr & sr & USART_SR_TXE) { u8 b; ... PUART->DR = b; ... if(EndTx) DisTxIrqUART(); } } Никаких двойных считываний и все работает как положено. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 13 июля, 2020 Опубликовано 13 июля, 2020 · Жалоба 9 minutes ago, Arlleex said: Мой обработчик (скелет) для приема/передачи Простите, если не в тему: а почему вы циклически не проверяете флаги статуса. Ведь до выхода из прерывания может оказаться что что-то пришло, или есть что передавать... Просто я так делаю, что меньше выходов/входов из/в прерывание было... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 13 июля, 2020 Опубликовано 13 июля, 2020 · Жалоба 27 минут назад, haker_fox сказал: Простите, если не в тему: а почему вы циклически не проверяете флаги статуса. Ведь до выхода из прерывания может оказаться что что-то пришло, или есть что передавать... Просто я так делаю, что меньше выходов/входов из/в прерывание было... ИМХО, это не имеет большого смысла, особенно учитывая периодичность возникновения прерываний. Но стоит отметить, что я, бывает, циклически тоже обрабатываю - но это больше в случае, когда на периферии висит аппаратный FIFO. КМК, когда прерывания от периферии забивают бОльшую часть времени CPU, стоит подумать о разгрузке, например, тем же DMA. Да и в целом: ну зациклим мы проверку while(cr & sr & USART_SR_RXNE) { ... } якобы в надежде, что при большой плотности данных есть шанс снизить риск потери байта. Однако, когда мы зайдем в такой же цикл опроса TXE (ниже по коду) - в этот момент может сновать возникнуть RXNE. И мы уже не обработаем его в текущем ISR. Мы выйдем из него и зайдем снова. И где тогда выгода, если даже при циклической обработке можно терять байты? Потери в любом случае будут связаны с загрузкой CPU, скоростью приема и передачи байт и их взаимными соотношениями. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 13 июля, 2020 Опубликовано 13 июля, 2020 · Жалоба 58 минут назад, KnightIgor сказал: То есть, каким-то образом двойное считывание обеспечивает правильную работу 44 минуты назад, Arlleex сказал: Двойное считывание в Вашем случае лишь прикрывает последствия бага, спрятанного где-то еще. Согласен с Arlleex. 58 минут назад, KnightIgor сказал: А уверены, что на плате стоит натуральный F103, а не китайский G... как его там? Вообще-то с RC я до сих пор проблем не имел, UARTы работают достаточно стабильно. Не уверен. Скорее даже подозреваю. Поэтому писал сюда: https://electronix.ru/forum/index.php?app=forums&module=forums&controller=topic&id=157135&do=findComment&comment=1700231 Но периферия (UART, таймер, SPI и пр.) работают там нормально, проблемы только с предвыборкой и HSI. UART.SR у меня считывается только единожды как видно: extern "C" void concat(isrUART, nUART_serv)() { uint c, i0, i1, i2; HwRegsUART volatile *io = &concat(UART, nUART_serv); if ((i0 = io->SR) & (1 << UART_SR_NE | 1 << UART_SR_FE)) c = io->DR; else if (i0 & 1 << UART_SR_RXNE) { c = io->DR; if (i0 & (1 << UART_SR_PE | 1 << UART_SR_ORE)) return; i0 = rxw; if ((i1 = i0 + 1) >= sizeof(bufService.rx)) i1 = 0; if (i1 == (i2 = rxr)) return; bufService.rx[i0] = c; rxw = i1; if (i0 == i2) OsFlagSet(&rxNoEmpty); } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 13 июля, 2020 Опубликовано 13 июля, 2020 · Жалоба 59 minutes ago, Arlleex said: И где тогда выгода, если даже при циклической обработке можно терять байты Да, погорячился я немного. Почему-то на ум пришёл синхронный интерфейс типа SPI, где сколько передали, столько и приняли. 1 hour ago, Arlleex said: Но стоит отметить, что я, бывает, циклически тоже обрабатываю - но это больше в случае, когда на периферии висит аппаратный FIFO. Аналогично! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться