diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile index dbc03153b..b5bc3166b 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile @@ -1,3 +1,3 @@ -SRC_FILES := socket.c connect_w5500.c w5500.c wizchip_conf.c spi_interface.c wiz_ping.c wiz_iperf.c +SRC_FILES := socket.c connect_w5500.c w5500.c wizchip_conf.c spi_interface.c wiz_ping.c connect_w5500_test.c wiz_iperf.c include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c index d06dfaa2d..0b245b11d 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c @@ -23,47 +23,53 @@ extern void spi_select_cs(void); extern void spi_deselete_cs(void); // global configurations for w5500 tcp connection -const uint32_t g_wiznet_buf_size = 2048; +uint32_t get_gbuf_size() { + static const uint32_t g_wiznet_buf_size = 2048; + return g_wiznet_buf_size; +} -static wiz_NetInfo g_wiz_netinfo = {.mac = {0x00, 0x08, 0xdc, 0x11, 0x11, 0x11}, - .ip = {192, 168, 131, 42}, - .sn = {255, 255, 254, 0}, - .gw = {192, 168, 130, 1}, - .dns = {0, 0, 0, 0}, - .dhcp = NETINFO_STATIC}; +wiz_NetInfo *get_gnetinfo() { + static wiz_NetInfo g_wiz_netinfo = {.mac = {0x00, 0x08, 0xdc, 0x11, 0x11, 0x11}, + .ip = {192, 168, 130, 77}, + .sn = {255, 255, 254, 0}, + .gw = {192, 168, 130, 1}, + .dns = {0, 0, 0, 0}, + .dhcp = NETINFO_STATIC}; + return &g_wiz_netinfo; +} int network_init() { wiz_NetInfo check_wiz_netinfo; check_wiz_netinfo.dhcp = NETINFO_STATIC; - ctlnetwork(CN_SET_NETINFO, (void *)&g_wiz_netinfo); + ctlnetwork(CN_SET_NETINFO, (void *)get_gnetinfo()); ctlnetwork(CN_GET_NETINFO, (void *)&check_wiz_netinfo); - if (memcmp(&g_wiz_netinfo, &check_wiz_netinfo, sizeof(wiz_NetInfo)) != 0) { + if (memcmp(get_gnetinfo(), &check_wiz_netinfo, sizeof(wiz_NetInfo)) != 0) { KPrintf( "mac: %d; ip: %d; gw: %d; sn: %d; dns: %d; dhcp: %d;\n", - memcmp(&g_wiz_netinfo.mac, &check_wiz_netinfo.mac, sizeof(uint8_t) * 6), - memcmp(&g_wiz_netinfo.ip, &check_wiz_netinfo.ip, sizeof(uint8_t) * 4), - memcmp(&g_wiz_netinfo.sn, &check_wiz_netinfo.sn, sizeof(uint8_t) * 4), - memcmp(&g_wiz_netinfo.gw, &check_wiz_netinfo.gw, sizeof(uint8_t) * 4), - memcmp(&g_wiz_netinfo.dns, &check_wiz_netinfo.dns, sizeof(uint8_t) * 4), - memcmp(&g_wiz_netinfo.dhcp, &check_wiz_netinfo.dhcp, sizeof(uint8_t))); + memcmp(&get_gnetinfo()->mac, &check_wiz_netinfo.mac, sizeof(uint8_t) * 6), + memcmp(&get_gnetinfo()->ip, &check_wiz_netinfo.ip, sizeof(uint8_t) * 4), + memcmp(&get_gnetinfo()->sn, &check_wiz_netinfo.sn, sizeof(uint8_t) * 4), + memcmp(&get_gnetinfo()->gw, &check_wiz_netinfo.gw, sizeof(uint8_t) * 4), + memcmp(&get_gnetinfo()->dns, &check_wiz_netinfo.dns, sizeof(uint8_t) * 4), + memcmp(&get_gnetinfo()->dhcp, &check_wiz_netinfo.dhcp, sizeof(uint8_t))); KPrintf("WIZCHIP set network information fail.\n"); return ERROR; } uint8_t tmpstr[6]; ctlwizchip(CW_GET_ID, (void *)tmpstr); KPrintf("=== %s NET CONF ===\r\n", (char *)tmpstr); - KPrintf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", g_wiz_netinfo.mac[0], - g_wiz_netinfo.mac[1], g_wiz_netinfo.mac[2], g_wiz_netinfo.mac[3], - g_wiz_netinfo.mac[4], g_wiz_netinfo.mac[5]); - KPrintf("SIP: %d.%d.%d.%d\r\n", g_wiz_netinfo.ip[0], g_wiz_netinfo.ip[1], - g_wiz_netinfo.ip[2], g_wiz_netinfo.ip[3]); - KPrintf("GAR: %d.%d.%d.%d\r\n", g_wiz_netinfo.gw[0], g_wiz_netinfo.gw[1], - g_wiz_netinfo.gw[2], g_wiz_netinfo.gw[3]); - KPrintf("SUB: %d.%d.%d.%d\r\n", g_wiz_netinfo.sn[0], g_wiz_netinfo.sn[1], - g_wiz_netinfo.sn[2], g_wiz_netinfo.sn[3]); - KPrintf("DNS: %d.%d.%d.%d\r\n", g_wiz_netinfo.dns[0], g_wiz_netinfo.dns[1], - g_wiz_netinfo.dns[2], g_wiz_netinfo.dns[3]); + KPrintf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", get_gnetinfo()->mac[0], + get_gnetinfo()->mac[1], get_gnetinfo()->mac[2], get_gnetinfo()->mac[3], + get_gnetinfo()->mac[4], get_gnetinfo()->mac[5]); + KPrintf("SIP: %d.%d.%d.%d\r\n", get_gnetinfo()->ip[0], get_gnetinfo()->ip[1], + get_gnetinfo()->ip[2], get_gnetinfo()->ip[3]); + KPrintf("GAR: %d.%d.%d.%d\r\n", get_gnetinfo()->gw[0], get_gnetinfo()->gw[1], + get_gnetinfo()->gw[2], get_gnetinfo()->gw[3]); + KPrintf("SUB: %d.%d.%d.%d\r\n", get_gnetinfo()->sn[0], get_gnetinfo()->sn[1], + get_gnetinfo()->sn[2], get_gnetinfo()->sn[3]); + KPrintf("DNS: %d.%d.%d.%d\r\n", get_gnetinfo()->dns[0], get_gnetinfo()->dns[1], + get_gnetinfo()->dns[2], get_gnetinfo()->dns[3]); KPrintf("======================\r\n"); return EOK; @@ -255,312 +261,4 @@ int HwWiznetInit(void) { network_init(); return EOK; -} - -/****************** basic functions ********************/ - -enum TCP_OPTION { - SEND_DATA = 0, - RECV_DATA, -}; - -uint32_t wiz_client_op(uint8_t sn, uint8_t *buf, uint32_t buf_size, - uint8_t dst_ip[4], uint16_t dst_port, - enum TCP_OPTION opt) { - // assert(buf_size <= g_wiznet_buf_size); - int32_t ret; - switch (getSn_SR(sn)) { - case SOCK_CLOSE_WAIT: - wiz_sock_disconnect(sn); - break; - case SOCK_CLOSED: - wiz_socket(sn, Sn_MR_TCP, 5000, 0x00); - break; - case SOCK_INIT: - KPrintf("[SOCKET CLIENT] sock init.\n"); - wiz_sock_connect(sn, dst_ip, dst_port); - break; - case SOCK_ESTABLISHED: - if (getSn_IR(sn) & Sn_IR_CON) { - printf("[SOCKET CLIENT] %d:Connected\r\n", sn); - setSn_IR(sn, Sn_IR_CON); - } - if (opt == SEND_DATA) { - uint32_t sent_size = 0; - ret = wiz_sock_send(sn, buf, buf_size); - if (ret < 0) { - wiz_sock_close(sn); - return ret; - } - } else if (opt == RECV_DATA) { - uint32_t size = 0; - if ((size = getSn_RX_RSR(sn)) > 0) { - if (size > buf_size) size = buf_size; - ret = wiz_sock_recv(sn, buf, size); - if (ret <= 0) return ret; - } - } - break; - default: - break; - } -} - -void wiz_client_op_test(int argc, char *argv[]) { - /* argv[1]: ip ip addr - * argv[2]: port port number - * argv[3]: msg send msg - * argv[4]: count test times,if no this parameter,default 10 times - */ - if (argc < 4) - { - KPrintf("wiz_client_op_test error\n"); - return; - } - uint8_t client_sock = 2; - uint32_t tmp_ip[4]; - uint8_t ip[4]; - uint64_t pCount = 10; - uint8_t buf[g_wiznet_buf_size]; - uint16_t port; - - sscanf(argv[1], "%d.%d.%d.%d", &tmp_ip[0], &tmp_ip[1], &tmp_ip[2], &tmp_ip[3]); - ip[0] = (uint8_t)tmp_ip[0]; - ip[1] = (uint8_t)tmp_ip[1]; - ip[2] = (uint8_t)tmp_ip[2]; - ip[3] = (uint8_t)tmp_ip[3]; - - port = atoi(argv[2]); - KPrintf("wiz client to wiz_server, send to %d.%d.%d.%d %d\n", // tip info - ip[0], ip[1], ip[2], ip[3], port); - - if (argc >= 5){ - pCount = atoi(argv[4]); - } - for(uint64_t i = 0; i < pCount; i++) - { - wiz_client_op(client_sock, argv[3], strlen(argv[3]), ip, port, SEND_DATA); - MdelayKTask(10); - // waiting for a responding. - wiz_client_op(client_sock, buf, g_wiznet_buf_size, ip, port, RECV_DATA); - KPrintf("received msg: %s\n", buf); - memset(buf, 0, g_wiznet_buf_size); - } -} - -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), - wiz_client_op, wiz_client_op_test, - wiz_sock_recv or wiz_sock_send data as tcp client); - -int32_t wiz_server_op(uint8_t sn, uint8_t *buf, uint32_t buf_size, - uint16_t port, enum TCP_OPTION opt) { - int32_t ret = 0; - uint16_t size = 0, sentsize = 0; - switch (getSn_SR(sn)) { - case SOCK_ESTABLISHED: - if (getSn_IR(sn) & Sn_IR_CON) { - printf("%d:Connected\r\n", sn); - setSn_IR(sn, Sn_IR_CON); - } - if (opt == SEND_DATA) { - uint32_t sent_size = 0; - ret = wiz_sock_send(sn, buf, buf_size); - if (ret < 0) { - wiz_sock_close(sn); - return ret; - } - } else if (opt == RECV_DATA) { - uint32_t size = 0; - if ((size = getSn_RX_RSR(sn)) > 0) { - if (size > buf_size) size = buf_size; - ret = wiz_sock_recv(sn, buf, size); - return ret; - } - } - break; - case SOCK_CLOSE_WAIT: - printf("%d:CloseWait\r\n", sn); - if ((ret = wiz_sock_disconnect(sn)) != SOCK_OK) return ret; - printf("%d:Closed\r\n", sn); - break; - case SOCK_INIT: - printf("%d:Listen, port [%d]\r\n", sn, port); - if ((ret = wiz_sock_listen(sn)) != SOCK_OK) return ret; - break; - case SOCK_CLOSED: - printf("%d:LBTStart\r\n", sn); - if ((ret = wiz_socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret; - printf("%d:Opened\r\n", sn); - break; - default: - break; - } - return 0; -} - -void wiz_server(void *param) { - uint16_t port = *(uint16_t *)param; - KPrintf("wiz server, listen port: %d\n", port); - uint8_t buf[g_wiznet_buf_size]; - memset(buf, 0, g_wiznet_buf_size); - int ret = 0; - uint32_t size = 0; - - while (1) { - ret = wiz_server_op(0, buf, g_wiznet_buf_size, port, RECV_DATA); - while(buf[size] != 0){ - size ++; - } - if (ret > 0) { - KPrintf("received %d bytes: %s\n", size, buf); - - wiz_server_op(0, buf, g_wiznet_buf_size, port, SEND_DATA); - memset(buf, 0, g_wiznet_buf_size); - } - size = 0; - } -} - -void wiz_server_test(uint16_t port) { - /* argv[1]: port - */ - int32 wiz_server_id = - KTaskCreate("wiz_server", wiz_server, (void *)&port, 4096, 25); - x_err_t flag = StartupKTask(wiz_server_id); - if (flag != EOK) { - KPrintf("StartupKTask wiz_server_id failed .\n"); - } -} - -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | - SHELL_CMD_PARAM_NUM(1), - wiz_server_op, wiz_server_test, - wiz_sock_recv or wiz_sock_send data as tcp server); - -void loopback_udps(int argc, char *argv[]) -{ - /* argv[1]: remote_ip ip address of remote udp - * argv[2]: remote_port the port number of the remote udp - * argv[2]: local_port the port number of the local udp - */ - uint32_t tmp_ip[4]; - uint8_t remote_ip[4]; - uint16_t remote_port, local_port; - uint8_t buffer[g_wiznet_buf_size]; - uint16_t len = 0; - - if (argc < 4) - { - KPrintf("loopback_udps test error\n"); - return; - } - - sscanf(argv[1], "%d.%d.%d.%d", &tmp_ip[0], &tmp_ip[1], &tmp_ip[2], &tmp_ip[3]); - for(int i = 0;i < 4; i++) - { - remote_ip[i] = (uint8_t)tmp_ip[i]; - } - - remote_port = atoi(argv[2]); - local_port = atoi(argv[3]); - while(1) - { - switch (getSn_SR(0)) - { - case SOCK_UDP: - if(getSn_IR(0) & Sn_IR_RECV) - { - setSn_IR(0, Sn_IR_RECV); - } - if((len = getSn_RX_RSR(0))>0) - { - memset(buffer,0,len+1); - wiz_sock_recvfrom(0, buffer, len, remote_ip, (uint16_t *)&remote_port); - printf("received msg: %s\n", buffer); - wiz_sock_sendto(0, buffer, len, remote_ip, remote_port); - } - break; - - case SOCK_CLOSED: - printf("LBUStart\r\n"); - wiz_socket(0, Sn_MR_UDP, local_port, 0); - break; - } - } -} - -/* wiz_udp remote_ip remote_port local_port */ -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), - wiz_udp, loopback_udps, w5500 upd test); - -void ifconfig() { - wiz_NetInfo wiz_netinfo; - ctlnetwork(CN_GET_NETINFO, (void *)&wiz_netinfo); - uint8_t tmpstr[6]; - ctlwizchip(CW_GET_ID, (void *)tmpstr); - KPrintf("=== %s NET CONF ===\r\n", (char *)tmpstr); - KPrintf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", wiz_netinfo.mac[0], - wiz_netinfo.mac[1], wiz_netinfo.mac[2], wiz_netinfo.mac[3], - wiz_netinfo.mac[4], wiz_netinfo.mac[5]); - KPrintf("SIP: %d.%d.%d.%d\r\n", wiz_netinfo.ip[0], wiz_netinfo.ip[1], - wiz_netinfo.ip[2], wiz_netinfo.ip[3]); - KPrintf("GAR: %d.%d.%d.%d\r\n", wiz_netinfo.gw[0], wiz_netinfo.gw[1], - wiz_netinfo.gw[2], wiz_netinfo.gw[3]); - KPrintf("SUB: %d.%d.%d.%d\r\n", wiz_netinfo.sn[0], wiz_netinfo.sn[1], - wiz_netinfo.sn[2], wiz_netinfo.sn[3]); - KPrintf("DNS: %d.%d.%d.%d\r\n", wiz_netinfo.dns[0], wiz_netinfo.dns[1], - wiz_netinfo.dns[2], wiz_netinfo.dns[3]); - KPrintf("======================\r\n"); -} -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), - ifconfig, ifconfig, printf w5500 configurations); - -void char_arr_assign(uint8_t *dst, uint32_t *src, int len) { - for (int i = 0; i < len; ++i) { - dst[i] = (uint8_t)(src[i]); - } -} - -char *network_param_name[] = {"ip", "sn", "gw"}; - -void config_w5500_network(int argc, char *argv[]) { - if (argc < 2) { - KPrintf("[W5500] Network config require params.\n"); - return; - } - - wiz_NetInfo wiz_netinfo; - memcpy(&wiz_netinfo, &g_wiz_netinfo, sizeof(wiz_NetInfo)); - - int cur_arg_idx = 1; - - while (argv[cur_arg_idx] != NULL) { - if (argv[cur_arg_idx + 1] == NULL) { - KPrintf("[W5500] Network config %s requires value.\n", argv[cur_arg_idx]); - return; - } - uint32_t tmp_arr[4]; - sscanf(argv[cur_arg_idx + 1], "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], - &tmp_arr[2], &tmp_arr[3]); - if (memcmp(argv[cur_arg_idx], network_param_name[0], 2 * sizeof(char)) == - 0) { - char_arr_assign(wiz_netinfo.ip, tmp_arr, 4); - } else if (memcmp(argv[cur_arg_idx], network_param_name[1], - 2 * sizeof(char)) == 0) { - char_arr_assign(wiz_netinfo.sn, tmp_arr, 4); - } else if (memcmp(argv[cur_arg_idx], network_param_name[2], - 2 * sizeof(char)) == 0) { - char_arr_assign(wiz_netinfo.gw, tmp_arr, 4); - } else { - KPrintf("[W5500] Invalid network param.\n"); - } - cur_arg_idx += 2; - } - - ctlnetwork(CN_SET_NETINFO, (void *)&wiz_netinfo); - KPrintf("[W5500] Network config success.\n", argv[cur_arg_idx]); - ifconfig(); -} -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), - config_w5500_network, config_w5500_network, - set w5500 configurations); \ No newline at end of file +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500_test.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500_test.c new file mode 100644 index 000000000..c85c33090 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500_test.c @@ -0,0 +1,314 @@ +#include +#include +#include + +#include "socket.h" + +extern uint32_t get_gbuf_size(); +extern wiz_NetInfo *get_gnetinfo(); + +enum TCP_OPTION { + SEND_DATA = 0, + RECV_DATA, +}; + +uint32_t wiz_client_op(uint8_t sn, uint8_t *buf, uint32_t buf_size, + uint8_t dst_ip[4], uint16_t dst_port, + enum TCP_OPTION opt) { + // assert(buf_size <= get_gbuf_size()); + int32_t ret; + switch (getSn_SR(sn)) { + case SOCK_CLOSE_WAIT: + wiz_sock_disconnect(sn); + break; + case SOCK_CLOSED: + wiz_socket(sn, Sn_MR_TCP, 5000, 0x00); + break; + case SOCK_INIT: + KPrintf("[SOCKET CLIENT] sock init.\n"); + wiz_sock_connect(sn, dst_ip, dst_port); + break; + case SOCK_ESTABLISHED: + if (getSn_IR(sn) & Sn_IR_CON) { + printf("[SOCKET CLIENT] %d:Connected\r\n", sn); + setSn_IR(sn, Sn_IR_CON); + } + if (opt == SEND_DATA) { + uint32_t sent_size = 0; + ret = wiz_sock_send(sn, buf, buf_size); + if (ret < 0) { + wiz_sock_close(sn); + return ret; + } + } else if (opt == RECV_DATA) { + uint32_t size = 0; + if ((size = getSn_RX_RSR(sn)) > 0) { + if (size > buf_size) size = buf_size; + ret = wiz_sock_recv(sn, buf, size); + if (ret <= 0) return ret; + } + } + break; + default: + break; + } +} + +void wiz_client_op_test(int argc, char *argv[]) { + /* argv[1]: ip ip addr + * argv[2]: port port number + * argv[3]: msg send msg + * argv[4]: count test times,if no this parameter,default 10 times + */ + if (argc < 4) + { + KPrintf("wiz_client_op_test error\n"); + return; + } + uint8_t client_sock = 2; + uint32_t tmp_ip[4]; + uint8_t ip[4]; + uint64_t pCount = 10; + uint8_t buf[get_gbuf_size()]; + uint16_t port; + + sscanf(argv[1], "%d.%d.%d.%d", &tmp_ip[0], &tmp_ip[1], &tmp_ip[2], &tmp_ip[3]); + ip[0] = (uint8_t)tmp_ip[0]; + ip[1] = (uint8_t)tmp_ip[1]; + ip[2] = (uint8_t)tmp_ip[2]; + ip[3] = (uint8_t)tmp_ip[3]; + + port = atoi(argv[2]); + KPrintf("wiz client to wiz_server, send to %d.%d.%d.%d %d\n", // tip info + ip[0], ip[1], ip[2], ip[3], port); + + if (argc >= 5){ + pCount = atoi(argv[4]); + } + for(uint64_t i = 0; i < pCount; i++) + { + wiz_client_op(client_sock, argv[3], strlen(argv[3]), ip, port, SEND_DATA); + MdelayKTask(10); + // waiting for a responding. + wiz_client_op(client_sock, buf, get_gbuf_size(), ip, port, RECV_DATA); + KPrintf("received msg: %s\n", buf); + memset(buf, 0, get_gbuf_size()); + } +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + wiz_client_op, wiz_client_op_test, + wiz_sock_recv or wiz_sock_send data as tcp client); + +int32_t wiz_server_op(uint8_t sn, uint8_t *buf, uint32_t buf_size, + uint16_t port, enum TCP_OPTION opt) { + int32_t ret = 0; + uint16_t size = 0, sentsize = 0; + switch (getSn_SR(sn)) { + case SOCK_ESTABLISHED: + if (getSn_IR(sn) & Sn_IR_CON) { + printf("%d:Connected\r\n", sn); + setSn_IR(sn, Sn_IR_CON); + } + if (opt == SEND_DATA) { + uint32_t sent_size = 0; + ret = wiz_sock_send(sn, buf, buf_size); + if (ret < 0) { + wiz_sock_close(sn); + return ret; + } + } else if (opt == RECV_DATA) { + uint32_t size = 0; + if ((size = getSn_RX_RSR(sn)) > 0) { + if (size > buf_size) size = buf_size; + ret = wiz_sock_recv(sn, buf, size); + return ret; + } + } + break; + case SOCK_CLOSE_WAIT: + printf("%d:CloseWait\r\n", sn); + if ((ret = wiz_sock_disconnect(sn)) != SOCK_OK) return ret; + printf("%d:Closed\r\n", sn); + break; + case SOCK_INIT: + printf("%d:Listen, port [%d]\r\n", sn, port); + if ((ret = wiz_sock_listen(sn)) != SOCK_OK) return ret; + break; + case SOCK_CLOSED: + printf("%d:LBTStart\r\n", sn); + if ((ret = wiz_socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret; + printf("%d:Opened\r\n", sn); + break; + default: + break; + } + return 0; +} + +void wiz_server(void *param) { + uint16_t port = *(uint16_t *)param; + KPrintf("wiz server, listen port: %d\n", port); + uint8_t buf[get_gbuf_size()]; + memset(buf, 0, get_gbuf_size()); + int ret = 0; + uint32_t size = 0; + + while (1) { + ret = wiz_server_op(0, buf, get_gbuf_size(), port, RECV_DATA); + while(buf[size] != 0){ + size ++; + } + if (ret > 0) { + KPrintf("received %d bytes: %s\n", size, buf); + + wiz_server_op(0, buf, get_gbuf_size(), port, SEND_DATA); + memset(buf, 0, get_gbuf_size()); + } + size = 0; + } +} + +void wiz_server_test(uint16_t port) { + /* argv[1]: port + */ + int32 wiz_server_id = + KTaskCreate("wiz_server", wiz_server, (void *)&port, 4096, 25); + x_err_t flag = StartupKTask(wiz_server_id); + if (flag != EOK) { + KPrintf("StartupKTask wiz_server_id failed .\n"); + } +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(1), + wiz_server_op, wiz_server_test, + wiz_sock_recv or wiz_sock_send data as tcp server); + +void loopback_udps(int argc, char *argv[]) +{ + /* argv[1]: remote_ip ip address of remote udp + * argv[2]: remote_port the port number of the remote udp + * argv[2]: local_port the port number of the local udp + */ + uint32_t tmp_ip[4]; + uint8_t remote_ip[4]; + uint16_t remote_port, local_port; + uint8_t buffer[get_gbuf_size()]; + uint16_t len = 0; + + if (argc < 4) + { + KPrintf("loopback_udps test error\n"); + return; + } + + sscanf(argv[1], "%d.%d.%d.%d", &tmp_ip[0], &tmp_ip[1], &tmp_ip[2], &tmp_ip[3]); + for(int i = 0;i < 4; i++) + { + remote_ip[i] = (uint8_t)tmp_ip[i]; + } + + remote_port = atoi(argv[2]); + local_port = atoi(argv[3]); + while(1) + { + switch (getSn_SR(0)) + { + case SOCK_UDP: + if(getSn_IR(0) & Sn_IR_RECV) + { + setSn_IR(0, Sn_IR_RECV); + } + if((len = getSn_RX_RSR(0))>0) + { + memset(buffer, 0, len + 1); + wiz_sock_recvfrom(0, buffer, len, remote_ip, (uint16_t *)&remote_port); + printf("received msg: %s\n", buffer); + wiz_sock_sendto(0, buffer, len, remote_ip, remote_port); + } + break; + + case SOCK_CLOSED: + printf("LBUStart\r\n"); + wiz_socket(0, Sn_MR_UDP, local_port, 0); + break; + } + } +} + +/* wiz_udp remote_ip remote_port local_port */ +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + wiz_udp, loopback_udps, w5500 upd test); + +void ifconfig() { + wiz_NetInfo wiz_netinfo; + ctlnetwork(CN_GET_NETINFO, (void *)&wiz_netinfo); + uint8_t tmpstr[6]; + ctlwizchip(CW_GET_ID, (void *)tmpstr); + KPrintf("=== %s NET CONF ===\r\n", (char *)tmpstr); + KPrintf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", wiz_netinfo.mac[0], + wiz_netinfo.mac[1], wiz_netinfo.mac[2], wiz_netinfo.mac[3], + wiz_netinfo.mac[4], wiz_netinfo.mac[5]); + KPrintf("SIP: %d.%d.%d.%d\r\n", wiz_netinfo.ip[0], wiz_netinfo.ip[1], + wiz_netinfo.ip[2], wiz_netinfo.ip[3]); + KPrintf("GAR: %d.%d.%d.%d\r\n", wiz_netinfo.gw[0], wiz_netinfo.gw[1], + wiz_netinfo.gw[2], wiz_netinfo.gw[3]); + KPrintf("SUB: %d.%d.%d.%d\r\n", wiz_netinfo.sn[0], wiz_netinfo.sn[1], + wiz_netinfo.sn[2], wiz_netinfo.sn[3]); + KPrintf("DNS: %d.%d.%d.%d\r\n", wiz_netinfo.dns[0], wiz_netinfo.dns[1], + wiz_netinfo.dns[2], wiz_netinfo.dns[3]); + KPrintf("======================\r\n"); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), + ifconfig, ifconfig, printf w5500 configurations); + +void char_arr_assign(uint8_t *dst, uint32_t *src, int len) { + for (int i = 0; i < len; ++i) { + dst[i] = (uint8_t)(src[i]); + } +} + +char *network_param_name[] = {"ip", "sn", "gw"}; + +void config_w5500_network(int argc, char *argv[]) { + if (argc < 2) { + KPrintf("[W5500] Network config require params.\n"); + return; + } + + wiz_NetInfo wiz_netinfo; + memcpy(&wiz_netinfo, get_gnetinfo(), sizeof(wiz_NetInfo)); + + int cur_arg_idx = 1; + + while (argv[cur_arg_idx] != NULL) { + if (argv[cur_arg_idx + 1] == NULL) { + KPrintf("[W5500] Network config %s requires value.\n", argv[cur_arg_idx]); + return; + } + uint32_t tmp_arr[4]; + sscanf(argv[cur_arg_idx + 1], "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], + &tmp_arr[2], &tmp_arr[3]); + if (memcmp(argv[cur_arg_idx], network_param_name[0], 2 * sizeof(char)) == + 0) { + char_arr_assign(wiz_netinfo.ip, tmp_arr, 4); + } else if (memcmp(argv[cur_arg_idx], network_param_name[1], + 2 * sizeof(char)) == 0) { + char_arr_assign(wiz_netinfo.sn, tmp_arr, 4); + } else if (memcmp(argv[cur_arg_idx], network_param_name[2], + 2 * sizeof(char)) == 0) { + char_arr_assign(wiz_netinfo.gw, tmp_arr, 4); + } else { + KPrintf("[W5500] Invalid network param.\n"); + } + cur_arg_idx += 2; + } + + ctlnetwork(CN_SET_NETINFO, (void *)&wiz_netinfo); + KPrintf("[W5500] Network config success.\n", argv[cur_arg_idx]); + ifconfig(); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + config_w5500_network, config_w5500_network, + set w5500 configurations); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_iperf.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_iperf.c index 3c4daa75f..3b1647c0f 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_iperf.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_iperf.c @@ -462,4 +462,4 @@ __usage: SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), iperf, iperf, iperf throughput test); -#endif \ No newline at end of file +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.c index 9db4abf31..4abb10aac 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.c +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.c @@ -78,6 +78,10 @@ Modification: #include #endif +#ifdef BSP_USING_LWIP +#include +#endif + extern void entry(void); extern int HwUsartInit(); @@ -209,6 +213,8 @@ struct InitSequenceDesc _board_init[] = #endif #ifdef BSP_USING_CAN { "can", HwCanInit }, +#endif +#ifdef BSP_USING_LWIP #endif { " NONE ", NONE }, }; diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/Kconfig b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/Kconfig index 8b1378917..64b081e23 100755 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/Kconfig @@ -1 +1,3 @@ - +config BSP_USING_ETH + bool + default y \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/Makefile index c1b8c3ab9..b63aff8c2 100755 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/Makefile @@ -1,3 +1,3 @@ -SRC_FILES := ethernetif.c +SRC_FILES := ethernetif.c eth_driver.c include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/eth_driver.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/eth_driver.c new file mode 100644 index 000000000..ea8cf81c3 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/eth_driver.c @@ -0,0 +1,287 @@ +/** +* @file ethernetif.c +* @brief support hc32f4a0-board ethernetif function and register to Lwip +* @version 3.0 +* @author AIIT XUOS Lab +* @date 2022-12-05 +*/ + +#include +#include +#include +#include +#include +#include + +#include + +void eth_irq_handler(void) { + static x_base eth_irq_lock; + eth_irq_lock = DISABLE_INTERRUPT(); + + // handle irq + if (RESET != ETH_DMA_GetStatus(ETH_DMA_FLAG_RIS)) { + sys_sem_signal(get_eth_recv_sem()); + ETH_DMA_ClearStatus(ETH_DMA_FLAG_RIS | ETH_DMA_FLAG_NIS); + } + + ENABLE_INTERRUPT(eth_irq_lock); +} + +/** + * @brief In this function, the hardware should be initialized. + * @param netif The already initialized network interface structure for this ethernetif. + * @retval int32_t: + * - LL_OK: Initialize success + * - LL_ERR: Initialize failed + */ +int32_t low_level_init(struct netif *netif) +{ + int32_t i32Ret = LL_ERR; + stc_eth_init_t stcEthInit; + uint16_t u16RegVal; + + /* Enable ETH clock */ + FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_ETHMAC, ENABLE); + /* Init Ethernet GPIO */ + Ethernet_GpioInit(); + /* Reset ETHERNET */ + (void)ETH_DeInit(); + /* Configure structure initialization */ + (void)ETH_CommStructInit(&EthHandle.stcCommInit); + (void)ETH_StructInit(&stcEthInit); + +#ifdef ETH_INTERFACE_RMII + EthHandle.stcCommInit.u32Interface = ETH_MAC_IF_RMII; +#else + EthHandle.stcCommInit.u32Interface = ETH_MAC_IF_MII; +#endif + // stcEthInit.stcMacInit.u32ReceiveAll = ETH_MAC_RX_ALL_ENABLE; + EthHandle.stcCommInit.u32ReceiveMode = ETH_RX_MD_INT; + // EthHandle.stcCommInit.u32ChecksumMode = ETH_MAC_CHECKSUM_MD_SW; + + // install irq + sys_sem_new(get_eth_recv_sem(), 0); + hc32_install_irq_handler(ð_irq_config, eth_irq_handler, ENABLE); + + /* Configure ethernet peripheral */ + if (LL_OK == ETH_Init(&EthHandle, &stcEthInit)) { + u8EthInitStatus = 1U; + i32Ret = LL_OK; + } + +#ifdef ETHERNET_LOOPBACK_TEST + /* Enable PHY loopback */ + (void)ETH_PHY_LoopBackCmd(&EthHandle, ENABLE); +#endif + + /* Initialize Tx Descriptors list: Chain Mode */ + (void)ETH_DMA_TxDescListInit(&EthHandle, EthDmaTxDscrTab, &EthTxBuff[0][0], ETH_TX_BUF_NUM); + /* Initialize Rx Descriptors list: Chain Mode */ + (void)ETH_DMA_RxDescListInit(&EthHandle, EthDmaRxDscrTab, &EthRxBuff[0][0], ETH_RX_BUF_NUM); + + /* set MAC hardware address length */ + netif->hwaddr_len = 6U; + /* set MAC hardware address */ + EthHandle.stcCommInit.u16AutoNego = ETH_AUTO_NEGO_DISABLE; + + netif->hwaddr[0] = (EthHandle.stcCommInit).au8MacAddr[0]; + netif->hwaddr[1] = (EthHandle.stcCommInit).au8MacAddr[1]; + netif->hwaddr[2] = (EthHandle.stcCommInit).au8MacAddr[2]; + netif->hwaddr[3] = (EthHandle.stcCommInit).au8MacAddr[3]; + netif->hwaddr[4] = (EthHandle.stcCommInit).au8MacAddr[4]; + netif->hwaddr[5] = (EthHandle.stcCommInit).au8MacAddr[5]; + /* maximum transfer unit */ + netif->mtu = 1500U; + + /* device capabilities */ + netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; + + /* Enable MAC and DMA transmission and reception */ + (void)ETH_Start(); + + /* Configure PHY LED mode */ + u16RegVal = PHY_PAGE_ADDR_7; + (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal); + (void)ETH_PHY_ReadReg(&EthHandle, PHY_P7_IWLFR, &u16RegVal); + MODIFY_REG16(u16RegVal, PHY_LED_SELECT, PHY_LED_SELECT_10); + (void)ETH_PHY_WriteReg(&EthHandle, PHY_P7_IWLFR, u16RegVal); + u16RegVal = PHY_PAGE_ADDR_0; + (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal); + +#ifdef ETH_INTERFACE_RMII + /* Disable Power Saving Mode */ + (void)ETH_PHY_ReadReg(&EthHandle, PHY_PSMR, &u16RegVal); + CLR_REG16_BIT(u16RegVal, PHY_EN_PWR_SAVE); + (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSMR, u16RegVal); + + /* Configure PHY to generate an interrupt when Eth Link state changes */ + u16RegVal = PHY_PAGE_ADDR_7; + (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal); + /* Enable Interrupt on change of link status */ + (void)ETH_PHY_ReadReg(&EthHandle, PHY_P7_IWLFR, &u16RegVal); + SET_REG16_BIT(u16RegVal, PHY_INT_LINK_CHANGE); + (void)ETH_PHY_WriteReg(&EthHandle, PHY_P7_IWLFR, u16RegVal); + u16RegVal = PHY_PAGE_ADDR_0; + (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal); +#endif + + return i32Ret; +} + +/** + * @brief This function should do the actual transmission of the packet. + * @param netif The network interface structure for this ethernetif. + * @param p The MAC packet to send. + * @retval int32_t: + * - LL_OK: The packet could be sent + * - LL_ERR: The packet couldn't be sent + */ +err_t low_level_output(struct netif *netif, struct pbuf *p) +{ + err_t i32Ret; + struct pbuf *q; + uint8_t *txBuffer; + __IO stc_eth_dma_desc_t *DmaTxDesc; + uint32_t byteCnt; + uint32_t frameLength = 0UL; + uint32_t bufferOffset; + uint32_t payloadOffset; + + DmaTxDesc = EthHandle.stcTxDesc; + txBuffer = (uint8_t *)((EthHandle.stcTxDesc)->u32Buf1Addr); + bufferOffset = 0UL; + /* Copy frame from pbufs to driver buffers */ + for (q = p; q != NULL; q = q->next) { + /* If this buffer isn't available, goto error */ + if (0UL != (DmaTxDesc->u32ControlStatus & ETH_DMA_TXDESC_OWN)) { + i32Ret = (err_t)ERR_USE; + goto error; + } + + /* Get bytes in current buffer */ + byteCnt = q->len; + payloadOffset = 0UL; + /* Check if the length of data to copy is bigger than Tx buffer size */ + while ((byteCnt + bufferOffset) > ETH_TX_BUF_SIZE) { + /* Copy data to Tx buffer*/ + (void)memcpy((uint8_t *) & (txBuffer[bufferOffset]), (uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), (ETH_TX_BUF_SIZE - bufferOffset)); + /* Point to next descriptor */ + DmaTxDesc = (stc_eth_dma_desc_t *)(DmaTxDesc->u32Buf2NextDescAddr); + /* Check if the buffer is available */ + if (0UL != (DmaTxDesc->u32ControlStatus & ETH_DMA_TXDESC_OWN)) { + i32Ret = (err_t)ERR_USE; + goto error; + } + + txBuffer = (uint8_t *)(DmaTxDesc->u32Buf1Addr); + byteCnt = byteCnt - (ETH_TX_BUF_SIZE - bufferOffset); + payloadOffset = payloadOffset + (ETH_TX_BUF_SIZE - bufferOffset); + frameLength = frameLength + (ETH_TX_BUF_SIZE - bufferOffset); + bufferOffset = 0UL; + } + /* Copy the remaining bytes */ + (void)memcpy((uint8_t *) & (txBuffer[bufferOffset]), (uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), byteCnt); + bufferOffset = bufferOffset + byteCnt; + frameLength = frameLength + byteCnt; + } + /* Prepare transmit descriptors to give to DMA */ + if(LL_OK != ETH_DMA_SetTransFrame(&EthHandle, frameLength)) { + KPrintf("[%s] Error sending eth DMA frame\n", __func__); + } + i32Ret = (err_t)ERR_OK; + +error: + /* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */ + if (RESET != ETH_DMA_GetStatus(ETH_DMA_FLAG_UNS)) { + /* Clear DMA UNS flag */ + ETH_DMA_ClearStatus(ETH_DMA_FLAG_UNS); + /* Resume DMA transmission */ + WRITE_REG32(CM_ETH->DMA_TXPOLLR, 0UL); + } + + return i32Ret; +} + +/** + * @brief Should allocate a pbuf and transfer the bytes of the incoming packet from the interface into the pbuf. + * @param netif The network interface structure for this ethernetif. + * @retval A pbuf filled with the received packet (including MAC header) or NULL on memory error. + */ +struct pbuf *low_level_input(struct netif *netif) +{ + struct pbuf *p = NULL; + struct pbuf *q; + uint32_t len; + uint8_t *rxBuffer; + __IO stc_eth_dma_desc_t *DmaRxDesc; + uint32_t byteCnt; + uint32_t bufferOffset; + uint32_t payloadOffset; + uint32_t i; + + /* Get received frame */ + if (LL_OK != ETH_DMA_GetReceiveFrame(&EthHandle)) { + return NULL; + } + + /* Obtain the size of the packet */ + len = (EthHandle.stcRxFrame).u32Len; + rxBuffer = (uint8_t *)(EthHandle.stcRxFrame).u32Buf; + if (len > 0UL) { + /* Allocate a pbuf chain of pbufs from the buffer */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + // p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + } + if (p != NULL) { + DmaRxDesc = (EthHandle.stcRxFrame).pstcFSDesc; + bufferOffset = 0UL; + for (q = p; q != NULL; q = q->next) { + byteCnt = q->len; + payloadOffset = 0UL; + + /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size */ + while ((byteCnt + bufferOffset) > ETH_RX_BUF_SIZE) { + /* Copy data to pbuf */ + (void)memcpy((uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), (uint8_t *) & (rxBuffer[bufferOffset]), (ETH_RX_BUF_SIZE - bufferOffset)); + /* Point to next descriptor */ + DmaRxDesc = (stc_eth_dma_desc_t *)(DmaRxDesc->u32Buf2NextDescAddr); + rxBuffer = (uint8_t *)(DmaRxDesc->u32Buf1Addr); + byteCnt = byteCnt - (ETH_RX_BUF_SIZE - bufferOffset); + payloadOffset = payloadOffset + (ETH_RX_BUF_SIZE - bufferOffset); + bufferOffset = 0UL; + } + + /* Copy remaining data in pbuf */ + (void)memcpy((uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), (uint8_t *) & (rxBuffer[bufferOffset]), byteCnt); + bufferOffset = bufferOffset + byteCnt; + } + } + /* Release descriptors to DMA */ + DmaRxDesc = (EthHandle.stcRxFrame).pstcFSDesc; + for (i = 0UL; i < (EthHandle.stcRxFrame).u32SegCount; i++) { + DmaRxDesc->u32ControlStatus |= ETH_DMA_RXDESC_OWN; + DmaRxDesc = (stc_eth_dma_desc_t *)(DmaRxDesc->u32Buf2NextDescAddr); + } + /* Clear Segment_Count */ + (EthHandle.stcRxFrame).u32SegCount = 0UL; + + /* When Rx Buffer unavailable flag is set, clear it and resume reception */ + if (RESET != ETH_DMA_GetStatus(ETH_DMA_FLAG_RUS)) { + /* Clear DMA RUS flag */ + ETH_DMA_ClearStatus(ETH_DMA_FLAG_RUS); + /* Resume DMA reception */ + WRITE_REG32(CM_ETH->DMA_RXPOLLR, 0UL); + } + + return p; +} + +extern void LwipSetIPTest(int argc, char *argv[]); +int HwEthInit(void) { +// lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, lwip_gwaddr); + LwipSetIPTest(1, NULL); + return EOK; +} + + diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/ethernetif.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/ethernetif.c index 6658a96e2..c5d8fc1dd 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/ethernetif.c +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/ethernetif.c @@ -46,14 +46,15 @@ Modification: /******************************************************************************* * Include files ******************************************************************************/ -#include -#include +#include #include #include #include #include #include +#include + /** * @addtogroup HC32F4A0_DDL_Examples * @{ @@ -71,33 +72,7 @@ Modification: /******************************************************************************* * Local pre-processor symbols/macros ('#define') ******************************************************************************/ -/* Define those to better describe your network interface. */ -#define IFNAME0 'h' -#define IFNAME1 'd' -/* PHY hardware reset time */ -#define PHY_HW_RST_DELAY (0x40U) - -/* ETH_RST = PH11 */ -#define ETH_RST_PORT (GPIO_PORT_H) -#define ETH_RST_PIN (GPIO_PIN_11) - -/* ETH_LINK_LED = PD00 LED2 */ -#define ETH_LINK_LED_PORT (GPIO_PORT_D) -#define ETH_LINK_LED_PIN (GPIO_PIN_00) - -//#define ETHERNET_LOOPBACK_TEST -#ifdef ETHERNET_LOOPBACK_TEST - -#define USER_KEY_PORT (GPIO_PORT_I) -#define USER_KEY_PIN (GPIO_PIN_07) - -/* ethe global netif */ -static struct netif testnetif; -/* eth tx buffer */ -static struct pbuf txPbuf; -static char txBuf[] = "Ethernet Loop-Back Test"; -#endif /******************************************************************************* * Global variable definitions (declared in header file with 'extern') @@ -110,19 +85,7 @@ static char txBuf[] = "Ethernet Loop-Back Test"; /******************************************************************************* * Local variable definitions ('static') ******************************************************************************/ -/* Global Ethernet handle*/ -static stc_eth_handle_t EthHandle; -/* Ethernet Tx DMA Descriptor */ -__ALIGN_BEGIN static stc_eth_dma_desc_t EthDmaTxDscrTab[ETH_TX_BUF_NUM]; -/* Ethernet Rx DMA Descriptor */ -__ALIGN_BEGIN static stc_eth_dma_desc_t EthDmaRxDscrTab[ETH_RX_BUF_NUM]; -/* Ethernet Transmit Buffer */ -__ALIGN_BEGIN static uint8_t EthTxBuff[ETH_TX_BUF_NUM][ETH_TX_BUF_SIZE]; -/* Ethernet Receive Buffer */ -__ALIGN_BEGIN static uint8_t EthRxBuff[ETH_RX_BUF_NUM][ETH_RX_BUF_SIZE]; -/* Ethernet link status */ -static uint8_t u8PhyLinkStatus = 0U, u8EthInitStatus = 0U; /******************************************************************************* * Function implementation - global ('extern') and local ('static') @@ -132,22 +95,12 @@ static uint8_t u8PhyLinkStatus = 0U, u8EthInitStatus = 0U; * @{ */ -void *ethernetif_config_enet_set(uint8_t enet_port) -{ - return NONE; -} - -void Time_Update_LwIP(void) -{ - //no need to do -} - /** * @brief Initializes the Ethernet GPIO. * @param None * @retval None */ -static void Ethernet_GpioInit(void) +void Ethernet_GpioInit(void) { /* ETH_RST */ stc_gpio_init_t stcGpioInit; @@ -227,241 +180,12 @@ static void Ethernet_GpioInit(void) #endif } -/** - * @brief In this function, the hardware should be initialized. - * @param netif The already initialized network interface structure for this ethernetif. - * @retval int32_t: - * - LL_OK: Initialize success - * - LL_ERR: Initialize failed - */ -static int32_t low_level_init(struct netif *netif) -{ - int32_t i32Ret = LL_ERR; - stc_eth_init_t stcEthInit; - uint16_t u16RegVal; - - /* Enable ETH clock */ - FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_ETHMAC, ENABLE); - /* Init Ethernet GPIO */ - Ethernet_GpioInit(); - /* Reset ETHERNET */ - (void)ETH_DeInit(); - /* Configure structure initialization */ - (void)ETH_CommStructInit(&EthHandle.stcCommInit); - (void)ETH_StructInit(&stcEthInit); -#ifdef ETH_INTERFACE_RMII - EthHandle.stcCommInit.u32Interface = ETH_MAC_IF_RMII; -#else - EthHandle.stcCommInit.u32Interface = ETH_MAC_IF_MII; -#endif - stcEthInit.stcMacInit.u32ReceiveAll = ETH_MAC_RX_ALL_ENABLE; - - /* Configure ethernet peripheral */ - if (LL_OK == ETH_Init(&EthHandle, &stcEthInit)) { - u8EthInitStatus = 1U; - i32Ret = LL_OK; - } - -#ifdef ETHERNET_LOOPBACK_TEST - /* Enable PHY loopback */ - (void)ETH_PHY_LoopBackCmd(&EthHandle, ENABLE); -#endif - - /* Initialize Tx Descriptors list: Chain Mode */ - (void)ETH_DMA_TxDescListInit(&EthHandle, EthDmaTxDscrTab, &EthTxBuff[0][0], ETH_TX_BUF_NUM); - /* Initialize Rx Descriptors list: Chain Mode */ - (void)ETH_DMA_RxDescListInit(&EthHandle, EthDmaRxDscrTab, &EthRxBuff[0][0], ETH_RX_BUF_NUM); - - /* set MAC hardware address length */ - netif->hwaddr_len = 6U; - /* set MAC hardware address */ - netif->hwaddr[0] = (EthHandle.stcCommInit).au8MacAddr[0]; - netif->hwaddr[1] = (EthHandle.stcCommInit).au8MacAddr[1]; - netif->hwaddr[2] = (EthHandle.stcCommInit).au8MacAddr[2]; - netif->hwaddr[3] = (EthHandle.stcCommInit).au8MacAddr[3]; - netif->hwaddr[4] = (EthHandle.stcCommInit).au8MacAddr[4]; - netif->hwaddr[5] = (EthHandle.stcCommInit).au8MacAddr[5]; - /* maximum transfer unit */ - netif->mtu = 1500U; - - /* device capabilities */ - netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; - - /* Enable MAC and DMA transmission and reception */ - (void)ETH_Start(); - - /* Configure PHY LED mode */ - u16RegVal = PHY_PAGE_ADDR_7; - (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal); - (void)ETH_PHY_ReadReg(&EthHandle, PHY_P7_IWLFR, &u16RegVal); - MODIFY_REG16(u16RegVal, PHY_LED_SELECT, PHY_LED_SELECT_10); - (void)ETH_PHY_WriteReg(&EthHandle, PHY_P7_IWLFR, u16RegVal); - u16RegVal = PHY_PAGE_ADDR_0; - (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal); - -#ifdef ETH_INTERFACE_RMII - /* Disable Power Saving Mode */ - (void)ETH_PHY_ReadReg(&EthHandle, PHY_PSMR, &u16RegVal); - CLR_REG16_BIT(u16RegVal, PHY_EN_PWR_SAVE); - (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSMR, u16RegVal); - - /* Configure PHY to generate an interrupt when Eth Link state changes */ - u16RegVal = PHY_PAGE_ADDR_7; - (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal); - /* Enable Interrupt on change of link status */ - (void)ETH_PHY_ReadReg(&EthHandle, PHY_P7_IWLFR, &u16RegVal); - SET_REG16_BIT(u16RegVal, PHY_INT_LINK_CHANGE); - (void)ETH_PHY_WriteReg(&EthHandle, PHY_P7_IWLFR, u16RegVal); - u16RegVal = PHY_PAGE_ADDR_0; - (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal); -#endif - - return i32Ret; +void *ethernetif_config_enet_set(uint8_t enet_port) { + return NONE; } -/** - * @brief This function should do the actual transmission of the packet. - * @param netif The network interface structure for this ethernetif. - * @param p The MAC packet to send. - * @retval int32_t: - * - LL_OK: The packet could be sent - * - LL_ERR: The packet couldn't be sent - */ -err_t low_level_output(struct netif *netif, struct pbuf *p) -{ - err_t i32Ret; - struct pbuf *q; - uint8_t *txBuffer; - __IO stc_eth_dma_desc_t *DmaTxDesc; - uint32_t byteCnt; - uint32_t frameLength = 0UL; - uint32_t bufferOffset; - uint32_t payloadOffset; - - DmaTxDesc = EthHandle.stcTxDesc; - txBuffer = (uint8_t *)((EthHandle.stcTxDesc)->u32Buf1Addr); - bufferOffset = 0UL; - /* Copy frame from pbufs to driver buffers */ - for (q = p; q != NULL; q = q->next) { - /* If this buffer isn't available, goto error */ - if (0UL != (DmaTxDesc->u32ControlStatus & ETH_DMA_TXDESC_OWN)) { - i32Ret = LL_ERR; - goto error; - } - - /* Get bytes in current buffer */ - byteCnt = q->len; - payloadOffset = 0UL; - /* Check if the length of data to copy is bigger than Tx buffer size */ - while ((byteCnt + bufferOffset) > ETH_TX_BUF_SIZE) { - /* Copy data to Tx buffer*/ - (void)memcpy((uint8_t *) & (txBuffer[bufferOffset]), (uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), (ETH_TX_BUF_SIZE - bufferOffset)); - /* Point to next descriptor */ - DmaTxDesc = (stc_eth_dma_desc_t *)(DmaTxDesc->u32Buf2NextDescAddr); - /* Check if the buffer is available */ - if (0UL != (DmaTxDesc->u32ControlStatus & ETH_DMA_TXDESC_OWN)) { - i32Ret = LL_ERR; - goto error; - } - - txBuffer = (uint8_t *)(DmaTxDesc->u32Buf1Addr); - byteCnt = byteCnt - (ETH_TX_BUF_SIZE - bufferOffset); - payloadOffset = payloadOffset + (ETH_TX_BUF_SIZE - bufferOffset); - frameLength = frameLength + (ETH_TX_BUF_SIZE - bufferOffset); - bufferOffset = 0UL; - } - /* Copy the remaining bytes */ - (void)memcpy((uint8_t *) & (txBuffer[bufferOffset]), (uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), byteCnt); - bufferOffset = bufferOffset + byteCnt; - frameLength = frameLength + byteCnt; - } - /* Prepare transmit descriptors to give to DMA */ - (void)ETH_DMA_SetTransFrame(&EthHandle, frameLength); - i32Ret = LL_OK; - -error: - /* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */ - if (RESET != ETH_DMA_GetStatus(ETH_DMA_FLAG_UNS)) { - /* Clear DMA UNS flag */ - ETH_DMA_ClearStatus(ETH_DMA_FLAG_UNS); - /* Resume DMA transmission */ - WRITE_REG32(CM_ETH->DMA_TXPOLLR, 0UL); - } - - return i32Ret; -} - -/** - * @brief Should allocate a pbuf and transfer the bytes of the incoming packet from the interface into the pbuf. - * @param netif The network interface structure for this ethernetif. - * @retval A pbuf filled with the received packet (including MAC header) or NULL on memory error. - */ -static struct pbuf *low_level_input(struct netif *netif) -{ - struct pbuf *p = NULL; - struct pbuf *q; - uint32_t len; - uint8_t *rxBuffer; - __IO stc_eth_dma_desc_t *DmaRxDesc; - uint32_t byteCnt; - uint32_t bufferOffset; - uint32_t payloadOffset; - uint32_t i; - - /* Get received frame */ - if (LL_OK != ETH_DMA_GetReceiveFrame(&EthHandle)) { - return NULL; - } - - /* Obtain the size of the packet */ - len = (EthHandle.stcRxFrame).u32Len; - rxBuffer = (uint8_t *)(EthHandle.stcRxFrame).u32Buf; - if (len > 0UL) { - /* Allocate a pbuf chain of pbufs from the buffer */ - p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); - } - if (p != NULL) { - DmaRxDesc = (EthHandle.stcRxFrame).pstcFSDesc; - bufferOffset = 0UL; - for (q = p; q != NULL; q = q->next) { - byteCnt = q->len; - payloadOffset = 0UL; - - /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size */ - while ((byteCnt + bufferOffset) > ETH_RX_BUF_SIZE) { - /* Copy data to pbuf */ - (void)memcpy((uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), (uint8_t *) & (rxBuffer[bufferOffset]), (ETH_RX_BUF_SIZE - bufferOffset)); - /* Point to next descriptor */ - DmaRxDesc = (stc_eth_dma_desc_t *)(DmaRxDesc->u32Buf2NextDescAddr); - rxBuffer = (uint8_t *)(DmaRxDesc->u32Buf1Addr); - byteCnt = byteCnt - (ETH_RX_BUF_SIZE - bufferOffset); - payloadOffset = payloadOffset + (ETH_RX_BUF_SIZE - bufferOffset); - bufferOffset = 0UL; - } - - /* Copy remaining data in pbuf */ - (void)memcpy((uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), (uint8_t *) & (rxBuffer[bufferOffset]), byteCnt); - bufferOffset = bufferOffset + byteCnt; - } - } - /* Release descriptors to DMA */ - DmaRxDesc = (EthHandle.stcRxFrame).pstcFSDesc; - for (i = 0UL; i < (EthHandle.stcRxFrame).u32SegCount; i++) { - DmaRxDesc->u32ControlStatus |= ETH_DMA_RXDESC_OWN; - DmaRxDesc = (stc_eth_dma_desc_t *)(DmaRxDesc->u32Buf2NextDescAddr); - } - /* Clear Segment_Count */ - (EthHandle.stcRxFrame).u32SegCount = 0UL; - - /* When Rx Buffer unavailable flag is set, clear it and resume reception */ - if (RESET != ETH_DMA_GetStatus(ETH_DMA_FLAG_RUS)) { - /* Clear DMA RUS flag */ - ETH_DMA_ClearStatus(ETH_DMA_FLAG_RUS); - /* Resume DMA reception */ - WRITE_REG32(CM_ETH->DMA_RXPOLLR, 0UL); - } - - return p; +void Time_Update_LwIP(void) { + //no need to do } /** @@ -485,8 +209,8 @@ err_t ethernetif_init(struct netif *netif) * You can instead declare your own function an call etharp_output() * from it if you have to do some checks before sending (e.g. if link * is available...) */ - netif->output = ðarp_output; - netif->linkoutput = &low_level_output; + netif->output = etharp_output; + netif->linkoutput = low_level_output; #endif /* initialize the hardware */ @@ -498,34 +222,38 @@ err_t ethernetif_init(struct netif *netif) * @param netif The network interface structure for this ethernetif. * @retval None */ -void ethernetif_input(struct netif *netif) +void ethernetif_input(void *netif_arg) { - err_t err; struct pbuf *p; + struct netif *netif = (struct netif *)netif_arg; + x_base critical_lock; /* Move received packet into a new pbuf */ - p = low_level_input(netif); - + while (1) { + sys_arch_sem_wait(get_eth_recv_sem(), WAITING_FOREVER); + while(1) { + p = low_level_input(netif); #ifndef ETHERNET_LOOPBACK_TEST - /* No packet could be read, silently ignore this */ - if (NULL == p) { - return; - } - - /* Entry point to the LwIP stack */ - err = netif->input(p, netif); - if (err != (err_t)ERR_OK) { - LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); - (void)pbuf_free(p); - } + /* Entry point to the LwIP stack */ + if (p != NULL) { + if (netif->input(p, netif) != ERR_OK) { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); + KPrintf("ethernetif_input: IP input error\n"); + pbuf_free(p); + p = NULL; + } + } else { + break; + } +#else + /* No packet could be read, silently ignore this */ + if (p != NULL) { + EthernetIF_InputCallback(netif, p); + free(p); + } #endif -#ifdef ETHERNET_LOOPBACK_TEST - /* No packet could be read, silently ignore this */ - if (p != NULL) { - EthernetIF_InputCallback(netif, p); - free(p); + } } -#endif } /** @@ -725,8 +453,7 @@ __WEAKDEF void EthernetIF_NotifyLinkChange(struct netif *netif) * @param p The MAC packet to receive * @retval None */ -__WEAKDEF void EthernetIF_InputCallback(struct netif *netif, struct pbuf *p) -{ +__WEAKDEF void EthernetIF_InputCallback(struct netif *netif, struct pbuf *p) { /* This is function could be implemented in user file when the callback is needed */ #ifdef ETHERNET_LOOPBACK_TEST if ((0 == (memcmp(p->payload, txPbuf.payload, p->len))) && (p->len == txPbuf.len)) { diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_ethernet.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_ethernet.h index 625c1d815..7fae45a9f 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_ethernet.h +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_ethernet.h @@ -22,11 +22,49 @@ #define CONNECT_ETHERNET_H #include "hardware_ethernetif.h" +#include +#include +#include #ifdef __cplusplus extern "C" { #endif +struct hc32_irq_config +{ + IRQn_Type irq_num; + uint32_t irq_prio; + en_int_src_t int_src; +}; + +/* Global Ethernet handle*/ +static stc_eth_handle_t EthHandle; +/* Ethernet Tx DMA Descriptor */ +__ALIGN_BEGIN static stc_eth_dma_desc_t EthDmaTxDscrTab[ETH_TX_BUF_NUM]; +/* Ethernet Rx DMA Descriptor */ +__ALIGN_BEGIN static stc_eth_dma_desc_t EthDmaRxDscrTab[ETH_RX_BUF_NUM]; +/* Ethernet Transmit Buffer */ +__ALIGN_BEGIN static uint8_t EthTxBuff[ETH_TX_BUF_NUM][ETH_TX_BUF_SIZE]; +/* Ethernet Receive Buffer */ +__ALIGN_BEGIN static uint8_t EthRxBuff[ETH_RX_BUF_NUM][ETH_RX_BUF_SIZE]; + +/* Ethernet link status */ +static uint8_t u8PhyLinkStatus = 0U, u8EthInitStatus = 0U; + +static struct Hc32IrqConfig eth_irq_config = { + .irq_num = BSP_ETH_IRQ_NUM, + .irq_prio = BSP_ETH_IRQ_PRIO, + .int_src = INT_SRC_ETH_GLB_INT, +}; + +void Ethernet_GpioInit(void); +int32_t low_level_init(struct netif *netif); +err_t low_level_output(struct netif *netif, struct pbuf *p); +struct pbuf *low_level_input(struct netif *netif); + +int HwEthInit(void); + + #ifdef __cplusplus } #endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/hardware_ethernetif.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/hardware_ethernetif.h index e07b5495e..a366fd075 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/hardware_ethernetif.h +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/hardware_ethernetif.h @@ -133,9 +133,37 @@ extern "C" * @addtogroup ETH_IF_Global_Functions * @{ */ +/* Define those to better describe your network interface. */ +#define IFNAME0 'h' +#define IFNAME1 'd' + +/* PHY hardware reset time */ +#define PHY_HW_RST_DELAY (0x40U) + +/* ETH_RST = PH11 */ +#define ETH_RST_PORT (GPIO_PORT_H) +#define ETH_RST_PIN (GPIO_PIN_11) + +/* ETH_LINK_LED = PD00 LED2 */ +#define ETH_LINK_LED_PORT (GPIO_PORT_D) +#define ETH_LINK_LED_PIN (GPIO_PIN_00) + +//#define ETHERNET_LOOPBACK_TEST +#ifdef ETHERNET_LOOPBACK_TEST + +#define USER_KEY_PORT (GPIO_PORT_I) +#define USER_KEY_PIN (GPIO_PIN_07) + +/* ethe global netif */ +static struct netif testnetif; +/* eth tx buffer */ +static struct pbuf txPbuf; +static char txBuf[] = "Ethernet Loop-Back Test"; +#endif + err_t ethernetif_init(struct netif *netif); -void ethernetif_input(struct netif *netif); -err_t low_level_output(struct netif *netif, struct pbuf *p); +void ethernetif_input(void *netif); +// err_t low_level_output(struct netif *netif, struct pbuf *p); void EthernetIF_CheckLink(struct netif *netif); void EthernetIF_UpdateLink(struct netif *netif); diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/timer/connect_hwtimer.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/timer/connect_hwtimer.c index d753db2c6..37ad87ec6 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/timer/connect_hwtimer.c +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/timer/connect_hwtimer.c @@ -163,7 +163,7 @@ static int BoardHwtimerDevBend(void) return ret; } -/*K210 BOARD HWTIMER INIT*/ +/*HC32F4A0 BOARD HWTIMER INIT*/ int HwTimerInit(void) { x_err_t ret = EOK; diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/Makefile b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/Makefile index 1c0cdf531..b59cbd62e 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/Makefile +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/Makefile @@ -2,10 +2,12 @@ SRC_DIR += api SRC_DIR += arch SRC_DIR += core SRC_DIR += netif +SRC_DIR += apps LWIP_DIR += api LWIP_DIR += arch LWIP_DIR += core LWIP_DIR += netif +LWIP_DIR += apps include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/apps/Makefile b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/apps/Makefile new file mode 100644 index 000000000..6f5f2913e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/apps/Makefile @@ -0,0 +1,3 @@ +SRC_FILES += lwiperf/lwiperf.c http/http_client.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/apps/http/http_client.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/apps/http/http_client.c index 82da60d73..9d6ca9cf3 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/apps/http/http_client.c +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/apps/http/http_client.c @@ -64,7 +64,8 @@ * HTTPC_DEBUG: Enable debugging for HTTP client. */ #ifndef HTTPC_DEBUG -#define HTTPC_DEBUG LWIP_DBG_OFF +#define HTTPC_DEBUG LWIP_DBG_ON +// #define HTTPC_DEBUG LWIP_DBG_OFF #endif /** Set this to 1 to keep server name and uri in request state */ diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/lwipopts.h b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/lwipopts.h index 698afb121..5bbd27f95 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/lwipopts.h +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/lwipopts.h @@ -30,6 +30,193 @@ #ifndef __LWIPOPTS_H__ #define __LWIPOPTS_H__ +/* ---------- Debug options ---------- */ +#ifndef LWIP_DEBUG +#define LWIP_DEBUG 1 +#endif + +#ifdef LWIP_DEBUG +#ifdef LWIP_SYS_DEBUG +#define SYS_DEBUG LWIP_DBG_ON +#else +#define SYS_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_ETHARP_DEBUG +#define ETHARP_DEBUG LWIP_DBG_ON +#else +#define ETHARP_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_PPP_DEBUG +#define PPP_DEBUG LWIP_DBG_ON +#else +#define PPP_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_MEM_DEBUG +#define MEM_DEBUG LWIP_DBG_ON +#else +#define MEM_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_MEMP_DEBUG +#define MEMP_DEBUG LWIP_DBG_ON +#else +#define MEMP_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_PBUF_DEBUG +#define PBUF_DEBUG LWIP_DBG_ON +#else +#define PBUF_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_API_LIB_DEBUG +#define API_LIB_DEBUG LWIP_DBG_ON +#else +#define API_LIB_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_API_MSG_DEBUG +#define API_MSG_DEBUG LWIP_DBG_ON +#else +#define API_MSG_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_TCPIP_DEBUG +#define TCPIP_DEBUG LWIP_DBG_ON +#else +#define TCPIP_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_NETIF_DEBUG +#define NETIF_DEBUG LWIP_DBG_ON +#else +#define NETIF_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_SOCKETS_DEBUG +#define SOCKETS_DEBUG LWIP_DBG_ON +#else +#define SOCKETS_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_DNS_DEBUG +#define DNS_DEBUG LWIP_DBG_ON +#else +#define DNS_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_AUTOIP_DEBUG +#define AUTOIP_DEBUG LWIP_DBG_ON +#else +#define AUTOIP_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_DHCP_DEBUG +#define DHCP_DEBUG LWIP_DBG_ON +#else +#define DHCP_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_IP_DEBUG +#define IP_DEBUG LWIP_DBG_ON +#else +#define IP_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_IP_REASS_DEBUG +#define IP_REASS_DEBUG LWIP_DBG_ON +#else +#define IP_REASS_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_ICMP_DEBUG +#define ICMP_DEBUG LWIP_DBG_ON +#else +#define ICMP_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_IGMP_DEBUG +#define IGMP_DEBUG LWIP_DBG_ON +#else +#define IGMP_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_UDP_DEBUG +#define UDP_DEBUG LWIP_DBG_ON +#else +#define UDP_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_TCP_DEBUG +#define TCP_DEBUG LWIP_DBG_ON +#else +#define TCP_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_TCP_INPUT_DEBUG +#define TCP_INPUT_DEBUG LWIP_DBG_ON +#else +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_TCP_OUTPUT_DEBUG +#define TCP_OUTPUT_DEBUG LWIP_DBG_ON +#else +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_TCP_RTO_DEBUG +#define TCP_RTO_DEBUG LWIP_DBG_ON +#else +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_TCP_CWND_DEBUG +#define TCP_CWND_DEBUG LWIP_DBG_ON +#else +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_TCP_WND_DEBUG +#define TCP_WND_DEBUG LWIP_DBG_ON +#else +#define TCP_WND_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_TCP_FR_DEBUG +#define TCP_FR_DEBUG LWIP_DBG_ON +#else +#define TCP_FR_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_TCP_QLEN_DEBUG +#define TCP_QLEN_DEBUG LWIP_DBG_ON +#else +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#endif + +#ifdef LWIP_TCP_RST_DEBUG +#define TCP_RST_DEBUG LWIP_DBG_ON +#else +#define TCP_RST_DEBUG LWIP_DBG_OFF +#endif + +#endif /* LWIP_DEBUG */ + + +#define LWIP_TIMEVAL_PRIVATE 0 +#define LWIP_NO_UNISTD_H 0 +#define LWIP_NO_STDDEF_H 0 +#define LWIP_NO_STDINT_H 0 +#define LWIP_NO_INTTYPES_H 0 +#define LWIP_NO_LIMITS_H 0 +#define LWIP_NO_CTYPE_H 0 +#define LWIP_SOCKET_SELECT 1 +#define LWIP_SOCKET_POLL 1 + /** * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain * critical regions during buffer allocation, deallocation and memory @@ -57,35 +244,40 @@ /* MEM_SIZE: the size of the heap memory. If the application will send a lot of data that needs to be copied, this should be set high. */ -#define MEM_SIZE (25*1024) +#define MEM_SIZE (64*1024) /* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application sends a lot of data out of ROM (or other static memory), this should be set high. */ -#define MEMP_NUM_PBUF 15 +#define MEMP_NUM_PBUF 32 /* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One per active UDP "connection". */ #define MEMP_NUM_UDP_PCB 4 /* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. */ -#define MEMP_NUM_TCP_PCB 4 +#define MEMP_NUM_TCP_PCB 64 /* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. */ #define MEMP_NUM_TCP_PCB_LISTEN 2 /* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. */ -#define MEMP_NUM_TCP_SEG 20 +#define MEMP_NUM_TCP_SEG 256 /* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. */ -#define MEMP_NUM_SYS_TIMEOUT 6 - +// #define MEMP_NUM_SYS_TIMEOUT 6 +#define MEMP_NUM_SYS_TIMEOUT (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT + (LWIP_IPV6 ? (1 + (2*LWIP_IPV6)) : 0)) /* ---------- Pbuf options ---------- */ /* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */ -#define PBUF_POOL_SIZE 20 +#define PBUF_POOL_SIZE 255 /* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */ +// #define PBUF_POOL_BUFSIZE 1024 #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) +/* ---------- ARP options ---------- */ +#define LWIP_ARP 1 +#define ARP_TABLE_SIZE 10 +#define ARP_QUEUEING 1 /* ---------- TCP options ---------- */ #define LWIP_TCP 1 @@ -93,7 +285,7 @@ a lot of data that needs to be copied, this should be set high. */ /* Controls if TCP should queue segments that arrive out of order. Define to 0 if your device is low on memory. */ -#define TCP_QUEUE_OOSEQ 0 +#define TCP_QUEUE_OOSEQ 1 /* TCP Maximum segment size. */ #define TCP_MSS (1500 - 40) /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */ @@ -107,9 +299,69 @@ a lot of data that needs to be copied, this should be set high. */ #define TCP_SND_QUEUELEN (8* TCP_SND_BUF/TCP_MSS) /* TCP receive window. */ -#define TCP_WND (12*TCP_MSS) +#define TCP_WND 8192 +// #define TCP_WND (12 * TCP_MSS) +/* Maximum number of retransmissions of data segments. */ +#define TCP_MAXRTX 12 + +/* Maximum number of retransmissions of SYN segments. */ +#define TCP_SYNMAXRTX 4 + +/** + * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT + * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set + * in seconds. (does not require sockets.c, and will affect tcp.c) + */ +#ifndef LWIP_TCP_KEEPALIVE +#define LWIP_TCP_KEEPALIVE 1 +#endif + +/** + * LWIP_NETIF_HOSTNAME==1: Support netif hostname + */ +#ifndef LWIP_NETIF_HOSTNAME +#define LWIP_NETIF_HOSTNAME 1 +#endif + +/** + * LWIP_NETIF_API==1: Support netif api (in netifapi.c) + */ +#ifndef LWIP_NETIF_API +#define LWIP_NETIF_API 1 +#endif + +/** + * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and + * SO_SNDTIMEO processing. + */ +#ifndef LWIP_SO_SNDTIMEO +#define LWIP_SO_SNDTIMEO 1 +#endif + +/** + * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and + * SO_RCVTIMEO processing. + */ +#ifndef LWIP_SO_RCVTIMEO +#define LWIP_SO_RCVTIMEO 1 +#endif + +/** + * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. + */ +#ifndef LWIP_SO_RCVBUF +#define LWIP_SO_RCVBUF 1 +#endif + +/** + * If LWIP_SO_RCVBUF is used, this is the default value for recv_bufsize. + */ +#ifndef RECV_BUFSIZE_DEFAULT +#define RECV_BUFSIZE_DEFAULT 8192 +#endif + /* ---------- ICMP options ---------- */ #define LWIP_ICMP 1 @@ -127,7 +379,6 @@ a lot of data that needs to be copied, this should be set high. */ /* ---------- Statistics options ---------- */ -#define LWIP_STATS 0 #define LWIP_PROVIDE_ERRNO 1 /* ---------- link callback options ---------- */ @@ -146,7 +397,7 @@ The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums - To use this feature let the following define uncommented. - To disable it and process by CPU comment the the checksum. */ -//#define CHECKSUM_BY_HARDWARE +#define CHECKSUM_BY_HARDWARE #ifdef CHECKSUM_BY_HARDWARE /* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/ @@ -176,7 +427,7 @@ The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums #define CHECKSUM_CHECK_UDP 1 /* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/ #define CHECKSUM_CHECK_TCP 1 - /* CHECKSUM_CHECK_ICMP==1: Check checksums by hardware for incoming ICMP packets.*/ + /* CHECKSUM_CHECK_ICMP==1: Check checksums by software for incoming ICMP packets.*/ #define CHECKSUM_GEN_ICMP 1 #endif @@ -225,7 +476,50 @@ The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums /** * LWIP_SO_LINGER==1: Enable SO_LINGER processing. */ -#define LWIP_SO_LINGER 1 +// #define LWIP_SO_LINGER 1 + +/* ---------- IP options ---------- */ +/* Define IP_FORWARD to 1 if you wish to have the ability to forward + IP packets across network interfaces. If you are going to run lwIP + on a device with only one network interface, define this to 0. */ +#define IP_FORWARD 0 + +/* IP reassembly and segmentation.These are orthogonal even + * if they both deal with IP fragments */ +#ifdef LWIP_REASSEMBLY_FRAG +#define IP_REASSEMBLY 1 +#define IP_FRAG 1 +#define IP_REASS_MAX_PBUFS 10 +#define MEMP_NUM_REASSDATA 10 +#else +#define IP_REASSEMBLY 0 +#define IP_FRAG 0 +#endif + +/* ---------- ICMP options ---------- */ +#define ICMP_TTL 255 + +/* ---------- DHCP options ---------- */ +/* Define LWIP_DHCP to 1 if you want DHCP configuration of + interfaces. */ +#define LWIP_DHCP 1 + +/* 1 if you want to do an ARP check on the offered address + (recommended). */ +#define DHCP_DOES_ARP_CHECK (LWIP_DHCP) + +/* ---------- AUTOIP options ------- */ +#define LWIP_AUTOIP 0 +#define LWIP_DHCP_AUTOIP_COOP (LWIP_DHCP && LWIP_AUTOIP) + + +#define LWIP_UDPLITE 0 +#define UDP_TTL 255 + + +/* ---------- Statistics options ---------- */ +#define LWIP_STATS 1 +#define LWIP_STATS_DISPLAY 1 /* --------------------------------- @@ -236,23 +530,21 @@ The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums #define DEFAULT_RAW_RECVMBOX_SIZE 8 #define DEFAULT_UDP_RECVMBOX_SIZE 8 #define DEFAULT_TCP_RECVMBOX_SIZE 8 -#define DEFAULT_ACCEPTMBOX_SIZE 8 +#define DEFAULT_ACCEPTMBOX_SIZE 10 #define DEFAULT_THREAD_PRIO 20 #define DEFAULT_THREAD_STACKSIZE 1024 #define TCPIP_THREAD_NAME "tcp" -#define TCPIP_THREAD_STACKSIZE 8192 -#define TCPIP_MBOX_SIZE 8 -#define TCPIP_THREAD_PRIO 15 +#define TCPIP_THREAD_STACKSIZE 1024 +#define TCPIP_MBOX_SIZE 16 +#define TCPIP_THREAD_PRIO 20 /* ---------------------------------------- ---------- Lwip Debug options ---------- ---------------------------------------- */ -#define LWIP_DEBUG 1 - #define LWIP_IPV4 1 #define LWIP_RAW 1 #define LWIP_DNS 1 diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.c index c7cb3b07e..281ad1f56 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.c +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.c @@ -69,96 +69,58 @@ #include "ethernet.h" #include "connect_ethernet.h" -char lwip_ipaddr[20] = {192, 168, 131, 77}; +char lwip_ipaddr[20] = {192, 168, 130, 77}; char lwip_netmask[20] = {255, 255, 254, 0}; -char lwip_gwaddr[20] = {192, 168, 131, 23}; +char lwip_gwaddr[20] = {192, 168, 130, 1}; -char lwip_eth0_ipaddr[20] = {192, 168, 131, 77}; +char lwip_eth0_ipaddr[20] = {192, 168, 130, 77}; char lwip_eth0_netmask[20] = {255, 255, 254, 0}; -char lwip_eth0_gwaddr[20] = {192, 168, 131, 23}; +char lwip_eth0_gwaddr[20] = {192, 168, 130, 1}; -char lwip_eth1_ipaddr[20] = {192, 168, 131, 99}; +char lwip_eth1_ipaddr[20] = {192, 168, 130, 99}; char lwip_eth1_netmask[20] = {255, 255, 254, 0}; -char lwip_eth1_gwaddr[20] = {192, 168, 131, 23}; +char lwip_eth1_gwaddr[20] = {192, 168, 130, 23}; char lwip_flag = 0; x_ticks_t lwip_sys_now; -struct sys_timeouts { - struct sys_timeo *next; -}; - -struct timeoutlist -{ - struct sys_timeouts timeouts; - int32 pid; -}; - #define SYS_THREAD_MAX 4 -static struct timeoutlist s_timeoutlist[SYS_THREAD_MAX]; +struct netif gnetif; +sys_sem_t* get_eth_recv_sem() { + static sys_sem_t g_recv_sem = 0; + return &g_recv_sem; +} -static u16_t s_nextthread = 0; +void sys_init(void) { + // do nothing +} u32_t -sys_jiffies(void) -{ +sys_jiffies(void) { lwip_sys_now = CurrentTicksGain(); return lwip_sys_now; } u32_t -sys_now(void) -{ +sys_now(void) { lwip_sys_now = CurrentTicksGain(); - return lwip_sys_now; + return CalculateTimeMsFromTick(lwip_sys_now); } -void -sys_init(void) -{ - int i; - for(i = 0; i < SYS_THREAD_MAX; i++) - { - s_timeoutlist[i].pid = 0; - s_timeoutlist[i].timeouts.next = NULL; - } - s_nextthread = 0; -} - -struct sys_timeouts *sys_arch_timeouts(void) -{ - int i; - int32 pid; - struct timeoutlist *tl; - pid = (int32)GetKTaskDescriptor()->id.id; - for(i = 0; i < s_nextthread; i++) - { - tl = &(s_timeoutlist[i]); - if(tl->pid == pid) - { - return &(tl->timeouts); - } - } - return NULL; -} - -sys_prot_t sys_arch_protect(void) -{ +sys_prot_t sys_arch_protect(void) { return CriticalAreaLock(); } -void sys_arch_unprotect(sys_prot_t pval) -{ +void sys_arch_unprotect(sys_prot_t pval) { CriticalAreaUnLock(pval); } #if !NO_SYS err_t -sys_sem_new(sys_sem_t *sem, u8_t count) -{ +sys_sem_new(sys_sem_t *sem, u8_t count) { *sem = KSemaphoreCreate((uint16)count); #if SYS_STATS @@ -170,8 +132,7 @@ sys_sem_new(sys_sem_t *sem, u8_t count) if(*sem >= 0) return ERR_OK; - else - { + else { #if SYS_STATS ++lwip_stats.sys.sem.err; #endif /* SYS_STATS */ @@ -181,8 +142,7 @@ sys_sem_new(sys_sem_t *sem, u8_t count) } void -sys_sem_free(sys_sem_t *sem) -{ +sys_sem_free(sys_sem_t *sem) { #if SYS_STATS --lwip_stats.sys.sem.used; #endif /* SYS_STATS */ @@ -190,19 +150,16 @@ sys_sem_free(sys_sem_t *sem) *sem = SYS_SEM_NULL; } -int sys_sem_valid(sys_sem_t *sem) -{ +int sys_sem_valid(sys_sem_t *sem) { return (*sem > SYS_SEM_NULL); } void -sys_sem_set_invalid(sys_sem_t *sem) -{ +sys_sem_set_invalid(sys_sem_t *sem) { *sem = SYS_SEM_NULL; } -u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) -{ +u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) { x_ticks_t start_tick = 0 ; int32 wait_time = 0; @@ -220,61 +177,51 @@ u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) if(KSemaphoreObtain(*sem, wait_time) == EOK) - return ((CurrentTicksGain()-start_tick)*MS_PER_SYSTICK); + return CalculateTimeMsFromTick(CurrentTicksGain()-start_tick); else return SYS_ARCH_TIMEOUT; } -void sys_sem_signal(sys_sem_t *sem) -{ - if(KSemaphoreAbandon( *sem ) != EOK) +void sys_sem_signal(sys_sem_t *sem) { + if(KSemaphoreAbandon(*sem) != EOK) KPrintf("[sys_arch]:sem signal fail!\n"); } -err_t sys_mutex_new(sys_mutex_t *mutex) -{ +err_t sys_mutex_new(sys_mutex_t *mutex) { *mutex = KMutexCreate(); - if(*mutex > SYS_MRTEX_NULL) + if (*mutex > SYS_MRTEX_NULL) return ERR_OK; - else - { + else { KPrintf("[sys_arch]:new mutex fail!\n"); return ERR_MEM; } } -void sys_mutex_free(sys_mutex_t *mutex) -{ +void sys_mutex_free(sys_mutex_t *mutex) { KMutexDelete(*mutex); } -void sys_mutex_set_invalid(sys_mutex_t *mutex) -{ +void sys_mutex_set_invalid(sys_mutex_t *mutex) { *mutex = SYS_MRTEX_NULL; } -void sys_mutex_lock(sys_mutex_t *mutex) -{ - KMutexObtain(*mutex, - WAITING_FOREVER); +void sys_mutex_lock(sys_mutex_t *mutex) { + KMutexObtain(*mutex, WAITING_FOREVER); } -void sys_mutex_unlock(sys_mutex_t *mutex) -{ - KMutexAbandon( *mutex ); +void sys_mutex_unlock(sys_mutex_t *mutex) { + KMutexAbandon(*mutex); } -sys_thread_t sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio) -{ +sys_thread_t sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio) { sys_thread_t handle = -1; handle = KTaskCreate(name, function, arg, (uint32)stacksize, (uint8)prio); - if (handle >= 0) - { + if (handle >= 0) { StartupKTask(handle); lw_print("lw: [%s] create %s handle %x\n", __func__, name, handle); return handle; @@ -283,8 +230,7 @@ sys_thread_t sys_thread_new(const char *name, lwip_thread_fn function, void *arg return -ERROR; } -err_t sys_mbox_new(sys_mbox_t *mbox, int size) -{ +err_t sys_mbox_new(sys_mbox_t *mbox, int size) { *mbox = KCreateMsgQueue(sizeof(void *), size); #if SYS_STATS @@ -293,8 +239,7 @@ err_t sys_mbox_new(sys_mbox_t *mbox, int size) lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used; } #endif /* SYS_STATS */ - if(*mbox < 0) - { + if(*mbox < 0) { lw_print("lw: [%s] alloc %d mbox %p failed\n", __func__, size, mbox); return ERR_MEM; } @@ -303,44 +248,38 @@ err_t sys_mbox_new(sys_mbox_t *mbox, int size) return ERR_OK; } -void sys_mbox_free(sys_mbox_t *mbox) -{ +void sys_mbox_free(sys_mbox_t *mbox) { KDeleteMsgQueue(*mbox); } -int sys_mbox_valid(sys_mbox_t *mbox) -{ +int sys_mbox_valid(sys_mbox_t *mbox) { if (*mbox <= SYS_MBOX_NULL) return 0; else return 1; } -void sys_mbox_set_invalid(sys_mbox_t *mbox) -{ +void sys_mbox_set_invalid(sys_mbox_t *mbox) { *mbox = SYS_MBOX_NULL; } -void sys_mbox_post(sys_mbox_t *q, void *msg) -{ - while(KMsgQueueSendwait( *q, &msg, sizeof(void *), WAITING_FOREVER) != EOK); +void sys_mbox_post(sys_mbox_t *q, void *msg) { + KMsgQueueSendwait(*q, &msg, sizeof(void *), WAITING_FOREVER); } -err_t sys_mbox_trypost(sys_mbox_t *q, void *msg) -{ +err_t sys_mbox_trypost(sys_mbox_t *q, void *msg) { + // if(KMsgQueueSend(*q, &msg, sizeof(void *)) == EOK) if(KMsgQueueSend(*q, &msg, sizeof(void *)) == EOK) return ERR_OK; else return ERR_MEM; } -err_t sys_mbox_trypost_fromisr(sys_mbox_t *q, void *msg) -{ +err_t sys_mbox_trypost_fromisr(sys_mbox_t *q, void *msg) { return sys_mbox_trypost(q, msg); } -u32_t sys_arch_mbox_fetch(sys_mbox_t *q, void **msg, u32_t timeout) -{ +u32_t sys_arch_mbox_fetch(sys_mbox_t *q, void **msg, u32_t timeout) { x_ticks_t start_tick = 0 ; int32 wait_time = 0; @@ -351,17 +290,15 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *q, void **msg, u32_t timeout) else wait_time = timeout; - if(KMsgQueueRecv(*q, &(*msg), sizeof(void *), wait_time) == EOK) - return ((CurrentTicksGain()-start_tick)*MS_PER_SYSTICK); - else{ - *msg = NULL; + if(KMsgQueueRecv(*q, &(*msg), sizeof(void *), wait_time) == EOK) { + return CalculateTimeMsFromTick(CurrentTicksGain() - start_tick); + } else { return SYS_ARCH_TIMEOUT; } } -u32_t sys_arch_mbox_tryfetch(sys_mbox_t *q, void **msg) -{ - if(KMsgQueueRecv(*q, &(*msg), sizeof(void *), 0) == EOK) +u32_t sys_arch_mbox_tryfetch(sys_mbox_t *q, void **msg) { + if (KMsgQueueRecv(*q, &(*msg), sizeof(void *), 0) == EOK) return ERR_OK; else return SYS_MBOX_EMPTY; @@ -374,97 +311,15 @@ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *q, void **msg) #endif /* !NO_SYS */ /* Variables Initialization */ -struct netif gnetif; ip4_addr_t ipaddr; ip4_addr_t netmask; ip4_addr_t gw; -void lwip_tcp_init(void) -{ - tcpip_init(NULL, NULL); - - /* IP addresses initialization */ - /* USER CODE BEGIN 0 */ -#if LWIP_DHCP - ip_addr_set_zero_ip4(&ipaddr); - ip_addr_set_zero_ip4(&netmask); - ip_addr_set_zero_ip4(&gw); -#else - IP4_ADDR(&ipaddr, lwip_ipaddr[0], lwip_ipaddr[1], lwip_ipaddr[2], lwip_ipaddr[3]); - IP4_ADDR(&netmask, lwip_netmask[0], lwip_netmask[1], lwip_netmask[2], lwip_netmask[3]); - IP4_ADDR(&gw, lwip_gwaddr[0], lwip_gwaddr[1], lwip_gwaddr[2], lwip_gwaddr[3]); -#endif /* USE_DHCP */ - /* USER CODE END 0 */ - /* Initilialize the LwIP stack without RTOS */ - /* add the network interface (IPv4/IPv6) without RTOS */ -#ifdef NETIF_ENET0_INIT_FUNC - netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, NETIF_ENET0_INIT_FUNC, &tcpip_input); -#endif - - /* Registers the default network interface */ - netif_set_default(&gnetif); - - if (netif_is_link_up(&gnetif)) - { - /* When the netif is fully configured this function must be called */ - KPrintf("%s : netif_set_up\n", __func__); - netif_set_up(&gnetif); - } - else - { - /* When the netif link is down this function must be called */ - KPrintf("%s : netif_set_down\n", __func__); - netif_set_down(&gnetif); - } - -#if LWIP_DHCP - int err; - /* Creates a new DHCP client for this interface on the first call. - Note: you must call dhcp_fine_tmr() and dhcp_coarse_tmr() at - the predefined regular intervals after starting the client. - You can peek in the netif->dhcp struct for the actual DHCP status.*/ - - - err = dhcp_start(&gnetif); - if(err == ERR_OK) - KPrintf("lwip dhcp init success...\n\n"); - else - KPrintf("lwip dhcp init fail...\n\n"); - while(ip_addr_cmp(&(gnetif.ip_addr),&ipaddr)) - { - DelayKTask(1); - } -#endif - KPrintf("\n\nIP:%d.%d.%d.%d\n\n", \ - ((gnetif.ip_addr.addr)&0x000000ff), \ - (((gnetif.ip_addr.addr)&0x0000ff00)>>8), \ - (((gnetif.ip_addr.addr)&0x00ff0000)>>16), \ - ((gnetif.ip_addr.addr)&0xff000000)>>24); -} - -// lwip input thread to get network packet -void lwip_input_thread(void *param) -{ - struct netif *net = param; - - while (1) - { -#ifdef FSL_RTOS_XIUOS - if (lwip_obtain_semaphore(net) == EOK) -#endif - { - /* Poll the driver, get any outstanding frames */ - ethernetif_input(net); - sys_check_timeouts(); /* Handle all system timeouts for all core protocols */ - } - } -} - -void lwip_config_input(struct netif *net) -{ +void lwip_config_input(struct netif *net) { sys_thread_t th_id = 0; - th_id = sys_thread_new("eth_input", lwip_input_thread, net, LWIP_TASK_STACK_SIZE, 15); + extern void ethernetif_input(void *netif_arg); + th_id = sys_thread_new("eth_input", ethernetif_input, net, LWIP_TASK_STACK_SIZE, 20); if (th_id >= 0) { lw_print("%s %d successfully!\n", __func__, th_id); @@ -473,15 +328,65 @@ void lwip_config_input(struct netif *net) } } -void lwip_config_net(uint8_t enet_port, char *ip, char *mask, char *gw) -{ +void lwip_config_tcp(uint8_t enet_port, char *ip, char *mask, char *gw) { ip4_addr_t net_ipaddr, net_netmask, net_gw; char* eth_cfg; eth_cfg = ethernetif_config_enet_set(enet_port); - if(chk_lwip_bit(LWIP_INIT_FLAG)) - { + if(chk_lwip_bit(LWIP_INIT_FLAG)) { + lw_print("lw: [%s] already ...\n", __func__); + return; + } + + set_lwip_bit(LWIP_INIT_FLAG); + + tcpip_init(NULL, NULL); + + lw_print("lw: [%s] start ...\n", __func__); + + IP4_ADDR(&net_ipaddr, ip[0], ip[1], ip[2], ip[3]); + IP4_ADDR(&net_netmask, mask[0], mask[1], mask[2], mask[3]); + IP4_ADDR(&net_gw, gw[0], gw[1], gw[2], gw[3]); + + if (0 == enet_port) { +#ifdef NETIF_ENET0_INIT_FUNC + printf("[%s:%d] call netif_add\n", __func__, __LINE__); + netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET0_INIT_FUNC, + tcpip_input); +#endif + } else if (1 == enet_port) { +#ifdef NETIF_ENET1_INIT_FUNC + netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET1_INIT_FUNC, + tcpip_input); +#endif + } + + netif_set_default(&gnetif); + netif_set_up(&gnetif); + + lw_print("\r\n************************************************\r\n"); + lw_print(" Network Configuration\r\n"); + lw_print("************************************************\r\n"); + lw_print(" IPv4 Address : %u.%u.%u.%u\r\n", ((u8_t *)&net_ipaddr)[0], ((u8_t *)&net_ipaddr)[1], + ((u8_t *)&net_ipaddr)[2], ((u8_t *)&net_ipaddr)[3]); + lw_print(" IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t *)&net_netmask)[0], ((u8_t *)&net_netmask)[1], + ((u8_t *)&net_netmask)[2], ((u8_t *)&net_netmask)[3]); + lw_print(" IPv4 Gateway : %u.%u.%u.%u\r\n", ((u8_t *)&net_gw)[0], ((u8_t *)&net_gw)[1], + ((u8_t *)&net_gw)[2], ((u8_t *)&net_gw)[3]); + lw_print("************************************************\r\n"); + + lwip_config_input(&gnetif); +} + + +void lwip_config_net(uint8_t enet_port, char *ip, char *mask, char *gw) { + ip4_addr_t net_ipaddr, net_netmask, net_gw; + char* eth_cfg; + + eth_cfg = ethernetif_config_enet_set(enet_port); + + if(chk_lwip_bit(LWIP_INIT_FLAG)) { lw_print("lw: [%s] already ...\n", __func__); IP4_ADDR(&net_ipaddr, ip[0], ip[1], ip[2], ip[3]); @@ -521,8 +426,7 @@ void lwip_config_net(uint8_t enet_port, char *ip, char *mask, char *gw) netif_set_default(&gnetif); netif_set_up(&gnetif); - if(chk_lwip_bit(LWIP_PRINT_FLAG)) - { + if(chk_lwip_bit(LWIP_PRINT_FLAG)) { lw_notice("\r\n************************************************\r\n"); lw_notice(" Network Configuration\r\n"); lw_notice("************************************************\r\n"); @@ -537,55 +441,3 @@ void lwip_config_net(uint8_t enet_port, char *ip, char *mask, char *gw) lwip_config_input(&gnetif); } -void lwip_config_tcp(uint8_t enet_port, char *ip, char *mask, char *gw) -{ - ip4_addr_t net_ipaddr, net_netmask, net_gw; - char* eth_cfg; - - eth_cfg = ethernetif_config_enet_set(enet_port); - - if(chk_lwip_bit(LWIP_INIT_FLAG)) - { - lw_print("lw: [%s] already ...\n", __func__); - return; - } - - set_lwip_bit(LWIP_INIT_FLAG); - - tcpip_init(NULL, NULL); - - lw_print("lw: [%s] start ...\n", __func__); - - IP4_ADDR(&net_ipaddr, ip[0], ip[1], ip[2], ip[3]); - IP4_ADDR(&net_netmask, mask[0], mask[1], mask[2], mask[3]); - IP4_ADDR(&net_gw, gw[0], gw[1], gw[2], gw[3]); - - if(0 == enet_port) { -#ifdef NETIF_ENET0_INIT_FUNC - netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET0_INIT_FUNC, - ethernet_input); -#endif - } else if (1 == enet_port) { -#ifdef NETIF_ENET1_INIT_FUNC - netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET1_INIT_FUNC, - ethernet_input); -#endif - } - - netif_set_default(&gnetif); - netif_set_up(&gnetif); - - lw_print("\r\n************************************************\r\n"); - lw_print(" Network Configuration\r\n"); - lw_print("************************************************\r\n"); - lw_print(" IPv4 Address : %u.%u.%u.%u\r\n", ((u8_t *)&net_ipaddr)[0], ((u8_t *)&net_ipaddr)[1], - ((u8_t *)&net_ipaddr)[2], ((u8_t *)&net_ipaddr)[3]); - lw_print(" IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t *)&net_netmask)[0], ((u8_t *)&net_netmask)[1], - ((u8_t *)&net_netmask)[2], ((u8_t *)&net_netmask)[3]); - lw_print(" IPv4 Gateway : %u.%u.%u.%u\r\n", ((u8_t *)&net_gw)[0], ((u8_t *)&net_gw)[1], - ((u8_t *)&net_gw)[2], ((u8_t *)&net_gw)[3]); - lw_print("************************************************\r\n"); - - lwip_config_input(&gnetif); -} - diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.h b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.h index 517f5c014..e606c710b 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.h +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.h @@ -54,7 +54,7 @@ #define LWIP_TARGET_PORT LWIP_LOCAL_PORT #define LWIP_DEMO_TIMES 10 -#define LWIP_TASK_STACK_SIZE 4096 +#define LWIP_TASK_STACK_SIZE 1536 #define LWIP_DEMO_TASK_PRIO 20 // /* MAC address configuration. */ @@ -72,7 +72,8 @@ typedef int32 sys_mbox_t; typedef int32 sys_thread_t; typedef x_base sys_prot_t; -#define MS_PER_SYSTICK (1000 / TICK_PER_SECOND) +#define MS_PER_SYSTICK (float)(1000 / TICK_PER_SECOND) +#define TICKS_PER_MS (TICK_PER_SECOND / 1000) //debug rtos with IRQ //#define FSL_RTOS_XIUOS @@ -99,6 +100,7 @@ extern char lwip_eth1_netmask[]; extern char lwip_eth1_gwaddr[]; extern struct netif gnetif; +extern sys_sem_t* get_eth_recv_sem(); void lwip_tcp_init(void); void lwip_config_net(uint8_t enet_port, char *ip, char *mask, char *gw); diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/debug.h b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/debug.h index 0711078cd..cbddaf146 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/debug.h +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/debug.h @@ -142,18 +142,22 @@ #endif #ifdef LWIP_DEBUG -#define LWIP_DEBUGF(debug, message) do { \ +#define LWIP_DEBUGF(debug_flag, message) do { \ if ( \ - ((debug) & LWIP_DBG_ON) && \ - ((debug) & LWIP_DBG_TYPES_ON) && \ - ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \ + ((debug_flag) & LWIP_DBG_ON) && \ + ((debug_flag) & LWIP_DBG_TYPES_ON) && \ + (debug_flag)) { \ LWIP_PLATFORM_DIAG(message); \ - if ((debug) & LWIP_DBG_HALT) { \ + if ((debug_flag) & LWIP_DBG_HALT) { \ while(1); \ } \ } \ } while(0) + // ((s16_t)((debug_flag) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \ +// #define LWIP_DEBUGF(debug, message) do { \ +// LWIP_PLATFORM_DIAG(message); \ +// } while(0) #else /* LWIP_DEBUG */ #define LWIP_DEBUGF(debug, message) #endif /* LWIP_DEBUG */ diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/Makefile b/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/Makefile index 9426c8faf..697c6c141 100755 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/Makefile +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/Makefile @@ -1,3 +1,4 @@ -SRC_FILES := ping.c lwip_ping_demo.c lwip_tcp_demo.c lwip_udp_demo.c tcpecho_raw.c lwip_config_demo.c lwip_dhcp_demo.c +SRC_FILES := ping.c lwip_ping_demo.c lwip_tcp_demo.c tcpecho_raw.c lwip_config_demo.c lwip_dhcp_demo.c iperf.c http_test.c +# SRC_FILES := ping.c lwip_ping_demo.c lwip_tcp_demo.c lwip_udp_demo.c tcpecho_raw.c lwip_config_demo.c lwip_dhcp_demo.c iperf.c include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/http_test.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/http_test.c new file mode 100644 index 000000000..911eebfc0 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/http_test.c @@ -0,0 +1,68 @@ + +#include +#include +#include + +#include "lwip/apps/http_client.h" + +void httpc_app_recv_end(void *arg, httpc_result_t httpc_result, u32_t rx_content_len, u32_t srv_res, err_t err) { + httpc_state_t **req = (httpc_state_t**)arg; + + LWIP_DEBUGF(LWIP_DEBUG, ("[HTTPC] Transfer finished. rx_content_len is %lu\r\n", rx_content_len)); + printf("[HTTPC] Transfer finished. rx_content_len is %lu\r\n", rx_content_len); + *req = NULL; +} + + +err_t httpc_app_headers_done(httpc_state_t *connection, void *arg, struct pbuf *hdr, u16_t hdr_len, u32_t content_len) { + LWIP_DEBUGF(LWIP_DEBUG, ("[%s] headers done call back.\n", __func__)); + printf("[%s] headers done call back, content len: %d.\n", __func__, content_len); + return ERR_OK; +} + +err_t httpc_app_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { + printf("[%s] Get %d Data\n", __func__, p->len); + + pbuf_free(p); + return ERR_OK; +} + +ip_addr_t *get_server_ip() { + static ip_addr_t server_ip; + return &server_ip; +} + +httpc_state_t **get_conn_state() { + static httpc_state_t *conn_state; + return &conn_state; +} + +httpc_connection_t *get_conn_setting() { + static httpc_connection_t conn_setting; + return &conn_setting; +} + +void httpc_get_file_app(int argc, char *argv[]) { + // deal input ip + + // get file from server + const uint8_t server_ip_by_arr[4] = {39, 156, 66, 10}; + // const uint8_t server_ip_by_arr[4] = {114, 215, 151, 106}; + IP4_ADDR(get_server_ip(), + server_ip_by_arr[0], server_ip_by_arr[1], server_ip_by_arr[2], server_ip_by_arr[3]); + + get_conn_setting()->use_proxy = 0; + get_conn_setting()->result_fn = httpc_app_recv_end; + get_conn_setting()->headers_done_fn = httpc_app_headers_done; + + LWIP_DEBUGF(HTTPC_DEBUG, ("[%s] Calling httpc_get_file\n", __func__)); + printf("[%s] Calling httpc_get_file\n", __func__); + err_t errnum = httpc_get_file(get_server_ip(), 80, "/index.html", get_conn_setting(), httpc_app_recv, NULL, get_conn_state()); + // err_t errnum = httpc_get_file_dns("https://www.baidu.com", 80, "/index.html", get_conn_setting(), httpc_app_recv, NULL, get_conn_state()); + + if (errnum != ERR_OK) { + printf("httpc_get_file failed (%d)\n", errnum); + } +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0), + lwip_http_test, httpc_get_file_app, get file from net server); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/iperf.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/iperf.c new file mode 100644 index 000000000..29c947a18 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/iperf.c @@ -0,0 +1,686 @@ +/** +* iperf-liked network performance tool +* +*/ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "lwip/sockets.h" +#include +#include + +#define IPERF_PORT 5001 +#define IPERF_BUFSZ (4 * 1024) + +#define IPERF_MODE_STOP 0 +#define IPERF_MODE_SERVER 1 +#define IPERF_MODE_CLIENT 2 + +typedef struct{ + int mode; + char *host; + int port; +} IPERF_PARAM; +static IPERF_PARAM param = {IPERF_MODE_STOP, NULL, IPERF_PORT}; + +char tcp_iperf_ip[] = {192, 168, 130, 77}; +char tcp_iperf_mask[] = {255, 255, 254, 0}; +char tcp_iperf_gw[] = {192, 168, 130, 1}; + +static void iperf_udp_client(void *thread_param) +{ + int sock; + uint32 *buffer; + struct sockaddr_in server; + uint32 packet_count = 0; + uint32 tick; + int send_size; + + send_size = IPERF_BUFSZ > 1470 ? 1470 : IPERF_BUFSZ; + + sock = socket(PF_INET, SOCK_DGRAM, 0); + if(sock < 0){ + KPrintf("[%s:%d] can't create socket! exit!\n", __FILE__, __LINE__); + return; + } + + server.sin_family = PF_INET; + server.sin_port = htons(param.port); + server.sin_addr.s_addr = inet_addr(param.host); + memset(&(server.sin_zero), 0, sizeof(server.sin_zero)); + + if (connect(sock, (struct sockaddr *)&server, sizeof(struct sockaddr))){ + lw_error("Unable to connect\n"); + closesocket(sock); + return; + } + + buffer = malloc(IPERF_BUFSZ); + if (buffer == NULL){ + printf("[%s:%d] malloc failed\n", __FILE__, __LINE__); + return; + } + memset(buffer, 0x00, IPERF_BUFSZ); + + KPrintf("iperf udp mode run...\n"); + while (param.mode != IPERF_MODE_STOP){ + packet_count++; + tick = CurrentTicksGain(); + buffer[0] = htonl(packet_count); + buffer[1] = htonl(tick / TICK_PER_SECOND); + buffer[2] = htonl((tick % TICK_PER_SECOND) * 1000); + sendto(sock, buffer, send_size, 0, (struct sockaddr *)&server, sizeof(struct sockaddr_in)); + } + closesocket(sock); + free(buffer); + KPrintf("iperf udp mode exit...\n"); +} + +static void iperf_udp_server(void *thread_param) +{ + int sock; + uint32 *buffer; + struct sockaddr_in server; + struct sockaddr_in sender; + int sender_len, r_size; + uint64 sentlen; + uint32 pcount = 0, last_pcount = 0; + uint32 lost, total; + x_ticks_t tick1, tick2; + struct timeval timeout; + + buffer = malloc(IPERF_BUFSZ); + if (buffer == NULL){ + return; + } + + sock = socket(PF_INET, SOCK_DGRAM, 0); + if(sock < 0){ + KPrintf("can't create socket! exit!"); + return; + } + + server.sin_family = PF_INET; + server.sin_port = htons(param.port); + server.sin_addr.s_addr = inet_addr("0.0.0.0"); + + timeout.tv_sec = 2; + timeout.tv_usec = 0; + if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == -1){ + KPrintf("setsockopt failed!"); + closesocket(sock); + free(buffer); + return; + } + + if (bind(sock, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) < 0){ + KPrintf("iperf server bind failed! exit!"); + closesocket(sock); + free(buffer); + return; + } + + while (param.mode != IPERF_MODE_STOP){ + tick1 = CurrentTicksGain(); + tick2 = tick1; + lost = 0; + total = 0; + sentlen = 0; + while ((tick2 - tick1) < (TICK_PER_SECOND * 5)){ + r_size = recvfrom(sock, buffer, IPERF_BUFSZ, 0, (struct sockaddr *)&sender, (socklen_t*)&sender_len); + if (r_size > 12){ + pcount = ntohl(buffer[0]); + if (last_pcount < pcount){ + lost += pcount - last_pcount - 1; + total += pcount - last_pcount; + } + else{ + last_pcount = pcount; + } + last_pcount = pcount; + sentlen += r_size; + } + tick2 = CurrentTicksGain(); + } + if (sentlen > 0){ + long data; + int integer, decimal; + KTaskDescriptorType tid; + + tid = GetKTaskDescriptor(); + data = sentlen * TICK_PER_SECOND / 125 / (tick2 - tick1); + integer = data/1000; + decimal = data%1000; + KPrintf("%s: %d.%03d0 Mbps! lost:%d total:%d\n", tid->task_base_info.name, integer, decimal, lost, total); + } + } + free(buffer); + closesocket(sock); +} + +static void iperf_client(void *thread_param) +{ + int i; + int sock; + int ret; + int tips = 1; + uint8_t *send_buf; + uint64 sentlen; + x_ticks_t tick1, tick2; + struct sockaddr_in addr; + + send_buf = (uint8_t *) malloc(IPERF_BUFSZ); + if (!send_buf) return ; + + for (i = 0; i < IPERF_BUFSZ; i ++) + send_buf[i] = i & 0xff; + + while (param.mode != IPERF_MODE_STOP) + { + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0){ + KPrintf("create socket failed!"); + DelayKTask(TICK_PER_SECOND); + continue; + } + + addr.sin_family = PF_INET; + addr.sin_port = htons(param.port); + addr.sin_addr.s_addr = inet_addr((char *)param.host); + + ret = connect(sock, (const struct sockaddr *)&addr, sizeof(addr)); + if (ret == -1){ + if (tips){ + KPrintf("Connect to iperf server faile, Waiting for the server to open!"); + tips = 0; + } + closesocket(sock); + DelayKTask(TICK_PER_SECOND); + continue; + } + KPrintf("Connect to iperf server successful!\n"); + + { + int flag = 1; + + setsockopt(sock, + IPPROTO_TCP, /* set option at TCP level */ + TCP_NODELAY, /* name of option */ + (void *) &flag, /* the cast is historical cruft */ + sizeof(int)); /* length of option value */ + } + + sentlen = 0; + + tick1 = CurrentTicksGain(); + while (param.mode != IPERF_MODE_STOP){ + tick2 = CurrentTicksGain(); + if (tick2 - tick1 >= TICK_PER_SECOND * 5){ + double speed; + // int integer, decimal; + KTaskDescriptorType tid; + + tid = GetKTaskDescriptor(); + speed = (double)(sentlen * TICK_PER_SECOND / 125 / (tick2 - tick1)); + speed = speed / 1000.0f; + printf("%s: %2.4f Mbps!\n", tid->task_base_info.name, speed); + tick1 = tick2; + sentlen = 0; + } + + ret = send(sock, send_buf, IPERF_BUFSZ, 0); + if (ret > 0){ + sentlen += ret; + } + + if (ret < 0) break; + } + + closesocket(sock); + + DelayKTask(TICK_PER_SECOND * 2); + KPrintf("Disconnected, iperf server shut down!"); + tips = 1; + } + free(send_buf); +} + +// iperf tcp server running thread +struct sock_conn_cb { + struct sockaddr_in server_addr; + struct sockaddr_in client_addr; + int connected; + int parent_id; +}; + +void iperf_sever_worker(void* arg) { + struct sock_conn_cb *sccb = (struct sock_conn_cb *)arg; + x_ticks_t tick1, tick2; + + uint8_t *recv_data = (uint8_t *)malloc(IPERF_BUFSZ); + if(recv_data == NULL) { + KPrintf("[%s] No Memory.\n", __func__); + goto exit__; + } + + uint64 recvlen = 0; + int32_t bytes_received = 0; + + int flag = 1; + setsockopt(sccb->connected, + IPPROTO_TCP, /* set option at TCP level */ + TCP_NODELAY, /* name of option */ + (void *) &flag, /* the cast is historical cruft */ + sizeof(int)); /* length of option value */ + + int cur_tid = GetKTaskDescriptor()->id.id; + + tick1 = CurrentTicksGain(); + while (param.mode != IPERF_MODE_STOP){ + bytes_received = recv(sccb->connected, recv_data, IPERF_BUFSZ, 0); + if (bytes_received == 0) { + KPrintf("client disconnected (%s, %d)\n", + inet_ntoa(sccb->client_addr.sin_addr), ntohs(sccb->client_addr.sin_port)); + break; + } else if (bytes_received < 0) { + KPrintf("recv error, client: (%s, %d)\n", + inet_ntoa(sccb->client_addr.sin_addr), ntohs(sccb->client_addr.sin_port)); + break; + } + + recvlen += bytes_received; + + tick2 = CurrentTicksGain(); + if (tick2 - tick1 >= TICK_PER_SECOND * 5) { + double speed; + // int integer, decimal; + KTaskDescriptorType tid; + + tid = GetKTaskDescriptor(); + speed = (double)(recvlen * TICK_PER_SECOND / (125 * (tick2 - tick1))); + speed = speed / 1000.0f; + printf("%s%d: %2.4f Mbps!\n", + tid->task_base_info.name, cur_tid - sccb->parent_id, speed); + tick1 = tick2; + recvlen = 0; + } + } + free(recv_data); + +exit__: + if (sccb->connected >= 0) closesocket(sccb->connected); + sccb->connected = -1; + free(sccb); + KPrintf("iperf server %d quiting.\n", cur_tid - sccb->parent_id); +} + +void iperf_server_multithread(void *thread_param) +{ + socklen_t sin_size; + x_ticks_t tick1, tick2; + int sock; + int connected; + struct sockaddr_in server_addr, client_addr; + fd_set readset; + struct timeval timeout; + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0){ + KPrintf("[%s:%d] Socket error!\n", __FILE__, __LINE__); + goto __exit; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(param.port); + server_addr.sin_addr.s_addr = INADDR_ANY; + memset(&(server_addr.sin_zero), 0x0, sizeof(server_addr.sin_zero)); + + if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1){ + KPrintf("Unable to bind!\n"); + goto __exit; + } + + if (listen(sock, 5) == -1){ + KPrintf("Listen error!\n"); + goto __exit; + } + + int cur_tid = GetKTaskDescriptor()->id.id; + + timeout.tv_sec = 5; + timeout.tv_usec = 0; + while (param.mode != IPERF_MODE_STOP){ + FD_ZERO(&readset); + FD_SET(sock, &readset); + + if (select(sock + 1, &readset, NULL, NULL, &timeout) == 0) { + continue; + } + + sin_size = sizeof(struct sockaddr_in); + + connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size); + + printf("new client connected from (%s, %d)\n", + inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); + struct sock_conn_cb *sccb = malloc(sizeof(struct sock_conn_cb)); + sccb->connected = connected; + sccb->client_addr = client_addr; + sccb->server_addr = server_addr; + sccb->parent_id = cur_tid; + int tid = KTaskCreate("iperf server", iperf_sever_worker, sccb, LWIP_TASK_STACK_SIZE, 20); + // iperf_sever_worker(sccb); + if (tid) { + StartupKTask(tid); + } else { + KPrintf("[%s] Failed to create server worker.\n", __func__); + free(sccb); + } + } + +__exit: + if (sock >= 0) closesocket(sock); +} + +void iperf_server(void *thread_param) +{ + uint8_t *recv_data; + socklen_t sin_size; + x_ticks_t tick1, tick2; + int sock = -1, connected, bytes_received; + uint64 recvlen; + struct sockaddr_in server_addr, client_addr; + fd_set readset; + struct timeval timeout; + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0){ + KPrintf("[%s:%d] Socket error!\n", __FILE__, __LINE__); + goto __exit; + } + + recv_data = (uint8_t *)malloc(IPERF_BUFSZ); + if (recv_data == NULL){ + KPrintf("No memory!\n"); + goto __exit; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(param.port); + server_addr.sin_addr.s_addr = INADDR_ANY; + memset(&(server_addr.sin_zero), 0x0, sizeof(server_addr.sin_zero)); + + if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1){ + KPrintf("Unable to bind!\n"); + goto __exit; + } + + if (listen(sock, 5) == -1){ + KPrintf("Listen error!\n"); + goto __exit; + } + + timeout.tv_sec = 3; + timeout.tv_usec = 0; + + while (param.mode != IPERF_MODE_STOP){ + FD_ZERO(&readset); + FD_SET(sock, &readset); + + if (select(sock + 1, &readset, NULL, NULL, &timeout) == 0) { + continue; + } + + sin_size = sizeof(struct sockaddr_in); + + connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size); + + printf("new client connected from (%s, %d)\n", + inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); + + int flag = 1; + setsockopt(connected, + IPPROTO_TCP, /* set option at TCP level */ + TCP_NODELAY, /* name of option */ + (void *) &flag, /* the cast is historical cruft */ + sizeof(int)); /* length of option value */ + + recvlen = 0; + tick1 = CurrentTicksGain(); + while (param.mode != IPERF_MODE_STOP){ + bytes_received = recv(connected, recv_data, IPERF_BUFSZ, 0); + if (bytes_received == 0) { + KPrintf("client disconnected (%s, %d)\n", + inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); + break; + } else if (bytes_received < 0) { + KPrintf("recv error, client: (%s, %d)\n", + inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); + break; + } + + recvlen += bytes_received; + + tick2 = CurrentTicksGain(); + if (tick2 - tick1 >= TICK_PER_SECOND * 5) { + double speed; + // int integer, decimal; + KTaskDescriptorType tid; + + tid = GetKTaskDescriptor(); + speed = (double)(recvlen * TICK_PER_SECOND / (125 * (tick2 - tick1))); + speed = speed / 1000.0f; + printf("%s: %2.4f Mbps!\n", tid->task_base_info.name, speed); + tick1 = tick2; + recvlen = 0; + } + } + if (connected >= 0) closesocket(connected); + connected = -1; + } + +__exit: + if (sock >= 0) closesocket(sock); + if (recv_data) free(recv_data); +} + +void iperf_usage(void) +{ + KPrintf("Usage: iperf [-s|-c host] [options] [multi-threaded]\n"); + KPrintf(" iperf [-h|--stop]\n"); + KPrintf("\n"); + KPrintf("Client/Server:\n"); + KPrintf(" -p # server port to listen on/connect to\n"); + KPrintf("\n"); + KPrintf("Server specific:\n"); + KPrintf(" -s run in server mode\n"); + KPrintf("\n"); + KPrintf("Client specific:\n"); + KPrintf(" -c run in client mode, connecting to \n"); + KPrintf("\n"); + KPrintf("Miscellaneous:\n"); + KPrintf(" -h print this message and quit\n"); + KPrintf(" --stop stop iperf program\n"); + KPrintf(" -u testing UDP protocol\n"); + KPrintf(" -m