ESP8266 Developer Zone The Official ESP8266 Forum 2017-10-19T01:37:13+08:00 https://bbs.espressif.com:443/feed.php?f=7&t=142 2017-10-19T01:37:13+08:00 2017-10-19T01:37:13+08:00 https://bbs.espressif.com:443/viewtopic.php?t=142&p=16508#p16508 <![CDATA[Re: vsprintf, vsnprintf]]> Statistics: Posted by smbgaiden — Thu Oct 19, 2017 1:37 am


]]>
2017-10-18T14:01:22+08:00 2017-10-18T14:01:22+08:00 https://bbs.espressif.com:443/viewtopic.php?t=142&p=16497#p16497 <![CDATA[Re: vsprintf, vsnprintf]]>
smbgaiden wrote:
I have nonOS SDK 2.1 with the xtensa includes from https://github.com/esp8266/esp8266-wiki ... nclude.tgz and using the crosstool-NG

You should be able to find stdarg.h in the crosstool-NG build directory: xtensa-lx106-elf/lib/gcc/xtensa-lx106-elf/4.8.5/include/stdarg.h

Statistics: Posted by jcmvbkbc — Wed Oct 18, 2017 2:01 pm


]]>
2017-10-18T08:23:08+08:00 2017-10-18T08:23:08+08:00 https://bbs.espressif.com:443/viewtopic.php?t=142&p=16495#p16495 <![CDATA[Re: vsprintf, vsnprintf]]>
I have nonOS SDK 2.1 with the xtensa includes from https://github.com/esp8266/esp8266-wiki ... nclude.tgz and using the crosstool-NG from jcmvbkbc. None of these produces a stdarg.h file to define va_list, va_start, va_arg, or va_end. Searching for espmissingincludes.h and downloading it I am able to find signatures for the ets_vsprintf function, but it includes stdarg.h also and lacks the file.

I don't have \VC\crt\src\vadefs.h as Peter does, but it seems that's likely no the right one to include.

Usually I can overcome the ambiguities on va_list in a similar manner to Peter by indexing to the correct stack location. Reading the Xtensa doc I see they do either stack based call0 or they do windowed registers. That's an area I don't know how to overcome to realise va_list and va_start.

Any pointers to replicate Peter's success are appreciated.

Statistics: Posted by smbgaiden — Wed Oct 18, 2017 8:23 am


]]>
2015-01-21T06:29:28+08:00 2015-01-21T06:29:28+08:00 https://bbs.espressif.com:443/viewtopic.php?t=142&p=525#p525 <![CDATA[Re: vsprintf, vsnprintf]]>

Code:

//send formatted output to send buffer
sint8 ICACHE_FLASH_ATTR  espbuffsentprintf(serverConnData *conn, const char *format, ...) {
   uint16 len;
   va_list al;
   va_start(al, format);
   len = ets_vsnprintf(conn->txbuffer + conn->txbufferlen, MAX_TXBUFFER - conn->txbufferlen - 1, format, al);
   va_end(al);
   if (len <0)  {
      os_printf("espbuffsentprintf: txbuffer full on conn %p\n", conn);
      return len;
   }
   conn->txbufferlen += len;
   if (conn->readytosend)
      return sendtxbuffer(conn);
   return ESPCONN_OK;
}

Statistics: Posted by Peter — Wed Jan 21, 2015 6:29 am


]]>
2015-01-21T05:55:07+08:00 2015-01-21T05:55:07+08:00 https://bbs.espressif.com:443/viewtopic.php?t=142&p=524#p524 <![CDATA[Re: vsprintf, vsnprintf]]> in espmissingincludes.h

Code:

#include <stdarg.h>
int ets_vsprintf(char *str, const char *format, va_list argptr);
int ets_vsnprintf(char *buffer, size_t sizeOfBuffer,  const char *format, va_list argptr);

Code:

