esp-open-rtosを使ってみる

printfの拡張

examples/uart_configにUART1_TXDへ文字を出力するサンプルが有りました。
そこで、これを元に任意の文字をUART1_TXDに表示するアプリを作ってみました。

esp-open-rtosではprintf()が使えます。
そこで、_printf()と__printf()を作りました。

_printf()はUART1_TXDに文字を出力します。
UART関連のアプリを作る際のデバッグで使うことを想定しています。
実行直後のUART1にはFlash関連の情報が表示されます。


__printf()はタスク名とTick数を付加してUART0_TXDに文字を出力します。
多数のタスクが連動して動くアプリのデバッグで使うことを想定しています。




コードは以下の通りです。
_printf()はMessageBuffer経由でdebug_printタスクにデータを渡し、debug_printタスクが UART1_TXDに文字を出力します。
MessageBufferは100バイトの領域しか確保していないので、短時間に多量のデータを出力するとオーバーフローします。
UART1のボーレートは115200としています。
可変長引数の扱いについては、こちらを 参考にさせていただきました。
#include <string.h>
#include "espressif/esp_common.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "message_buffer.h"

#include <esp/uart.h>
#include <esp/uart_regs.h>
#include <stdarg.h>

MessageBufferHandle_t xMessageBuffer;

//https://qiita.com/kurasho/items/1f6e04ab98d70b582ab7
void _printf( const char *format, ... )
{
    char buffer[64];
    va_list ap;

    // 可変長引数を1個の変数にまとめる
    va_start( ap, format );
    // まとめられた変数で処理する
    //vprintf( format, ap );
    vsnprintf( buffer, sizeof(buffer), format, ap );
    xMessageBufferSend( xMessageBuffer, ( void * ) buffer,
                        strlen( buffer ), 0 );
    va_end( ap );
    // 戻り値省略
}

void __printf( const char *format, ... )
{
    va_list ap;
    TickType_t nowTick;
    nowTick = xTaskGetTickCount();
    printf("[%s:%d] ",pcTaskGetName(0),nowTick);

    // 可変長引数を1個の変数にまとめる
    va_start( ap, format );
    // まとめられた変数で処理する
    vprintf( format, ap );
    va_end( ap );
    // 戻り値省略
}

void debug_print(void *pvParameters){
    __printf("Start\n");

    /* Activate UART for GPIO2 */
    gpio_set_iomux_function(2, IOMUX_GPIO2_FUNC_UART1_TXD);

    /* Set baud rate of UART1 to 115200 */
    uart_set_baud(1, 115200);

    /* Set to 1 stopbits */
    uart_set_stopbits(1, UART_STOPBITS_1);

    /* Enable parity bit */
    //uart_set_parity_enabled(1, true);

    /* Set parity bit to even */
    //uart_set_parity(1, UART_PARITY_EVEN);

    size_t xBytesReceived;
    char ucRxData[ 100 ];
    while(1) {
      xBytesReceived = xMessageBufferReceive( xMessageBuffer,
                                            ( void * ) ucRxData,
                                            sizeof( ucRxData ),
                                            portMAX_DELAY );
      __printf("xBytesReceived=%d\n",xBytesReceived);
      if (xBytesReceived != 0) {
        ucRxData[xBytesReceived] = 0;
        for(int i=0;i<xBytesReceived;i++) {
          if (ucRxData[i] == '\n') {
            uart_putc(1, 0x0d);
            uart_putc(1, 0x0a);
          } else {
            uart_putc(1, ucRxData[i]);
          }
        }
        uart_flush_txfifo(1);
      }


    }
}

void uart_print_config(void *pvParameters){
    __printf("Start\n");

    for(;;) {
        /* Get data */
        int baud = uart_get_baud(1);
        UART_StopBits stopbits = uart_get_stopbits(1);
        bool parity_enabled = uart_get_parity_enabled(1);
        UART_Parity parity = uart_get_parity(1);

        /* Print to UART0 */
        printf("Baud: %d ", baud);
        _printf("Baud: %d ", baud);

        switch(stopbits){
        case UART_STOPBITS_0:
            printf("Stopbits: 0 ");
            _printf("Stopbits: 0 ");
        break;
        case UART_STOPBITS_1:
            printf("Stopbits: 1 ");
            _printf("Stopbits: 1 ");
        break;
        case UART_STOPBITS_1_5:
            printf("Stopbits: 1.5 ");
            _printf("Stopbits: 1.5 ");
        break;
        case UART_STOPBITS_2:
            printf("Stopbits: 2");
            _printf("Stopbits: 2");
        break;
        default:
            printf("Stopbits: Error");
            _printf("Stopbits: Error");
        }

        printf("Parity bit enabled: %d ", parity_enabled);
        _printf("Parity bit enabled: %d ", parity_enabled);

        if (parity_enabled) {
          switch(parity){
          case UART_PARITY_EVEN:
            printf("Parity: Even");
            _printf("Parity: Even");
          break;
          case UART_PARITY_ODD:
            printf("Parity: Odd");
            _printf("Parity: Odd");
          break;
          default:
            printf("Parity: Error");
            _printf("Parity: Error");
          }

        } else {
            printf("Parity: None");
            _printf("Parity: None");

        }

        printf("\n");
        _printf("\n");


        vTaskDelay(5000 / portTICK_PERIOD_MS);
    }
}


void user_init(void){
    uart_set_baud(0, 115200);
    printf("SDK version:%s\n", sdk_system_get_sdk_version());

    const size_t xMessageBufferSizeBytes = 100;
    /* Create a message buffer that can hold 100 bytes.  The memory used to hold
    both the message buffer structure and the data in the message buffer is
    allocated dynamically. */
    xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes );
    configASSERT( xMessageBuffer );

    xTaskCreate(debug_print, "task1", 256, NULL, 2, NULL);
    xTaskCreate(uart_print_config, "task2", 256, NULL, 3, NULL);
}

続く....