The second box that I put together features an Olimex iMX233-OlinuXino-MAXI for the SBC, connects to the network via an ethernet-over-power device, and uses a Digital Loggers "IoT Relay" device. The MAXI features the i.MX233 SoC which has a 32-bit, ARM9 arm926ej-s at its core. My intention is to use this device to run the lights on the bush in front of the house.
Parts:
- Olimex iMX233-OlinuXino-MAXI
- Digital Loggers IoT Relay
- Wago 221 connectors
- TP-Link AV1000 powerline adapter
- NEMA 5-15P/C13 piggy-back power cord
When I was first thinking of this project (a couple years ago), I thought the "IoT Relay" from Digital Loggers would be a good device around-which to create my design. I was hoping it would keep me from having to do a lot of cutting and splicing of mains power cables. However, in order to get cables into and out of the box, cutting and splicing is unavoidable. So while these are neat devices, and I did end up using a couple of them (I had already bought them for this project), they're a little over-kill. Simple relays (as in box 1) would be more than adequate, and would save a bunch of space. Nevertheless, the IoT Relay has 4 NEMA 5-15P outlets: 3 of which are controlled by the control signal, 1 of which is "always on" (provided the device itself has power and is switched on). 2 of the 3 controlled outlets are "normally OFF" and the 3rd outlet is "normally ON". A removable screw terminal provides the signal by which to control the relay.
To supply power for the MAXI, I simply plugged the 12V 1A wall wart that came with the board into the IoT Relay's "Always ON" outlet.
The piggy-back NEMA 5-15P to C13 do-hicky was quite a lucky find! The IoT Relay has a C14 connector, and I needed a second 5-15P for the powerline adapter, so this device was able to solve both problems.
One small thing that tripped me up momentarily when working with the MAXI is that it doesn't have a manufacturer-assigned, static MAC address. I noticed this while setting up and testing my DHCP configuration, this board kept being assigned an IP address from the DHCP pool instead of the static IP I wanted it to have. Fortunately setting up a static, user-defined, locally-administered, unicast, MAC address isn't too difficult if it only needs to be set when Linux runs (if you need your bootloader to know/setup the MAC address, then other arrangements need to be made).
The iMX233-OlinuXino-MAXI is designed around the Freescale (now NXP) i.MX233 SoC. This SoC has an arm926ej-s at its core. The arm926ej-s was introduced in 2001; the i.MX233 SoC was brought to market in 2009. Despite its age, this SoC is still being produced, and Olimex is still building and selling boards around this device. Unfortunately, being an older device, its Linux kernel support isn't up to par. One of the issues is due to the fact it is so old, meaning it receives less active development. When it was introduced and support was added for it in the Linux kernel, the kernel had a completely different GPIO subsystem. In the intervening years that subsystem has been entirely re-written. All the newer, more popular, regularly-used SoCs all had their GPIO subsystems well integrated with the new subsystem. Older SoCs compile, but that's about it. As a result the kernel's GPIO information is rather lacking:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | root@imx233-olinuxino-maxi:~# gpioinfo gpiochip0 - 32 lines: line 0: unnamed unused input active-high line 1: unnamed unused input active-high line 2: unnamed unused input active-high line 3: unnamed unused input active-high line 4: unnamed unused input active-high line 5: unnamed unused input active-high line 6: unnamed unused input active-high line 7: unnamed unused input active-high line 8: unnamed unused input active-high line 9: unnamed unused input active-high line 10: unnamed unused input active-high line 11: unnamed unused input active-high line 12: unnamed unused input active-high line 13: unnamed unused input active-high line 14: unnamed unused input active-high line 15: unnamed unused input active-high line 16: unnamed unused input active-high line 17: unnamed "regulators:regulator@0" output active-high [used] line 18: unnamed unused input active-high line 19: unnamed unused input active-high line 20: unnamed unused input active-high line 21: unnamed unused input active-high line 22: unnamed unused input active-high line 23: unnamed unused input active-high line 24: unnamed unused input active-high line 25: unnamed unused input active-high line 26: unnamed unused input active-high line 27: unnamed unused input active-high line 28: unnamed unused input active-high line 29: unnamed unused input active-high line 30: unnamed unused input active-high line 31: unnamed unused input active-high gpiochip1 - 32 lines: line 0: unnamed unused input active-high line 1: unnamed unused input active-high line 2: unnamed unused input active-high line 3: unnamed unused input active-high line 4: unnamed unused input active-high line 5: unnamed unused input active-high line 6: unnamed unused input active-high line 7: unnamed unused input active-high line 8: unnamed unused input active-high line 9: unnamed unused input active-high line 10: unnamed unused input active-high line 11: unnamed unused input active-high line 12: unnamed unused input active-high line 13: unnamed unused input active-high line 14: unnamed unused input active-high line 15: unnamed unused input active-high line 16: unnamed unused input active-high line 17: unnamed unused input active-high line 18: unnamed unused input active-high line 19: unnamed unused input active-high line 20: unnamed unused input active-high line 21: unnamed unused input active-high line 22: unnamed unused input active-high line 23: unnamed unused input active-high line 24: unnamed unused input active-high line 25: unnamed unused input active-high line 26: unnamed unused output active-high line 27: unnamed unused input active-high line 28: unnamed unused input active-high line 29: unnamed unused input active-high line 30: unnamed unused input active-high line 31: unnamed unused input active-high gpiochip2 - 32 lines: line 0: unnamed unused input active-high line 1: unnamed "green" output active-high [used] line 2: unnamed unused input active-high line 3: unnamed unused input active-high line 4: unnamed unused input active-high line 5: unnamed unused input active-high line 6: unnamed unused input active-high line 7: unnamed unused input active-high line 8: unnamed unused input active-high line 9: unnamed unused input active-high line 10: unnamed unused input active-high line 11: unnamed unused input active-high line 12: unnamed unused input active-high line 13: unnamed unused input active-high line 14: unnamed unused input active-high line 15: unnamed unused input active-high line 16: unnamed unused input active-high line 17: unnamed unused input active-high line 18: unnamed unused input active-high line 19: unnamed unused input active-high line 20: unnamed unused input active-high line 21: unnamed unused input active-high line 22: unnamed unused input active-high line 23: unnamed unused input active-high line 24: unnamed unused input active-high line 25: unnamed unused input active-high line 26: unnamed unused input active-high line 27: unnamed unused input active-high line 28: unnamed unused input active-high line 29: unnamed unused input active-high line 30: unnamed unused input active-high line 31: unnamed unused input active-high |
Therefore, in order to figure out how its GPIOs connect to the SoC, we're going to have to do some digging into the board's schematics, then into the SoC's Reference Manual.
Thankfully, being open hardware, the schematics are publicly available (thank you Olimex!). The MAXI has a large, 40-pin, male connector on its side which is described in the schematic. Pretty much any GPIO line could be used, I decided to use the one labeled "PIN30".
Looking at the schematic:
We can see that PIN30 is connected to pin #28 of the board connector. We can also see that PIN30 connects to the SoC's pin 81, and the the SoC knows this pin as GPMI_CE1N.
[NOTE: There seems to be a little mistake in this schematic since it shows the SoC's pin 81 not connected to anything. Thankfully that's not the case, and we can associate the SoC pin with the connector pin by the common wire name: PIN30]
Now if we look at the SoC's Reference Manual and search for GPMI_CE1N we find (on page 37-28):
and we also find (on page 37-7):
Both of these confirm that the SoC pin known as GPMI_CE1N is found in GPIO bank 2, pin 27.
[NOTE: This SoC comes in 2 form factors: 128-pin QFP and 169-pin BGA. The schematics from Olimex show that they're using the MCIMX233CAG4C specifically. Page 41-1 of the Reference Manual shows that the CAG4C is the 128-pin LQFP (actually it shows that the CAG4B is the 128-pin LQFP, but searching on the Internet shows that the CAG4C is simply a later revision of the same device). When you're looking at the pin descriptions in the Reference Manual, make sure you're looking at the tables for the QFP specifically and not the BGA, otherwise you'll get the wrong GPIO bank/pin]
Performing the following simple test on the target board with everything wired up correctly proves we've found the right place:
1 | root@imx233-olinuxino-maxi:~# gpioset gpiochip2 27=1 |
One thing that I did notice about this device compared to the other SBCs that I used for these boxes is that this SoC does run noticeably slower than the others. If I used systemd for the init system the device would run just fine for a while, but then become completely unresponsive for quite a while (perhaps 30 seconds?). Then it would run perfectly fine for many minutes, but then be unresponsive. When it was possible to type in commands again, running cat /proc/loadavg would show a lot of recent activity. Switching to sysvinit gives a system that doesn't have unresponsive gaps.
I had decided that I was going to install an ssh server on all these devices so I could interact with them "in the field" should I so desire. As part of any device's first boot with an ssh server installed, a bunch of security keys need to be generated. Without exaggeration, installing an ssh server on this device causes the first boot to take well over 5 minutes before a command line is reached as the device generates/calculates its ssh keys. Maybe using dropbear would be better? I didn't check. My guess is that dropbear would need to generate its own initial keys as well, so it would probably run just as poorly on first boot?
I suspect the real source of the problem is the the random number generator code in the kernel. Random numbers produce the best security keys, but generating randomness from deterministic devices is difficult. Over the years the Linux kernel has had several iterations of the random-generating subsystem as people find issues. Most modern SoCs now come with circuitry specifically designed to generate randomness in order to feed the pool of entropy that is used to generate secure keys (for example). This new code assumes such units exist, but in older hardware they either don't exist, or the kernel's drivers haven't been updated to support the new functionality. In any case, generating the randomness required to create cryptographically secure keys (by some definition of "secure") takes a long time.
Conceptually box2 could be described by the following Fritzing diagram:
No comments:
Post a Comment