⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socket.c

📁 FreeRTOSV4.1.0 安裝文件 FreeRTOS 是一个源码公开的免费的嵌入式实时操作系统
💻 C
📖 第 1 页 / 共 4 页
字号:
*
* Description : Called by the send() function for TCP transmission.
*    It first calculates the free transmit buffer size
*    and compares it with the size of the data to be transmitted to determine the transmission size.
*    After calculating the data size, it copies data from TX_WR_PTR.
*    It waits if there is a previous send command in process.
*    When the send command is cleared, it updates the TX_WR_PTR up to the size to be transmitted
     and performs the send command.
* Arguments   : s   - channel number
*               buf - Pointer pointing data to send
*               len - data size to send
* Returns     : Succeeded: sent data size, Failed: -1
* Note        : Internal Function
****************************************************************************************************
*/
int send_in(SOCKET s, u_char far * buf, u_int len)
{
u_char k;
u_int size;
union un_l2cval wr_ptr, ack_ptr;
unsigned int offset;

S_START:
disable();            // CT: Shadow register access should not conflict with ISR.
k = READ_VALUE(SHADOW_TXWR_PTR(s));
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
delay0(2);
wr_ptr.cVal[3] = READ_VALUE(TX_WR_PTR(s));
wr_ptr.cVal[2] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(1));
wr_ptr.cVal[1] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(2));
wr_ptr.cVal[0] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(3));

k = READ_VALUE(SHADOW_TXACK_PTR(s));
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
delay0(2);
ack_ptr.cVal[3] = READ_VALUE(TX_ACK_PTR(s));
ack_ptr.cVal[2] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(1));
ack_ptr.cVal[1] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(2));
ack_ptr.cVal[0] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(3));
enable();

// Suppress compiler errors that k is not used
k = k;

//  Calculate send free buffer size
if (wr_ptr.lVal >= ack_ptr.lVal)
  size = (u_int)(SSIZE[s] - (wr_ptr.lVal - ack_ptr.lVal));
else
  size = (u_int)(SSIZE[s] - (0 - ack_ptr.lVal + wr_ptr.lVal));

// Recalulate after some delay because of error in pointer calculation
if (size > SSIZE[s])
  {
  if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED)
    return -1;
  delay_ms(1);
	 goto S_START;
  }

// Wait when previous sending has not finished yet and there's no free buffer
if (size == 0)
  {
  if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED)
    return -1;

  delay_ms(1);
  goto S_START;
  }
else if (size < len)
  {
  len = size;
  }

//  Calculate pointer to data copy
offset = (UINT)(wr_ptr.lVal & SMASK[s]);

// copy data
write_data(s, buf, offset, len);

while (READ_VALUE(COMMAND(s)) & CSEND)
  {
  // Confirm previous send command
  if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED)
    return -1;
  }

//  update tx_wr_ptr
wr_ptr.lVal = wr_ptr.lVal + len;
WRITE_VALUE(TX_WR_PTR(s), wr_ptr.cVal[3]);
WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(1), wr_ptr.cVal[2]);
WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(2), wr_ptr.cVal[1]);
WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(3), wr_ptr.cVal[0]);

delay0(1);

// SEND
WRITE_VALUE(COMMAND(s), CSEND);

return(len);
}

/*
****************************************************************************************************
*              TCP data receiving function.
*
* Description : This function is to clear out any received TCP data.
* Arguments   : s   - channel number
* Returns     : None
* Note        : API Fcuntion
****************************************************************************************************
*/
void recv_clear(SOCKET s)
{
u_char k;
u_int size;
union un_l2cval wr_ptr, rd_ptr;

disable();
k = READ_VALUE(SHADOW_RXWR_PTR(s));
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
delay0(2);
wr_ptr.cVal[3] = READ_VALUE(RX_WR_PTR(s));
wr_ptr.cVal[2] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(1));
wr_ptr.cVal[1] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(2));
wr_ptr.cVal[0] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(3));

k = READ_VALUE(SHADOW_RXRD_PTR(s));
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
delay0(2);
rd_ptr.cVal[3] = READ_VALUE(RX_RD_PTR(s));
rd_ptr.cVal[2] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(1));
rd_ptr.cVal[1] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(2));
rd_ptr.cVal[0] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(3));
enable();

// Suppress compiler errors that k is not used
k = k;

//  calculate received data size
if (wr_ptr.lVal >= rd_ptr.lVal)
  size = (u_int)(wr_ptr.lVal - rd_ptr.lVal);
else
  size = (u_int)(0 - rd_ptr.lVal + wr_ptr.lVal);

// Update rx_rd_ptr
rd_ptr.lVal += size;
WRITE_VALUE(RX_RD_PTR(s), rd_ptr.cVal[3]);
WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(1), rd_ptr.cVal[2]);
WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(2), rd_ptr.cVal[1]);
WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(3), rd_ptr.cVal[0]);

