WIZnet Developer Forum

Non blocking use of the ioLibrary_Driver

I am using the socket interface provided by the ioLibrary_Driver in a non-blocking mode. I have a small problem which I can resolve by changing the code in the library but was wondering if there is another way to solve this.

  1. I call send to send some data via a TCP socket.
  2. I receive a SEND_OK interrupt which I use to notify the caller that the data has been sent successfully.
  3. I then clear this interrupt as I am done with it.
  4. I call send again to send more data via the same TCP socket.
  5. I get a SOCK_BUSY status returned as the sock_is_sending bit corresponding to my socket is set. This bit would be cleared during the call to send if the Sn_IR_SENDOK was set in the sn_IR register but I have already cleared this interrupt so this bit is not set.

My workaround involves a call that clear the sock_is_sending bit corresponding to my socket when the SEND_OK interrupt has happened. This requires modifying the library and I rather not do that. Is there another way?

Hello,

I don’t understand your words.
First, if you are using the socket.c file in ioLibrary, the SOCK_BUSY state is obtained in case that sock_is_sending is set and the SENDOK interrupt is not set in the Sn_IR register.
Also, our library already clears sock_is_sending if sock_is_sending is set and a SEND_OK interrupt has occurred at send time.
If I have a misunderstanding, let me tell you again.

Thankyou :smiley:

int32_t send(uint8_t sn, uint8_t * buf, uint16_t len)
{
   uint8_t tmp=0;
   uint16_t freesize=0;
   
   CHECK_SOCKNUM();
   CHECK_SOCKMODE(Sn_MR_TCP);
   CHECK_SOCKDATA();
   tmp = getSn_SR(sn);
   if(tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) return SOCKERR_SOCKSTATUS;
   if( sock_is_sending & (1<<sn) )
   {
      tmp = getSn_IR(sn);
     if(tmp & Sn_IR_SENDOK)
      {
         setSn_IR(sn, Sn_IR_SENDOK);
         //M20150401 : Typing Error
         //#if _WZICHIP_ == 5200
         #if _WIZCHIP_ == W5200
            if(getSn_TX_RD(sn) != sock_next_rd[sn])
            {
               setSn_CR(sn,Sn_CR_SEND);
               while(getSn_CR(sn));
               return SOCK_BUSY;
            }
         #endif
         sock_is_sending &= ~(1<<sn);     
      }
      else if(tmp & Sn_IR_TIMEOUT)
      {
         close(sn);
         return SOCKERR_TIMEOUT;
      }
      else return SOCK_BUSY;
   }
   freesize = getSn_TxMAX(sn);
   if (len > freesize) len = freesize; // check size not to exceed MAX size.
   while(1)
   {
      freesize = getSn_TX_FSR(sn);
      tmp = getSn_SR(sn);
      if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT))
      {
         close(sn);
         return SOCKERR_SOCKSTATUS;
      }
      if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
      if(len <= freesize) break;
   }
   wiz_send_data(sn, buf, len);
   #if _WIZCHIP_ == W5200
      sock_next_rd[sn] = getSn_TX_RD(sn) + len;
   #endif

   #if _WIZCHIP_ == W5300
      setSn_TX_WRSR(sn,len);
   #endif
   
   setSn_CR(sn,Sn_CR_SEND);
   /* wait to process the command... */
   while(getSn_CR(sn));

   sock_is_sending |= (1 << sn);
   //M20150409 : Explicit Type Casting
   //return len;
   return (int32_t)len;
}

I got the same problem.
The point is, send() clears sock_is_sending if SEND_OK occurred, ONLY SINCE THE SECOND TIME SEND() IS CALLED! There is no other way to clear sock_is_sending, unless you reopen the socket. But, SEND_OK is cleared by you before the second calling of send() so you never have the sock_is_sending cleared. If you don’t clear SEND_OK interrupt, you won’t get any more interrupt.
It seems modifying lib is the only way, if I want to use interrupt and don’t reopen the socket for each sending…
Maybe the INTLEVEL works? But for various length of data to send, it seems not very practical.
Please enlighten me if there is any other way. Thanks!

1 Like

I think @tyx interpretation is correct, and it really seems to be a bug in the library. The assumption is that we would close the socket every time, but if the socket keeps open - the whole thing just fails.

Can someone from Wiznet team respond to this and clarify if there is a solution the situation that @tyx described? @becky

Copyright © 2017 WIZnet Co., Ltd. All Rights Reserved.