//send formatted output through espbuffsent
sint8 ICACHE_FLASH_ATTR  espbuffsentprintf(serverConnData *conn, const char *format, ...) {
#define MaxBuff 1024
   char buffer[MaxBuff]; uint16 len;
   va_list al;
   va_start(al, format);
   len = ets_vsnprintf(buffer, MaxBuff-1, format, al);
   va_end(al);
   if (len >= 0)
      return espbuffsent(conn, buffer, len);
   else
      return len;
}


It is for buffered send, waiting on serverSentCb befor call next espconn_sent . The other code work fine:

Code:

static char txbuffer[MAX_CONN][MAX_TXBUFFER];
serverConnData connData[MAX_CONN];

//send all data in conn->txbuffer
//returns result from espconn_sent if data in buffer or ESPCONN_OK (0)
//only internal used by espbuffsent, serverSentCb
static sint8  ICACHE_FLASH_ATTR sendtxbuffer(serverConnData *conn) {
   sint8 result = ESPCONN_OK;
   if (conn->txbufferlen != 0)   {
      conn->readytosend = false;
      result= espconn_sent(conn->conn, (uint8_t*)conn->txbuffer, conn->txbufferlen);
      conn->txbufferlen = 0;   
      if (result != ESPCONN_OK)
         os_printf("sendtxbuffer: espconn_sent error %d on conn %p\n", result, conn);
   }
   return result;
}


//send string through espbuffsent
sint8 ICACHE_FLASH_ATTR espbuffsentstring(serverConnData *conn, const char *data) {
   return espbuffsent(conn, data, strlen(data));
}

//use espbuffsent instead of espconn_sent
//It solve problem: the next espconn_sent must after espconn_sent_callback of the pre-packet.
//Add data to the send buffer and send if previous send was completed it call sendtxbuffer and  espconn_sent
//Returns ESPCONN_OK (0) for success, -128 if buffer is full or error from  espconn_sent
sint8 ICACHE_FLASH_ATTR espbuffsent(serverConnData *conn, const char *data, uint16 len) {
   if (conn->txbufferlen + len > MAX_TXBUFFER) {
      os_printf("espbuffsent: txbuffer full on conn %p\n", conn);
      return -128;
   }
   os_memcpy(conn->txbuffer + conn->txbufferlen, data, len);
   conn->txbufferlen += len;
   if (conn->readytosend)
      return sendtxbuffer(conn);
   return ESPCONN_OK;
}
//callback after the data are sent
static void ICACHE_FLASH_ATTR serverSentCb(void *arg) {
   serverConnData *conn = serverFindConnData(arg);
   //os_printf("Sent callback on conn %p\n", conn);
   if (conn==NULL) return;
   conn->readytosend = true;
   sendtxbuffer(conn); // send possible new data in txbuffer
}

void ICACHE_FLASH_ATTR serverInit(int port) {
   int i;
   for (i = 0; i < MAX_CONN; i++) {
      connData[i].conn = NULL;
      connData[i].txbuffer = txbuffer[i];
      connData[i].txbufferlen = 0;
      connData[i].readytosend = true;
   }
   serverConn.type=ESPCONN_TCP;
   serverConn.state=ESPCONN_NONE;
   serverTcp.local_port=port;
   serverConn.proto.tcp=&serverTcp;

   espconn_regist_connectcb(&serverConn, serverConnectCb);
   espconn_accept(&serverConn);
   espconn_regist_time(&serverConn, SERVER_TIMEOUT, 0);
}



with
#define MAX_TXBUFFER 1024
struct serverConnData {
        struct espconn *conn;
      char *txbuffer; //the buffer for the data to send
      uint16  txbufferlen; //the length  of data in txbuffer
       bool readytosend; //true, if txbuffer can send by espconn_sent
};



Statistics: Posted by Peter — Wed Jan 21, 2015 5:55 am


]]>
2015-01-20T19:53:40+08:00 2015-01-20T19:53:40+08:00 https://bbs.espressif.com:443/viewtopic.php?t=142&p=522#p522 <![CDATA[Re: vsprintf, vsnprintf]]>
Peter wrote:
yes, but there is no va_list defined. And in \VC\crt\src\vadefs.h I find
typedef char * va_list;

