ESP-IDFを使ってみる

FreeRTOSの新機能 StreamBuffer


ESP-IDF V4.3から、組み込まれているFreeRTOSがV10になり、StreamBufferが使えるようになりました。
そこで、どのような機能なのか確認してみました。
コードは以下の様に単純なものです。
動きが分かり易いように、送信側は送信するたびに10Tick待ちます。
/* The example of ESP-IDF
 *
 * This sample code is in the public domain.
 */

#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/stream_buffer.h"
#include "esp_log.h"

StreamBufferHandle_t xStreamBuffer = NULL;

void ReceivingTask(void *pvParameters)
{
        ESP_LOGI(pcTaskGetName(NULL), "Start");
        char cRxBuffer[ 20 ];
        memset( cRxBuffer, 0x00, sizeof( cRxBuffer ) );

        while(1) {
                size_t readBytes = xStreamBufferReceive(xStreamBuffer,
                                                        cRxBuffer,
                                                        sizeof(cRxBuffer),
                                                        pdMS_TO_TICKS(1000) );
                ESP_LOGD(pcTaskGetName(NULL), "readBytes=%d", readBytes);
                if (readBytes != 0) {
                        ESP_LOGI(pcTaskGetName(NULL), "readBytes=%d cRxBuffer=[%.*s]", readBytes, readBytes, cRxBuffer);
                }
        }
}

void SendingTask(void *pvParameters)
{
        ESP_LOGI(pcTaskGetName(NULL),"Start");
        static size_t xNextByteToSend = 0;
        static size_t xTotalByteToSend = 0;
        const BaseType_t xBytesToSend = 2;
        static const char * pcStringToSend = "_____Hello FreeRTOS_____";
        ESP_LOGI(pcTaskGetName(NULL),"length=%d", strlen(pcStringToSend));

        for(int i=0; i<strlen(pcStringToSend); i++) {
                xStreamBufferSend( xStreamBuffer,
                                                ( void * ) ( pcStringToSend + xNextByteToSend ),
                                                xBytesToSend,
                                                portMAX_DELAY );
                xTotalByteToSend += xBytesToSend;
                ESP_LOGI(pcTaskGetName(NULL),"xTotalByteToSend=%d", xTotalByteToSend);
                xNextByteToSend += xBytesToSend;
                if( xNextByteToSend >= strlen( pcStringToSend ) )
                {
                        xNextByteToSend = 0;
                }
                vTaskDelay(10);
        }
        vTaskDelete(NULL);
}

void app_main()
{
        // Get current priority
        UBaseType_t priority = uxTaskPriorityGet(NULL);
        ESP_LOGI(pcTaskGetName(NULL), "priority=%d", priority);

        // Create Stream Buffer
        xStreamBuffer = xStreamBufferCreate(100, 10);

        // Check everything was created
        configASSERT( xStreamBuffer );

        /* Create task */
        xTaskCreate(&SendingTask, "SEND", 1024*2, NULL, priority, NULL);
        xTaskCreate(&ReceivingTask, "RECV", 1024*2, NULL, priority, NULL);
}

ビルドして実行すると以下の様に表示されます。

StreamBuffer自体は100バイト確保していますが、トリガーを10バイトにしているので、これ以上のデータがバッファに無いと受信が 完 了しません。
送信側が10Tick待っている間に、StreamBufferが全て読まれて空になるので、受信側はまたトリガーを満足するまで待ちます。

最後は8バイトしかバッファに積まれないのでトリガーになりませんが、受信タイムアウトを1秒に設定しているので、
タイムアウトで受信が完了します。
I (0) cpu_start: Starting scheduler on APP CPU.
I (322) main: priority=1
I (322) RECV: Start
I (322) SEND: Start
I (332) SEND: length=24
I (332) SEND: xTotalByteToSend=2
I (442) SEND: xTotalByteToSend=4
I (542) SEND: xTotalByteToSend=6
I (642) SEND: xTotalByteToSend=8
I (742) SEND: xTotalByteToSend=10
I (742) RECV: readBytes=10 cRxBuffer=[_____Hello]
I (842) SEND: xTotalByteToSend=12
I (942) SEND: xTotalByteToSend=14
I (1042) SEND: xTotalByteToSend=16
I (1142) SEND: xTotalByteToSend=18
I (1242) SEND: xTotalByteToSend=20
I (1242) RECV: readBytes=10 cRxBuffer=[ FreeRTOS_]
I (1342) SEND: xTotalByteToSend=22
I (1442) SEND: xTotalByteToSend=24
I (1542) SEND: xTotalByteToSend=26
I (1642) SEND: xTotalByteToSend=28
I (1742) SEND: xTotalByteToSend=30
I (1742) RECV: readBytes=10 cRxBuffer=[_________H]
I (1842) SEND: xTotalByteToSend=32
I (1942) SEND: xTotalByteToSend=34
I (2042) SEND: xTotalByteToSend=36
I (2142) SEND: xTotalByteToSend=38
I (2242) SEND: xTotalByteToSend=40
I (2242) RECV: readBytes=10 cRxBuffer=[ello FreeR]
I (2342) SEND: xTotalByteToSend=42
I (2442) SEND: xTotalByteToSend=44
I (2542) SEND: xTotalByteToSend=46
I (2642) SEND: xTotalByteToSend=48
I (3242) RECV: readBytes=8 cRxBuffer=[TOS_____]

続く....