// RECV
 WRITE_VALUE(COMMAND(s), CRECV);
}

/*
****************************************************************************************************
*              TCP data receiving function.
*
* Description : This function is for receiving TCP data.
*     The recv() function is an application I/F function. It will read up to len chars if there are
      enough characters in the buffer, otherwise will onl read the number of characters availiable
* Arguments   : s   - channel number
*               buf - Pointer where the data to be received is copied
*               len - Size of the data to be received
* Returns     : Succeeded: received data size, Failed: -1
* Note        : API Fcuntion
****************************************************************************************************
*/
int recv(SOCKET s, u_char far * buf, u_int len)
{
u_char k;
u_int size;
union un_l2cval wr_ptr, rd_ptr;
unsigned int offset;

// If out length is 0, then we do not need to do anything
if (len <= 0)
  return (0);

disable();
k = READ_VALUE(SHADOW_RXWR_PTR(s));
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
delay0(2);
wr_ptr.cVal[3] = READ_VALUE(RX_WR_PTR(s));
wr_ptr.cVal[2] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(1));
wr_ptr.cVal[1] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(2));
wr_ptr.cVal[0] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(3));

k = READ_VALUE(SHADOW_RXRD_PTR(s));
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
delay0(2);
rd_ptr.cVal[3] = READ_VALUE(RX_RD_PTR(s));
rd_ptr.cVal[2] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(1));
rd_ptr.cVal[1] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(2));
rd_ptr.cVal[0] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(3));
enable();

// Suppress compiler errors that k is not used
k = k;

//  calculate IIM7010A received data size
if (wr_ptr.lVal == rd_ptr.lVal)
  return(0);
else if (wr_ptr.lVal >= rd_ptr.lVal)
  size = (u_int)(wr_ptr.lVal - rd_ptr.lVal);
else
  size = (u_int)(0 - rd_ptr.lVal + wr_ptr.lVal);

// Make sure we do not try to read more characters than what is availiable in the IIM7010 buffer
if (size < len)
  len = size;

// Calculate pointer to be copied received data
offset = ((UINT)(rd_ptr.lVal & RMASK[s]));

// Copy received data
size = read_data(s, offset, buf, len);

// Update rx_rd_ptr
rd_ptr.lVal += size;
WRITE_VALUE(RX_RD_PTR(s), rd_ptr.cVal[3]);
WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(1), rd_ptr.cVal[2]);
WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(2), rd_ptr.cVal[1]);
WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(3), rd_ptr.cVal[0]);

// RECV
 WRITE_VALUE(COMMAND(s), CRECV);
return(size);
}


/*
****************************************************************************************************
*               UDP data sending function.
*
* Description : Composed of the sendto()and sendto_in() functions.
*    The send() function is an application I/F function.
*    It continues to call the send_in() function to complete the sending of the data up to the
*    size of the data to be sent
*    when the application is called.Unlike TCP transmission, it designates the destination address
*    and the port.
* Arguments   : s    - channel port
*               buf  - Pointer pointing data to send
*               len  - data size to send
*               addr - destination IP address to send data
*               port - destination port number to send data
* Returns     : Sent data size
* Note        : API Function
****************************************************************************************************
*/
u_int sendto(SOCKET s, u_char far * buf, u_int len, u_char * addr, u_int port)
{
//char val;
u_int ptr, size;

// Wait until previous send commnad has completed.
while(READ_VALUE(COMMAND(s)) & CSEND)
  {
  if(select(s, SEL_CONTROL) == SOCK_CLOSED)
    return -1;	// Error.
  }

// Designate destination port number.
if (port != 0)
  {
  WRITE_VALUE(DST_PORT_PTR(s), (u_char)((port & 0xff00) >> 8));
  WRITE_VALUE(DST_PORT_PTR(s) + SA_OFFSET(1), (u_char)(port & 0x00ff));
  }

//  Designate destination IP address
WRITE_VALUE(DST_IP_PTR(s), addr[0]);
WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(1), addr[1]);
WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(2), addr[2]);
WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(3), addr[3]);

if (len <= 0)
  return (0);
else
  {
  ptr = 0;
  do
    {
	 size = sendto_in(s, buf + ptr, len);
	 len = len - size;
	 ptr += size;
	 } while ( len > 0);
  }
return ptr;
}

/*
****************************************************************************************************
*            UDP data sending function.
*
* Description : An internal function that is the same as the send_in() function of the TCP.
* Arguments   : s   - Channel number
*               buf - Pointer indicating the data to send
*               len - data size to send
* Returns     : Sent data size
* Note        : Internal Function
****************************************************************************************************
*/
u_int sendto_in(SOCKET s, u_char far * buf, u_int len)
{
u_char k;
u_int size;
union un_l2cval wr_ptr, rd_ptr;
unsigned int offset;

S2_START:
disable();
k = READ_VALUE(SHADOW_TXWR_PTR(s));
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
delay0(2);
wr_ptr.cVal[3] = READ_VALUE(TX_WR_PTR(s));
wr_ptr.cVal[2] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(1));
wr_ptr.cVal[1] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(2));
wr_ptr.cVal[0] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(3));

k = READ_VALUE(SHADOW_TXRD_PTR(s));
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
delay0(2);
rd_ptr.cVal[3] = READ_VALUE(TX_RD_PTR(s));
rd_ptr.cVal[2] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(1));
rd_ptr.cVal[1] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(2));
rd_ptr.cVal[0] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(3));
enable();

// Suppress compiler errors that k is not used
k = k;

//  Calculate free buffer size to send
if (wr_ptr.lVal >= rd_ptr.lVal)
  size = (u_int)(SSIZE[s] - (wr_ptr.lVal - rd_ptr.lVal));
else
  size = (u_int)(SSIZE[s] - (0 - rd_ptr.lVal + wr_ptr.lVal));

//  Recalulate after some delay because of error in pointer caluation
if (size > SSIZE[s])
  {
  delay_ms(1);
  goto S2_START;
  }

// Wait when previous sending has not finished yet and there's no free buffer
if (size == 0)
  {
  delay_ms(1);
  goto S2_START;

  }
else if (size < len)
  {
  len = size;
  }

// Calculate pointer to copy data pointer
offset =(UINT)(wr_ptr.lVal & SMASK[s]);

// copy data
write_data(s, buf, offset, len);

// Confirm previous send command
while (READ_VALUE(COMMAND(s)) & CSEND)
  {
  if(select(s, SEL_CONTROL)==SOCK_CLOSED)
    return -1;                  // Error
  }

// update tx_wr_ptr
wr_ptr.lVal = wr_ptr.lVal + len;
WRITE_VALUE(TX_WR_PTR(s), wr_ptr.cVal[3]);
WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(1), wr_ptr.cVal[2]);
WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(2), wr_ptr.cVal[1]);
WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(3), wr_ptr.cVal[0]);

delay0(1);

// SEND
WRITE_VALUE(COMMAND(s), CSEND);

return(len);
}

/*
****************************************************************************************************
*             UDP data receiving function.
*
* Description : Function for receiving UDP and IP layer RAW mode data, and handling the data header.
* Arguments   : s    - channel number
*               buf  - Pointer where the data to be received is copied
*               len  - Size of the data to be received
*               addr - Peer IP address for receiving
*               port - Peer port number for receiving
* Returns     : Received data size
* Note        : API Function
****************************************************************************************************
*/
u_int recvfrom(SOCKET s, u_char far *buf, u_int len, u_char *addr, u_int *port)
{
struct _UDPHeader									// When receiving UDP data, header added by W3100A
  {
  union
	 {
	 struct
		{
		u_int size;
		u_char addr[4];
		u_int port;
		} header;
	 u_char stream[8];
    } u;
  } UDPHeader;

u_int ret;
union un_l2cval wr_ptr, rd_ptr;
u_long size;
u_char k;
unsigned int offset;

if(select(s,SEL_CONTROL)==SOCK_CLOSED)
  return -1;

disable();
k = READ_VALUE(SHADOW_RXWR_PTR(s));
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
delay0(2);
wr_ptr.cVal[3] = READ_VALUE(RX_WR_PTR(s));
wr_ptr.cVal[2] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(1));
wr_ptr.cVal[1] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(2));
wr_ptr.cVal[0] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(3));

k = READ_VALUE(SHADOW_RXRD_PTR(s));
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
delay0(2);
rd_ptr.cVal[3] = READ_VALUE(RX_RD_PTR(s));
rd_ptr.cVal[2] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(1));
rd_ptr.cVal[1] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(2));
rd_ptr.cVal[0] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(3));
enable();

// Suppress compiler errors that k is not used
k = k;

// Calculate received data size
if (len <= 0)
  return (0);
else if (wr_ptr.lVal >= rd_ptr.lVal)
  size = wr_ptr.lVal - rd_ptr.lVal;
else
  size = 0 - rd_ptr.lVal + wr_ptr.lVal;

if (size == 0)
  return 0;

  // Calulate received data pointer
offset = ((UINT)(rd_ptr.lVal & RMASK[s]));

// When UDP data
if (( READ_VALUE(OPT_PROTOCOL(s)) & 0x07) == SOCK_DGRAM)
  {
  // Copy W3100A UDP header
  read_data(s, offset, UDPHeader.u.stream, 8);

  // Read UDP Packet size
  size = UDPHeader.u.stream[0];
  size = (size << 8) + UDPHeader.u.stream[1];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -