реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> STM32 Прерывание UART, Странное поведение
Vladimir Prokofi...
сообщение Feb 20 2014, 10:37
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 47
Регистрация: 9-03-11
Пользователь №: 63 481



Простой модуль чтения данных с GPS, из проекта выкинул все, кроме uart драйвера и парсера сообщений UBX. (Ublox gps protocol), STM415 стоит, но софт везде работает с ним как с 215 ( Это не влияет, я это ловил и на настоящих 215 )

Настройка порта:
CODE
case USART6_BASE:

#ifdef USE_IN_UART6_BUFFER
UART6_InputBufWR = 0;
UART6_InputBufRD = 0;
#endif

#ifdef USE_OUT_UART6_BUFFER
UART6_OutputBufWR = 0;
UART6_OutputBufRD = 0;
#endif

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE);

GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_USART6);

GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_6;
GPIO_Init_Struct.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init_Struct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init_Struct.GPIO_OType = GPIO_OType_PP;
GPIO_Init_Struct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_Init_Struct);

GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_7;
GPIO_Init_Struct.GPIO_OType = GPIO_OType_OD;
GPIO_Init_Struct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_Init_Struct);

#if defined (USE_IN_UART6_BUFFER) || defined (USE_OUT_UART6_BUFFER)
NVIC_InitStructure.NVIC_IRQChannel = USART6_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = UART6_PreemptionPriority;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = UART6_SubPriority;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif
#ifdef USE_IN_UART6_BUFFER
USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);
//USART_ITConfig(USARTx, USART_IT_ORE, ENABLE);
#endif

break;
}

USART_Init_Struct.USART_BaudRate = Baudrate;
USART_Init_Struct.USART_WordLength = USART_WordLength_8b;
USART_Init_Struct.USART_StopBits = USART_StopBits_1;
USART_Init_Struct.USART_Parity = USART_Parity_No;
USART_Init_Struct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init_Struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USARTx, &USART_Init_Struct);

USART_Cmd(USARTx,ENABLE);


Прерывание:
CODE
void USART6_IRQHandler(void)
{
if(USART_GetITStatus(USART6, USART_IT_TXE) != RESET)
{
#ifdef USE_OUT_UART6_BUFFER

if(UART6_out_counter != 0)
{
UART6_out_counter--;
USART_SendData(USART6,(uint16_t) UART6_OutputBuf[UART6_OutputBufRD]);

if(UART6_OutputBufRD >= (UART6_OutputBuf_size - 1))
{
UART6_OutputBufRD = 0;
}
else
{
UART6_OutputBufRD++;
}
} else {
USART_ITConfig(USART6, USART_IT_TXE, DISABLE);
isTxDone6 = 1;
#endif
}
} else if(USART_GetITStatus(USART6, USART_IT_RXNE) != RESET)
{
USART6->SR;
#ifdef USE_IN_UART6_BUFFER

uint8_t read_UART;

read_UART = USART_ReceiveData(USART6);
#ifdef FATFS_ON
GPSLOGGER_PushByte( read_UART );
#endif



if(UART6_in_counter < UART6_InputBuf_size)
{
UART6_InputBuf[UART6_InputBufWR] = read_UART;

if(UART6_InputBufWR == (UART6_InputBuf_size - 1))
{
UART6_InputBufWR = 0;
}
else
{
UART6_InputBufWR++;
}
UART6_in_counter++;
}
#endif
}else {
USART6->SR;
USART6->DR;
}

USART_ClearFlag( USART6, USART_FLAG_CTS | USART_FLAG_LBD | USART_FLAG_RXNE | USART_IT_TC );
}


Ну тык вот, есть странности (скорость 200к). Самый главный вопрос, почему мы иногда попадаем в последний else, выполняя
USART6->SR;
USART6->DR;


При этом, это должно было быть прерывание RX, НО RXNEIE = 0! Все остальные биты такие-же как и при нормальном прерывании.

Еще странность что ORE почти всегда 1.

В GPSLOGGER_PushByte есть глобальное разрешение и запрещение прерывания, но функция просто просто байт сохраняет:
CODE
inline void GPSLOGGER_PushByte( uint8_t b ){
__disable_irq();
if( sizebuf[curBuf] < LOGBUFSIZE ){
logbuf[ curBuf ][ sizebuf[curBuf] ] = b;
}
sizebuf[ curBuf ] ++;
__enable_irq();
}


Сообщение отредактировал Vladimir Prokofiev - Feb 20 2014, 10:40
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Feb 20 2014, 18:06
Сообщение #2


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



У STM-ок это довольно часто бывает - "ложное" (spurious) прерывание. Просто не реагируйте.
И, кстати, вполне возможно одновременное единичное состояние флагов RXNE и TXE. Поэтому второй else - лишний.
Примерно вот так:
Код
    uint16_t status = USARTx->SR;
    uint8_t data = USARTx->DR;
    
    // чистим ошибки
    if (status & (USART_SR_ORE | USART_SR_NE | USART_SR_FE | USART_SR_PE))
        USARTx->SR = 0;
    
    if (status & USART_SR_RXNE)
    {
        // обрабатываем приём.
    }

    if (status & USART_SR_TXE)
    {
        // обрабатываем передачу.
    }



--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Feb 24 2014, 08:24
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(Vladimir Prokofiev @ Feb 20 2014, 11:37) *
В GPSLOGGER_PushByte есть глобальное разрешение и запрещение прерывания, но функция просто просто байт сохраняет:
CODE
inline void GPSLOGGER_PushByte( uint8_t b ){
__disable_irq();
if( sizebuf[curBuf] < LOGBUFSIZE ){
logbuf[ curBuf ][ sizebuf[curBuf] ] = b;
}
sizebuf[ curBuf ] ++;
__enable_irq();
}

Кстати, код можно построить так, чтобы не запрещать глобальные прерывания.
Go to the top of the page
 
+Quote Post
Vladimir Prokofi...
сообщение Feb 26 2014, 09:47
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 47
Регистрация: 9-03-11
Пользователь №: 63 481



Цитата(KnightIgor @ Feb 24 2014, 12:24) *
Кстати, код можно построить так, чтобы не запрещать глобальные прерывания.

Подскажите?sm.gif

А прерывание судя по всему не лишнее, а настоящее, только с невыставленным флагом RXNEIE. Я воспользовался библиотечной функцией USART_GetITStatus, которая проверяет этот флаг. Если написать как у вас то проблема не заметна. И ошибки CRC пропали sm.gif. Про одновременное срабатывание спасибо, не подумал.
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Apr 29 2014, 09:19
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(Vladimir Prokofiev @ Feb 20 2014, 11:37) *
...странное...

Прежде, чем начинать новую тему, поискал, не было ли чего похожего. Оказался здесь. Мой пост есть не столько ответ к ТС сколько нарытая информация к UART STM32F10x.

Предыстория раскопок.

Применяю, естессно, UART широко и с размахом. Возникла тема подключить WiFi-модуль к STM32F103 через UART. Сделал, заработало. Более тщательные тесты обнаружили спорадическую потерю байтов при приеме от WiFi-модуля. Ну, скажем, один байт на каждые полмега.

Прием построен по принципу FIFO в виде аппаратно-независимого драйвера. Полный код приводить не буду, но процедура обработки прерывания в части приема выглядит так:
CODE
/******************************************************************************/
//
// IRQ Handler
//
void bufio_IRQHandler(bufio_FIFO *FIFO)
{
bufio_DRIVER* h = FIFO->HD; // to shorten the script
if (h && h->RI)
{
while (h->RI()) {

// If no more place in the input buffer, no char read out
// from the data register follows, and RI flag stays ON.
// The interrupt will be disabled. As soon as it is reenabled
// in the ReadChar, the interrupt shoots again.

if (bufio_RXBufferReady() && !FIFO->RX.flag)

bufio_StoreChar(FIFO, h->Get());

else {

h->RIE(0); // disable RX interrupt w/o getting the char
break; // from the device; it should keep the RI flag on.
}
}
}
....


h->RI() - это, по сути, чтение SR на предмет RXNE. Ну а h->Get() - чтение DR. Вроде все согласно логике и докам.
Обработчик - это еще не вектор прерывания: тот инкапсулирует вызов обработчика как:
CODE
/******************************************************************************/
//
// USART IRQ Handler
//
/******************************************************************************/
void STDIO_IRQHandler(void)
{
bufio_IRQHandler(&FIFO);
}


Когда я натолкнулся на потерю байтов, я, естественно, начал подозревать переполнение буфера UART, хотя при 115200 бод и 72MHz проца такого быть бы не должно (приоритет прерывания для UART установлен неслабенький). Для поимки жука я выставил ловушку:
CODE
/******************************************************************************/
//
// USART IRQ Handler
//
/******************************************************************************/
void STDIO_IRQHandler(void)
{
if (STDIO_DEVICE->SR & USART_SR_ORE)
__NOP();
bufio_IRQHandler(&FIFO);
}

После чего в ловушку никто не попал, а потери байтов, похоже, прекратились...

Чисто феноменологически, а также из опыта продирания сквозь дебри I2C этого проца, я сделал вывод, что, похоже, прерывание возникает раньше, чем биты, его вызвавшие, появляются в SR. Это, возможно, приводит к тому, что без задержки по причине if() вверху нарушается логика работы основного обработчика. Чтение же (явно лишнее) SR просто так перед дальнейшими действиями приводит UART в чувство после пинка прерывания. Где-то напортачили с синхронизацией регистров и шин. Даже осмелюсь высказать крамольную гипотезу, что обновления SR происходят не от основной частоты, а синхронизируются с baud-частотой.

В общем, оставил я тупое предчтение SR пока. Не люблю я таких work around... А что делать? И кто виноват?

Сообщение отредактировал KnightIgor - Apr 29 2014, 09:33
Go to the top of the page
 
+Quote Post
adnega
сообщение Apr 29 2014, 10:03
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(KnightIgor @ Apr 29 2014, 13:19) *
Чисто феноменологически, а также из опыта продирания сквозь дебри I2C этого проца, я сделал вывод, что, похоже, прерывание возникает раньше, чем биты, его вызвавшие, появляются в SR. Это, возможно, приводит к тому, что без задержки по причине if() вверху нарушается логика работы основного обработчика. Чтение же (явно лишнее) SR просто так перед дальнейшими действиями приводит UART в чувство после пинка прерывания. Где-то напортачили с синхронизацией регистров и шин. Даже осмелюсь высказать крамольную гипотезу, что обновления SR происходят не от основной частоты, а синхронизируются с baud-частотой.
В общем, оставил я тупое предчтение SR пока. Не люблю я таких work around... А что делать? И кто виноват?

Недавно тоже боролся с потерей байтов в USART у STM32, но проблема была в... компиляторе - при записи в регистр USART->DR
вставлялось фиктивное его чтение (древняя сборка kgp, в последней все нормально).
Нигде в Интернете жалоб на пропажу байт не нашел, эррата тоже пуста.
Если бы прерывание выставлялось раньше флага, то у Вас просто были бы повторные вхождения в прерывание. Флаг же очищается только
чтением из USART->DR.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Apr 29 2014, 10:48
Сообщение #7


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(KnightIgor @ Apr 29 2014, 13:19) *
Можно слегка упростить:
Код
void STDIO_IRQHandler(void)
{
    STDIO_DEVICE->SR; // dummy read (ИМХО нафиг не надо)
    bufio_IRQHandler(&FIFO);
}
Ничего подобного, о чём вы говорите не наблюдал.
Работаю с UART и с DMA и без оного. Проектов штук 10 сделано. Никаких нареканий.
Вот пример обработчика без DMA:
Код
static INLINE void uart_isr(uart_t* const uart)
{
    uint_fast16_t status = uart->sfr->SR;

    if (status & USART_SR_RXNE)      // if RX data_reg isn't empty (auto-clr by reading data_reg)
    {  
        uart_rx_isr(uart, status);
    }
    else if (status & USART_SR_TXE)  // if TX data_reg is empty (auto-clr by writing data_reg)
    {
        uart_tx_isr(uart);
    }
}
Как видите, никаких двойных чтений статуса.
Читаю строго один раз согласно DS.

Цитата(adnega @ Apr 29 2014, 14:03) *
...древняя сборка kgp, в последней все нормально
Чем же вам оттестированная тысячами пользователей сборка с ланчпада не угодила?
С чего такая тяга к экзотике?
Цитата
Нигде в Интернете жалоб на пропажу байт не нашел, эррата тоже пуста.
+1


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Apr 29 2014, 12:07
Сообщение #8


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(demiurg_spb @ Apr 29 2014, 11:48) *
Можно слегка упростить:

Стремно как-то. Работает пока.

Мы тут с коллегой покумекали, почему потеря редко происходит, и почему добавление инструкции ошибку (пока) устранило (может чтение SR и не нужно, достаточно просто задержки). Предположение следующее.

Видать, по причине внутреннего поведения UART задержка таки нужна, но в большинстве случаев она как бы присутствует, поскольку на вход в прерывание Cortex нужно 12(?) тактов. Это если оно прерывает синхронный цикл. А вот если происходит прерывание более низкоприоритетного прерывания, то для Cortex процов ARM гордо раскидывает пальцы и говорит, что tail chaining, или как там оно зовется, позволяет оказаться в прерывании вдвое быстрее. Поскольку у меня не программа мигания светодиодами, а устройство с множеством других прерываний (ADC, RTC и прочие периодические процессы), то вполне возможен "збiг обставин" - такое стечение обстоятельств, что прерывается прерывание, и имеем, что имеем. А лишняя инструкция или две (ну так исторически сложилось, что это чтение SR для ловушки), выравнивают шансы.

Я почему упомянул и I2C в этой связи: я ловил статусы (комбинации битов) в прерывании I2C, которые не описаны в доке и константах. Причем такие статусы, словно биты не добегали, хотя процессор уже попал в прерывание. А I2C у меня рубает на нулевом приоритете: вы знаете, там в доках требование, чтобы никто не прерывал определенные последовательности действий, вот я так и предотвращаю. А чуть подождешь - и все ОК. Поэтому я укрепляюсь в своей гипотезе, что не все прекрасно в Королевстве Датском, и где-то вагоны бегут впереди паровоза у ST.
Go to the top of the page
 
+Quote Post
adnega
сообщение Apr 29 2014, 13:22
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(KnightIgor @ Apr 29 2014, 16:07) *
Поэтому я укрепляюсь в своей гипотезе, что не все прекрасно в Королевстве Датском, и где-то вагоны бегут впереди паровоза у ST.

Что за камешек? Хотелось бы повторить бяку.
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Apr 29 2014, 13:56
Сообщение #10


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(adnega @ Apr 29 2014, 14:22) *
Что за камешек? Хотелось бы повторить бяку.

Дык неоднократно поминали всуе: STM32F103, в частности STM32F103RCT6. Конкретно, если это важно, дальше стоит типа GH21E 9U CHN GH 218 на корпусе.
Go to the top of the page
 
+Quote Post
adnega
сообщение Apr 29 2014, 17:25
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(KnightIgor @ Apr 29 2014, 17:56) *
Дык неоднократно поминали всуе: STM32F103, в частности STM32F103RCT6. Конкретно, если это важно, дальше стоит типа GH21E 9U CHN GH 218 на корпусе.

Собрал стендик - ошибка не повторяется:
1. USART1 с частотой 100Гц отправляет поочередно "01234567";
2. USART2 принимает эти символы, и если переданный не совпадает с принятым, то увеличивается счетчик ошибок;
3. В обработчике прерывания USART2 включается и выключается LED1;
4. По спаду сигнала на ножке приемника вызывается прерывание EXTI, в котором включается LED2, происходит задержка
на два интервала символа, LED2 выключается и выходим из прерывания;
5. Приоритет USART2 выше EXTI, т.е. прерывание EXTI вытесняется с использованием tail chaining
(вижу на осциллографе импульс LED1 внутри импульса LED2).

Ошибок нет. Может, что-то не так делаю?
CODE
//-----------------------------------------------------------------------------
// void USART2_IRQHandler(void)
//-----------------------------------------------------------------------------
void USART2_IRQHandler(void)
{
BYTE x;

if(USART2->SR & (1 << USART_SR_RXNE))
{
// новый символ в приемнике
x = USART2->DR;

crx++;

GPIOB->BSRR = (1 << 0);

if(x != ('0' + (cnt & 7)))
{
WORKLED_bit ^= 1;
cerror++;
eflag = 1;
}

GPIOB->BSRR = (1 << 0) << 16;
}

if((USART2->SR) & (1 << USART_SR_ORE)) USART2->DR;

}

//-----------------------------------------------------------------------------
// void EXTI3_IRQHandler(void)
//-----------------------------------------------------------------------------
void EXTI3_IRQHandler(void)
{
volatile int d;
if(EXTI->PR & (1 << 3))
{
cexti++;

GPIOB->BSRR = (1 << 1);
for(d = 0; d < 1000; d++);

EXTI->PR = (1 << 3);
GPIOB->BSRR = (1 << 1) << 16;
}
}



Добавил строгую проверку последовательности вызовов обработчиков ОТПРАВКА->EXTI->USART2.
Т.е. если перед очередной отправкой не был принят предыдущий символ, то увеличивается счетчик ошибок.
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Apr 29 2014, 18:38
Сообщение #12


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(adnega @ Apr 29 2014, 18:25) *
Собрал стендик - ошибка не повторяется:
Ошибок нет. Может, что-то не так делаю?

Спасибо, что подхватили тему и пробуете разобраться.
Что "не так делаю", сказать сложно.
Ну, во-первых, USART_SR_RXNE есть сама маска (0x20), а не номер бита. То есть (1 << USART_SR_RXNE) делать нельзя. Если, конечно, этот символ у Вас не определен как-то иначе, чем в "stm32f10x.h".
Во-вторых, вряд ли стОит ожидать, что ошибку (или странное поведение) можно спровоцировать вне сложной системы, в которую выросла моя. И как я писал, у меня ошибка имела место спорадически, примерно каждые пол-мегабайта. Сегодня же, после вышеописанной заплатки, мы с коллегой наперегонки еще погоняли мегабайты и не обнаружили пока ни одного сбоя.
В-третьих, - и думаю, это самое главное, - источником данных у меня является внешнее устройство, которое асинхронно к UART процессора, а Вы передаете в рамках одного процессора, то есть UART'ы "когерентны" и стабильны. Может jitter, а также разбросы в действительной скорости (baud rate) между двумя устройствами и провоцирует UART на непредвиденное поведение. В конце концов, в доках написано, что UART2 (мой случай) тактируется от 36MHz, и скорость 115200 на самом деле устанавливается с ошибкой (по памяти фактически 115384).

Go to the top of the page
 
+Quote Post
adnega
сообщение Apr 29 2014, 21:40
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



С USART_SR_RXNE Вы правы - он у меня определен как номер бита, а не как маска.
По сложности могу усилить и другими блоками, но они будут работать параллельно и вряд ли это окажет влияния.
Можно DMA врубить для усложнения, но насколько я понял, гипотеза была в том, что флаг не успевает за периферией.
Я даже на асме хотел написать обработчик, чтоб было максимально быстрое обращение к USART->SR.
Насчет разброса частоты UART согласен, что ошибка нулевая. Но как мне кажется при допустимом уровне рассогласования все будет работать,
при превышении уровня - все перестанет работать. У меня тоже на тестовой плате USART2 тактруется от 36МГц. На второй стороне у Вас
какое устройство? С какой расчетной частотой? Могу добавить еще одну отладку с "удачным" кварцем на 11.0592МГц, который даст точные
115200. Я за то, что USART у STM32F103 не глючит, хотя в более поздних процах USART заметно поменялся, но это скорее усовершенствование
блока, чем латание дыр. Может все-таки в программе (или компиляторе) проблемы, а может железо сбоит. Заметил, что преобразователь USB-COM TTL
работает стабильнее, если подключать его через последовательные сопротивления (иначе на осциллографе вижу выбросы вверх или вниз аж под 1.5В).
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Apr 30 2014, 06:55
Сообщение #14


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



А зачем этот участок кода? Ведь по приходу нового байта статут формируется заново. Или я что-то упустил?
Цитата(AHTOXA @ Feb 20 2014, 22:06) *
Код
    // чистим ошибки
    if (status & (USART_SR_ORE | USART_SR_NE | USART_SR_FE | USART_SR_PE))
        USARTx->SR = 0;



--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Apr 30 2014, 07:51
Сообщение #15


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(adnega @ Apr 29 2014, 22:40) *
С USART_SR_RXNE Вы правы - он у меня определен как номер бита, а не как маска.

Интересно, зачем. Это же конфликт с CMSIS-согласованным файлом stm32f10x.h
Цитата
На второй стороне у Вас какое устройство? С какой расчетной частотой?

WiFi-"модем" HLK-RM04. Там внутри Ralink RT5350F и кварц, по которому не видно, сколько MHz. Но еще раз: после добавления заплатки, действие которой заключается либо в задержке, либо в предварительном "тупом" чтении регистра SR, ошибка спорадической потери байтов забилась в угол до такой степени, что мы вчера в течение долгих тестов не смогли ее обнаружить.
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Apr 30 2014, 08:57
Сообщение #16


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(demiurg_spb @ Apr 30 2014, 07:55) *
А зачем этот участок кода? Ведь по приходу нового байта статут формируется заново. Или я что-то упустил?

Думаю, ничего не упустили. Более того, операция записи нуля в SR бесполезна для битов ошибок, т.к. они Read Only, а для TC и RXNE может оказаться фатальной: смотрим мануал в части описания регистра SR и читаем:

The TC bit can also be cleared by writing a '0' to it. This clearing sequence is recommended only for multibuffer communication.
The RXNE flag can also be cleared by writing a zero to it. This clearing sequence is recommended only for multibuffer communication.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 30 2014, 09:31
Сообщение #17


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Да, эта часть бесполезна. Видимо, наследие какого-то другого контроллераsm.gif
Но вреда от неё тоже нетsm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
adnega
сообщение Apr 30 2014, 09:38
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(KnightIgor @ Apr 30 2014, 11:51) *
Интересно, зачем. Это же конфликт с CMSIS-согласованным файлом stm32f10x.h

WiFi-"модем" HLK-RM04. Там внутри Ralink RT5350F и кварц, по которому не видно, сколько MHz. Но еще раз: после добавления заплатки, действие которой заключается либо в задержке, либо в предварительном "тупом" чтении регистра SR, ошибка спорадической потери байтов забилась в угол до такой степени, что мы вчера в течение долгих тестов не смогли ее обнаружить.

Насчет битиков ответ простой: я не пользуюсь сторонними библиотеками.

Насчет UARTа я пока уверен, что накакие заплатки не нужны, т.к. железо работает отлично. Но если у Вас есть желание переубедить меня, то
я с радостью помогу. Ибо я лучше сейчас огребу, чем в будущем. В свое время я сталкивался с потерей байт, но не придавал этому особого значения.
Старался писать код не чувствительным к таким потерям (точнее допускающим редкие потери с гарантированным восстановлением за конкретное время/
число перепосылок). Сейчас, когда начал копаться детально (где-то месяц назад), понял, что так или иначе аппаратура не виновата в потерях - виноват
исключительно софт. Если Вы считаете вопрос решенным (для своего круга задач), то, думаю, и копать дальше не стоит (меня тоже сейчас все устраивает).
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Apr 30 2014, 10:11
Сообщение #19


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(adnega @ Apr 30 2014, 10:38) *
Насчет битиков ответ простой: я не пользуюсь сторонними библиотеками.

Жесть sm.gif.
Цитата
Насчет UARTа я пока уверен, что накакие заплатки не нужны, т.к. железо работает отлично. Но если у Вас есть желание переубедить меня, то
я с радостью помогу.

Нет, я никого переубеждать не хочу, тем более человека, который даже библиотеками производителя процессоров не пользуется. Просто поделился информацией на случай, если кто сталкивался, но не понял, что происходит.
Go to the top of the page
 
+Quote Post
adnega
сообщение Apr 30 2014, 10:34
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(KnightIgor @ Apr 30 2014, 14:11) *
Жесть sm.gif.

Нет, я никого переубеждать не хочу, тем более человека, который даже библиотеками производителя процессоров не пользуется. Просто поделился информацией на случай, если кто сталкивался, но не понял, что происходит.

Да, все нормально: просто я с STM практически с самого начала (тогда и библиотеки никакой не было), поэтому библиотеки у меня свои.
Библиотеками производителя я пользуюсь, но только в ознакомительных целях. И документацию читаю внимательно.
Если честно, то до сих пор не понятно, в чем собственно проблема UART на STM32 и почему только у Вас UART теряет байты.
За информацию спасибо: если что-то не работает в сложной системе, то нужно вставлять задержки и дополнительные чтения статусных регистров.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 30 2014, 11:03
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Да библиотеки производителя все (ну большинство точно )с дисклаймером - это только пример!!! они в курсе качества их программистов, так что тоже не сторонник брать не глядя, и по большей части не использую.

А у вас окружающее UART железо нормальное? У нас было такое дело на драйвере в RS232 конденсаторы на землю не запаялись и при ненасыщенном обмене все работало, а в каких то критических случаях иногда проскакивали ошибки, когда от вида данных или еще от чего что-то там разряжалось, недозаряжалось, и уровни перли тупо не правильные...

местные программисты добавили контроль целостности и успокоились, а я осциллографом потыкал и увидел весь этот кавардак, как уровни медленно дрейфуют, может они уплывают и байт теряется?


И еще из интересных тестов я бы первой командой в прерывании пришел байт поставил бы счетчик входа в прерывание, а по сохранению байта в буфер счетчик сохраненных байт, и поглядел не расходиться ли это по ходу дела? Есть у меня такая теория что когда приходит прерывание вы в него вваливаетесь, потом вас куда то дергают, и за это время старый байт затирается, и вы пришли в прерывание за символом, а внутри получили ошибку и не сохранили символ. что-то типа того....
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Apr 30 2014, 16:54
Сообщение #22


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(Golikov A. @ Apr 30 2014, 12:03) *
Да библиотеки производителя все (ну большинство точно )с дисклаймером - это только пример!!! они в курсе качества их программистов, так что тоже не сторонник брать не глядя, и по большей части не использую.

Я о CMSIS говорил.

Цитата
А у вас окружающее UART железо нормальное?

Модуль WiFi и процессор находятся рядом на плате и общаются на TTL/CMOS уровне, без всяких RS-232. Я уверен, с этой точки зрения там все стабильно.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 00:10
Рейтинг@Mail.ru


Страница сгенерированна за 0.0161 секунд с 7
ELECTRONIX ©2004-2016