-3

I have a structure as follows

struct msg {  
uint16_t data1;
int data2;
}

I am sending it through the serial port after converting the structure data into a string (char buffer).

I am actually using memcpy to copy the contents into the buffer (using PRAGMA for struct packing)

The problem what I face is the puts function of my board, will stop once it encounters a NULL character (ie if 1 bye is 0, as ASCII equivalent o decimal 0 is NULL)

if data2 = 12 then the memory after memcpy will be 00 00 00 0C (HEX). One puts sees the first 00 it stops and returns.

I cannot change my serial port setting or the puts function. What is best method to convert int into 4 byte's in char buffer without any byte being 0

  • 6
    You have three choices. The first is to stop sending binary data and send an ASCII formatted number instead. The second is to use a function that's designed for binary data, something other than `puts`. The third is to encode the entire string using something like [Base64](https://en.wikipedia.org/wiki/Base64). – Mark Ransom Aug 24 '15 at 16:59
  • You should search for "serialization" or "marshalling". In any way, you should not just send a binary image of the `struct`. – too honest for this site Aug 24 '15 at 17:00
  • _"What is best method to convert int into 4 byte's in char buffer without any byte being 0"_ Well use a conversion to a character string. – πάντα ῥεῖ Aug 24 '15 at 17:02
  • Are you sure the only way to access the serial port is via `stdout`? – MooseBoys Aug 24 '15 at 17:02
  • Why can't you use something other than `puts`? That makes no sense. Use `fwrite` which is designed to send binary information. There is no answer to your actual question so you are going to have to compromise somewhere. – john Aug 24 '15 at 17:07
  • possible duplicate of [sending data from microcontroller to the computer using tiva series c](http://stackoverflow.com/questions/32029503/sending-data-from-microcontroller-to-the-computer-using-tiva-series-c) – Cloud Aug 24 '15 at 17:10
  • The sending part is an already existing framework..I can not change that....Only way is to format the integer in a way that it does not contain NULL character (decimal 0) – Jose John Thottungal Aug 24 '15 at 17:11
  • 3
    Pidgeonhole principle says you lose. – EOF Aug 24 '15 at 17:13
  • @MarkRansom How to send a ASCII formatted number, in 4 bytes of char array..? – Jose John Thottungal Aug 24 '15 at 17:17
  • @JoseJohnThottungal You should add some information about the actual communication protocol. You either need to send the data in binary format (probably using network byte ordering), then you use a `write()` function. Or you need to send text encoded data, well but you're right, that can't be managed within 4 bytes. Anyway there are also formats (like used in DVB standards partially) that want to see [decimal binary encoded numbers](https://en.m.wikipedia.org/wiki/Binary-coded_decimal). – πάντα ῥεῖ Aug 24 '15 at 17:39
  • @JoseJohnThottungal Fact is, you can't represent a binary encoded integer without containing `0` bytes. – πάντα ῥεῖ Aug 24 '15 at 17:48
  • @JoseJohnThottungal you can't, converting to ASCII might produce 11 digits (10 if unsigned). Is there some reason you need to keep it to 4 bytes? Are your values limited, or can they be any 32-bit value? – Mark Ransom Aug 24 '15 at 18:13
  • When sending multi-byte values, like integers, outside of your computer (including files), keep in mind the difference between **Big Endian** versus **Little Endian** order. Which does your receiver want? – Thomas Matthews Aug 24 '15 at 18:58

1 Answers1

2

puts() is designed for sending null terminated strings. It's not the right function to use for sending binary data:

  • binary data is not guaranteed to be null terminated, causing puts() to send more data than needed.
  • binary data might embed '\0' chars which would end prematurely the output
  • binary data might embed other special chars that may cause harm, if your standard output is open in text mode, depending on your system/environment.

The right solution depends on the environment/compiler/library you are using for your microcontroler. There are often some special functions for serial I/O (via UART/USART). But if you are allowed to use puts(), you could certainly use putchar() to output byte by byte.

 msg m;  
 int sz = sizeof(m); 
 for (char*p=reinterpret_cast<char*>(&m); sz--; p++) 
     putchar(*p); 

If you're obliged to use puts() at all cost, one way could be to convert the buffer in printable hex digits and send this string. The hex ditigts will require twice the size of your message (+1 null terminator).

Community
  • 1
  • 1
Christophe
  • 68,716
  • 7
  • 72
  • 138