LoginSignup
1
1

More than 5 years have passed since last update.

NRF_LOG_INFO 出力を printf で UART 出力に直す

Posted at

「Nordic SDK で printf と NRF_LOG」
https://qiita.com/nanbuwks/items/3673691779b2e6eca89a

の実例として、

NRF_LOG_INFO 出力しているプログラムを printf で UART 出力に直してみます。

環境

  • Nordic nRF5 SDK v15.2.0
  • SEGGER Embedded studio for ARM V4.10a
  • J-link v8(中華製)
  • Raytac MDBT50Q-DB

対象プログラム

対象とするのは、

SDK/examples/peripheral/twi_scanner

です。このサンプルプログラムはI2Cのデバイスが何がつながっているかスキャンして表示します。

pca10056/blank/ses/twi_scanner_pca10056.emProject を開き、

実際の配線に合わせて


#define ARDUINO_SCL_PIN 31
#define ARDUINO_SDA_PIN 30

を書き足しました。
これを実行すると、UARTに以下のように出ます。


<info> app: TWI scanner started.
<info> app: No device was found.

(あらかじめ、該当の USBシリアルモジュールなどを使ってPCなどで UART 出力を受信できるようにしておく必要があります。)

printf を Debug Terminal で表示させる

まずは、NRF_LOG_INFO を使わずに、printfを使うようにします。
main.c を以下のように書き換えます。(コード部分だけ抜粋しています)


#include <stdio.h>
#include "boards.h"
#include "app_util_platform.h"
#include "app_error.h"
#include "nrf_drv_twi.h"



#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

#define ARDUINO_SCL_PIN 31
#define ARDUINO_SDA_PIN 30

/* TWI instance ID. */
#if TWI0_ENABLED
#define TWI_INSTANCE_ID     0
#elif TWI1_ENABLED
#define TWI_INSTANCE_ID     1
#endif

 /* Number of possible TWI addresses. */
 #define TWI_ADDRESSES      127

/* TWI instance. */
static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);


/**
 * @brief TWI initialization.
 */
void twi_init (void)
{
    ret_code_t err_code;

    const nrf_drv_twi_config_t twi_config = {
       .scl                = ARDUINO_SCL_PIN,
       .sda                = ARDUINO_SDA_PIN,
       .frequency          = NRF_DRV_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
       .clear_bus_init     = false
    };

    err_code = nrf_drv_twi_init(&m_twi, &twi_config, NULL, NULL);
    APP_ERROR_CHECK(err_code);

    nrf_drv_twi_enable(&m_twi);
}


/**
 * @brief Function for main application entry.
 */
int main(void)
{
    ret_code_t err_code;
    uint8_t address;
    uint8_t sample_data;
    bool detected_device = false;

    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

//    NRF_LOG_INFO("TWI scanner started.");
//    NRF_LOG_FLUSH();
    printf("TWI scanner started printf.\n");
    twi_init();

    for (address = 1; address <= TWI_ADDRESSES; address++)
    {
        err_code = nrf_drv_twi_rx(&m_twi, address, &sample_data, sizeof(sample_data));
        if (err_code == NRF_SUCCESS)
        {
            detected_device = true;
//          NRF_LOG_INFO("TWI device detected at address 0x%x.", address);
            printf("TWI device ddddetected at address 0x%x. printf\n", address);
        }
//      NRF_LOG_FLUSH();
    }

    if (!detected_device)
    {
//      NRF_LOG_INFO("No device was found.");
//      NRF_LOG_FLUSH();
        printf("No deviceddd was found printf.\n");
    }

    while (true)
    {
        /* Empty loop. */
    }
}

NRF_LOG_INFO と NRF_LOG_FLUSH を printfに書き換えています。

これを実行してもまだ UART には何も出ませんが、J-Link 経由で Debug Terminalに


TWI scanner started printf.
No deviceddd was found printf.

と出ます。

これをUART出力に直すには、sdk_config.hにいくつか書き足します。

sdk_config.h

nRF_Librariesハイブの冒頭に、以下のディレクティブを追加します。

  • APP_FIFO_ENABLED
  • APP_UART_ENABLED
  • APP_UART_DRIVER_INSTANCE


//==========================================================

// <h> nRF_Libraries 

//==========================================================
// <e> NRF_BALLOC_ENABLED - nrf_balloc - Block allocator module
//==========================================================
#ifndef NRF_BALLOC_ENABLED
#define NRF_BALLOC_ENABLED 1
#endif


//==========================================================

// <h> nRF_Libraries 

//==========================================================
// <q> APP_FIFO_ENABLED  - app_fifo - Software FIFO implementation


#ifndef APP_FIFO_ENABLED
#define APP_FIFO_ENABLED 1
#endif

// <e> APP_UART_ENABLED - app_uart - UART driver
//==========================================================
#ifndef APP_UART_ENABLED
#define APP_UART_ENABLED 1
#endif
// <o> APP_UART_DRIVER_INSTANCE  - UART instance used

// <0=> 0 

#ifndef APP_UART_DRIVER_INSTANCE
#define APP_UART_DRIVER_INSTANCE 0
#endif

// </e>

// <e> NRF_BALLOC_ENABLED - nrf_balloc - Block allocator module
//==========================================================
#ifndef NRF_BALLOC_ENABLED
#define NRF_BALLOC_ENABLED 1
#endif

更に、nRF_Librariesハイブの最後に

  • NRF_STRERROR_ENABLED

ディレクティブを追加します。


// <q> NRF_STRERROR_ENABLED  - nrf_strerror - Library for converting error code to string.


#ifndef NRF_STRERROR_ENABLED
#define NRF_STRERROR_ENABLED 1
#endif

// </h> 
//==========================================================

// <h> nRF_Log 

//==========================================================


// <q> NRF_STRERROR_ENABLED  - nrf_strerror - Library for converting error code to string.


#ifndef NRF_STRERROR_ENABLED
#define NRF_STRERROR_ENABLED 1
#endif

// <q> RETARGET_ENABLED  - retarget - Retargeting stdio functions


#ifndef RETARGET_ENABLED
#define RETARGET_ENABLED 1
#endif

// </h> 
//==========================================================

// <h> nRF_Log 

//==========================================================

twi_scanner_pca10056.emProject

インクルードパスを追加します。


      c_user_include_directories="../../../config;...


      c_user_include_directories="../../../../../../components/libraries/uart;../../../../../../components/libraries/fifo;../../../config;...

cファイルを追加します。


    <folder Name="nRF_Libraries">
      <file file_name="../../../../../../components/libraries/util/app_error.c" />
      <file file_name="../../../../../../components/libraries/util/app_error_handler_gcc.c" />
      <file file_name="../../../../../../components/libraries/util/app_error_weak.c" />
      <file file_name="../../../../../../components/libraries/util/app_util_platform.c" />
      <file file_name="../../../../../../components/libraries/util/nrf_assert.c" />
      <file file_name="../../../../../../components/libraries/atomic/nrf_atomic.c" />
      <file file_name="../../../../../../components/libraries/balloc/nrf_balloc.c" />
      <file file_name="../../../../../../external/fprintf/nrf_fprintf.c" />
      <file file_name="../../../../../../external/fprintf/nrf_fprintf_format.c" />
      <file file_name="../../../../../../components/libraries/memobj/nrf_memobj.c" />
      <file file_name="../../../../../../components/libraries/ringbuf/nrf_ringbuf.c" />
      <file file_name="../../../../../../components/libraries/strerror/nrf_strerror.c" />
    </folder>


    <folder Name="nRF_Libraries">
      <file file_name="../../../../../../components/libraries/util/app_error.c" />
      <file file_name="../../../../../../components/libraries/util/app_error_handler_gcc.c" />
      <file file_name="../../../../../../components/libraries/util/app_error_weak.c" />
      <file file_name="../../../../../../components/libraries/fifo/app_fifo.c" />
      <file file_name="../../../../../../components/libraries/uart/app_uart_fifo.c" />
      <file file_name="../../../../../../components/libraries/util/app_util_platform.c" />
      <file file_name="../../../../../../components/libraries/util/nrf_assert.c" />
      <file file_name="../../../../../../components/libraries/atomic/nrf_atomic.c" />
      <file file_name="../../../../../../components/libraries/balloc/nrf_balloc.c" />
      <file file_name="../../../../../../external/fprintf/nrf_fprintf.c" />
      <file file_name="../../../../../../external/fprintf/nrf_fprintf_format.c" />
      <file file_name="../../../../../../components/libraries/memobj/nrf_memobj.c" />
      <file file_name="../../../../../../components/libraries/ringbuf/nrf_ringbuf.c" />
      <file file_name="../../../../../../components/libraries/strerror/nrf_strerror.c" />
      <file file_name="../../../../../../components/libraries/uart/retarget.c" />
    </folder>

main.c

その上で、以下のように追加していきます。

まず、ふつうにUARTを使うための include や defaine をします。


#include "app_uart.h"
#if defined (UART_PRESENT)
#include "nrf_uart.h"
#endif
#if defined (UARTE_PRESENT)
#include "nrf_uarte.h"
#endif

#define UART_TX_BUF_SIZE 256                                          
#define UART_RX_BUF_SIZE 256 
#define UART_HWFC APP_UART_FLOW_CONTROL_DISABLED

#define ARDUINO_SCL_PIN 31
#define ARDUINO_SDA_PIN 30

UARTの初期化ルーチンを作ります。


void uart_error_handle(app_uart_evt_t * p_event)
{
    if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR)
    {
        APP_ERROR_HANDLER(p_event->data.error_communication);
    }
    else if (p_event->evt_type == APP_UART_FIFO_ERROR)
    {
        APP_ERROR_HANDLER(p_event->data.error_code);
    }
}
static void uart_init(void)
{
  uint32_t err_code;
  const app_uart_comm_params_t comm_params =
  {
   RX_PIN_NUMBER,
   TX_PIN_NUMBER,
   RTS_PIN_NUMBER,
   CTS_PIN_NUMBER,
   UART_HWFC,
   false,
   NRF_UART_BAUDRATE_115200
  };

    APP_UART_FIFO_INIT(&comm_params,
                         UART_RX_BUF_SIZE,
                         UART_TX_BUF_SIZE,
                         uart_error_handle,
                         APP_IRQ_PRIORITY_LOWEST,
                         err_code);

    APP_ERROR_CHECK(err_code);
}

main() に以下の構文を入れます。


    uart_init();

また、RETARGET の設定が元々あるため NRF_LOG が UART に出ていますが、そのままだと競合するので以下のようにコメントうアウトするか、
```

// APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
// NRF_LOG_DEFAULT_BACKENDS_INIT();
```
sdk_config.h中の以下の行を 0 に書き換えて無効にします。

#define NRF_LOG_BACKEND_UART_ENABLED 1

上記を反映した main.c は以下のようになります。


#include <stdio.h>
#include "boards.h"
#include "app_util_platform.h"
#include "app_error.h"
#include "nrf_drv_twi.h"


#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

#include "app_uart.h"
#if defined (UART_PRESENT)
#include "nrf_uart.h"
#endif
#if defined (UARTE_PRESENT)
#include "nrf_uarte.h"
#endif

#define UART_TX_BUF_SIZE 256                                          
#define UART_RX_BUF_SIZE 256 
#define UART_HWFC APP_UART_FLOW_CONTROL_DISABLED

#define ARDUINO_SCL_PIN 31
#define ARDUINO_SDA_PIN 30

#if TWI0_ENABLED
#define TWI_INSTANCE_ID     0
#elif TWI1_ENABLED
#define TWI_INSTANCE_ID     1
#endif

 #define TWI_ADDRESSES      127

static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);

void twi_init (void)
{
    ret_code_t err_code;

    const nrf_drv_twi_config_t twi_config = {
       .scl                = ARDUINO_SCL_PIN,
       .sda                = ARDUINO_SDA_PIN,
       .frequency          = NRF_DRV_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
       .clear_bus_init     = false
    };

    err_code = nrf_drv_twi_init(&m_twi, &twi_config, NULL, NULL);
    APP_ERROR_CHECK(err_code);

    nrf_drv_twi_enable(&m_twi);
}

void uart_error_handle(app_uart_evt_t * p_event)
{
    if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR)
    {
        APP_ERROR_HANDLER(p_event->data.error_communication);
    }
    else if (p_event->evt_type == APP_UART_FIFO_ERROR)
    {
        APP_ERROR_HANDLER(p_event->data.error_code);
    }
}
static void uart_init(void)
{
  uint32_t err_code;
  const app_uart_comm_params_t comm_params =
  {
   RX_PIN_NUMBER,
   TX_PIN_NUMBER,
   RTS_PIN_NUMBER,
   CTS_PIN_NUMBER,
   UART_HWFC,
   false,
   NRF_UART_BAUDRATE_115200
  };

    APP_UART_FIFO_INIT(&comm_params,
                         UART_RX_BUF_SIZE,
                         UART_TX_BUF_SIZE,
                         uart_error_handle,
                         APP_IRQ_PRIORITY_LOWEST,
                         err_code);

    APP_ERROR_CHECK(err_code);
}

/**
 * @brief Function for main application entry.
 */
int main(void)
{
    ret_code_t err_code;
    uint8_t address;
    uint8_t sample_data;
    bool detected_device = false;

 //   APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
 //   NRF_LOG_DEFAULT_BACKENDS_INIT();

    uart_init();

//    NRF_LOG_INFO("TWI scanner started.");
//    NRF_LOG_FLUSH();
    printf("TWI scanner started printf.\n");
    twi_init();

    for (address = 1; address <= TWI_ADDRESSES; address++)
    {
        err_code = nrf_drv_twi_rx(&m_twi, address, &sample_data, sizeof(sample_data));
        if (err_code == NRF_SUCCESS)
        {
            detected_device = true;
//          NRF_LOG_INFO("TWI device detected at address 0x%x.", address);
            printf("TWI device ddddetected at address 0x%x. printf\n", address);
        }
//      NRF_LOG_FLUSH();
    }

    if (!detected_device)
    {
//      NRF_LOG_INFO("No device was found.");
//      NRF_LOG_FLUSH();
        printf("No device was found printf.\n");
    }

    while (true)
    {
        /* Empty loop. */
    }
}

実行結果

上記のようにしたプログラムを実行すると、USBシリアル接続したPCに以下のように出てきました。


TWI scanner started printf.
No device was found printf.
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1