Score:1

การตั้งค่าเครือข่าย USB ระหว่าง Android และ Linux แบบฝังตัว

ธง lk

ตอนนี้ฉันกำลังทำงานในโครงการที่เรามีระบบ Linux แบบฝังตัวที่เรียกใช้ฟังก์ชันการควบคุมเซ็นเซอร์/มอเตอร์ และเรากำลังสร้างแอปพลิเคชัน GUI เพื่อให้ผู้ใช้สามารถควบคุมระบบได้ ในอนาคต เราอาจเรียกใช้ทั้งสองแอปพลิเคชันบนระบบเดียว แต่ในขณะนี้ เราต้องการให้สามารถติดตั้งสิ่งนี้เป็นการอัปเกรดให้กับเครื่องที่มีอยู่ และบอร์ดควบคุมที่มีอยู่ไม่มีความสามารถในการเรียกใช้ GUI ได้ ได้รับการออกแบบมา ดังนั้นจึงจะทำงานบน SBC แยกต่างหาก (ขณะนี้เรากำลังสร้างต้นแบบด้วยไฟล์ ODroid C4 ใช้แอนดรอยด์ 9)

เราได้พัฒนา API การสื่อสารระหว่างสองระบบ และฉันได้ทำการทดสอบเบื้องต้นโดยใช้การเชื่อมต่ออีเทอร์เน็ตโดยตรงระหว่างทั้งสองระบบด้วยที่อยู่ IP แบบคงที่ อย่างไรก็ตาม เนื่องจากข้อกำหนดการปรับใช้และข้อจำกัดของ Android ฉันจึงต้องหาวิธีอื่น วิธีการเชื่อมต่อสำหรับการปรับใช้จริงของผลิตภัณฑ์ เราต้องการให้ลูกค้าสามารถเชื่อมต่ออินเทอร์เน็ตบนระบบ GUI ผ่าน WiFi หรืออีเธอร์เน็ต ดังนั้นพอร์ตอีเธอร์เน็ตออนบอร์ดของ ODroid จึงไม่สามารถใช้เพื่อจุดประสงค์นั้นได้ และยิ่งไปกว่านั้น เคอร์เนลของ Android มีลักษณะการทำงานภายในบางอย่าง ที่อนุญาตให้มีการเชื่อมต่อเครือข่ายเดียวเท่านั้นที่ใช้งานได้ตลอดเวลา

ข้อยกเว้นสำหรับกฎการจัดลำดับความสำคัญของเครือข่ายของ Android คืออินเทอร์เฟซเครือข่าย USB ทั้งระบบควบคุม Linux และอุปกรณ์ Android เองมีความสามารถในการปรากฏเป็นอินเทอร์เฟซเครือข่ายไปยังโฮสต์ระยะไกล - บนระบบควบคุมเรามีพอร์ตอุปกรณ์ USB พร้อมใช้งาน และฉันเปิดใช้งาน g_ether โมดูลเคอร์เนลในอิมเมจระบบของเรา และบนระบบ GUI เรามีพอร์ต USB OTG และฉันสามารถเปิดใช้งานการปล่อยสัญญาณผ่าน USB ในการตั้งค่าระบบ Android

ฉันสามารถรับการสื่อสารระหว่างระบบใดระบบหนึ่งเหล่านี้กับระบบพัฒนา Windows ของฉันโดยใช้อินเทอร์เฟซที่เกี่ยวข้อง แต่จนถึงขณะนี้ฉันยังไม่ทราบว่าจะหาโซลูชันใดมาพูดคุยกับอีกระบบหนึ่งได้อย่างไร

ระบบ Linux เป็นอินเทอร์เฟซระยะไกล (อุปกรณ์ USB พร้อมไดรเวอร์ g_ether)

  • การโหลดโมดูลเคอร์เนล g_ether บนระบบ linux จะสร้าง usb0 อินเตอร์เฟซ:
# modprobe g_ether
#ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
        inet 10.42.128.107 netmask 255.255.255.0 ออกอากาศ 10.42.128.255
        inet6 fe80::206:cff:fe01:1027 คำนำหน้า 64 scopeid 0x20<link>
        อีเธอร์ 00:06:0c:01:10:27 txqueuelen 1000 (อีเธอร์เน็ต)
        แพ็คเก็ต RX 500 ไบต์ 54062 (52.7 KiB)
        ข้อผิดพลาด RX 0 หลุด 46 โอเวอร์รัน 0 เฟรม 0
        แพ็กเก็ต TX 0 ไบต์ 24423 (23.8 KiB)
        ข้อผิดพลาด TX 0 หลุด 0 โอเวอร์รัน 0 พาหะ 0 ชนกัน 0

แท้จริง: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
        inet 127.0.0.1 เน็ตมาสก์ 255.0.0.0
        inet6 ::1 คำนำหน้าlen 128 scopeid 0x10<host>
        วนซ้ำ txqueuelen 0 (วนกลับในเครื่อง)
        แพ็คเก็ต RX 0 ไบต์ 0 (0.0 B)
        ข้อผิดพลาด RX 0 หลุด 0 โอเวอร์รัน 0 เฟรม 0
        แพ็กเก็ต TX 0 ไบต์ 0 (0.0 B)
        ข้อผิดพลาด TX 0 หลุด 0 โอเวอร์รัน 0 พาหะ 0 ชนกัน 0

usb0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
        inet6 fe80::24b:5bfc:8a9e:b148 คำนำหน้า 64 scopeid 0x20<link>
        อีเธอร์ 9a:8c:fa:85:ec:a1 txqueuelen 1000 (อีเธอร์เน็ต)
        แพ็คเก็ต RX 0 ไบต์ 0 (0.0 B)
        ข้อผิดพลาด RX 0 หลุด 0 โอเวอร์รัน 0 เฟรม 0
        แพ็กเก็ต TX 1 ไบต์ 96 (96.0 B)
        ข้อผิดพลาด TX 0 หลุด 0 โอเวอร์รัน 0 พาหะ 0 ชนกัน 0
  • การเชื่อมต่อสาย USB จากพอร์ตแกดเจ็ตบนระบบ linux เข้ากับพอร์ตโฮสต์บนระบบ Android จะสร้าง a usb0 อินเทอร์เฟซบน Android และสร้างที่อยู่ IP สำหรับ usb0 อินเทอร์เฟซบน Linux:

แอนดรอยด์:

odroidc4:/ # ifconfig usb0
usb0 ลิงก์ encap:Ethernet HWaddr fa:4c:95:c0:8d:18 ไดรเวอร์ cdc_subset
          มัลติคาสต์ออกอากาศ MTU:1500 เมตริก:1
          แพ็กเก็ต RX:0 ข้อผิดพลาด:0 หลุด:0 โอเวอร์รัน:0 เฟรม:0
          แพ็กเก็ต TX:0 ข้อผิดพลาด:0 หลุด:0 โอเวอร์รัน:0 ผู้ให้บริการ:0
          การชน:0 txqueuelen:1000
          ไบต์ RX:0 ไบต์ TX:0

ลินุกซ์:

# ifconfig usb0
usb0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
        inet 169.254.119.94 netmask 255.255.0.0 ออกอากาศ 169.254.255.255
        inet6 fe80::24b:5bfc:8a9e:b148 คำนำหน้า 64 scopeid 0x20<link>
        อีเธอร์ 9a:8c:fa:85:ec:a1 txqueuelen 1000 (อีเธอร์เน็ต)
        แพ็คเก็ต RX 0 ไบต์ 0 (0.0 B)
        ข้อผิดพลาด RX 0 หลุด 0 โอเวอร์รัน 0 เฟรม 0
        แพ็กเก็ต TX 1 ไบต์ 96 (96.0 B)
        ข้อผิดพลาด TX 0 หลุด 0 โอเวอร์รัน 0 พาหะ 0 ชนกัน 0
  • การเรียกใช้อินเทอร์เฟซบนระบบ Android ไม่ได้กำหนดที่อยู่ IP ดังนั้นฉันต้องกำหนดด้วยตนเองโดยใช้ช่องว่าง 169.254/16 ที่ระบบ Linux กำหนดด้วยตนเอง
odroidc4:/ # ifconfig usb0 ขึ้น
odroidc4:/ # ifconfig usb0
usb0 ลิงก์ encap:Ethernet HWaddr fa:4c:95:c0:8d:18 ไดรเวอร์ cdc_subset
          inet6 addr: fe80::f84c:95ff:fec0:8d18/64 ขอบเขต: ลิงก์
          การออกอากาศที่เรียกใช้มัลติคาสต์ MTU:1500 เมตริก:1
          แพ็กเก็ต RX:117 ข้อผิดพลาด:4 หลุด:75 โอเวอร์รัน:0 เฟรม:4
          แพ็กเก็ต TX:27 ข้อผิดพลาด:0 หลุด:0 โอเวอร์รัน:0 ผู้ให้บริการ:0
          การชน:0 txqueuelen:1000
          ไบต์ RX:5080 ไบต์ TX:4897

odroidc4:/ # ip addr เพิ่ม 169.254.1.1/16 ออกอากาศ 169.254.255.255 dev usb0
odroidc4:/ # ifconfig usb0
usb0 ลิงก์ encap:Ethernet HWaddr fa:4c:95:c0:8d:18 ไดรเวอร์ cdc_subset
          inet addr:169.254.1.1 Bcast:169.254.255.255 มาสก์:255.255.0.0
          inet6 addr: fe80::f84c:95ff:fec0:8d18/64 ขอบเขต: ลิงค์
          การออกอากาศที่เรียกใช้มัลติคาสต์ MTU:1500 เมตริก:1
          แพ็กเก็ต RX:117 ข้อผิดพลาด:4 หลุด:75 โอเวอร์รัน:0 เฟรม:4
          แพ็กเก็ต TX:44 ข้อผิดพลาด:0 หลุด:0 โอเวอร์รัน:0 ผู้ให้บริการ:0
          การชน:0 txqueuelen:1000
          ไบต์ RX:5080 ไบต์ TX:8528

ฉันมีปัญหา 2 ประการ ณ จุดนี้ ประการแรกคือการส่ง Ping อุปกรณ์ใดอุปกรณ์หนึ่งจากอีกเครื่องหนึ่งส่งผลให้ไม่มีการตอบสนอง การดูจำนวนแพ็กเก็ตในฝั่ง Android ทำให้ดูเหมือนว่าได้รับ ping จากฝั่ง Linux แต่ไม่ตอบสนอง ซึ่งอาจเกิดจากปัญหาที่สองคือ routing table ไม่ทำงานตามที่คาดไว้ ทางฝั่งแอนดรอยด์ เนื่องจากฉันต้องการให้สิ่งนี้ทำงานในขณะที่มีการเชื่อมต่ออินเทอร์เน็ตที่ใช้งานได้บนระบบ Android ฉันจึงเชื่อมต่ออีเธอร์เน็ตในเวลาเดียวกัน และนี่คือสิ่งที่ฉันเห็นเมื่อดูที่การกำหนดเส้นทาง:

odroidc4:/ # รายการเส้นทาง ip
169.254.0.0/16 dev usb0 โปรโตเคอร์เนลขอบเขตลิงก์ src 169.254.1.1
10.42.128.0/24 dev eth0 ลิงก์ขอบเขตเคอร์เนลโปรโต src 10.42.128.166
odroidc4:/ # เส้นทาง ip รับ 169.254.119.94
169.254.119.94 ผ่าน 10.42.128.2 dev eth0 ตาราง eth0 src 10.42.128.166 uid 0
    แคช
odroidc4:/ # ip เส้นทางแสดงตาราง 0
ค่าเริ่มต้นผ่าน 10.42.128.2 dev eth0 table eth0 proto static
...

ระบบ Android เป็นอินเทอร์เฟซระยะไกล (การปล่อยสัญญาณผ่าน USB พร้อมพอร์ต OTG)

สถานการณ์นี้ดูเหมือนจะทำให้ฉันใกล้ชิดขึ้นอีกเล็กน้อย เนื่องจากฉันสามารถสื่อสารทางเดียวได้

  • หลังจากเพิ่มไดรเวอร์ที่จำเป็นในอิมเมจ Linux ของฉันแล้ว การเชื่อมต่อสายเคเบิลจากพอร์ต Android OTG ไปยังพอร์ตโฮสต์ Linux แสดงระบบที่รู้จักอุปกรณ์ USB ใน dmesg:
[235.710937] usb 1-2.3: อุปกรณ์ USB ความเร็วสูงใหม่หมายเลข 7 โดยใช้ at91_ohci
[ 235.862304] rndis_host 1-2.3:1.0 usb0: ลงทะเบียน 'rndis_host' ที่ usb-at91-2.3, อุปกรณ์ RNDIS, 32:1d:e8:fc:dd:8
  • usb0 อินเทอร์เฟซถูกสร้างขึ้นทันทีและกำหนดที่อยู่ IP บนส่วนท้ายของ Linux:
