Progress in UPSide, and a change of plans.

Much has changed in UPSide over the last week. Ground has been broken on the software; one key piece of the control daemon, the policy state machine, now exists.

The big news, though, is that I found Gobot, a Go service library for writing IoT-like stuff and robotics. It’s kind of a hardware abstraction layer that gives you access via Go to things like GPIO pins and two-wire buses without C or assembler glue code. Supports three dozen different platforms, so (it plausibly claims) you get to port your code across them with relatively small changes like the names of the GPIO pins.

This is a big deal. Not having to write and test that glue code will probably cut UPSide’s development time by a good 50%. But even more importantly, it will largely decouple our software from the idiosyncracies of whatever SBC we first develop it on. If it turns out we have to change hardware horses in midstream this greatly reduces the chances of that being a disruptive setback for the software.

Recently I wrote on buying options as a hedge against uncertainty. Using GoBot is a cheap buy that looks like a really effective hedge.

There is only one real drawback. The LIME2 SBC I have is not on their support list. But I had a BeagleBone Black, gifted to me by a hacker at a Penguicon one or two years back, lying around unused. And it has the USB gadget port we need. So I’ve said goodbye to the LIME2 – free to good home – and adopted the BBB.

This has had fast results. This afternoon I got Go+Gobot to blink an LED on the BBB, exercising the GPIO pins. The thread across the chasm – and the whole procedure to set up your BBB and cross-build environment to make that happen is documented.

This is already so much less painful than C/C++ would have been that I feel like grinning like a fool.

There is, however, one purely physical problem with the BB that’s going to be a huge pain in the ass when we fabricate, and may force us to a different SBC in the final design. It’s the placement of the ports. (Good thing “different SBC in the final design” is now thinkable without stark terror, eh?)

The Ethernet, USB gadget port, an power plug are on one short edge of the board. The host port and the micro-DVI are on the opposite edge. Which is OK if you’re just using it in a hobby case – but we’re planning to build it into a larger enclosure, and for that kind of deployment this is crazy. You really want all your external ports on one side where they can be presented through a cutout, the way PC cases do it.

The fact that the power jack points forward is especially irritating. It should have been swapped with the USB host port. (This at least is a mistake the RPi designers didn’t make.) And those LEDs are not important enough to take up scarce edge space – that should be where the micro-DVI comes out.

(The LIME2 had similar though less severe port-placement problems, including the forward-facing power port.)

Oh well. It’s good enough for breadboarding, and if I have to I can imagine a strangely shaped 3D-printed shroud that exposes the Ethernet port while leaving just enough room for a right-angled barrel plug inside it.

Wanted: Linux SBC with one host USB port, one gadget USB port, one Ethernet port, and a mini-DVI all one one edge, with the power jack and SD card slot on a different edge. Grumble…

