J-Link as UART- Logging Output for nRF51/52

I use SEGGER RTT to replace UART logging .

STEP 1.
Download J-Link RTT Viewer and install it.
Download the RTT library files from SEGGER site and unzip them into a folder of your BLE SDK:

nRF51_SDK_10.0.0\nRF51_SDK_10.0.0\components\RTT











STEP 2.

Add the folder to  your project.

STEP 3.
add the RTT folder path to config your Project


STEP 4. my example code for main function printf

#include "SEGGER_RTT.h"

//SEGGER Delay
static void _Delay(int period) {
  int i = 100000*period;
  do { ; } while (i--);
}

int main(void)
{
    uint32_t err_code;
    bool erase_bonds;

    // Initialize.
    timers_init();
    buttons_leds_init(&erase_bonds);
    ble_stack_init();
    device_manager_init(erase_bonds);
    gap_params_init();
    advertising_init();
    services_init();
    conn_params_init();

    // Start execution.
    application_timers_start();
    err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
    APP_ERROR_CHECK(err_code);

    // Enter main loop.
    for (;;)
    {
        power_manage();
    SEGGER_RTT_SetTerminal(0);
    SEGGER_RTT_WriteString(0, "Hello from SEGGER!\r\n");
    _Delay(100);
   
    SEGGER_RTT_TerminalOut(1,"terminalOut 1 \r\n");
    _Delay(100);
   
   int terminalNumber=2;
    SEGGER_RTT_SetTerminal(terminalNumber);
    SEGGER_RTT_printf(0, "terminal = %u \r\n",terminalNumber);
    _Delay(100);
   
    SEGGER_RTT_WriteString(0, "terminal 2\r\n");
    _Delay(100);
   
    SEGGER_RTT_TerminalOut(1,"terminalOut from 1 \r\n");
    _Delay(100);    
    }
}


then rebuild.


 If nothing is configured, all data is sent to Terminal 0.

The Teminal to output all following via Write(), WriteString() or printf() can be set withSEGGER_RTT_SetTerminal() .

Output of only one string via a specific Terminal can be done withSEGGER_RTT_TerminalOut(). I could set the parameter to specify which terminal would be the output target.

STEP 5. Open J-Link RTT Viewer

While I want 2 threads( maybe one is main thread, the other one is  interrupt thread) to print in the same terminal, the output message might be disorder or  tattered.

First, config your channel

press "OK".
press File-> connect


the main function output will be like :

STEP 6. my example code for button interrupt printf

add the following code demonstrating a button interrupt

//Add SEGGER_RTT
#include "SEGGER_RTT.h"

void bsp_event_handler(bsp_event_t event)
{
    uint32_t err_code;
    switch (event)
    {
        case BSP_EVENT_SLEEP:
            sleep_mode_enter();
            break;

        case BSP_EVENT_DISCONNECT:
            err_code = sd_ble_gap_disconnect(m_conn_handle,
                       BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            if (err_code != NRF_ERROR_INVALID_STATE)
            {
                APP_ERROR_CHECK(err_code);
            }
            break;

        case BSP_EVENT_WHITELIST_OFF:
            err_code = ble_advertising_restart_without_whitelist();
            if (err_code != NRF_ERROR_INVALID_STATE)
            {
                APP_ERROR_CHECK(err_code);
            }
            break;
 
// add button interrupt      
 case BSP_EVENT_KEY_0:
     break;       

        default:
            break;
    }
}


// add button interrupt handler
static void button_event_handler(uint8_t pin_no, uint8_t button_action)
{
    uint32_t err_code;

    switch (pin_no)
    {
        case BSP_BUTTON_0:
  if(0 != button_action)
  {       
   SEGGER_RTT_TerminalOut(3,"BUTTON ACTION \r\n"); 
   button_action = 1; 
  } 
        
  if(1 == button_action)
  {
   LEDS_ON(BSP_LED_1_MASK);
     
   SEGGER_RTT_TerminalOut(3,"BUTTON on \r\n");
   break;
  }
  else
  {    
   LEDS_OFF(BSP_LED_1_MASK); 
    
   SEGGER_RTT_TerminalOut(3,"BUTTON off \r\n");
   break;
  }
    
   
        default:
            APP_ERROR_HANDLER(pin_no);
            break;
    }
}



/**@brief Function for initializing buttons and leds.
 *
 * @param[out] p_erase_bonds  Will be true if the clear bonding button was pressed to wake the application up.
 */
static void buttons_leds_init(bool * p_erase_bonds)
{
    bsp_event_t startup_event;

#if (0)
    uint32_t err_code = bsp_init(BSP_INIT_LED | BSP_INIT_BUTTONS,
                                 APP_TIMER_TICKS(100, APP_TIMER_PRESCALER), 
                                 bsp_event_handler);
#else
  uint32_t err_code = bsp_init(BSP_INIT_NONE,
                                 APP_TIMER_TICKS(100, APP_TIMER_PRESCALER), 
                                 bsp_event_handler);
 static app_button_cfg_t buttons[] =
    {
        {BSP_BUTTON_0, false, BUTTON_PULL, button_event_handler}
    };

    err_code = app_button_init(buttons, sizeof(buttons) / sizeof(buttons[0]),
                               APP_TIMER_TICKS(300, APP_TIMER_PRESCALER));
    APP_ERROR_CHECK(err_code);
 app_button_enable();
#endif
    APP_ERROR_CHECK(err_code);

    err_code = bsp_btn_ble_init(NULL, &startup_event);
    APP_ERROR_CHECK(err_code);

    *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);
}


then rebuild.



Now,  press button 0 (for pin define, please open  pca100xx.h)













the output will be

























You can try what will happen if 2 threads(interrupt and main thread) print in same terminal.

while you press down, it shows "BUTTON ACTION" and "BUTTON on".
And while you release the button, it shows "BUTTON off"




APPENDIX.
0.For more example, please check the following web site:

https://www.segger.com/jlink-rtt.html#RTT_Example_Code
http://blog.blecentral.com/2015/06/22/rtt_debugging/
http://dl.btc.pl/kamami_wa/j_link_edu_segger.pdf


1.J-Link RTT has function to input , just like what UART logging has done.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章