みつきんのメモ

組み込みエンジニアです。Interface誌で「Yocto Projectではじめる 組み込みLinux開発入門」連載中

NuttX STM32F4Discovery+RNDISでEthernet(ついでにMQTT)

はじめに

NuttXはRNDISドライバを持っている。

STM32F4DiscoveryはRNDISドライバを使用すると、USBでEthernetバイスとして通信できるようになる。

意外なほど簡単に使用することができる。

コンフィグレーション

$ tools/configure.sh -l configs/stm32f4discovery/rndis

動作確認

STM32F4Discovery側

初期状態では、デバイスは認識しているがIPアドレスは振られていない。

nsh> ifconfig
eth0    Link encap:Ethernet HWaddr 00:e0:de:ad:ca:fe at UP
        inet addr:0.0.0.0 DRaddr:0.0.0.0 Mask:0.0.0.0

lo      Link encap:Local Loopback at UP
        inet addr:127.0.0.1 DRaddr:127.0.0.1 Mask:255.0.0.0

             IPv4   TCP   UDP  ICMP
Received     0008  0000  0008  0000
Dropped      0000  0000  0000  0000
  IPv4        VHL: 0000   Frg: 0000
  Checksum   0000  0000  0000  ----
  TCP         ACK: 0000   SYN: 0000
              RST: 0000  0000
  Type       0000  ----  ----  0000
Sent         0005  0000  0005  0000
  Rexmit     ----  0000  ----  ----

次のコマンドでIPアドレスを割り当てる。

nsh> ifconfig eth0 192.168.20.100

IPアドレスを指定すると、ネットマスクとゲートウェイは自動的に設定される。

nsh> ifconfig
eth0    Link encap:Ethernet HWaddr 00:e0:de:ad:ca:fe at UP
        inet addr:192.168.20.100 DRaddr:192.168.20.1 Mask:255.255.255.0

lo      Link encap:Local Loopback at UP
        inet addr:127.0.0.1 DRaddr:127.0.0.1 Mask:255.0.0.0

             IPv4   TCP   UDP  ICMP
Received     0016  0000  0016  0000
Dropped      0000  0000  0000  0000
  IPv4        VHL: 0000   Frg: 0000
  Checksum   0000  0000  0000  ----
  TCP         ACK: 0000   SYN: 0000
              RST: 0000  0000
  Type       0000  ----  ----  0000
Sent         0011  0000  0011  0000
  Rexmit     ----  0000  ----  ----

PC側

RNDISを有効化してSTM32F4DiscoveryのマイクロUSBとPCのUSBポートを接続すると、 次のように認識される。

$ dmesg
...(snip)...
[187044.300595] usb 1-7.4: new full-speed USB device number 9 using xhci_hcd
[187044.646579] usb 1-7.4: New USB device found, idVendor=584e, idProduct=5342
[187044.646584] usb 1-7.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[187044.646586] usb 1-7.4: Product: RNDIS gadget
[187044.646588] usb 1-7.4: Manufacturer: NuttX
[187044.646590] usb 1-7.4: SerialNumber: 1234
[187044.672267] usbcore: registered new interface driver cdc_ether
[187044.674191] rndis_host 1-7.4:1.0: skipping garbage
[187044.689562] rndis_host 1-7.4:1.0: dev can't take 1558 byte packets (max 660), adjusting MTU to 602
[187044.739995] rndis_host 1-7.4:1.0 eth0: register 'rndis_host' at usb-0000:15:00.0-7.4, RNDIS device, a0:e0:de:ad:ca:fe
[187044.740051] usbcore: registered new interface driver rndis_host
[187044.744102] usbcore: registered new interface driver rndis_wlan
[187044.752038] rndis_host 1-7.4:1.0 enxa0e0deadcafe: renamed from eth0

enxa0e0deadcafeというネットワークデバイスとして見えている。

これもIPアドレスは振られていないので、ネットワーク設定画面で192.168.20.1に設定する。

pingが通ればOK。

$ ping 192.168.20.100
PING 192.168.20.100 (192.168.20.100) 56(84) bytes of data.
64 bytes from 192.168.20.100: icmp_seq=2 ttl=64 time=0.472 ms
64 bytes from 192.168.20.100: icmp_seq=3 ttl=64 time=0.460 ms
64 bytes from 192.168.20.100: icmp_seq=4 ttl=64 time=0.446 ms
64 bytes from 192.168.20.100: icmp_seq=5 ttl=64 time=0.438 ms

ついでにSTM32F4Discovery側からpingも確認しておく。

nsh> ping 192.168.20.1
PING 192.168.20.1 56 bytes of data
56 bytes from 192.168.20.1: icmp_seq=0 time=0 ms
56 bytes from 192.168.20.1: icmp_seq=1 time=0 ms
56 bytes from 192.168.20.1: icmp_seq=2 time=0 ms
56 bytes from 192.168.20.1: icmp_seq=3 time=0 ms
56 bytes from 192.168.20.1: icmp_seq=4 time=0 ms
56 bytes from 192.168.20.1: icmp_seq=5 time=0 ms
56 bytes from 192.168.20.1: icmp_seq=6 time=0 ms
56 bytes from 192.168.20.1: icmp_seq=7 time=0 ms
56 bytes from 192.168.20.1: icmp_seq=8 time=0 ms
56 bytes from 192.168.20.1: icmp_seq=9 time=0 ms
10 packets transmitted, 10 received, 0% packet loss, time 10100 ms

MQTT

Ethernetが使えるので当然MQTTも使えるはず。

前回の要領でMQTTを有効化する。

nsh> ifconfig eth0 192.168.20.100
nsh> ifconfig
eth0    Link encap:Ethernet HWaddr 00:e0:de:ad:ca:fe at UP
        inet addr:192.168.20.100 DRaddr:192.168.20.1 Mask:255.255.255.0

lo      Link encap:Local Loopback at UP
        inet addr:127.0.0.1 DRaddr:127.0.0.1 Mask:255.0.0.0

             IPv4   TCP   UDP  ICMP
Received     0039  0000  0001  0000
Dropped      0002  0000  0000  0000
  IPv4        VHL: 0002   Frg: 0000
  Checksum   0000  0000  0000  ----
  TCP         ACK: 0000   SYN: 0000
              RST: 0000  0000
  Type       0000  ----  ----  0000
Sent         0002  0000  0002  0000
  Rexmit     ----  0000  ----  ----
nsh> ping 192.168.20.1
PING 192.168.20.1 56 bytes of data
56 bytes from 192.168.20.1: icmp_seq=0 time=0 ms
56 bytes from 192.168.20.1: icmp_seq=1 time=0 ms
56 bytes from 192.168.20.1: icmp_seq=2 time=0 ms
56 bytes from 192.168.20.1: icmp_seq=3 time=0 ms
56 bytes from 192.168.20.1: icmp_seq=4 time=0 ms
56 bytes from 192.168.20.1: icmp_seq=5 time=0 ms
56 bytes from 192.168.20.1: icmp_seq=6 time=0 ms
56 bytes from 192.168.20.1: icmp_seq=7 time=0 ms
56 bytes from 192.168.20.1: icmp_seq=8 time=0 ms
56 bytes from 192.168.20.1: icmp_seq=9 time=0 ms
10 packets transmitted, 10 received, 0% packet loss, time 10100 ms
nsh> mqttc 192.168.20.1
mqttc is ready to begin publishing the time.
Press ENTER to publish the current time.
Press CTRL-D (or any other key) to exit.

mqttc published : "The time is 1970-01-01 00:00:57"
packet_id = 0x0000C96A,536916472
mqttc published : "The time is 1970-01-01 00:00:58"
packet_id = 0x000064B5,536916452
mqttc published : "The time is 1970-01-01 00:00:59"
packet_id = 0x0000865A,536916432
mqttc published : "The time is 1970-01-01 00:00:59"
packet_id = 0x0000432D,536916412
mqttc published : "The time is 1970-01-01 00:01:00"
packet_id = 0x00009596,536916392
mqttc published : "The time is 1970-01-01 00:01:00"
packet_id = 0x00004ACB,536916372
mqttc published : "The time is 1970-01-01 00:01:00"
packet_id = 0x00009165,536916352
mqttc published : "The time is 1970-01-01 00:01:00"
packet_id = 0x0000FCB2,536916332
mqttc published : "The time is 1970-01-01 00:01:00"
packet_id = 0x00007E59,536916312

mqttc disconnecting from 192.168.20.1

PC側の様子。

$ mosquitto_sub -t datetime
The time is 1970-01-01 00:00:57
The time is 1970-01-01 00:00:58
The time is 1970-01-01 00:00:59
The time is 1970-01-01 00:00:59
The time is 1970-01-01 00:01:00
The time is 1970-01-01 00:01:00
The time is 1970-01-01 00:01:00
The time is 1970-01-01 00:01:00
The time is 1970-01-01 00:01:00

おまけ

簡単に試せるようにGithubリポジトリを用意した。

$ git clone https://github.com/mickey-happygolucky/nuttx.git -b mqtt
$ git clone https://github.com/mickey-happygolucky/apps.git -b mqtt
$ cd nuttx
$ tools/configure.sh -l configs/stm32f4discovery/rndis_mqtt
$ make -j4
$ st-flash write nuttx.bin 0x8000000