diff --git a/kernel/bsp/imx6ull-artpi-smart/drivers/drv_eth.c b/kernel/bsp/imx6ull-artpi-smart/drivers/drv_eth.c index 74b3b5b1c2a3301cc38b87120cf0258888c1f825..63a50defc825669dc47ba0286b12c0c61c5b2b7b 100644 --- a/kernel/bsp/imx6ull-artpi-smart/drivers/drv_eth.c +++ b/kernel/bsp/imx6ull-artpi-smart/drivers/drv_eth.c @@ -15,24 +15,23 @@ #define DBG_LVL DBG_LOG #include -#define BSP_USING_IMX6ULL_ART_PI -#if (defined(RT_USING_ENET1)) || (defined(RT_USING_ENET2)) -#ifdef BSP_USING_IMX6ULL_ART_PI +#if (defined(RT_USING_ENET1)) || (defined(RT_USING_ENET2)) -static struct imx6ull_iomuxc mdio_gpio[2] = +static struct imx6ull_iomuxc mdio_gpio[] = { +#ifdef RT_USING_ENET1 {IOMUXC_GPIO1_IO06_ENET1_MDIO,0U,0xB029}, - {IOMUXC_GPIO1_IO07_ENET1_MDC,0U,0xB0E9} -}; -#else -static struct imx6ull_iomuxc mdio_gpio[2] = -{ + {IOMUXC_GPIO1_IO07_ENET1_MDC,0U,0xB0E9}, +#endif + +#ifdef RT_USING_ENET2 {IOMUXC_GPIO1_IO06_ENET2_MDIO,0U,0xB029}, {IOMUXC_GPIO1_IO07_ENET2_MDC,0U,0xB0E9}, +#endif }; -#endif + enum { #ifdef RT_USING_ENET1 @@ -426,20 +425,19 @@ struct pbuf *rt_imx6ul_eth_rx(rt_device_t dev) int32_t get_instance_by_base(void *base) { - int32_t i = 0; - int32_t instance = 0; + uint32_t i = 0; + for(i = 0; i < DEV_ENET_MAX; i ++) { if((void *)_imx6ul_eth_device[i].enet_virtual_base_addr == base) { - break; + return i; } } - if(i == DEV_ENET_MAX) + if(i >= DEV_ENET_MAX) { return -1; } - return instance; } void rx_enet_callback(void *base) @@ -466,9 +464,12 @@ static void phy_detect_thread_entry(void *param) bool link = false; phy_speed_t speed; phy_duplex_t duplex; - ENET_Type *base_addr = RT_NULL; + static ENET_Type *base_addr = RT_NULL; struct rt_imx6ul_ethps *imx6ul_device = (struct rt_imx6ul_ethps *)param; - base_addr = imx6ul_device->enet_virtual_base_addr; + if(base_addr == RT_NULL) + { + base_addr = imx6ul_device->enet_virtual_base_addr; + } phy_reset(imx6ul_device->phy_base_addr,imx6ul_device->phy_gpio_pin); PHY_Init(base_addr, imx6ul_device->phy_num, SYS_CLOCK_HZ,imx6ul_device->phy_id); @@ -483,7 +484,7 @@ static void phy_detect_thread_entry(void *param) } else { - LOG_E("\r\nPHY Link down, please check the cable connection and link partner setting.\r\n"); + LOG_E("PHY%d Link down, please check the cable connection and link partner setting.", imx6ul_device->mac_num); } while(1) @@ -515,12 +516,10 @@ _internal_ro struct rt_device_ops _k_enet_ops = static int imx6ul_eth_init(void) { rt_err_t state = RT_EOK; - char link_detect[10]; + char link_detect[10] = {0}; - #if 1 imx6ull_gpio_init(&mdio_gpio[0]); imx6ull_gpio_init(&mdio_gpio[1]); - #endif for (int idx=0; idx +#include +#include + +extern int _tftp_msh(int argc, char *argv[]); + +int main(int argc, char **argv) +{ + _tftp_msh(argc, argv); + + return 0; +} diff --git a/userapps/apps/tftp/packages/SConscript b/userapps/apps/tftp/packages/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..ca95be14e2b891254901c1c1737c0784d9972abb --- /dev/null +++ b/userapps/apps/tftp/packages/SConscript @@ -0,0 +1,12 @@ +import os +from building import * + +objs = [] +cwd = GetCurrentDir() +list = os.listdir(cwd) + +for item in list: + if os.path.isfile(os.path.join(cwd, item, 'SConscript')): + objs = objs + SConscript(os.path.join(item, 'SConscript')) + +Return('objs') diff --git a/userapps/apps/tftp/packages/netutils-latest/LICENSE b/userapps/apps/tftp/packages/netutils-latest/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64 --- /dev/null +++ b/userapps/apps/tftp/packages/netutils-latest/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/userapps/apps/tftp/packages/netutils-latest/README.md b/userapps/apps/tftp/packages/netutils-latest/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ab91c41dd0bdd643b808a3bae6640be0c8cf3161 --- /dev/null +++ b/userapps/apps/tftp/packages/netutils-latest/README.md @@ -0,0 +1,27 @@ +# RT-Thread Network Gadgets Collection + +[Chinese](README_ZH.md) | English + +## 1 Introduction + +When RT-Thread is connected to the network, the playability is greatly enhanced. Here is a collection of all the web widgets available for RT-Thread, and all the widgets you need can be found here. + +## 2. How to obtain + +Please use ENV tool to assist download: + +The path of the package is: `RT-Thread online package` -> `IoT-internet of things` -> `netutils` + +## 3. Instructions for use + +Each gadget can be enabled/disabled independently using menuconfig and provides commands for using Finsh/MSH. There is a detailed usage document in its catalog. If you need to use it, please check separately. The following is a summary of currently supported gadgets: + +| Name | Classification | Function Introduction | Use Document | +| :--------------------------- | :------: | :--------------------------------------------------------- | :---------------------------- | +| [Ping](ping/README-en.md) | Debugging test | Use the "ping" command to check whether the network is connected, which can help us analyze and determine network failures | [click to view](ping/README-en.md) | +| [TFTP](tftp/README-en.md) | File transfer | TFTP is a simple protocol for transferring files, which is lighter than FTP | [click to view](tftp/README-en.md) | +| [iperf](iperf/README-en.md) | Performance Test | Test maximum TCP and UDP bandwidth performance, report bandwidth, delay jitter and packet loss | [Click to view](iperf/README-en.md) | +| [NetIO](netio/README-en.md) | Performance Test | Tools for testing network throughput | [Click to view](netio/README-en.md) | +| [NTP](ntp/README-en.md) | Time synchronization | Network time protocol, support 3 alternative servers | [Click to view](ntp/README-en.md) | +| [Telnet](telnet/README-en.md) | Remote access | Can remotely log in to RT-Thread's Finsh/MSH Shell | [Click to view](telnet/README-en.md) | +| [tcpdump](tcpdump/README-en.md) | Network debugging | tcpdump is RT-Thread's lwip-based network packet capture tool | [Click to view](tcpdump/README-en.md) | \ No newline at end of file diff --git a/userapps/apps/tftp/packages/netutils-latest/README_ZH.md b/userapps/apps/tftp/packages/netutils-latest/README_ZH.md new file mode 100644 index 0000000000000000000000000000000000000000..7501caf9f9122f2b0a888f98d94c7d99957fff59 --- /dev/null +++ b/userapps/apps/tftp/packages/netutils-latest/README_ZH.md @@ -0,0 +1,28 @@ +# RT-Thread 网络小工具集 + +中文页 | [英文页](README.md) + +## 1、介绍 + +当 RT-Thread 接入网络后,可玩性大大增强。这里汇集了 RT-Thread 可用的全部网络小工具集合,你所需要的小工具都可以在这里找到。 + +## 2、获取方式 + +请使用 ENV 工具辅助下载: + +包的路径为:`RT-Thread online package` -> `IoT - internet of things` -> `netutils` + +## 3、使用说明 + +每个小工具可使用 menuconfig 独立控制启用/停用,并提供了 Finsh/MSH 的使用命令。在其目录下都存有一份详细的使用文档。如需使用,请单独查看。下面是目前支持的小工具汇总: + +| 名称 | 分类 | 功能简介 | 使用文档 | +| :--------------------------- | :------: | :----------------------------------------------------------- | :---------------------------- | +| [Ping](ping/README.md) | 调试测试 | 利用“ping”命令可以检查网络是否连通,可以很好地帮助我们分析和判定网络故障 | [点击查看](ping/README.md) | +| [TFTP](tftp/README.md) | 文件传输 | TFTP是一个传输文件的简单协议,比 FTP 还要轻量级 | [点击查看](tftp/README.md) | +| [iperf](iperf/README.md) | 性能测试 | 测试最大 TCP 和 UDP 带宽性能,可以报告带宽、延迟抖动和数据包丢失 | [点击查看](iperf/README.md) | +| [NetIO](netio/README.md) | 性能测试 | 测试网络的吞吐量的工具 | [点击查看](netio/README.md) | +| [NTP](ntp/README.md) | 时间同步 | 网络时间协议,支持 3 个备选服务器 | [点击查看](ntp/README.md) | +| [Telnet](telnet/README.md) | 远程访问 | 可以远程登录到 RT-Thread 的 Finsh/MSH Shell | [点击查看](telnet/README.md) | +| [tcpdump](tcpdump/README.md) | 网络调试 | tcpdump 是 RT-Thread 基于 lwip 的网络抓包工具 | [点击查看](tcpdump/README.md) | + diff --git a/userapps/apps/tftp/packages/netutils-latest/SConscript b/userapps/apps/tftp/packages/netutils-latest/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..ca95be14e2b891254901c1c1737c0784d9972abb --- /dev/null +++ b/userapps/apps/tftp/packages/netutils-latest/SConscript @@ -0,0 +1,12 @@ +import os +from building import * + +objs = [] +cwd = GetCurrentDir() +list = os.listdir(cwd) + +for item in list: + if os.path.isfile(os.path.join(cwd, item, 'SConscript')): + objs = objs + SConscript(os.path.join(item, 'SConscript')) + +Return('objs') diff --git a/userapps/apps/tftp/packages/netutils-latest/images/iperfc-udp.png b/userapps/apps/tftp/packages/netutils-latest/images/iperfc-udp.png new file mode 100644 index 0000000000000000000000000000000000000000..60a4997d2dd5df8a453d9d34412c28339f1e2bda Binary files /dev/null and b/userapps/apps/tftp/packages/netutils-latest/images/iperfc-udp.png differ diff --git a/userapps/apps/tftp/packages/netutils-latest/images/iperfc.png b/userapps/apps/tftp/packages/netutils-latest/images/iperfc.png new file mode 100644 index 0000000000000000000000000000000000000000..47698348c15f821ff3eb101724d89f78470024e5 Binary files /dev/null and b/userapps/apps/tftp/packages/netutils-latest/images/iperfc.png differ diff --git a/userapps/apps/tftp/packages/netutils-latest/images/iperfs-udp.png b/userapps/apps/tftp/packages/netutils-latest/images/iperfs-udp.png new file mode 100644 index 0000000000000000000000000000000000000000..708cdac514bf09fd4d0e570eb39d882f4a71b40e Binary files /dev/null and b/userapps/apps/tftp/packages/netutils-latest/images/iperfs-udp.png differ diff --git a/userapps/apps/tftp/packages/netutils-latest/images/iperfs.png b/userapps/apps/tftp/packages/netutils-latest/images/iperfs.png new file mode 100644 index 0000000000000000000000000000000000000000..3fcc7e3db4354be62ddaea2d5b19c02632daafe8 Binary files /dev/null and b/userapps/apps/tftp/packages/netutils-latest/images/iperfs.png differ diff --git a/userapps/apps/tftp/packages/netutils-latest/images/netio_tested.png b/userapps/apps/tftp/packages/netutils-latest/images/netio_tested.png new file mode 100644 index 0000000000000000000000000000000000000000..98b4e611bc96bfb3e98536a9dc2ee82f8e5ea064 Binary files /dev/null and b/userapps/apps/tftp/packages/netutils-latest/images/netio_tested.png differ diff --git a/userapps/apps/tftp/packages/netutils-latest/images/telnet_connect_cfg.png b/userapps/apps/tftp/packages/netutils-latest/images/telnet_connect_cfg.png new file mode 100644 index 0000000000000000000000000000000000000000..caa046342b598fdd81ae8143ad40fb844283ab98 Binary files /dev/null and b/userapps/apps/tftp/packages/netutils-latest/images/telnet_connect_cfg.png differ diff --git a/userapps/apps/tftp/packages/netutils-latest/images/telnet_connected.png b/userapps/apps/tftp/packages/netutils-latest/images/telnet_connected.png new file mode 100644 index 0000000000000000000000000000000000000000..ac06f8e0d9ea5b70dee9489c9aeab062ec201e7f Binary files /dev/null and b/userapps/apps/tftp/packages/netutils-latest/images/telnet_connected.png differ diff --git a/userapps/apps/tftp/packages/netutils-latest/images/tftp_server.png b/userapps/apps/tftp/packages/netutils-latest/images/tftp_server.png new file mode 100644 index 0000000000000000000000000000000000000000..80ffa691f9140ae3ecc10c3b8ae563fe2ad1fe33 Binary files /dev/null and b/userapps/apps/tftp/packages/netutils-latest/images/tftp_server.png differ diff --git a/userapps/apps/tftp/packages/netutils-latest/images/tftpd_cfg.png b/userapps/apps/tftp/packages/netutils-latest/images/tftpd_cfg.png new file mode 100644 index 0000000000000000000000000000000000000000..499844c1b1700df6a33e82c76132bacc5a5078f5 Binary files /dev/null and b/userapps/apps/tftp/packages/netutils-latest/images/tftpd_cfg.png differ diff --git a/userapps/apps/tftp/packages/netutils-latest/images/tftpd_get.png b/userapps/apps/tftp/packages/netutils-latest/images/tftpd_get.png new file mode 100644 index 0000000000000000000000000000000000000000..8419def0697a021f7fc69db0358743f90ee3c4a1 Binary files /dev/null and b/userapps/apps/tftp/packages/netutils-latest/images/tftpd_get.png differ diff --git a/userapps/apps/tftp/packages/netutils-latest/images/tftpd_put.png b/userapps/apps/tftp/packages/netutils-latest/images/tftpd_put.png new file mode 100644 index 0000000000000000000000000000000000000000..a3fbe673629538f75d438a316d3d856813f520a5 Binary files /dev/null and b/userapps/apps/tftp/packages/netutils-latest/images/tftpd_put.png differ diff --git a/userapps/apps/tftp/packages/netutils-latest/iperf/README-en.md b/userapps/apps/tftp/packages/netutils-latest/iperf/README-en.md new file mode 100644 index 0000000000000000000000000000000000000000..c0d50659fc731f27476980b7b479d8a9336b60df --- /dev/null +++ b/userapps/apps/tftp/packages/netutils-latest/iperf/README-en.md @@ -0,0 +1,117 @@ +# iperf: Network bandwidth test tool + +## 1 Introduction + +[iperf](https://baike.baidu.com/item/iperf) is a network performance testing tool. iperf can test the maximum TCP and UDP bandwidth performance, has a variety of parameters and UDP characteristics, can be adjusted as needed, can report bandwidth, delay jitter and packet loss. + +## 2. Use + +iperf uses a master-slave architecture, that is, one end is a server, and the other end is a client. The iperf component package we provide implements the TCP server mode and the client mode. UDP testing is not currently supported. The usage of the two modes will be explained in detail below. + +### 2.1 iperf server mode + +#### 2.1.1 Get IP address + +You need to use Finsh/MSH commands on RT-Thread to obtain an IP address. The general effect is as follows: + +``` +msh />ifconfig +network interface: e0 (Default) +MTU: 1500 +MAC: 00 04 9f 05 44 e5 +FLAGS: UP LINK_UP ETHARP +ip address: 192.168.12.71 +gw address: 192.168.10.1 +net mask: 255.255.0.0 +dns server #0: 192.168.10.1 +dns server #1: 223.5.5.5 +``` + +-Write down the obtained IP address 192.168.12.71 (record according to the actual situation) + +#### 2.1.2 Start iperf server + +You need to use Finsh/MSH commands on RT-Thread to start the iperf server. The general effect is as follows: + +tcp mode + +``` +msh />iperf -s -p 5001 +``` + +udp mode + +``` +msh />iperf -u -s -p 5001 +``` + +- -s means to start as a server +- -p means to monitor port 5001 + +#### 2.1.3 Install JPerf test software + +The installation file is located in `/tools/jperf.rar`, this is a green software, the installation is actually a process of decompression, just unzip it to a new folder. + +#### 2.1.4 Perform jperf test + +Open the `jperf.bat` software and configure as follows: + +- Select `Client` mode +- Enter the IP address 192.168.12.71 just obtained (fill in according to the actual address) +- Modify the port number to 5001 +- Click `run Lperf!` to start the test +- Wait for the test to end. During the test, the test data will be displayed on the shell interface and JPerf software. + +TCP mode software settings + +![iperfs](../images/iperfs.png) + +udp mode software settings + +![iperfs-udp](../images/iperfs-udp.png) + +### 2.2 iperf client mode + +#### 2.2.1 Get the IP address of the PC + +Use the ipconfig command on the command prompt window of the PC to obtain the IP address of the PC, and write down the obtained PC IP address as 192.168.12.45 (record according to the actual situation). + +#### 2.2.2 Install JPerf test software + +The installation file is located in `/tools/jperf.rar`, this is a green software, the installation is actually a process of decompression, just unzip it to a new folder. + +#### 2.2.3 Start jperf server + +Open the `jperf.bat` software and configure as follows: + +- Select `Server` mode +- Modify the port number to 5001 +- Click `run Lperf!` to start the server + +#### 2.2.4 Start iperf client + +You need to use Finsh/MSH commands on RT-Thread to start the iperf client. The general effect is as follows: + +tcp mode + +``` +msh />iperf -c 192.168.12.45 -p 5001 +``` + +udp mode + +``` +msh />iperf -u -c 192.168.12.45 -p 5001 +``` + +- -c means to start as a client, and then need to add the IP address of the pc running the server +- -p means to connect to port 5001 +- Wait for the test to end. During the test, the test data will be displayed on the shell interface and JPerf software. + +TCP mode software settings + +![iperfc](../images/iperfc.png) + +udp mode software settings + +![iperfc-udp](../images/iperfc-udp.png) \ No newline at end of file diff --git a/userapps/apps/tftp/packages/netutils-latest/iperf/README.md b/userapps/apps/tftp/packages/netutils-latest/iperf/README.md new file mode 100644 index 0000000000000000000000000000000000000000..d8fdacf69e04cfd7585e360e20b06ff6e4ffff6a --- /dev/null +++ b/userapps/apps/tftp/packages/netutils-latest/iperf/README.md @@ -0,0 +1,117 @@ +# iperf:网络带宽测试工具 + +## 1、介绍 + +[iperf](https://baike.baidu.com/item/iperf) 是一个网络性能测试工具。iperf 可以测试最大 TCP 和 UDP 带宽性能,具有多种参数和 UDP 特性,可以根据需要调整,可以报告带宽、延迟抖动和数据包丢失。 + +## 2、使用 + +iperf 使用的是主从式架构,即一端是服务器,另一端是客户端,我们提供的 iperf 组件包实现了 TCP 服务器模式和客户端模式,暂不支持 UDP 测试。下面将具体讲解 2 种模式的使用方法。 + +### 2.1 iperf 服务器模式 + +#### 2.1.1 获取 IP 地址 + +需要在 RT-Thread 上使用 Finsh/MSH 命令来获取 IP 地址,大致效果如下: + +``` +msh />ifconfig +network interface: e0 (Default) +MTU: 1500 +MAC: 00 04 9f 05 44 e5 +FLAGS: UP LINK_UP ETHARP +ip address: 192.168.12.71 +gw address: 192.168.10.1 +net mask : 255.255.0.0 +dns server #0: 192.168.10.1 +dns server #1: 223.5.5.5 +``` + +- 记下获得的 IP 地址 192.168.12.71(按实际情况记录) + +#### 2.1.2 启动 iperf 服务器 + +需要在 RT-Thread 上使用 Finsh/MSH 命令来启动 iperf 服务器,大致效果如下: + +tcp 模式 + +``` +msh />iperf -s -p 5001 +``` + +udp 模式 + +``` +msh />iperf -u -s -p 5001 +``` + +- -s 表示作为服务器启动 +- -p 表示监听 5001 端口 + +#### 2.1.3 安装 JPerf 测试软件 + +安装文件位于 `/tools/jperf.rar` ,这个是绿色软件,安装实际上是解压的过程,解压到新文件夹即可。 + +#### 2.1.4 进行 jperf 测试 + +打开 `jperf.bat`软件,按如下操作进行配置: + +- 选择 `Client` 模式 +- 输入刚刚获得的 IP 地址 192.168.12.71(按实际地址填写) +- 修改端口号为 5001 +- 点击 `run Lperf!` 开始测试 +- 等待测试结束。测试时,测试数据会在 shell 界面和 JPerf 软件上显示。 + +tcp 模式软件设置 + +![iperfs](../images/iperfs.png) + +udp 模式软件设置 + +![iperfs-udp](../images/iperfs-udp.png) + +### 2.2 iperf 客户端模式 + +#### 2.2.1 获取 PC 的 IP 地址 + +在 PC 的命令提示符窗口上使用 ipconfig 命令获取 PC 的 IP 地址,记下获得的 PC IP 地址为 192.168.12.45(按实际情况记录)。 + +#### 2.2.2 安装 JPerf 测试软件 + +安装文件位于 `/tools/jperf.rar` ,这个是绿色软件,安装实际上是解压的过程,解压到新文件夹即可。 + +#### 2.2.3 开启 jperf 服务器 + +打开 `jperf.bat`软件,按如下操作进行配置: + +- 选择 `Server` 模式 +- 修改端口号为 5001 +- 点击 `run Lperf!` 开启服务器 + +#### 2.2.4 启动 iperf 客户端 + +需要在 RT-Thread 上使用 Finsh/MSH 命令来启动 iperf 客户端,大致效果如下: + +tcp 模式 + +``` +msh />iperf -c 192.168.12.45 -p 5001 +``` + +udp 模式 + +``` +msh />iperf -u -c 192.168.12.45 -p 5001 +``` + +- -c 表示作为客户端启动,后面需要加运行服务器端的pc的 IP 地址 +- -p 表示连接 5001 端口 +- 等待测试结束。测试时,测试数据会在 shell 界面和 JPerf 软件上显示。 + +tcp 模式软件设置 + +![iperfc](../images/iperfc.png) + +udp 模式软件设置 + +![iperfc-udp](../images/iperfc-udp.png) diff --git a/userapps/apps/tftp/packages/netutils-latest/iperf/SConscript b/userapps/apps/tftp/packages/netutils-latest/iperf/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..14e97edafad3720dafdce47b36cba658d174f570 --- /dev/null +++ b/userapps/apps/tftp/packages/netutils-latest/iperf/SConscript @@ -0,0 +1,7 @@ +from building import * + +src = Glob('*.c') + +group = DefineGroup('NetUtils', src, depend = ['PKG_NETUTILS_IPERF']) + +Return('group') \ No newline at end of file diff --git a/userapps/apps/tftp/packages/netutils-latest/iperf/iperf.c b/userapps/apps/tftp/packages/netutils-latest/iperf/iperf.c new file mode 100644 index 0000000000000000000000000000000000000000..ed5add71c2ef1a4d1c14ee98b8329f313fe5f62a --- /dev/null +++ b/userapps/apps/tftp/packages/netutils-latest/iperf/iperf.c @@ -0,0 +1,522 @@ +/** +* iperf-liked network performance tool +* +*/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define DBG_SECTION_NAME "iperf" +#define DBG_LEVEL DBG_INFO +#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}; + +static void iperf_udp_client(void *thread_param) +{ + int sock; + rt_uint32_t *buffer; + struct sockaddr_in server; + rt_uint32_t packet_count = 0; + rt_uint32_t tick; + int send_size; + + send_size = IPERF_BUFSZ > 1470 ? 1470 : IPERF_BUFSZ; + buffer = rt_malloc(IPERF_BUFSZ); + if (buffer == NULL) + { + return; + } + rt_memset(buffer, 0x00, IPERF_BUFSZ); + sock = socket(PF_INET, SOCK_DGRAM, 0); + if(sock < 0) + { + LOG_E("can't create socket! exit!"); + return; + } + server.sin_family = PF_INET; + server.sin_port = htons(param.port); + server.sin_addr.s_addr = inet_addr(param.host); + LOG_I("iperf udp mode run..."); + while (param.mode != IPERF_MODE_STOP) + { + packet_count++; + tick = rt_tick_get(); + buffer[0] = htonl(packet_count); + buffer[1] = htonl(tick / RT_TICK_PER_SECOND); + buffer[2] = htonl((tick % RT_TICK_PER_SECOND) * 1000); + sendto(sock, buffer, send_size, 0, (struct sockaddr *)&server, sizeof(struct sockaddr_in)); + } + closesocket(sock); + rt_free(buffer); +} + +static void iperf_udp_server(void *thread_param) +{ + int sock; + rt_uint32_t *buffer; + struct sockaddr_in server; + struct sockaddr_in sender; + int sender_len, r_size; + rt_uint64_t sentlen; + rt_uint32_t pcount = 0, last_pcount = 0; + rt_uint32_t lost, total; + rt_tick_t tick1, tick2; + struct timeval timeout; + + buffer = rt_malloc(IPERF_BUFSZ); + if (buffer == NULL) + { + return; + } + sock = socket(PF_INET, SOCK_DGRAM, 0); + if(sock < 0) + { + LOG_E("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) + { + LOG_E("setsockopt failed!"); + closesocket(sock); + rt_free(buffer); + return; + } + if (bind(sock, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) < 0) + { + LOG_E("iperf server bind failed! exit!"); + closesocket(sock); + rt_free(buffer); + return; + } + while (param.mode != IPERF_MODE_STOP) + { + tick1 = rt_tick_get(); + tick2 = tick1; + lost = 0; + total = 0; + sentlen = 0; + while ((tick2 - tick1) < (RT_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 = rt_tick_get(); + } + if (sentlen > 0) + { + long data; + int integer, decimal; + rt_thread_t tid; + + tid = rt_thread_self(); + data = sentlen * RT_TICK_PER_SECOND / 125 / (tick2 - tick1); + integer = data/1000; + decimal = data%1000; + LOG_I("%s: %d.%03d0 Mbps! lost:%d total:%d\n", tid->name, integer, decimal, lost, total); + } + } + rt_free(buffer); + closesocket(sock); +} + +static void iperf_client(void *thread_param) +{ + int i; + int sock; + int ret; + int tips = 1; + uint8_t *send_buf; + rt_uint64_t sentlen; + rt_tick_t tick1, tick2; + struct sockaddr_in addr; + + send_buf = (uint8_t *) rt_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, IPPROTO_TCP); + if (sock < 0) + { + LOG_E("create socket failed!"); + rt_thread_delay(RT_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) + { + LOG_E("Connect to iperf server faile, Waiting for the server to open!"); + tips = 0; + } + closesocket(sock); + rt_thread_delay(RT_TICK_PER_SECOND); + continue; + } + + LOG_I("Connect to iperf server successful!"); + + { + 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 = rt_tick_get(); + while (param.mode != IPERF_MODE_STOP) + { + tick2 = rt_tick_get(); + if (tick2 - tick1 >= RT_TICK_PER_SECOND * 5) + { + long data; + int integer, decimal; + rt_thread_t tid; + + tid = rt_thread_self(); + data = sentlen * RT_TICK_PER_SECOND / 125 / (tick2 - tick1); + integer = data/1000; + decimal = data%1000; + LOG_I("%s: %d.%03d0 Mbps!", tid->name, integer, decimal); + tick1 = tick2; + sentlen = 0; + } + + ret = send(sock, send_buf, IPERF_BUFSZ, 0); + if (ret > 0) + { + sentlen += ret; + } + + if (ret < 0) break; + } + + closesocket(sock); + + rt_thread_delay(RT_TICK_PER_SECOND * 2); + LOG_W("Disconnected, iperf server shut down!"); + tips = 1; + } + rt_free(send_buf); +} + +void iperf_server(void *thread_param) +{ + uint8_t *recv_data; + socklen_t sin_size; + rt_tick_t tick1, tick2; + int sock = -1, connected, bytes_received; + rt_uint64_t recvlen; + struct sockaddr_in server_addr, client_addr; + fd_set readset; + struct timeval timeout; + + recv_data = (uint8_t *)rt_malloc(IPERF_BUFSZ); + if (recv_data == RT_NULL) + { + LOG_E("No memory!"); + goto __exit; + } + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) + { + LOG_E("Socket error!"); + goto __exit; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(param.port); + server_addr.sin_addr.s_addr = INADDR_ANY; + rt_memset(&(server_addr.sin_zero), 0x0, sizeof(server_addr.sin_zero)); + + if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) + { + LOG_E("Unable to bind!"); + goto __exit; + } + + if (listen(sock, 5) == -1) + { + LOG_E("Listen error!"); + 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, RT_NULL, RT_NULL, &timeout) == 0) + continue; + + sin_size = sizeof(struct sockaddr_in); + + connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size); + + LOG_I("new client connected from (%s, %d)", + 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 = rt_tick_get(); + while (param.mode != IPERF_MODE_STOP) + { + bytes_received = recv(connected, recv_data, IPERF_BUFSZ, 0); + if (bytes_received <= 0) break; + + recvlen += bytes_received; + + tick2 = rt_tick_get(); + if (tick2 - tick1 >= RT_TICK_PER_SECOND * 5) + { + long data; + int integer, decimal; + rt_thread_t tid; + + tid = rt_thread_self(); + data = recvlen * RT_TICK_PER_SECOND / 125 / (tick2 - tick1); + integer = data/1000; + decimal = data%1000; + LOG_I("%s: %d.%03d0 Mbps!", tid->name, integer, decimal); + tick1 = tick2; + recvlen = 0; + } + } + LOG_W("client disconnected (%s, %d)", + inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); + if (connected >= 0) closesocket(connected); + connected = -1; + } + +__exit: + if (sock >= 0) closesocket(sock); + if (recv_data) rt_free(recv_data); +} + +void iperf_usage(void) +{ + rt_kprintf("Usage: iperf [-s|-c host] [options] [multi-threaded]\n"); + rt_kprintf(" iperf [-h|--stop]\n"); + rt_kprintf("\n"); + rt_kprintf("Client/Server:\n"); + rt_kprintf(" -p # server port to listen on/connect to\n"); + rt_kprintf("\n"); + rt_kprintf("Server specific:\n"); + rt_kprintf(" -s run in server mode\n"); + rt_kprintf("\n"); + rt_kprintf("Client specific:\n"); + rt_kprintf(" -c run in client mode, connecting to \n"); + rt_kprintf("\n"); + rt_kprintf("Miscellaneous:\n"); + rt_kprintf(" -h print this message and quit\n"); + rt_kprintf(" --stop stop iperf program\n"); + rt_kprintf(" -u testing UDP protocol\n"); + rt_kprintf(" -m