+ Post New Thread
Results 1 to 7 of 7
  1. #1
    Member level 1
    Points: 409, Level: 4

    Join Date
    Jul 2017
    Posts
    38
    Helped
    0 / 0
    Points
    409
    Level
    4

    itoa Function in C : How to read all DestinationBuffer values (int) into String Forma

    For hardware implementation, I am writing this function to read the data in Hercules. In Hercules, integer data can be read in string format. So, i have tried itoa conversion in XSDK. I am running counter module for e.g. N times. That N number of data should be converted into String from int and should read in Hercules.

    I have tried with below code but single data i am able to read. How to put loop for N times for DestinationBuffer.

    Code C - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    
    char buf[32] = {0};
    extern u32 DestinationBuffer[10];              // Global
    int transfer_data() {
        return 0;
    }
    char *itoa(int val, int base)
    {
     int i = 30;
    for(; val && i ; --i, val /= base)
    buf[i] = "0123456789abcdef"[val % base];
    return &buf[i+1];
    }
    err_t recv_callback(void *arg, struct tcp_pcb *tpcb,
                                   struct pbuf *p, err_t err)
    {
        int i,j,Status;
        Status=aurora_rx_main();         ///FUNCTION CALL
     
        for(i=0;i<10;i++)
         {
            xil_printf(" Data:%d,",DestinationBuffer[i]);
        }
     
        int base=10; // here 10 means decimal
      char *result={0};
     
      result= itoa(DestinationBuffer[0],base);    //// How to make it into loop to read all the DestinationBuffer values into String in Hercules. Now, i am able to read only 0th position values
     
        if (!p) {
            tcp_close(tpcb);
            tcp_recv(tpcb, NULL);
            return ERR_OK;
        }
     
        /* indicate that the packet has been received */
        tcp_recved(tpcb, p->len);
     
        if (tcp_sndbuf(tpcb) > 10) {
            err = tcp_write(tpcb,result,10,1);
     
        } else
            xil_printf("no space in tcp_sndbuf\n\r");
     
        /* free the received pbuf */
        pbuf_free(p);
     
        return ERR_OK;
    }

    Data stored in DestinationBuffer should be converted into string using itoa function.

    •   AltAdvertisment

        
       

  2. #2
    Super Moderator
    Points: 28,087, Level: 40
    andre_teprom's Avatar
    Join Date
    Nov 2006
    Location
    Brazil
    Posts
    8,389
    Helped
    1058 / 1058
    Points
    28,087
    Level
    40
    Blog Entries
    6

    Re: itoa Function in C : How to read all DestinationBuffer values (int) into String F

    You have defined the return type as err_t which is likely a numeric value. Instead, you should return not only the address of the first character of the string, but also its length.
    --------------------------------------------------------------------------------------------------
    Part of the world that you live in, You are the part that you're giving ( Renaissance )



  3. #3
    Advanced Member level 3
    Points: 7,037, Level: 19

    Join Date
    Jan 2015
    Posts
    985
    Helped
    312 / 312
    Points
    7,037
    Level
    19

    Re: itoa Function in C : How to read all DestinationBuffer values (int) into String F

    I think your 'itoa' function is wrong in that it will:
    - write the characters in the reverse order into the 'buf' array
    - not null terminate the string
    - pass back a pointer to the last character of the string, not the first
    Try using pencil and paper with 'val'of (say) 23 and 'base' of 10 - alternatively just write a small program to let you step through your code to see what is really is doing.
    As for your question, you have a 'for' loop just above where you step 'i' from 0 to 9 - why not use similar code to print out each value or put the code to print each value into that loop (perhaps no need for an array in that case).
    I recommend that you look at some of the many code examples on the Internet for the 'itoa' function - why reinvent the wheel.
    Susan



    •   AltAdvertisment

        
       

  4. #4
    Member level 1
    Points: 409, Level: 4

    Join Date
    Jul 2017
    Posts
    38
    Helped
    0 / 0
    Points
    409
    Level
    4

    Re: itoa Function in C : How to read all DestinationBuffer values (int) into String F

    DestinationBuffer values are decimal values. I am using this function in LWIP Echo server (Ethernetlite).

    Default Code ( itoa)

    Code:
    char* itoa(int val, int base){
    	
    	static char buf[32] = {0};
    	
    	int i = 30;
    	
    	for(; val && i ; --i, val /= base)
    	
    		buf[i] = "0123456789abcdef"[val % base];
    	
    	return &buf[i+1];
    	
    }
    Can anyone tell me how to increase the buf size from 32. Whether the above code will work for buf size 4028 ? For e.g. static char buf[4028] = {0}; if so then i value should be same or different ? Please tell me



  5. #5
    Advanced Member level 3
    Points: 7,037, Level: 19

    Join Date
    Jan 2015
    Posts
    985
    Helped
    312 / 312
    Points
    7,037
    Level
    19

    Re: itoa Function in C: How to read all DestinationBuffer values (int) into String Fo

    I think you need to understand what the code is actually doing before you try to edit it - and also understand the C programming language a bit better.
    The 'static char buf[32]' part defines the array variable called 'buf' and creates 32 'char' sized elements to it. If you want to make it larger, say 64 then change the '32' to '64'. (BUT see later!)
    The '= {0}' part is an initialiser that sets the initial array locations to a known value. In this particular case, it only specified the initial value of the first element which it sets to zero. Depending on how a compiler it implemented, it may also set all of the other array locations to zero or leave them at some random value - you will need to check the compiler documentation to determine how it handles this situation. However I think the writing of this code assumes (or has checked with his/her situation and determined) that this will set the entire array to 0.
    As for setting the array size to 4028 - WHY? If you look at how the code works, it starts by taking an integer value that is passed as a parameter. Again you will need to look at the compiler documentation to see what size (in bytes) is the default of 'int' variables. Typically it is 16, 32 or 64 bits depending on the architecture the code is intended to run on. By setting the buffer size to 32, I would assume that the author assumes a 32-bit integer value.
    That begin said, the longest resulting string would come when the 'base' being passed is 2 (i.e. convert the value to a binary string). As there are 32 bits i the original value, the longest string that could be generated is 32 characters.
    Therefore, making the result array 4028 elements long would merely waste 3996 bytes of data memory.
    This also shows a couple of logical errors that are embedded in this code.
    If the base is 2, then we have seen that there could be 32 characters (either '0' or '1') created. That means the entire 'buf' would be filled. Typically strings need a 'null' character at the end which is why the variable 'i' is initialised to 30 - leaving location buf[31] to be the null.
    Now look at the way the 'cal' parameter is defined - it is a 'signed integer' as the 'signed' (as opposed to 'unsigned') is the C standard default if neither keyword is used. This means that 'val' could be passed a value such as -32768 quite legitimately. In binary that is 0b10000000000000000000000000000000. If that value was fed in to the function and displayed as binary, it would generate "0000000000000000000000000000000" - 31 '0's.
    Note also that it will not show the '1' in the left-most position. The reason is that the for loop will terminate when either 'v' or 'i' becomes zero. Because the buffer is only 32 characters long and the last character is reserved for the trailing null, 'i' will become zero just before the last actual digit is generated. Therefore it would be better if the array was 33 elements long, again with the last one for the trailing null but with space then for all of the possible digits.
    If the 'val' is really to be signed, then the sign needs to be taken into account and included in the display - which may require that buf be 34 elements long and the absolute value of 'val' is the one that is converted.
    Susan



    •   AltAdvertisment

        
       

  6. #6
    Member level 1
    Points: 409, Level: 4

    Join Date
    Jul 2017
    Posts
    38
    Helped
    0 / 0
    Points
    409
    Level
    4

    Re: itoa Function in C: How to read all DestinationBuffer values (int) into String Fo

    Modified code but even i am unable to read the data in Hercules.

    I am working with Xilinx Ethernetlite (LWIP) design. I am able to transfer the data from KC board to PC (Hercules) through Ethernet only if buf =32. But my actual buffer size is 1024. How to increase the buffer size from 32 to 1024. I am unable to make sure whether the mistake is in code or in hercules. To read the values (integer) in hercules i am doing this function.

    initially, From hercules i will send the Hello command to Board,then board with accept that request. After that, board will output the data (integer values) to Hercules.

    Code:
    #define  DAQ_FIFO_DEPTH  100
    
    err_t tcp_write_u32_string(struct tcp_pcb *pcb, unsigned char   prefix, u32_t value)
    {
        /* Because 0 <= u32_t <= 4294967295, the value itself is at most 10 digits long. */
        unsigned char  buf[11]; /* enough room for prefix and value. */
        err_t          result;
        u16_t          len;
        unsigned char *p = buf + sizeof buf;
    
        /* Construct the value first, from right to left. */
        do {
            /* ASCII encoding: '0' = 48, '1' = 49, ..., '9' = 57. */
            *(--p) = 48 + (value % 10u);
            value /= 10;
        } while (value);
    
        /* Prepend the prefix, if any. */
        if (prefix)
            *(--p) = prefix;
    
        /* Calculate the length of this part. */
        len = buf + sizeof buf - p;
    
        /* If the TCP buffer does not have enough free space, flush it. */
        if (tcp_sndbuf(pcb) < len) {
            result = tcp_output(pcb);
            if (result != ERR_OK)
                return result;
        }
    
        /* Append the buffer to the TCP send buffer.
           We also assume the packet is not done yet. */
        return tcp_write(pcb, p, len, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE);
    }
    
    err_t send_list(struct tcp_pcb *pcb, const u32_t data[], u16_t len)
    {
        static const char  newline[2] = { 13, 10 }; /* ASCII \r\n */
        err_t              result;
    
        if (len > 0) {
            u16_t  i;
    
            /* The first number has no prefix. */
            result = tcp_write_u32_string(pcb, 0, data[0]);
            if (result != ERR_OK)
                return result;
    
            /* The following numbers have a comma prefix. */
            for (i = 1; i < len; i++) {
                /* ASCII comma is code 44. (Use 32 for space, or 9 for tab.) */
                result = tcp_write_u32_string(pcb, 44, data[i]);
                if (result != ERR_OK)
                    return result;
            }
        }
    
        /* We add a final newline.
           Note that this one can be referenced,
           and it does complete what we wanted to send thus far. */
        result = tcp_write(pcb, newline, 2, 0);
        if (result)
            return result;
    
        /* and flush the buffer, so the packet gets sent right now. */
        return tcp_output(pcb);
    }
    
    
    err_t application_connection(void *arg, struct tcp_pcb *conn, err_t err)
    {
    	struct netif *echo_netif = arg; /* Because of tcp_arg(, netif). */
        u32_t         data[DAQ_FIFO_DEPTH];
        u32_t         i, n;
    
        /* Drop the connection if there was an error. */
        if (err != ERR_OK) {
            tcp_abort(conn);
            return ERR_ABRT;
        }
    
        /* Setup the data aquisition. */
        err = daq_setup();
        if (err != ERR_OK) {
            tcp_abort(conn);
            return ERR_ABRT;
        }
    
        /* Data acquisition to TCP loop. */
        while (1) {
    
            /* Keep the networking stack running. */
            xemacif_input(echo_netif);
            tcp_tmr();
    
            /* Tell the networking stack to output what it can. */
            tcp_output(conn);
    
            /* Acquire up to DAQ_FIFO_DEPTH samples. */
            n = daq_acquire(data, DAQ_FIFO_DEPTH);
            if (n > DAQ_FIFO_DEPTH)
                break;
    
            /* Write data as-is to the tcp buffer. */
            if (tcp_write(conn, data, n * sizeof data[0], TCP_WRITE_FLAG_COPY) != ERR_OK)
                break;
        }
    
        /* Stop data acquisition. */
       // daq_close();
    
        /* Close the TCP connection. */
        if (tcp_close(conn) == ERR_OK)
            return ERR_OK;
    
        /* Close failed. Abort it, then. */
        tcp_abort(conn);
        return ERR_ABRT;
    }
    
    
    int start_application()
    {
    	struct tcp_pcb *pcb;
    	err_t err;
    	unsigned port = 7;
    
    	/* create new TCP PCB structure */
    	pcb = tcp_new();
    	if (!pcb) {
    		xil_printf("Error creating PCB. Out of Memory\n\r");
    		return -1;
    	}
    
    	/* bind to specified @port */
    	err = tcp_bind(pcb, IP_ADDR_ANY, port);
    	if (err != ERR_OK) {
    		xil_printf("Unable to bind to port %d: err = %d\n\r", port, err);
    		return -2;
    	}
    
    	/* we do not need any arguments to callback functions */
    	tcp_arg(pcb, NULL);
    
    	/* listen for connections */
    	pcb = tcp_listen(pcb);
    	if (!pcb) {
    		xil_printf("Out of memory while tcp_listen\n\r");
    		return -3;
    	}
    
    	/* specify callback to use for incoming connections */
    	tcp_accept(pcb, application_connection);
    
    	xil_printf("TCP echo server started @ port %d\n\r", port);
    
    	return 0;
    }
    Click image for larger version. 

Name:	Hercules.JPG 
Views:	2 
Size:	211.2 KB 
ID:	149756



  7. #7
    Advanced Member level 3
    Points: 7,037, Level: 19

    Join Date
    Jan 2015
    Posts
    985
    Helped
    312 / 312
    Points
    7,037
    Level
    19

    Re: itoa Function in C: How to read all DestinationBuffer values (int) into String Fo

    I'm lost - are you still talking about the 'buf' in the 'itoa' function being of size 32?
    What does that have to do with the size of the TCP packet which I take it you want to set to 1024?
    Once you convert the integer to a string using 'itoa' then you need to copy that string into whatever buffer you want to send via TCP along with whatever else goes into the packet.
    Also, if you have control of how the other end of the TCP connection is coded, why convert it to a string - just send it as a binary value in the TCP packet.
    Susan



--[[ ]]--