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

Wireless Printf using BLE UART

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. I am using pure-gcc, Linux/Eclipse, and a custom PCB without UART-USB capability.

I noticed there is a printf-gcc which works with the over wire UART on the evaluation boards. Is there an example of how to do something similar with the BLE UART?

Currently what i have working is sending and receiving text strings over UART using a modified ble_app_uart and an the Android UART App. What i cannot figure out is how to utilize all the nice features of printf with UART to print more than just strings. I see there are examples for over the wire UART and printf but not for BLE UART.

Much Thanks!

Nick

  • Hi,

    see ble_app_uart , is an uart over ble , probably it fits your needs.

    Path : /sdk/nrf51_sdk_v6_0_0_43681/nrf51822/Board/pca10001/s110/experimental/ble_app_uart
    

    -c

  • 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.

    I have edited the main post in case this was not clear.

  • You need to route the _write system call to use the ble_nus_send_string() function. I've done this before with GCC for a Cortex-M4 device (STM32F4).

    You need to add new source file to your project called "syscalls.c" (code below is untested, but it should give you a pretty good idea on how it's done).

    EDIT: As in the printf-gcc example you linked, you probably only have to supply the _write() function. However, I've provided the entire syscalls.c file below for completeness.

    #include <sys/stat.h>
    #include <stdint.h>
    #include "app_error.h"
    #include "ble_nus.h"
    
    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 ("sp");
    
    caddr_t _sbrk_r (struct _reent *r, int incr) {
    	extern char   end asm ("end"); // Defined by the linker.
    	static char * heap_end;
    	char *        prev_heap_end;
    
    	if (heap_end == NULL)
    		heap_end = & end;
    
    	prev_heap_end = heap_end;
    
    	if (heap_end + incr > 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(&m_nus, ptr, len);
    	APP_ERROR_CHECK(err_code);
        return len;
    }
    
  • Hi Nick, this is very usefull code. I think Nordic should ask to you about how adopt it in its SDK.

    -c

  • The solution Nick outlined works. I tested by replacing

    void nus_data_handler(ble_nus_t * p_nus, uint8_t * p_data, uint16_t length)
    

    with

    void nus_data_handler(ble_nus_t * p_nus, uint8_t * p_data, uint16_t length)
    {
    	if(p_data[0] == 'a')
    	{
    		ble_nus_send_string(&m_nus, "Using BLE NUS", 13);
    	}
    	else if(p_data[0] == 'b')
    	{
    		printf("Using Printf %d",1234);
    	}
    }
    

    When i send 'a' from my Android App it returns "Using BLE NUS"

    When i send 'b' from my Android App it returns "Using Printf 1234"

    Unfortunately floats dont work even with

    CFLAGS = -O0 -g
    LDFLAGS = -u _printf_float
    

    in my Makefile.

Related