12.Ethernet
以SC-3568HA为例,板卡上有双以太网网口
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节点:
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文档
官方标准开发文档
3.社区Demo
简介
为了帮助开发者更快速的使用板子开发和学习,我们在gitee上提供了一个以太网相关的使用示例,每一个项目都是独立的DevEco Studio工程,开发者可以将工程导入到DevEco Studio中即可,通过浏览代码、编译工程、安装和运行应用示例来了解应用示例中涉及API的使用方法。
小技巧
在导入社区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应用以及部署 中的第二部分(构建第一个页面部分内容)