Перевод может содержать ошибки. Читайте первоисточник: xStreamBufferSendFromISR()
| Назад: [xStreamBufferSend()] | Вверх: [ИПП: Буферы потока] | Вперёд: [xStreamBufferReceive()] |
Функция объявляется в файле stream_buffer.h, кроме того, в проект должен быть включён файл исходного кода FreeRTOS/source/stream_buffer.c.
size_t xStreamBufferSendFromISR(
StreamBufferHandle_t xStreamBuffer,
const void *pvTxData,
size_t xDataLengthBytes,
BaseType_t *pxHigherPriorityTaskWoken );
Функция отправляет данные в буфер потока так же, как и функция xStreamBufferSend(), но используется для вызова из прерываний.
ПРИМЕЧАНИЕ: Уникальная среди объектов FreeRTOS реализация буфера потока (а также реализация буфера сообщений, поскольку буферы сообщений построены поверх буферов потока) предполагает, что есть только одна задача или прерывание, которые будут записывать в буфер (отправитель), и только одна задача или прерывание, которые будут считывать из буфера (получатель). Отправитель и получатель могут быть разными задачами или прерываниями, но, в отличие от других объектов FreeRTOS, небезопасно иметь несколько разных отправителей или несколько разных получателей. Если должно быть несколько разных отправителей, то программист должен поместить каждый вызов функции ИПП записи (например, xStreamBufferSend()) внутрь критической секции и использовать время блокировки на отправке, равное 0. Аналогично, если должно быть несколько разных получателей, то программист должен поместить каждый вызов функции API чтения (например, xStreamBufferReceive()) внутрь критической секции и использовать время блокировки на приеме, равное 0.
Если нужно отправить данные в буфер потока из прерывания (ISR - Interrupt Service Routine), используйте эту функцию. Если же нужно отправить данные из задачи, используйте вызов xStreamBufferSend().
Параметры
| xStreamBuffer | Хэндлер буфера потока, в который будут отправлены данные. |
| pvTxData | Указатель на буфер, содержащий байты, которые будут скопированы в буфер потока. |
| xDataLengthBytes | Максимальное количество байтов, которое будет скопировано из pvTxData в буфер потока. |
| pxHigherPriorityTaskWoken |
(Это необязательный параметр, которому в качестве аргумента можно указать NULL.) Возможно, что будет задача, заблокированная на ожидании данных в буфере потока. Вызов xStreamBufferSendFromISR() может сделать данные доступными для чтения, и, как следствие, ожидающая задача выйдет из заблокированного состояния. Если вызов xStreamBufferSendFromISR() приводит к разблокировке задачи, имеющей приоритет выше текущей выполняемой задачи (которая была прервана вызовом обработчика прерывания), то во время выполнения xStreamBufferSendFromISR() значение *pxHigherPriorityTaskWoken будет установлено в pdTRUE. И, как правило, в таком случае перед выходом из обработчика прерывания выполняется принудительное переключение контекста. В таком случае возврат из прерывания осуществится в задачу с наивысшим приоритетом (из тех, что находятся в состоянии готовности к выполнению). Перед вызовом xStreamBufferSendFromISR() значение *pxHigherPriorityTaskWoken должно быть установлено равным pdFALSE. |
Возвращаемое значение
Количество байтов, фактически отправленных в буфер потока.
Пример использования:
/* Буфер потока, который должен быть создан заранее. */
StreamBufferHandle_t xStreamBuffer;
void vAnInterruptServiceRoutine( void )
{
size_t xBytesSent;
char *pcStringToSend = "String to send";
BaseType_t xHigherPriorityTaskWoken = pdFALSE; /* Инициализируется значением pdFALSE. */
/* Выполняем попытку отправить данные в буфер потока. */
xBytesSent = xStreamBufferSendFromISR( xStreamBuffer,
( void * ) pcStringToSend,
strlen( pcStringToSend ),
&xHigherPriorityTaskWoken );
if( xBytesSent != strlen( pcStringToSend ) )
{
/* В буфере потока не хватило места для размещения всех предложенных
данных, поэтому было размещено только xBytesSent байтов данных. */
}
/* Если значение xHigherPriorityTaskWoken было установлено в pdTRUE
во время выполнения xStreamBufferSendFromISR(), то была разблокирована
некоторая задача, имеющая приоритет выше, чем та, из которой
произошло прерывание. Поэтому нужно выполнить переключение контекста,
чтобы возврат произошёл сразу в задачу с наивысшим приоритетом
(разумеется из наивысшим из тех задач, которые готовы выполнению).
В большинстве портов (реализаций) переключение контекста выполняется
простым вызовом taskYIELD_FROM_ISR().
Однако используйте документацию на используемый вами порт (реализацию) FreRTOS
для уточнения (кажется в последних версиях FreeRTOS уже называется portYIELD_FROM_ISR(). */
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}