This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Add own backend interface to the logger failed

I try to send the NRF_LOG_INFO() messages over a own backend interface. I tried to add a new backend with nrf_log_backend_add() and enable it with nrf_log_backend_enable(). But as soon as I do this, I only get the first log print over RTT and afterwards I receive nothing. I seems the software is "stuck" somewhere.

NRF52832, SDK 15.3 and Softdevice 6.1.1.

#define NRF_LOG_BACKEND_RTT_ENABLED 1 in sdk_conf.h

void logPut(nrf_log_backend_t const * p_backend, nrf_log_entry_t * p_msg)
{
   //send over uart
}

static void logFlush(nrf_log_backend_t const * p_backend)
{
    //send over uart
}

static void logPanic(nrf_log_backend_t const * p_backend)
{
    //send over uart
}

const nrf_log_backend_api_t sOwnLogBackendApi = {
   .put       = logPut,
   .flush     = logFlush,
   .panic_set = logPanic,
};

static nrf_log_backend_t sOwnLogBackend = {
   .p_api = & sOwnLogBackendApi,
};

void logInit()
{
   const ret_code_t err_code = NRF_LOG_INIT(NULL);
   APP_ERROR_CHECK(err_code);

   NRF_LOG_DEFAULT_BACKENDS_INIT();

   int32_t backend_id = nrf_log_backend_add(& sOwnLogBackend, NRF_LOG_SEVERITY_DEBUG);
   APP_ERROR_CHECK_BOOL(backend_id >= 0);
   nrf_log_backend_enable(& sOwnLogBackend);
}

void uartInit(uartMessageHandler_t uartMessageHandler)
{
   sUartMessageHandler = uartMessageHandler;

   const app_uart_comm_params_t comm_params =
   {
      .rx_pin_no    = RX_PIN_NUMBER,
      .tx_pin_no    = TX_PIN_NUMBER,
      .rts_pin_no   = RTS_PIN_NUMBER,
      .cts_pin_no   = CTS_PIN_NUMBER,
      .flow_control = APP_UART_FLOW_CONTROL_DISABLED,
      .use_parity   = false,
      .baud_rate    = NRF_UART_BAUDRATE_115200
   };

   uint32_t result;
   APP_UART_FIFO_INIT(& comm_params,
                      UART_RX_BUF_SIZE,
                      UART_TX_BUF_SIZE,
                      onUartEvent,
                      APP_IRQ_PRIORITY_LOWEST,
                      result);
   APP_ERROR_CHECK(result);
}

Parents
  • I try to implement a UART backend for the logger, but with custom functions. This because I add some data to indentify these messages as log messages. The UART is additionaly used for sending commands.
    I figured out, that there is a problem with my uartInit(). I took the example ble_app_hrs and added my uart communication. As soon as I call my uartInit() the example, I get error code 0x08 on APP_UART_FIFO_INIT() call. But how do I init the uart to get the uartHandler?

    // UART
    #define UART_TX_BUF_SIZE                  512
    #define UART_RX_BUF_SIZE                  1024
    
    typedef uint16_t uarttMessageLength_t;
    typedef void (* uartMessageHandler_t) (const uint8_t * data, uarttMessageLength_t length);
    
    /*
     * @brief Sends the specified data to the uart port.
     */
    bool uartSendMessage(const void * data, uarttMessageLength_t length)
    {
       //send uart data
       return true;
    }
    
    /*
     * @brief The uart messages flow.
     */
    void onUartMessage(const uint8_t * data, uint16_t length)
    {
       NRF_LOG_HEXDUMP_DEBUG(data, length);
    }
    
    /*
     * @brief The UART communication callback.
     */
    void onUartEvent(app_uart_evt_t * p_event)
    {
       switch (p_event->evt_type)
       {
          case APP_UART_DATA:
             break;
    
          case APP_UART_DATA_READY:
             break;
    
          case APP_UART_COMMUNICATION_ERROR:
             APP_ERROR_HANDLER(p_event->data.error_communication);
             break;
    
          case APP_UART_FIFO_ERROR:
             APP_ERROR_HANDLER(p_event->data.error_code);
             break;
    
          default:
             break;
        }
    }
    
    void uartInit(uartMessageHandler_t uartMessageHandler)
    {
    
       const app_uart_comm_params_t comm_params =
       {
          .rx_pin_no    = 5,
          .tx_pin_no    = 6,
          .rts_pin_no   = 31,
          .cts_pin_no   = 7,
          .flow_control = APP_UART_FLOW_CONTROL_DISABLED,
          .use_parity   = false,
          .baud_rate    = UART_BAUDRATE_BAUDRATE_Baud115200
       };
    
       uint32_t result;
       APP_UART_FIFO_INIT(& comm_params,
                          UART_RX_BUF_SIZE,
                          UART_TX_BUF_SIZE,
                          onUartEvent,
                          APP_IRQ_PRIORITY_LOWEST,
                          result);
       APP_ERROR_CHECK(result);
    }
    
    
    
    /**@brief Function for application main entry.
     */
    int main(void)
    {
        bool erase_bonds;
    
        // Initialize.
        uartInit(& onUartMessage);
        log_init();
        timers_init();
        buttons_leds_init(&erase_bonds);
        power_management_init();
        ble_stack_init();
        gap_params_init();
        gatt_init();
        advertising_init();
        services_init();
        sensor_simulator_init();
        conn_params_init();
        peer_manager_init();
    
        // Start execution.
        NRF_LOG_INFO("Heart Rate Sensor example started.");
        application_timers_start();
        advertising_start(erase_bonds);
    
        // Enter main loop.
        for (;;)
        {
            idle_state_handle();
        }
    }

    : Unfortunately I have only a Make project and no SES or Keil project to debug step by step.

  • It is probably possible to use the UART for logging and application, but that is not something that our SDK supports. The issue is that you try to initialize the UART twice. I suggest you use the RTT backend for your logging, and use the JLink RTT Viewer to monitor this log, to save you some trouble.

    8 means NRF_ERROR_INVALID_STATE, which is returned because the uart is already initialized. I don't know whether you use the same uart instance and the same pins for your custom UART, or whether you are aware that only one uart instance can be used at the time, not both.

    If you try to use the same instance, but with two uartHandlers, I suggest you use only one handler, which also calls the second.

    But again, if this is only for log monitoring during development, I recommend that you save yourself some trouble and use the RTT backend.

Reply
  • It is probably possible to use the UART for logging and application, but that is not something that our SDK supports. The issue is that you try to initialize the UART twice. I suggest you use the RTT backend for your logging, and use the JLink RTT Viewer to monitor this log, to save you some trouble.

    8 means NRF_ERROR_INVALID_STATE, which is returned because the uart is already initialized. I don't know whether you use the same uart instance and the same pins for your custom UART, or whether you are aware that only one uart instance can be used at the time, not both.

    If you try to use the same instance, but with two uartHandlers, I suggest you use only one handler, which also calls the second.

    But again, if this is only for log monitoring during development, I recommend that you save yourself some trouble and use the RTT backend.

Children
No Data
Related