12.Ethernet

以SC-3568HA为例,板卡上有双以太网网口

ETH_1

12.1 dts配置

  • arch/arm64/boot/dts/rockchip/rk3568-toybrick-x0.dtsi

 1&gmac0 {
 2    phy-mode = "rgmii";
 3    clock_in_out = "output";
 4
 5    snps,reset-gpio = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>;
 6    snps,reset-active-low;
 7    /* Reset time is 20ms, 100ms for rtl8211f */
 8    snps,reset-delays-us = <0 20000 100000>;
 9
10    assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
11    assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>;
12    assigned-clock-rates = <0>, <125000000>;
13
14    pinctrl-names = "default";
15    pinctrl-0 = <&gmac0_miim
16            &gmac0_tx_bus2
17            &gmac0_rx_bus2
18            &gmac0_rgmii_clk
19            &gmac0_rgmii_bus>;
20
21    tx_delay = <0x2d>;
22    rx_delay = <0x13>;
23
24    phy-handle = <&rgmii_phy0>;
25    status = "okay";
26};
27
28&gmac1 {
29    phy-mode = "rgmii";
30    clock_in_out = "output";
31
32    snps,reset-gpio = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>;
33    snps,reset-active-low;
34    /* Reset time is 20ms, 100ms for rtl8211f */
35    snps,reset-delays-us = <0 20000 100000>;
36
37    assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
38    assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru CLK_MAC1_2TOP>;
39    assigned-clock-rates = <0>, <125000000>;
40
41    pinctrl-names = "default";
42    pinctrl-0 = <&gmac1m1_miim
43            &gmac1m1_tx_bus2
44            &gmac1m1_rx_bus2
45            &gmac1m1_rgmii_clk
46            &gmac1m1_rgmii_bus>;
47
48    tx_delay = <0x37>;
49    rx_delay = <0x0f>;
50
51    phy-handle = <&rgmii_phy1>;
52    status = "okay";
53};

12.2 检查eth接口

使用ifconfig命令检查是否生成ethX节点:

ETH_0

12.3 连通性测试

使用以下命令测试网口

  • eth0:

 1~# ping -I eth0 -c 10 www.baidu.com
 2Ping www.baidu.com (183.2.172.42) from eth0 (192.168.49.35): 56(84) bytes.
 364 bytes from 183.2.172.42: icmp_seq=1 ttl=50 time=12 ms
 464 bytes from 183.2.172.42: icmp_seq=2 ttl=50 time=10 ms
 564 bytes from 183.2.172.42: icmp_seq=3 ttl=50 time=10 ms
 664 bytes from 183.2.172.42: icmp_seq=4 ttl=50 time=10 ms
 764 bytes from 183.2.172.42: icmp_seq=5 ttl=50 time=17 ms
 864 bytes from 183.2.172.42: icmp_seq=6 ttl=50 time=8 ms
 964 bytes from 183.2.172.42: icmp_seq=7 ttl=50 time=9 ms
1064 bytes from 183.2.172.42: icmp_seq=8 ttl=50 time=8 ms
1164 bytes from 183.2.172.42: icmp_seq=9 ttl=50 time=10 ms
1264 bytes from 183.2.172.42: icmp_seq=10 ttl=50 time=9 ms
13
14--- 183.2.172.42 ping statistics ---
1510 packets transmitted, 10 received, 0% packet loss
16round-trip min/avg/max = 8/10/17 ms
  • eth1:

 1# ping -I eth1 -c 10 www.baidu.com
 2Ping www.baidu.com (183.2.172.185) from eth1 (192.168.49.241): 56(84) bytes.
 364 bytes from 183.2.172.185: icmp_seq=1 ttl=50 time=9 ms
 464 bytes from 183.2.172.185: icmp_seq=2 ttl=50 time=9 ms
 564 bytes from 183.2.172.185: icmp_seq=3 ttl=50 time=9 ms
 664 bytes from 183.2.172.185: icmp_seq=4 ttl=50 time=9 ms
 764 bytes from 183.2.172.185: icmp_seq=5 ttl=50 time=8 ms
 864 bytes from 183.2.172.185: icmp_seq=6 ttl=50 time=8 ms
 964 bytes from 183.2.172.185: icmp_seq=7 ttl=50 time=9 ms
1064 bytes from 183.2.172.185: icmp_seq=8 ttl=50 time=8 ms
1164 bytes from 183.2.172.185: icmp_seq=9 ttl=50 time=8 ms
1264 bytes from 183.2.172.185: icmp_seq=10 ttl=50 time=9 ms
13
14--- 183.2.172.185 ping statistics ---
1510 packets transmitted, 10 received, 0% packet loss
16round-trip min/avg/max = 8/8/9 ms

