vn821202 0 23 декабря, 2021 Опубликовано 23 декабря, 2021 (изменено) · Жалоба Всем привет! Пересылаю информацию из 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 */ } Изменено 23 декабря, 2021 пользователем VadimNic_nt Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 10 24 декабря, 2021 Опубликовано 24 декабря, 2021 · Жалоба 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 } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vn821202 0 24 декабря, 2021 Опубликовано 24 декабря, 2021 · Жалоба 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 10 24 декабря, 2021 Опубликовано 24 декабря, 2021 · Жалоба А что в rxUartStream до printf("TickCount1)? буфер rxUartStream до printf("TickCount1) точно пустой? StreamBuffer описание какое-то неоднозначное. xStreamBufferReceive заблокируется до тригера только при чтении пустого буфера. Т.е. если задача заблокировалась на чтении буфера, то она разблокируется либо через 7 мс, либо через 64 байта. Если буфер был пустой, то задача на нем заблокируется. Но если в буфере был 1 байт, то задача не заблокируется. xStreamBufferReceive() прочитает из rxUartStream все, что там есть, но не более 64. А раз задача не заблокирована, то и тригер мимо. ps глупый конечно вопрос, но 7 - это точно 7 мс? у вас тик == 1 мс? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vn821202 0 24 декабря, 2021 Опубликовано 24 декабря, 2021 · Жалоба Спасибо, разобрался после чтения официальной документации. Первоначально я думал, что вызов xStreamBufferReceive заблокируется до приема 64 байт, но чтение и разблокировка происходит при любом количестве байт от 1 до 64. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться