#ifndefSTM32_VET6_SOCKET_H#defineSTM32_VET6_SOCKET_H#include"w5500_config.h"// Opens a socket(TCP or UDP or IP_RAW mode)externuint8_tsocket(SOCKET s,uint8_t protocol,uint16_t port,uint8_t flag);// Close socketexternvoidclose(SOCKET s);// Establish TCP connection (Active connection)externuint8_tconnect(SOCKET s,uint8_t*addr,uint16_t port);externvoiddisconnect(SOCKET s);externuint8_tlisten(SOCKET s);// Send data (TCP)externuint16_tsend(SOCKET s,constuint8_t*buf,uint16_t len);// Receive data (TCP)externuint16_trecv(SOCKET s,uint8_t*buf,uint16_t len);// Send data (UDP/IP RAW)externuint16_tsendto(SOCKET s,constuint8_t*buf,uint16_t len,uint8_t*addr,uint16_t port);// Receive data (UDP/IP RAW)externuint16_trecvfrom(SOCKET s,uint8_t*buf,uint16_t len,uint8_t*addr,uint16_t*port);externvoidclearSocketFlag(SOCKET s);
sys_force_static_inline uint8_tsocket_status(SOCKET s){returnw5500_status_read(s);}
bool udp_socket_init(SOCKET s,uint16_t local_port);
bool udp_send(SOCKET s,uint8_t*dst_ip,uint16_t dst_port,uint8_t*data,uint16_t len);
bool udp_rec(SOCKET s,uint16_t listen_port,uint8_t*dstIp,uint16_t*dstPort,uint8_t*recData,uint16_t*recLen);voidtcp_client_connect(SOCKET s,uint8_t*dst_ip,uint16_t dst_port);
bool tcp_client_send(SOCKET s,uint8_t*data,uint16_t len);uint16_ttcp_client_rec(SOCKET s,uint8_t*out_data);/******************************************TCP SERVER 端********************************************//**
* @brief 服务端初始化
* @param s
* @param listen_port 监听端口
* @param netData 数据区域
*/voidtcp_server_init(SOCKET s,uint16_t listen_port,w5500_buf_t*netData);/**
* @brief 监听socket
* @param s
* @return
*/w5500_buf_t*tcp_server_listen(SOCKET s);/*响应字节数组数据*/
sys_force_static_inline voidtcp_server_resp(SOCKET s,uint8_t*data,uint16_t len){sys_assert_void(data !=NULL);send(s, data, len);}#endif//STM32_VET6_SOCKET_H
源文件
#include"socket.h"#defineDBG_ENABLE#defineDBG_SECTION_NAME"socket-module"#defineDBG_LEVELDBG_WARNING#include"sys_dbg.h"uint16_t udp_local_port = UDP_CLIENT_PORT;uint16_t tcp_local_port = TCP_CLIENT_PORT;uint16_t socket_port[8];w5500_buf_t*socket_net_data[8];#definew5500_tx_max_size(i)(module_w5500_read()->base_conf.tx_size[i]*1024)/****************************************************************
* @Date: 2022-08-27 13:39:17
* @Funticon name: 清除socket 中断标志位
* @Berif:
* @Author: scl
* @Note:
* @param {SOCKET} s
* @return {*}
******************************************************************/voidclearSocketFlag(SOCKET s){uint8_t stat =w5500_socket_it_status_read(s);if(stat & Sn_IR_CON)// tcp{w5500_reg_socket_it_set(s, Sn_IR_CON);/*清除接收中断标志位*/return;}if(stat & Sn_IR_RECV){w5500_reg_socket_it_set(s, Sn_IR_RECV);/*清接收中断*/return;}}/**
*@brief This Socket function initialize the channel in perticular mode,
and set the port and wait for W5200 done it.
*@param s: socket number.
*@param protocol: The socket to chose.
*@param port:The port to bind.
*@param flag: Set some bit of MR,such as **< No Delayed Ack(TCP) flag.
*@return 1 for sucess else 0.
*/uint8_tsocket(SOCKET s,uint8_t protocol,uint16_t port,uint8_t flag){uint8_t ret;if(((protocol &0x0F)== Sn_MR_TCP)||((protocol &0x0F)== Sn_MR_UDP)||((protocol &0x0F)== Sn_MR_IPRAW)||((protocol &0x0F)== Sn_MR_MACRAW)||((protocol &0x0F)== Sn_MR_PPPOE)){close(s);w5500_write(Sn_MR(s), protocol | flag);w5500_write(Sn_PORT0(s),(uint8_t)((port &0xff00)>>8));w5500_write(Sn_PORT1(s),(uint8_t)(port &0x00ff));w5500_write(Sn_CR(s), Sn_CR_OPEN);// run sockinit Sn_CR/* wait to process the command... */while(w5500_read(Sn_CR(s)));/* ------- */
ret =1;}else{
ret =0;}return ret;}/**
*@brief This function close the socket and parameter is "s" which represent
*the socket number
*@param s: socket number.
*@return None
*/voidclose(SOCKET s){w5500_write(Sn_CR(s), Sn_CR_CLOSE);/* 验证配置是否成功 */while(w5500_read(Sn_CR(s)));/* all clear */w5500_write(Sn_IR(s),0xFF);}/**
*@brief This function established the connection for the channel in passive
(server) mode. This function waits for the request from the peer.
*@param s: socket number.
*@return 1 for success else 0.
*/uint8_tlisten(SOCKET s){uint8_t ret;if(w5500_read(Sn_SR(s))== s_init){w5500_write(Sn_CR(s), Sn_CR_LISTEN);/* wait to process the command... */while(w5500_read(Sn_CR(s)));/* ------- */
ret =1;}else{
ret =0;}return ret;}/**
*@brief This function established the connection for the channel in
Active (client) mode. This function waits for the untill the connection is
established.
*@param s: socket number.
*@param addr: The server IP address to connect
*@param port: The server IP port to connect
*@return 1 for success else 0.
*/uint8_tconnect(SOCKET s,uint8_t*addr,uint16_t port){uint8_t ret;if(((addr[0]==0xFF)&&(addr[1]==0xFF)&&(addr[2]==0xFF)&&(addr[3]==0xFF))||((addr[0]==0x00)&&(addr[1]==0x00)&&(addr[2]==0x00)&&(addr[3]==0x00))||(port ==0x00)){
ret =0;}else{
ret =1;// set destination IPw5500_write(Sn_DIPR0(s), addr[0]);w5500_write(Sn_DIPR1(s), addr[1]);w5500_write(Sn_DIPR2(s), addr[2]);w5500_write(Sn_DIPR3(s), addr[3]);w5500_write(Sn_DPORT0(s),(uint8_t)((port &0xff00)>>8));w5500_write(Sn_DPORT1(s),(uint8_t)(port &0x00ff));w5500_write(Sn_CR(s), Sn_CR_CONNECT);/* wait for completion */while(w5500_read(Sn_CR(s)));while(w5500_read(Sn_SR(s))!= s_syn_sent){if(w5500_read(Sn_SR(s))== s_established){break;}if(w5500_socket_it_status_read(s)& Sn_IR_TIMEOUT){w5500_write(Sn_IR(s),(Sn_IR_TIMEOUT));// clear TIMEOUT Interrupt
ret =0;break;}if(w5500_socket_it_status_read(s)& Sn_IR_DISCON){// clear dis connect Interruptdisconnect(s);
ret =0;break;}}}return ret;}/**
*@brief This function used for disconnect the socket s
*@param s: socket number.
*@return 1 for success else 0.
*/voiddisconnect(SOCKET s){w5500_write(Sn_CR(s), Sn_CR_DISCON);/* wait to process the command... */while(w5500_read(Sn_CR(s)));/* ------- */}/**
*@brief This function used to send the data in TCP mode
*@param s: socket number.
*@param buf: data buffer to send.
*@param len: data length.
*@return 1 for success else 0.
*/uint16_tsend(SOCKET s,constuint8_t*buf,uint16_t len){uint8_t status =0;uint16_t ret =0;uint16_t freesize =0;if(len >w5500_tx_max_size(s))
ret =w5500_tx_max_size(s);// check size not to exceed MAX size.else
ret = len;// if freebuf is available, start.do{
freesize =w5500_socket_tx_size_read(s);
status =w5500_read(Sn_SR(s));if((status != s_established)&&(status != s_close_wait)){
ret =0;break;}}while(freesize < ret);// copy dataw5500_send_data_processing(s,(uint8_t*) buf, ret);w5500_write(Sn_CR(s), Sn_CR_SEND);/* wait to process the command... */while(w5500_read(Sn_CR(s)));while((w5500_read(Sn_IR(s))& Sn_IR_SEND_OK)!= Sn_IR_SEND_OK){
status =w5500_read(Sn_SR(s));if((status != s_established)&&(status != s_close_wait)){// printf("SEND_OK Problem!!\r\n");close(s);return0;}}w5500_write(Sn_IR(s), Sn_IR_SEND_OK);#ifdef__DEF_IINCHIP_INT__putISR(s,getISR(s)&(~Sn_IR_SEND_OK));#elsew5500_write(Sn_IR(s), Sn_IR_SEND_OK);#endifreturn ret;}/**
*@brief This function is an application I/F function which is used to
receive the data in TCP mode. It continues to wait for data as much as the
application wants to receive.
*@param s: socket number.
*@param buf: data buffer to receive.
*@param len: data length.
*@return received data size for success else 0.
*/uint16_trecv(SOCKET s,uint8_t*buf,uint16_t len){uint16_t ret =0;if(len >0){w5500_recv_data_processing(s, buf, len);w5500_write(Sn_CR(s), Sn_CR_RECV);/* wait to process the command... */while(w5500_read(Sn_CR(s)));/* ------- */
ret = len;}return ret;}/**
*@brief This function is an application I/F function which is used to send the
data for other then TCP mode. Unlike TCP transmission, The peer's destination
address and the port is needed.
*@param s: socket number.
*@param buf: data buffer to send.
*@param len: data length.
*@param addr: IP address to send.
*@param port: IP port to send.
*@return This function return send data size for success else 0.
*/uint16_tsendto(SOCKET s,constuint8_t*buf,uint16_t len,uint8_t*addr,uint16_t port){uint16_t ret =0;if(len >w5500_tx_max_size(s))
ret =w5500_tx_max_size(s);// check size not to exceed MAX size.else
ret = len;if(((addr[0]==0x00)&&(addr[1]==0x00)&&(addr[2]==0x00)&&(addr[3]==0x00))||((port ==0x00)))//||(ret == 0) ){/* added return value */
ret =0;}else{w5500_write(Sn_DIPR0(s), addr[0]);w5500_write(Sn_DIPR1(s), addr[1]);w5500_write(Sn_DIPR2(s), addr[2]);w5500_write(Sn_DIPR3(s), addr[3]);w5500_write(Sn_DPORT0(s),(uint8_t)((port &0xff00)>>8));w5500_write(Sn_DPORT1(s),(uint8_t)(port &0x00ff));// copy dataw5500_send_data_processing(s,(uint8_t*) buf, ret);w5500_write(Sn_CR(s), Sn_CR_SEND);/* wait to process the command... */while(w5500_read(Sn_CR(s)));/* ------- */while((w5500_read(Sn_IR(s))& Sn_IR_SEND_OK)!= Sn_IR_SEND_OK){if(w5500_read(Sn_IR(s))& Sn_IR_TIMEOUT){/* clear interrupt */w5500_write(Sn_IR(s),(Sn_IR_SEND_OK | Sn_IR_TIMEOUT));/* clear SEND_OK & TIMEOUT */return0;}}w5500_write(Sn_IR(s), Sn_IR_SEND_OK);}return ret;}/**
*@brief This function is an application I/F function which is used to receive
the data in other then TCP mode. This function is used to receive UDP, IP_RAW
and MAC_RAW mode, and handle the header as well.
*@param s: socket number.
*@param buf: data buffer to receive.
*@param len: data length.
*@param addr: IP address to receive.
*@param port: IP port to receive.
*@return This function return received data size for success else 0.
*/uint16_trecvfrom(SOCKET s,uint8_t*buf,uint16_t len,uint8_t*addr,uint16_t*port){uint8_t head[8];uint16_t data_len =0;uint16_t ptr =0;uint32_t addrbsb =0;if(len >0){
ptr =w5500_read(Sn_RX_RD0(s));
ptr =((ptr &0x00ff)<<8)+w5500_read(Sn_RX_RD1(s));
addrbsb =(uint32_t)(ptr <<8)+(s <<5)+0x18;switch(w5500_read(Sn_MR(s))&0x07){case Sn_MR_UDP:w5500_reads(addrbsb, head,0x08);
ptr +=8;// read peer's IP address, port number.
addr[0]= head[0];
addr[1]= head[1];
addr[2]= head[2];
addr[3]= head[3];*port = head[4];*port =(*port <<8)+ head[5];
data_len = head[6];
data_len =(data_len <<8)+ head[7];
addrbsb =(uint32_t)(ptr <<8)+(s <<5)+0x18;w5500_reads(addrbsb, buf, data_len);
ptr += data_len;w5500_write(Sn_RX_RD0(s),(uint8_t)((ptr &0xff00)>>8));w5500_write(Sn_RX_RD1(s),(uint8_t)(ptr &0x00ff));break;case Sn_MR_IPRAW:w5500_reads(addrbsb, head,0x06);
ptr +=6;
addr[0]= head[0];
addr[1]= head[1];
addr[2]= head[2];
addr[3]= head[3];
data_len = head[4];
data_len =(data_len <<8)+ head[5];
addrbsb =(uint32_t)(ptr <<8)+(s <<5)+0x18;// printf(" data:%d \r\n",data_len);w5500_reads(addrbsb, buf, data_len);
ptr += data_len;w5500_write(Sn_RX_RD0(s),(uint8_t)((ptr &0xff00)>>8));w5500_write(Sn_RX_RD1(s),(uint8_t)(ptr &0x00ff));break;case Sn_MR_MACRAW:w5500_reads(addrbsb, head,0x02);
ptr +=2;
data_len = head[0];
data_len =(data_len <<8)+ head[1]-2;if(data_len >1514){// printf("data_len over 1514\r\n");while(1);}
addrbsb =(uint32_t)(ptr <<8)+(s <<5)+0x18;w5500_reads(addrbsb, buf, data_len);
ptr += data_len;w5500_write(Sn_RX_RD0(s),(uint8_t)((ptr &0xff00)>>8));w5500_write(Sn_RX_RD1(s),(uint8_t)(ptr &0x00ff));break;default:break;}w5500_write(Sn_CR(s), Sn_CR_RECV);/* wait to process the command... */while(w5500_read(Sn_CR(s)));/* ------- */}return data_len;}
bool udp_socket_init(SOCKET s,uint16_t local_port){
udp_local_port = local_port;socket(s, Sn_MR_UDP, udp_local_port,0);return true;}
bool udp_send(SOCKET s,uint8_t*dst_ip,uint16_t dst_port,uint8_t*data,uint16_t len){clearSocketFlag(s);/*清接收中断*/if(w5500_socket_status_read(s)!= s_udp){socket(s, Sn_MR_UDP, udp_local_port,0);}returnsendto(s, data, len, dst_ip, dst_port)== len ? true : false;}
bool udp_rec(SOCKET s,uint16_t listen_port,uint8_t*dstIp,uint16_t*dstPort,uint8_t*recData,uint16_t*recLen){uint16_t len;switch(w5500_socket_status_read(s))/*获取socket的状态*/{case s_udp:/*socket初始化完成*/clearSocketFlag(s);if((len =w5500_socket_rx_size_read(s))>0)/*接收到数据*/{recvfrom(s, recData, len, dstIp, dstPort);/*W5500接收计算机发送来的数据*/*recLen = len;
recData[len]=0x00;return true;/*添加字符串结束符*/}break;case s_closed:/*socket处于关闭状态*/default:socket(s, Sn_MR_UDP, listen_port,0);/*初始化socket*/break;}return false;}voidtcp_client_connect(SOCKET s,uint8_t*dst_ip,uint16_t dst_port){uint8_t status =w5500_socket_status_read(s);if(status == s_close_wait){disconnect(s);
status =w5500_socket_status_read(s);LOG_D("close socket");}if(status == s_closed){socket(s, Sn_MR_TCP, tcp_local_port++, Sn_MR_ND);
status =w5500_socket_status_read(s);LOG_D("build socket");}if(status == s_init){connect(s, dst_ip, dst_port);LOG_D("connect");}}
bool tcp_client_send(SOCKET s,uint8_t*data,uint16_t len){if(w5500_status_read(s)== s_established){send(s, data, len);return true;}return false;}uint16_ttcp_client_rec(SOCKET s,uint8_t*out_data){if(w5500_status_read(s)== s_established){uint16_t len =w5500_socket_rx_size_read(s);/*定义len为已接收数据的长度*/if(len >0){recv(s, out_data, len);/*接收来自Client的数据*/return len;}}return0;}/**
* @brief 初始化tcp server 接口
* @param s
* @param listen_port
* @param buf
* @param buf_len
*/voidtcp_server_init(SOCKET s,uint16_t listen_port,w5500_buf_t*netData){
socket_port[s]= listen_port;
socket_net_data[s]= netData;// 关闭上次的socketdisconnect(s);close(s);}w5500_buf_t*tcp_server_listen(SOCKET s){
socket_status_type state =w5500_status_read(s);
socket_net_data[s]->buf_len =0;switch(state){case s_closed:{socket(s, Sn_MR_TCP, socket_port[s], Sn_MR_ND);/*打开socket*/break;}case s_init:{/*socket建立监听*/listen(s);break;}case s_established:{/*与客户端建立连接*/clearSocketFlag(s);// 清除接收中断标志位uint16_t len =w5500_socket_rx_size_read(s);/*定义len为已接收数据的长度*/if(len >0){memset(socket_net_data[s]->buf,0, socket_net_data[s]->buf_len);recv(s, socket_net_data[s]->buf, len);/*接收来自Client的数据*/}else{// 检查芯片处于连接状态,但网线已断开时,自动释放端口,避免下次无法连接if((w5500_read(PHYCFGR)&0x1)==0){close(s);}}
socket_net_data[s]->buf_len = len;return socket_net_data[s];}case s_listen:{/*服务端处于监听中*/// todo 统计失去控制时间break;}case s_close_wait:{/*客户端,主动断开连接*/disconnect(s);break;}default:{disconnect(s);close(s);break;}}return socket_net_data[s];}
今天在npm run serve项目的时候遇到一个问题,终端提示TypeError: transpileDependencies.map is not a function,项目跑不起来。
网上搜到的解决办法: 网上提供的解决办法基本上是:
1.npm audit fix执行才会报这个错——没用 2.…
题目描述: 主要思路:
利用二分答案的思想进行求解。 首先遍历到最底下的最左结点,然后可以得到一个答案范围,然后二分求解验证即可。 具体细节见代码。
/*** Definition for a binary tree node.* struct TreeNode {* int v…