12.4 以太网API使用与实践

1.HDC相关指令

hdc指令可以用于查询以太网的信息以及连接状态
hdc shell ifconfig

关闭/打开以太网

hdc命令:

ifconfig eth0 X.X.X.X up

ifconfig eth0 X.X.X.X down

x.x.x.x 为网卡地址

2.标准API使用方法

备注

以太网连接管理主要提供有线网络能力,提供设置有线网络的IP地址,子网掩码,网关,DNS,代理等信息 本模块首批接口从API version 9开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 本模块为系统接口。

  • 以太网标准接口

    @ohos.net.ethernet (以太网连接管理)(系统接口)

  • API使用说明

    使用以太网相关API开发时候,需要先了解熟悉第一个open Harmony工程的创建,相关文档 Hello World应用以及部署

    在使用一个API时,需要注意以下几点:
    • API权限说明

    • API的参数与返回值

    • API调用错误的时候,参考API错误码和通用错误码

    • API示例的正确使用

如下图所示,即为标准API文档

entDemo

3.社区Demo

  • 简介

    为了帮助开发者更快速的使用板子开发和学习,我们在gitee上提供了一个以太网相关的使用示例,每一个项目都是独立的DevEco Studio工程,开发者可以将工程导入到DevEco Studio中即可,通过浏览代码、编译工程、安装和运行应用示例来了解应用示例中涉及API的使用方法。

    giteeWIFI示例

小技巧

在导入社区Demo工程的时候,需要开发者需要注意本地的开发环境是否与项目的一致,即本地SDK是否与项目SDK一致。

  • 导入模块

    在使用以太网标准API的时候,最重要的一步是导入以太网的模块,才能使用以太网相应的API接口。通常模块导入是在文件头导入 导入模块如下:

    import ethernet from '@ohos.net.ethernet'

  • API 介绍

    社区Demo的实现引用以下API,实现如何打开获取以太网信息,设置静动态,以及以太网的连接的基本实现。

备注

以下介绍均以为简单介绍API的系统能力以及对应函数 请结合 gitee以太网示例以太网官方标准API开发文档 去熟悉开发

  • ethernet.setIfaceConfig(设置网络接口配置信息)

    • setIfaceConfig(iface: string, ic: InterfaceConfiguration): Promise<void>

    • 需要权限: ohos.permission.CONNECTIVITY_INTERNAL 。

  • ethernet.getIfaceConfig(获取指定网络接口信息,)

    • getIfaceConfig(iface: string): Promise<InterfaceConfiguration>

    • 需要权限: ohos.permission.GET_NETWORK_INFO 。

  • ethernet.isIfaceActive(判断接口是否已激活)

    • isIfaceActive(iface: string): Promise<number>

    • 需要权限: ohos.permission.GET_NETWORK_INFO 。

  • ethernet.getAllActiveIfaces(获取活动的网络接口)

    • getAllActiveIfaces(): Promise<Array<string>>

    • 需要权限: ohos.permission.GET_NETWORK_INFO 。

  • ethernet.on(‘interfaceStateChange’)(注册网卡热插拔事件)

    • getAllActiveIfaces(): Promise<Array<string>>

    • 需要权限: ohos.permission.GET_NETWORK_INFO 。

  • Demo主要实现源码

  • ent.ets
      1  import ethernet from '@ohos.net.ethernet'
      2  import { BusinessError } from '@ohos.base';
      3
      4  @Entry
      5  @Component
      6  struct Index {
      7  @State message: string = '以太网Demo';
      8  private  TAG : string = 'ent_Demo'
      9  @State entModeTest : string = '当前动态Ip'
     10  @State entName : string = "eth0"
     11  @State entModeStatus : boolean = true;//动/静态Ip的判断
     12  @State entMsg : string = ''
     13  @State entIp : string = ''
     14  @State entRoute : string = ''
     15  @State entGateway : string = ''
     16  @State entMask : string = ''
     17  @State entDNS : string = ''
     18  @State entMode : number = 1;
     19
     20
     21  aboutToAppear(): void {
     22     this.getAllActiveIfaces();
     23     this.getIfaceConfig();
     24  }
     25
     26
     27  setIfaceConfig(){
     28     let config: ethernet.InterfaceConfiguration = {
     29        mode: this.entMode,
     30        ipAddr: this.entIp,
     31        route: this.entRoute,
     32        gateway: this.entGateway,
     33        netMask: this.entMask,
     34        dnsServers: this.entDNS
     35     };
     36
     37     const setConfigPromise = ethernet.setIfaceConfig("eth0", config);
     38
     39     setConfigPromise.then(() => {
     40        console.log(this.TAG,"setIfaceConfig promise ok");
     41     }).catch((error: BusinessError)  => {
     42        console.error(this.TAG,"setIfaceConfig promise error = " + JSON.stringify(error));
     43     });
     44  }
     45
     46  getIfaceConfig(){
     47     ethernet.getIfaceConfig(this.entName).then((data: ethernet.InterfaceConfiguration) => {
     48        console.log(this.TAG,"getIfaceConfig promise mode = " + data.mode);
     49        console.log(this.TAG,"getIfaceConfig promise ipAddr = " + JSON.stringify(data.ipAddr));
     50        console.log(this.TAG,"getIfaceConfig promise route = " + JSON.stringify(data.route));
     51        console.log(this.TAG,"getIfaceConfig promise gateway = " + JSON.stringify(data.gateway));
     52        console.log(this.TAG,"getIfaceConfig promise netMask = " + JSON.stringify(data.netMask));
     53        console.log(this.TAG,"getIfaceConfig promise dnsServers = " + JSON.stringify(data.dnsServers));
     54        if (data.mode == 0) {
     55        this.entModeStatus = false;
     56        }else {
     57        this.entModeStatus = true
     58        }
     59        this.entMode = data.mode
     60        this.entMsg = JSON.stringify(data).toString();
     61        this.entRoute = data.route.toString();
     62        this.entGateway = data.gateway.toString();
     63        this.entMask = data.netMask.toString();
     64        this.entDNS = data.dnsServers.toString();
     65     }).catch((error: BusinessError) => {
     66        console.error(this.TAG,"getIfaceConfig promise error = " + JSON.stringify(error));
     67     });
     68  }
     69
     70  isIfaceActive(){
     71     ethernet.isIfaceActive("eth0").then((data: number) => {
     72        console.log(this.TAG,"isIfaceActive promise = " + JSON.stringify(data));
     73     }).catch((error: BusinessError) => {
     74        console.log(this.TAG,"isIfaceActive promise error = " + JSON.stringify(error));
     75     });
     76  }
     77
     78  getAllActiveIfaces(){
     79     ethernet.getAllActiveIfaces().then((data: string[]) => {
     80        console.log(this.TAG,"getAllActiveIfaces promise data.length = " + JSON.stringify(data.length));
     81        if (JSON.stringify(data.length) == '1' ) {
     82        console.log(this.TAG,'data.length')
     83        }
     84        for (let i = 0; i < data.length; i++) {
     85        console.log(this.TAG,"getAllActiveIfaces promise  = " + JSON.stringify(data[i]));
     86        }
     87     }).catch((error:BusinessError) => {
     88        console.error(this.TAG,"getAllActiveIfaces promise error = " + JSON.stringify(error));
     89     });
     90  }
     91
     92  build() {
     93        Column() {
     94        Text(this.message)
     95           .fontSize(50)
     96           .fontWeight(FontWeight.Bold)
     97           .padding(20)
     98        Button('点击切换动/静态IP')
     99           .onClick(()=>{
    100              if (this.entMode == 0) {
    101              this.entMode = 1;
    102              this.entModeTest = '当前动态Ip'
    103              this.entModeStatus = true;
    104              }else{
    105              this.entMode = 0;
    106              this.entModeTest = '当前静态Ip'
    107              this.entModeStatus = false;
    108              }
    109              this.setIfaceConfig();
    110              this.getIfaceConfig();
    111           })
    112        if (this.entModeStatus){
    113           Column(){
    114              TextInput({placeholder : '静态Ip'})
    115              .onChange((value : string)=>{
    116                 this.entIp = value
    117              })
    118           }
    119           .height(80)
    120           .width(300)
    121           .padding(10)
    122           .margin(10)
    123        }
    124        Text(this.entModeTest)
    125           .fontSize(50)
    126           .fontWeight(FontWeight.Bold)
    127           .padding(30)
    128        Column(){
    129           Text('网口信息')
    130           Blank()
    131           Text(this.entMsg)
    132        }
    133        .height(80)
    134        .padding(10)
    135        }
    136        .width('100%')
    137  }
    138
    139  }
    

4.代码编译

小技巧

代码编译详细流程可见,Hello World应用以及部署 中的第二部分(构建第一个页面部分内容)

5.代码运行效果

用以上标准API接口实现以太网Demo,如下图所示:

entIndex