{"id":1,"date":"2015-01-15T19:59:22","date_gmt":"2015-01-15T19:59:22","guid":{"rendered":"http:\/\/siever.info\/blog\/?p=1"},"modified":"2015-03-19T21:58:24","modified_gmt":"2015-03-19T21:58:24","slug":"hello-world","status":"publish","type":"post","link":"https:\/\/siever.info\/home\/hello-world\/","title":{"rendered":"Logging events with on Nordic&#8217;s nRF series via Seger&#8217;s J-Link Real-Time Terminal"},"content":{"rendered":"<p>One of the most most common debugging techniques is &#8220;logging&#8221;, or creating a history of what happens while code runs. \u00a0Logging can be especially difficult in embedded systems, which often lack a natural way to log events, like a console. \u00a0Commonly UARTs are used to log messages via a serial port, but this approach can consume significant run-time that may undermine the timing constraints of the software. It also requires the use of additional pins to support development.<\/p>\n<p>I&#8217;ve found it especially difficult to debug applications using Nordic&#8217;s Bluetooth Low Energy products (nRF family). \u00a0Fortunately, due to some helpful hints by fellow Nordic developers (Thanks <a href=\"https:\/\/devzone.nordicsemi.com\/question\/23763\/j-link-rtt-for-easy-debug-prints\/\">Jeremy<\/a>) and great products\u00a0from <a href=\"http:\/\/segger.com\/\">Segger<\/a>, I&#8217;ve got a solution that suits my needs fairly well. Segger&#8217;s <a href=\"https:\/\/www.segger.com\/jlink-real-time-terminal.html\">Real-Time Terminal<\/a> is a perfect solution to the problem. I&#8217;ve taken the example&#8217;s provided by Segger and made a package from them (easier to configure on multiple projects). I&#8217;ve also added some wrapper functions that provide additional data I find helpful when debugging.<\/p>\n<p>The following explains how to setup a logger for the nRF series of chips, but assumes that:<\/p>\n<ol>\n<li>You are using a Segger J-Link (I&#8217;m using the J-Link <a href=\"https:\/\/www.segger.com\/jlink-lite-cortexm.html\">CortexM<\/a>)<\/li>\n<li>You are using <a href=\"http:\/\/www2.keil.com\/mdk5\/\">Keil MDK v5<\/a> or later,which uses Software Packs.<\/li>\n<\/ol>\n<p>This guide is broken into three distinct phases:<\/p>\n<ol>\n<li><a href=\"#install\">Installing the Logging Package and updating the Keil&#8217;s IDE to easily connect to Segger&#8217;s Log Viewer<\/a><\/li>\n<li><a href=\"#config_prj\">Configuring a project to use the Logging functions<\/a><\/li>\n<li><a href=\"#use\">A quick demo of actual use<\/a><\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<div id=\"install\">\n<h3>Installing the Logging Package and updating the Keil<\/h3>\n<\/div>\n<p>These steps should only need to be performed once.<\/p>\n<ol>\n<ol>\n<li>Install the latest version of Segger&#8217;s J-Link: <a href=\"https:\/\/www.segger.com\/jlink-software.html?step=1&amp;file=JLink_496a\">https:\/\/www.segger.com\/jlink-software.html?step=1&amp;file=JLink_496a<\/a>.<\/li>\n<\/ol>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol>\n<li>Install the Software Package I created for Logging\n<ol>\n<li>Download <a href=\"http:\/\/siever.info\/pack\/Siever.Segger_RTT_Logger.1.0.1.pack\">Siever.Segger_RTT_Logger.1.0.1.pack<\/a>. (It works with any system that Segger&#8217;s RTT supports, not just Nordic)<\/li>\n<li>Double click on the package. It should automatically install via Keil&#8217;s Package Installer.<\/li>\n<\/ol>\n<\/li>\n<li>Update Keil&#8217;s Tools menu to allow easy access to the Log Viewer (which is the window you will use to view log messages).\n<ol>\n<li>Open Keil.<\/li>\n<li>Select <tt>Tools \u2192 Customize Tools Menu... <\/tt> from the menu:<br \/>\n<center><br \/>\n<a href=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/1_AddCustomEntry.png\"><img loading=\"lazy\" decoding=\"async\" width=\"199\" height=\"164\" class=\"alignnone size-full wp-image-10\" src=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/1_AddCustomEntry.png\" alt=\"1_AddCustomEntry\" \/><\/a><\/center><\/li>\n<li>Add a new entry for the Log Viewer. When done it should look something like:<br \/>\n<center><a href=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/2_LogViewerEntryDetails.png\"><img loading=\"lazy\" decoding=\"async\" width=\"438\" height=\"365\" class=\"alignnone size-medium wp-image-11\" src=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/2_LogViewerEntryDetails.png\" alt=\"2_LogViewerEntryDetails\" srcset=\"https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/2_LogViewerEntryDetails.png 438w, https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/2_LogViewerEntryDetails-300x250.png 300w\" sizes=\"(max-width: 438px) 100vw, 438px\" \/><\/a><\/center><br \/>\nThere are a few things to notice here:<\/p>\n<ul>\n<li>I typed <tt>Log Viewer<\/tt> in the first available slot. This will be the name of the new item on the <tt>Tools<\/tt> menu.<\/li>\n<li>The <tt>Command<\/tt> is the <tt>JLinkRTTViewer.exe<\/tt>. Verify that the path is correct for your installation.<\/li>\n<li>Note that <tt>Run Independent<\/tt> is checked.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>The <tt>Tools<\/tt> menu should now have a new item that will be used to launcher the Log Viewer.<\/li>\n<\/ol>\n<hr \/>\n<div id=\"config_prj\">\n<h3>Configuring a project to use the Logging functions<\/h3>\n<\/div>\n<p>You will need to do this for each project on which you want to use these logging functions.<\/p>\n<ol>\n<ol>\n<li>Open the Project<\/li>\n<li>Select the <tt>Logger Package<\/tt> for inclusion in the project. Select <tt>Project \u2192 Manage \u2192 Select Software Packs...<\/tt>:<br \/>\n<center><br \/>\n<a href=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/1_AddPack.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1266\" height=\"435\" class=\"alignnone size-medium wp-image-12\" src=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/1_AddPack.png\" alt=\"1_AddPack\" srcset=\"https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/1_AddPack.png 1266w, https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/1_AddPack-300x103.png 300w, https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/1_AddPack-1024x352.png 1024w\" sizes=\"(max-width: 1266px) 100vw, 1266px\" \/><\/a><\/center><\/li>\n<li>Select the newly added Logger Package and set the version to <tt>fixed<\/tt>:<br \/>\n<center><br \/>\n<a href=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/2_SelectPackToAdd_1.0.1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"889\" height=\"583\" class=\"alignnone size-medium wp-image-36\" src=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/2_SelectPackToAdd_1.0.1.png\" alt=\"2_SelectPackToAdd_1.0.1\" srcset=\"https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/2_SelectPackToAdd_1.0.1.png 889w, https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/2_SelectPackToAdd_1.0.1-300x197.png 300w\" sizes=\"(max-width: 889px) 100vw, 889px\" \/><\/a><\/center><\/li>\n<\/ol>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol>\n<li>Add the Pack to the Run-Time Environment. Select <tt>Project \u2192 Manage \u2192 Run-Time Environment...<\/tt>:<br \/>\n<center><br \/>\n<a href=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/3_AddPackToRunTime.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1273\" height=\"433\" class=\"alignnone size-medium wp-image-14\" src=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/3_AddPackToRunTime.png\" alt=\"3_AddPackToRunTime\" srcset=\"https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/3_AddPackToRunTime.png 1273w, https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/3_AddPackToRunTime-300x102.png 300w, https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/3_AddPackToRunTime-1024x348.png 1024w\" sizes=\"(max-width: 1273px) 100vw, 1273px\" \/><\/a><\/center><\/li>\n<li>Ensure that the package will be included at Run-Time. Expand it and make sure it is selected:<br \/>\n<center><br \/>\n<a href=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/4_ExpandLoggerPackAndSelect_1.0.1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"910\" height=\"508\" class=\"alignnone size-medium wp-image-40\" src=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/4_ExpandLoggerPackAndSelect_1.0.1.png\" alt=\"4_ExpandLoggerPackAndSelect_1.0.1\" srcset=\"https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/4_ExpandLoggerPackAndSelect_1.0.1.png 910w, https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/4_ExpandLoggerPackAndSelect_1.0.1-300x167.png 300w\" sizes=\"(max-width: 910px) 100vw, 910px\" \/><\/a><\/center><\/li>\n<li>The package will need to be enabled via a define. Add the define to the project&#8217;s Preprocessor Symbols.\n<ol>\n<li>Select <tt>Project \u2192 Options For Target...<\/tt>:<br \/>\n<center><br \/>\n<a href=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/OptionsForTarget.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1006\" height=\"433\" class=\"alignnone size-medium wp-image-19\" src=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/OptionsForTarget.png\" alt=\"OptionsForTarget\" srcset=\"https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/OptionsForTarget.png 1006w, https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/OptionsForTarget-300x129.png 300w\" sizes=\"(max-width: 1006px) 100vw, 1006px\" \/><\/a><\/center><\/li>\n<li>Navigate to the <tt>C\/C++<\/tt> tab and add <tt>RTT_LOG_ENABLED<\/tt> to the <tt>Defines<\/tt>:<br \/>\n<center><br \/>\n<a href=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/AddDefine.png\"><img loading=\"lazy\" decoding=\"async\" width=\"642\" height=\"474\" class=\"alignnone size-medium wp-image-20\" src=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/AddDefine.png\" alt=\"AddDefine\" srcset=\"https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/AddDefine.png 642w, https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/AddDefine-300x221.png 300w\" sizes=\"(max-width: 642px) 100vw, 642px\" \/><\/a><\/center><\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<hr \/>\n<div id=\"use\">\n<h3>Demo of Use<\/h3>\n<\/div>\n<p>In order to use the logging functions you will need to add calls to the logging functions to your code. You can use primitive functions provided by Segger, but I choose to use my own wrappers. In order to use my wrappers you will need to include the header file:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/6_AddIncludeWhereNeeded.png\"><img loading=\"lazy\" decoding=\"async\" width=\"175\" height=\"17\" class=\"alignnone size-full wp-image-17\" src=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/6_AddIncludeWhereNeeded.png\" alt=\"6_AddIncludeWhereNeeded\" \/><\/a><\/center><br \/>\nand insert calls into your code. I&#8217;ve provided three functions that each have <tt>printf<\/tt> semantics (and each call Segger&#8217;s <tt>SEGGER_RTT_vprintf()<\/tt>). My functions are:<\/p>\n<dl>\n<dt>loge(&#8230;)<\/dt>\n<dd>Used for logging run-time errors (shown in red)<\/dd>\n<dt>logw(&#8230;)<\/dt>\n<dd>Used for logging warnings (shown in yellow)<\/dd>\n<dt>logi(&#8230;)<\/dt>\n<dd>Used for logging general information (shown in white)<\/dd>\n<\/dl>\n<p>Here are some examples in code:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/7_AddLogMessages.png\"><img loading=\"lazy\" decoding=\"async\" width=\"383\" height=\"95\" class=\"alignnone size-medium wp-image-18\" src=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/7_AddLogMessages.png\" alt=\"7_AddLogMessages\" srcset=\"https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/7_AddLogMessages.png 383w, https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/7_AddLogMessages-300x74.png 300w\" sizes=\"(max-width: 383px) 100vw, 383px\" \/><\/a><\/center>I generally start a debugging session and then launch the <tt>Log Viewer<\/tt> via the item added to the <tt>Tools<\/tt> menu:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/3_UpdatesMenu-Launching.png\"><img loading=\"lazy\" decoding=\"async\" width=\"559\" height=\"199\" class=\"alignnone size-medium wp-image-22\" src=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/3_UpdatesMenu-Launching.png\" alt=\"3_UpdatesMenu Launching\" srcset=\"https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/3_UpdatesMenu-Launching.png 559w, https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/3_UpdatesMenu-Launching-300x107.png 300w\" sizes=\"(max-width: 559px) 100vw, 559px\" \/><\/a><\/center><br \/>\nThe <tt>Log Viewer<\/tt> you will ask how it should connect to a debugger session. When being run with an existing debugging session just indicate it should connect to the debugging session:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/4_LaunchSettings.png\"><img loading=\"lazy\" decoding=\"async\" width=\"280\" height=\"174\" class=\"alignnone size-full wp-image-21\" src=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/4_LaunchSettings.png\" alt=\"4_LaunchSettings\" \/><\/a><\/center><br \/>\nHere&#8217;s an example of the log generated by the three examples shown above:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/RunAndDebug.png\"><img loading=\"lazy\" decoding=\"async\" width=\"816\" height=\"518\" class=\"alignnone size-medium wp-image-23\" src=\"http:\/\/siever.info\/blog\/wp-content\/uploads\/2015\/01\/RunAndDebug.png\" alt=\"RunAndDebug\" srcset=\"https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/RunAndDebug.png 816w, https:\/\/siever.info\/home\/wp-content\/uploads\/2015\/01\/RunAndDebug-300x190.png 300w\" sizes=\"(max-width: 816px) 100vw, 816px\" \/><\/a><\/center><br \/>\nNotice that:<\/p>\n<ul>\n<li>The different warning styles are color coded.<\/li>\n<li>The <tt>log<\/tt> macros I&#8217;ve created insert the file name and line number. This does consume additional flash memory, so don&#8217;t get too carried away with log messages.<\/li>\n<li>Currently I have all log messages going to the tab for Terminal 0. It would be easy to update the approach to include different messages to different terminal tabs for different modules.<\/li>\n<\/ul>\n<h3>Disclaimers<\/h3>\n<p>This work is provided as-is with no warranty or guarantee of any sort. I&#8217;m new to Segger&#8217;s RTT and haven&#8217;t done any review of performance issues. I&#8217;m also new to CMSIS Packages and haven&#8217;t verified that I&#8217;ve followed all appropriate package conventions. At this point this is an alpha version, but any input or suggestions are welcome. The <tt>log<\/tt> macros were made for my needs when I developed them and may not suite other&#8217;s needs. The formatting used for them could certainly be improved.<\/p>\n<h3>Credits<\/h3>\n<p>The package includes unmodified code provided by Segger at: <a href=\"http:\/\/download.segger.com\/J-Link\/RTT\/RTT_Implementation_141217.zip\">http:\/\/download.segger.com\/J-Link\/RTT\/RTT_Implementation_141217.zip<\/a>. Code by Segger includes a copyright notice, but they have given me permission to share the package.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the most most common debugging techniques is &#8220;logging&#8221;, or creating a history of what happens while code runs. \u00a0Logging can be especially difficult in embedded systems, which often lack a natural way to log events, like a console. \u00a0Commonly UARTs are used to log messages via a serial port, but this approach can &hellip; <a href=\"https:\/\/siever.info\/home\/hello-world\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Logging events with on Nordic&#8217;s nRF series via Seger&#8217;s J-Link Real-Time Terminal<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-1","post","type-post","status-publish","format-standard","hentry","category-bluetooth-low-energy"],"_links":{"self":[{"href":"https:\/\/siever.info\/home\/wp-json\/wp\/v2\/posts\/1"}],"collection":[{"href":"https:\/\/siever.info\/home\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/siever.info\/home\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/siever.info\/home\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/siever.info\/home\/wp-json\/wp\/v2\/comments?post=1"}],"version-history":[{"count":23,"href":"https:\/\/siever.info\/home\/wp-json\/wp\/v2\/posts\/1\/revisions"}],"predecessor-version":[{"id":50,"href":"https:\/\/siever.info\/home\/wp-json\/wp\/v2\/posts\/1\/revisions\/50"}],"wp:attachment":[{"href":"https:\/\/siever.info\/home\/wp-json\/wp\/v2\/media?parent=1"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/siever.info\/home\/wp-json\/wp\/v2\/categories?post=1"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/siever.info\/home\/wp-json\/wp\/v2\/tags?post=1"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}