I'm not sure what VC you're referring to. This type is defined in headers that come with the compiler and it's very architecture-specific.
On xtensa calling va_start is absolutely necessary for the correctness of va_list operation. Use #include <stdarg.h> to get its definition.

Statistics: Posted by jcmvbkbc — Tue Jan 20, 2015 7:53 pm


]]>
2015-01-20T16:06:36+08:00 2015-01-20T16:06:36+08:00 https://bbs.espressif.com:443/viewtopic.php?t=142&p=521#p521 <![CDATA[Re: vsprintf, vsnprintf]]> typedef char * va_list;
So I tried also not successful

Code:

typedef char *  va_list;
int ets_vsprintf(char *str, const char *format, va_list argptr);
int ets_vsnprintf(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, va_list argptr);

How is the definition of ets_vsprintf and ets_vsnprintf ?

Statistics: Posted by Peter — Tue Jan 20, 2015 4:06 pm


]]>
2015-01-20T11:27:02+08:00 2015-01-20T11:27:02+08:00 https://bbs.espressif.com:443/viewtopic.php?t=142&p=518#p518 <![CDATA[Re: vsprintf, vsnprintf]]>
Peter wrote:
Hi,
I need the functions vsprintf or vsnprintf . In libmain.a are defined: ets_vsprintf, ets_vsnprintf. I tried to call with the standard signature:
int ets_vsprintf(char *str, const char *format, char * argptr);
int ets_vsnprintf(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, char * argptr);

These signatures don't look standard. The 'v' letter means that the function expects va_list parameter, so they should look like
int ets_vsprintf(char *str, const char *format, va_list arg);
int ets_vsnprintf(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, va_list arg);

Peter wrote:
I want use it in

Code:

sint8 ICACHE_FLASH_ATTR  espconn_printf(serverConnData *conn, const char *format, ...) {
#define MaxBuff 256
   char buffer[MaxBuff]; uint16 len;
   len = ets_vsprintf(buffer, format, (char *) ((&format)+1));
//or
   len = ets_vsnprintf(buffer, MaxBuff, MaxBuff-1, format, (char *) ((&format)+1));

...
later: write to buffer and call espconn_sent after serverSentCb.

But both call crashed: Fatal exception (28) with reboot.

How can I use ets_vsprintf , ets_vsnprintf ?

Try

Code:

sint8 ICACHE_FLASH_ATTR  espconn_printf(serverConnData *conn, const char *format, ...) {
#define MaxBuff 256
   char buffer[MaxBuff]; uint16 len;
   va_list al;
   va_start(al, format);
   len = ets_vsprintf(buffer, format, al);
   va_end(al);

Statistics: Posted by jcmvbkbc — Tue Jan 20, 2015 11:27 am


]]>
2015-01-20T11:04:20+08:00 2015-01-20T11:04:20+08:00 https://bbs.espressif.com:443/viewtopic.php?t=142&p=517#p517 <![CDATA[vsprintf, vsnprintf]]> I need the functions vsprintf or vsnprintf . In libmain.a are defined: ets_vsprintf, ets_vsnprintf. I tried to call with the standard signature:
int ets_vsprintf(char *str, const char *format, char * argptr);
int ets_vsnprintf(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, char * argptr);

I want use it in

Code:

sint8 ICACHE_FLASH_ATTR  espconn_printf(serverConnData *conn, const char *format, ...) {
#define MaxBuff 256
   char buffer[MaxBuff]; uint16 len;
   len = ets_vsprintf(buffer, format, (char *) ((&format)+1));
//or
   len = ets_vsnprintf(buffer, MaxBuff, MaxBuff-1, format, (char *) ((&format)+1));

...
later: write to buffer and call espconn_sent after serverSentCb.

But both call crashed: Fatal exception (28) with reboot.

How can I use ets_vsprintf , ets_vsnprintf ?

Peter

Statistics: Posted by Peter — Tue Jan 20, 2015 11:04 am


]]>