33 comments

    1. >One of the ODroids might work

      I’ve actually got a C1 somewhere in my parts bins, left over from a failed attempt to make Stratum-1 microserver from it. Some issue with the UART I don’t remember – no workaround.

      That does look like a nice row of ports. Alas, not on the Gobot platform list.

      1. This is the other side of the coin, right? Once you are courting a particular solution, everything not supported is off the table.

        How hard is it to extend the lib to support additional SBCs? Are maintainers willing to lend a hand? I’d be looking into that – as well as the angle you’re covering – at this point. But maybe nagging busy maintainers is a rookie mistake. shrug.

        1. >How hard is it to extend the lib to support additional SBCs?

          Probably not very. I’ve looked at some of the adaptors; you could probably write one in two working days starting from a hardware manual. Testing it would be the bitchy part and that’s mostly a matter of having the right parts and lab space to breadboard up a rig. I don’t, and would prefer that be someone else’s problem.

          >But maybe nagging busy maintainers is a rookie mistake.

          Alas, yes. I have offered to send the Gobot devs my LIME2 if they’ll port to it – not having to pay for the hardware does tend to mollify busy maintainers considerably. No response yet.

  1. > Go service library for writing IoT-like stuff and robotics. It’s kind of a hardware abstraction layer that gives you access via Go to things like GPIO pins and two-wire buses without C or assembler glue code.

    The Linux kernel already does a fairly good job at that through interfaces like /sys/class/gpio (echo 1 for on, 0 for off). I2C is a bit harder, but glue code is still a one-line subroutine in any language whose designer has heard of ioctls.

    I’m not quite sure what you want all this flexibility for, and especially not why you’d pay so much to get so little.

    If the UPS hardware is variable, you need a full-blown hardware abstraction layer. Just remapping GPIO pins won’t be sufficient if there are different devices on the I2C bus, because the devices won’t speak the same protocols. You need an interface that deals with high-level concepts like “ask the BMS how much run time is available in seconds” and then implements that interface with a hardware-specific protocol involving whatever signalling your BMS uses (I2C, GPIO, analog voltage 0..3V, CAN bus, all of those, whatever). If you’re dealing with live supply chains that stuff will change several times during the design lifetime anyway.

    Make the bottom layers of software correspond fairly directly to the hardware, so that a new board requires changing only those parts of the software that correspond to the hardware changes. Make the top layers correspond to the inputs to your policy framework. Everything in between, code included, is loadable, user-supplied hardware configuration data.

    If the SBC hardware is variable, you need a way to map the SBC’s pins to the connector to the UPS hardware, and that can be done by reading a 10-line config file in any language that can construct an ioctl parameter block by binary struct packing (are there any useful languages that can’t?). If the UPS hardware needs 8 GPIO pins and your SBC has 6, you have to choose which features to drop or you can’t use that SBC. If your SBC has 8 GPIO pins then all you need to configure is which one is connected to which UPS pin. If your SBC has a SPI shift register or I2C expander where its GPIO pins should be, you need a new device driver to pass the GPIO through that hardware.

    I’ve built systems that control hundreds of devices on SPI and GPIO buses with Perl scripts, mostly because a smoke testing application just kind of grew into 3600 lines of mature, tested code before I noticed. Porting this to new hardware involves changing maybe 12 lines of code for each board, but so far every new board has required new code–there’s always some unique interface device in the middle that introduces new signalling topology and protocol that can’t be configured with a table of a few constants unless that “table” is Turing-complete and can open arbitrary files in /dev.

    > This is already so much less painful than C/C++ would have been

    My day job is designing and building safety-certified hardware control systems. We do it in C because higher-level languages aren’t helpful for the certification process. We’d have to reverse-engineer everything the language does behind the scenes for us, then prove whatever it did wasn’t the wrong thing to do, every time. The places where a language like Go “helps” are often part of the noise not the signal. It’s not a performance thing, it’s a correctness thing.

    I find your aversion to the C language almost hilarious at times. The upside problem domain is one of the very few things C is good for (at least for the bottom two or three layers of abstraction) and yet you’ll pull in multiple third-party support layers to avoid C for one more month.

    > I can imagine a strangely shaped 3D-printed shroud that exposes the Ethernet port while leaving just enough room for a right-angled barrel plug inside it.

    Mount one of these to the panel and connect it to the SBC inside the box. They make a USB version too. You can run screws through the case and connector so it won’t be going anywhere until after so much force has been applied that the RJ45 jack (i.e. the cheap, replaceable, user-supplied component) is destroyed.

    There is no need to mount the SBC against the side of the case and you should not try to do so. It will get busted, especially if a tug-of-war occurs with the UPS batteries on one end of the Ethernet cable and some immobile object on the other. Take a look at the through-holes or card edges that you’d use to hold the SBC in place, then calculate how much force it will take to break them or dislodge the SBC. It’s usually a distressingly small number.

    1. >I’m not quite sure what you want all this flexibility for, and especially not why you’d pay so much to get so little.

      I thought I explained that already – I want “all this flexibility” as a hedge against the possibility that any given SBC won’t actually do what we think it will. I’m influenced by my bad experience with the ODroid C1 here; I wanted an alternative engine for my stratum-1 microserver recipe but couldn’t use it because of undocumented issues around the UART.

      Not sure what the “so much” you think I’m paying is. The BB is cheaper than the LIME2. Go is probably going to cut LOC at least in half relative to C. Gobot will cut LOC by another chunk, plus it’s already pulled me way ahead of my schedule estimate – I wan’t expecting to actually light up my first GPIO pin nearly this soon.

      >If the UPS hardware is variable

      That’s not presently in my planning, because we control the design of the high-power hardware and it’s easy to see all the way down to the bottom of it. The one thing that might vary significantly is the battery charateristics and I have carefully masked that off by specifying that it has to have an on-board BMS that is SBS 1.1 compliant. From the point of view of the rest of the design it’s two DC leads and a collection of I2C messages.

      Yeah, of course I’m going to do the obvious thing and hide all the I2C addresses in a lookup table. Duh. But heroic measures aren’t yet called for.

      >Make the bottom layers of software correspond fairly directly to the hardware, so that a new board requires changing only those parts of the software that correspond to the hardware changes. Make the top layers correspond to the inputs to your policy framework. Everything in between, code included, is loadable, user-supplied hardware configuration data.

      Taught your grandmother to suck eggs lately, man? I’d do this if I were coding upsided in my sleep.

      Well, OK. In stage 1 I’ll only have hardware parameters isolated in a hardware description structure; being able to load that table from a config file will come later.

      >If the SBC hardware is variable, you need…

      Your analysis is quite right. What you’re missing is that Gobot can largely be the bottom end of my device driver(s). I get to delegate that problem to platform experts while still being able to check and if necessary bypass their work.

      >We do it in C because higher-level languages aren’t helpful for the certification process. We’d have to reverse-engineer everything the language does behind the scenes for us, then prove whatever it did wasn’t the wrong thing to do, every time.

      Why don’t you have to do this in C itself? Never mind, that was a rhetorical question, I know why. It’s because in C you can see all the way through the code down to an execution-semantics model of how the machine language behaves (the folk way of expressing this is “C is structured assembler”). It’s not like, say, Python or Java where you’ve got an opaque layer of interpretation in the way.

      Well, guess what? Go has almost the same transparency. “Almost” because there’s one exception; it assumes you have reliable heap storage and the exact state of your heap can’t be exactly modeled in your head the way static buffers can. That’s a good trade for never having overrun or stale-pointer or double-free bugs.

      >I find your aversion to the C language almost hilarious at times.

      Funny thing to say about a guy who’s in year 36 as a C programmer. I don’t have an aversion to C at all – I have an aversion to the defect-rate consequences of manual memory allocation.

      It’s time we stopped doing that stupid shit, and I say that as someone who remembers when C took over systems programming and why it deserved to, because I was there when it happened in the early 1980s. It’s just not necessary any more outside of kernels and hard realtime.

      >Mount one of these

      No good. Doesn’t bring out the link or activity lights. You’re not the first person to think of this, I had to shoot it down on G+ too.

      >There is no need to mount the SBC against the side of the case and you should not try to do so.

      Here’s how I plan to handle that. The SBC will sit in a 3D-printed cradle sized to fit the enclosure but customized for the SBC type. All cables out of it get strain-relieved so the cradle has to break before the SBC itself gets put under mechanical stress. One side of the cradle fits a slot in the enclosure and exposes Ethernet, USB host and gadget ports, etc.

      The fewer ports have to have patch cables running inside the cradle to non-exposed board ports, the better off we are in terms of lowering build complexity. In the ideal case (not achieved with current hardware) there are zero such cables.

      Only four wires run out of the cradle: DC power and two I2C bus lines.

      (Hm. Possible exception for control buttons wired direct to a GPIO pin.)

      In the really ideal case, possibly not achievable for cost reasons, you can get at the cradle in situ by loosening a couple of screws and lifting off the enclosure top. I’m looking at mini-ITX cases as a possible way to achieve this.

      1. > already pulled me way ahead of my schedule estimate – I wan’t expecting to actually light up my first GPIO pin nearly this soon.

        Ah, you and I have very different expectations here.

        30 years ago, lighting up a GPIO pin and making it blink was an exercise for a high school senior student to be completed in under an hour. Today they teach it to kids five years younger. The students are not allowed to Google the answer, but you are.

        echo 8 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio8/direction
        while sleep 1; do echo 1 > /sys/class/gpio/gpio8/value; sleep 1; echo 0 > /sys/class/gpio/gpio8/value; done; # make LED on GPIO8 blink

        > In stage 1 I’ll only have hardware parameters isolated in a hardware description structure; being able to load that table from a config file will come later.

        In my experience with embedded hardware, that config file never fully materializes, or it morphs into a scripting language over time. It’s easier to give the customer source code to a loadable module that implements the entire IO framework–that way, if they need to do something you haven’t thought of, they just implement it themselves in the upside implementation language, instead of trying to translate it into whatever language the config file uses.

        For an open-source project this is trivial. It often ends up being a requirement for closed-source projects too.

        > Why don’t you have to do this in C itself?

        We do have to do it in C itself. Certified toolchain, certified libc, verification at binary level. We’re not even allowed to assume the C compiler produces deterministic output in case the build machine has some kind of hardware problem that affects only one build.

        > It’s because in C you can see all the way through the code down to an execution-semantics model of how the machine language behaves (the folk way of expressing this is “C is structured assembler”). It’s not like, say, Python or Java where you’ve got an opaque layer of interpretation in the way.

        It’s because we have tools that measure what the binaries do, and can sanely map their behavior back to C source code. When you run those tools on a garbage-collected language, a single } can expand to thousands of instructions and hundreds of branches. We have the same problem with plain C macros if they contain conditional statements–our toolchain flags those as errors, and if we really need an exception it has to be reviewed and approved with analysis the auditors can read. Mandatory branch coverage is a pretty harsh requirement; MCDC is even harsher.

        Use-after-free bugs would be relevant if we were allowed to use dynamic memory in safety applications in the first place. If we say “you can have up to N things” the auditors immediately ask “what is the largest value of N possible and where is your test report showing that you handle it successfully? Where is your system modelling report showing that you don’t ever run out of memory or suffer from free space fragmentation?” If we do anything that behaves like an allocator we have to show object life-cycle proofs that show where every object is allocated, initialized, and destroyed, and deallocated. We end up with bespoke memory management for each safety application because the memory manager itself is part of the safety function.

        We end up effectively modelling in Rust, then translate to C for implementation. It would be nice if we could just use Rust instead, but AFAIK there isn’t a Rust implementation available with the right certifications yet.

        > Go has almost the same transparency. “Almost” because there’s one exception; it assumes you have reliable heap storage

        Applications at higher safety rating levels can’t make that assumption.
        Languages like Python, Go, and Java are on a list of languages we can’t use, mostly because the answer to the question “what happens if we flip N heap bits at random” is “undefined behavior” not “we detect the error at line X with probability P, and do something safe at line Y.”

        > Funny thing to say about a guy who’s in year 36 as a C programmer.

        I know, that’s why it’s hilarious to me. You know where the traps are, and can bang out a prototype in a matter of hours. Instead, you inject third-party frameworks that your contributors have to learn instead of…what, exactly? Modifying a 10-line Go function and rebuilding?

        Compare with an online tutorial for an Arduino project. They write in Processing, which is more or less C. They don’t try to design an adjustable platinum alloy chassis for a kub kar. If they have to run on a different track width they just hammer new wheels onto a different-shaped block of wood.

        > No good. Doesn’t bring out the link or activity lights. You’re not the first person to think of this, I had to shoot it down on G+ too.

        There are panel mount LEDs too. Linux kernel has a LED framework so you can do things like connect the ifconfig status to a GPIO pin that the LED is wired to.

        You could put the cradle against the front of the USB case with a transparent panel that makes the on-board LEDs visible.

        If you look around on Digikey there are probably panel-mountable connectors with embedded LEDs available.

        > One side of the cradle fits a slot in the enclosure and exposes Ethernet, USB host and gadget ports, etc.

        I don’t think you can physically build such a cradle, because non-trivial force on the Ethernet cable will just rip the RJ45 socket right off of the SBC board. Even if it only bends the board a little, it can cause microfractures in PCB traces that will severely impact reliability.

        > Only four wires run out of the cradle: DC power and two I2C bus lines.

        That worries me. I2C may not be suitable in the electrical environment. It requires stable ground voltage and limited induced currents from EMI, and the inside of a UPS–especially between separate PCBs–has neither. I2C is usually used inside chips, or between chips inside a shielded box with a single ground plane, or inside heavily shielded cables (and even in that case, it’s not used for anything important like device control).

        What happens to your config file if I2C gets replaced with CAN or a bespoke serial protocol with ECC?

        1. >In my experience with embedded hardware, that config file never fully materializes, or it morphs into a scripting language over time

          I can readily believe this. But I suspect you’re talking about projects much more complex and demanding than the UPSide control software which, when you come down to it, is going to have a pretty simple interface to its environment. I already know what the architecture and data flows will look like and have even written most of them down in the transaction design.

          >We do have to do it in C itself.

          Well, the UPSide team has neither the man-hours nor the budget for the measures you describe. So arguing that we should stick to languages that theoretically support them seems kind of nugatory.

          >Languages like Python, Go, and Java are on a list of languages we can’t use, mostly because the answer to the question “what happens if we flip N heap bits at random” is “undefined behavior”

          At the level of verifiability you’re budgeting for that’s quite reasonable. UPSide can’t get there, because we can’t afford the tools or the time. So I have to think in terms of how to minimize our expected downstream defect rate without all that tooling.

          And when I think about that, GC seems like the biggest and most obvious mitigation measure we can take given the normal error statistics of C, followed by minimizing LOC, followed by delegating as much work as possible to people with more experience in supporting the SBC than we have.

          One of my main goals is to keep the amount of code we have to write down to below 4KLOC. Probably ain’t going to happen even in Go if I have to do all the glue myself, and I think hopeless in C.

          >Instead, you inject third-party frameworks that your contributors have to learn instead of…what, exactly?

          Instead of writing lots of code that epoxies us to whatever SBC we start with. I’m all about the decoupling and risk mitigation.

          >You could put the cradle against the front of the USB case with a transparent panel that makes the on-board LEDs visible.

          Good idea.

          >I don’t think you can physically build such a cradle, because non-trivial force on the Ethernet cable will just rip the RJ45 socket right off of the SBC board.

          And yet PC boards are built with Ethernet jacks sitting direct on a board edge all the time and “ripped right off” is a failure mode I’ve never heard of actually happening. I think you’re worrying too much here.

          >I2C may not be suitable in the electrical environment. It requires stable ground voltage and limited induced currents from EMI, and the inside of a UPS–especially between separate PCBs–has neither.

          On the other hand, here I’m afraid you may have a point. I don’t know what to do about it other than try I2C and see; the next step up from there in bus robustness would be hellaciously expensive. Still, I’ve made a point of writing the systems architecture so it’s only dependent on having a packet bus, not any particular bus technology.

          In part I’m leaning on Eric Baskin’s expertise here. As an experienced power and signals engineer who’s been a UL compliance monitor he has to be acutely aware of these issues and he hasn’t red-flagged I2C yet. If I understand the way he thinks, he’ll reply that the right thing to do is design so you’re not spewing EMI all over the shop to begin with.

          1. > One of my main goals is to keep the amount of code we have to write down to below 4KLOC. Probably ain’t going to happen even in Go if I have to do all the glue myself, and I think hopeless in C.

            I think the amount of board-specific glue code required is at most 100 lines in either Go or C–probably only 20 lines in Go for something as simple as UPSide. For the most part you’re doing read and write commands, maybe one or two ioctls (of the “pack an int into a buffer” variety) to configure a signalling rate on a bus protocol. “Make a LED blink” can be done from a boring standard Unix shell with no special language support at all.

            > And yet PC boards are built with Ethernet jacks sitting direct on a board edge all the time and “ripped right off” is a failure mode I’ve never heard of actually happening. I think you’re worrying too much here.

            PC boards for ATX cases are built with panel-mount connectors on a dedicated riser that spreads pull force over the surface where it meets the side of the case. The main PCB remains unbent because the panel is at a 90-degree angle and designed to flex without bending the mainboard where the data lives.

            Laptops usually have a robust metal frame around the port connectors and some space around the connector to allow the PCB to flex. Laptops also have a lot less weight than a UPS–the lighter ones will happily hang suspended from their cables.

            SBC boards are not designed for this kind of physical robustness, and will break if you treat them as though they are. If you make a panel cutout capable of holding the RJ45 in when the UPS falls off the desk, it will cover up the LEDs you want to be visible.

        2. >What happens to your config file if I2C gets replaced with CAN or a bespoke serial protocol with ECC?

          Probably very little. All it has to do is carry unique device addresses; it diesn’t need to care what those addresses mean to the interconnect layer.

          1. I think you’re missing some requirements there. The device addresses on a different bus protocol are a different size, the messages have different lengths, and a new bus protocol is likely to consist of different messages with different operational semantics. Some protocols require synchronous replies, others are asynchronous.

            Unless the config file is equivalent to a Python script, it’d be pretty amazing if you can make that kind of leap without writing new driver code.

            1. >Unless the config file is equivalent to a Python script, it’d be pretty amazing if you can make that kind of leap without writing new driver code.

              Why would I want to try? If we’re moving to a new interconnect method, we’re oving to a new interconnect method and a new driver is completely appropriate.

        3. >What happens to your config file if I2C gets replaced with CAN or a bespoke serial protocol with ECC?

          I have new information.

          The Beaglebone has two CANBUS controllers on board. And there is such a thing as a CANBUS-I2C bridge. So in one scenario we end up using CANBUS to connect the controller to the high-voltage board and short, well-buried traces for local I2C on the latter.

          I’ve talked with Eric Baskin. As I anticipated, his preferred approach is to design carefully for low EMI and a stable ground. He rightly points out that we need these for regulatory compliance anyway.

      2. Why don’t you have to do this in C itself? Never mind, that was a rhetorical question, I know why. It’s because in C you can see all the way through the code down to an execution-semantics model of how the machine language behaves (the folk way of expressing this is “C is structured assembler”).

        And, if necessary, look at the generated assembler and mentally map it back to the C source. I’ve spent significant time the past couple of weeks doing exactly that, in bringing up a new board for my employer.

        I’m not even sure I could do that in Go, much less Python or Ruby or…

  2. IIRC, the BBB is open enough that board layouts and circuit CAD files are available, so you could consider spinning your own board that has ports where ever you want. You’ll have to QC it, but if it’s just a layout change (vs circuit-and-layout) it shouldn’t be too bad.

    1. >so you could consider spinning your own board that has ports where ever you want.

      Too much work and cost for my team. Instead I just sent Jason Kridner a proposal and business case for the BeagleBone Edge. We’ll see what happens.

      1. RPi Compute Module with a custom backplane?

        Those seem to be relatively easy to customize (I randomly found a “design your own”), and in quantities relevant for this project would probably be quite affordable.

        And would let you align everything how you wanted AND reinforce the RJ45 plug (or arrange for a panel-mount connector natively).

        1. >RPi Compute Module with a custom backplane?

          The words “custom backplane” strike terror into my heart.

          One of the principal objectives of the design is to minimize build complexity. We need to have one custom PCB for the high-power plane; otherwise we want to stick to COTS components.

          1. Fair, but note in this context that there are sites out there whose entire job appears to be “custom backplane design for an RPi Compute module”, where you basically plug it into a designer program and they spit out an estimate and plans, from what I saw.

            It’s “custom” the way “get some T-shirts printed” is custom, as far as I can tell.

            (E.g. the place I found is https://www.gumstix.com/blog/build-your-own-custom-expansion-board-for-raspberry-pi-compute-module-in-a-day/)

  3. If you’re doing it in Go, perhaps https://gokrazy.org/ would be of interest: a pure Go userland Linux distro. Targeted at RPi, but the firmware bits are perhaps easily swappable for other boards. (I imagine most of the work is in the Go userland.)

    1. >If you’re doing it in Go, perhaps https://gokrazy.org/ would be of interest:

      That is a very interesting idea and I plan to keep an eye on it. But there are two reasons I’m not planning to use it in UPSide.

      1. I don’t expect to be relying on Linux userland much after boot time, if at all. The SBC comes up, the control daemon launches, and it runs. We’re done.

      2. Project looks alpha stage, more a proof of concept than a production suite. That’s OK, everything starts that way.

      1. > I don’t expect to be relying on Linux userland much after boot time, if at all.

        I’m reminded of a talk Bruce Schneier gave in which he explained that his company’s security appliances don’t have bash or a lot of other Linux user-space binaries because they don’t need them. And if you don’t need them, you don’t want them, because they can be used by an attacker (or in this case trigger a red flag from a safety audit and cause compliance headaches). Since we’re building something that can run off an initrd loaded from μSD at boot time, it’s entirely possible to build a stripped-down Linux whose init brings up some hardware-support daemons (net, usb) and UPSided, then does nothing other than monitor those daemons to restart them if they crash.

        We have all of those tools on the machine where we build the initrd, but if we use FAT32 as the filesystem on the μSD no one needs any special tools to copy it over. User prefs and other local config info can be written to UPSide.conf on the μSD’s FAT32, rather than needing to be written into the initrd, making it bog-simple for people to back up and restore the μSD from any laptop with an SD-card slot, regardless of OS. (We probably should expose the μSD to the host computer connected via USB, so that these files can be read/written without even removing the μSD from the SBC.)

        1. >Since we’re building something that can run off an initrd loaded from ?SD at boot time, it’s entirely possible to build a stripped-down Linux whose init brings up some hardware-support daemons (net, usb) and UPSided, then does nothing other than monitor those daemons to restart them if they crash.

          Yes, that’s the direction I’ll be heading once I have the control daemon solid enough.

  4. I am not sure why the insistence on using the board-edge power jack; nearly all SBCs, the ‘bone especially, can be powered directly through the 5VDC or 3.3VDC pins in the GPIO header with great success. The ideal solution is to use the 5VDC pins, because then you get the USB host port powered as well. Should be a simpler solution to source power on a couple 0.1″ header pins than trying to source power onto a power plug.

    1. >nearly all SBCs, the ‘bone especially, can be powered directly through the 5VDC or 3.3VDC pins in the GPIO header with great success.

      Thanks. This is the kind of thing I don’t know because I are just an ignorant software engineer.

      1. Just be careful that you don’t plug that connector in backwards, or better yet come up with a way to prevent it. I fried an original Pi Model B that way, even though I was being careful…apparently, not careful enough.

        1. The only time I’ve ever played around with GPIO power injection, I was fortunately using a battery-charger hat that, because of hat-ness, was inherently polarity-correct.

          Otherwise I’m sure I would have managed to gank the Pi I was playing with.

      2. Careful, in some cases (like on the RPi) this bypasses some of the protection circuitry (capacitors and fuses).

  5. Conditional on good-quality unit tests and integration tests, I approve. One of the critical elements of engineering is knowing where functional boundaries are and when you can rely on others to do the work for you according to specification.

    If you want to start designing a new car, or a new car company, you don’t first spend time wondering what material you’d use to make bolts of out. “Gee … I wonder how well a bolt made out of recycled newspaper would work. Huh able to support about 2 newtons of force before failing. Less if wet. Let’s try cut up pop bottles …”
    Instead, you grab your suppliers catalogs of pre-made bolts with specifications, pick the one(s) which meet your design requirements and move on to the challenging parts.

    I’ve noticed that fresh engineers (including myself) tend to like to re-invent the wheel a lot. Maybe it’s about learning. Maybe it’s about starting with something you can understand. This is fine in college, but once in the “real” world, re-inventing something is often a major waste of resources. I once was working with a new software engineer who wanted to rewrite from scratch our multi-machine multi-threaded configuration/job framework. Not because the old one was broken, but because he didn’t fully understand it. This is a piece of software which had another team of about a dozen engineers working on it iteratively for years. He wasn’t going to make a useful or compatible replacement in a few months. Even if we had the months to spare, there were far better things to focus the energy on rewriting.

    1. “”I’ve noticed that fresh engineers (including myself) tend to like to re-invent the wheel a lot. ”

      This is the inflection point where the design engineer begins to listen to advice, understand cost tradeoffs and budget constraints and practical reality; or earns the reputation as a “chaos monkey” and gets to be in charge of testing. Career paths are chosen early by how you approach problems in industry. Usually. And then there was the guy that designed the Oroville dam. The one that got away.

      One consideration for any power supply (more important than you may think) is EMI emissions. It is very easy to create an illegal radiator of significant consquence with switching power sources. Smoke isn’t the only way to fail.

      As long as the interface to the power electronics is generic I2C and digital IO – the rest of it doesn’t really have to matter. Folks can roll their own if there is a documented interface.

      1. >One consideration for any power supply (more important than you may think) is EMI emissions. It is very easy to create an illegal radiator of significant consquence with switching power sources. Smoke isn’t the only way to fail.

        Eric Baskin and I are very aware of this. I think “How are we going to keep EMI at tolerable levels” is probably our second biggest worry, right after “Where do we find a COTS battery that meets our specs?

        1. Lots of copper tape, a single ground on the board and a well bonded multi strand conductor to a good earth ground should fix the EMI, which discounts all the other design constraints. If you want to achieve zero EMI, don’t turn it on…

          I’m not a software person, but I am a chemist. There are some hybrid supercapacitor setups that can store the energy and tolerate deep cycling reasonably well. I saw the energy storage specs go by. What are the constraints on the number of charge/discharge cycles before significant degradation, size of the unit, and cost? If these are in the dev files, please point me to them.

          I’m appreciative of this effort. lead sulfate batteries have their place, but they can degrade pretty quickly.

Leave a comment

Your email address will not be published. Required fields are marked *