Перевод может содержать ошибки. Читайте первоисточник: xStreamBufferCreate(), xStreamBufferCreateWithCallback()
| Назад: [xStreamBufferCreate] | Вверх: [ИПП: Буферы потока] | Вперёд: [xStreamBufferCreateStatic] |
Функция объявляется в файле stream_buffer.h, кроме того, в проект должен быть включён файл исходного кода FreeRTOS/source/stream_buffer.c.
StreamBufferHandle_t xStreamBufferCreateWithCallback
(
size_t xBufferSizeBytes,
size_t xTriggerLevelBytes
StreamBufferCallbackFunction_t pxSendCompletedCallback,
StreamBufferCallbackFunction_t pxReceiveCompletedCallback
);
Функция создаёт новый буфер потока, используя динамически распределяемую память.
Для того, чтобы функция xStreamBufferCreateWithCallback() была доступна, параметр configSUPPORT_DYNAMIC_ALLOCATION в файле FreeRTOSConfig.h должен быть установлен в 1 или оставлен неопределённым (по-умолчанию определяется как 1). Дополнительно должен быть установлен в 1 параметр configUSE_SB_COMPLETED_CALLBACK.
Буфер потока выполняет соответствующий обратный вызов после завершения каждой операции отправки и получения. Буферы потока, созданные с помощью вызова xStreamBufferCreateWithCallback() используют индивидуальные функции обратного вызова, которые необходимо указать при создании буфера потока. Если нет необходимости в индивидуальных функциях обратного вызова, для создания следует использовать вызов ИПП xStreamBufferCreate().
Если требуется размещать буферы потока в статически выделяемой памяти (на этапе компиляции), используйте соответствующие вызовы xStreamBufferCreateStatic() и xStreamBufferCreateStaticWithCallback(). Более подробно отличия динамического и статического распределения ОЗУ описаны здесь.
Параметры
| xBufferSizeBytes | Общее количество байт, которое буфер потока может хранить одновременно. |
| xTriggerLevelBytes | Уровень срабатывания. Это количество байт, которое должно появиться в буфере потока, чтобы задача, заблокированная на ожидании данных в буфере потока, была выведена из заблокированного состояния. Например, если задача заблокирована при чтении из пустого буфера потока, у которого уровень срабатывания установлен равным 1, то задача будет разблокирована, когда в буфер потока будет записан один байт или когда истечёт время блокировки на ожидании данных в буфере потока. Ещё пример: если некая задача заблокирована на чтении пустого буфера потока с установленным уровнем срабатывания 10, то эта задача не будет разблокироваться до тех пор, пока в буфере не накопится как минимум 10 байт или пока не истечёт время блокировки задачи. Если время блокировки читающей задачи истечёт до достижения уровня срабатывания, то задача сможет получить столько байт, сколько будет фактически доступно. Установка уровня срабатывания в 0 приведёт к использованию уровня срабатывания 1. И, разумеется, недопустимо устанавливать уровень срабатывания, превышающий размер буфера. |
| pxSendCompletedCallback | Функция обратного вызова, которая вызывается, если запись в буфер приводит к тому, что количество байт в буфере потока становится больше уровня срабатывания. Если параметр задан равным NULL, будет использована реализация по-умолчанию, которая предоставляется макросом sbSEND_COMPLETED. Функция обратного вызова, выполняемая при записи в буфер, должна иметь прототип, определяемый с помощью StreamBufferCallbackFunction_t, и выглядит он следующим образом:
|
| pxReceiveCompletedCallback | Функция обратного вызова, которая вызывается, если из буфера потока были считаны данные (больше нуля байтов). Если параметр задан NULL, будет использована реализация по-умолчанию, которая предоставляется макросом sbRECEIVE_COMPLETED. Функция обратного вызова, выполняемая при завершении приёма, должна иметь прототип, определяемый с помощью StreamBufferCallbackFunction_t, и выглядит он следующим образом:
|
Возвращаемое значение
Если возвращается значение NULL, буфер потока не был создан, т.к. не хватило места в доступной FreeRTOS памяти кучи (динамически распределяемой) для размещения структуры данных и области хранения буфера потока.
Если было возвращено ненулевое значение, буфер потока был успешно создан. И возвращённое значение нужно сохранить как хэндлер созданного буфера потока.
Пример использования:
void vSendCallbackFunction( StreamBufferHandle_t xStreamBuffer,
BaseType_t xIsInsideISR,
BaseType_t * const pxHigherPriorityTaskWoken
)
{
/* Здесь должен располагаться код, который вызывается, когда
операция записи в буфер приводит к тому, что количество сохранённых
в буфере байт становится больше уровня срабатывания.
Это полезно в случае использования буфера потока для передачи данных
между ядрами многоядерного процессора. В таком сценарии этот
обратный вызов может быть использован для выработки прерывания в
другом ядре процессора, чтобы затем в обработчике прерывания вызовом функции
ИПП xStreamBufferSendCompletedFromISR() проверить и, по необходимости,
разблокировать задачу, ожидающую данные.
*/
}
void vReceiveCallbackFunction( StreamBufferHandle_t xStreamBuffer,
BaseType_t xIsInsideISR,
BaseType_t * const xHigherPriorityTaskWoken
)
{
/* Здесь должен располагаться код, который вызывается при чтении данных
из буфера потока.
Это полезно в случае использования буфера потока для передачи данных
между ядрами многоядерного процессора. В таком сценарии этот
обратный вызов может быть использован для выработки прерывания в
другом ядре процессора, чтобы затем обработчик прерывания вызовом функции
ИПП xStreamBufferReceiveCompletedFromISR() проверил и, при необходимости,
разблокировал задачу, ожидающую отправки данных в буфер потока.
*/
}
void vAFunction( void )
{
StreamBufferHandle_t xStreamBufferWithCallback;
const size_t xStreamBufferSizeBytes = 100;
const size_t xTriggerLevel = 10;
/* Создаём буфер потока, который может содержать до 100 байт и
использует функции vSendCallbackFunction() и vReceiveCallbackFunction()
как функции обратного вызова при завершении передачи и приёма данных из
буфера потока.
Память, используемая для размещения структуры буфера потока и
области данных буфера потока выделяется динамически из кучи,
доступной для использования FreeRTOS.
*/
xStreamBufferWithCallback = xStreamBufferCreateWithCallback(
xStreamBufferSizeBytes,
xTriggerLevel,
vSendCallbackFunction,
vReceiveCallbackFunction );
if( xStreamBufferWithCallback == NULL )
{
/* Для создания буфера потока не хватило места в куче FreeRTOS. */
}
else
{
/* буфер потока был успешно создан и теперь может быть использован. */
}
}
Примечание.
Описание функций xStreamBufferSendCompletedFromISR() и xStreamBufferReceiveCompletedFromISR() есть только в файле stream_buffer.h, возможно потом добавлю отдельные страницы с их описанием
Также хорошо бы обмозговать и описать тип StreamBufferCallbackFunction_t.