#include #include #include "debug.h" #include #include #include "interface_ethernet.h" #include "eth_cfg.h" #include "lwip/timeouts.h" #include "sdrv_eth.h" #include "IAP_Task.h" //参数管理 #define MAX_BUFFER_SIZE (sizeof(((RequestContext *)0)->param_request->arr)) #define MAX_PACKET_SIZE 1024 // 定义最大包大小为1K struct udp_pcb *udpcb_1; struct udp_pcb *udpcb_2; struct udp_pcb *udpcb_3; bool eth_pool_rx = false; UnEthernetFault ethernet_fault_Info = { .bit_data.auto_count = 0, .bit_data.manual_count = 0, .bit_data.auto_state = 0, .bit_data.manual_state = 0, }; StrEthernetParameter ethernet_parameter = { .local_ip = {192,168,17,20}, .mask = {255,255,255,0}, .computer_ip = {192,168,17,3}, .local_communication_port = 8011, .Local_upper_port = 8000, .Local_download_port = 7811, .upper_ip = {192,168,17,3}, .download_ip = {192,168,17,183}, .target_upper_port = 8000, .target_download_port = 7811, .target_communication_port = 8011, }; static bool g_eth1_rx_pkt; static void eth_dma_rx_int_cb(struct net_driver_s *dev) { if (dev == &g_eth1_dev) g_eth1_rx_pkt = true; } void lwip_Ethernet(void) { // 接收ETH帧,并传递给LWIP协议栈 // 如果使能接收中断,因为ISR里会disable接收中断,因此,这里对于 // 中断接收标志(g_eth1_rx_pkt)的处理过程中不会有 // 新的接收中断被响应,所以,这里不存在原子性问题。 if ((!eth_pool_rx && g_eth1_rx_pkt) || eth_pool_rx) { g_eth1_rx_pkt = false; dwc_eth_rx(&g_eth1_dev, eth_pool_rx); } // LWIP协议栈接口,用于做LWIP超时检测 sys_check_timeouts(); // printf("lwipInterface spend time:%d\n",getCurrentTime() - time_boot);//检查app用了多长时间 } //err_t //udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port) void UdpSendToData(uint8_t udpcbID, uint8_t *buf, uint16_t len, uint8_t *sip, uint16_t port) { struct pbuf *DesPuff = NULL; ip4_addr_t Desaddr; //---------------------------------------------------------------------------------------------------- IP4_ADDR(&Desaddr,sip[0],sip[1],sip[2],sip[3]);//地址值转换 DesPuff = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_POOL); /* 申请内存 */ pbuf_take(DesPuff, buf, len); /* 将g_lwip_demo_sendbuf中的数据打包进pbuf结构中 */ if(UDPCB_1 == udpcbID) { udp_sendto(udpcb_1, DesPuff, &Desaddr, port); } else if(UDPCB_2 == udpcbID) { udp_sendto(udpcb_2, DesPuff, &Desaddr, port); } else { } pbuf_free(DesPuff); /* 释放内存 */ } // udpcbID UDP索引 //recv 回调函数 //port 绑定端口 void UDP_Echo_Init(uint8_t udpcbID, udp_recv_fn recv, uint16_t port) { //------------------------------------------ if(UDPCB_1 == udpcbID) { /* 新建一个控制块*/ udpcb_1 = udp_new(); ASSERT(udpcb_1); /* 绑定端口号 */ udp_bind(udpcb_1, IP_ADDR_ANY, port); /* 注册接收数据回调函数 */ udp_recv(udpcb_1, recv, (void *)udpcbID); } else if(UDPCB_2 == udpcbID) { /* 新建一个控制块*/ udpcb_2 = udp_new(); ASSERT(udpcb_2); /* 绑定端口号 */ udp_bind(udpcb_2, IP_ADDR_ANY, port); /* 注册接收数据回调函数 */ udp_recv(udpcb_2, recv, (void *)udpcbID); } else if(UDPCB_3 == udpcbID) { /* 新建一个控制块*/ udpcb_3 = udp_new(); ASSERT(udpcb_3); /* 绑定端口号 */ udp_bind(udpcb_3, IP_ADDR_ANY, port); /* 注册接收数据回调函数 */ udp_recv(udpcb_3, recv, (void *)udpcbID); } else { } } void udp_Callback_2(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) { uint16_t FrameHeader = 0; uint8_t *Abuf = (uint8_t *)(p->payload); // Eth_Rx_Flag = 1; FrameHeader = ( (Abuf[0] << 8) | (Abuf[1]) ); if(WDT_Refresh == FrameHeader)//喂狗 { WDTReFresh_flag = true;//接收到帧就更新 ssdk_printf(SSDK_CRIT, "WDT_Refresh:0x%x\r\n", WDTReFresh_flag); } pbuf_free(p); } void udp_Callback_1(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) { uint8_t *Abuf = (uint8_t *)(p->payload); Flash_info Bbuf = {0}; Flash_info *buf = &Bbuf; uint16_t FrameHeader = 0; //------------------------------------------------------------------------------ des_ipaddr[0] = addr->addr & 0xff; /* IADDR4 */ des_ipaddr[1] = (addr->addr >> 8) & 0xff; /* IADDR3 */ des_ipaddr[2] = (addr->addr >> 16) & 0xff; /* IADDR2 */ des_ipaddr[3] = (addr->addr >> 24) & 0xff; /* IADDR1 */ Eth_Rx_Flag ++; Flash_RxBuf_1.Download_Mode = DOWNLOAD_ETH;//以太网下载模式 for(uint16_t i = 0;i < (p->len);i++)//数据转移 { buf->dataBuffer[i] = Abuf[i]; } buf->length = p->len;//长度 FrameHeader = ( (buf->dataBuffer[0] << 8) | (buf->dataBuffer[1]) ); switch(ethCmdSTT) { case 0: if(FrameHeader == CRC_UPDATE )//CRC指令 { memcpy(&ENET_RxBuf_1.RxData[0],buf->dataBuffer,buf->length);//复制数据 flash_eth_time = 1; if( (FlashBufInitial == (Flash_RxBuf_1.Flash_RxBufSta)) || (FlashBufCRCFail == (Flash_RxBuf_1.Flash_RxBufSta)) || (FlashBufWrite == (Flash_RxBuf_1.Flash_RxBufSta)) )//初始状态,写完成,crc错误重发 { Flash_RxBuf_1.Flash_RxBufCRC = ( (buf->dataBuffer[2] << 8) | (buf->dataBuffer[3]) );//CRC Flash_RxBuf_1.Flash_RxBufLen = ( (buf->dataBuffer[5] << 16) | (buf->dataBuffer[6] << 8) | (buf->dataBuffer[7]) );//帧长度 Flash_RxBuf_1.Flash_RxBufLenNow = 0; Flash_RxBuf_1.Flash_RxBufSta = FlashBufInComplete;//切换状态 ethCmdSTT = 10; } else if( (FlashBufInitial == (Flash_RxBuf_2.Flash_RxBufSta)) || (FlashBufCRCFail == (Flash_RxBuf_2.Flash_RxBufSta)) || (FlashBufWrite == (Flash_RxBuf_2.Flash_RxBufSta)) )//初始状态,写完成,crc错误重发 { Flash_RxBuf_2.Flash_RxBufCRC = ( (buf->dataBuffer[2] << 8) | (buf->dataBuffer[3]) );//CRC Flash_RxBuf_2.Flash_RxBufLen = ( (buf->dataBuffer[5] << 16) | (buf->dataBuffer[6] << 8) | (buf->dataBuffer[7]) );//帧长度 Flash_RxBuf_2.Flash_RxBufLenNow = 0; Flash_RxBuf_2.Flash_RxBufSta = FlashBufInComplete;//切换状态 ethCmdSTT = 20; } else{} } else if(1024 == buf->length )//直接发送1K的数据,没有收到CRC就直接发送数据,认为丢帧 { ENET_RxBuf_1.RxData[0] = (uint8_t)(LOST_FRAME >> 8);//高位 手动添加ID,方便后面判断 ENET_RxBuf_1.RxData[1] = (uint8_t)(LOST_FRAME); ethCmdSTT = 0; } else//其他指令 { memcpy(&ENET_RxBuf_1.RxData[0],buf->dataBuffer,buf->length);//复制数据 ssdk_printf(SSDK_CRIT, "ENET_RxBuf[0] :0x%x, ENET_RxBuf[1]:0x%x\r\n", ENET_RxBuf_1.RxData[0],ENET_RxBuf_1.RxData[1]); ethCmdSTT = 0; } break; case 10: ENET_RxBuf_1.RxData[0] = (uint8_t)(CRC_UPDATE >> 8);//高位 手动添加ID,方便后面判断 ENET_RxBuf_1.RxData[1] = (uint8_t)(CRC_UPDATE); memcpy(&Flash_RxBuf_1.RxData[Flash_RxBuf_1.Flash_RxBufLenNow],buf->dataBuffer,buf->length);//复制数据 Flash_RxBuf_1.Flash_RxBufLenNow = (Flash_RxBuf_1.Flash_RxBufLenNow) + (buf->length); if( (Flash_RxBuf_1.Flash_RxBufLenNow) >= (Flash_RxBuf_1.Flash_RxBufLen) )//接收长度满足要求 { Flash_RxBuf_1.Flash_RxBufSta = FlashBufComplete;//切换状态 ethCmdSTT = 0; flash_eth_time = 0; } else { flash_eth_time = 1; Flash_RxBuf_1.Flash_RxBufSta = FlashBufInComplete;//切换状态 ethCmdSTT = 10; } break; case 20://缓存2 ENET_RxBuf_1.RxData[0] = (uint8_t)(CRC_UPDATE >> 8);//高位 手动添加ID,方便后面判断 ENET_RxBuf_1.RxData[1] = (uint8_t)(CRC_UPDATE); memcpy(&Flash_RxBuf_2.RxData[Flash_RxBuf_2.Flash_RxBufLenNow],buf->dataBuffer,buf->length);//复制数据 Flash_RxBuf_2.Flash_RxBufLenNow = (Flash_RxBuf_2.Flash_RxBufLenNow) + (buf->length); if( (Flash_RxBuf_2.Flash_RxBufLenNow) >= (Flash_RxBuf_2.Flash_RxBufLen) )//接收长度满足要求 { Flash_RxBuf_2.Flash_RxBufSta = FlashBufComplete;//切换状态 ethCmdSTT = 0; flash_eth_time = 0; } else { flash_eth_time = 1; Flash_RxBuf_2.Flash_RxBufSta = FlashBufInComplete;//切换状态 ethCmdSTT = 20; } break; } pbuf_free(p); } // APP模块的初始化 void ethernetInterfaceInit(void) { //----------------------------------- if (!eth_pool_rx) { // 使能DMA Rx中断。Tx未使用中断,因为ETH速率很高, // Tx中断处理耗时反而可能拖慢发送速度。 dwc_eth_enable_dma_rx_int(&g_eth1_dev, eth_dma_rx_int_cb); } }