# ifconfig usb0
usb0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
        inet 169.254.249.80 netmask 255.255.0.0 ออกอากาศ 169.254.255.255
        inet6 fe80::e341:f9b1:b676:99b7 คำนำหน้า 64 scopeid 0x20<link>
        อีเธอร์ 32:1d:e8:fc:dd:80 txqueuelen 1000 (อีเธอร์เน็ต)
        แพ็คเก็ต RX 69 ไบต์ 13572 (13.2 KiB)
        ข้อผิดพลาด RX 0 หลุด 0 โอเวอร์รัน 0 เฟรม 0
        แพ็กเก็ต TX 73 ไบต์ 18251 (17.8 KiB)
        ข้อผิดพลาด TX 8 หลุด 0 โอเวอร์รัน 0 พาหะ 0 ชนกัน 0
  • ในส่วน Android ที่เปิดใช้งานการปล่อยสัญญาณผ่าน USB ในการตั้งค่า อินเทอร์เฟซ usb0 จะปรากฏขึ้น แต่ เริ่มออก การนำขึ้นมาไม่ได้ให้ที่อยู่ IP ดังนั้นฉันจึงกำหนดที่อยู่ IP ด้วยตนเอง แต่เช่นเดียวกับสถานการณ์แรก ตารางเส้นทางดูเหมือนจะไม่ทำงานตามที่คาดไว้:
odroidc4:/ # ifconfig usb0
usb0 ลิงก์ encap:Ethernet HWaddr จาก:75:5c:41:2a:e6
          มัลติคาสต์ออกอากาศ MTU:1500 เมตริก:1
          แพ็กเก็ต RX:0 ข้อผิดพลาด:0 หลุด:0 โอเวอร์รัน:0 เฟรม:0
          แพ็กเก็ต TX:0 ข้อผิดพลาด:0 หลุด:0 โอเวอร์รัน:0 ผู้ให้บริการ:0
          การชน:0 txqueuelen:1000
          ไบต์ RX:0 ไบต์ TX:0
odroidc4:/ # ifconfig usb0 ขึ้น
odroidc4:/ # ifconfig usb0
usb0 ลิงก์ encap:Ethernet HWaddr จาก:75:5c:41:2a:e6
          inet6 addr: fe80::dc75:5cff:fe41:2ae6/64 ขอบเขต: ลิงค์
          การออกอากาศที่เรียกใช้มัลติคาสต์ MTU:1500 เมตริก:1
          แพ็กเก็ต RX:10 ข้อผิดพลาด:0 หลุด:0 โอเวอร์รัน:0 เฟรม:0
          แพ็กเก็ต TX:12 ข้อผิดพลาด:0 หลุด:0 โอเวอร์รัน:0 ผู้ให้บริการ:0
          การชน:0 txqueuelen:1000
          ไบต์ RX:1090 ไบต์ TX:2751
odroidc4:/ # ip addr เพิ่ม 169.254.1.1/16 ออกอากาศ 169.254.255.255 dev usb0
odroidc4:/ # เส้นทาง ip
10.42.128.0/24 dev eth0 ลิงก์ขอบเขตเคอร์เนลโปรโต src 10.42.128.166
169.254.0.0/16 dev usb0 โปรโตเคอร์เนลขอบเขตลิงก์ src 169.254.1.1
odroidc4:/ # เส้นทาง ip รับ 169.254.249.80
169.254.249.80 ผ่าน 10.42.128.2 dev eth0 ตาราง eth0 src 10.42.128.166 uid 0
    แคช
  • อย่างไรก็ตาม ในสถานการณ์นี้ ฉันสามารถรับการสื่อสารที่ประสบความสำเร็จซึ่งเริ่มต้นจากปลาย Android ได้โดยการระบุอินเทอร์เฟซด้วยตนเอง:
odroidc4:/ # ping -c 5 -I usb0 169.254.249.80
PING 169.254.249.80 (169.254.249.80) จาก 169.254.1.1 usb0: 56(84) ไบต์ของข้อมูล
64 ไบต์จาก 169.254.249.80: icmp_seq=1 ttl=64 เวลา=1.56 ms
64 ไบต์จาก 169.254.249.80: icmp_seq=2 ttl=64 เวลา=1.89 ms
64 ไบต์จาก 169.254.249.80: icmp_seq=3 ttl=64 เวลา=1.71 ms
64 ไบต์จาก 169.254.249.80: icmp_seq=4 ttl=64 เวลา=1.75 ms
64 ไบต์จาก 169.254.249.80: icmp_seq=5 ttl=64 เวลา=1.85 ms

--- สถิติ ping 169.254.249.80 ---
ส่ง 5 แพ็กเก็ต ได้รับ 5 แพ็กเก็ต สูญเสียแพ็กเก็ต 0% เวลา 4006ms
2|odroidc4:/ # ping6 -c5 ff02::1%usb0
PING ff02::1%usb0(ff02::1) 56 ไบต์ข้อมูล
64 ไบต์จาก fe80::dc75:5cff:fe41:2ae6: icmp_seq=1 ttl=64 เวลา=0.202 ms
64 ไบต์จาก fe80::e341:f9b1:b676:99b7: icmp_seq=1 ttl=64 เวลา=1.91 ms (DUP!)
64 ไบต์จาก fe80::dc75:5cff:fe41:2ae6: icmp_seq=2 ttl=64 เวลา=0.196 ms
64 ไบต์จาก fe80::e341:f9b1:b676:99b7: icmp_seq=2 ttl=64 เวลา=1.80 ms (DUP!)
64 ไบต์จาก fe80::dc75:5cff:fe41:2ae6: icmp_seq=3 ttl=64 เวลา=0.199 ms
64 ไบต์จาก fe80::e341:f9b1:b676:99b7: icmp_seq=3 ttl=64 เวลา=1.37 ms (DUP!)
64 ไบต์จาก fe80::dc75:5cff:fe41:2ae6: icmp_seq=4 ttl=64 เวลา=0.199 ms
64 ไบต์จาก fe80::e341:f9b1:b676:99b7: icmp_seq=4 ttl=64 เวลา=1.85 ms (DUP!)
64 ไบต์จาก fe80::dc75:5cff:fe41:2ae6: icmp_seq=5 ttl=64 เวลา=0.205 ms

--- สถิติ ping ff02::1%usb0 ---
ส่ง 5 แพ็กเก็ต, 5 ได้รับ, +4 ซ้ำ, 0% แพ็กเก็ตสูญหาย, เวลา 4004ms
rtt นาที/เฉลี่ย/สูงสุด/mdev = 0.196/0.883/1.914/0.776 มิลลิวินาที
  • ฉันยังไม่สามารถรับทราฟฟิกใด ๆ ที่มาจากฝั่ง Linux ให้ทำงานได้ อาจเป็นเพราะปัญหาการกำหนดเส้นทางบนปลาย Android ทำให้ไม่สามารถกำหนดเส้นทางการรับส่งข้อมูลกลับได้อย่างถูกต้อง:
# ping -c 5 -I usb0 169.254.1.1
PING 169.254.1.1 (169.254.1.1) จาก 169.254.249.80 usb0: 56(84) ไบต์ของข้อมูล

--- สถิติ ping 169.254.1.1 ---
ส่ง 5 แพ็กเก็ต ได้รับ 0 แพ็กเก็ต สูญเสียแพ็กเก็ต 100% เวลา 4295ms
# ping6 -c 5 ff02::1%usb0
PING ff02::1%usb0(ff02::1) 56 ไบต์ข้อมูล
64 ไบต์จาก fe80::e341:f9b1:b676:99b7: icmp_seq=1 ttl=64 เวลา=0.522 ms
64 ไบต์จาก fe80::e341:f9b1:b676:99b7: icmp_seq=2 ttl=64 เวลา=0.302 ms
64 ไบต์จาก fe80::e341:f9b1:b676:99b7: icmp_seq=3 ttl=64 เวลา=0.376 ms
64 ไบต์จาก fe80::e341:f9b1:b676:99b7: icmp_seq=4 ttl=64 เวลา=0.383 ms
64 ไบต์จาก fe80::e341:f9b1:b676:99b7: icmp_seq=5 ttl=64 เวลา=0.385 ms

--- สถิติ ping ff02::1%usb0 ---
ส่ง 5 แพ็กเก็ต, 5 แพ็กเก็ตที่ได้รับ, การสูญเสียแพ็กเก็ต 0%, เวลา 4009ms
rtt นาที/เฉลี่ย/สูงสุด/mdev = 0.302/0.393/0.522/0.074 มิลลิวินาที

ในทั้งสองสถานการณ์ ดูเหมือนว่าต้นตอของปัญหาคือตารางเส้นทางบนปลาย Android กำหนดเส้นทางทราฟฟิกไม่ถูกต้องผ่านอินเทอร์เฟซ USB และปลาย Android ไม่กำหนดที่อยู่ IP โดยอัตโนมัติในขณะที่ปลาย Linux ทำ ด้วยอินเทอร์เฟซแกดเจ็ต Linux/โฮสต์ Android ฉันสามารถเข้าใจปัญหาเหล่านี้ได้บ้าง แต่ด้วยการปล่อยสัญญาณผ่านพอร์ต Android OTG/โฮสต์ Linux ฉันคาดหวังให้เส้นทางถูกต้องเนื่องจากระบบ Android ควบคุมการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ

Score:0
ธง um

ไฮ @rdowell,

เพื่อแก้ไขปัญหานี้ จำเป็นต้องเพิ่มตารางเส้นทางหลักบนอุปกรณ์ Android ของคุณ:

กฎ ip เพิ่มจากการตั้งค่าหลักการค้นหาทั้งหมด 1

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา