<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Wireless Printf using BLE UART</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/3222/wireless-printf-using-ble-uart</link><description>We are developing a custom ble service and profile however having printf makes our lives that much easier so we are trying to incorporate it purely for testing purposes. 
 The idea is to send debug messages to an Android device via the nRF UART App.</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 04 Sep 2017 18:01:59 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/3222/wireless-printf-using-ble-uart" /><item><title>RE: Wireless Printf using BLE UART</title><link>https://devzone.nordicsemi.com/thread/11826?ContentTypeID=1</link><pubDate>Mon, 04 Sep 2017 18:01:59 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:35c17bfc-2a13-4caf-9692-8bd8de71f128</guid><dc:creator>flodis</dc:creator><description>&lt;p&gt;You can inhibit the already existing nRF redirection module &lt;strong&gt;&lt;em&gt;retarget.c&lt;/em&gt;&lt;/strong&gt; by setting &amp;quot;RETARGET_ENABLED 0&amp;quot; in the &lt;strong&gt;sdk_config.h&lt;/strong&gt; file.&lt;/p&gt;
&lt;p&gt;If you then make a copy of retarget.c named &lt;strong&gt;my_retarget.c&lt;/strong&gt; in your project source and enable that module using som other module name like &amp;quot;MY_RETARGET_ENABLED 1&amp;quot; you can redirect as you like.&lt;/p&gt;
&lt;p&gt;In my case I included a &amp;#39;my_retarget.h&amp;#39; header file in the &amp;quot;my_retarget.c&amp;quot; and &amp;quot;main.c&amp;quot; with an added reference to the &amp;quot;ble_nus.h&amp;quot; library and a redirection flag and a pointer to the &lt;em&gt;ble_nus_t&lt;/em&gt; structure to use.&lt;/p&gt;
&lt;p&gt;Header file &amp;quot;my_retarget.h&amp;quot;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;quot;ble_nus.h&amp;quot;
extern bool use_ble_prn;       //* Enable to use printf over ble set &amp;#39;use_ble_prn&amp;#39; true prior to a call to printf() */
extern ble_nus_t * p_nus;      //* Pointer to a static &amp;#39;ble_nus_t&amp;#39; structure*/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the &amp;quot;my_retarget.c&amp;quot; I added som more code to the _write() function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int _write(int file, const char * p_char, int len)
{
    int i;

    UNUSED_PARAMETER(file);

	if (!use_ble_prn)
	{
		//Print to hardware UART
		for (i = 0; i &amp;lt; len; i++)
		{
			UNUSED_VARIABLE(app_uart_put(*p_char++));
		}	

	}
	else
	{
		//Print to Bluetooth UART
		if (p_nus != NULL)
		{
			ble_nus_string_send(p_nus, (uint8_t *) p_char, len);			
		}

		//Disable redirection after each print
		use_ble_prn = false;
	}

    return len;
} 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The pointer &lt;em&gt;p_nus&lt;/em&gt; was initialized in the main.c on the line next after the &lt;em&gt;ble_nus_t&lt;/em&gt; structure&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;static ble_nus_t                        m_nus;                                      /**&amp;lt; Structure to identify the Nordic UART Service. */
ble_nus_t *								p_nus = &amp;amp;m_nus;                             /**&amp;lt; Ponter to UART structure used by external retarget&amp;gt; */  
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;More generic approach - implementing a callback function:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A more generic aproach would be a writeCallback() function in the &lt;strong&gt;my_retarget.c&lt;/strong&gt; file. In that case you avoid references to UART devices and can do whatever you like in the callback residing in your main module.&lt;/p&gt;
&lt;p&gt;Declared in the my_retarget.h as&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;extern volatile int (*_writeCallback)(int, const char *, int);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the &lt;strong&gt;my_retarget.c&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;volatile int(*_writeCallback)(int, const char *, int) = NULL;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;..and callback declared in main.c as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//Printf callback function
volatile int printfCallback(int file, const char * p_char, int len)
{
	//Send printf data to ble UART
	ble_nus_string_send(&amp;amp;m_nus, (uint8_t *) p_char, len);
	return len;	
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;..and to init the callback from main:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;void printf_redirect_init()
{
	_writeCallback = printfCallback;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The my_redirect.c may contain a _write() function like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int _write(int file, const char * p_char, int len)
{
    int i;

    UNUSED_PARAMETER(file);


	if (use_ble_prn)
	{
		//Disable redirection after each print
		use_ble_prn = false;	

		if (_writeCallback != NULL)
		{
			//Invoke callback function
			return _writeCallback(file, p_char, len);		
		}
	
	}	
	else
	{
		//Print to hardware UART
		for (i = 0; i &amp;lt; len; i++)
		{
			UNUSED_VARIABLE(app_uart_put(*p_char++));
		}	

	}


    return len;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At least some ideas to irritate or inspire.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Wireless Printf using BLE UART</title><link>https://devzone.nordicsemi.com/thread/11825?ContentTypeID=1</link><pubDate>Thu, 24 Jul 2014 23:03:06 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:2fc9d9b1-62de-4627-a11e-acd006be2501</guid><dc:creator>Nick</dc:creator><description>&lt;p&gt;The solution Nick outlined works. I tested by replacing&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;void nus_data_handler(ble_nus_t * p_nus, uint8_t * p_data, uint16_t length)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;with&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;void nus_data_handler(ble_nus_t * p_nus, uint8_t * p_data, uint16_t length)
{
	if(p_data[0] == &amp;#39;a&amp;#39;)
	{
		ble_nus_send_string(&amp;amp;m_nus, &amp;quot;Using BLE NUS&amp;quot;, 13);
	}
	else if(p_data[0] == &amp;#39;b&amp;#39;)
	{
		printf(&amp;quot;Using Printf %d&amp;quot;,1234);
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When i send &amp;#39;a&amp;#39; from my Android App it returns &amp;quot;Using BLE NUS&amp;quot;&lt;/p&gt;
&lt;p&gt;When i send &amp;#39;b&amp;#39; from my Android App it returns &amp;quot;Using Printf 1234&amp;quot;&lt;/p&gt;
&lt;p&gt;Unfortunately floats dont work even with&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CFLAGS = -O0 -g
LDFLAGS = -u _printf_float
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;in my Makefile.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Wireless Printf using BLE UART</title><link>https://devzone.nordicsemi.com/thread/11824?ContentTypeID=1</link><pubDate>Thu, 24 Jul 2014 13:14:50 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:66a50449-1dd6-48be-b7e9-34554912cb6f</guid><dc:creator>cocoa</dc:creator><description>&lt;p&gt;Hi Nick,
this is very usefull code. I think Nordic should ask to you about how adopt it in its SDK.&lt;/p&gt;
&lt;p&gt;-c&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Wireless Printf using BLE UART</title><link>https://devzone.nordicsemi.com/thread/11823?ContentTypeID=1</link><pubDate>Thu, 24 Jul 2014 01:09:07 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ad1c349c-6459-427f-b8a7-61b38a562ef7</guid><dc:creator>Nick</dc:creator><description>&lt;p&gt;You need to route the _write system call to use the ble_nus_send_string() function. I&amp;#39;ve done this before with GCC for a Cortex-M4 device (STM32F4).&lt;/p&gt;
&lt;p&gt;You need to add new source file to your project called &amp;quot;syscalls.c&amp;quot; (code below is untested, but it should give you a pretty good idea on how it&amp;#39;s done).&lt;/p&gt;
&lt;p&gt;EDIT: As in the printf-gcc example you linked, you probably only have to supply the _write() function. However, I&amp;#39;ve provided the entire syscalls.c file below for completeness.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;sys/stat.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
#include &amp;quot;app_error.h&amp;quot;
#include &amp;quot;ble_nus.h&amp;quot;

extern ble_nus_t m_nus;

int __errno;

int _close(int file) {
	return 0;
}

int _fstat(int file, struct stat *st) {
	return 0;
}

int _isatty(int file) {
	return 1;
}

int _lseek(int file, int ptr, int dir) {
	return 0;
}

int _open(const char *name, int flags, int mode) {
	return -1;
}

int _read(int file, char *ptr, int len) {
	if (file != 0) {
		return 0;
	}

    // Add read implementation here if required

	return 1;
}

// Register name faking - works in collusion with the linker. 
register char * stack_ptr asm (&amp;quot;sp&amp;quot;);

caddr_t _sbrk_r (struct _reent *r, int incr) {
	extern char   end asm (&amp;quot;end&amp;quot;); // Defined by the linker.
	static char * heap_end;
	char *        prev_heap_end;

	if (heap_end == NULL)
		heap_end = &amp;amp; end;

	prev_heap_end = heap_end;

	if (heap_end + incr &amp;gt; stack_ptr) {
		return (caddr_t) -1;
	}

	heap_end += incr;

	return (caddr_t) prev_heap_end;
}

int _write(int file, char *ptr, int len) {
    uint32_t err_code = ble_nus_send_string(&amp;amp;m_nus, ptr, len);
	APP_ERROR_CHECK(err_code);
    return len;
}
&lt;/code&gt;&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Wireless Printf using BLE UART</title><link>https://devzone.nordicsemi.com/thread/11822?ContentTypeID=1</link><pubDate>Wed, 23 Jul 2014 17:23:28 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:51ed8b29-b87c-4583-87d1-60a64bc06c52</guid><dc:creator>Nick</dc:creator><description>&lt;p&gt;Hi Cocoa, currently I am using a modified ble_app_uart which can communicate over ble uart both ways however it has the limitation of having to manually convert floating point numbers to strings. My goal is to use printf so i can access all the automatic text formatting.&lt;/p&gt;
&lt;p&gt;I have edited the main post in case this was not clear.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Wireless Printf using BLE UART</title><link>https://devzone.nordicsemi.com/thread/11821?ContentTypeID=1</link><pubDate>Wed, 23 Jul 2014 08:03:30 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:708214dc-362a-47f8-a009-fed6604b9d2a</guid><dc:creator>cocoa</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;see ble_app_uart ,  is an uart over ble , probably it fits your needs.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Path : /sdk/nrf51_sdk_v6_0_0_43681/nrf51822/Board/pca10001/s110/experimental/ble_app_uart
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;-c&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>