0% found this document useful (0 votes)
230 views36 pages

Writing Your Own Gadget: 02 November 2018

The document discusses using a Zephyr-powered embedded board as a USB gadget to connect devices with non-standard interfaces to a PC. It describes how Zephyr's USB device stack allows a board to present itself as a USB device like Ethernet or custom classes. Implementation details covered include enabling Ethernet-over-USB protocols, building a custom USB class, and examples of using the USB connection for applications like an HTTP server or border router.

Uploaded by

Erick Cafferata
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
230 views36 pages

Writing Your Own Gadget: 02 November 2018

The document discusses using a Zephyr-powered embedded board as a USB gadget to connect devices with non-standard interfaces to a PC. It describes how Zephyr's USB device stack allows a board to present itself as a USB device like Ethernet or custom classes. Implementation details covered include enabling Ethernet-over-USB protocols, building a custom USB class, and examples of using the USB connection for applications like an HTTP server or border router.

Uploaded by

Erick Cafferata
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 36

02 November 2018

Writing Your Own Gadget


Andrei Emeltchenko
Contents
▪ Introduction
▪ General USB
▪ Using Ethernet over USB
▪ Using 802.15.4 over USB
▪ Other USB usages
▪ Experimental USB features: WebUSB
▪ Debugging without the board
▪ Summary
▪ References

2
Introduction: Problem
▪ Devices around (sensors, switches, etc)
▪ Problem connecting to devices with non standard PC interfaces
○ SPI, I2C, etc

Access

Complex Hardware

3
Introduction: Solution
▪ Use embedded board with special interfaces powered by Zephyr OS
▪ Zephyr board connects to Host via USB

Zephyr gadget

Interface
USB

Complex Hardware

4
Introduction: Zephyr
▪ Open Source RTOS for connected resource constrained devices
https://www.zephyrproject.org/what-is-zephyr/
▪ Hosted by Linux Foundation
▪ Supported more then 100 boards:
https://docs.zephyrproject.org/latest/boards/boards.html
▪ Zephyr Project Documentation https://docs.zephyrproject.org/latest/index.html
▪ License: Apache 2.0
▪ Source:
https://github.com/zephyrproject-rtos/zephyr

5
Hello world in Zephyr
▪ Set up a development system
https://docs.zephyrproject.org/latest/getting_started/getting_started.html#set-up-a-development-system
▪ Set up build environment
$ source zephyr-env.sh

▪ Build hello_world sample for Qemu ▪ Run hello_world in Qemu


$ cd samples/hello_world/ $ make run
$ mkdir build
$ cd build To exit from QEMU enter: 'CTRL+a, x'
# Use cmake to configure a Make-based build [QEMU] CPU: qemu32,+nx,+pae
$ cmake -DBOARD=qemu_x86 ..
# Now run make on the generated build system: ***** Booting Zephyr OS zephyr-v1.13.0 *****
$ make Hello World! qemu_x86

6
USB: General overview
▪ One Host connected to many devices Device Descriptor
▪ Device identifies itself through
Descriptors Endpoint Descriptor 1
▪ Descriptors are binary data ...
describing USB capabilities Endpoint Descriptor N
○ Device Class Interface Descriptor 1
○ Product ID / Vendor ID ...
Interface Descriptor N
○ Configuration, Interfaces,
Endpoints Configuration Descriptor 1
▪ Endpoints are communication
...
channels between Host and Device Configuration Descriptor N

7
Programming USB gadgets: Standard Classes
▪ Basic USB Device Classes supported by Zephyr Device Stack
○ Can be enabled in Zephyr application via menuconfig

8
Programming USB gadgets: Custom Device
Define Device Descriptors Define Endpoints and config data and enable
static const struct dev_common_descriptor { static struct usb_ep_cfg_data ep[] = {
struct usb_device_descriptor device_descriptor; {
struct usb_cfg_descriptor configuration_descr; .ep_cb = bulk_in,
struct usb_device_config { .ep_addr = ENDP_BULK_IN
struct usb_if_descriptor if0; },
struct usb_ep_descriptor if0_in_ep; };
} __packed device_configuration; static struct usb_cfg_data config = {
} __packed desc = { .usb_device_description = (u8_t *)&desc,
.device_descriptor = { .cb_usb_status = status_cb,
.bDeviceClass = CUSTOM_CLASS, .interface = {
.idVendor = sys_cpu_to_le16((u16_t)CONFIG_USB_DEVICE_VID), .vendor_handler = NULL,
.idProduct = sys_cpu_to_le16((u16_t)CONFIG_USB_DEVICE_PID), .class_handler = NULL,
.bcdDevice = sys_cpu_to_le16(BCDDEVICE_RELNUM), .custom_handler = NULL,
}, },
.device_configuration = { .num_endpoints = ARRAY_SIZE(ep),
.if0 = { .endpoint = ep,
.bInterfaceClass = CUSTOM_CLASS, };
.bInterfaceSubClass = WPANUSB_SUBCLASS,
.bInterfaceProtocol = WPANUSB_PROTOCOL,
}, /* Initialize the USB driver with the right configuration */
.if0_in_ep = { ret = usb_set_config(&wpanusb_config);
.bEndpointAddress = ENDP_BULK_IN,
.bmAttributes = USB_DC_EP_BULK, /* Enable USB driver */
... ret = usb_enable(&wpanusb_config);

9
Ethernet over USB: Use case
Browser Zephyr app

Apps: DNS / LLMNR / MDNS / CoAP / MQTT / HTTP http server

Transport Layer: UDP / TCP

Host PC Zephyr gadget


Network Layer: IPv4 / IPv6

Physical Layer: ECM / EEM / RNDIS Ethernet frames

USB

10
Ethernet over USB: Standards
▪ Motivation: Application independent data exchange
▪ Standards:
○ Microsoft Remote NDIS (RNDIS)
○ Communications Device Class (CDC) protocols
■ Ethernet Control Model (ECM)
■ Ethernet Emulation Model (EEM)
■ Network Control Model (NCM)
▪ macOS supports CDC ECM
▪ MS Windows supports RNDIS
▪ Linux support all protocols

11
Ethernet over USB: Enabling in Zephyr
▪ Zephyr supports RNDIS, ECM and EEM
▪ Simple configuration: protocols are implemented in USB Device Stack
○ User only need to select Ethernet over USB checkboxes

12
Ethernet over USB: Zero configuration
● IPv4 address autoconfiguration for Host and Zephyr
IcannIan_00:53:01 Broadcast |
| | |
| Who has 169.254.81.1 | | ARP: Who has 169.254.81.199? Tell 0.0.0.0
|----------------------------->| |
| Gratuitous ARP | | ARP: Gratuitous ARP for 169.254.81.199 (Request)
|----------------------------->| |

● Link Local Multicast Name Resolution (LLMNR)


Host 224.0.0.252 Zephyr |
| | | |
| Standard query A zephyr | | | LLMNR: Standard query A zephyr
|------------------------->| | |
| Standard query resp A zephyr 169.254.9.70 | | LLMNR: Standard query response
|<---------------------------------------------| | A zephyr A 169.254.9.70

● zephyr can now be used as a hostname

13
Ethernet over USB: HTTP server app
Zephyr app + extra configuration Host PC
# USB Device settings
CONFIG_USB=y Ethernet over
CONFIG_USB_DEVICE_STACK=y
USB overlay
# Select USB Configurations config
CONFIG_USB_DEVICE_NETWORK_ECM=y

# Zero Configuration
CONFIG_NET_IPV4_AUTO=y Zero
CONFIG_NET_HOSTNAME_ENABLE=y WEB GUI for Zephyr app
CONFIG_DNS_RESOLVER=y Configuration
CONFIG_LLMNR_RESOLVER=y overlay config
CONFIG_LLMNR_RESPONDER=y

$ cmake ... -DOVERLAY_CONFIG=overlay-netusb.conf

Sample README https://docs.zephyrproject.org/latest/samples/net/http_server/README.html


14
Ethernet over USB: border router app
▪ Border Router connects networks with different routing domains
▪ Zephyr capabilities:
○ Multiple interfaces
○ Routing

USB
Zephyr
border router

radio
some custom radio network

15
Ethernet over USB Drivers: Linux
▪ ECM, EEM, RNDIS protocols are all supported by Linux

16
Ethernet over USB Drivers: Windows
▪ Only MS RNDIS is supported
▪ RNDIS gadget may be recognized as Serial / COM
○ Device Class / Subclass matches usbser.inf

17
OS Drivers for Zephyr USB: OS Descriptors
▪ Microsoft OS Descriptors help to autoconfigure MS Windows driver
○ Implemented for RNDIS at the moment
○ Tested with MS Windows 8.1 / 10

MS Windows Zephyr

Windows INF files Compatible ID Subcompatible ID


OS
INF Descriptors RNDIS 5162001

INF

rndiscmp.inf USB\MS_COMP_RNDIS&MS_SUBCOMP_5162001

Compatibe ID: https://docs.microsoft.com/en-us/windows-hardware/drivers/install/compatible-ids

18
IEEE802.15.4 USB: Use case

Access IEEE802.15.4 network

Zephyr gadget

▪ Only one USB 802.15.4 transceiver is supported

802.15.4
by Linux (atusb)
USB

19
IEEE802.15.4 USB gadget
▪ A board with 802.15.4 radio and USB might be used as a USB adapter
○ Board, radio and USB shall be supported by Zephyr

Board used:
Intel C1000 Eval Kit
● TI CC2520 802.15.4 radio
module connected over SPI
● DW USB controller

Source code: https://github.com/zephyrproject-rtos/zephyr/tree/master/samples/net/wpanusb

20
Low Power Wireless Linux stack

Linux

Applications

IPv6

6LoWPAN

802.15.4 MAC

802.15.4 driver SPI

802.15.4 Hardware
Raspberry Pi + OpenLabs Atmel AT86RF233 radio

21
IEEE802.15.4 USB gadget

Linux Zephyr gadget

Applications
SPI

802.15.4 radio
IPv6

6LoWPAN 802.15.4 driver

802.15.4 MAC wpanusb application

wpanusb driver USB

USB

22
IEEE802.15.4 USB gadget: API
Zephyr 802154 Driver API Linux 802154 SoftMAC API
struct ieee802154_radio_api { struct ieee802154_ops {
... ...
int (*start)(struct device *dev); int (*start)(struct ieee802154_hw *hw);
int (*stop)(struct device *dev); void (*stop)(struct ieee802154_hw *hw);
int (*tx)(struct device *dev, int (*xmit_async)(struct ieee802154_hw *hw,
struct net_pkt *pkt, struct sk_buff *skb);
struct net_buf *frag); int (*set_channel)(struct ieee802154_hw *hw,
int (*set_channel)(struct device *dev, u8 page, u8 channel);
u16_t channel); int (*set_txpower)(struct ieee802154_hw *hw,
int (*set_txpower)(struct device *dev, s16_t dbm); s32 mbm);
... ...
} __packed; };

opcode: SET_CHANNEL setup.bRequest data

USB
parameters: channel, page opcode parameters

23
IEEE802.15.4 USB: Linux driver
▪ SoftMAC driver similar to atusb Linux kernel driver
▪ Protocol defined:
https://github.com/zephyrproject-rtos/zephyr/blob/master/samples/net/wpanusb/
wpan-radio-spec.txt
▪ Vendor specific class - driver loads on specific Product ID / Vendor ID pair
▪ Zephyr has own Vendor ID (0x2FE3)
https://docs.zephyrproject.org/latest/subsystems/usb/usb.html#usb-vendor-and-
product-identifiers
▪ Source code: https://github.com/finikorg/wpanusb

24
IEEE802.15.4 atusb vs wpanusb protocol

atusb wpanusb
▪ Vendor - dependent protocol ▪ Vendor - independent GENERIC
protocol

Linux ieee802154_ops.set_channel

setup.bRequest data data setup.bRequest data data


ATUSB_REG_WRITE SR_CHANNEL channel SET_CHANNEL page channel

25
IEEE802.15.4 USB: Linux driver
#!/bin/sh
usb-devices output for the gadget: PHY=`iwpan phy | grep wpan_phy | cut -d' ' -f2`
CHAN=${1:-20}
T: Bus=01 Lev=03 Prnt=03 Port=01 Cnt=01 Dev#= 23 Spd=12 MxCh= 0 echo 'Using phy' $PHY 'channel' $CHAN
D: Ver= 1.10 Cls=ff(vend.) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 iwpan dev wpan0 set pan_id 0xabcd
P: Vendor=2fe3 ProdID=0101 Rev=00.11 iwpan dev wpan0 set short_addr 0xbeef
C: #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr=100mA iwpan phy $PHY set channel 0 $CHAN
I: If#= 0 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=00 Prot=00 Driver=wpanusb ip link add link wpan0 name lowpan0 type lowpan
ip link set wpan0 up
ip link set lowpan0 up
interfaces needed for IPv6 communication

20: wpan0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 123 qdisc pfifo_fast state UNKNOWN group default qlen 300
link/ieee802.15.4 6e:18:24:17:8c:e4:ef:88 brd ff:ff:ff:ff:ff:ff:ff:ff
21: lowpan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1280 qdisc noqueue state UNKNOWN group default qlen 1000
link/[825] 6e:18:24:17:8c:e4:ef:88 brd ff:ff:ff:ff:ff:ff:ff:ff
inet6 fe80::6c18:2417:8ce4:ef88/64 scope link
valid_lft forever preferred_lft forever

26
Other USB usages
▪ Human Interface Device (HID)
▪ Device Firmware Upgrade (DFU)
▪ Mass storage over USB
▪ Serial Port over USB
▪ 802.15.4 “serial radio” protocol
○ 802.15.4 frames over Serial USB
○ Works with Contiki native border router app
https://github.com/contiki-os/contiki/tree/master/examples/ipv6/native-bor
der-router
▪ Bluetooth USB adapter
○ Bluetooth HCI RAW access is used to send HCI over USB
○ Bluetooth USB Transport Layer Spec. (bluetooth.org)

27
WebUSB: Use case

WebUSB Notification when device is connected WebUSB Device Chooser

28
WebUSB: API & Zephyr support
▪ Simple WebUSB API
// Select configuration #1 for the device
device.selectConfiguration(1)
https://wicg.github.io/webusb/
▪ Works with recent Chrome // Request exclusive control over interface #2

▪ USB Device direct access


device.claimInterface(2)

▪ USB Device announce support by // Waiting for 64 bytes of data from endpoint #3
including special Descriptor device.transferIn(3, 64)

▪ Vendor - Specific Request specified // Send Control Transfer


▪ Zephyr supports WebUSB device.controlTransferOut({
requestType: 'class',
recipient: 'interface',
request: 0x22,
value: 0x01,
index: 0x02})

Zephyr WebUSB app https://github.com/zephyrproject-rtos/zephyr/tree/master/samples/subsys/usb/webusb

29
Debugging Zephyr USB app without a hardware
▪ Zephyr app and kernel run as a native Linux console application
○ native_posix board: https://docs.zephyrproject.org/latest/boards/posix/
▪ Virtual USB controller over USBIP protocol
○ Zephyr is a server which decapsulates USBIP packets into USB requests
handled by Zephyr
○ Linux is a client which uses VHCI driver which encapsulate USB requests
to USBIP packets

30
Virtual USB Controller over USB/IP
Client Server Server
userspace

usbip daemon
Application Zephyr native_posix
listens TCP:3240
Linux console app

TCP:3240
USB Devices Stub Driver USB Device Class
Linux kernel

Drivers
USB Core USB Core USB Device Core
Virtual Host Host Controller Virtual Controller
Controller Driver Driver Driver
VC Adaptation
Host Controller listens TCP:3240
Hardware

USB device

31
Zephyr Virtual USB Controller: Attaching
$ sudo modprobe vhci-hcd Load USB/IP Virtual Host Controller driver
$ lsof -i -P | grep zephyr Run Zephyr app and verify USBIP
zephyr.ex 13633 niko 4u IPv4 32089735 0t0 TCP *:3240 (LISTEN) listening socket

$ usbip list -r localhost List exportable USB devices with usbip list
Exportable USB devices
======================
- 127.0.0.1
1-1: unknown vendor : unknown product (2fe3:0100)
: /sys/devices/pci0000:00/0000:00:01.2/usb1/1-1
: (Defined at Interface level) (00/00/00)
: 0 - Human Interface Device / No Subclass / None(03/00/00)

$ sudo usbip attach -r localhost -b 1-1


Attach exportable device to the Host
$ lsusb -d 2fe3:0100 Verify USB device attached to the Host
Bus 007 Device 013: ID 2fe3:0100

32
Zephyr Virtual USB Controller: Linux logs
vhci_hcd vhci_hcd.0: USB/IP Virtual Host Controller
Loading Virtual Host
vhci_hcd vhci_hcd.0: new USB bus registered, assigned bus number 7
vhci_hcd: created sysfs vhci_hcd.0 Controller driver
usb usb7: New USB device found, idVendor=1d6b, idProduct=0002
usb usb7: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb7: Product: USB/IP Virtual Host Controller
usb usb7: Manufacturer: Linux 4.15.0-31-generic vhci_hcd
usb usb7: SerialNumber: vhci_hcd.0 Attaching exportable
hub 7-0:1.0: USB hub found device over USB/IP
hub 7-0:1.0: 8 ports detected

usb 7-1: New USB device found, idVendor=2fe3, idProduct=0100


usb 7-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 7-1: Product: Zephyr HID sample
usb 7-1: Manufacturer: ZEPHYR
usb 7-1: SerialNumber: 0.01
input: ZEPHYR Zephyr HID sample as
/devices/platform/vhci_hcd.0/usb7/7-1/7-1:1.0/0003:2FE3:0100.004E/input/input89
hid-generic 0003:2FE3:0100.004E: input,hidraw2: USB HID v1.10 Device [ZEPHYR Zephyr HID sample] on
usb-vhci_hcd.0-1/input0

33
Summary

Zephyr gadget

Interface
USB

Complex Hardware

34
References
Zephyr USB
▪ Zephyr OS https://www.zephyrproject.org/ ▪ How to Create and Program USB Devices
▪ Native Posix board ▪ Microsoft OS Descriptors
https://docs.zephyrproject.org/latest/boards/posix/ https://docs.microsoft.com/en-us/windows-hardware/drivers/u
▪ Zephyr HTTP Server app sbcon/microsoft-defined-usb-descriptors
https://docs.zephyrproject.org/latest/samples/net/http_server/ ▪ WebUSB API https://wicg.github.io/webusb/
README.html ▪ WebUSB Privacy and Security
▪ Zephyr wpanusb app https://developers.google.com/web/updates/2016/03/access-
https://github.com/zephyrproject-rtos/zephyr/tree/master/sam usb-devices-on-the-web#privacy_and_security
ples/net/wpanusb
▪ Zephyr webusb app
https://docs.microsoft.com/en-us/windows-hardware/drivers/u Linux
sbcon/microsoft-defined-usb-descriptors ▪ USB/IP project http://usbip.sourceforge.net/
▪ Linux IEEE 802.15.4 implementation

Contiki
▪ Contiki OS http://www.contiki-os.org/
▪ Contiki native border router
https://github.com/contiki-os/contiki/tree/master/examples/ipv
6/native-border-router

35

You might also like