Перейти к содержанию
    

Не блокируется xStreamBufferReceive

Всем привет!

Пересылаю информацию из UART ISR в USB CDC для этого использую  StreamBuffer размером 256 байт и установленным триггером на 64 байта.

При скорости UART 115200 бод (8 бит данных, 2 стоп бита) пересылка 64 байт требует примерно 6,1 с. При отладке обнаружил, что вызов
xStreamBufferReceive не приводит к блокировке не по количеству байт, не по тайм-ауту. В чем может быть дело? В результате код работает корректно
только если использовать osDelay(7).

Фрагмент кода:

/* Stream from UART Recive ISR */
StreamBufferHandle_t   rxUartStream = NULL;
rxUartStream = xStreamBufferCreate(256, 64);

/* USER CODE BEGIN Header_fnc_Uart_Usb */
/**
* @brief Function implementing the task_Uart_Usb thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_fnc_Uart_Usb */
void fnc_Uart_Usb(void *argument)
{
  /* USER CODE BEGIN fnc_Uart_Usb */
    
    uint8_t numBytes;
    uint8_t rxUartAwait = 64;
    uint8_t rxUartData[rxUartAwait];
    
    for(;;)
    {
        
        printf("TickCount1 = %d\n", osKernelGetTickCount()); //debug out j-link


        numBytes = xStreamBufferReceive(    rxUartStream,    //Stream Handle (Stream Size = 256 byte, trigger Level = 64)
                                            rxUartData,        //Recive Buffer
                                            rxUartAwait,     //await count data
                                            7                //> (1/115200)*(8+3)*sizeof(rxUartData) = 6.1 ms
                                        );
        printf("TickCount2 = %d\n", osKernelGetTickCount());  //debug out j-link                                                                  

        if (numBytes)
        {
            uint8_t result, busy = 0, error = 0;
                        
            do
            {
                result = CDC_Transmit_FS(rxUartData, numBytes);
                
                if (USBD_BUSY == result)
                {    
                    if(++busy > 3) break;
                }
              if (USBD_FAIL == result)
                {    
                    if(++error > 3) break;
                }
            }
            while(result != USBD_OK);
                        
            if (result == USBD_OK)
            {     
                #ifdef DEBUG
                    printf("to_USB  ->, numBytes = %d\n", numBytes); //debug out j-link
                #endif                        
                osDelay(7);
            }
            else
            {
                #ifdef DEBUG
                    printf("Error: busy - %d, error - %d\n", busy, error); //debug out j-link
                #endif                    
                osDelay(1);
            }
                
        }
    }
    
  /* USER CODE END fnc_Uart_Usb */
}

 

Изменено пользователем VadimNic_nt

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

 printf("TickCount1 = %d\n", osKernelGetTickCount()); //debug out j-link


        numBytes = xStreamBufferReceive(    rxUartStream,    //Stream Handle (Stream Size = 256 byte, trigger Level = 64)
                                            rxUartData,        //Recive Buffer
                                            64,     //await count data
                                            500                
                                        );
        printf("TickCount2 = %d\n", osKernelGetTickCount());  //debug out j-link   
		printf("numBytes = %d\n", numBytes);  //debug out j-link 
		if(numBytes > 0)
        {
          for(int i = 0; i<numBytes; i++)
            printf("rxUartData[%d] = %d\n", i, rxUartData[i]);  //debug out j-link 
        }

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, juvf said:

 


 printf("TickCount1 = %d\n", osKernelGetTickCount()); //debug out j-link


        numBytes = xStreamBufferReceive(    rxUartStream,    //Stream Handle (Stream Size = 256 byte, trigger Level = 64)
                                            rxUartData,        //Recive Buffer
                                            64,     //await count data
                                            500                
                                        );
        printf("TickCount2 = %d\n", osKernelGetTickCount());  //debug out j-link   
		printf("numBytes = %d\n", numBytes);  //debug out j-link 
		if(numBytes > 0)
        {
          for(int i = 0; i<numBytes; i++)
            printf("rxUartData[%d] = %d\n", i, rxUartData[i]);  //debug out j-link 
        }

 

printf("TickCount1 = %d\n", osKernelGetTickCount()); //debug out j-link (допустим TickCount1 = 100)


numBytes = xStreamBufferReceive( rxUartStream,       //Stream Handle (Stream Size = 256 byte, trigger Level = 64)
                                 rxUartData,         //Recive Buffer
                                 64,     			 //await count data
                                 7                
                               );
printf("TickCount2 = %d\n", osKernelGetTickCount());  //debug out j-link (тут я ожидаю увидеть TickCount1 = 107 или numBytes = 64))  


//на самом деле получаю TickCount1 = TickCount2 и numBytes = 1 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А что в rxUartStream до printf("TickCount1)?  буфер  rxUartStream до printf("TickCount1) точно пустой?

StreamBuffer описание какое-то неоднозначное. xStreamBufferReceive заблокируется до тригера только при чтении пустого буфера.

Т.е. если задача заблокировалась на чтении буфера, то она разблокируется либо через 7 мс, либо через 64 байта. Если буфер был пустой, то задача на нем заблокируется. Но если в буфере был 1 байт, то задача не заблокируется. xStreamBufferReceive() прочитает из rxUartStream все, что там есть, но не более 64. А раз задача не заблокирована, то и тригер мимо.

 

ps глупый конечно вопрос, но 7 - это точно 7 мс? у вас тик == 1 мс?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, разобрался после чтения официальной документации. Первоначально я думал, что вызов xStreamBufferReceive заблокируется до приема 64 байт, но чтение и разблокировка происходит при любом количестве байт от 1 до 64.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...